blob: fabe0c80acccf7f066d55e03619b9b429df00db1 [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},
Cristy798981a2020-02-17 12:07:15 -0500443 {"moments", StringReference}, {"unique", StringReference} } },
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} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000580 };
581
582static SplayTreeInfo
583 *magick_registry = (SplayTreeInfo *) NULL;
584
585/*
586 Forward declarations.
587*/
588static Image
589 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
590
591static ssize_t
592 strEQcase(const char *,const char *);
593
594/*
595%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
596% %
597% %
598% %
599% C l o n e P a c k a g e I n f o %
600% %
601% %
602% %
603%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
604%
605% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
606% a new one.
607%
608% The format of the ClonePackageInfo routine is:
609%
610% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
611% exception)
612%
613% A description of each parameter follows:
614%
615% o info: a structure of type info.
616%
617% o exception: Return any errors or warnings in this structure.
618%
619*/
620static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
621 ExceptionInfo *exception)
622{
623 struct PackageInfo
624 *clone_info;
625
626 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
627 if (clone_info == (struct PackageInfo *) NULL)
628 {
629 ThrowPerlException(exception,ResourceLimitError,
630 "UnableToClonePackageInfo",PackageName);
631 return((struct PackageInfo *) NULL);
632 }
633 if (info == (struct PackageInfo *) NULL)
634 {
635 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
636 return(clone_info);
637 }
638 *clone_info=(*info);
639 clone_info->image_info=CloneImageInfo(info->image_info);
640 return(clone_info);
641}
642
643/*
644%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
645% %
646% %
647% %
648% c o n s t a n t %
649% %
650% %
651% %
652%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
653%
654% constant() returns a double value for the specified name.
655%
656% The format of the constant routine is:
657%
658% double constant(char *name,ssize_t sans)
659%
660% A description of each parameter follows:
661%
662% o value: Method constant returns a double value for the specified name.
663%
664% o name: The name of the constant.
665%
666% o sans: This integer value is not used.
667%
668*/
669static double constant(char *name,ssize_t sans)
670{
671 (void) sans;
672 errno=0;
673 switch (*name)
674 {
675 case 'B':
676 {
677 if (strEQ(name,"BlobError"))
678 return(BlobError);
679 if (strEQ(name,"BlobWarning"))
680 return(BlobWarning);
681 break;
682 }
683 case 'C':
684 {
685 if (strEQ(name,"CacheError"))
686 return(CacheError);
687 if (strEQ(name,"CacheWarning"))
688 return(CacheWarning);
689 if (strEQ(name,"CoderError"))
690 return(CoderError);
691 if (strEQ(name,"CoderWarning"))
692 return(CoderWarning);
693 if (strEQ(name,"ConfigureError"))
694 return(ConfigureError);
695 if (strEQ(name,"ConfigureWarning"))
696 return(ConfigureWarning);
697 if (strEQ(name,"CorruptImageError"))
698 return(CorruptImageError);
699 if (strEQ(name,"CorruptImageWarning"))
700 return(CorruptImageWarning);
701 break;
702 }
703 case 'D':
704 {
705 if (strEQ(name,"DelegateError"))
706 return(DelegateError);
707 if (strEQ(name,"DelegateWarning"))
708 return(DelegateWarning);
709 if (strEQ(name,"DrawError"))
710 return(DrawError);
711 if (strEQ(name,"DrawWarning"))
712 return(DrawWarning);
713 break;
714 }
715 case 'E':
716 {
717 if (strEQ(name,"ErrorException"))
718 return(ErrorException);
719 if (strEQ(name,"ExceptionError"))
720 return(CoderError);
721 if (strEQ(name,"ExceptionWarning"))
722 return(CoderWarning);
723 break;
724 }
725 case 'F':
726 {
727 if (strEQ(name,"FatalErrorException"))
728 return(FatalErrorException);
729 if (strEQ(name,"FileOpenError"))
730 return(FileOpenError);
731 if (strEQ(name,"FileOpenWarning"))
732 return(FileOpenWarning);
733 break;
734 }
735 case 'I':
736 {
737 if (strEQ(name,"ImageError"))
738 return(ImageError);
739 if (strEQ(name,"ImageWarning"))
740 return(ImageWarning);
741 break;
742 }
743 case 'M':
744 {
745 if (strEQ(name,"MaxRGB"))
746 return(QuantumRange);
747 if (strEQ(name,"MissingDelegateError"))
748 return(MissingDelegateError);
749 if (strEQ(name,"MissingDelegateWarning"))
750 return(MissingDelegateWarning);
751 if (strEQ(name,"ModuleError"))
752 return(ModuleError);
753 if (strEQ(name,"ModuleWarning"))
754 return(ModuleWarning);
755 break;
756 }
757 case 'O':
758 {
759 if (strEQ(name,"Opaque"))
760 return(OpaqueAlpha);
761 if (strEQ(name,"OptionError"))
762 return(OptionError);
763 if (strEQ(name,"OptionWarning"))
764 return(OptionWarning);
765 break;
766 }
767 case 'Q':
768 {
769 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
770 return(MAGICKCORE_QUANTUM_DEPTH);
771 if (strEQ(name,"QuantumDepth"))
772 return(MAGICKCORE_QUANTUM_DEPTH);
773 if (strEQ(name,"QuantumRange"))
774 return(QuantumRange);
775 break;
776 }
777 case 'R':
778 {
779 if (strEQ(name,"ResourceLimitError"))
780 return(ResourceLimitError);
781 if (strEQ(name,"ResourceLimitWarning"))
782 return(ResourceLimitWarning);
783 if (strEQ(name,"RegistryError"))
784 return(RegistryError);
785 if (strEQ(name,"RegistryWarning"))
786 return(RegistryWarning);
787 break;
788 }
789 case 'S':
790 {
791 if (strEQ(name,"StreamError"))
792 return(StreamError);
793 if (strEQ(name,"StreamWarning"))
794 return(StreamWarning);
795 if (strEQ(name,"Success"))
796 return(0);
797 break;
798 }
799 case 'T':
800 {
801 if (strEQ(name,"Transparent"))
802 return(TransparentAlpha);
803 if (strEQ(name,"TypeError"))
804 return(TypeError);
805 if (strEQ(name,"TypeWarning"))
806 return(TypeWarning);
807 break;
808 }
809 case 'W':
810 {
811 if (strEQ(name,"WarningException"))
812 return(WarningException);
813 break;
814 }
815 case 'X':
816 {
817 if (strEQ(name,"XServerError"))
818 return(XServerError);
819 if (strEQ(name,"XServerWarning"))
820 return(XServerWarning);
821 break;
822 }
823 }
824 errno=EINVAL;
825 return(0);
826}
827
828/*
829%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
830% %
831% %
832% %
833% D e s t r o y P a c k a g e I n f o %
834% %
835% %
836% %
837%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
838%
839% Method DestroyPackageInfo frees a previously created info structure.
840%
841% The format of the DestroyPackageInfo routine is:
842%
843% DestroyPackageInfo(struct PackageInfo *info)
844%
845% A description of each parameter follows:
846%
847% o info: a structure of type info.
848%
849*/
850static void DestroyPackageInfo(struct PackageInfo *info)
851{
852 info->image_info=DestroyImageInfo(info->image_info);
853 info=(struct PackageInfo *) RelinquishMagickMemory(info);
854}
855
856/*
857%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
858% %
859% %
860% %
861% G e t L i s t %
862% %
863% %
864% %
865%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
866%
867% Method GetList is recursively called by SetupList to traverse the
868% Image__Magick reference. If building an reference_vector (see SetupList),
869% *current is the current position in *reference_vector and *last is the final
870% entry in *reference_vector.
871%
872% The format of the GetList routine is:
873%
874% GetList(info)
875%
876% A description of each parameter follows:
877%
878% o info: a structure of type info.
879%
880*/
881static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
882 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
883{
884 Image
885 *image;
886
887 if (reference == (SV *) NULL)
888 return(NULL);
889 switch (SvTYPE(reference))
890 {
891 case SVt_PVAV:
892 {
893 AV
894 *av;
895
896 Image
897 *head,
898 *previous;
899
900 register ssize_t
901 i;
902
903 ssize_t
904 n;
905
906 /*
907 Array of images.
908 */
909 previous=(Image *) NULL;
910 head=(Image *) NULL;
911 av=(AV *) reference;
912 n=av_len(av);
913 for (i=0; i <= n; i++)
914 {
915 SV
916 **rv;
917
918 rv=av_fetch(av,i,0);
919 if (rv && *rv && sv_isobject(*rv))
920 {
921 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
922 exception);
923 if (image == (Image *) NULL)
924 continue;
925 if (image == previous)
926 {
927 image=CloneImage(image,0,0,MagickTrue,exception);
928 if (image == (Image *) NULL)
929 return(NULL);
930 }
931 image->previous=previous;
932 *(previous ? &previous->next : &head)=image;
933 for (previous=image; previous->next; previous=previous->next) ;
934 }
935 }
936 return(head);
937 }
938 case SVt_PVMG:
939 {
940 /*
941 Blessed scalar, one image.
942 */
943 image=INT2PTR(Image *,SvIV(reference));
944 if (image == (Image *) NULL)
945 return(NULL);
946 image->previous=(Image *) NULL;
947 image->next=(Image *) NULL;
948 if (reference_vector)
949 {
950 if (*current == *last)
951 {
952 *last+=256;
953 if (*reference_vector == (SV **) NULL)
954 *reference_vector=(SV **) AcquireQuantumMemory(*last,
955 sizeof(*reference_vector));
956 else
957 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
958 *last,sizeof(*reference_vector));
959 }
960 if (*reference_vector == (SV **) NULL)
961 {
962 ThrowPerlException(exception,ResourceLimitError,
963 "MemoryAllocationFailed",PackageName);
964 return((Image *) NULL);
965 }
966 (*reference_vector)[*current]=reference;
967 (*reference_vector)[++(*current)]=NULL;
968 }
969 return(image);
970 }
971 default:
972 break;
973 }
974 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
975 (double) SvTYPE(reference));
976 return((Image *) NULL);
977}
978
979/*
980%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
981% %
982% %
983% %
984% G e t P a c k a g e I n f o %
985% %
986% %
987% %
988%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
989%
990% Method GetPackageInfo looks up or creates an info structure for the given
991% Image__Magick reference. If it does create a new one, the information in
992% package_info is used to initialize it.
993%
994% The format of the GetPackageInfo routine is:
995%
996% struct PackageInfo *GetPackageInfo(void *reference,
997% struct PackageInfo *package_info,ExceptionInfo *exception)
998%
999% A description of each parameter follows:
1000%
1001% o info: a structure of type info.
1002%
1003% o exception: Return any errors or warnings in this structure.
1004%
1005*/
1006static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
1007 struct PackageInfo *package_info,ExceptionInfo *exception)
1008{
1009 char
cristy151b66d2015-04-15 10:50:31 +00001010 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00001011
1012 struct PackageInfo
1013 *clone_info;
1014
1015 SV
1016 *sv;
1017
cristy151b66d2015-04-15 10:50:31 +00001018 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00001019 PackageName,XS_VERSION,reference);
1020 sv=perl_get_sv(message,(TRUE | 0x02));
1021 if (sv == (SV *) NULL)
1022 {
1023 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1024 message);
1025 return(package_info);
1026 }
1027 if (SvREFCNT(sv) == 0)
1028 (void) SvREFCNT_inc(sv);
1029 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1030 return(clone_info);
1031 clone_info=ClonePackageInfo(package_info,exception);
1032 sv_setiv(sv,PTR2IV(clone_info));
1033 return(clone_info);
1034}
1035
1036/*
1037%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1038% %
1039% %
1040% %
1041% S e t A t t r i b u t e %
1042% %
1043% %
1044% %
1045%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1046%
1047% SetAttribute() sets the attribute to the value in sval. This can change
1048% either or both of image or info.
1049%
1050% The format of the SetAttribute routine is:
1051%
1052% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1053% SV *sval,ExceptionInfo *exception)
1054%
1055% A description of each parameter follows:
1056%
1057% o list: a list of strings.
1058%
1059% o string: a character string.
1060%
1061*/
1062
1063static double SiPrefixToDoubleInterval(const char *string,const double interval)
1064{
1065 char
1066 *q;
1067
1068 double
1069 value;
1070
1071 value=InterpretSiPrefixValue(string,&q);
1072 if (*q == '%')
1073 value*=interval/100.0;
1074 return(value);
1075}
1076
1077static inline double StringToDouble(const char *string,char **sentinal)
1078{
1079 return(InterpretLocaleValue(string,sentinal));
1080}
1081
1082static double StringToDoubleInterval(const char *string,const double interval)
1083{
1084 char
1085 *q;
1086
1087 double
1088 value;
1089
1090 value=InterpretLocaleValue(string,&q);
1091 if (*q == '%')
1092 value*=interval/100.0;
1093 return(value);
1094}
1095
1096static inline ssize_t StringToLong(const char *value)
1097{
1098 return(strtol(value,(char **) NULL,10));
1099}
1100
1101static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1102 const char *attribute,SV *sval,ExceptionInfo *exception)
1103{
1104 GeometryInfo
1105 geometry_info;
1106
1107 long
1108 x,
1109 y;
1110
1111 PixelInfo
1112 pixel;
1113
1114 MagickStatusType
1115 flags;
1116
1117 PixelInfo
1118 *color,
1119 target_color;
1120
1121 ssize_t
1122 sp;
1123
1124 switch (*attribute)
1125 {
1126 case 'A':
1127 case 'a':
1128 {
1129 if (LocaleCompare(attribute,"adjoin") == 0)
1130 {
1131 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1132 SvPV(sval,na)) : SvIV(sval);
1133 if (sp < 0)
1134 {
1135 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1136 SvPV(sval,na));
1137 break;
1138 }
1139 if (info)
1140 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1141 break;
1142 }
1143 if (LocaleCompare(attribute,"alpha") == 0)
1144 {
1145 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1146 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1147 if (sp < 0)
1148 {
1149 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1150 SvPV(sval,na));
1151 break;
1152 }
1153 for ( ; image; image=image->next)
1154 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1155 exception);
1156 break;
1157 }
1158 if (LocaleCompare(attribute,"antialias") == 0)
1159 {
1160 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1161 SvPV(sval,na)) : SvIV(sval);
1162 if (sp < 0)
1163 {
1164 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1165 SvPV(sval,na));
1166 break;
1167 }
1168 if (info)
1169 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1170 break;
1171 }
1172 if (LocaleCompare(attribute,"area-limit") == 0)
1173 {
1174 MagickSizeType
1175 limit;
1176
1177 limit=MagickResourceInfinity;
1178 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1179 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1180 100.0);
1181 (void) SetMagickResourceLimit(AreaResource,limit);
1182 break;
1183 }
1184 if (LocaleCompare(attribute,"attenuate") == 0)
1185 {
1186 if (info)
1187 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1188 break;
1189 }
1190 if (LocaleCompare(attribute,"authenticate") == 0)
1191 {
1192 if (info)
1193 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1194 break;
1195 }
1196 if (info)
1197 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1198 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001199 {
1200 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstra337c9bc2017-04-03 16:04:21 +02001201 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001202 }
cristy4a3ce0a2013-08-03 20:06:59 +00001203 break;
1204 }
1205 case 'B':
1206 case 'b':
1207 {
1208 if (LocaleCompare(attribute,"background") == 0)
1209 {
1210 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1211 exception);
1212 if (info)
1213 info->image_info->background_color=target_color;
1214 for ( ; image; image=image->next)
1215 image->background_color=target_color;
1216 break;
1217 }
1218 if (LocaleCompare(attribute,"blue-primary") == 0)
1219 {
1220 for ( ; image; image=image->next)
1221 {
1222 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1223 image->chromaticity.blue_primary.x=geometry_info.rho;
1224 image->chromaticity.blue_primary.y=geometry_info.sigma;
1225 if ((flags & SigmaValue) == 0)
1226 image->chromaticity.blue_primary.y=
1227 image->chromaticity.blue_primary.x;
1228 }
1229 break;
1230 }
1231 if (LocaleCompare(attribute,"bordercolor") == 0)
1232 {
1233 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1234 exception);
1235 if (info)
1236 info->image_info->border_color=target_color;
1237 for ( ; image; image=image->next)
1238 image->border_color=target_color;
1239 break;
1240 }
1241 if (info)
1242 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1243 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001244 {
1245 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001246 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001247 }
cristy4a3ce0a2013-08-03 20:06:59 +00001248 break;
1249 }
1250 case 'C':
1251 case 'c':
1252 {
1253 if (LocaleCompare(attribute,"cache-threshold") == 0)
1254 {
1255 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1256 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1257 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1258 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1259 break;
1260 }
1261 if (LocaleCompare(attribute,"clip-mask") == 0)
1262 {
1263 Image
1264 *clip_mask;
1265
1266 clip_mask=(Image *) NULL;
1267 if (SvPOK(sval))
1268 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1269 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001270 SetImageMask(image,ReadPixelMask,clip_mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001271 break;
1272 }
1273 if (LocaleNCompare(attribute,"colormap",8) == 0)
1274 {
1275 for ( ; image; image=image->next)
1276 {
1277 int
1278 items;
1279
1280 long
1281 i;
1282
1283 if (image->storage_class == DirectClass)
1284 continue;
1285 i=0;
1286 items=sscanf(attribute,"%*[^[][%ld",&i);
1287 (void) items;
1288 if (i > (ssize_t) image->colors)
1289 i%=image->colors;
1290 if ((strchr(SvPV(sval,na),',') == 0) ||
1291 (strchr(SvPV(sval,na),')') != 0))
1292 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1293 image->colormap+i,exception);
1294 else
1295 {
1296 color=image->colormap+i;
1297 pixel.red=color->red;
1298 pixel.green=color->green;
1299 pixel.blue=color->blue;
1300 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1301 pixel.red=geometry_info.rho;
1302 pixel.green=geometry_info.sigma;
1303 pixel.blue=geometry_info.xi;
1304 color->red=ClampToQuantum(pixel.red);
1305 color->green=ClampToQuantum(pixel.green);
1306 color->blue=ClampToQuantum(pixel.blue);
1307 }
1308 }
1309 break;
1310 }
1311 if (LocaleCompare(attribute,"colorspace") == 0)
1312 {
1313 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1314 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1315 if (sp < 0)
1316 {
1317 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1318 SvPV(sval,na));
1319 break;
1320 }
1321 for ( ; image; image=image->next)
Cristy59262d92016-12-05 15:21:50 -05001322 (void) SetImageColorspace(image,(ColorspaceType) sp,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001323 break;
1324 }
1325 if (LocaleCompare(attribute,"comment") == 0)
1326 {
1327 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001328 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001329 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001330 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001331 break;
1332 }
1333 if (LocaleCompare(attribute,"compression") == 0)
1334 {
1335 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1336 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1337 if (sp < 0)
1338 {
1339 ThrowPerlException(exception,OptionError,
1340 "UnrecognizedImageCompression",SvPV(sval,na));
1341 break;
1342 }
1343 if (info)
1344 info->image_info->compression=(CompressionType) sp;
1345 for ( ; image; image=image->next)
1346 image->compression=(CompressionType) sp;
1347 break;
1348 }
1349 if (info)
1350 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1351 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001352 {
1353 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001354 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001355 }
cristy4a3ce0a2013-08-03 20:06:59 +00001356 break;
1357 }
1358 case 'D':
1359 case 'd':
1360 {
1361 if (LocaleCompare(attribute,"debug") == 0)
1362 {
1363 SetLogEventMask(SvPV(sval,na));
1364 break;
1365 }
1366 if (LocaleCompare(attribute,"delay") == 0)
1367 {
1368 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1369 for ( ; image; image=image->next)
1370 {
1371 image->delay=(size_t) floor(geometry_info.rho+0.5);
1372 if ((flags & SigmaValue) != 0)
1373 image->ticks_per_second=(ssize_t)
1374 floor(geometry_info.sigma+0.5);
1375 }
1376 break;
1377 }
1378 if (LocaleCompare(attribute,"disk-limit") == 0)
1379 {
1380 MagickSizeType
1381 limit;
1382
1383 limit=MagickResourceInfinity;
1384 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1385 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1386 100.0);
1387 (void) SetMagickResourceLimit(DiskResource,limit);
1388 break;
1389 }
1390 if (LocaleCompare(attribute,"density") == 0)
1391 {
1392 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1393 {
1394 ThrowPerlException(exception,OptionError,"MissingGeometry",
1395 SvPV(sval,na));
1396 break;
1397 }
1398 if (info)
1399 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1400 for ( ; image; image=image->next)
1401 {
1402 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1403 image->resolution.x=geometry_info.rho;
1404 image->resolution.y=geometry_info.sigma;
1405 if ((flags & SigmaValue) == 0)
1406 image->resolution.y=image->resolution.x;
1407 }
1408 break;
1409 }
1410 if (LocaleCompare(attribute,"depth") == 0)
1411 {
1412 if (info)
1413 info->image_info->depth=SvIV(sval);
1414 for ( ; image; image=image->next)
1415 (void) SetImageDepth(image,SvIV(sval),exception);
1416 break;
1417 }
1418 if (LocaleCompare(attribute,"dispose") == 0)
1419 {
1420 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1421 SvPV(sval,na)) : SvIV(sval);
1422 if (sp < 0)
1423 {
1424 ThrowPerlException(exception,OptionError,
1425 "UnrecognizedDisposeMethod",SvPV(sval,na));
1426 break;
1427 }
1428 for ( ; image; image=image->next)
1429 image->dispose=(DisposeType) sp;
1430 break;
1431 }
1432 if (LocaleCompare(attribute,"dither") == 0)
1433 {
1434 if (info)
1435 {
1436 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1437 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1438 if (sp < 0)
1439 {
1440 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1441 SvPV(sval,na));
1442 break;
1443 }
1444 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1445 }
1446 break;
1447 }
1448 if (LocaleCompare(attribute,"display") == 0)
1449 {
1450 display:
1451 if (info)
1452 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1453 break;
1454 }
1455 if (info)
1456 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1457 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001458 {
1459 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001460 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001461 }
cristy4a3ce0a2013-08-03 20:06:59 +00001462 break;
1463 }
1464 case 'E':
1465 case 'e':
1466 {
1467 if (LocaleCompare(attribute,"endian") == 0)
1468 {
1469 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1470 SvPV(sval,na)) : SvIV(sval);
1471 if (sp < 0)
1472 {
1473 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1474 SvPV(sval,na));
1475 break;
1476 }
1477 if (info)
1478 info->image_info->endian=(EndianType) sp;
1479 for ( ; image; image=image->next)
1480 image->endian=(EndianType) sp;
1481 break;
1482 }
1483 if (LocaleCompare(attribute,"extract") == 0)
1484 {
1485 /*
1486 Set image extract geometry.
1487 */
1488 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1489 break;
1490 }
1491 if (info)
1492 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1493 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001494 {
1495 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001496 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001497 }
cristy4a3ce0a2013-08-03 20:06:59 +00001498 break;
1499 }
1500 case 'F':
1501 case 'f':
1502 {
1503 if (LocaleCompare(attribute,"filename") == 0)
1504 {
1505 if (info)
1506 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001507 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001508 for ( ; image; image=image->next)
1509 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001510 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001511 break;
1512 }
1513 if (LocaleCompare(attribute,"file") == 0)
1514 {
1515 FILE
1516 *file;
1517
1518 PerlIO
1519 *io_info;
1520
1521 if (info == (struct PackageInfo *) NULL)
1522 break;
1523 io_info=IoIFP(sv_2io(sval));
1524 if (io_info == (PerlIO *) NULL)
1525 {
1526 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1527 PackageName);
1528 break;
1529 }
1530 file=PerlIO_findFILE(io_info);
1531 if (file == (FILE *) NULL)
1532 {
1533 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1534 PackageName);
1535 break;
1536 }
1537 SetImageInfoFile(info->image_info,file);
1538 break;
1539 }
1540 if (LocaleCompare(attribute,"fill") == 0)
1541 {
1542 if (info)
1543 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1544 break;
1545 }
1546 if (LocaleCompare(attribute,"font") == 0)
1547 {
1548 if (info)
1549 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1550 break;
1551 }
1552 if (LocaleCompare(attribute,"foreground") == 0)
1553 break;
1554 if (LocaleCompare(attribute,"fuzz") == 0)
1555 {
1556 if (info)
1557 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1558 QuantumRange+1.0);
1559 for ( ; image; image=image->next)
1560 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1561 QuantumRange+1.0);
1562 break;
1563 }
1564 if (info)
1565 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1566 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001567 {
1568 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001569 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001570 }
cristy4a3ce0a2013-08-03 20:06:59 +00001571 break;
1572 }
1573 case 'G':
1574 case 'g':
1575 {
1576 if (LocaleCompare(attribute,"gamma") == 0)
1577 {
1578 for ( ; image; image=image->next)
1579 image->gamma=SvNV(sval);
1580 break;
1581 }
1582 if (LocaleCompare(attribute,"gravity") == 0)
1583 {
1584 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1585 SvPV(sval,na)) : SvIV(sval);
1586 if (sp < 0)
1587 {
1588 ThrowPerlException(exception,OptionError,
1589 "UnrecognizedGravityType",SvPV(sval,na));
1590 break;
1591 }
1592 if (info)
1593 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1594 for ( ; image; image=image->next)
1595 image->gravity=(GravityType) sp;
1596 break;
1597 }
1598 if (LocaleCompare(attribute,"green-primary") == 0)
1599 {
1600 for ( ; image; image=image->next)
1601 {
1602 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1603 image->chromaticity.green_primary.x=geometry_info.rho;
1604 image->chromaticity.green_primary.y=geometry_info.sigma;
1605 if ((flags & SigmaValue) == 0)
1606 image->chromaticity.green_primary.y=
1607 image->chromaticity.green_primary.x;
1608 }
1609 break;
1610 }
1611 if (info)
1612 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1613 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001614 {
1615 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001616 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001617 }
cristy4a3ce0a2013-08-03 20:06:59 +00001618 break;
1619 }
1620 case 'I':
1621 case 'i':
1622 {
1623 if (LocaleNCompare(attribute,"index",5) == 0)
1624 {
1625 int
1626 items;
1627
1628 long
1629 index;
1630
1631 register Quantum
1632 *q;
1633
1634 CacheView
1635 *image_view;
1636
1637 for ( ; image; image=image->next)
1638 {
1639 if (image->storage_class != PseudoClass)
1640 continue;
1641 x=0;
1642 y=0;
1643 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1644 (void) items;
1645 image_view=AcquireAuthenticCacheView(image,exception);
1646 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1647 if (q != (Quantum *) NULL)
1648 {
1649 items=sscanf(SvPV(sval,na),"%ld",&index);
1650 if ((index >= 0) && (index < (ssize_t) image->colors))
1651 SetPixelIndex(image,index,q);
1652 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1653 }
1654 image_view=DestroyCacheView(image_view);
1655 }
1656 break;
1657 }
1658 if (LocaleCompare(attribute,"iterations") == 0)
1659 {
1660 iterations:
1661 for ( ; image; image=image->next)
1662 image->iterations=SvIV(sval);
1663 break;
1664 }
1665 if (LocaleCompare(attribute,"interlace") == 0)
1666 {
1667 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1668 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1669 if (sp < 0)
1670 {
1671 ThrowPerlException(exception,OptionError,
1672 "UnrecognizedInterlaceType",SvPV(sval,na));
1673 break;
1674 }
1675 if (info)
1676 info->image_info->interlace=(InterlaceType) sp;
1677 for ( ; image; image=image->next)
1678 image->interlace=(InterlaceType) sp;
1679 break;
1680 }
1681 if (info)
1682 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1683 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001684 {
1685 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001686 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001687 }
cristy4a3ce0a2013-08-03 20:06:59 +00001688 break;
1689 }
1690 case 'L':
1691 case 'l':
1692 {
1693 if (LocaleCompare(attribute,"label") == 0)
1694 {
1695 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001696 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001697 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001698 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001699 break;
1700 }
1701 if (LocaleCompare(attribute,"loop") == 0)
1702 goto iterations;
1703 if (info)
1704 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1705 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001706 {
1707 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001708 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001709 }
cristy4a3ce0a2013-08-03 20:06:59 +00001710 break;
1711 }
1712 case 'M':
1713 case 'm':
1714 {
1715 if (LocaleCompare(attribute,"magick") == 0)
1716 {
1717 if (info)
Cristyb5b1f5d2017-03-31 16:42:35 -04001718 (void) FormatLocaleString(info->image_info->filename,
1719 MagickPathExtent,"%s:",SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001720 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001721 (void) CopyMagickString(image->magick,SvPV(sval,na),
1722 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001723 break;
1724 }
1725 if (LocaleCompare(attribute,"map-limit") == 0)
1726 {
1727 MagickSizeType
1728 limit;
1729
1730 limit=MagickResourceInfinity;
1731 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1732 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1733 100.0);
1734 (void) SetMagickResourceLimit(MapResource,limit);
1735 break;
1736 }
1737 if (LocaleCompare(attribute,"mask") == 0)
1738 {
1739 Image
1740 *mask;
1741
1742 mask=(Image *) NULL;
1743 if (SvPOK(sval))
1744 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1745 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001746 SetImageMask(image,ReadPixelMask,mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001747 break;
1748 }
1749 if (LocaleCompare(attribute,"mattecolor") == 0)
1750 {
1751 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1752 exception);
1753 if (info)
Cristy8645e042016-02-03 16:35:29 -05001754 info->image_info->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001755 for ( ; image; image=image->next)
Cristy8645e042016-02-03 16:35:29 -05001756 image->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001757 break;
1758 }
1759 if (LocaleCompare(attribute,"matte") == 0)
1760 {
1761 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1762 SvPV(sval,na)) : SvIV(sval);
1763 if (sp < 0)
1764 {
1765 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1766 SvPV(sval,na));
1767 break;
1768 }
1769 for ( ; image; image=image->next)
1770 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1771 break;
1772 }
1773 if (LocaleCompare(attribute,"memory-limit") == 0)
1774 {
1775 MagickSizeType
1776 limit;
1777
1778 limit=MagickResourceInfinity;
1779 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1780 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1781 100.0);
1782 (void) SetMagickResourceLimit(MemoryResource,limit);
1783 break;
1784 }
1785 if (LocaleCompare(attribute,"monochrome") == 0)
1786 {
1787 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1788 SvPV(sval,na)) : SvIV(sval);
1789 if (sp < 0)
1790 {
1791 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1792 SvPV(sval,na));
1793 break;
1794 }
1795 if (info)
1796 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1797 for ( ; image; image=image->next)
1798 (void) SetImageType(image,BilevelType,exception);
1799 break;
1800 }
1801 if (info)
1802 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1803 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001804 {
1805 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001806 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001807 }
cristy4a3ce0a2013-08-03 20:06:59 +00001808 break;
1809 }
1810 case 'O':
1811 case 'o':
1812 {
1813 if (LocaleCompare(attribute,"option") == 0)
1814 {
1815 if (info)
1816 DefineImageOption(info->image_info,SvPV(sval,na));
1817 break;
1818 }
1819 if (LocaleCompare(attribute,"orientation") == 0)
1820 {
1821 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1822 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1823 if (sp < 0)
1824 {
1825 ThrowPerlException(exception,OptionError,
1826 "UnrecognizedOrientationType",SvPV(sval,na));
1827 break;
1828 }
1829 if (info)
1830 info->image_info->orientation=(OrientationType) sp;
1831 for ( ; image; image=image->next)
1832 image->orientation=(OrientationType) sp;
1833 break;
1834 }
1835 if (info)
1836 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1837 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001838 {
1839 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001840 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001841 }
cristy4a3ce0a2013-08-03 20:06:59 +00001842 break;
1843 }
1844 case 'P':
1845 case 'p':
1846 {
1847 if (LocaleCompare(attribute,"page") == 0)
1848 {
1849 char
1850 *geometry;
1851
1852 geometry=GetPageGeometry(SvPV(sval,na));
1853 if (info)
1854 (void) CloneString(&info->image_info->page,geometry);
1855 for ( ; image; image=image->next)
1856 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1857 geometry=(char *) RelinquishMagickMemory(geometry);
1858 break;
1859 }
1860 if (LocaleNCompare(attribute,"pixel",5) == 0)
1861 {
1862 int
1863 items;
1864
1865 PixelInfo
1866 pixel;
1867
1868 register Quantum
1869 *q;
1870
1871 CacheView
1872 *image_view;
1873
1874 for ( ; image; image=image->next)
1875 {
1876 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1877 break;
1878 x=0;
1879 y=0;
1880 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1881 (void) items;
1882 image_view=AcquireVirtualCacheView(image,exception);
1883 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1884 if (q != (Quantum *) NULL)
1885 {
1886 if ((strchr(SvPV(sval,na),',') == 0) ||
1887 (strchr(SvPV(sval,na),')') != 0))
1888 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1889 &pixel,exception);
1890 else
1891 {
1892 GetPixelInfo(image,&pixel);
1893 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1894 pixel.red=geometry_info.rho;
1895 if ((flags & SigmaValue) != 0)
1896 pixel.green=geometry_info.sigma;
1897 if ((flags & XiValue) != 0)
1898 pixel.blue=geometry_info.xi;
1899 if ((flags & PsiValue) != 0)
1900 pixel.alpha=geometry_info.psi;
1901 if ((flags & ChiValue) != 0)
1902 pixel.black=geometry_info.chi;
1903 }
1904 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1905 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1906 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1907 if (image->colorspace == CMYKColorspace)
1908 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1909 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1910 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1911 }
1912 image_view=DestroyCacheView(image_view);
1913 }
1914 break;
1915 }
1916 if (LocaleCompare(attribute,"pointsize") == 0)
1917 {
1918 if (info)
1919 {
1920 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1921 info->image_info->pointsize=geometry_info.rho;
1922 }
1923 break;
1924 }
Cristy798981a2020-02-17 12:07:15 -05001925 if (LocaleCompare(attribute,"precision") == 0)
1926 {
1927 (void) SetMagickPrecision(SvIV(sval));
1928 break;
1929 }
cristy4a3ce0a2013-08-03 20:06:59 +00001930 if (info)
1931 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1932 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001933 {
1934 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001935 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001936 }
cristy4a3ce0a2013-08-03 20:06:59 +00001937 break;
1938 }
1939 case 'Q':
1940 case 'q':
1941 {
1942 if (LocaleCompare(attribute,"quality") == 0)
1943 {
1944 if (info)
1945 info->image_info->quality=SvIV(sval);
1946 for ( ; image; image=image->next)
1947 image->quality=SvIV(sval);
1948 break;
1949 }
1950 if (info)
1951 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1952 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001953 {
1954 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001955 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001956 }
cristy4a3ce0a2013-08-03 20:06:59 +00001957 break;
1958 }
1959 case 'R':
1960 case 'r':
1961 {
cristyc0fe4752015-07-27 18:02:39 +00001962 if (LocaleCompare(attribute,"read-mask") == 0)
1963 {
1964 Image
1965 *mask;
1966
1967 mask=(Image *) NULL;
1968 if (SvPOK(sval))
1969 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1970 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001971 SetImageMask(image,ReadPixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00001972 break;
1973 }
cristy4a3ce0a2013-08-03 20:06:59 +00001974 if (LocaleCompare(attribute,"red-primary") == 0)
1975 {
1976 for ( ; image; image=image->next)
1977 {
1978 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1979 image->chromaticity.red_primary.x=geometry_info.rho;
1980 image->chromaticity.red_primary.y=geometry_info.sigma;
1981 if ((flags & SigmaValue) == 0)
1982 image->chromaticity.red_primary.y=
1983 image->chromaticity.red_primary.x;
1984 }
1985 break;
1986 }
1987 if (LocaleCompare(attribute,"render") == 0)
1988 {
1989 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1990 SvPV(sval,na)) : SvIV(sval);
1991 if (sp < 0)
1992 {
1993 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1994 SvPV(sval,na));
1995 break;
1996 }
1997 for ( ; image; image=image->next)
1998 image->rendering_intent=(RenderingIntent) sp;
1999 break;
2000 }
2001 if (LocaleCompare(attribute,"repage") == 0)
2002 {
2003 RectangleInfo
2004 geometry;
2005
2006 for ( ; image; image=image->next)
2007 {
2008 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
2009 if ((flags & WidthValue) != 0)
2010 {
2011 if ((flags & HeightValue) == 0)
2012 geometry.height=geometry.width;
2013 image->page.width=geometry.width;
2014 image->page.height=geometry.height;
2015 }
2016 if ((flags & AspectValue) != 0)
2017 {
2018 if ((flags & XValue) != 0)
2019 image->page.x+=geometry.x;
2020 if ((flags & YValue) != 0)
2021 image->page.y+=geometry.y;
2022 }
2023 else
2024 {
2025 if ((flags & XValue) != 0)
2026 {
2027 image->page.x=geometry.x;
2028 if (((flags & WidthValue) != 0) && (geometry.x > 0))
2029 image->page.width=image->columns+geometry.x;
2030 }
2031 if ((flags & YValue) != 0)
2032 {
2033 image->page.y=geometry.y;
2034 if (((flags & HeightValue) != 0) && (geometry.y > 0))
2035 image->page.height=image->rows+geometry.y;
2036 }
2037 }
2038 }
2039 break;
2040 }
2041 if (info)
2042 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2043 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002044 {
2045 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002046 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002047 }
cristy4a3ce0a2013-08-03 20:06:59 +00002048 break;
2049 }
2050 case 'S':
2051 case 's':
2052 {
2053 if (LocaleCompare(attribute,"sampling-factor") == 0)
2054 {
2055 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2056 {
2057 ThrowPerlException(exception,OptionError,"MissingGeometry",
2058 SvPV(sval,na));
2059 break;
2060 }
2061 if (info)
2062 (void) CloneString(&info->image_info->sampling_factor,
2063 SvPV(sval,na));
2064 break;
2065 }
2066 if (LocaleCompare(attribute,"scene") == 0)
2067 {
2068 for ( ; image; image=image->next)
2069 image->scene=SvIV(sval);
2070 break;
2071 }
2072 if (LocaleCompare(attribute,"server") == 0)
2073 goto display;
2074 if (LocaleCompare(attribute,"size") == 0)
2075 {
2076 if (info)
2077 {
2078 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2079 {
2080 ThrowPerlException(exception,OptionError,"MissingGeometry",
2081 SvPV(sval,na));
2082 break;
2083 }
2084 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2085 }
2086 break;
2087 }
2088 if (LocaleCompare(attribute,"stroke") == 0)
2089 {
2090 if (info)
2091 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2092 break;
2093 }
2094 if (info)
2095 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2096 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002097 {
2098 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002099 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002100 }
cristy4a3ce0a2013-08-03 20:06:59 +00002101 break;
2102 }
2103 case 'T':
2104 case 't':
2105 {
2106 if (LocaleCompare(attribute,"texture") == 0)
2107 {
2108 if (info)
2109 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2110 break;
2111 }
2112 if (LocaleCompare(attribute,"thread-limit") == 0)
2113 {
2114 MagickSizeType
2115 limit;
2116
2117 limit=MagickResourceInfinity;
2118 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2119 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2120 100.0);
2121 (void) SetMagickResourceLimit(ThreadResource,limit);
2122 break;
2123 }
2124 if (LocaleCompare(attribute,"tile-offset") == 0)
2125 {
2126 char
2127 *geometry;
2128
2129 geometry=GetPageGeometry(SvPV(sval,na));
2130 if (info)
2131 (void) CloneString(&info->image_info->page,geometry);
2132 for ( ; image; image=image->next)
2133 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2134 exception);
2135 geometry=(char *) RelinquishMagickMemory(geometry);
2136 break;
2137 }
2138 if (LocaleCompare(attribute,"time-limit") == 0)
2139 {
2140 MagickSizeType
2141 limit;
2142
2143 limit=MagickResourceInfinity;
2144 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2145 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2146 100.0);
2147 (void) SetMagickResourceLimit(TimeResource,limit);
2148 break;
2149 }
2150 if (LocaleCompare(attribute,"transparent-color") == 0)
2151 {
2152 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2153 exception);
2154 if (info)
2155 info->image_info->transparent_color=target_color;
2156 for ( ; image; image=image->next)
2157 image->transparent_color=target_color;
2158 break;
2159 }
2160 if (LocaleCompare(attribute,"type") == 0)
2161 {
2162 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2163 SvPV(sval,na)) : SvIV(sval);
2164 if (sp < 0)
2165 {
2166 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2167 SvPV(sval,na));
2168 break;
2169 }
2170 if (info)
2171 info->image_info->type=(ImageType) sp;
2172 for ( ; image; image=image->next)
2173 SetImageType(image,(ImageType) sp,exception);
2174 break;
2175 }
2176 if (info)
2177 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2178 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002179 {
2180 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002181 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002182 }
cristy4a3ce0a2013-08-03 20:06:59 +00002183 break;
2184 }
2185 case 'U':
2186 case 'u':
2187 {
2188 if (LocaleCompare(attribute,"units") == 0)
2189 {
2190 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2191 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2192 if (sp < 0)
2193 {
2194 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2195 SvPV(sval,na));
2196 break;
2197 }
2198 if (info)
2199 info->image_info->units=(ResolutionType) sp;
2200 for ( ; image; image=image->next)
2201 {
2202 ResolutionType
2203 units;
2204
2205 units=(ResolutionType) sp;
2206 if (image->units != units)
2207 switch (image->units)
2208 {
2209 case UndefinedResolution:
2210 case PixelsPerInchResolution:
2211 {
2212 if (units == PixelsPerCentimeterResolution)
2213 {
2214 image->resolution.x*=2.54;
2215 image->resolution.y*=2.54;
2216 }
2217 break;
2218 }
2219 case PixelsPerCentimeterResolution:
2220 {
2221 if (units == PixelsPerInchResolution)
2222 {
2223 image->resolution.x/=2.54;
2224 image->resolution.y/=2.54;
2225 }
2226 break;
2227 }
2228 }
2229 image->units=units;
2230 }
2231 break;
2232 }
2233 if (info)
2234 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2235 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002236 {
2237 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002238 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002239 }
cristy4a3ce0a2013-08-03 20:06:59 +00002240 break;
2241 }
2242 case 'V':
2243 case 'v':
2244 {
2245 if (LocaleCompare(attribute,"verbose") == 0)
2246 {
2247 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2248 SvPV(sval,na)) : SvIV(sval);
2249 if (sp < 0)
2250 {
2251 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2252 SvPV(sval,na));
2253 break;
2254 }
2255 if (info)
2256 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2257 break;
2258 }
cristy4a3ce0a2013-08-03 20:06:59 +00002259 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2260 {
2261 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2262 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2263 if (sp < 0)
2264 {
2265 ThrowPerlException(exception,OptionError,
2266 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2267 break;
2268 }
2269 for ( ; image; image=image->next)
2270 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2271 break;
2272 }
2273 if (info)
2274 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2275 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002276 {
2277 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002278 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002279 }
cristy4a3ce0a2013-08-03 20:06:59 +00002280 break;
2281 }
2282 case 'W':
2283 case 'w':
2284 {
2285 if (LocaleCompare(attribute,"white-point") == 0)
2286 {
2287 for ( ; image; image=image->next)
2288 {
2289 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2290 image->chromaticity.white_point.x=geometry_info.rho;
2291 image->chromaticity.white_point.y=geometry_info.sigma;
2292 if ((flags & SigmaValue) == 0)
2293 image->chromaticity.white_point.y=
2294 image->chromaticity.white_point.x;
2295 }
2296 break;
2297 }
cristyc0fe4752015-07-27 18:02:39 +00002298 if (LocaleCompare(attribute,"write-mask") == 0)
2299 {
2300 Image
2301 *mask;
2302
2303 mask=(Image *) NULL;
2304 if (SvPOK(sval))
2305 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2306 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002307 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002308 break;
2309 }
cristy4a3ce0a2013-08-03 20:06:59 +00002310 if (info)
2311 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2312 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002313 {
2314 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002315 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002316 }
cristy4a3ce0a2013-08-03 20:06:59 +00002317 break;
2318 }
2319 default:
2320 {
2321 if (info)
2322 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2323 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002324 {
2325 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002326 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002327 }
cristy4a3ce0a2013-08-03 20:06:59 +00002328 break;
2329 }
2330 }
2331}
2332
2333/*
2334%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2335% %
2336% %
2337% %
2338% S e t u p L i s t %
2339% %
2340% %
2341% %
2342%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2343%
2344% Method SetupList returns the list of all the images linked by their
2345% image->next and image->previous link lists for use with ImageMagick. If
2346% info is non-NULL, an info structure is returned in *info. If
2347% reference_vector is non-NULL,an array of SV* are returned in
2348% *reference_vector. Reference_vector is used when the images are going to be
2349% replaced with new Image*'s.
2350%
2351% The format of the SetupList routine is:
2352%
2353% Image *SetupList(SV *reference,struct PackageInfo **info,
2354% SV ***reference_vector,ExceptionInfo *exception)
2355%
2356% A description of each parameter follows:
2357%
2358% o list: a list of strings.
2359%
2360% o string: a character string.
2361%
2362% o exception: Return any errors or warnings in this structure.
2363%
2364*/
2365static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2366 SV ***reference_vector,ExceptionInfo *exception)
2367{
2368 Image
2369 *image;
2370
2371 ssize_t
2372 current,
2373 last;
2374
2375 if (reference_vector)
2376 *reference_vector=NULL;
2377 if (info)
2378 *info=NULL;
2379 current=0;
2380 last=0;
2381 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2382 if (info && (SvTYPE(reference) == SVt_PVAV))
2383 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2384 exception);
2385 return(image);
2386}
2387
2388/*
2389%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2390% %
2391% %
2392% %
2393% s t r E Q c a s e %
2394% %
2395% %
2396% %
2397%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2398%
2399% strEQcase() compares two strings and returns 0 if they are the
2400% same or if the second string runs out first. The comparison is case
2401% insensitive.
2402%
2403% The format of the strEQcase routine is:
2404%
2405% ssize_t strEQcase(const char *p,const char *q)
2406%
2407% A description of each parameter follows:
2408%
2409% o p: a character string.
2410%
2411% o q: a character string.
2412%
2413%
2414*/
2415static ssize_t strEQcase(const char *p,const char *q)
2416{
2417 char
2418 c;
2419
2420 register ssize_t
2421 i;
2422
2423 for (i=0 ; (c=(*q)) != 0; i++)
2424 {
2425 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2426 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2427 return(0);
2428 p++;
2429 q++;
2430 }
2431 return(((*q == 0) && (*p == 0)) ? i : 0);
2432}
2433
2434/*
2435%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2436% %
2437% %
2438% %
2439% I m a g e : : M a g i c k %
2440% %
2441% %
2442% %
2443%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2444%
2445%
2446*/
2447MODULE = Image::Magick PACKAGE = Image::Magick
2448
2449PROTOTYPES: ENABLE
2450
2451BOOT:
2452 MagickCoreGenesis("PerlMagick",MagickFalse);
2453 SetWarningHandler(NULL);
2454 SetErrorHandler(NULL);
2455 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2456 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2457
2458void
2459UNLOAD()
2460 PPCODE:
2461 {
2462 if (magick_registry != (SplayTreeInfo *) NULL)
2463 magick_registry=DestroySplayTree(magick_registry);
2464 MagickCoreTerminus();
2465 }
2466
2467double
2468constant(name,argument)
2469 char *name
2470 ssize_t argument
2471
2472#
2473###############################################################################
2474# #
2475# #
2476# #
2477# A n i m a t e #
2478# #
2479# #
2480# #
2481###############################################################################
2482#
2483#
2484void
2485Animate(ref,...)
2486 Image::Magick ref=NO_INIT
2487 ALIAS:
2488 AnimateImage = 1
2489 animate = 2
2490 animateimage = 3
2491 PPCODE:
2492 {
2493 ExceptionInfo
2494 *exception;
2495
2496 Image
2497 *image;
2498
2499 register ssize_t
2500 i;
2501
2502 struct PackageInfo
2503 *info,
2504 *package_info;
2505
2506 SV
2507 *perl_exception,
2508 *reference;
2509
2510 PERL_UNUSED_VAR(ref);
2511 PERL_UNUSED_VAR(ix);
2512 exception=AcquireExceptionInfo();
2513 perl_exception=newSVpv("",0);
2514 package_info=(struct PackageInfo *) NULL;
2515 if (sv_isobject(ST(0)) == 0)
2516 {
2517 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2518 PackageName);
2519 goto PerlException;
2520 }
2521 reference=SvRV(ST(0));
2522 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2523 if (image == (Image *) NULL)
2524 {
2525 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2526 PackageName);
2527 goto PerlException;
2528 }
2529 package_info=ClonePackageInfo(info,exception);
2530 if (items == 2)
2531 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2532 else
2533 if (items > 2)
2534 for (i=2; i < items; i+=2)
2535 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2536 exception);
2537 (void) AnimateImages(package_info->image_info,image,exception);
2538 (void) CatchImageException(image);
2539
2540 PerlException:
2541 if (package_info != (struct PackageInfo *) NULL)
2542 DestroyPackageInfo(package_info);
2543 InheritPerlException(exception,perl_exception);
2544 exception=DestroyExceptionInfo(exception);
2545 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2546 SvPOK_on(perl_exception);
2547 ST(0)=sv_2mortal(perl_exception);
2548 XSRETURN(1);
2549 }
2550
2551#
2552###############################################################################
2553# #
2554# #
2555# #
2556# A p p e n d #
2557# #
2558# #
2559# #
2560###############################################################################
2561#
2562#
2563void
2564Append(ref,...)
2565 Image::Magick ref=NO_INIT
2566 ALIAS:
2567 AppendImage = 1
2568 append = 2
2569 appendimage = 3
2570 PPCODE:
2571 {
2572 AV
2573 *av;
2574
2575 char
2576 *attribute;
2577
2578 ExceptionInfo
2579 *exception;
2580
2581 HV
2582 *hv;
2583
2584 Image
2585 *image;
2586
2587 register ssize_t
2588 i;
2589
2590 ssize_t
2591 stack;
2592
2593 struct PackageInfo
2594 *info;
2595
2596 SV
2597 *av_reference,
2598 *perl_exception,
2599 *reference,
2600 *rv,
2601 *sv;
2602
2603 PERL_UNUSED_VAR(ref);
2604 PERL_UNUSED_VAR(ix);
2605 exception=AcquireExceptionInfo();
2606 perl_exception=newSVpv("",0);
2607 sv=NULL;
2608 attribute=NULL;
2609 av=NULL;
2610 if (sv_isobject(ST(0)) == 0)
2611 {
2612 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2613 PackageName);
2614 goto PerlException;
2615 }
2616 reference=SvRV(ST(0));
2617 hv=SvSTASH(reference);
2618 av=newAV();
2619 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2620 SvREFCNT_dec(av);
2621 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2622 if (image == (Image *) NULL)
2623 {
2624 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2625 PackageName);
2626 goto PerlException;
2627 }
2628 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2629 /*
2630 Get options.
2631 */
2632 stack=MagickTrue;
2633 for (i=2; i < items; i+=2)
2634 {
2635 attribute=(char *) SvPV(ST(i-1),na);
2636 switch (*attribute)
2637 {
2638 case 'S':
2639 case 's':
2640 {
2641 if (LocaleCompare(attribute,"stack") == 0)
2642 {
2643 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2644 SvPV(ST(i),na));
2645 if (stack < 0)
2646 {
2647 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2648 SvPV(ST(i),na));
2649 return;
2650 }
2651 break;
2652 }
2653 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2654 attribute);
2655 break;
2656 }
2657 default:
2658 {
2659 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2660 attribute);
2661 break;
2662 }
2663 }
2664 }
2665 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2666 if (image == (Image *) NULL)
2667 goto PerlException;
2668 for ( ; image; image=image->next)
2669 {
2670 AddImageToRegistry(sv,image);
2671 rv=newRV(sv);
2672 av_push(av,sv_bless(rv,hv));
2673 SvREFCNT_dec(sv);
2674 }
2675 exception=DestroyExceptionInfo(exception);
2676 ST(0)=av_reference;
2677 SvREFCNT_dec(perl_exception);
2678 XSRETURN(1);
2679
2680 PerlException:
2681 InheritPerlException(exception,perl_exception);
2682 exception=DestroyExceptionInfo(exception);
2683 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2684 SvPOK_on(perl_exception);
2685 ST(0)=sv_2mortal(perl_exception);
2686 XSRETURN(1);
2687 }
2688
2689#
2690###############################################################################
2691# #
2692# #
2693# #
2694# A v e r a g e #
2695# #
2696# #
2697# #
2698###############################################################################
2699#
2700#
2701void
2702Average(ref)
2703 Image::Magick ref=NO_INIT
2704 ALIAS:
2705 AverageImage = 1
2706 average = 2
2707 averageimage = 3
2708 PPCODE:
2709 {
2710 AV
2711 *av;
2712
2713 char
2714 *p;
2715
2716 ExceptionInfo
2717 *exception;
2718
2719 HV
2720 *hv;
2721
2722 Image
2723 *image;
2724
2725 struct PackageInfo
2726 *info;
2727
2728 SV
2729 *perl_exception,
2730 *reference,
2731 *rv,
2732 *sv;
2733
2734 PERL_UNUSED_VAR(ref);
2735 PERL_UNUSED_VAR(ix);
2736 exception=AcquireExceptionInfo();
2737 perl_exception=newSVpv("",0);
2738 sv=NULL;
2739 if (sv_isobject(ST(0)) == 0)
2740 {
2741 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2742 PackageName);
2743 goto PerlException;
2744 }
2745 reference=SvRV(ST(0));
2746 hv=SvSTASH(reference);
2747 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2748 if (image == (Image *) NULL)
2749 {
2750 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2751 PackageName);
2752 goto PerlException;
2753 }
2754 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2755 if (image == (Image *) NULL)
2756 goto PerlException;
2757 /*
2758 Create blessed Perl array for the returned image.
2759 */
2760 av=newAV();
2761 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2762 SvREFCNT_dec(av);
2763 AddImageToRegistry(sv,image);
2764 rv=newRV(sv);
2765 av_push(av,sv_bless(rv,hv));
2766 SvREFCNT_dec(sv);
2767 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002768 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2769 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002770 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2771 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002772 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002773 SetImageInfo(info->image_info,0,exception);
2774 exception=DestroyExceptionInfo(exception);
2775 SvREFCNT_dec(perl_exception);
2776 XSRETURN(1);
2777
2778 PerlException:
2779 InheritPerlException(exception,perl_exception);
2780 exception=DestroyExceptionInfo(exception);
2781 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2782 SvPOK_on(perl_exception);
2783 ST(0)=sv_2mortal(perl_exception);
2784 XSRETURN(1);
2785 }
2786
2787#
2788###############################################################################
2789# #
2790# #
2791# #
2792# B l o b T o I m a g e #
2793# #
2794# #
2795# #
2796###############################################################################
2797#
2798#
2799void
2800BlobToImage(ref,...)
2801 Image::Magick ref=NO_INIT
2802 ALIAS:
2803 BlobToImage = 1
2804 blobtoimage = 2
2805 blobto = 3
2806 PPCODE:
2807 {
2808 AV
2809 *av;
2810
2811 char
2812 **keep,
2813 **list;
2814
2815 ExceptionInfo
2816 *exception;
2817
2818 HV
2819 *hv;
2820
2821 Image
2822 *image;
2823
2824 register char
2825 **p;
2826
2827 register ssize_t
2828 i;
2829
2830 ssize_t
2831 ac,
2832 n,
2833 number_images;
2834
2835 STRLEN
2836 *length;
2837
2838 struct PackageInfo
2839 *info;
2840
2841 SV
2842 *perl_exception,
2843 *reference,
2844 *rv,
2845 *sv;
2846
2847 PERL_UNUSED_VAR(ref);
2848 PERL_UNUSED_VAR(ix);
2849 exception=AcquireExceptionInfo();
2850 perl_exception=newSVpv("",0);
2851 sv=NULL;
2852 number_images=0;
2853 ac=(items < 2) ? 1 : items-1;
2854 length=(STRLEN *) NULL;
2855 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2856 if (list == (char **) NULL)
2857 {
2858 ThrowPerlException(exception,ResourceLimitError,
2859 "MemoryAllocationFailed",PackageName);
2860 goto PerlException;
2861 }
2862 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2863 if (length == (STRLEN *) NULL)
2864 {
2865 ThrowPerlException(exception,ResourceLimitError,
2866 "MemoryAllocationFailed",PackageName);
2867 goto PerlException;
2868 }
2869 if (sv_isobject(ST(0)) == 0)
2870 {
2871 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2872 PackageName);
2873 goto PerlException;
2874 }
2875 reference=SvRV(ST(0));
2876 hv=SvSTASH(reference);
2877 if (SvTYPE(reference) != SVt_PVAV)
2878 {
2879 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2880 PackageName);
2881 goto PerlException;
2882 }
2883 av=(AV *) reference;
2884 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2885 exception);
2886 n=1;
2887 if (items <= 1)
2888 {
2889 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2890 goto PerlException;
2891 }
2892 for (n=0, i=0; i < ac; i++)
2893 {
2894 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2895 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2896 {
2897 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2898 continue;
2899 }
2900 n++;
2901 }
2902 list[n]=(char *) NULL;
2903 keep=list;
2904 for (i=number_images=0; i < n; i++)
2905 {
2906 image=BlobToImage(info->image_info,list[i],length[i],exception);
2907 if (image == (Image *) NULL)
2908 break;
2909 for ( ; image; image=image->next)
2910 {
2911 AddImageToRegistry(sv,image);
2912 rv=newRV(sv);
2913 av_push(av,sv_bless(rv,hv));
2914 SvREFCNT_dec(sv);
2915 number_images++;
2916 }
2917 }
2918 /*
2919 Free resources.
2920 */
2921 for (i=0; i < n; i++)
2922 if (list[i] != (char *) NULL)
2923 for (p=keep; list[i] != *p++; )
2924 if (*p == (char *) NULL)
2925 {
2926 list[i]=(char *) RelinquishMagickMemory(list[i]);
2927 break;
2928 }
2929
2930 PerlException:
2931 if (list)
2932 list=(char **) RelinquishMagickMemory(list);
2933 if (length)
2934 length=(STRLEN *) RelinquishMagickMemory(length);
2935 InheritPerlException(exception,perl_exception);
2936 exception=DestroyExceptionInfo(exception);
2937 sv_setiv(perl_exception,(IV) number_images);
2938 SvPOK_on(perl_exception);
2939 ST(0)=sv_2mortal(perl_exception);
2940 XSRETURN(1);
2941 }
2942
2943#
2944###############################################################################
2945# #
2946# #
2947# #
2948# C h a n n e l F x #
2949# #
2950# #
2951# #
2952###############################################################################
2953#
2954#
2955void
2956ChannelFx(ref,...)
2957 Image::Magick ref=NO_INIT
2958 ALIAS:
2959 ChannelFxImage = 1
2960 channelfx = 2
2961 channelfximage = 3
2962 PPCODE:
2963 {
2964 AV
2965 *av;
2966
2967 char
2968 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002969 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002970
2971 ChannelType
2972 channel,
2973 channel_mask;
2974
2975 ExceptionInfo
2976 *exception;
2977
2978 HV
2979 *hv;
2980
2981 Image
2982 *image;
2983
2984 register ssize_t
2985 i;
2986
2987 struct PackageInfo
2988 *info;
2989
2990 SV
2991 *av_reference,
2992 *perl_exception,
2993 *reference,
2994 *rv,
2995 *sv;
2996
2997 PERL_UNUSED_VAR(ref);
2998 PERL_UNUSED_VAR(ix);
2999 exception=AcquireExceptionInfo();
3000 perl_exception=newSVpv("",0);
3001 sv=NULL;
3002 attribute=NULL;
3003 av=NULL;
3004 if (sv_isobject(ST(0)) == 0)
3005 {
3006 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3007 PackageName);
3008 goto PerlException;
3009 }
3010 reference=SvRV(ST(0));
3011 hv=SvSTASH(reference);
3012 av=newAV();
3013 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3014 SvREFCNT_dec(av);
3015 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3016 if (image == (Image *) NULL)
3017 {
3018 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3019 PackageName);
3020 goto PerlException;
3021 }
3022 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3023 /*
3024 Get options.
3025 */
3026 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00003027 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003028 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00003029 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003030 else
3031 for (i=2; i < items; i+=2)
3032 {
3033 attribute=(char *) SvPV(ST(i-1),na);
3034 switch (*attribute)
3035 {
3036 case 'C':
3037 case 'c':
3038 {
3039 if (LocaleCompare(attribute,"channel") == 0)
3040 {
3041 ssize_t
3042 option;
3043
3044 option=ParseChannelOption(SvPV(ST(i),na));
3045 if (option < 0)
3046 {
3047 ThrowPerlException(exception,OptionError,
3048 "UnrecognizedType",SvPV(ST(i),na));
3049 return;
3050 }
3051 channel=(ChannelType) option;
3052 break;
3053 }
3054 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3055 attribute);
3056 break;
3057 }
3058 case 'E':
3059 case 'e':
3060 {
3061 if (LocaleCompare(attribute,"expression") == 0)
3062 {
3063 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00003064 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003065 break;
3066 }
3067 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3068 attribute);
3069 break;
3070 }
3071 default:
3072 {
3073 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3074 attribute);
3075 break;
3076 }
3077 }
3078 }
3079 channel_mask=SetImageChannelMask(image,channel);
3080 image=ChannelFxImage(image,expression,exception);
3081 if (image != (Image *) NULL)
3082 (void) SetImageChannelMask(image,channel_mask);
3083 if (image == (Image *) NULL)
3084 goto PerlException;
3085 for ( ; image; image=image->next)
3086 {
3087 AddImageToRegistry(sv,image);
3088 rv=newRV(sv);
3089 av_push(av,sv_bless(rv,hv));
3090 SvREFCNT_dec(sv);
3091 }
3092 exception=DestroyExceptionInfo(exception);
3093 ST(0)=av_reference;
3094 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3095 XSRETURN(1);
3096
3097 PerlException:
3098 InheritPerlException(exception,perl_exception);
3099 exception=DestroyExceptionInfo(exception);
3100 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3101 SvPOK_on(perl_exception);
3102 ST(0)=sv_2mortal(perl_exception);
3103 XSRETURN(1);
3104 }
3105
3106#
3107###############################################################################
3108# #
3109# #
3110# #
3111# C l o n e #
3112# #
3113# #
3114# #
3115###############################################################################
3116#
3117#
3118void
3119Clone(ref)
3120 Image::Magick ref=NO_INIT
3121 ALIAS:
3122 CopyImage = 1
3123 copy = 2
3124 copyimage = 3
3125 CloneImage = 4
3126 clone = 5
3127 cloneimage = 6
3128 Clone = 7
3129 PPCODE:
3130 {
3131 AV
3132 *av;
3133
3134 ExceptionInfo
3135 *exception;
3136
3137 HV
3138 *hv;
3139
3140 Image
3141 *clone,
3142 *image;
3143
3144 struct PackageInfo
3145 *info;
3146
3147 SV
3148 *perl_exception,
3149 *reference,
3150 *rv,
3151 *sv;
3152
3153 PERL_UNUSED_VAR(ref);
3154 PERL_UNUSED_VAR(ix);
3155 exception=AcquireExceptionInfo();
3156 perl_exception=newSVpv("",0);
3157 sv=NULL;
3158 if (sv_isobject(ST(0)) == 0)
3159 {
3160 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3161 PackageName);
3162 goto PerlException;
3163 }
3164 reference=SvRV(ST(0));
3165 hv=SvSTASH(reference);
3166 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3167 if (image == (Image *) NULL)
3168 {
3169 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3170 PackageName);
3171 goto PerlException;
3172 }
3173 /*
3174 Create blessed Perl array for the returned image.
3175 */
3176 av=newAV();
3177 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3178 SvREFCNT_dec(av);
3179 for ( ; image; image=image->next)
3180 {
3181 clone=CloneImage(image,0,0,MagickTrue,exception);
3182 if (clone == (Image *) NULL)
3183 break;
3184 AddImageToRegistry(sv,clone);
3185 rv=newRV(sv);
3186 av_push(av,sv_bless(rv,hv));
3187 SvREFCNT_dec(sv);
3188 }
3189 exception=DestroyExceptionInfo(exception);
3190 SvREFCNT_dec(perl_exception);
3191 XSRETURN(1);
3192
3193 PerlException:
3194 InheritPerlException(exception,perl_exception);
3195 exception=DestroyExceptionInfo(exception);
3196 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3197 SvPOK_on(perl_exception);
3198 ST(0)=sv_2mortal(perl_exception);
3199 XSRETURN(1);
3200 }
3201
3202#
3203###############################################################################
3204# #
3205# #
3206# #
3207# C L O N E #
3208# #
3209# #
3210# #
3211###############################################################################
3212#
3213#
3214void
3215CLONE(ref,...)
3216 SV *ref;
3217 CODE:
3218 {
3219 PERL_UNUSED_VAR(ref);
3220 if (magick_registry != (SplayTreeInfo *) NULL)
3221 {
3222 register Image
3223 *p;
3224
3225 ResetSplayTreeIterator(magick_registry);
3226 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3227 while (p != (Image *) NULL)
3228 {
3229 ReferenceImage(p);
3230 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3231 }
3232 }
3233 }
3234
3235#
3236###############################################################################
3237# #
3238# #
3239# #
3240# C o a l e s c e #
3241# #
3242# #
3243# #
3244###############################################################################
3245#
3246#
3247void
3248Coalesce(ref)
3249 Image::Magick ref=NO_INIT
3250 ALIAS:
3251 CoalesceImage = 1
3252 coalesce = 2
3253 coalesceimage = 3
3254 PPCODE:
3255 {
3256 AV
3257 *av;
3258
3259 ExceptionInfo
3260 *exception;
3261
3262 HV
3263 *hv;
3264
3265 Image
3266 *image;
3267
3268 struct PackageInfo
3269 *info;
3270
3271 SV
3272 *av_reference,
3273 *perl_exception,
3274 *reference,
3275 *rv,
3276 *sv;
3277
3278 PERL_UNUSED_VAR(ref);
3279 PERL_UNUSED_VAR(ix);
3280 exception=AcquireExceptionInfo();
3281 perl_exception=newSVpv("",0);
3282 sv=NULL;
3283 if (sv_isobject(ST(0)) == 0)
3284 {
3285 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3286 PackageName);
3287 goto PerlException;
3288 }
3289 reference=SvRV(ST(0));
3290 hv=SvSTASH(reference);
3291 av=newAV();
3292 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3293 SvREFCNT_dec(av);
3294 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3295 if (image == (Image *) NULL)
3296 {
3297 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3298 PackageName);
3299 goto PerlException;
3300 }
3301 image=CoalesceImages(image,exception);
3302 if (image == (Image *) NULL)
3303 goto PerlException;
3304 for ( ; image; image=image->next)
3305 {
3306 AddImageToRegistry(sv,image);
3307 rv=newRV(sv);
3308 av_push(av,sv_bless(rv,hv));
3309 SvREFCNT_dec(sv);
3310 }
3311 exception=DestroyExceptionInfo(exception);
3312 ST(0)=av_reference;
3313 SvREFCNT_dec(perl_exception);
3314 XSRETURN(1);
3315
3316 PerlException:
3317 InheritPerlException(exception,perl_exception);
3318 exception=DestroyExceptionInfo(exception);
3319 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3320 SvPOK_on(perl_exception);
3321 ST(0)=sv_2mortal(perl_exception);
3322 XSRETURN(1);
3323 }
3324
3325#
3326###############################################################################
3327# #
3328# #
3329# #
3330# C o m p a r e #
3331# #
3332# #
3333# #
3334###############################################################################
3335#
3336#
3337void
3338Compare(ref,...)
3339 Image::Magick ref=NO_INIT
3340 ALIAS:
3341 CompareImages = 1
3342 compare = 2
3343 compareimage = 3
3344 PPCODE:
3345 {
3346 AV
3347 *av;
3348
3349 char
3350 *attribute;
3351
3352 double
3353 distortion;
3354
3355 ExceptionInfo
3356 *exception;
3357
3358 HV
3359 *hv;
3360
3361 Image
3362 *difference_image,
3363 *image,
3364 *reconstruct_image;
3365
3366 MetricType
3367 metric;
3368
3369 register ssize_t
3370 i;
3371
3372 ssize_t
3373 option;
3374
3375 struct PackageInfo
3376 *info;
3377
3378 SV
3379 *av_reference,
3380 *perl_exception,
3381 *reference,
3382 *rv,
3383 *sv;
3384
3385 PERL_UNUSED_VAR(ref);
3386 PERL_UNUSED_VAR(ix);
3387 exception=AcquireExceptionInfo();
3388 perl_exception=newSVpv("",0);
3389 sv=NULL;
3390 av=NULL;
3391 attribute=NULL;
3392 if (sv_isobject(ST(0)) == 0)
3393 {
3394 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3395 PackageName);
3396 goto PerlException;
3397 }
3398 reference=SvRV(ST(0));
3399 hv=SvSTASH(reference);
3400 av=newAV();
3401 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3402 SvREFCNT_dec(av);
3403 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3404 if (image == (Image *) NULL)
3405 {
3406 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3407 PackageName);
3408 goto PerlException;
3409 }
3410 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3411 /*
3412 Get attribute.
3413 */
3414 reconstruct_image=image;
3415 metric=RootMeanSquaredErrorMetric;
3416 for (i=2; i < items; i+=2)
3417 {
3418 attribute=(char *) SvPV(ST(i-1),na);
3419 switch (*attribute)
3420 {
3421 case 'C':
3422 case 'c':
3423 {
3424 if (LocaleCompare(attribute,"channel") == 0)
3425 {
3426 ssize_t
3427 option;
3428
3429 option=ParseChannelOption(SvPV(ST(i),na));
3430 if (option < 0)
3431 {
3432 ThrowPerlException(exception,OptionError,
3433 "UnrecognizedType",SvPV(ST(i),na));
3434 return;
3435 }
cristybcd59342015-06-07 14:07:19 +00003436 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003437 break;
3438 }
3439 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3440 attribute);
3441 break;
3442 }
3443 case 'F':
3444 case 'f':
3445 {
3446 if (LocaleCompare(attribute,"fuzz") == 0)
3447 {
3448 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3449 break;
3450 }
3451 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3452 attribute);
3453 break;
3454 }
3455 case 'I':
3456 case 'i':
3457 {
3458 if (LocaleCompare(attribute,"image") == 0)
3459 {
3460 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3461 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3462 break;
3463 }
3464 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3465 attribute);
3466 break;
3467 }
3468 case 'M':
3469 case 'm':
3470 {
3471 if (LocaleCompare(attribute,"metric") == 0)
3472 {
3473 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3474 SvPV(ST(i),na));
3475 if (option < 0)
3476 {
3477 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3478 SvPV(ST(i),na));
3479 break;
3480 }
3481 metric=(MetricType) option;
3482 break;
3483 }
3484 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3485 attribute);
3486 break;
3487 }
3488 default:
3489 {
3490 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3491 attribute);
3492 break;
3493 }
3494 }
3495 }
3496 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3497 exception);
3498 if (difference_image != (Image *) NULL)
3499 {
3500 difference_image->error.mean_error_per_pixel=distortion;
3501 AddImageToRegistry(sv,difference_image);
3502 rv=newRV(sv);
3503 av_push(av,sv_bless(rv,hv));
3504 SvREFCNT_dec(sv);
3505 }
3506 exception=DestroyExceptionInfo(exception);
3507 ST(0)=av_reference;
3508 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3509 XSRETURN(1);
3510
3511 PerlException:
3512 InheritPerlException(exception,perl_exception);
3513 exception=DestroyExceptionInfo(exception);
3514 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3515 SvPOK_on(perl_exception);
3516 ST(0)=sv_2mortal(perl_exception);
3517 XSRETURN(1);
3518 }
3519
3520#
3521###############################################################################
3522# #
3523# #
3524# #
cristy15655332013-10-06 00:27:33 +00003525# C o m p l e x I m a g e s #
3526# #
3527# #
3528# #
3529###############################################################################
3530#
3531#
3532void
3533ComplexImages(ref)
3534 Image::Magick ref=NO_INIT
3535 ALIAS:
3536 ComplexImages = 1
3537 compleximages = 2
3538 PPCODE:
3539 {
3540 AV
3541 *av;
3542
3543 char
3544 *attribute,
3545 *p;
3546
cristyfa21e9e2013-10-07 10:37:38 +00003547 ComplexOperator
3548 op;
3549
cristy15655332013-10-06 00:27:33 +00003550 ExceptionInfo
3551 *exception;
3552
3553 HV
3554 *hv;
3555
3556 Image
3557 *image;
3558
cristy15655332013-10-06 00:27:33 +00003559 register ssize_t
3560 i;
3561
3562 struct PackageInfo
3563 *info;
3564
3565 SV
3566 *perl_exception,
3567 *reference,
3568 *rv,
3569 *sv;
3570
3571 PERL_UNUSED_VAR(ref);
3572 PERL_UNUSED_VAR(ix);
3573 exception=AcquireExceptionInfo();
3574 perl_exception=newSVpv("",0);
3575 sv=NULL;
3576 if (sv_isobject(ST(0)) == 0)
3577 {
3578 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3579 PackageName);
3580 goto PerlException;
3581 }
3582 reference=SvRV(ST(0));
3583 hv=SvSTASH(reference);
3584 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3585 if (image == (Image *) NULL)
3586 {
3587 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3588 PackageName);
3589 goto PerlException;
3590 }
cristyfd168722013-10-07 15:59:31 +00003591 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003592 if (items == 2)
3593 {
3594 ssize_t
3595 in;
3596
3597 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3598 SvPV(ST(1),na));
3599 if (in < 0)
3600 {
3601 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3602 SvPV(ST(1),na));
3603 return;
3604 }
cristyfa21e9e2013-10-07 10:37:38 +00003605 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003606 }
3607 else
3608 for (i=2; i < items; i+=2)
3609 {
3610 attribute=(char *) SvPV(ST(i-1),na);
3611 switch (*attribute)
3612 {
3613 case 'O':
3614 case 'o':
3615 {
3616 if (LocaleCompare(attribute,"operator") == 0)
3617 {
3618 ssize_t
3619 in;
3620
3621 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3622 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3623 if (in < 0)
3624 {
3625 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3626 SvPV(ST(i),na));
3627 return;
3628 }
cristyfa21e9e2013-10-07 10:37:38 +00003629 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003630 break;
3631 }
3632 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3633 attribute);
3634 break;
3635 }
3636 default:
3637 {
3638 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3639 attribute);
3640 break;
3641 }
3642 }
3643 }
3644 image=ComplexImages(image,op,exception);
3645 if (image == (Image *) NULL)
3646 goto PerlException;
3647 /*
3648 Create blessed Perl array for the returned image.
3649 */
3650 av=newAV();
3651 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3652 SvREFCNT_dec(av);
3653 AddImageToRegistry(sv,image);
3654 rv=newRV(sv);
3655 av_push(av,sv_bless(rv,hv));
3656 SvREFCNT_dec(sv);
3657 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003658 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3659 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003660 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3661 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003662 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003663 SetImageInfo(info->image_info,0,exception);
3664 exception=DestroyExceptionInfo(exception);
3665 SvREFCNT_dec(perl_exception);
3666 XSRETURN(1);
3667
3668 PerlException:
3669 InheritPerlException(exception,perl_exception);
3670 exception=DestroyExceptionInfo(exception);
3671 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3672 SvPOK_on(perl_exception);
3673 ST(0)=sv_2mortal(perl_exception);
3674 XSRETURN(1);
3675 }
3676
3677#
3678###############################################################################
3679# #
3680# #
3681# #
cristy4a3ce0a2013-08-03 20:06:59 +00003682# C o m p a r e L a y e r s #
3683# #
3684# #
3685# #
3686###############################################################################
3687#
3688#
3689void
3690CompareLayers(ref)
3691 Image::Magick ref=NO_INIT
3692 ALIAS:
3693 CompareImagesLayers = 1
3694 comparelayers = 2
3695 compareimagelayers = 3
3696 PPCODE:
3697 {
3698 AV
3699 *av;
3700
3701 char
3702 *attribute;
3703
3704 ExceptionInfo
3705 *exception;
3706
3707 HV
3708 *hv;
3709
3710 Image
3711 *image;
3712
3713 LayerMethod
3714 method;
3715
3716 register ssize_t
3717 i;
3718
3719 ssize_t
3720 option;
3721
3722 struct PackageInfo
3723 *info;
3724
3725 SV
3726 *av_reference,
3727 *perl_exception,
3728 *reference,
3729 *rv,
3730 *sv;
3731
3732 PERL_UNUSED_VAR(ref);
3733 PERL_UNUSED_VAR(ix);
3734 exception=AcquireExceptionInfo();
3735 perl_exception=newSVpv("",0);
3736 sv=NULL;
3737 if (sv_isobject(ST(0)) == 0)
3738 {
3739 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3740 PackageName);
3741 goto PerlException;
3742 }
3743 reference=SvRV(ST(0));
3744 hv=SvSTASH(reference);
3745 av=newAV();
3746 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3747 SvREFCNT_dec(av);
3748 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3749 if (image == (Image *) NULL)
3750 {
3751 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3752 PackageName);
3753 goto PerlException;
3754 }
3755 method=CompareAnyLayer;
3756 for (i=2; i < items; i+=2)
3757 {
3758 attribute=(char *) SvPV(ST(i-1),na);
3759 switch (*attribute)
3760 {
3761 case 'M':
3762 case 'm':
3763 {
3764 if (LocaleCompare(attribute,"method") == 0)
3765 {
3766 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3767 SvPV(ST(i),na));
3768 if (option < 0)
3769 {
3770 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3771 SvPV(ST(i),na));
3772 break;
3773 }
3774 method=(LayerMethod) option;
3775 break;
3776 }
3777 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3778 attribute);
3779 break;
3780 }
3781 default:
3782 {
3783 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3784 attribute);
3785 break;
3786 }
3787 }
3788 }
3789 image=CompareImagesLayers(image,method,exception);
3790 if (image == (Image *) NULL)
3791 goto PerlException;
3792 for ( ; image; image=image->next)
3793 {
3794 AddImageToRegistry(sv,image);
3795 rv=newRV(sv);
3796 av_push(av,sv_bless(rv,hv));
3797 SvREFCNT_dec(sv);
3798 }
3799 exception=DestroyExceptionInfo(exception);
3800 ST(0)=av_reference;
3801 SvREFCNT_dec(perl_exception);
3802 XSRETURN(1);
3803
3804 PerlException:
3805 InheritPerlException(exception,perl_exception);
3806 exception=DestroyExceptionInfo(exception);
3807 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3808 SvPOK_on(perl_exception);
3809 ST(0)=sv_2mortal(perl_exception);
3810 XSRETURN(1);
3811 }
3812
3813#
3814###############################################################################
3815# #
3816# #
3817# #
3818# D e s t r o y #
3819# #
3820# #
3821# #
3822###############################################################################
3823#
3824#
3825void
3826DESTROY(ref)
3827 Image::Magick ref=NO_INIT
3828 PPCODE:
3829 {
3830 SV
3831 *reference;
3832
3833 PERL_UNUSED_VAR(ref);
3834 if (sv_isobject(ST(0)) == 0)
3835 croak("ReferenceIsNotMyType");
3836 reference=SvRV(ST(0));
3837 switch (SvTYPE(reference))
3838 {
3839 case SVt_PVAV:
3840 {
3841 char
cristy151b66d2015-04-15 10:50:31 +00003842 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003843
3844 const SV
3845 *key;
3846
3847 HV
3848 *hv;
3849
3850 GV
3851 **gvp;
3852
3853 struct PackageInfo
3854 *info;
3855
3856 SV
3857 *sv;
3858
3859 /*
3860 Array (AV *) reference
3861 */
cristy151b66d2015-04-15 10:50:31 +00003862 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003863 XS_VERSION,reference);
3864 hv=gv_stashpv(PackageName, FALSE);
3865 if (!hv)
3866 break;
3867 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3868 if (!gvp)
3869 break;
3870 sv=GvSV(*gvp);
3871 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3872 {
3873 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3874 DestroyPackageInfo(info);
3875 }
3876 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3877 (void) key;
3878 break;
3879 }
3880 case SVt_PVMG:
3881 {
3882 Image
3883 *image;
3884
3885 /*
3886 Blessed scalar = (Image *) SvIV(reference)
3887 */
3888 image=INT2PTR(Image *,SvIV(reference));
3889 if (image != (Image *) NULL)
3890 DeleteImageFromRegistry(reference,image);
3891 break;
3892 }
3893 default:
3894 break;
3895 }
3896 }
3897
3898#
3899###############################################################################
3900# #
3901# #
3902# #
3903# D i s p l a y #
3904# #
3905# #
3906# #
3907###############################################################################
3908#
3909#
3910void
3911Display(ref,...)
3912 Image::Magick ref=NO_INIT
3913 ALIAS:
3914 DisplayImage = 1
3915 display = 2
3916 displayimage = 3
3917 PPCODE:
3918 {
3919 ExceptionInfo
3920 *exception;
3921
3922 Image
3923 *image;
3924
3925 register ssize_t
3926 i;
3927
3928 struct PackageInfo
3929 *info,
3930 *package_info;
3931
3932 SV
3933 *perl_exception,
3934 *reference;
3935
3936 PERL_UNUSED_VAR(ref);
3937 PERL_UNUSED_VAR(ix);
3938 exception=AcquireExceptionInfo();
3939 perl_exception=newSVpv("",0);
3940 package_info=(struct PackageInfo *) NULL;
3941 if (sv_isobject(ST(0)) == 0)
3942 {
3943 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3944 PackageName);
3945 goto PerlException;
3946 }
3947 reference=SvRV(ST(0));
3948 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3949 if (image == (Image *) NULL)
3950 {
3951 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3952 PackageName);
3953 goto PerlException;
3954 }
3955 package_info=ClonePackageInfo(info,exception);
3956 if (items == 2)
3957 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3958 else
3959 if (items > 2)
3960 for (i=2; i < items; i+=2)
3961 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3962 exception);
3963 (void) DisplayImages(package_info->image_info,image,exception);
3964 (void) CatchImageException(image);
3965
3966 PerlException:
3967 if (package_info != (struct PackageInfo *) NULL)
3968 DestroyPackageInfo(package_info);
3969 InheritPerlException(exception,perl_exception);
3970 exception=DestroyExceptionInfo(exception);
3971 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3972 SvPOK_on(perl_exception);
3973 ST(0)=sv_2mortal(perl_exception);
3974 XSRETURN(1);
3975 }
3976
3977#
3978###############################################################################
3979# #
3980# #
3981# #
3982# E v a l u a t e I m a g e s #
3983# #
3984# #
3985# #
3986###############################################################################
3987#
3988#
3989void
3990EvaluateImages(ref)
3991 Image::Magick ref=NO_INIT
3992 ALIAS:
3993 EvaluateImages = 1
3994 evaluateimages = 2
3995 PPCODE:
3996 {
3997 AV
3998 *av;
3999
4000 char
4001 *attribute,
4002 *p;
4003
4004 ExceptionInfo
4005 *exception;
4006
4007 HV
4008 *hv;
4009
4010 Image
4011 *image;
4012
4013 MagickEvaluateOperator
4014 op;
4015
4016 register ssize_t
4017 i;
4018
4019 struct PackageInfo
4020 *info;
4021
4022 SV
4023 *perl_exception,
4024 *reference,
4025 *rv,
4026 *sv;
4027
4028 PERL_UNUSED_VAR(ref);
4029 PERL_UNUSED_VAR(ix);
4030 exception=AcquireExceptionInfo();
4031 perl_exception=newSVpv("",0);
4032 sv=NULL;
4033 if (sv_isobject(ST(0)) == 0)
4034 {
4035 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4036 PackageName);
4037 goto PerlException;
4038 }
4039 reference=SvRV(ST(0));
4040 hv=SvSTASH(reference);
4041 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4042 if (image == (Image *) NULL)
4043 {
4044 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4045 PackageName);
4046 goto PerlException;
4047 }
4048 op=MeanEvaluateOperator;
4049 if (items == 2)
4050 {
4051 ssize_t
4052 in;
4053
4054 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
4055 SvPV(ST(1),na));
4056 if (in < 0)
4057 {
4058 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4059 SvPV(ST(1),na));
4060 return;
4061 }
4062 op=(MagickEvaluateOperator) in;
4063 }
4064 else
4065 for (i=2; i < items; i+=2)
4066 {
4067 attribute=(char *) SvPV(ST(i-1),na);
4068 switch (*attribute)
4069 {
4070 case 'O':
4071 case 'o':
4072 {
4073 if (LocaleCompare(attribute,"operator") == 0)
4074 {
4075 ssize_t
4076 in;
4077
4078 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4079 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4080 if (in < 0)
4081 {
4082 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4083 SvPV(ST(i),na));
4084 return;
4085 }
4086 op=(MagickEvaluateOperator) in;
4087 break;
4088 }
4089 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4090 attribute);
4091 break;
4092 }
4093 default:
4094 {
4095 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4096 attribute);
4097 break;
4098 }
4099 }
4100 }
4101 image=EvaluateImages(image,op,exception);
4102 if (image == (Image *) NULL)
4103 goto PerlException;
4104 /*
4105 Create blessed Perl array for the returned image.
4106 */
4107 av=newAV();
4108 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4109 SvREFCNT_dec(av);
4110 AddImageToRegistry(sv,image);
4111 rv=newRV(sv);
4112 av_push(av,sv_bless(rv,hv));
4113 SvREFCNT_dec(sv);
4114 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004115 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4116 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004117 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4118 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004119 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004120 SetImageInfo(info->image_info,0,exception);
4121 exception=DestroyExceptionInfo(exception);
4122 SvREFCNT_dec(perl_exception);
4123 XSRETURN(1);
4124
4125 PerlException:
4126 InheritPerlException(exception,perl_exception);
4127 exception=DestroyExceptionInfo(exception);
4128 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4129 SvPOK_on(perl_exception);
4130 ST(0)=sv_2mortal(perl_exception);
4131 XSRETURN(1);
4132 }
4133
4134#
4135###############################################################################
4136# #
4137# #
4138# #
4139# F e a t u r e s #
4140# #
4141# #
4142# #
4143###############################################################################
4144#
4145#
4146void
4147Features(ref,...)
4148 Image::Magick ref=NO_INIT
4149 ALIAS:
4150 FeaturesImage = 1
4151 features = 2
4152 featuresimage = 3
4153 PPCODE:
4154 {
4155#define ChannelFeatures(channel,direction) \
4156{ \
Cristyb1710fe2017-02-11 13:51:48 -05004157 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004158 channel_features[channel].angular_second_moment[direction]); \
4159 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004160 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004161 channel_features[channel].contrast[direction]); \
4162 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004163 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004164 channel_features[channel].contrast[direction]); \
4165 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004166 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004167 channel_features[channel].variance_sum_of_squares[direction]); \
4168 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004169 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004170 channel_features[channel].inverse_difference_moment[direction]); \
4171 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004172 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004173 channel_features[channel].sum_average[direction]); \
4174 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004175 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004176 channel_features[channel].sum_variance[direction]); \
4177 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004178 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004179 channel_features[channel].sum_entropy[direction]); \
4180 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004181 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004182 channel_features[channel].entropy[direction]); \
4183 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004184 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004185 channel_features[channel].difference_variance[direction]); \
4186 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004187 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004188 channel_features[channel].difference_entropy[direction]); \
4189 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004190 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004191 channel_features[channel].measure_of_correlation_1[direction]); \
4192 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004193 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004194 channel_features[channel].measure_of_correlation_2[direction]); \
4195 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004196 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004197 channel_features[channel].maximum_correlation_coefficient[direction]); \
4198 PUSHs(sv_2mortal(newSVpv(message,0))); \
4199}
4200
4201 AV
4202 *av;
4203
4204 char
4205 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004206 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004207
4208 ChannelFeatures
4209 *channel_features;
4210
4211 double
4212 distance;
4213
4214 ExceptionInfo
4215 *exception;
4216
4217 Image
4218 *image;
4219
4220 register ssize_t
4221 i;
4222
4223 ssize_t
4224 count;
4225
4226 struct PackageInfo
4227 *info;
4228
4229 SV
4230 *perl_exception,
4231 *reference;
4232
4233 PERL_UNUSED_VAR(ref);
4234 PERL_UNUSED_VAR(ix);
4235 exception=AcquireExceptionInfo();
4236 perl_exception=newSVpv("",0);
4237 av=NULL;
4238 if (sv_isobject(ST(0)) == 0)
4239 {
4240 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4241 PackageName);
4242 goto PerlException;
4243 }
4244 reference=SvRV(ST(0));
4245 av=newAV();
4246 SvREFCNT_dec(av);
4247 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4248 if (image == (Image *) NULL)
4249 {
4250 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4251 PackageName);
4252 goto PerlException;
4253 }
cristy7dbd9262014-07-02 17:53:42 +00004254 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004255 for (i=2; i < items; i+=2)
4256 {
4257 attribute=(char *) SvPV(ST(i-1),na);
4258 switch (*attribute)
4259 {
4260 case 'D':
4261 case 'd':
4262 {
4263 if (LocaleCompare(attribute,"distance") == 0)
4264 {
4265 distance=StringToLong((char *) SvPV(ST(1),na));
4266 break;
4267 }
4268 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4269 attribute);
4270 break;
4271 }
4272 default:
4273 {
4274 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4275 attribute);
4276 break;
4277 }
4278 }
4279 }
4280 count=0;
4281 for ( ; image; image=image->next)
4282 {
Cristy5a854dc2017-02-11 15:43:46 -05004283 register ssize_t
4284 j;
4285
cristy4a3ce0a2013-08-03 20:06:59 +00004286 channel_features=GetImageFeatures(image,distance,exception);
4287 if (channel_features == (ChannelFeatures *) NULL)
4288 continue;
4289 count++;
Cristy5a854dc2017-02-11 15:43:46 -05004290 for (j=0; j < 4; j++)
cristy4a3ce0a2013-08-03 20:06:59 +00004291 {
Cristy5a854dc2017-02-11 15:43:46 -05004292 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
4293 {
4294 PixelChannel channel=GetPixelChannelChannel(image,i);
4295 PixelTrait traits=GetPixelChannelTraits(image,channel);
4296 if (traits == UndefinedPixelTrait)
4297 continue;
4298 EXTEND(sp,14*(i+1)*count);
4299 ChannelFeatures(channel,j);
4300 }
cristy4a3ce0a2013-08-03 20:06:59 +00004301 }
4302 channel_features=(ChannelFeatures *)
4303 RelinquishMagickMemory(channel_features);
4304 }
4305
4306 PerlException:
4307 InheritPerlException(exception,perl_exception);
4308 exception=DestroyExceptionInfo(exception);
4309 SvREFCNT_dec(perl_exception);
4310 }
4311
4312#
4313###############################################################################
4314# #
4315# #
4316# #
4317# F l a t t e n #
4318# #
4319# #
4320# #
4321###############################################################################
4322#
4323#
4324void
4325Flatten(ref)
4326 Image::Magick ref=NO_INIT
4327 ALIAS:
4328 FlattenImage = 1
4329 flatten = 2
4330 flattenimage = 3
4331 PPCODE:
4332 {
4333 AV
4334 *av;
4335
4336 char
4337 *attribute,
4338 *p;
4339
4340 ExceptionInfo
4341 *exception;
4342
4343 HV
4344 *hv;
4345
4346 Image
4347 *image;
4348
4349 PixelInfo
4350 background_color;
4351
4352 register ssize_t
4353 i;
4354
4355 struct PackageInfo
4356 *info;
4357
4358 SV
4359 *perl_exception,
4360 *reference,
4361 *rv,
4362 *sv;
4363
4364 PERL_UNUSED_VAR(ref);
4365 PERL_UNUSED_VAR(ix);
4366 exception=AcquireExceptionInfo();
4367 perl_exception=newSVpv("",0);
4368 sv=NULL;
4369 if (sv_isobject(ST(0)) == 0)
4370 {
4371 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4372 PackageName);
4373 goto PerlException;
4374 }
4375 reference=SvRV(ST(0));
4376 hv=SvSTASH(reference);
4377 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4378 if (image == (Image *) NULL)
4379 {
4380 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4381 PackageName);
4382 goto PerlException;
4383 }
4384 background_color=image->background_color;
4385 if (items == 2)
4386 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4387 &background_color,exception);
4388 else
4389 for (i=2; i < items; i+=2)
4390 {
4391 attribute=(char *) SvPV(ST(i-1),na);
4392 switch (*attribute)
4393 {
4394 case 'B':
4395 case 'b':
4396 {
4397 if (LocaleCompare(attribute,"background") == 0)
4398 {
4399 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4400 AllCompliance,&background_color,exception);
4401 break;
4402 }
4403 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4404 attribute);
4405 break;
4406 }
4407 default:
4408 {
4409 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4410 attribute);
4411 break;
4412 }
4413 }
4414 }
4415 image->background_color=background_color;
4416 image=MergeImageLayers(image,FlattenLayer,exception);
4417 if (image == (Image *) NULL)
4418 goto PerlException;
4419 /*
4420 Create blessed Perl array for the returned image.
4421 */
4422 av=newAV();
4423 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4424 SvREFCNT_dec(av);
4425 AddImageToRegistry(sv,image);
4426 rv=newRV(sv);
4427 av_push(av,sv_bless(rv,hv));
4428 SvREFCNT_dec(sv);
4429 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004430 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4431 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004432 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4433 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004434 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004435 SetImageInfo(info->image_info,0,exception);
4436 exception=DestroyExceptionInfo(exception);
4437 SvREFCNT_dec(perl_exception);
4438 XSRETURN(1);
4439
4440 PerlException:
4441 InheritPerlException(exception,perl_exception);
4442 exception=DestroyExceptionInfo(exception);
4443 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4444 SvPOK_on(perl_exception); /* return messages in string context */
4445 ST(0)=sv_2mortal(perl_exception);
4446 XSRETURN(1);
4447 }
4448
4449#
4450###############################################################################
4451# #
4452# #
4453# #
4454# F x #
4455# #
4456# #
4457# #
4458###############################################################################
4459#
4460#
4461void
4462Fx(ref,...)
4463 Image::Magick ref=NO_INIT
4464 ALIAS:
4465 FxImage = 1
4466 fx = 2
4467 fximage = 3
4468 PPCODE:
4469 {
4470 AV
4471 *av;
4472
4473 char
4474 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004475 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004476
4477 ChannelType
4478 channel,
4479 channel_mask;
4480
4481 ExceptionInfo
4482 *exception;
4483
4484 HV
4485 *hv;
4486
4487 Image
4488 *image;
4489
4490 register ssize_t
4491 i;
4492
4493 struct PackageInfo
4494 *info;
4495
4496 SV
4497 *av_reference,
4498 *perl_exception,
4499 *reference,
4500 *rv,
4501 *sv;
4502
4503 PERL_UNUSED_VAR(ref);
4504 PERL_UNUSED_VAR(ix);
4505 exception=AcquireExceptionInfo();
4506 perl_exception=newSVpv("",0);
4507 sv=NULL;
4508 attribute=NULL;
4509 av=NULL;
4510 if (sv_isobject(ST(0)) == 0)
4511 {
4512 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4513 PackageName);
4514 goto PerlException;
4515 }
4516 reference=SvRV(ST(0));
4517 hv=SvSTASH(reference);
4518 av=newAV();
4519 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4520 SvREFCNT_dec(av);
4521 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4522 if (image == (Image *) NULL)
4523 {
4524 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4525 PackageName);
4526 goto PerlException;
4527 }
4528 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4529 /*
4530 Get options.
4531 */
4532 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004533 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004534 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004535 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004536 else
4537 for (i=2; i < items; i+=2)
4538 {
4539 attribute=(char *) SvPV(ST(i-1),na);
4540 switch (*attribute)
4541 {
4542 case 'C':
4543 case 'c':
4544 {
4545 if (LocaleCompare(attribute,"channel") == 0)
4546 {
4547 ssize_t
4548 option;
4549
4550 option=ParseChannelOption(SvPV(ST(i),na));
4551 if (option < 0)
4552 {
4553 ThrowPerlException(exception,OptionError,
4554 "UnrecognizedType",SvPV(ST(i),na));
4555 return;
4556 }
4557 channel=(ChannelType) option;
4558 break;
4559 }
4560 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4561 attribute);
4562 break;
4563 }
4564 case 'E':
4565 case 'e':
4566 {
4567 if (LocaleCompare(attribute,"expression") == 0)
4568 {
4569 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004570 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004571 break;
4572 }
4573 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4574 attribute);
4575 break;
4576 }
4577 default:
4578 {
4579 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4580 attribute);
4581 break;
4582 }
4583 }
4584 }
4585 channel_mask=SetImageChannelMask(image,channel);
4586 image=FxImage(image,expression,exception);
4587 if (image != (Image *) NULL)
4588 (void) SetImageChannelMask(image,channel_mask);
4589 if (image == (Image *) NULL)
4590 goto PerlException;
4591 for ( ; image; image=image->next)
4592 {
4593 AddImageToRegistry(sv,image);
4594 rv=newRV(sv);
4595 av_push(av,sv_bless(rv,hv));
4596 SvREFCNT_dec(sv);
4597 }
4598 exception=DestroyExceptionInfo(exception);
4599 ST(0)=av_reference;
4600 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4601 XSRETURN(1);
4602
4603 PerlException:
4604 InheritPerlException(exception,perl_exception);
4605 exception=DestroyExceptionInfo(exception);
4606 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4607 SvPOK_on(perl_exception);
4608 ST(0)=sv_2mortal(perl_exception);
4609 XSRETURN(1);
4610 }
4611
4612#
4613###############################################################################
4614# #
4615# #
4616# #
4617# G e t #
4618# #
4619# #
4620# #
4621###############################################################################
4622#
4623#
4624void
4625Get(ref,...)
4626 Image::Magick ref=NO_INIT
4627 ALIAS:
4628 GetAttributes = 1
4629 GetAttribute = 2
4630 get = 3
4631 getattributes = 4
4632 getattribute = 5
4633 PPCODE:
4634 {
4635 char
4636 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004637 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004638
4639 const char
4640 *value;
4641
4642 ExceptionInfo
4643 *exception;
4644
4645 Image
4646 *image;
4647
4648 long
4649 j;
4650
4651 register ssize_t
4652 i;
4653
4654 struct PackageInfo
4655 *info;
4656
4657 SV
4658 *perl_exception,
4659 *reference,
4660 *s;
4661
4662 PERL_UNUSED_VAR(ref);
4663 PERL_UNUSED_VAR(ix);
4664 exception=AcquireExceptionInfo();
4665 perl_exception=newSVpv("",0);
4666 if (sv_isobject(ST(0)) == 0)
4667 {
4668 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4669 PackageName);
4670 XSRETURN_EMPTY;
4671 }
4672 reference=SvRV(ST(0));
4673 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4674 if (image == (Image *) NULL && !info)
4675 XSRETURN_EMPTY;
4676 EXTEND(sp,items);
4677 for (i=1; i < items; i++)
4678 {
4679 attribute=(char *) SvPV(ST(i),na);
4680 s=NULL;
4681 switch (*attribute)
4682 {
4683 case 'A':
4684 case 'a':
4685 {
4686 if (LocaleCompare(attribute,"adjoin") == 0)
4687 {
4688 if (info)
4689 s=newSViv((ssize_t) info->image_info->adjoin);
4690 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4691 continue;
4692 }
4693 if (LocaleCompare(attribute,"antialias") == 0)
4694 {
4695 if (info)
4696 s=newSViv((ssize_t) info->image_info->antialias);
4697 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4698 continue;
4699 }
4700 if (LocaleCompare(attribute,"area") == 0)
4701 {
4702 s=newSViv(GetMagickResource(AreaResource));
4703 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4704 continue;
4705 }
4706 if (LocaleCompare(attribute,"attenuate") == 0)
4707 {
4708 const char
4709 *value;
4710
4711 value=GetImageProperty(image,attribute,exception);
4712 if (value != (const char *) NULL)
4713 s=newSVpv(value,0);
4714 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4715 continue;
4716 }
4717 if (LocaleCompare(attribute,"authenticate") == 0)
4718 {
4719 if (info)
4720 {
4721 const char
4722 *option;
4723
4724 option=GetImageOption(info->image_info,attribute);
4725 if (option != (const char *) NULL)
4726 s=newSVpv(option,0);
4727 }
4728 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4729 continue;
4730 }
4731 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4732 attribute);
4733 break;
4734 }
4735 case 'B':
4736 case 'b':
4737 {
4738 if (LocaleCompare(attribute,"background") == 0)
4739 {
4740 if (image == (Image *) NULL)
4741 break;
cristy151b66d2015-04-15 10:50:31 +00004742 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004743 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4744 (double) image->background_color.green,
4745 (double) image->background_color.blue,
4746 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004747 s=newSVpv(color,0);
4748 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4749 continue;
4750 }
4751 if (LocaleCompare(attribute,"base-columns") == 0)
4752 {
4753 if (image != (Image *) NULL)
4754 s=newSViv((ssize_t) image->magick_columns);
4755 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4756 continue;
4757 }
4758 if (LocaleCompare(attribute,"base-filename") == 0)
4759 {
4760 if (image != (Image *) NULL)
4761 s=newSVpv(image->magick_filename,0);
4762 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4763 continue;
4764 }
4765 if (LocaleCompare(attribute,"base-height") == 0)
4766 {
4767 if (image != (Image *) NULL)
4768 s=newSViv((ssize_t) image->magick_rows);
4769 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4770 continue;
4771 }
4772 if (LocaleCompare(attribute,"base-rows") == 0)
4773 {
4774 if (image != (Image *) NULL)
4775 s=newSViv((ssize_t) image->magick_rows);
4776 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4777 continue;
4778 }
4779 if (LocaleCompare(attribute,"base-width") == 0)
4780 {
4781 if (image != (Image *) NULL)
4782 s=newSViv((ssize_t) image->magick_columns);
4783 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4784 continue;
4785 }
4786 if (LocaleCompare(attribute,"blue-primary") == 0)
4787 {
4788 if (image == (Image *) NULL)
4789 break;
Cristyb1710fe2017-02-11 13:51:48 -05004790 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004791 image->chromaticity.blue_primary.x,
4792 image->chromaticity.blue_primary.y);
4793 s=newSVpv(color,0);
4794 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4795 continue;
4796 }
4797 if (LocaleCompare(attribute,"bordercolor") == 0)
4798 {
4799 if (image == (Image *) NULL)
4800 break;
cristy151b66d2015-04-15 10:50:31 +00004801 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004802 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4803 (double) image->border_color.green,
4804 (double) image->border_color.blue,
4805 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004806 s=newSVpv(color,0);
4807 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4808 continue;
4809 }
4810 if (LocaleCompare(attribute,"bounding-box") == 0)
4811 {
4812 char
cristy151b66d2015-04-15 10:50:31 +00004813 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004814
4815 RectangleInfo
4816 page;
4817
4818 if (image == (Image *) NULL)
4819 break;
4820 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004821 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004822 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4823 page.height,(double) page.x,(double) page.y);
4824 s=newSVpv(geometry,0);
4825 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4826 continue;
4827 }
4828 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4829 attribute);
4830 break;
4831 }
4832 case 'C':
4833 case 'c':
4834 {
4835 if (LocaleCompare(attribute,"class") == 0)
4836 {
4837 if (image == (Image *) NULL)
4838 break;
4839 s=newSViv(image->storage_class);
4840 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4841 image->storage_class));
4842 SvIOK_on(s);
4843 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4844 continue;
4845 }
4846 if (LocaleCompare(attribute,"clip-mask") == 0)
4847 {
4848 if (image != (Image *) NULL)
4849 {
4850 Image
4851 *mask_image;
4852
4853 SV
4854 *sv;
4855
4856 sv=NULL;
4857 if (image->read_mask == MagickFalse)
4858 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004859 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004860 if (mask_image != (Image *) NULL)
4861 {
4862 AddImageToRegistry(sv,mask_image);
4863 s=sv_bless(newRV(sv),SvSTASH(reference));
4864 }
4865 }
4866 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4867 continue;
4868 }
4869 if (LocaleCompare(attribute,"clip-path") == 0)
4870 {
4871 if (image != (Image *) NULL)
4872 {
4873 Image
4874 *mask_image;
4875
4876 SV
4877 *sv;
4878
4879 sv=NULL;
4880 if (image->read_mask != MagickFalse)
4881 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004882 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004883 if (mask_image != (Image *) NULL)
4884 {
4885 AddImageToRegistry(sv,mask_image);
4886 s=sv_bless(newRV(sv),SvSTASH(reference));
4887 }
4888 }
4889 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4890 continue;
4891 }
4892 if (LocaleCompare(attribute,"compression") == 0)
4893 {
4894 j=info ? info->image_info->compression : image ?
4895 image->compression : UndefinedCompression;
4896 if (info)
4897 if (info->image_info->compression == UndefinedCompression)
4898 j=image->compression;
4899 s=newSViv(j);
4900 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4901 j));
4902 SvIOK_on(s);
4903 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4904 continue;
4905 }
4906 if (LocaleCompare(attribute,"colorspace") == 0)
4907 {
4908 j=image ? image->colorspace : RGBColorspace;
4909 s=newSViv(j);
4910 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4911 j));
4912 SvIOK_on(s);
4913 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4914 continue;
4915 }
4916 if (LocaleCompare(attribute,"colors") == 0)
4917 {
4918 if (image != (Image *) NULL)
4919 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4920 exception));
4921 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4922 continue;
4923 }
4924 if (LocaleNCompare(attribute,"colormap",8) == 0)
4925 {
4926 int
4927 items;
4928
4929 if (image == (Image *) NULL || !image->colormap)
4930 break;
4931 j=0;
4932 items=sscanf(attribute,"%*[^[][%ld",&j);
4933 (void) items;
4934 if (j > (ssize_t) image->colors)
4935 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004936 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004937 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4938 (double) image->colormap[j].green,
4939 (double) image->colormap[j].blue,
4940 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004941 s=newSVpv(color,0);
4942 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4943 continue;
4944 }
4945 if (LocaleCompare(attribute,"columns") == 0)
4946 {
4947 if (image != (Image *) NULL)
4948 s=newSViv((ssize_t) image->columns);
4949 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4950 continue;
4951 }
4952 if (LocaleCompare(attribute,"comment") == 0)
4953 {
4954 const char
4955 *value;
4956
Cristy935a4052017-03-31 17:45:37 -04004957 value=GetImageProperty(image,attribute,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004958 if (value != (const char *) NULL)
4959 s=newSVpv(value,0);
4960 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4961 continue;
4962 }
4963 if (LocaleCompare(attribute,"copyright") == 0)
4964 {
4965 s=newSVpv(GetMagickCopyright(),0);
4966 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4967 continue;
4968 }
4969 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4970 attribute);
4971 break;
4972 }
4973 case 'D':
4974 case 'd':
4975 {
4976 if (LocaleCompare(attribute,"density") == 0)
4977 {
4978 char
cristy151b66d2015-04-15 10:50:31 +00004979 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004980
4981 if (image == (Image *) NULL)
4982 break;
Cristyb1710fe2017-02-11 13:51:48 -05004983 (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004984 image->resolution.x,image->resolution.y);
4985 s=newSVpv(geometry,0);
4986 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4987 continue;
4988 }
4989 if (LocaleCompare(attribute,"delay") == 0)
4990 {
4991 if (image != (Image *) NULL)
4992 s=newSViv((ssize_t) image->delay);
4993 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4994 continue;
4995 }
4996 if (LocaleCompare(attribute,"depth") == 0)
4997 {
4998 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4999 if (image != (Image *) NULL)
5000 s=newSViv((ssize_t) GetImageDepth(image,exception));
5001 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5002 continue;
5003 }
5004 if (LocaleCompare(attribute,"directory") == 0)
5005 {
5006 if (image && image->directory)
5007 s=newSVpv(image->directory,0);
5008 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5009 continue;
5010 }
5011 if (LocaleCompare(attribute,"dispose") == 0)
5012 {
5013 if (image == (Image *) NULL)
5014 break;
5015
5016 s=newSViv(image->dispose);
5017 (void) sv_setpv(s,
5018 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
5019 SvIOK_on(s);
5020 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5021 continue;
5022 }
5023 if (LocaleCompare(attribute,"disk") == 0)
5024 {
5025 s=newSViv(GetMagickResource(DiskResource));
5026 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5027 continue;
5028 }
5029 if (LocaleCompare(attribute,"dither") == 0)
5030 {
5031 if (info)
5032 s=newSViv((ssize_t) info->image_info->dither);
5033 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5034 continue;
5035 }
5036 if (LocaleCompare(attribute,"display") == 0) /* same as server */
5037 {
5038 if (info && info->image_info->server_name)
5039 s=newSVpv(info->image_info->server_name,0);
5040 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5041 continue;
5042 }
5043 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5044 attribute);
5045 break;
5046 }
5047 case 'E':
5048 case 'e':
5049 {
5050 if (LocaleCompare(attribute,"elapsed-time") == 0)
5051 {
5052 if (image != (Image *) NULL)
5053 s=newSVnv(GetElapsedTime(&image->timer));
5054 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5055 continue;
5056 }
5057 if (LocaleCompare(attribute,"endian") == 0)
5058 {
5059 j=info ? info->image_info->endian : image ? image->endian :
5060 UndefinedEndian;
5061 s=newSViv(j);
5062 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
5063 SvIOK_on(s);
5064 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5065 continue;
5066 }
5067 if (LocaleCompare(attribute,"error") == 0)
5068 {
5069 if (image != (Image *) NULL)
5070 s=newSVnv(image->error.mean_error_per_pixel);
5071 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5072 continue;
5073 }
5074 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5075 attribute);
5076 break;
5077 }
5078 case 'F':
5079 case 'f':
5080 {
5081 if (LocaleCompare(attribute,"filesize") == 0)
5082 {
5083 if (image != (Image *) NULL)
5084 s=newSViv((ssize_t) GetBlobSize(image));
5085 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5086 continue;
5087 }
5088 if (LocaleCompare(attribute,"filename") == 0)
5089 {
Cristy2273d6a2017-07-14 19:19:55 -04005090 if (info && *info->image_info->filename)
cristy4a3ce0a2013-08-03 20:06:59 +00005091 s=newSVpv(info->image_info->filename,0);
5092 if (image != (Image *) NULL)
5093 s=newSVpv(image->filename,0);
5094 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5095 continue;
5096 }
5097 if (LocaleCompare(attribute,"filter") == 0)
5098 {
5099 s=image ? newSViv(image->filter) : newSViv(0);
5100 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5101 image->filter));
5102 SvIOK_on(s);
5103 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5104 continue;
5105 }
5106 if (LocaleCompare(attribute,"font") == 0)
5107 {
5108 if (info && info->image_info->font)
5109 s=newSVpv(info->image_info->font,0);
5110 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5111 continue;
5112 }
5113 if (LocaleCompare(attribute,"foreground") == 0)
5114 continue;
5115 if (LocaleCompare(attribute,"format") == 0)
5116 {
5117 const MagickInfo
5118 *magick_info;
5119
5120 magick_info=(const MagickInfo *) NULL;
5121 if (info && (*info->image_info->magick != '\0'))
5122 magick_info=GetMagickInfo(info->image_info->magick,exception);
5123 if (image != (Image *) NULL)
5124 magick_info=GetMagickInfo(image->magick,exception);
5125 if ((magick_info != (const MagickInfo *) NULL) &&
5126 (*magick_info->description != '\0'))
5127 s=newSVpv((char *) magick_info->description,0);
5128 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5129 continue;
5130 }
5131 if (LocaleCompare(attribute,"fuzz") == 0)
5132 {
5133 if (info)
5134 s=newSVnv(info->image_info->fuzz);
5135 if (image != (Image *) NULL)
5136 s=newSVnv(image->fuzz);
5137 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5138 continue;
5139 }
5140 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5141 attribute);
5142 break;
5143 }
5144 case 'G':
5145 case 'g':
5146 {
5147 if (LocaleCompare(attribute,"gamma") == 0)
5148 {
5149 if (image != (Image *) NULL)
5150 s=newSVnv(image->gamma);
5151 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5152 continue;
5153 }
5154 if (LocaleCompare(attribute,"geometry") == 0)
5155 {
5156 if (image && image->geometry)
5157 s=newSVpv(image->geometry,0);
5158 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5159 continue;
5160 }
5161 if (LocaleCompare(attribute,"gravity") == 0)
5162 {
5163 s=image ? newSViv(image->gravity) : newSViv(0);
5164 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5165 image->gravity));
5166 SvIOK_on(s);
5167 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5168 continue;
5169 }
5170 if (LocaleCompare(attribute,"green-primary") == 0)
5171 {
5172 if (image == (Image *) NULL)
5173 break;
Cristyb1710fe2017-02-11 13:51:48 -05005174 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005175 image->chromaticity.green_primary.x,
5176 image->chromaticity.green_primary.y);
5177 s=newSVpv(color,0);
5178 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5179 continue;
5180 }
5181 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5182 attribute);
5183 break;
5184 }
5185 case 'H':
5186 case 'h':
5187 {
5188 if (LocaleCompare(attribute,"height") == 0)
5189 {
5190 if (image != (Image *) NULL)
5191 s=newSViv((ssize_t) image->rows);
5192 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5193 continue;
5194 }
5195 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5196 attribute);
5197 break;
5198 }
5199 case 'I':
5200 case 'i':
5201 {
5202 if (LocaleCompare(attribute,"icc") == 0)
5203 {
5204 if (image != (Image *) NULL)
5205 {
5206 const StringInfo
5207 *profile;
5208
5209 profile=GetImageProfile(image,"icc");
5210 if (profile != (StringInfo *) NULL)
5211 s=newSVpv((const char *) GetStringInfoDatum(profile),
5212 GetStringInfoLength(profile));
5213 }
5214 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5215 continue;
5216 }
5217 if (LocaleCompare(attribute,"icm") == 0)
5218 {
5219 if (image != (Image *) NULL)
5220 {
5221 const StringInfo
5222 *profile;
5223
5224 profile=GetImageProfile(image,"icm");
5225 if (profile != (const StringInfo *) NULL)
5226 s=newSVpv((const char *) GetStringInfoDatum(profile),
5227 GetStringInfoLength(profile));
5228 }
5229 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5230 continue;
5231 }
5232 if (LocaleCompare(attribute,"id") == 0)
5233 {
5234 if (image != (Image *) NULL)
5235 {
5236 char
cristy151b66d2015-04-15 10:50:31 +00005237 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005238
5239 MagickBooleanType
5240 status;
5241
5242 static ssize_t
5243 id = 0;
5244
cristy151b66d2015-04-15 10:50:31 +00005245 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005246 id);
5247 status=SetImageRegistry(ImageRegistryType,key,image,
5248 exception);
5249 (void) status;
5250 s=newSViv(id++);
5251 }
5252 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5253 continue;
5254 }
5255 if (LocaleNCompare(attribute,"index",5) == 0)
5256 {
5257 char
cristy151b66d2015-04-15 10:50:31 +00005258 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005259
5260 int
5261 items;
5262
5263 long
5264 x,
5265 y;
5266
5267 register const Quantum
5268 *p;
5269
5270 CacheView
5271 *image_view;
5272
5273 if (image == (Image *) NULL)
5274 break;
5275 if (image->storage_class != PseudoClass)
5276 break;
5277 x=0;
5278 y=0;
5279 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5280 (void) items;
5281 image_view=AcquireVirtualCacheView(image,exception);
5282 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5283 if (p != (const Quantum *) NULL)
5284 {
cristy151b66d2015-04-15 10:50:31 +00005285 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005286 GetPixelIndex(image,p));
5287 s=newSVpv(name,0);
5288 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5289 }
5290 image_view=DestroyCacheView(image_view);
5291 continue;
5292 }
5293 if (LocaleCompare(attribute,"iptc") == 0)
5294 {
5295 if (image != (Image *) NULL)
5296 {
5297 const StringInfo
5298 *profile;
5299
5300 profile=GetImageProfile(image,"iptc");
5301 if (profile != (const StringInfo *) NULL)
5302 s=newSVpv((const char *) GetStringInfoDatum(profile),
5303 GetStringInfoLength(profile));
5304 }
5305 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5306 continue;
5307 }
5308 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5309 {
5310 if (image != (Image *) NULL)
5311 s=newSViv((ssize_t) image->iterations);
5312 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5313 continue;
5314 }
5315 if (LocaleCompare(attribute,"interlace") == 0)
5316 {
5317 j=info ? info->image_info->interlace : image ? image->interlace :
5318 UndefinedInterlace;
5319 s=newSViv(j);
5320 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5321 j));
5322 SvIOK_on(s);
5323 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5324 continue;
5325 }
5326 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5327 attribute);
5328 break;
5329 }
5330 case 'L':
5331 case 'l':
5332 {
5333 if (LocaleCompare(attribute,"label") == 0)
5334 {
5335 const char
5336 *value;
5337
5338 if (image == (Image *) NULL)
5339 break;
Cristy935a4052017-03-31 17:45:37 -04005340 value=GetImageProperty(image,"Label",exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005341 if (value != (const char *) NULL)
5342 s=newSVpv(value,0);
5343 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5344 continue;
5345 }
5346 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5347 {
5348 if (image != (Image *) NULL)
5349 s=newSViv((ssize_t) image->iterations);
5350 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5351 continue;
5352 }
5353 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5354 attribute);
5355 break;
5356 }
5357 case 'M':
5358 case 'm':
5359 {
5360 if (LocaleCompare(attribute,"magick") == 0)
5361 {
5362 if (info && *info->image_info->magick)
5363 s=newSVpv(info->image_info->magick,0);
5364 if (image != (Image *) NULL)
5365 s=newSVpv(image->magick,0);
5366 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5367 continue;
5368 }
5369 if (LocaleCompare(attribute,"map") == 0)
5370 {
5371 s=newSViv(GetMagickResource(MapResource));
5372 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5373 continue;
5374 }
5375 if (LocaleCompare(attribute,"maximum-error") == 0)
5376 {
5377 if (image != (Image *) NULL)
5378 s=newSVnv(image->error.normalized_maximum_error);
5379 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5380 continue;
5381 }
5382 if (LocaleCompare(attribute,"memory") == 0)
5383 {
5384 s=newSViv(GetMagickResource(MemoryResource));
5385 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5386 continue;
5387 }
5388 if (LocaleCompare(attribute,"mean-error") == 0)
5389 {
5390 if (image != (Image *) NULL)
5391 s=newSVnv(image->error.normalized_mean_error);
5392 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5393 continue;
5394 }
5395 if (LocaleCompare(attribute,"mime") == 0)
5396 {
5397 if (info && *info->image_info->magick)
5398 s=newSVpv(MagickToMime(info->image_info->magick),0);
5399 if (image != (Image *) NULL)
5400 s=newSVpv(MagickToMime(image->magick),0);
5401 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5402 continue;
5403 }
5404 if (LocaleCompare(attribute,"mattecolor") == 0)
5405 {
5406 if (image == (Image *) NULL)
5407 break;
cristy151b66d2015-04-15 10:50:31 +00005408 (void) FormatLocaleString(color,MagickPathExtent,
Cristy8645e042016-02-03 16:35:29 -05005409 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5410 (double) image->alpha_color.green,
5411 (double) image->alpha_color.blue,
5412 (double) image->alpha_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005413 s=newSVpv(color,0);
5414 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5415 continue;
5416 }
5417 if (LocaleCompare(attribute,"matte") == 0)
5418 {
5419 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005420 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005421 1 : 0);
5422 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5423 continue;
5424 }
5425 if (LocaleCompare(attribute,"mime") == 0)
5426 {
5427 const char
5428 *magick;
5429
5430 magick=NULL;
5431 if (info && *info->image_info->magick)
5432 magick=info->image_info->magick;
5433 if (image != (Image *) NULL)
5434 magick=image->magick;
5435 if (magick)
5436 {
5437 char
5438 *mime;
5439
5440 mime=MagickToMime(magick);
5441 s=newSVpv(mime,0);
5442 mime=(char *) RelinquishMagickMemory(mime);
5443 }
5444 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5445 continue;
5446 }
5447 if (LocaleCompare(attribute,"monochrome") == 0)
5448 {
5449 if (image == (Image *) NULL)
5450 continue;
5451 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005452 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005453 s=newSViv(j);
5454 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5455 continue;
5456 }
5457 if (LocaleCompare(attribute,"montage") == 0)
5458 {
5459 if (image && image->montage)
5460 s=newSVpv(image->montage,0);
5461 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5462 continue;
5463 }
5464 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5465 attribute);
5466 break;
5467 }
5468 case 'O':
5469 case 'o':
5470 {
5471 if (LocaleCompare(attribute,"orientation") == 0)
5472 {
5473 j=info ? info->image_info->orientation : image ?
5474 image->orientation : UndefinedOrientation;
5475 s=newSViv(j);
5476 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5477 j));
5478 SvIOK_on(s);
5479 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5480 continue;
5481 }
5482 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5483 attribute);
5484 break;
5485 }
5486 case 'P':
5487 case 'p':
5488 {
5489 if (LocaleCompare(attribute,"page") == 0)
5490 {
5491 if (info && info->image_info->page)
5492 s=newSVpv(info->image_info->page,0);
5493 if (image != (Image *) NULL)
5494 {
5495 char
cristy151b66d2015-04-15 10:50:31 +00005496 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005497
cristy151b66d2015-04-15 10:50:31 +00005498 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005499 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5500 (double) image->page.height,(double) image->page.x,(double)
5501 image->page.y);
5502 s=newSVpv(geometry,0);
5503 }
5504 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5505 continue;
5506 }
5507 if (LocaleCompare(attribute,"page.x") == 0)
5508 {
5509 if (image != (Image *) NULL)
5510 s=newSViv((ssize_t) image->page.x);
5511 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5512 continue;
5513 }
5514 if (LocaleCompare(attribute,"page.y") == 0)
5515 {
5516 if (image != (Image *) NULL)
5517 s=newSViv((ssize_t) image->page.y);
5518 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5519 continue;
5520 }
5521 if (LocaleNCompare(attribute,"pixel",5) == 0)
5522 {
5523 char
cristy151b66d2015-04-15 10:50:31 +00005524 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005525
5526 int
5527 items;
5528
5529 long
5530 x,
5531 y;
5532
5533 register const Quantum
5534 *p;
5535
5536 if (image == (Image *) NULL)
5537 break;
5538 x=0;
5539 y=0;
5540 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5541 (void) items;
5542 p=GetVirtualPixels(image,x,y,1,1,exception);
5543 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005544 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005545 QuantumFormat "," QuantumFormat "," QuantumFormat,
5546 GetPixelRed(image,p),GetPixelGreen(image,p),
5547 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5548 else
cristy151b66d2015-04-15 10:50:31 +00005549 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005550 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5551 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5552 GetPixelBlue(image,p),GetPixelBlack(image,p),
5553 GetPixelAlpha(image,p));
5554 s=newSVpv(tuple,0);
5555 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5556 continue;
5557 }
5558 if (LocaleCompare(attribute,"pointsize") == 0)
5559 {
5560 if (info)
5561 s=newSViv((ssize_t) info->image_info->pointsize);
5562 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5563 continue;
5564 }
Cristy798981a2020-02-17 12:07:15 -05005565 if (LocaleCompare(attribute,"precision") == 0)
5566 {
5567 s=newSViv((ssize_t) GetMagickPrecision());
5568 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5569 continue;
5570 }
cristy4a3ce0a2013-08-03 20:06:59 +00005571 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5572 attribute);
5573 break;
5574 }
5575 case 'Q':
5576 case 'q':
5577 {
5578 if (LocaleCompare(attribute,"quality") == 0)
5579 {
5580 if (info)
5581 s=newSViv((ssize_t) info->image_info->quality);
5582 if (image != (Image *) NULL)
5583 s=newSViv((ssize_t) image->quality);
5584 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5585 continue;
5586 }
5587 if (LocaleCompare(attribute,"quantum") == 0)
5588 {
5589 if (info)
5590 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5591 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5592 continue;
5593 }
5594 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5595 attribute);
5596 break;
5597 }
5598 case 'R':
5599 case 'r':
5600 {
5601 if (LocaleCompare(attribute,"rendering-intent") == 0)
5602 {
5603 s=newSViv(image->rendering_intent);
5604 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5605 image->rendering_intent));
5606 SvIOK_on(s);
5607 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5608 continue;
5609 }
5610 if (LocaleCompare(attribute,"red-primary") == 0)
5611 {
5612 if (image == (Image *) NULL)
5613 break;
Cristyb1710fe2017-02-11 13:51:48 -05005614 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005615 image->chromaticity.red_primary.x,
5616 image->chromaticity.red_primary.y);
5617 s=newSVpv(color,0);
5618 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5619 continue;
5620 }
5621 if (LocaleCompare(attribute,"rows") == 0)
5622 {
5623 if (image != (Image *) NULL)
5624 s=newSViv((ssize_t) image->rows);
5625 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5626 continue;
5627 }
5628 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5629 attribute);
5630 break;
5631 }
5632 case 'S':
5633 case 's':
5634 {
5635 if (LocaleCompare(attribute,"sampling-factor") == 0)
5636 {
5637 if (info && info->image_info->sampling_factor)
5638 s=newSVpv(info->image_info->sampling_factor,0);
5639 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5640 continue;
5641 }
5642 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5643 {
5644 if (info && info->image_info->server_name)
5645 s=newSVpv(info->image_info->server_name,0);
5646 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5647 continue;
5648 }
5649 if (LocaleCompare(attribute,"size") == 0)
5650 {
5651 if (info && info->image_info->size)
5652 s=newSVpv(info->image_info->size,0);
5653 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5654 continue;
5655 }
5656 if (LocaleCompare(attribute,"scene") == 0)
5657 {
5658 if (image != (Image *) NULL)
5659 s=newSViv((ssize_t) image->scene);
5660 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5661 continue;
5662 }
5663 if (LocaleCompare(attribute,"scenes") == 0)
5664 {
5665 if (image != (Image *) NULL)
5666 s=newSViv((ssize_t) info->image_info->number_scenes);
5667 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5668 continue;
5669 }
5670 if (LocaleCompare(attribute,"signature") == 0)
5671 {
5672 const char
5673 *value;
5674
5675 if (image == (Image *) NULL)
5676 break;
5677 (void) SignatureImage(image,exception);
5678 value=GetImageProperty(image,"Signature",exception);
5679 if (value != (const char *) NULL)
5680 s=newSVpv(value,0);
5681 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5682 continue;
5683 }
5684 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5685 attribute);
5686 break;
5687 }
5688 case 'T':
5689 case 't':
5690 {
5691 if (LocaleCompare(attribute,"taint") == 0)
5692 {
5693 if (image != (Image *) NULL)
5694 s=newSViv((ssize_t) IsTaintImage(image));
5695 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5696 continue;
5697 }
5698 if (LocaleCompare(attribute,"texture") == 0)
5699 {
5700 if (info && info->image_info->texture)
5701 s=newSVpv(info->image_info->texture,0);
5702 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5703 continue;
5704 }
5705 if (LocaleCompare(attribute,"total-ink-density") == 0)
5706 {
5707 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5708 if (image != (Image *) NULL)
5709 s=newSVnv(GetImageTotalInkDensity(image,exception));
5710 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5711 continue;
5712 }
5713 if (LocaleCompare(attribute,"transparent-color") == 0)
5714 {
5715 if (image == (Image *) NULL)
5716 break;
cristy151b66d2015-04-15 10:50:31 +00005717 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005718 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5719 (double) image->transparent_color.green,
5720 (double) image->transparent_color.blue,
5721 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005722 s=newSVpv(color,0);
5723 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5724 continue;
5725 }
5726 if (LocaleCompare(attribute,"type") == 0)
5727 {
5728 if (image == (Image *) NULL)
5729 break;
cristya26f54c2015-07-29 12:26:12 +00005730 j=(ssize_t) GetImageType(image);
cristy4a3ce0a2013-08-03 20:06:59 +00005731 s=newSViv(j);
5732 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5733 SvIOK_on(s);
5734 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5735 continue;
5736 }
5737 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5738 attribute);
5739 break;
5740 }
5741 case 'U':
5742 case 'u':
5743 {
5744 if (LocaleCompare(attribute,"units") == 0)
5745 {
5746 j=info ? info->image_info->units : image ? image->units :
5747 UndefinedResolution;
5748 if (info && (info->image_info->units == UndefinedResolution))
5749 if (image)
5750 j=image->units;
5751 if (j == UndefinedResolution)
5752 s=newSVpv("undefined units",0);
5753 else
5754 if (j == PixelsPerInchResolution)
5755 s=newSVpv("pixels / inch",0);
5756 else
5757 s=newSVpv("pixels / centimeter",0);
5758 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5759 continue;
5760 }
5761 if (LocaleCompare(attribute,"user-time") == 0)
5762 {
5763 if (image != (Image *) NULL)
5764 s=newSVnv(GetUserTime(&image->timer));
5765 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5766 continue;
5767 }
5768 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5769 attribute);
5770 break;
5771 }
5772 case 'V':
5773 case 'v':
5774 {
5775 if (LocaleCompare(attribute,"verbose") == 0)
5776 {
5777 if (info)
5778 s=newSViv((ssize_t) info->image_info->verbose);
5779 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5780 continue;
5781 }
5782 if (LocaleCompare(attribute,"version") == 0)
5783 {
5784 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5785 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5786 continue;
5787 }
cristy4a3ce0a2013-08-03 20:06:59 +00005788 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5789 {
5790 if (image == (Image *) NULL)
5791 break;
5792 j=(ssize_t) GetImageVirtualPixelMethod(image);
5793 s=newSViv(j);
5794 (void) sv_setpv(s,CommandOptionToMnemonic(
5795 MagickVirtualPixelOptions,j));
5796 SvIOK_on(s);
5797 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5798 continue;
5799 }
5800 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5801 attribute);
5802 break;
5803 }
5804 case 'W':
5805 case 'w':
5806 {
5807 if (LocaleCompare(attribute,"white-point") == 0)
5808 {
5809 if (image == (Image *) NULL)
5810 break;
Cristyb1710fe2017-02-11 13:51:48 -05005811 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005812 image->chromaticity.white_point.x,
5813 image->chromaticity.white_point.y);
5814 s=newSVpv(color,0);
5815 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5816 continue;
5817 }
5818 if (LocaleCompare(attribute,"width") == 0)
5819 {
5820 if (image != (Image *) NULL)
5821 s=newSViv((ssize_t) image->columns);
5822 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5823 continue;
5824 }
5825 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5826 attribute);
5827 break;
5828 }
5829 case 'X':
5830 case 'x':
5831 {
Cristyc1f9f9f2016-01-05 08:19:28 -05005832 if (LocaleCompare(attribute,"xmp") == 0)
5833 {
5834 if (image != (Image *) NULL)
5835 {
5836 const StringInfo
5837 *profile;
5838
5839 profile=GetImageProfile(image,"xmp");
5840 if (profile != (StringInfo *) NULL)
5841 s=newSVpv((const char *) GetStringInfoDatum(profile),
5842 GetStringInfoLength(profile));
5843 }
5844 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5845 continue;
5846 }
cristy4a3ce0a2013-08-03 20:06:59 +00005847 if (LocaleCompare(attribute,"x-resolution") == 0)
5848 {
5849 if (image != (Image *) NULL)
5850 s=newSVnv(image->resolution.x);
5851 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5852 continue;
5853 }
5854 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5855 attribute);
5856 break;
5857 }
5858 case 'Y':
5859 case 'y':
5860 {
5861 if (LocaleCompare(attribute,"y-resolution") == 0)
5862 {
5863 if (image != (Image *) NULL)
5864 s=newSVnv(image->resolution.y);
5865 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5866 continue;
5867 }
5868 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5869 attribute);
5870 break;
5871 }
5872 default:
5873 break;
5874 }
5875 if (image == (Image *) NULL)
5876 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5877 attribute)
5878 else
5879 {
5880 value=GetImageProperty(image,attribute,exception);
5881 if (value != (const char *) NULL)
5882 {
5883 s=newSVpv(value,0);
5884 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5885 }
5886 else
5887 if (*attribute != '%')
5888 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5889 attribute)
5890 else
5891 {
5892 char
5893 *meta;
5894
5895 meta=InterpretImageProperties(info ? info->image_info :
5896 (ImageInfo *) NULL,image,attribute,exception);
5897 s=newSVpv(meta,0);
5898 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5899 meta=(char *) RelinquishMagickMemory(meta);
5900 }
5901 }
5902 }
5903 exception=DestroyExceptionInfo(exception);
5904 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5905 }
5906
5907#
5908###############################################################################
5909# #
5910# #
5911# #
5912# G e t A u t h e n t i c P i x e l s #
5913# #
5914# #
5915# #
5916###############################################################################
5917#
5918#
5919void *
5920GetAuthenticPixels(ref,...)
5921 Image::Magick ref = NO_INIT
5922 ALIAS:
5923 getauthenticpixels = 1
5924 GetImagePixels = 2
5925 getimagepixels = 3
5926 CODE:
5927 {
5928 char
5929 *attribute;
5930
5931 ExceptionInfo
5932 *exception;
5933
5934 Image
5935 *image;
5936
5937 RectangleInfo
5938 region;
5939
5940 ssize_t
5941 i;
5942
5943 struct PackageInfo
5944 *info;
5945
5946 SV
5947 *perl_exception,
5948 *reference;
5949
5950 void
5951 *blob = NULL;
5952
5953 PERL_UNUSED_VAR(ref);
5954 PERL_UNUSED_VAR(ix);
5955 exception=AcquireExceptionInfo();
5956 perl_exception=newSVpv("",0);
5957 if (sv_isobject(ST(0)) == 0)
5958 {
5959 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5960 PackageName);
5961 goto PerlException;
5962 }
5963 reference=SvRV(ST(0));
5964
5965 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5966 if (image == (Image *) NULL)
5967 {
5968 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5969 PackageName);
5970 goto PerlException;
5971 }
5972
5973 region.x=0;
5974 region.y=0;
5975 region.width=image->columns;
5976 region.height=1;
5977 if (items == 1)
5978 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5979 for (i=2; i < items; i+=2)
5980 {
5981 attribute=(char *) SvPV(ST(i-1),na);
5982 switch (*attribute)
5983 {
5984 case 'g':
5985 case 'G':
5986 {
5987 if (LocaleCompare(attribute,"geometry") == 0)
5988 {
5989 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5990 break;
5991 }
5992 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5993 attribute);
5994 break;
5995 }
5996 case 'H':
5997 case 'h':
5998 {
5999 if (LocaleCompare(attribute,"height") == 0)
6000 {
6001 region.height=SvIV(ST(i));
6002 continue;
6003 }
6004 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6005 attribute);
6006 break;
6007 }
6008 case 'X':
6009 case 'x':
6010 {
6011 if (LocaleCompare(attribute,"x") == 0)
6012 {
6013 region.x=SvIV(ST(i));
6014 continue;
6015 }
6016 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6017 attribute);
6018 break;
6019 }
6020 case 'Y':
6021 case 'y':
6022 {
6023 if (LocaleCompare(attribute,"y") == 0)
6024 {
6025 region.y=SvIV(ST(i));
6026 continue;
6027 }
6028 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6029 attribute);
6030 break;
6031 }
6032 case 'W':
6033 case 'w':
6034 {
6035 if (LocaleCompare(attribute,"width") == 0)
6036 {
6037 region.width=SvIV(ST(i));
6038 continue;
6039 }
6040 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6041 attribute);
6042 break;
6043 }
6044 }
6045 }
6046 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
6047 region.height,exception);
6048 if (blob != (void *) NULL)
6049 goto PerlEnd;
6050
6051 PerlException:
6052 InheritPerlException(exception,perl_exception);
6053 exception=DestroyExceptionInfo(exception);
6054 SvREFCNT_dec(perl_exception); /* throw away all errors */
6055
6056 PerlEnd:
6057 RETVAL = blob;
6058 }
6059 OUTPUT:
6060 RETVAL
6061
6062#
6063###############################################################################
6064# #
6065# #
6066# #
6067# G e t V i r t u a l P i x e l s #
6068# #
6069# #
6070# #
6071###############################################################################
6072#
6073#
6074void *
6075GetVirtualPixels(ref,...)
6076 Image::Magick ref = NO_INIT
6077 ALIAS:
6078 getvirtualpixels = 1
6079 AcquireImagePixels = 2
6080 acquireimagepixels = 3
6081 CODE:
6082 {
6083 char
6084 *attribute;
6085
6086 const void
6087 *blob = NULL;
6088
6089 ExceptionInfo
6090 *exception;
6091
6092 Image
6093 *image;
6094
6095 RectangleInfo
6096 region;
6097
6098 ssize_t
6099 i;
6100
6101 struct PackageInfo
6102 *info;
6103
6104 SV
6105 *perl_exception,
6106 *reference;
6107
6108 PERL_UNUSED_VAR(ref);
6109 PERL_UNUSED_VAR(ix);
6110 exception=AcquireExceptionInfo();
6111 perl_exception=newSVpv("",0);
6112 if (sv_isobject(ST(0)) == 0)
6113 {
6114 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6115 PackageName);
6116 goto PerlException;
6117 }
6118 reference=SvRV(ST(0));
6119
6120 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6121 if (image == (Image *) NULL)
6122 {
6123 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6124 PackageName);
6125 goto PerlException;
6126 }
6127
6128 region.x=0;
6129 region.y=0;
6130 region.width=image->columns;
6131 region.height=1;
6132 if (items == 1)
6133 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6134 for (i=2; i < items; i+=2)
6135 {
6136 attribute=(char *) SvPV(ST(i-1),na);
6137 switch (*attribute)
6138 {
6139 case 'g':
6140 case 'G':
6141 {
6142 if (LocaleCompare(attribute,"geometry") == 0)
6143 {
6144 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6145 break;
6146 }
6147 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6148 attribute);
6149 break;
6150 }
6151 case 'H':
6152 case 'h':
6153 {
6154 if (LocaleCompare(attribute,"height") == 0)
6155 {
6156 region.height=SvIV(ST(i));
6157 continue;
6158 }
6159 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6160 attribute);
6161 break;
6162 }
6163 case 'X':
6164 case 'x':
6165 {
6166 if (LocaleCompare(attribute,"x") == 0)
6167 {
6168 region.x=SvIV(ST(i));
6169 continue;
6170 }
6171 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6172 attribute);
6173 break;
6174 }
6175 case 'Y':
6176 case 'y':
6177 {
6178 if (LocaleCompare(attribute,"y") == 0)
6179 {
6180 region.y=SvIV(ST(i));
6181 continue;
6182 }
6183 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6184 attribute);
6185 break;
6186 }
6187 case 'W':
6188 case 'w':
6189 {
6190 if (LocaleCompare(attribute,"width") == 0)
6191 {
6192 region.width=SvIV(ST(i));
6193 continue;
6194 }
6195 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6196 attribute);
6197 break;
6198 }
6199 }
6200 }
6201 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6202 region.height,exception);
6203 if (blob != (void *) NULL)
6204 goto PerlEnd;
6205
6206 PerlException:
6207 InheritPerlException(exception,perl_exception);
6208 exception=DestroyExceptionInfo(exception);
6209 SvREFCNT_dec(perl_exception); /* throw away all errors */
6210
6211 PerlEnd:
6212 RETVAL = (void *) blob;
6213 }
6214 OUTPUT:
6215 RETVAL
6216
6217#
6218###############################################################################
6219# #
6220# #
6221# #
6222# G e t A u t h e n t i c M e t a c o n t e n t #
6223# #
6224# #
6225# #
6226###############################################################################
6227#
6228#
6229void *
6230GetAuthenticMetacontent(ref,...)
6231 Image::Magick ref = NO_INIT
6232 ALIAS:
6233 getauthenticmetacontent = 1
6234 GetMetacontent = 2
6235 getmetacontent = 3
6236 CODE:
6237 {
6238 ExceptionInfo
6239 *exception;
6240
6241 Image
6242 *image;
6243
6244 struct PackageInfo
6245 *info;
6246
6247 SV
6248 *perl_exception,
6249 *reference;
6250
6251 void
6252 *blob = NULL;
6253
6254 PERL_UNUSED_VAR(ref);
6255 PERL_UNUSED_VAR(ix);
6256 exception=AcquireExceptionInfo();
6257 perl_exception=newSVpv("",0);
6258 if (sv_isobject(ST(0)) == 0)
6259 {
6260 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6261 PackageName);
6262 goto PerlException;
6263 }
6264 reference=SvRV(ST(0));
6265
6266 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6267 if (image == (Image *) NULL)
6268 {
6269 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6270 PackageName);
6271 goto PerlException;
6272 }
6273
6274 blob=(void *) GetAuthenticMetacontent(image);
6275 if (blob != (void *) NULL)
6276 goto PerlEnd;
6277
6278 PerlException:
6279 InheritPerlException(exception,perl_exception);
6280 exception=DestroyExceptionInfo(exception);
6281 SvREFCNT_dec(perl_exception); /* throw away all errors */
6282
6283 PerlEnd:
6284 RETVAL = blob;
6285 }
6286 OUTPUT:
6287 RETVAL
6288
6289#
6290###############################################################################
6291# #
6292# #
6293# #
6294# G e t V i r t u a l M e t a c o n t e n t #
6295# #
6296# #
6297# #
6298###############################################################################
6299#
6300#
6301void *
6302GetVirtualMetacontent(ref,...)
6303 Image::Magick ref = NO_INIT
6304 ALIAS:
6305 getvirtualmetacontent = 1
6306 CODE:
6307 {
6308 ExceptionInfo
6309 *exception;
6310
6311 Image
6312 *image;
6313
6314 struct PackageInfo
6315 *info;
6316
6317 SV
6318 *perl_exception,
6319 *reference;
6320
6321 void
6322 *blob = NULL;
6323
6324 PERL_UNUSED_VAR(ref);
6325 PERL_UNUSED_VAR(ix);
6326 exception=AcquireExceptionInfo();
6327 perl_exception=newSVpv("",0);
6328 if (sv_isobject(ST(0)) == 0)
6329 {
6330 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6331 PackageName);
6332 goto PerlException;
6333 }
6334 reference=SvRV(ST(0));
6335
6336 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6337 if (image == (Image *) NULL)
6338 {
6339 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6340 PackageName);
6341 goto PerlException;
6342 }
6343
6344 blob=(void *) GetVirtualMetacontent(image);
6345 if (blob != (void *) NULL)
6346 goto PerlEnd;
6347
6348 PerlException:
6349 InheritPerlException(exception,perl_exception);
6350 exception=DestroyExceptionInfo(exception);
6351 SvREFCNT_dec(perl_exception); /* throw away all errors */
6352
6353 PerlEnd:
6354 RETVAL = blob;
6355 }
6356 OUTPUT:
6357 RETVAL
6358
6359#
6360###############################################################################
6361# #
6362# #
6363# #
6364# H i s t o g r a m #
6365# #
6366# #
6367# #
6368###############################################################################
6369#
6370#
6371void
6372Histogram(ref,...)
6373 Image::Magick ref=NO_INIT
6374 ALIAS:
6375 HistogramImage = 1
6376 histogram = 2
6377 histogramimage = 3
6378 PPCODE:
6379 {
6380 AV
6381 *av;
6382
6383 char
cristy151b66d2015-04-15 10:50:31 +00006384 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006385
6386 PixelInfo
6387 *histogram;
6388
6389 ExceptionInfo
6390 *exception;
6391
6392 Image
6393 *image;
6394
6395 register ssize_t
6396 i;
6397
6398 ssize_t
6399 count;
6400
6401 struct PackageInfo
6402 *info;
6403
6404 SV
6405 *perl_exception,
6406 *reference;
6407
6408 size_t
6409 number_colors;
6410
6411 PERL_UNUSED_VAR(ref);
6412 PERL_UNUSED_VAR(ix);
6413 exception=AcquireExceptionInfo();
6414 perl_exception=newSVpv("",0);
6415 av=NULL;
6416 if (sv_isobject(ST(0)) == 0)
6417 {
6418 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6419 PackageName);
6420 goto PerlException;
6421 }
6422 reference=SvRV(ST(0));
6423 av=newAV();
6424 SvREFCNT_dec(av);
6425 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6426 if (image == (Image *) NULL)
6427 {
6428 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6429 PackageName);
6430 goto PerlException;
6431 }
cristy4a3ce0a2013-08-03 20:06:59 +00006432 count=0;
6433 for ( ; image; image=image->next)
6434 {
6435 histogram=GetImageHistogram(image,&number_colors,exception);
6436 if (histogram == (PixelInfo *) NULL)
6437 continue;
6438 count+=(ssize_t) number_colors;
6439 EXTEND(sp,6*count);
6440 for (i=0; i < (ssize_t) number_colors; i++)
6441 {
cristy151b66d2015-04-15 10:50:31 +00006442 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006443 histogram[i].red);
6444 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006445 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006446 histogram[i].green);
6447 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006448 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006449 histogram[i].blue);
6450 PUSHs(sv_2mortal(newSVpv(message,0)));
6451 if (image->colorspace == CMYKColorspace)
6452 {
cristy151b66d2015-04-15 10:50:31 +00006453 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006454 histogram[i].black);
6455 PUSHs(sv_2mortal(newSVpv(message,0)));
6456 }
cristy151b66d2015-04-15 10:50:31 +00006457 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006458 histogram[i].alpha);
6459 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006460 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006461 histogram[i].count);
6462 PUSHs(sv_2mortal(newSVpv(message,0)));
6463 }
6464 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6465 }
6466
6467 PerlException:
6468 InheritPerlException(exception,perl_exception);
6469 exception=DestroyExceptionInfo(exception);
6470 SvREFCNT_dec(perl_exception);
6471 }
6472
6473#
6474###############################################################################
6475# #
6476# #
6477# #
6478# G e t P i x e l #
6479# #
6480# #
6481# #
6482###############################################################################
6483#
6484#
6485void
6486GetPixel(ref,...)
6487 Image::Magick ref=NO_INIT
6488 ALIAS:
6489 getpixel = 1
6490 getPixel = 2
6491 PPCODE:
6492 {
6493 AV
6494 *av;
6495
6496 char
6497 *attribute;
6498
6499 ExceptionInfo
6500 *exception;
6501
6502 Image
6503 *image;
6504
6505 MagickBooleanType
6506 normalize;
6507
6508 RectangleInfo
6509 region;
6510
6511 register const Quantum
6512 *p;
6513
6514 register ssize_t
6515 i;
6516
6517 ssize_t
6518 option;
6519
6520 struct PackageInfo
6521 *info;
6522
6523 SV
6524 *perl_exception,
6525 *reference; /* reference is the SV* of ref=SvIV(reference) */
6526
6527 PERL_UNUSED_VAR(ref);
6528 PERL_UNUSED_VAR(ix);
6529 exception=AcquireExceptionInfo();
6530 perl_exception=newSVpv("",0);
6531 reference=SvRV(ST(0));
6532 av=(AV *) reference;
6533 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6534 exception);
6535 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6536 if (image == (Image *) NULL)
6537 {
6538 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6539 PackageName);
6540 goto PerlException;
6541 }
6542 normalize=MagickTrue;
6543 region.x=0;
6544 region.y=0;
6545 region.width=image->columns;
6546 region.height=1;
6547 if (items == 1)
6548 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6549 for (i=2; i < items; i+=2)
6550 {
6551 attribute=(char *) SvPV(ST(i-1),na);
6552 switch (*attribute)
6553 {
6554 case 'C':
6555 case 'c':
6556 {
6557 if (LocaleCompare(attribute,"channel") == 0)
6558 {
6559 ssize_t
6560 option;
6561
6562 option=ParseChannelOption(SvPV(ST(i),na));
6563 if (option < 0)
6564 {
6565 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6566 SvPV(ST(i),na));
6567 return;
6568 }
cristybcd59342015-06-07 14:07:19 +00006569 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00006570 break;
6571 }
6572 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6573 attribute);
6574 break;
6575 }
6576 case 'g':
6577 case 'G':
6578 {
6579 if (LocaleCompare(attribute,"geometry") == 0)
6580 {
6581 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6582 break;
6583 }
6584 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6585 attribute);
6586 break;
6587 }
6588 case 'N':
6589 case 'n':
6590 {
6591 if (LocaleCompare(attribute,"normalize") == 0)
6592 {
6593 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6594 SvPV(ST(i),na));
6595 if (option < 0)
6596 {
6597 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6598 SvPV(ST(i),na));
6599 break;
6600 }
6601 normalize=option != 0 ? MagickTrue : MagickFalse;
6602 break;
6603 }
6604 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6605 attribute);
6606 break;
6607 }
6608 case 'x':
6609 case 'X':
6610 {
6611 if (LocaleCompare(attribute,"x") == 0)
6612 {
6613 region.x=SvIV(ST(i));
6614 break;
6615 }
6616 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6617 attribute);
6618 break;
6619 }
6620 case 'y':
6621 case 'Y':
6622 {
6623 if (LocaleCompare(attribute,"y") == 0)
6624 {
6625 region.y=SvIV(ST(i));
6626 break;
6627 }
6628 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6629 attribute);
6630 break;
6631 }
6632 default:
6633 {
6634 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6635 attribute);
6636 break;
6637 }
6638 }
6639 }
6640 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6641 if (p == (const Quantum *) NULL)
6642 PUSHs(&sv_undef);
6643 else
6644 {
6645 double
6646 scale;
6647
6648 scale=1.0;
6649 if (normalize != MagickFalse)
6650 scale=1.0/QuantumRange;
6651 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6652 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6653 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6654 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6655 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6656 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6657 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6658 (image->colorspace == CMYKColorspace))
6659 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6660 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6661 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6662 }
6663
6664 PerlException:
6665 InheritPerlException(exception,perl_exception);
6666 exception=DestroyExceptionInfo(exception);
6667 SvREFCNT_dec(perl_exception);
6668 }
6669
6670#
6671###############################################################################
6672# #
6673# #
6674# #
6675# G e t P i x e l s #
6676# #
6677# #
6678# #
6679###############################################################################
6680#
6681#
6682void
6683GetPixels(ref,...)
6684 Image::Magick ref=NO_INIT
6685 ALIAS:
6686 getpixels = 1
6687 getPixels = 2
6688 PPCODE:
6689 {
6690 AV
6691 *av;
6692
6693 char
6694 *attribute;
6695
6696 const char
6697 *map;
6698
6699 ExceptionInfo
6700 *exception;
6701
6702 Image
6703 *image;
6704
6705 MagickBooleanType
6706 normalize,
6707 status;
6708
6709 RectangleInfo
6710 region;
6711
6712 register ssize_t
6713 i;
6714
6715 ssize_t
6716 option;
6717
6718 struct PackageInfo
6719 *info;
6720
6721 SV
6722 *perl_exception,
6723 *reference; /* reference is the SV* of ref=SvIV(reference) */
6724
6725 PERL_UNUSED_VAR(ref);
6726 PERL_UNUSED_VAR(ix);
6727 exception=AcquireExceptionInfo();
6728 perl_exception=newSVpv("",0);
6729 reference=SvRV(ST(0));
6730 av=(AV *) reference;
6731 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6732 exception);
6733 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6734 if (image == (Image *) NULL)
6735 {
6736 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6737 PackageName);
6738 goto PerlException;
6739 }
6740 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006741 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006742 map="RGBA";
6743 if (image->colorspace == CMYKColorspace)
6744 {
6745 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006746 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006747 map="CMYKA";
6748 }
6749 normalize=MagickFalse;
6750 region.x=0;
6751 region.y=0;
6752 region.width=image->columns;
6753 region.height=1;
6754 if (items == 1)
6755 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6756 for (i=2; i < items; i+=2)
6757 {
6758 attribute=(char *) SvPV(ST(i-1),na);
6759 switch (*attribute)
6760 {
6761 case 'g':
6762 case 'G':
6763 {
6764 if (LocaleCompare(attribute,"geometry") == 0)
6765 {
6766 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6767 break;
6768 }
6769 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6770 attribute);
6771 break;
6772 }
6773 case 'H':
6774 case 'h':
6775 {
6776 if (LocaleCompare(attribute,"height") == 0)
6777 {
6778 region.height=SvIV(ST(i));
6779 break;
6780 }
6781 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6782 attribute);
6783 break;
6784 }
6785 case 'M':
6786 case 'm':
6787 {
6788 if (LocaleCompare(attribute,"map") == 0)
6789 {
6790 map=SvPV(ST(i),na);
6791 break;
6792 }
6793 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6794 attribute);
6795 break;
6796 }
6797 case 'N':
6798 case 'n':
6799 {
6800 if (LocaleCompare(attribute,"normalize") == 0)
6801 {
6802 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6803 SvPV(ST(i),na));
6804 if (option < 0)
6805 {
6806 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6807 SvPV(ST(i),na));
6808 break;
6809 }
6810 normalize=option != 0 ? MagickTrue : MagickFalse;
6811 break;
6812 }
6813 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6814 attribute);
6815 break;
6816 }
6817 case 'W':
6818 case 'w':
6819 {
6820 if (LocaleCompare(attribute,"width") == 0)
6821 {
6822 region.width=SvIV(ST(i));
6823 break;
6824 }
6825 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6826 attribute);
6827 break;
6828 }
6829 case 'x':
6830 case 'X':
6831 {
6832 if (LocaleCompare(attribute,"x") == 0)
6833 {
6834 region.x=SvIV(ST(i));
6835 break;
6836 }
6837 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6838 attribute);
6839 break;
6840 }
6841 case 'y':
6842 case 'Y':
6843 {
6844 if (LocaleCompare(attribute,"y") == 0)
6845 {
6846 region.y=SvIV(ST(i));
6847 break;
6848 }
6849 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6850 attribute);
6851 break;
6852 }
6853 default:
6854 {
6855 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6856 attribute);
6857 break;
6858 }
6859 }
6860 }
6861 if (normalize != MagickFalse)
6862 {
6863 float
6864 *pixels;
6865
6866 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6867 region.height*sizeof(*pixels));
6868 if (pixels == (float *) NULL)
6869 {
6870 ThrowPerlException(exception,ResourceLimitError,
6871 "MemoryAllocationFailed",PackageName);
6872 goto PerlException;
6873 }
6874 status=ExportImagePixels(image,region.x,region.y,region.width,
6875 region.height,map,FloatPixel,pixels,exception);
6876 if (status == MagickFalse)
6877 PUSHs(&sv_undef);
6878 else
6879 {
6880 EXTEND(sp,strlen(map)*region.width*region.height);
6881 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6882 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6883 }
6884 pixels=(float *) RelinquishMagickMemory(pixels);
6885 }
6886 else
6887 {
6888 Quantum
6889 *pixels;
6890
6891 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6892 region.height*sizeof(*pixels));
6893 if (pixels == (Quantum *) NULL)
6894 {
6895 ThrowPerlException(exception,ResourceLimitError,
6896 "MemoryAllocationFailed",PackageName);
6897 goto PerlException;
6898 }
6899 status=ExportImagePixels(image,region.x,region.y,region.width,
6900 region.height,map,QuantumPixel,pixels,exception);
6901 if (status == MagickFalse)
6902 PUSHs(&sv_undef);
6903 else
6904 {
6905 EXTEND(sp,strlen(map)*region.width*region.height);
6906 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6907 PUSHs(sv_2mortal(newSViv(pixels[i])));
6908 }
6909 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6910 }
6911
6912 PerlException:
6913 InheritPerlException(exception,perl_exception);
6914 exception=DestroyExceptionInfo(exception);
6915 SvREFCNT_dec(perl_exception);
6916 }
6917
6918#
6919###############################################################################
6920# #
6921# #
6922# #
6923# I m a g e T o B l o b #
6924# #
6925# #
6926# #
6927###############################################################################
6928#
6929#
6930void
6931ImageToBlob(ref,...)
6932 Image::Magick ref=NO_INIT
6933 ALIAS:
6934 ImageToBlob = 1
6935 imagetoblob = 2
6936 toblob = 3
6937 blob = 4
6938 PPCODE:
6939 {
6940 char
cristy151b66d2015-04-15 10:50:31 +00006941 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006942
6943 ExceptionInfo
6944 *exception;
6945
6946 Image
6947 *image,
6948 *next;
6949
6950 register ssize_t
6951 i;
6952
6953 struct PackageInfo
6954 *info,
6955 *package_info;
6956
6957 size_t
6958 length;
6959
6960 ssize_t
6961 scene;
6962
6963 SV
6964 *perl_exception,
6965 *reference;
6966
6967 void
6968 *blob;
6969
6970 PERL_UNUSED_VAR(ref);
6971 PERL_UNUSED_VAR(ix);
6972 exception=AcquireExceptionInfo();
6973 perl_exception=newSVpv("",0);
6974 package_info=(struct PackageInfo *) NULL;
6975 if (sv_isobject(ST(0)) == 0)
6976 {
6977 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6978 PackageName);
6979 goto PerlException;
6980 }
6981 reference=SvRV(ST(0));
6982 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6983 if (image == (Image *) NULL)
6984 {
6985 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6986 PackageName);
6987 goto PerlException;
6988 }
6989 package_info=ClonePackageInfo(info,exception);
6990 for (i=2; i < items; i+=2)
6991 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6992 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006993 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006994 scene=0;
6995 for (next=image; next; next=next->next)
6996 {
cristy151b66d2015-04-15 10:50:31 +00006997 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006998 next->scene=scene++;
6999 }
7000 SetImageInfo(package_info->image_info,(unsigned int)
7001 GetImageListLength(image),exception);
7002 EXTEND(sp,(ssize_t) GetImageListLength(image));
7003 for ( ; image; image=image->next)
7004 {
7005 length=0;
7006 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
7007 if (blob != (char *) NULL)
7008 {
7009 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
7010 blob=(unsigned char *) RelinquishMagickMemory(blob);
7011 }
7012 if (package_info->image_info->adjoin)
7013 break;
7014 }
7015
7016 PerlException:
7017 if (package_info != (struct PackageInfo *) NULL)
7018 DestroyPackageInfo(package_info);
7019 InheritPerlException(exception,perl_exception);
7020 exception=DestroyExceptionInfo(exception);
7021 SvREFCNT_dec(perl_exception); /* throw away all errors */
7022 }
7023
7024#
7025###############################################################################
7026# #
7027# #
7028# #
7029# L a y e r s #
7030# #
7031# #
7032# #
7033###############################################################################
7034#
7035#
7036void
7037Layers(ref,...)
7038 Image::Magick ref=NO_INIT
7039 ALIAS:
7040 Layers = 1
7041 layers = 2
7042 OptimizeImageLayers = 3
7043 optimizelayers = 4
7044 optimizeimagelayers = 5
7045 PPCODE:
7046 {
7047 AV
7048 *av;
7049
7050 char
7051 *attribute;
7052
7053 CompositeOperator
7054 compose;
7055
7056 ExceptionInfo
7057 *exception;
7058
7059 HV
7060 *hv;
7061
7062 Image
7063 *image,
7064 *layers;
7065
7066 LayerMethod
7067 method;
7068
7069 register ssize_t
7070 i;
7071
7072 ssize_t
7073 option,
7074 sp;
7075
7076 struct PackageInfo
7077 *info;
7078
7079 SV
7080 *av_reference,
7081 *perl_exception,
7082 *reference,
7083 *rv,
7084 *sv;
7085
7086 PERL_UNUSED_VAR(ref);
7087 PERL_UNUSED_VAR(ix);
7088 exception=AcquireExceptionInfo();
7089 perl_exception=newSVpv("",0);
7090 sv=NULL;
7091 if (sv_isobject(ST(0)) == 0)
7092 {
7093 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7094 PackageName);
7095 goto PerlException;
7096 }
7097 reference=SvRV(ST(0));
7098 hv=SvSTASH(reference);
7099 av=newAV();
7100 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7101 SvREFCNT_dec(av);
7102 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7103 if (image == (Image *) NULL)
7104 {
7105 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7106 PackageName);
7107 goto PerlException;
7108 }
7109 compose=image->compose;
7110 method=OptimizeLayer;
7111 for (i=2; i < items; i+=2)
7112 {
7113 attribute=(char *) SvPV(ST(i-1),na);
7114 switch (*attribute)
7115 {
7116 case 'C':
7117 case 'c':
7118 {
7119 if (LocaleCompare(attribute,"compose") == 0)
7120 {
7121 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7122 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7123 if (sp < 0)
7124 {
7125 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7126 SvPV(ST(i),na));
7127 break;
7128 }
7129 compose=(CompositeOperator) sp;
7130 break;
7131 }
7132 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7133 attribute);
7134 break;
7135 }
7136 case 'M':
7137 case 'm':
7138 {
7139 if (LocaleCompare(attribute,"method") == 0)
7140 {
7141 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7142 SvPV(ST(i),na));
7143 if (option < 0)
7144 {
7145 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7146 SvPV(ST(i),na));
7147 break;
7148 }
7149 method=(LayerMethod) option;
7150 break;
7151 }
7152 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7153 attribute);
7154 break;
7155 }
7156 default:
7157 {
7158 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7159 attribute);
7160 break;
7161 }
7162 }
7163 }
7164 layers=(Image *) NULL;
7165 switch (method)
7166 {
7167 case CompareAnyLayer:
7168 case CompareClearLayer:
7169 case CompareOverlayLayer:
7170 default:
7171 {
7172 layers=CompareImagesLayers(image,method,exception);
7173 break;
7174 }
7175 case MergeLayer:
7176 case FlattenLayer:
7177 case MosaicLayer:
7178 {
7179 layers=MergeImageLayers(image,method,exception);
7180 break;
7181 }
7182 case DisposeLayer:
7183 {
7184 layers=DisposeImages(image,exception);
7185 break;
7186 }
7187 case OptimizeImageLayer:
7188 {
7189 layers=OptimizeImageLayers(image,exception);
7190 break;
7191 }
7192 case OptimizePlusLayer:
7193 {
7194 layers=OptimizePlusImageLayers(image,exception);
7195 break;
7196 }
7197 case OptimizeTransLayer:
7198 {
7199 OptimizeImageTransparency(image,exception);
7200 break;
7201 }
7202 case RemoveDupsLayer:
7203 {
7204 RemoveDuplicateLayers(&image,exception);
7205 break;
7206 }
7207 case RemoveZeroLayer:
7208 {
7209 RemoveZeroDelayLayers(&image,exception);
7210 break;
7211 }
7212 case OptimizeLayer:
7213 {
7214 QuantizeInfo
7215 *quantize_info;
7216
7217 /*
7218 General Purpose, GIF Animation Optimizer.
7219 */
7220 layers=CoalesceImages(image,exception);
7221 if (layers == (Image *) NULL)
7222 break;
7223 image=layers;
7224 layers=OptimizeImageLayers(image,exception);
7225 if (layers == (Image *) NULL)
7226 break;
7227 image=DestroyImageList(image);
7228 image=layers;
7229 layers=(Image *) NULL;
7230 OptimizeImageTransparency(image,exception);
7231 quantize_info=AcquireQuantizeInfo(info->image_info);
7232 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7233 quantize_info=DestroyQuantizeInfo(quantize_info);
7234 break;
7235 }
7236 case CompositeLayer:
7237 {
7238 Image
7239 *source;
7240
7241 RectangleInfo
7242 geometry;
7243
7244 /*
7245 Split image sequence at the first 'NULL:' image.
7246 */
7247 source=image;
7248 while (source != (Image *) NULL)
7249 {
7250 source=GetNextImageInList(source);
7251 if ((source != (Image *) NULL) &&
7252 (LocaleCompare(source->magick,"NULL") == 0))
7253 break;
7254 }
7255 if (source != (Image *) NULL)
7256 {
7257 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7258 (GetNextImageInList(source) == (Image *) NULL))
7259 source=(Image *) NULL;
7260 else
7261 {
7262 /*
7263 Separate the two lists, junk the null: image.
7264 */
7265 source=SplitImageList(source->previous);
7266 DeleteImageFromList(&source);
7267 }
7268 }
7269 if (source == (Image *) NULL)
7270 {
7271 (void) ThrowMagickException(exception,GetMagickModule(),
7272 OptionError,"MissingNullSeparator","layers Composite");
7273 break;
7274 }
7275 /*
7276 Adjust offset with gravity and virtual canvas.
7277 */
7278 SetGeometry(image,&geometry);
7279 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7280 geometry.width=source->page.width != 0 ? source->page.width :
7281 source->columns;
7282 geometry.height=source->page.height != 0 ? source->page.height :
7283 source->rows;
7284 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7285 image->columns,image->page.height != 0 ? image->page.height :
7286 image->rows,image->gravity,&geometry);
7287 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7288 source=DestroyImageList(source);
7289 break;
7290 }
7291 }
7292 if (layers != (Image *) NULL)
7293 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007294 else
7295 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007296 if (image == (Image *) NULL)
7297 goto PerlException;
7298 for ( ; image; image=image->next)
7299 {
7300 AddImageToRegistry(sv,image);
7301 rv=newRV(sv);
7302 av_push(av,sv_bless(rv,hv));
7303 SvREFCNT_dec(sv);
7304 }
7305 exception=DestroyExceptionInfo(exception);
7306 ST(0)=av_reference;
7307 SvREFCNT_dec(perl_exception);
7308 XSRETURN(1);
7309
7310 PerlException:
7311 InheritPerlException(exception,perl_exception);
7312 exception=DestroyExceptionInfo(exception);
7313 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7314 SvPOK_on(perl_exception);
7315 ST(0)=sv_2mortal(perl_exception);
7316 XSRETURN(1);
7317 }
7318
7319#
7320###############################################################################
7321# #
7322# #
7323# #
7324# M a g i c k T o M i m e #
7325# #
7326# #
7327# #
7328###############################################################################
7329#
7330#
7331SV *
7332MagickToMime(ref,name)
7333 Image::Magick ref=NO_INIT
7334 char *name
7335 ALIAS:
7336 magicktomime = 1
7337 CODE:
7338 {
7339 char
7340 *mime;
7341
7342 PERL_UNUSED_VAR(ref);
7343 PERL_UNUSED_VAR(ix);
7344 mime=MagickToMime(name);
7345 RETVAL=newSVpv(mime,0);
7346 mime=(char *) RelinquishMagickMemory(mime);
7347 }
7348 OUTPUT:
7349 RETVAL
7350
7351#
7352###############################################################################
7353# #
7354# #
7355# #
7356# M o g r i f y #
7357# #
7358# #
7359# #
7360###############################################################################
7361#
7362#
7363void
7364Mogrify(ref,...)
7365 Image::Magick ref=NO_INIT
7366 ALIAS:
7367 Comment = 1
7368 CommentImage = 2
7369 Label = 3
7370 LabelImage = 4
7371 AddNoise = 5
7372 AddNoiseImage = 6
7373 Colorize = 7
7374 ColorizeImage = 8
7375 Border = 9
7376 BorderImage = 10
7377 Blur = 11
7378 BlurImage = 12
7379 Chop = 13
7380 ChopImage = 14
7381 Crop = 15
7382 CropImage = 16
7383 Despeckle = 17
7384 DespeckleImage = 18
7385 Edge = 19
7386 EdgeImage = 20
7387 Emboss = 21
7388 EmbossImage = 22
7389 Enhance = 23
7390 EnhanceImage = 24
7391 Flip = 25
7392 FlipImage = 26
7393 Flop = 27
7394 FlopImage = 28
7395 Frame = 29
7396 FrameImage = 30
7397 Implode = 31
7398 ImplodeImage = 32
7399 Magnify = 33
7400 MagnifyImage = 34
7401 MedianFilter = 35
7402 MedianConvolveImage = 36
7403 Minify = 37
7404 MinifyImage = 38
7405 OilPaint = 39
7406 OilPaintImage = 40
7407 ReduceNoise = 41
7408 ReduceNoiseImage = 42
7409 Roll = 43
7410 RollImage = 44
7411 Rotate = 45
7412 RotateImage = 46
7413 Sample = 47
7414 SampleImage = 48
7415 Scale = 49
7416 ScaleImage = 50
7417 Shade = 51
7418 ShadeImage = 52
7419 Sharpen = 53
7420 SharpenImage = 54
7421 Shear = 55
7422 ShearImage = 56
7423 Spread = 57
7424 SpreadImage = 58
7425 Swirl = 59
7426 SwirlImage = 60
7427 Resize = 61
7428 ResizeImage = 62
7429 Zoom = 63
7430 ZoomImage = 64
7431 Annotate = 65
7432 AnnotateImage = 66
7433 ColorFloodfill = 67
7434 ColorFloodfillImage= 68
7435 Composite = 69
7436 CompositeImage = 70
7437 Contrast = 71
7438 ContrastImage = 72
7439 CycleColormap = 73
7440 CycleColormapImage = 74
7441 Draw = 75
7442 DrawImage = 76
7443 Equalize = 77
7444 EqualizeImage = 78
7445 Gamma = 79
7446 GammaImage = 80
7447 Map = 81
7448 MapImage = 82
7449 MatteFloodfill = 83
7450 MatteFloodfillImage= 84
7451 Modulate = 85
7452 ModulateImage = 86
7453 Negate = 87
7454 NegateImage = 88
7455 Normalize = 89
7456 NormalizeImage = 90
7457 NumberColors = 91
7458 NumberColorsImage = 92
7459 Opaque = 93
7460 OpaqueImage = 94
7461 Quantize = 95
7462 QuantizeImage = 96
7463 Raise = 97
7464 RaiseImage = 98
7465 Segment = 99
7466 SegmentImage = 100
7467 Signature = 101
7468 SignatureImage = 102
7469 Solarize = 103
7470 SolarizeImage = 104
7471 Sync = 105
7472 SyncImage = 106
7473 Texture = 107
7474 TextureImage = 108
7475 Evaluate = 109
7476 EvaluateImage = 110
7477 Transparent = 111
7478 TransparentImage = 112
7479 Threshold = 113
7480 ThresholdImage = 114
7481 Charcoal = 115
7482 CharcoalImage = 116
7483 Trim = 117
7484 TrimImage = 118
7485 Wave = 119
7486 WaveImage = 120
7487 Separate = 121
7488 SeparateImage = 122
7489 Stereo = 125
7490 StereoImage = 126
7491 Stegano = 127
7492 SteganoImage = 128
7493 Deconstruct = 129
7494 DeconstructImage = 130
7495 GaussianBlur = 131
7496 GaussianBlurImage = 132
7497 Convolve = 133
7498 ConvolveImage = 134
7499 Profile = 135
7500 ProfileImage = 136
7501 UnsharpMask = 137
7502 UnsharpMaskImage = 138
7503 MotionBlur = 139
7504 MotionBlurImage = 140
7505 OrderedDither = 141
7506 OrderedDitherImage = 142
7507 Shave = 143
7508 ShaveImage = 144
7509 Level = 145
7510 LevelImage = 146
7511 Clip = 147
7512 ClipImage = 148
7513 AffineTransform = 149
7514 AffineTransformImage = 150
7515 Difference = 151
7516 DifferenceImage = 152
7517 AdaptiveThreshold = 153
7518 AdaptiveThresholdImage = 154
7519 Resample = 155
7520 ResampleImage = 156
7521 Describe = 157
7522 DescribeImage = 158
7523 BlackThreshold = 159
7524 BlackThresholdImage= 160
7525 WhiteThreshold = 161
7526 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007527 RotationalBlur = 163
7528 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007529 Thumbnail = 165
7530 ThumbnailImage = 166
7531 Strip = 167
7532 StripImage = 168
7533 Tint = 169
7534 TintImage = 170
7535 Channel = 171
7536 ChannelImage = 172
7537 Splice = 173
7538 SpliceImage = 174
7539 Posterize = 175
7540 PosterizeImage = 176
7541 Shadow = 177
7542 ShadowImage = 178
7543 Identify = 179
7544 IdentifyImage = 180
7545 SepiaTone = 181
7546 SepiaToneImage = 182
7547 SigmoidalContrast = 183
7548 SigmoidalContrastImage = 184
7549 Extent = 185
7550 ExtentImage = 186
7551 Vignette = 187
7552 VignetteImage = 188
7553 ContrastStretch = 189
7554 ContrastStretchImage = 190
7555 Sans0 = 191
7556 Sans0Image = 192
7557 Sans1 = 193
7558 Sans1Image = 194
7559 AdaptiveSharpen = 195
7560 AdaptiveSharpenImage = 196
7561 Transpose = 197
7562 TransposeImage = 198
7563 Transverse = 199
7564 TransverseImage = 200
7565 AutoOrient = 201
7566 AutoOrientImage = 202
7567 AdaptiveBlur = 203
7568 AdaptiveBlurImage = 204
7569 Sketch = 205
7570 SketchImage = 206
7571 UniqueColors = 207
7572 UniqueColorsImage = 208
7573 AdaptiveResize = 209
7574 AdaptiveResizeImage= 210
7575 ClipMask = 211
7576 ClipMaskImage = 212
7577 LinearStretch = 213
7578 LinearStretchImage = 214
7579 ColorMatrix = 215
7580 ColorMatrixImage = 216
7581 Mask = 217
7582 MaskImage = 218
7583 Polaroid = 219
7584 PolaroidImage = 220
7585 FloodfillPaint = 221
7586 FloodfillPaintImage= 222
7587 Distort = 223
7588 DistortImage = 224
7589 Clut = 225
7590 ClutImage = 226
7591 LiquidRescale = 227
7592 LiquidRescaleImage = 228
7593 Encipher = 229
7594 EncipherImage = 230
7595 Decipher = 231
7596 DecipherImage = 232
7597 Deskew = 233
7598 DeskewImage = 234
7599 Remap = 235
7600 RemapImage = 236
7601 SparseColor = 237
7602 SparseColorImage = 238
7603 Function = 239
7604 FunctionImage = 240
7605 SelectiveBlur = 241
7606 SelectiveBlurImage = 242
7607 HaldClut = 243
7608 HaldClutImage = 244
7609 BlueShift = 245
7610 BlueShiftImage = 246
7611 ForwardFourierTransform = 247
7612 ForwardFourierTransformImage = 248
7613 InverseFourierTransform = 249
7614 InverseFourierTransformImage = 250
7615 ColorDecisionList = 251
7616 ColorDecisionListImage = 252
7617 AutoGamma = 253
7618 AutoGammaImage = 254
7619 AutoLevel = 255
7620 AutoLevelImage = 256
7621 LevelColors = 257
7622 LevelImageColors = 258
7623 Clamp = 259
7624 ClampImage = 260
7625 BrightnessContrast = 261
7626 BrightnessContrastImage = 262
7627 Morphology = 263
7628 MorphologyImage = 264
Cristy3ca633e2016-02-13 12:49:01 -05007629 Mode = 265
7630 ModeImage = 266
7631 Statistic = 267
7632 StatisticImage = 268
7633 Perceptible = 269
7634 PerceptibleImage = 270
7635 Poly = 271
7636 PolyImage = 272
7637 Grayscale = 273
7638 GrayscaleImage = 274
7639 CannyEdge = 275
7640 CannyEdgeImage = 276
7641 HoughLine = 277
7642 HoughLineImage = 278
7643 MeanShift = 279
7644 MeanShiftImage = 280
7645 Kuwahara = 281
7646 KuwaharaImage = 282
Cristy0f5df812017-07-04 18:30:05 -04007647 ConnectedComponents = 283
7648 ConnectedComponentsImage = 284
Cristy3ca633e2016-02-13 12:49:01 -05007649 CopyPixels = 285
7650 CopyImagePixels = 286
Cristy5488c982016-02-13 14:07:50 -05007651 Color = 287
7652 ColorImage = 288
Cristy2d830ed2016-02-21 10:54:16 -05007653 WaveletDenoise = 289
7654 WaveletDenoiseImage= 290
Cristy99a57162016-12-05 11:47:57 -05007655 Colorspace = 291
7656 ColorspaceImage = 292
Cristy53353872017-07-02 12:24:24 -04007657 AutoThreshold = 293
7658 AutoThresholdImage = 294
Cristy532b3382018-08-05 17:56:56 -04007659 RangeThreshold = 295
7660 RangeThresholdImage= 296
Cristy9f252542018-11-21 19:13:46 -05007661 CLAHE = 297
7662 CLAHEImage = 298
Cristyb4ab5192019-12-19 06:53:46 -05007663 Kmeans = 299
7664 KMeansImage = 300
cristy4a3ce0a2013-08-03 20:06:59 +00007665 MogrifyRegion = 666
7666 PPCODE:
7667 {
7668 AffineMatrix
7669 affine,
7670 current;
7671
7672 char
7673 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007674 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007675
7676 ChannelType
7677 channel,
7678 channel_mask;
7679
7680 CompositeOperator
7681 compose;
7682
7683 const char
7684 *attribute,
7685 *value;
7686
7687 double
7688 angle;
7689
7690 ExceptionInfo
7691 *exception;
7692
7693 GeometryInfo
7694 geometry_info;
7695
7696 Image
7697 *image,
Cristy7e567962018-02-03 12:42:20 -05007698 *next;
cristy4a3ce0a2013-08-03 20:06:59 +00007699
cristy4a3ce0a2013-08-03 20:06:59 +00007700 MagickStatusType
7701 flags;
7702
7703 PixelInfo
7704 fill_color;
7705
7706 RectangleInfo
7707 geometry,
7708 region_info;
7709
7710 register ssize_t
7711 i;
7712
7713 ssize_t
7714 base,
7715 j,
7716 number_images;
7717
7718 struct Methods
7719 *rp;
7720
7721 struct PackageInfo
7722 *info;
7723
7724 SV
7725 *perl_exception,
7726 **pv,
7727 *reference,
7728 **reference_vector;
7729
7730 struct ArgumentList
7731 argument_list[MaxArguments];
7732
7733 PERL_UNUSED_VAR(ref);
7734 PERL_UNUSED_VAR(ix);
7735 exception=AcquireExceptionInfo();
7736 perl_exception=newSVpv("",0);
7737 reference_vector=NULL;
cristy4a3ce0a2013-08-03 20:06:59 +00007738 number_images=0;
7739 base=2;
7740 if (sv_isobject(ST(0)) == 0)
7741 {
7742 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7743 PackageName);
7744 goto PerlException;
7745 }
7746 reference=SvRV(ST(0));
7747 region_info.width=0;
7748 region_info.height=0;
7749 region_info.x=0;
7750 region_info.y=0;
cristy4a3ce0a2013-08-03 20:06:59 +00007751 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7752 if (ix && (ix != 666))
7753 {
7754 /*
7755 Called as Method(...)
7756 */
7757 ix=(ix+1)/2;
7758 rp=(&Methods[ix-1]);
7759 attribute=rp->name;
7760 }
7761 else
7762 {
7763 /*
7764 Called as Mogrify("Method",...)
7765 */
7766 attribute=(char *) SvPV(ST(1),na);
7767 if (ix)
7768 {
7769 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7770 attribute=(char *) SvPV(ST(2),na);
7771 base++;
7772 }
7773 for (rp=Methods; ; rp++)
7774 {
7775 if (rp >= EndOf(Methods))
7776 {
7777 ThrowPerlException(exception,OptionError,
7778 "UnrecognizedPerlMagickMethod",attribute);
7779 goto PerlException;
7780 }
7781 if (strEQcase(attribute,rp->name))
7782 break;
7783 }
7784 ix=rp-Methods+1;
7785 base++;
7786 }
7787 if (image == (Image *) NULL)
7788 {
7789 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7790 goto PerlException;
7791 }
7792 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7793 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7794 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7795 {
7796 Arguments
7797 *pp,
7798 *qq;
7799
7800 ssize_t
7801 ssize_test;
7802
7803 struct ArgumentList
7804 *al;
7805
7806 SV
7807 *sv;
7808
7809 sv=NULL;
7810 ssize_test=0;
7811 pp=(Arguments *) NULL;
7812 qq=rp->arguments;
7813 if (i == items)
7814 {
7815 pp=rp->arguments,
7816 sv=ST(i-1);
7817 }
7818 else
7819 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7820 {
7821 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7822 break;
7823 if (strEQcase(attribute,qq->method) > ssize_test)
7824 {
7825 pp=qq;
7826 ssize_test=strEQcase(attribute,qq->method);
7827 }
7828 }
7829 if (pp == (Arguments *) NULL)
7830 {
7831 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7832 attribute);
7833 goto continue_outer_loop;
7834 }
7835 al=(&argument_list[pp-rp->arguments]);
7836 switch (pp->type)
7837 {
7838 case ArrayReference:
7839 {
7840 if (SvTYPE(sv) != SVt_RV)
7841 {
cristy151b66d2015-04-15 10:50:31 +00007842 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007843 "invalid %.60s value",pp->method);
7844 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7845 goto continue_outer_loop;
7846 }
7847 al->array_reference=SvRV(sv);
7848 break;
7849 }
7850 case RealReference:
7851 {
7852 al->real_reference=SvNV(sv);
7853 break;
7854 }
7855 case FileReference:
7856 {
7857 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7858 break;
7859 }
7860 case ImageReference:
7861 {
7862 if (!sv_isobject(sv) ||
7863 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7864 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7865 {
7866 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7867 PackageName);
7868 goto PerlException;
7869 }
7870 break;
7871 }
7872 case IntegerReference:
7873 {
7874 al->integer_reference=SvIV(sv);
7875 break;
7876 }
7877 case StringReference:
7878 {
7879 al->string_reference=(char *) SvPV(sv,al->length);
7880 if (sv_isobject(sv))
7881 al->image_reference=SetupList(aTHX_ SvRV(sv),
7882 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7883 break;
7884 }
7885 default:
7886 {
7887 /*
7888 Is a string; look up name.
7889 */
7890 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7891 {
7892 al->string_reference=(char *) SvPV(sv,al->length);
7893 al->integer_reference=(-1);
7894 break;
7895 }
7896 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7897 MagickFalse,SvPV(sv,na));
7898 if (pp->type == MagickChannelOptions)
7899 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7900 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7901 {
cristy151b66d2015-04-15 10:50:31 +00007902 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007903 "invalid %.60s value",pp->method);
7904 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7905 goto continue_outer_loop;
7906 }
7907 break;
7908 }
7909 }
7910 attribute_flag[pp-rp->arguments]++;
7911 continue_outer_loop: ;
7912 }
7913 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7914 pv=reference_vector;
7915 SetGeometryInfo(&geometry_info);
7916 channel=DefaultChannels;
7917 for (next=image; next; next=next->next)
7918 {
7919 image=next;
7920 SetGeometry(image,&geometry);
7921 if ((region_info.width*region_info.height) != 0)
Cristy7e567962018-02-03 12:42:20 -05007922 (void) SetImageRegionMask(image,WritePixelMask,&region_info,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007923 switch (ix)
7924 {
7925 default:
7926 {
cristy151b66d2015-04-15 10:50:31 +00007927 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007928 ThrowPerlException(exception,OptionError,
7929 "UnrecognizedPerlMagickMethod",message);
7930 goto PerlException;
7931 }
7932 case 1: /* Comment */
7933 {
7934 if (attribute_flag[0] == 0)
7935 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007936 (void) SetImageProperty(image,"comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007937 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007938 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007939 break;
7940 }
7941 case 2: /* Label */
7942 {
7943 if (attribute_flag[0] == 0)
7944 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007945 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007946 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007947 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007948 break;
7949 }
7950 case 3: /* AddNoise */
7951 {
7952 double
7953 attenuate;
7954
7955 if (attribute_flag[0] == 0)
7956 argument_list[0].integer_reference=UniformNoise;
7957 attenuate=1.0;
7958 if (attribute_flag[1] != 0)
7959 attenuate=argument_list[1].real_reference;
7960 if (attribute_flag[2] != 0)
7961 channel=(ChannelType) argument_list[2].integer_reference;
7962 channel_mask=SetImageChannelMask(image,channel);
7963 image=AddNoiseImage(image,(NoiseType)
7964 argument_list[0].integer_reference,attenuate,exception);
7965 if (image != (Image *) NULL)
7966 (void) SetImageChannelMask(image,channel_mask);
7967 break;
7968 }
7969 case 4: /* Colorize */
7970 {
7971 PixelInfo
7972 target;
7973
7974 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7975 0,0,&target,exception);
7976 if (attribute_flag[0] != 0)
7977 (void) QueryColorCompliance(argument_list[0].string_reference,
7978 AllCompliance,&target,exception);
7979 if (attribute_flag[1] == 0)
7980 argument_list[1].string_reference="100%";
7981 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7982 exception);
7983 break;
7984 }
7985 case 5: /* Border */
7986 {
7987 CompositeOperator
7988 compose;
7989
7990 geometry.width=0;
7991 geometry.height=0;
7992 if (attribute_flag[0] != 0)
7993 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7994 &geometry,exception);
7995 if (attribute_flag[1] != 0)
7996 geometry.width=argument_list[1].integer_reference;
7997 if (attribute_flag[2] != 0)
7998 geometry.height=argument_list[2].integer_reference;
7999 if (attribute_flag[3] != 0)
8000 QueryColorCompliance(argument_list[3].string_reference,
8001 AllCompliance,&image->border_color,exception);
8002 if (attribute_flag[4] != 0)
8003 QueryColorCompliance(argument_list[4].string_reference,
8004 AllCompliance,&image->border_color,exception);
8005 if (attribute_flag[5] != 0)
8006 QueryColorCompliance(argument_list[5].string_reference,
8007 AllCompliance,&image->border_color,exception);
8008 compose=image->compose;
8009 if (attribute_flag[6] != 0)
8010 compose=(CompositeOperator) argument_list[6].integer_reference;
8011 image=BorderImage(image,&geometry,compose,exception);
8012 break;
8013 }
8014 case 6: /* Blur */
8015 {
8016 if (attribute_flag[0] != 0)
8017 {
8018 flags=ParseGeometry(argument_list[0].string_reference,
8019 &geometry_info);
8020 if ((flags & SigmaValue) == 0)
8021 geometry_info.sigma=1.0;
8022 }
8023 if (attribute_flag[1] != 0)
8024 geometry_info.rho=argument_list[1].real_reference;
8025 if (attribute_flag[2] != 0)
8026 geometry_info.sigma=argument_list[2].real_reference;
8027 if (attribute_flag[3] != 0)
8028 channel=(ChannelType) argument_list[3].integer_reference;
8029 channel_mask=SetImageChannelMask(image,channel);
8030 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
8031 exception);
8032 if (image != (Image *) NULL)
8033 (void) SetImageChannelMask(image,channel_mask);
8034 break;
8035 }
8036 case 7: /* Chop */
8037 {
cristy260bd762014-08-15 12:46:34 +00008038 if (attribute_flag[5] != 0)
8039 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00008040 if (attribute_flag[0] != 0)
8041 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8042 &geometry,exception);
8043 if (attribute_flag[1] != 0)
8044 geometry.width=argument_list[1].integer_reference;
8045 if (attribute_flag[2] != 0)
8046 geometry.height=argument_list[2].integer_reference;
8047 if (attribute_flag[3] != 0)
8048 geometry.x=argument_list[3].integer_reference;
8049 if (attribute_flag[4] != 0)
8050 geometry.y=argument_list[4].integer_reference;
8051 image=ChopImage(image,&geometry,exception);
8052 break;
8053 }
8054 case 8: /* Crop */
8055 {
8056 if (attribute_flag[6] != 0)
8057 image->gravity=(GravityType) argument_list[6].integer_reference;
8058 if (attribute_flag[0] != 0)
8059 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8060 &geometry,exception);
8061 if (attribute_flag[1] != 0)
8062 geometry.width=argument_list[1].integer_reference;
8063 if (attribute_flag[2] != 0)
8064 geometry.height=argument_list[2].integer_reference;
8065 if (attribute_flag[3] != 0)
8066 geometry.x=argument_list[3].integer_reference;
8067 if (attribute_flag[4] != 0)
8068 geometry.y=argument_list[4].integer_reference;
8069 if (attribute_flag[5] != 0)
8070 image->fuzz=StringToDoubleInterval(
8071 argument_list[5].string_reference,(double) QuantumRange+1.0);
8072 image=CropImage(image,&geometry,exception);
8073 break;
8074 }
8075 case 9: /* Despeckle */
8076 {
8077 image=DespeckleImage(image,exception);
8078 break;
8079 }
8080 case 10: /* Edge */
8081 {
8082 if (attribute_flag[0] != 0)
8083 geometry_info.rho=argument_list[0].real_reference;
8084 image=EdgeImage(image,geometry_info.rho,exception);
8085 break;
8086 }
8087 case 11: /* Emboss */
8088 {
8089 if (attribute_flag[0] != 0)
8090 {
8091 flags=ParseGeometry(argument_list[0].string_reference,
8092 &geometry_info);
8093 if ((flags & SigmaValue) == 0)
8094 geometry_info.sigma=1.0;
8095 }
8096 if (attribute_flag[1] != 0)
8097 geometry_info.rho=argument_list[1].real_reference;
8098 if (attribute_flag[2] != 0)
8099 geometry_info.sigma=argument_list[2].real_reference;
8100 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8101 exception);
8102 break;
8103 }
8104 case 12: /* Enhance */
8105 {
8106 image=EnhanceImage(image,exception);
8107 break;
8108 }
8109 case 13: /* Flip */
8110 {
8111 image=FlipImage(image,exception);
8112 break;
8113 }
8114 case 14: /* Flop */
8115 {
8116 image=FlopImage(image,exception);
8117 break;
8118 }
8119 case 15: /* Frame */
8120 {
8121 CompositeOperator
8122 compose;
8123
8124 FrameInfo
8125 frame_info;
8126
8127 if (attribute_flag[0] != 0)
8128 {
8129 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8130 &geometry,exception);
8131 frame_info.width=geometry.width;
8132 frame_info.height=geometry.height;
8133 frame_info.outer_bevel=geometry.x;
8134 frame_info.inner_bevel=geometry.y;
8135 }
8136 if (attribute_flag[1] != 0)
8137 frame_info.width=argument_list[1].integer_reference;
8138 if (attribute_flag[2] != 0)
8139 frame_info.height=argument_list[2].integer_reference;
8140 if (attribute_flag[3] != 0)
8141 frame_info.inner_bevel=argument_list[3].integer_reference;
8142 if (attribute_flag[4] != 0)
8143 frame_info.outer_bevel=argument_list[4].integer_reference;
8144 if (attribute_flag[5] != 0)
8145 QueryColorCompliance(argument_list[5].string_reference,
8146 AllCompliance,&fill_color,exception);
8147 if (attribute_flag[6] != 0)
8148 QueryColorCompliance(argument_list[6].string_reference,
8149 AllCompliance,&fill_color,exception);
8150 frame_info.x=(ssize_t) frame_info.width;
8151 frame_info.y=(ssize_t) frame_info.height;
8152 frame_info.width=image->columns+2*frame_info.x;
8153 frame_info.height=image->rows+2*frame_info.y;
8154 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
Cristy8645e042016-02-03 16:35:29 -05008155 image->alpha_color=fill_color;
cristy4a3ce0a2013-08-03 20:06:59 +00008156 compose=image->compose;
8157 if (attribute_flag[7] != 0)
8158 compose=(CompositeOperator) argument_list[7].integer_reference;
8159 image=FrameImage(image,&frame_info,compose,exception);
8160 break;
8161 }
8162 case 16: /* Implode */
8163 {
8164 PixelInterpolateMethod
8165 method;
8166
8167 if (attribute_flag[0] == 0)
8168 argument_list[0].real_reference=0.5;
8169 method=UndefinedInterpolatePixel;
8170 if (attribute_flag[1] != 0)
8171 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8172 image=ImplodeImage(image,argument_list[0].real_reference,
8173 method,exception);
8174 break;
8175 }
8176 case 17: /* Magnify */
8177 {
8178 image=MagnifyImage(image,exception);
8179 break;
8180 }
8181 case 18: /* MedianFilter */
8182 {
8183 if (attribute_flag[0] != 0)
8184 {
8185 flags=ParseGeometry(argument_list[0].string_reference,
8186 &geometry_info);
8187 if ((flags & SigmaValue) == 0)
8188 geometry_info.sigma=geometry_info.rho;
8189 }
8190 if (attribute_flag[1] != 0)
8191 geometry_info.rho=argument_list[1].real_reference;
8192 if (attribute_flag[2] != 0)
8193 geometry_info.sigma=argument_list[2].real_reference;
8194 if (attribute_flag[3] != 0)
8195 channel=(ChannelType) argument_list[3].integer_reference;
8196 channel_mask=SetImageChannelMask(image,channel);
8197 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8198 (size_t) geometry_info.sigma,exception);
8199 if (image != (Image *) NULL)
8200 (void) SetImageChannelMask(image,channel_mask);
8201 break;
8202 }
8203 case 19: /* Minify */
8204 {
8205 image=MinifyImage(image,exception);
8206 break;
8207 }
8208 case 20: /* OilPaint */
8209 {
8210 if (attribute_flag[0] == 0)
8211 argument_list[0].real_reference=0.0;
8212 if (attribute_flag[1] == 0)
8213 argument_list[1].real_reference=1.0;
8214 image=OilPaintImage(image,argument_list[0].real_reference,
8215 argument_list[1].real_reference,exception);
8216 break;
8217 }
8218 case 21: /* ReduceNoise */
8219 {
8220 if (attribute_flag[0] != 0)
8221 {
8222 flags=ParseGeometry(argument_list[0].string_reference,
8223 &geometry_info);
8224 if ((flags & SigmaValue) == 0)
8225 geometry_info.sigma=1.0;
8226 }
8227 if (attribute_flag[1] != 0)
8228 geometry_info.rho=argument_list[1].real_reference;
8229 if (attribute_flag[2] != 0)
8230 geometry_info.sigma=argument_list[2].real_reference;
8231 if (attribute_flag[3] != 0)
8232 channel=(ChannelType) argument_list[3].integer_reference;
8233 channel_mask=SetImageChannelMask(image,channel);
8234 image=StatisticImage(image,NonpeakStatistic,(size_t)
8235 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8236 if (image != (Image *) NULL)
8237 (void) SetImageChannelMask(image,channel_mask);
8238 break;
8239 }
8240 case 22: /* Roll */
8241 {
8242 if (attribute_flag[0] != 0)
Cristyf94b0842017-07-14 07:05:02 -04008243 {
8244 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8245 &geometry,exception);
8246 if ((flags & PercentValue) != 0)
8247 {
8248 geometry.x*=(double) image->columns/100.0;
8249 geometry.y*=(double) image->rows/100.0;
8250 }
8251 }
cristy4a3ce0a2013-08-03 20:06:59 +00008252 if (attribute_flag[1] != 0)
8253 geometry.x=argument_list[1].integer_reference;
8254 if (attribute_flag[2] != 0)
8255 geometry.y=argument_list[2].integer_reference;
8256 image=RollImage(image,geometry.x,geometry.y,exception);
8257 break;
8258 }
8259 case 23: /* Rotate */
8260 {
8261 if (attribute_flag[0] == 0)
8262 argument_list[0].real_reference=90.0;
8263 if (attribute_flag[1] != 0)
8264 {
8265 QueryColorCompliance(argument_list[1].string_reference,
8266 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008267 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8268 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008269 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8270 }
8271 image=RotateImage(image,argument_list[0].real_reference,exception);
8272 break;
8273 }
8274 case 24: /* Sample */
8275 {
8276 if (attribute_flag[0] != 0)
8277 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8278 &geometry,exception);
8279 if (attribute_flag[1] != 0)
8280 geometry.width=argument_list[1].integer_reference;
8281 if (attribute_flag[2] != 0)
8282 geometry.height=argument_list[2].integer_reference;
8283 image=SampleImage(image,geometry.width,geometry.height,exception);
8284 break;
8285 }
8286 case 25: /* Scale */
8287 {
8288 if (attribute_flag[0] != 0)
8289 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8290 &geometry,exception);
8291 if (attribute_flag[1] != 0)
8292 geometry.width=argument_list[1].integer_reference;
8293 if (attribute_flag[2] != 0)
8294 geometry.height=argument_list[2].integer_reference;
8295 image=ScaleImage(image,geometry.width,geometry.height,exception);
8296 break;
8297 }
8298 case 26: /* Shade */
8299 {
8300 if (attribute_flag[0] != 0)
8301 {
8302 flags=ParseGeometry(argument_list[0].string_reference,
8303 &geometry_info);
8304 if ((flags & SigmaValue) == 0)
8305 geometry_info.sigma=0.0;
8306 }
8307 if (attribute_flag[1] != 0)
8308 geometry_info.rho=argument_list[1].real_reference;
8309 if (attribute_flag[2] != 0)
8310 geometry_info.sigma=argument_list[2].real_reference;
8311 image=ShadeImage(image,
8312 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8313 geometry_info.rho,geometry_info.sigma,exception);
8314 break;
8315 }
8316 case 27: /* Sharpen */
8317 {
8318 if (attribute_flag[0] != 0)
8319 {
8320 flags=ParseGeometry(argument_list[0].string_reference,
8321 &geometry_info);
8322 if ((flags & SigmaValue) == 0)
8323 geometry_info.sigma=1.0;
8324 }
8325 if (attribute_flag[1] != 0)
8326 geometry_info.rho=argument_list[1].real_reference;
8327 if (attribute_flag[2] != 0)
8328 geometry_info.sigma=argument_list[2].real_reference;
8329 if (attribute_flag[3] != 0)
8330 channel=(ChannelType) argument_list[3].integer_reference;
8331 channel_mask=SetImageChannelMask(image,channel);
8332 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8333 exception);
8334 if (image != (Image *) NULL)
8335 (void) SetImageChannelMask(image,channel_mask);
8336 break;
8337 }
8338 case 28: /* Shear */
8339 {
8340 if (attribute_flag[0] != 0)
8341 {
8342 flags=ParseGeometry(argument_list[0].string_reference,
8343 &geometry_info);
8344 if ((flags & SigmaValue) == 0)
8345 geometry_info.sigma=geometry_info.rho;
8346 }
8347 if (attribute_flag[1] != 0)
8348 geometry_info.rho=argument_list[1].real_reference;
8349 if (attribute_flag[2] != 0)
8350 geometry_info.sigma=argument_list[2].real_reference;
8351 if (attribute_flag[3] != 0)
8352 QueryColorCompliance(argument_list[3].string_reference,
8353 AllCompliance,&image->background_color,exception);
8354 if (attribute_flag[4] != 0)
8355 QueryColorCompliance(argument_list[4].string_reference,
8356 AllCompliance,&image->background_color,exception);
8357 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8358 exception);
8359 break;
8360 }
8361 case 29: /* Spread */
8362 {
Cristye3319c12015-08-24 07:11:48 -04008363 PixelInterpolateMethod
8364 method;
8365
cristy4a3ce0a2013-08-03 20:06:59 +00008366 if (attribute_flag[0] == 0)
8367 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008368 method=UndefinedInterpolatePixel;
8369 if (attribute_flag[1] != 0)
8370 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8371 image=SpreadImage(image,method,argument_list[0].real_reference,
8372 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008373 break;
8374 }
8375 case 30: /* Swirl */
8376 {
8377 PixelInterpolateMethod
8378 method;
8379
8380 if (attribute_flag[0] == 0)
8381 argument_list[0].real_reference=50.0;
8382 method=UndefinedInterpolatePixel;
8383 if (attribute_flag[1] != 0)
8384 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8385 image=SwirlImage(image,argument_list[0].real_reference,
8386 method,exception);
8387 break;
8388 }
8389 case 31: /* Resize */
8390 case 32: /* Zoom */
8391 {
8392 if (attribute_flag[0] != 0)
8393 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8394 &geometry,exception);
8395 if (attribute_flag[1] != 0)
8396 geometry.width=argument_list[1].integer_reference;
8397 if (attribute_flag[2] != 0)
8398 geometry.height=argument_list[2].integer_reference;
8399 if (attribute_flag[3] == 0)
8400 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8401 if (attribute_flag[4] != 0)
8402 SetImageArtifact(image,"filter:support",
8403 argument_list[4].string_reference);
8404 image=ResizeImage(image,geometry.width,geometry.height,
Cristy8645e042016-02-03 16:35:29 -05008405 (FilterType) argument_list[3].integer_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00008406 exception);
8407 break;
8408 }
8409 case 33: /* Annotate */
8410 {
8411 DrawInfo
8412 *draw_info;
8413
8414 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8415 (DrawInfo *) NULL);
8416 if (attribute_flag[0] != 0)
8417 {
8418 char
8419 *text;
8420
8421 text=InterpretImageProperties(info ? info->image_info :
8422 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8423 exception);
8424 (void) CloneString(&draw_info->text,text);
8425 text=DestroyString(text);
8426 }
8427 if (attribute_flag[1] != 0)
8428 (void) CloneString(&draw_info->font,
8429 argument_list[1].string_reference);
8430 if (attribute_flag[2] != 0)
8431 draw_info->pointsize=argument_list[2].real_reference;
8432 if (attribute_flag[3] != 0)
8433 (void) CloneString(&draw_info->density,
8434 argument_list[3].string_reference);
8435 if (attribute_flag[4] != 0)
8436 (void) QueryColorCompliance(argument_list[4].string_reference,
8437 AllCompliance,&draw_info->undercolor,exception);
8438 if (attribute_flag[5] != 0)
8439 {
8440 (void) QueryColorCompliance(argument_list[5].string_reference,
8441 AllCompliance,&draw_info->stroke,exception);
8442 if (argument_list[5].image_reference != (Image *) NULL)
8443 draw_info->stroke_pattern=CloneImage(
8444 argument_list[5].image_reference,0,0,MagickTrue,exception);
8445 }
8446 if (attribute_flag[6] != 0)
8447 {
8448 (void) QueryColorCompliance(argument_list[6].string_reference,
8449 AllCompliance,&draw_info->fill,exception);
8450 if (argument_list[6].image_reference != (Image *) NULL)
8451 draw_info->fill_pattern=CloneImage(
8452 argument_list[6].image_reference,0,0,MagickTrue,exception);
8453 }
8454 if (attribute_flag[7] != 0)
8455 {
8456 (void) CloneString(&draw_info->geometry,
8457 argument_list[7].string_reference);
8458 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8459 &geometry,exception);
8460 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8461 geometry_info.sigma=geometry_info.xi;
8462 }
8463 if (attribute_flag[8] != 0)
8464 (void) QueryColorCompliance(argument_list[8].string_reference,
8465 AllCompliance,&draw_info->fill,exception);
8466 if (attribute_flag[11] != 0)
8467 draw_info->gravity=(GravityType)
8468 argument_list[11].integer_reference;
8469 if (attribute_flag[25] != 0)
8470 {
8471 AV
8472 *av;
8473
8474 av=(AV *) argument_list[25].array_reference;
8475 if ((av_len(av) != 3) && (av_len(av) != 5))
8476 {
8477 ThrowPerlException(exception,OptionError,
8478 "affine matrix must have 4 or 6 elements",PackageName);
8479 goto PerlException;
8480 }
8481 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8482 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8483 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8484 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8485 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8486 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8487 {
8488 ThrowPerlException(exception,OptionError,
8489 "affine matrix is singular",PackageName);
8490 goto PerlException;
8491 }
8492 if (av_len(av) == 5)
8493 {
8494 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8495 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8496 }
8497 }
8498 for (j=12; j < 17; j++)
8499 {
8500 if (attribute_flag[j] == 0)
8501 continue;
8502 value=argument_list[j].string_reference;
8503 angle=argument_list[j].real_reference;
8504 current=draw_info->affine;
8505 GetAffineMatrix(&affine);
8506 switch (j)
8507 {
8508 case 12:
8509 {
8510 /*
8511 Translate.
8512 */
8513 flags=ParseGeometry(value,&geometry_info);
8514 affine.tx=geometry_info.xi;
8515 affine.ty=geometry_info.psi;
8516 if ((flags & PsiValue) == 0)
8517 affine.ty=affine.tx;
8518 break;
8519 }
8520 case 13:
8521 {
8522 /*
8523 Scale.
8524 */
8525 flags=ParseGeometry(value,&geometry_info);
8526 affine.sx=geometry_info.rho;
8527 affine.sy=geometry_info.sigma;
8528 if ((flags & SigmaValue) == 0)
8529 affine.sy=affine.sx;
8530 break;
8531 }
8532 case 14:
8533 {
8534 /*
8535 Rotate.
8536 */
8537 if (angle == 0.0)
8538 break;
8539 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8540 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8541 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8542 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8543 break;
8544 }
8545 case 15:
8546 {
8547 /*
8548 SkewX.
8549 */
8550 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8551 break;
8552 }
8553 case 16:
8554 {
8555 /*
8556 SkewY.
8557 */
8558 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8559 break;
8560 }
8561 }
8562 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8563 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8564 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8565 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8566 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8567 current.tx;
8568 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8569 current.ty;
8570 }
8571 if (attribute_flag[9] == 0)
8572 argument_list[9].real_reference=0.0;
8573 if (attribute_flag[10] == 0)
8574 argument_list[10].real_reference=0.0;
8575 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8576 {
8577 char
cristy151b66d2015-04-15 10:50:31 +00008578 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008579
cristy151b66d2015-04-15 10:50:31 +00008580 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008581 (double) argument_list[9].real_reference+draw_info->affine.tx,
8582 (double) argument_list[10].real_reference+draw_info->affine.ty);
8583 (void) CloneString(&draw_info->geometry,geometry);
8584 }
8585 if (attribute_flag[17] != 0)
8586 draw_info->stroke_width=argument_list[17].real_reference;
8587 if (attribute_flag[18] != 0)
8588 {
8589 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8590 MagickTrue : MagickFalse;
8591 draw_info->stroke_antialias=draw_info->text_antialias;
8592 }
8593 if (attribute_flag[19] != 0)
8594 (void) CloneString(&draw_info->family,
8595 argument_list[19].string_reference);
8596 if (attribute_flag[20] != 0)
8597 draw_info->style=(StyleType) argument_list[20].integer_reference;
8598 if (attribute_flag[21] != 0)
8599 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8600 if (attribute_flag[22] != 0)
8601 draw_info->weight=argument_list[22].integer_reference;
8602 if (attribute_flag[23] != 0)
8603 draw_info->align=(AlignType) argument_list[23].integer_reference;
8604 if (attribute_flag[24] != 0)
8605 (void) CloneString(&draw_info->encoding,
8606 argument_list[24].string_reference);
8607 if (attribute_flag[25] != 0)
8608 draw_info->fill_pattern=CloneImage(
8609 argument_list[25].image_reference,0,0,MagickTrue,exception);
8610 if (attribute_flag[26] != 0)
8611 draw_info->fill_pattern=CloneImage(
8612 argument_list[26].image_reference,0,0,MagickTrue,exception);
8613 if (attribute_flag[27] != 0)
8614 draw_info->stroke_pattern=CloneImage(
8615 argument_list[27].image_reference,0,0,MagickTrue,exception);
8616 if (attribute_flag[29] != 0)
8617 draw_info->kerning=argument_list[29].real_reference;
8618 if (attribute_flag[30] != 0)
8619 draw_info->interline_spacing=argument_list[30].real_reference;
8620 if (attribute_flag[31] != 0)
8621 draw_info->interword_spacing=argument_list[31].real_reference;
8622 if (attribute_flag[32] != 0)
8623 draw_info->direction=(DirectionType)
8624 argument_list[32].integer_reference;
Cristy3d1de822019-02-15 18:06:30 -05008625 if (attribute_flag[33] != 0)
8626 draw_info->decorate=(DecorationType)
8627 argument_list[33].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00008628 (void) AnnotateImage(image,draw_info,exception);
8629 draw_info=DestroyDrawInfo(draw_info);
8630 break;
8631 }
8632 case 34: /* ColorFloodfill */
8633 {
8634 DrawInfo
8635 *draw_info;
8636
8637 MagickBooleanType
8638 invert;
8639
8640 PixelInfo
8641 target;
8642
8643 draw_info=CloneDrawInfo(info ? info->image_info :
8644 (ImageInfo *) NULL,(DrawInfo *) NULL);
8645 if (attribute_flag[0] != 0)
8646 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8647 &geometry,exception);
8648 if (attribute_flag[1] != 0)
8649 geometry.x=argument_list[1].integer_reference;
8650 if (attribute_flag[2] != 0)
8651 geometry.y=argument_list[2].integer_reference;
8652 if (attribute_flag[3] != 0)
8653 (void) QueryColorCompliance(argument_list[3].string_reference,
8654 AllCompliance,&draw_info->fill,exception);
8655 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8656 geometry.x,geometry.y,&target,exception);
8657 invert=MagickFalse;
8658 if (attribute_flag[4] != 0)
8659 {
8660 QueryColorCompliance(argument_list[4].string_reference,
8661 AllCompliance,&target,exception);
8662 invert=MagickTrue;
8663 }
8664 if (attribute_flag[5] != 0)
8665 image->fuzz=StringToDoubleInterval(
8666 argument_list[5].string_reference,(double) QuantumRange+1.0);
8667 if (attribute_flag[6] != 0)
8668 invert=(MagickBooleanType) argument_list[6].integer_reference;
8669 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8670 geometry.y,invert,exception);
8671 draw_info=DestroyDrawInfo(draw_info);
8672 break;
8673 }
8674 case 35: /* Composite */
8675 {
8676 char
cristy151b66d2015-04-15 10:50:31 +00008677 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008678
8679 Image
8680 *composite_image,
8681 *rotate_image;
8682
8683 MagickBooleanType
8684 clip_to_self;
8685
8686 compose=OverCompositeOp;
8687 if (attribute_flag[0] != 0)
8688 composite_image=argument_list[0].image_reference;
8689 else
8690 {
8691 ThrowPerlException(exception,OptionError,
8692 "CompositeImageRequired",PackageName);
8693 goto PerlException;
8694 }
8695 /*
8696 Parameter Handling used for BOTH normal and tiled composition.
8697 */
8698 if (attribute_flag[1] != 0) /* compose */
8699 compose=(CompositeOperator) argument_list[1].integer_reference;
8700 if (attribute_flag[6] != 0) /* opacity */
8701 {
8702 if (compose != DissolveCompositeOp)
8703 (void) SetImageAlpha(composite_image,(Quantum)
8704 StringToDoubleInterval(argument_list[6].string_reference,
8705 (double) QuantumRange+1.0),exception);
8706 else
8707 {
8708 CacheView
8709 *composite_view;
8710
8711 double
8712 opacity;
8713
8714 MagickBooleanType
8715 sync;
8716
8717 register ssize_t
8718 x;
8719
8720 register Quantum
8721 *q;
8722
8723 ssize_t
8724 y;
8725
8726 /*
8727 Handle dissolve composite operator (patch by
8728 Kevin A. McGrail).
8729 */
8730 (void) CloneString(&image->geometry,
8731 argument_list[6].string_reference);
8732 opacity=(Quantum) StringToDoubleInterval(
8733 argument_list[6].string_reference,(double) QuantumRange+
8734 1.0);
cristy17f11b02014-12-20 19:37:04 +00008735 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008736 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8737 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8738 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8739 {
8740 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8741 composite_image->columns,1,exception);
8742 for (x=0; x < (ssize_t) composite_image->columns; x++)
8743 {
8744 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8745 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8746 q);
8747 q+=GetPixelChannels(composite_image);
8748 }
8749 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8750 if (sync == MagickFalse)
8751 break;
8752 }
8753 composite_view=DestroyCacheView(composite_view);
8754 }
8755 }
8756 if (attribute_flag[9] != 0) /* "color=>" */
8757 QueryColorCompliance(argument_list[9].string_reference,
8758 AllCompliance,&composite_image->background_color,exception);
8759 if (attribute_flag[12] != 0) /* "interpolate=>" */
8760 image->interpolate=(PixelInterpolateMethod)
8761 argument_list[12].integer_reference;
8762 if (attribute_flag[13] != 0) /* "args=>" */
8763 (void) SetImageArtifact(composite_image,"compose:args",
8764 argument_list[13].string_reference);
8765 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8766 (void) SetImageArtifact(composite_image,"compose:args",
8767 argument_list[14].string_reference);
Cristy72aed842018-07-08 18:25:50 -04008768 clip_to_self=MagickTrue;
8769 switch (compose)
8770 {
8771 case ClearCompositeOp:
8772 case SrcCompositeOp:
8773 case InCompositeOp:
8774 case SrcInCompositeOp:
8775 case OutCompositeOp:
8776 case SrcOutCompositeOp:
8777 case DstInCompositeOp:
8778 case DstAtopCompositeOp:
Cristy901f5212018-07-08 18:43:34 -04008779 case CopyAlphaCompositeOp:
Cristy72aed842018-07-08 18:25:50 -04008780 case ChangeMaskCompositeOp:
8781 case DissolveCompositeOp:
8782 case BlendCompositeOp:
8783 {
Cristy901f5212018-07-08 18:43:34 -04008784 clip_to_self=MagickFalse;
Cristy72aed842018-07-08 18:25:50 -04008785 break;
8786 }
8787 default:
8788 break;
8789 }
cristy4a3ce0a2013-08-03 20:06:59 +00008790 if (attribute_flag[15] != 0)
8791 clip_to_self=(MagickBooleanType)
8792 argument_list[15].integer_reference;
8793 /*
8794 Tiling Composition (with orthogonal rotate).
8795 */
8796 rotate_image=(Image *) NULL;
8797 if (attribute_flag[8] != 0) /* "rotate=>" */
8798 {
8799 /*
8800 Rotate image.
8801 */
8802 rotate_image=RotateImage(composite_image,
8803 argument_list[8].real_reference,exception);
8804 if (rotate_image == (Image *) NULL)
8805 break;
8806 }
8807 if ((attribute_flag[7] != 0) &&
8808 (argument_list[7].integer_reference != 0)) /* tile */
8809 {
8810 ssize_t
8811 x,
8812 y;
8813
8814 /*
8815 Tile the composite image.
8816 */
cristy4a3ce0a2013-08-03 20:06:59 +00008817 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8818 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8819 {
8820 if (attribute_flag[8] != 0) /* rotate */
8821 (void) CompositeImage(image,rotate_image,compose,
Cristyde6c67d2018-07-08 19:14:08 -04008822 MagickTrue,x,y,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008823 else
8824 (void) CompositeImage(image,composite_image,compose,
Cristyde6c67d2018-07-08 19:14:08 -04008825 MagickTrue,x,y,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008826 }
8827 if (attribute_flag[8] != 0) /* rotate */
8828 rotate_image=DestroyImage(rotate_image);
8829 break;
8830 }
8831 /*
8832 Parameter Handling used used ONLY for normal composition.
8833 */
8834 if (attribute_flag[5] != 0) /* gravity */
8835 image->gravity=(GravityType) argument_list[5].integer_reference;
8836 if (attribute_flag[2] != 0) /* geometry offset */
8837 {
8838 SetGeometry(image,&geometry);
8839 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8840 &geometry);
8841 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8842 &geometry);
8843 }
8844 if (attribute_flag[3] != 0) /* x offset */
8845 geometry.x=argument_list[3].integer_reference;
8846 if (attribute_flag[4] != 0) /* y offset */
8847 geometry.y=argument_list[4].integer_reference;
8848 if (attribute_flag[10] != 0) /* mask */
8849 {
8850 if ((image->compose == DisplaceCompositeOp) ||
8851 (image->compose == DistortCompositeOp))
8852 {
8853 /*
8854 Merge Y displacement into X displacement image.
8855 */
8856 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8857 exception);
8858 (void) CompositeImage(composite_image,
8859 argument_list[10].image_reference,CopyGreenCompositeOp,
Cristy74e39292018-07-08 13:13:20 -04008860 clip_to_self,0,0,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008861 }
8862 else
8863 {
8864 Image
8865 *mask_image;
8866
8867 /*
8868 Set a blending mask for the composition.
8869 */
8870 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8871 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008872 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008873 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008874 mask_image=DestroyImage(mask_image);
8875 }
8876 }
8877 if (attribute_flag[11] != 0) /* channel */
8878 channel=(ChannelType) argument_list[11].integer_reference;
8879 /*
8880 Composite two images (normal composition).
8881 */
cristy151b66d2015-04-15 10:50:31 +00008882 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008883 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8884 (double) composite_image->rows,(double) geometry.x,(double)
8885 geometry.y);
8886 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8887 exception);
8888 channel_mask=SetImageChannelMask(image,channel);
8889 if (attribute_flag[8] == 0) /* no rotate */
8890 CompositeImage(image,composite_image,compose,clip_to_self,
8891 geometry.x,geometry.y,exception);
8892 else
8893 {
8894 /*
8895 Position adjust rotated image then composite.
8896 */
8897 geometry.x-=(ssize_t) (rotate_image->columns-
8898 composite_image->columns)/2;
8899 geometry.y-=(ssize_t) (rotate_image->rows-
8900 composite_image->rows)/2;
8901 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8902 geometry.y,exception);
8903 rotate_image=DestroyImage(rotate_image);
8904 }
8905 if (attribute_flag[10] != 0) /* mask */
8906 {
8907 if ((image->compose == DisplaceCompositeOp) ||
8908 (image->compose == DistortCompositeOp))
8909 composite_image=DestroyImage(composite_image);
8910 else
cristy1f7ffb72015-07-29 11:07:03 +00008911 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008912 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008913 }
8914 (void) SetImageChannelMask(image,channel_mask);
8915 break;
8916 }
8917 case 36: /* Contrast */
8918 {
8919 if (attribute_flag[0] == 0)
8920 argument_list[0].integer_reference=0;
8921 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8922 MagickTrue : MagickFalse,exception);
8923 break;
8924 }
8925 case 37: /* CycleColormap */
8926 {
8927 if (attribute_flag[0] == 0)
8928 argument_list[0].integer_reference=6;
8929 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8930 exception);
8931 break;
8932 }
8933 case 38: /* Draw */
8934 {
8935 DrawInfo
8936 *draw_info;
8937
8938 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8939 (DrawInfo *) NULL);
8940 (void) CloneString(&draw_info->primitive,"point");
8941 if (attribute_flag[0] != 0)
8942 {
8943 if (argument_list[0].integer_reference < 0)
8944 (void) CloneString(&draw_info->primitive,
8945 argument_list[0].string_reference);
8946 else
8947 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8948 MagickPrimitiveOptions,argument_list[0].integer_reference));
8949 }
8950 if (attribute_flag[1] != 0)
8951 {
8952 if (LocaleCompare(draw_info->primitive,"path") == 0)
8953 {
8954 (void) ConcatenateString(&draw_info->primitive," '");
8955 ConcatenateString(&draw_info->primitive,
8956 argument_list[1].string_reference);
8957 (void) ConcatenateString(&draw_info->primitive,"'");
8958 }
8959 else
8960 {
8961 (void) ConcatenateString(&draw_info->primitive," ");
8962 ConcatenateString(&draw_info->primitive,
8963 argument_list[1].string_reference);
8964 }
8965 }
8966 if (attribute_flag[2] != 0)
8967 {
8968 (void) ConcatenateString(&draw_info->primitive," ");
8969 (void) ConcatenateString(&draw_info->primitive,
8970 CommandOptionToMnemonic(MagickMethodOptions,
8971 argument_list[2].integer_reference));
8972 }
8973 if (attribute_flag[3] != 0)
8974 {
8975 (void) QueryColorCompliance(argument_list[3].string_reference,
8976 AllCompliance,&draw_info->stroke,exception);
8977 if (argument_list[3].image_reference != (Image *) NULL)
8978 draw_info->stroke_pattern=CloneImage(
8979 argument_list[3].image_reference,0,0,MagickTrue,exception);
8980 }
8981 if (attribute_flag[4] != 0)
8982 {
8983 (void) QueryColorCompliance(argument_list[4].string_reference,
8984 AllCompliance,&draw_info->fill,exception);
8985 if (argument_list[4].image_reference != (Image *) NULL)
8986 draw_info->fill_pattern=CloneImage(
8987 argument_list[4].image_reference,0,0,MagickTrue,exception);
8988 }
8989 if (attribute_flag[5] != 0)
8990 draw_info->stroke_width=argument_list[5].real_reference;
8991 if (attribute_flag[6] != 0)
8992 (void) CloneString(&draw_info->font,
8993 argument_list[6].string_reference);
8994 if (attribute_flag[7] != 0)
8995 (void) QueryColorCompliance(argument_list[7].string_reference,
8996 AllCompliance,&draw_info->border_color,exception);
8997 if (attribute_flag[8] != 0)
8998 draw_info->affine.tx=argument_list[8].real_reference;
8999 if (attribute_flag[9] != 0)
9000 draw_info->affine.ty=argument_list[9].real_reference;
9001 if (attribute_flag[20] != 0)
9002 {
9003 AV
9004 *av;
9005
9006 av=(AV *) argument_list[20].array_reference;
9007 if ((av_len(av) != 3) && (av_len(av) != 5))
9008 {
9009 ThrowPerlException(exception,OptionError,
9010 "affine matrix must have 4 or 6 elements",PackageName);
9011 goto PerlException;
9012 }
9013 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9014 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9015 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9016 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9017 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9018 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9019 {
9020 ThrowPerlException(exception,OptionError,
9021 "affine matrix is singular",PackageName);
9022 goto PerlException;
9023 }
9024 if (av_len(av) == 5)
9025 {
9026 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9027 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9028 }
9029 }
9030 for (j=10; j < 15; j++)
9031 {
9032 if (attribute_flag[j] == 0)
9033 continue;
9034 value=argument_list[j].string_reference;
9035 angle=argument_list[j].real_reference;
9036 current=draw_info->affine;
9037 GetAffineMatrix(&affine);
9038 switch (j)
9039 {
9040 case 10:
9041 {
9042 /*
9043 Translate.
9044 */
9045 flags=ParseGeometry(value,&geometry_info);
9046 affine.tx=geometry_info.xi;
9047 affine.ty=geometry_info.psi;
9048 if ((flags & PsiValue) == 0)
9049 affine.ty=affine.tx;
9050 break;
9051 }
9052 case 11:
9053 {
9054 /*
9055 Scale.
9056 */
9057 flags=ParseGeometry(value,&geometry_info);
9058 affine.sx=geometry_info.rho;
9059 affine.sy=geometry_info.sigma;
9060 if ((flags & SigmaValue) == 0)
9061 affine.sy=affine.sx;
9062 break;
9063 }
9064 case 12:
9065 {
9066 /*
9067 Rotate.
9068 */
9069 if (angle == 0.0)
9070 break;
9071 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9072 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9073 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9074 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9075 break;
9076 }
9077 case 13:
9078 {
9079 /*
9080 SkewX.
9081 */
9082 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9083 break;
9084 }
9085 case 14:
9086 {
9087 /*
9088 SkewY.
9089 */
9090 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9091 break;
9092 }
9093 }
9094 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9095 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9096 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9097 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9098 draw_info->affine.tx=
9099 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9100 draw_info->affine.ty=
9101 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9102 }
9103 if (attribute_flag[15] != 0)
9104 draw_info->fill_pattern=CloneImage(
9105 argument_list[15].image_reference,0,0,MagickTrue,exception);
9106 if (attribute_flag[16] != 0)
9107 draw_info->pointsize=argument_list[16].real_reference;
9108 if (attribute_flag[17] != 0)
9109 {
Cristy36c30b62018-11-22 09:33:30 -05009110 draw_info->stroke_antialias=argument_list[17].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009111 draw_info->text_antialias=draw_info->stroke_antialias;
9112 }
9113 if (attribute_flag[18] != 0)
9114 (void) CloneString(&draw_info->density,
9115 argument_list[18].string_reference);
9116 if (attribute_flag[19] != 0)
9117 draw_info->stroke_width=argument_list[19].real_reference;
9118 if (attribute_flag[21] != 0)
9119 draw_info->dash_offset=argument_list[21].real_reference;
9120 if (attribute_flag[22] != 0)
9121 {
9122 AV
9123 *av;
9124
9125 av=(AV *) argument_list[22].array_reference;
9126 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9127 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9128 if (draw_info->dash_pattern != (double *) NULL)
9129 {
9130 for (i=0; i <= av_len(av); i++)
9131 draw_info->dash_pattern[i]=(double)
9132 SvNV(*(av_fetch(av,i,0)));
9133 draw_info->dash_pattern[i]=0.0;
9134 }
9135 }
9136 if (attribute_flag[23] != 0)
9137 image->interpolate=(PixelInterpolateMethod)
9138 argument_list[23].integer_reference;
9139 if ((attribute_flag[24] != 0) &&
9140 (draw_info->fill_pattern != (Image *) NULL))
9141 flags=ParsePageGeometry(draw_info->fill_pattern,
9142 argument_list[24].string_reference,
9143 &draw_info->fill_pattern->tile_offset,exception);
9144 if (attribute_flag[25] != 0)
9145 {
9146 (void) ConcatenateString(&draw_info->primitive," '");
9147 (void) ConcatenateString(&draw_info->primitive,
9148 argument_list[25].string_reference);
9149 (void) ConcatenateString(&draw_info->primitive,"'");
9150 }
9151 if (attribute_flag[26] != 0)
9152 draw_info->fill_pattern=CloneImage(
9153 argument_list[26].image_reference,0,0,MagickTrue,exception);
9154 if (attribute_flag[27] != 0)
9155 draw_info->stroke_pattern=CloneImage(
9156 argument_list[27].image_reference,0,0,MagickTrue,exception);
9157 if (attribute_flag[28] != 0)
9158 (void) CloneString(&draw_info->primitive,
9159 argument_list[28].string_reference);
9160 if (attribute_flag[29] != 0)
9161 draw_info->kerning=argument_list[29].real_reference;
9162 if (attribute_flag[30] != 0)
9163 draw_info->interline_spacing=argument_list[30].real_reference;
9164 if (attribute_flag[31] != 0)
9165 draw_info->interword_spacing=argument_list[31].real_reference;
9166 if (attribute_flag[32] != 0)
9167 draw_info->direction=(DirectionType)
9168 argument_list[32].integer_reference;
Cristy36c30b62018-11-22 09:33:30 -05009169 (void) DrawImage(image,draw_info,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009170 draw_info=DestroyDrawInfo(draw_info);
9171 break;
9172 }
9173 case 39: /* Equalize */
9174 {
9175 if (attribute_flag[0] != 0)
9176 channel=(ChannelType) argument_list[0].integer_reference;
9177 channel_mask=SetImageChannelMask(image,channel);
Cristy36c30b62018-11-22 09:33:30 -05009178 (void) EqualizeImage(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009179 (void) SetImageChannelMask(image,channel_mask);
9180 break;
9181 }
9182 case 40: /* Gamma */
9183 {
9184 if (attribute_flag[1] != 0)
9185 channel=(ChannelType) argument_list[1].integer_reference;
9186 if (attribute_flag[2] == 0)
9187 argument_list[2].real_reference=1.0;
9188 if (attribute_flag[3] == 0)
9189 argument_list[3].real_reference=1.0;
9190 if (attribute_flag[4] == 0)
9191 argument_list[4].real_reference=1.0;
9192 if (attribute_flag[0] == 0)
9193 {
cristy151b66d2015-04-15 10:50:31 +00009194 (void) FormatLocaleString(message,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -05009195 "%.20g,%.20g,%.20g",(double) argument_list[2].real_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009196 (double) argument_list[3].real_reference,
9197 (double) argument_list[4].real_reference);
9198 argument_list[0].string_reference=message;
9199 }
9200 (void) GammaImage(image,StringToDouble(
9201 argument_list[0].string_reference,(char **) NULL),exception);
9202 break;
9203 }
9204 case 41: /* Map */
9205 {
9206 QuantizeInfo
9207 *quantize_info;
9208
9209 if (attribute_flag[0] == 0)
9210 {
9211 ThrowPerlException(exception,OptionError,"MapImageRequired",
9212 PackageName);
9213 goto PerlException;
9214 }
9215 quantize_info=AcquireQuantizeInfo(info->image_info);
9216 if (attribute_flag[1] != 0)
9217 quantize_info->dither_method=(DitherMethod)
9218 argument_list[1].integer_reference;
9219 (void) RemapImages(quantize_info,image,
9220 argument_list[0].image_reference,exception);
9221 quantize_info=DestroyQuantizeInfo(quantize_info);
9222 break;
9223 }
9224 case 42: /* MatteFloodfill */
9225 {
9226 DrawInfo
9227 *draw_info;
9228
9229 MagickBooleanType
9230 invert;
9231
9232 PixelInfo
9233 target;
9234
9235 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9236 (DrawInfo *) NULL);
9237 if (attribute_flag[0] != 0)
9238 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9239 &geometry,exception);
9240 if (attribute_flag[1] != 0)
9241 geometry.x=argument_list[1].integer_reference;
9242 if (attribute_flag[2] != 0)
9243 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009244 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009245 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9246 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9247 geometry.x,geometry.y,&target,exception);
9248 if (attribute_flag[4] != 0)
9249 QueryColorCompliance(argument_list[4].string_reference,
9250 AllCompliance,&target,exception);
9251 if (attribute_flag[3] != 0)
9252 target.alpha=StringToDoubleInterval(
9253 argument_list[3].string_reference,(double) (double) QuantumRange+
9254 1.0);
9255 if (attribute_flag[5] != 0)
9256 image->fuzz=StringToDoubleInterval(
9257 argument_list[5].string_reference,(double) QuantumRange+1.0);
9258 invert=MagickFalse;
9259 if (attribute_flag[6] != 0)
9260 invert=(MagickBooleanType) argument_list[6].integer_reference;
9261 channel_mask=SetImageChannelMask(image,AlphaChannel);
9262 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9263 geometry.y,invert,exception);
9264 (void) SetImageChannelMask(image,channel_mask);
9265 draw_info=DestroyDrawInfo(draw_info);
9266 break;
9267 }
9268 case 43: /* Modulate */
9269 {
9270 char
cristy151b66d2015-04-15 10:50:31 +00009271 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009272
9273 geometry_info.rho=100.0;
9274 geometry_info.sigma=100.0;
9275 geometry_info.xi=100.0;
9276 if (attribute_flag[0] != 0)
9277 (void)ParseGeometry(argument_list[0].string_reference,
9278 &geometry_info);
9279 if (attribute_flag[1] != 0)
9280 geometry_info.xi=argument_list[1].real_reference;
9281 if (attribute_flag[2] != 0)
9282 geometry_info.sigma=argument_list[2].real_reference;
9283 if (attribute_flag[3] != 0)
9284 {
9285 geometry_info.sigma=argument_list[3].real_reference;
9286 SetImageArtifact(image,"modulate:colorspace","HWB");
9287 }
9288 if (attribute_flag[4] != 0)
9289 {
9290 geometry_info.rho=argument_list[4].real_reference;
9291 SetImageArtifact(image,"modulate:colorspace","HSB");
9292 }
9293 if (attribute_flag[5] != 0)
9294 {
9295 geometry_info.sigma=argument_list[5].real_reference;
9296 SetImageArtifact(image,"modulate:colorspace","HSL");
9297 }
9298 if (attribute_flag[6] != 0)
9299 {
9300 geometry_info.rho=argument_list[6].real_reference;
9301 SetImageArtifact(image,"modulate:colorspace","HWB");
9302 }
Cristy935a4052017-03-31 17:45:37 -04009303 (void) FormatLocaleString(modulate,MagickPathExtent,"%.20g,%.20g,%.20g",
9304 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy4a3ce0a2013-08-03 20:06:59 +00009305 (void) ModulateImage(image,modulate,exception);
9306 break;
9307 }
9308 case 44: /* Negate */
9309 {
9310 if (attribute_flag[0] == 0)
9311 argument_list[0].integer_reference=0;
9312 if (attribute_flag[1] != 0)
9313 channel=(ChannelType) argument_list[1].integer_reference;
9314 channel_mask=SetImageChannelMask(image,channel);
9315 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9316 MagickTrue : MagickFalse,exception);
9317 (void) SetImageChannelMask(image,channel_mask);
9318 break;
9319 }
9320 case 45: /* Normalize */
9321 {
9322 if (attribute_flag[0] != 0)
9323 channel=(ChannelType) argument_list[0].integer_reference;
9324 channel_mask=SetImageChannelMask(image,channel);
9325 NormalizeImage(image,exception);
9326 (void) SetImageChannelMask(image,channel_mask);
9327 break;
9328 }
9329 case 46: /* NumberColors */
9330 break;
9331 case 47: /* Opaque */
9332 {
9333 MagickBooleanType
9334 invert;
9335
9336 PixelInfo
9337 fill_color,
9338 target;
9339
9340 (void) QueryColorCompliance("none",AllCompliance,&target,
9341 exception);
9342 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9343 exception);
9344 if (attribute_flag[0] != 0)
9345 (void) QueryColorCompliance(argument_list[0].string_reference,
9346 AllCompliance,&target,exception);
9347 if (attribute_flag[1] != 0)
9348 (void) QueryColorCompliance(argument_list[1].string_reference,
9349 AllCompliance,&fill_color,exception);
9350 if (attribute_flag[2] != 0)
9351 image->fuzz=StringToDoubleInterval(
9352 argument_list[2].string_reference,(double) QuantumRange+1.0);
9353 if (attribute_flag[3] != 0)
9354 channel=(ChannelType) argument_list[3].integer_reference;
9355 invert=MagickFalse;
9356 if (attribute_flag[4] != 0)
9357 invert=(MagickBooleanType) argument_list[4].integer_reference;
9358 channel_mask=SetImageChannelMask(image,channel);
9359 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9360 (void) SetImageChannelMask(image,channel_mask);
9361 break;
9362 }
9363 case 48: /* Quantize */
9364 {
9365 QuantizeInfo
9366 *quantize_info;
9367
9368 quantize_info=AcquireQuantizeInfo(info->image_info);
9369 if (attribute_flag[0] != 0)
9370 quantize_info->number_colors=(size_t)
9371 argument_list[0].integer_reference;
9372 if (attribute_flag[1] != 0)
9373 quantize_info->tree_depth=(size_t)
9374 argument_list[1].integer_reference;
9375 if (attribute_flag[2] != 0)
9376 quantize_info->colorspace=(ColorspaceType)
9377 argument_list[2].integer_reference;
9378 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009379 quantize_info->dither_method=(DitherMethod)
9380 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009381 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009382 quantize_info->measure_error=
9383 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009384 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009385 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009386 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009387 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009388 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009389 argument_list[7].integer_reference;
9390 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009391 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009392 else
cristyf7563392014-03-25 13:54:04 +00009393 if ((image->storage_class == DirectClass) ||
9394 (image->colors > quantize_info->number_colors) ||
9395 (quantize_info->colorspace == GRAYColorspace))
9396 (void) QuantizeImage(quantize_info,image,exception);
9397 else
9398 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009399 quantize_info=DestroyQuantizeInfo(quantize_info);
9400 break;
9401 }
9402 case 49: /* Raise */
9403 {
9404 if (attribute_flag[0] != 0)
9405 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9406 &geometry,exception);
9407 if (attribute_flag[1] != 0)
9408 geometry.width=argument_list[1].integer_reference;
9409 if (attribute_flag[2] != 0)
9410 geometry.height=argument_list[2].integer_reference;
9411 if (attribute_flag[3] == 0)
9412 argument_list[3].integer_reference=1;
9413 (void) RaiseImage(image,&geometry,
9414 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9415 exception);
9416 break;
9417 }
9418 case 50: /* Segment */
9419 {
9420 ColorspaceType
9421 colorspace;
9422
9423 double
9424 cluster_threshold,
9425 smoothing_threshold;
9426
9427 MagickBooleanType
9428 verbose;
9429
9430 cluster_threshold=1.0;
9431 smoothing_threshold=1.5;
9432 colorspace=sRGBColorspace;
9433 verbose=MagickFalse;
9434 if (attribute_flag[0] != 0)
9435 {
9436 flags=ParseGeometry(argument_list[0].string_reference,
9437 &geometry_info);
9438 cluster_threshold=geometry_info.rho;
9439 if (flags & SigmaValue)
9440 smoothing_threshold=geometry_info.sigma;
9441 }
9442 if (attribute_flag[1] != 0)
9443 cluster_threshold=argument_list[1].real_reference;
9444 if (attribute_flag[2] != 0)
9445 smoothing_threshold=argument_list[2].real_reference;
9446 if (attribute_flag[3] != 0)
9447 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9448 if (attribute_flag[4] != 0)
9449 verbose=argument_list[4].integer_reference != 0 ?
9450 MagickTrue : MagickFalse;
9451 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9452 smoothing_threshold,exception);
9453 break;
9454 }
9455 case 51: /* Signature */
9456 {
9457 (void) SignatureImage(image,exception);
9458 break;
9459 }
9460 case 52: /* Solarize */
9461 {
9462 geometry_info.rho=QuantumRange/2.0;
9463 if (attribute_flag[0] != 0)
9464 flags=ParseGeometry(argument_list[0].string_reference,
9465 &geometry_info);
9466 if (attribute_flag[1] != 0)
9467 geometry_info.rho=StringToDoubleInterval(
9468 argument_list[1].string_reference,(double) QuantumRange+1.0);
9469 (void) SolarizeImage(image,geometry_info.rho,exception);
9470 break;
9471 }
9472 case 53: /* Sync */
9473 {
9474 (void) SyncImage(image,exception);
9475 break;
9476 }
9477 case 54: /* Texture */
9478 {
9479 if (attribute_flag[0] == 0)
9480 break;
9481 TextureImage(image,argument_list[0].image_reference,exception);
9482 break;
9483 }
9484 case 55: /* Evalute */
9485 {
9486 MagickEvaluateOperator
9487 op;
9488
9489 op=SetEvaluateOperator;
9490 if (attribute_flag[0] == MagickFalse)
9491 argument_list[0].real_reference=0.0;
9492 if (attribute_flag[1] != MagickFalse)
9493 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9494 if (attribute_flag[2] != MagickFalse)
9495 channel=(ChannelType) argument_list[2].integer_reference;
9496 channel_mask=SetImageChannelMask(image,channel);
9497 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9498 exception);
9499 (void) SetImageChannelMask(image,channel_mask);
9500 break;
9501 }
9502 case 56: /* Transparent */
9503 {
9504 double
9505 opacity;
9506
9507 MagickBooleanType
9508 invert;
9509
9510 PixelInfo
9511 target;
9512
9513 (void) QueryColorCompliance("none",AllCompliance,&target,
9514 exception);
9515 if (attribute_flag[0] != 0)
9516 (void) QueryColorCompliance(argument_list[0].string_reference,
9517 AllCompliance,&target,exception);
9518 opacity=TransparentAlpha;
9519 if (attribute_flag[1] != 0)
9520 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9521 (double) QuantumRange+1.0);
9522 if (attribute_flag[2] != 0)
9523 image->fuzz=StringToDoubleInterval(
9524 argument_list[2].string_reference,(double) QuantumRange+1.0);
9525 if (attribute_flag[3] == 0)
9526 argument_list[3].integer_reference=0;
9527 invert=MagickFalse;
9528 if (attribute_flag[3] != 0)
9529 invert=(MagickBooleanType) argument_list[3].integer_reference;
9530 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9531 invert,exception);
9532 break;
9533 }
9534 case 57: /* Threshold */
9535 {
9536 double
9537 threshold;
9538
9539 if (attribute_flag[0] == 0)
9540 argument_list[0].string_reference="50%";
9541 if (attribute_flag[1] != 0)
9542 channel=(ChannelType) argument_list[1].integer_reference;
9543 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9544 (double) QuantumRange+1.0);
9545 channel_mask=SetImageChannelMask(image,channel);
9546 (void) BilevelImage(image,threshold,exception);
9547 (void) SetImageChannelMask(image,channel_mask);
9548 break;
9549 }
9550 case 58: /* Charcoal */
9551 {
9552 if (attribute_flag[0] != 0)
9553 {
9554 flags=ParseGeometry(argument_list[0].string_reference,
9555 &geometry_info);
9556 if ((flags & SigmaValue) == 0)
9557 geometry_info.sigma=1.0;
9558 }
9559 if (attribute_flag[1] != 0)
9560 geometry_info.rho=argument_list[1].real_reference;
9561 if (attribute_flag[2] != 0)
9562 geometry_info.sigma=argument_list[2].real_reference;
9563 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9564 exception);
9565 break;
9566 }
9567 case 59: /* Trim */
9568 {
9569 if (attribute_flag[0] != 0)
9570 image->fuzz=StringToDoubleInterval(
9571 argument_list[0].string_reference,(double) QuantumRange+1.0);
9572 image=TrimImage(image,exception);
9573 break;
9574 }
9575 case 60: /* Wave */
9576 {
9577 PixelInterpolateMethod
9578 method;
9579
9580 if (attribute_flag[0] != 0)
9581 {
9582 flags=ParseGeometry(argument_list[0].string_reference,
9583 &geometry_info);
9584 if ((flags & SigmaValue) == 0)
9585 geometry_info.sigma=1.0;
9586 }
9587 if (attribute_flag[1] != 0)
9588 geometry_info.rho=argument_list[1].real_reference;
9589 if (attribute_flag[2] != 0)
9590 geometry_info.sigma=argument_list[2].real_reference;
9591 method=UndefinedInterpolatePixel;
9592 if (attribute_flag[3] != 0)
9593 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9594 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9595 method,exception);
9596 break;
9597 }
9598 case 61: /* Separate */
9599 {
9600 if (attribute_flag[0] != 0)
9601 channel=(ChannelType) argument_list[0].integer_reference;
9602 image=SeparateImage(image,channel,exception);
9603 break;
9604 }
9605 case 63: /* Stereo */
9606 {
9607 if (attribute_flag[0] == 0)
9608 {
9609 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9610 PackageName);
9611 goto PerlException;
9612 }
9613 if (attribute_flag[1] != 0)
9614 geometry.x=argument_list[1].integer_reference;
9615 if (attribute_flag[2] != 0)
9616 geometry.y=argument_list[2].integer_reference;
9617 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9618 geometry.x,geometry.y,exception);
9619 break;
9620 }
9621 case 64: /* Stegano */
9622 {
9623 if (attribute_flag[0] == 0)
9624 {
9625 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9626 PackageName);
9627 goto PerlException;
9628 }
9629 if (attribute_flag[1] == 0)
9630 argument_list[1].integer_reference=0;
9631 image->offset=argument_list[1].integer_reference;
9632 image=SteganoImage(image,argument_list[0].image_reference,exception);
9633 break;
9634 }
9635 case 65: /* Deconstruct */
9636 {
9637 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9638 break;
9639 }
9640 case 66: /* GaussianBlur */
9641 {
9642 if (attribute_flag[0] != 0)
9643 {
9644 flags=ParseGeometry(argument_list[0].string_reference,
9645 &geometry_info);
9646 if ((flags & SigmaValue) == 0)
9647 geometry_info.sigma=1.0;
9648 }
9649 if (attribute_flag[1] != 0)
9650 geometry_info.rho=argument_list[1].real_reference;
9651 if (attribute_flag[2] != 0)
9652 geometry_info.sigma=argument_list[2].real_reference;
9653 if (attribute_flag[3] != 0)
9654 channel=(ChannelType) argument_list[3].integer_reference;
9655 channel_mask=SetImageChannelMask(image,channel);
9656 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9657 exception);
9658 if (image != (Image *) NULL)
9659 (void) SetImageChannelMask(image,channel_mask);
9660 break;
9661 }
9662 case 67: /* Convolve */
9663 {
9664 KernelInfo
9665 *kernel;
9666
9667 kernel=(KernelInfo *) NULL;
9668 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9669 break;
9670 if (attribute_flag[0] != 0)
9671 {
9672 AV
9673 *av;
9674
9675 size_t
9676 order;
9677
cristy2c57b742014-10-31 00:40:34 +00009678 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009679 if (kernel == (KernelInfo *) NULL)
9680 break;
9681 av=(AV *) argument_list[0].array_reference;
9682 order=(size_t) sqrt(av_len(av)+1);
9683 kernel->width=order;
9684 kernel->height=order;
9685 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9686 order*sizeof(*kernel->values));
9687 if (kernel->values == (MagickRealType *) NULL)
9688 {
9689 kernel=DestroyKernelInfo(kernel);
9690 ThrowPerlException(exception,ResourceLimitFatalError,
9691 "MemoryAllocationFailed",PackageName);
9692 goto PerlException;
9693 }
9694 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9695 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9696 for ( ; j < (ssize_t) (order*order); j++)
9697 kernel->values[j]=0.0;
9698 }
9699 if (attribute_flag[1] != 0)
9700 channel=(ChannelType) argument_list[1].integer_reference;
9701 if (attribute_flag[2] != 0)
Cristyc4ff6bd2017-07-05 21:00:11 -04009702 SetImageArtifact(image,"convolve:bias",
cristy4a3ce0a2013-08-03 20:06:59 +00009703 argument_list[2].string_reference);
9704 if (attribute_flag[3] != 0)
9705 {
cristy2c57b742014-10-31 00:40:34 +00009706 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9707 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009708 if (kernel == (KernelInfo *) NULL)
9709 break;
9710 }
9711 channel_mask=SetImageChannelMask(image,channel);
9712 image=ConvolveImage(image,kernel,exception);
9713 if (image != (Image *) NULL)
9714 (void) SetImageChannelMask(image,channel_mask);
9715 kernel=DestroyKernelInfo(kernel);
9716 break;
9717 }
9718 case 68: /* Profile */
9719 {
9720 const char
9721 *name;
9722
9723 Image
9724 *profile_image;
9725
9726 ImageInfo
9727 *profile_info;
9728
9729 StringInfo
9730 *profile;
9731
9732 name="*";
9733 if (attribute_flag[0] != 0)
9734 name=argument_list[0].string_reference;
9735 if (attribute_flag[2] != 0)
9736 image->rendering_intent=(RenderingIntent)
9737 argument_list[2].integer_reference;
9738 if (attribute_flag[3] != 0)
9739 image->black_point_compensation=
9740 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9741 if (attribute_flag[1] != 0)
9742 {
9743 if (argument_list[1].length == 0)
9744 {
9745 /*
9746 Remove a profile from the image.
9747 */
9748 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9749 exception);
9750 break;
9751 }
9752 /*
9753 Associate user supplied profile with the image.
9754 */
9755 profile=AcquireStringInfo(argument_list[1].length);
9756 SetStringInfoDatum(profile,(const unsigned char *)
9757 argument_list[1].string_reference);
9758 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9759 (size_t) GetStringInfoLength(profile),exception);
9760 profile=DestroyStringInfo(profile);
9761 break;
9762 }
9763 /*
9764 Associate a profile with the image.
9765 */
9766 profile_info=CloneImageInfo(info ? info->image_info :
9767 (ImageInfo *) NULL);
9768 profile_image=ReadImages(profile_info,name,exception);
9769 if (profile_image == (Image *) NULL)
9770 break;
9771 ResetImageProfileIterator(profile_image);
9772 name=GetNextImageProfile(profile_image);
9773 while (name != (const char *) NULL)
9774 {
9775 const StringInfo
9776 *profile;
9777
9778 profile=GetImageProfile(profile_image,name);
9779 if (profile != (const StringInfo *) NULL)
9780 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9781 (size_t) GetStringInfoLength(profile),exception);
9782 name=GetNextImageProfile(profile_image);
9783 }
9784 profile_image=DestroyImage(profile_image);
9785 profile_info=DestroyImageInfo(profile_info);
9786 break;
9787 }
9788 case 69: /* UnsharpMask */
9789 {
9790 if (attribute_flag[0] != 0)
9791 {
9792 flags=ParseGeometry(argument_list[0].string_reference,
9793 &geometry_info);
9794 if ((flags & SigmaValue) == 0)
9795 geometry_info.sigma=1.0;
9796 if ((flags & XiValue) == 0)
9797 geometry_info.xi=1.0;
9798 if ((flags & PsiValue) == 0)
9799 geometry_info.psi=0.5;
9800 }
9801 if (attribute_flag[1] != 0)
9802 geometry_info.rho=argument_list[1].real_reference;
9803 if (attribute_flag[2] != 0)
9804 geometry_info.sigma=argument_list[2].real_reference;
9805 if (attribute_flag[3] != 0)
9806 geometry_info.xi=argument_list[3].real_reference;
9807 if (attribute_flag[4] != 0)
9808 geometry_info.psi=argument_list[4].real_reference;
9809 if (attribute_flag[5] != 0)
9810 channel=(ChannelType) argument_list[5].integer_reference;
9811 channel_mask=SetImageChannelMask(image,channel);
9812 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9813 geometry_info.xi,geometry_info.psi,exception);
9814 if (image != (Image *) NULL)
9815 (void) SetImageChannelMask(image,channel_mask);
9816 break;
9817 }
9818 case 70: /* MotionBlur */
9819 {
9820 if (attribute_flag[0] != 0)
9821 {
9822 flags=ParseGeometry(argument_list[0].string_reference,
9823 &geometry_info);
9824 if ((flags & SigmaValue) == 0)
9825 geometry_info.sigma=1.0;
9826 if ((flags & XiValue) == 0)
9827 geometry_info.xi=1.0;
9828 }
9829 if (attribute_flag[1] != 0)
9830 geometry_info.rho=argument_list[1].real_reference;
9831 if (attribute_flag[2] != 0)
9832 geometry_info.sigma=argument_list[2].real_reference;
9833 if (attribute_flag[3] != 0)
9834 geometry_info.xi=argument_list[3].real_reference;
9835 if (attribute_flag[4] != 0)
9836 channel=(ChannelType) argument_list[4].integer_reference;
9837 channel_mask=SetImageChannelMask(image,channel);
9838 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9839 geometry_info.xi,exception);
9840 if (image != (Image *) NULL)
9841 (void) SetImageChannelMask(image,channel_mask);
9842 break;
9843 }
9844 case 71: /* OrderedDither */
9845 {
9846 if (attribute_flag[0] == 0)
9847 argument_list[0].string_reference="o8x8";
9848 if (attribute_flag[1] != 0)
9849 channel=(ChannelType) argument_list[1].integer_reference;
9850 channel_mask=SetImageChannelMask(image,channel);
Cristy6b93c072016-02-04 07:45:48 -05009851 (void) OrderedDitherImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009852 exception);
9853 (void) SetImageChannelMask(image,channel_mask);
9854 break;
9855 }
9856 case 72: /* Shave */
9857 {
9858 if (attribute_flag[0] != 0)
9859 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9860 &geometry,exception);
9861 if (attribute_flag[1] != 0)
9862 geometry.width=argument_list[1].integer_reference;
9863 if (attribute_flag[2] != 0)
9864 geometry.height=argument_list[2].integer_reference;
9865 image=ShaveImage(image,&geometry,exception);
9866 break;
9867 }
9868 case 73: /* Level */
9869 {
9870 double
9871 black_point,
9872 gamma,
9873 white_point;
9874
9875 black_point=0.0;
9876 white_point=(double) image->columns*image->rows;
9877 gamma=1.0;
9878 if (attribute_flag[0] != 0)
9879 {
9880 flags=ParseGeometry(argument_list[0].string_reference,
9881 &geometry_info);
9882 black_point=geometry_info.rho;
9883 if ((flags & SigmaValue) != 0)
9884 white_point=geometry_info.sigma;
9885 if ((flags & XiValue) != 0)
9886 gamma=geometry_info.xi;
9887 if ((flags & PercentValue) != 0)
9888 {
9889 black_point*=(double) (QuantumRange/100.0);
9890 white_point*=(double) (QuantumRange/100.0);
9891 }
9892 if ((flags & SigmaValue) == 0)
9893 white_point=(double) QuantumRange-black_point;
9894 }
9895 if (attribute_flag[1] != 0)
9896 black_point=argument_list[1].real_reference;
9897 if (attribute_flag[2] != 0)
9898 white_point=argument_list[2].real_reference;
9899 if (attribute_flag[3] != 0)
9900 gamma=argument_list[3].real_reference;
9901 if (attribute_flag[4] != 0)
9902 channel=(ChannelType) argument_list[4].integer_reference;
9903 if (attribute_flag[5] != 0)
9904 {
9905 argument_list[0].real_reference=argument_list[5].real_reference;
9906 attribute_flag[0]=attribute_flag[5];
9907 }
9908 channel_mask=SetImageChannelMask(image,channel);
9909 (void) LevelImage(image,black_point,white_point,gamma,exception);
9910 (void) SetImageChannelMask(image,channel_mask);
9911 break;
9912 }
9913 case 74: /* Clip */
9914 {
9915 if (attribute_flag[0] == 0)
9916 argument_list[0].string_reference="#1";
9917 if (attribute_flag[1] == 0)
9918 argument_list[1].integer_reference=MagickTrue;
9919 (void) ClipImagePath(image,argument_list[0].string_reference,
9920 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9921 exception);
9922 break;
9923 }
9924 case 75: /* AffineTransform */
9925 {
9926 DrawInfo
9927 *draw_info;
9928
9929 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9930 (DrawInfo *) NULL);
9931 if (attribute_flag[0] != 0)
9932 {
9933 AV
9934 *av;
9935
9936 av=(AV *) argument_list[0].array_reference;
9937 if ((av_len(av) != 3) && (av_len(av) != 5))
9938 {
9939 ThrowPerlException(exception,OptionError,
9940 "affine matrix must have 4 or 6 elements",PackageName);
9941 goto PerlException;
9942 }
9943 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9944 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9945 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9946 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9947 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9948 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9949 {
9950 ThrowPerlException(exception,OptionError,
9951 "affine matrix is singular",PackageName);
9952 goto PerlException;
9953 }
9954 if (av_len(av) == 5)
9955 {
9956 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9957 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9958 }
9959 }
9960 for (j=1; j < 6; j++)
9961 {
9962 if (attribute_flag[j] == 0)
9963 continue;
9964 value=argument_list[j].string_reference;
9965 angle=argument_list[j].real_reference;
9966 current=draw_info->affine;
9967 GetAffineMatrix(&affine);
9968 switch (j)
9969 {
9970 case 1:
9971 {
9972 /*
9973 Translate.
9974 */
9975 flags=ParseGeometry(value,&geometry_info);
9976 affine.tx=geometry_info.xi;
9977 affine.ty=geometry_info.psi;
9978 if ((flags & PsiValue) == 0)
9979 affine.ty=affine.tx;
9980 break;
9981 }
9982 case 2:
9983 {
9984 /*
9985 Scale.
9986 */
9987 flags=ParseGeometry(value,&geometry_info);
9988 affine.sx=geometry_info.rho;
9989 affine.sy=geometry_info.sigma;
9990 if ((flags & SigmaValue) == 0)
9991 affine.sy=affine.sx;
9992 break;
9993 }
9994 case 3:
9995 {
9996 /*
9997 Rotate.
9998 */
9999 if (angle == 0.0)
10000 break;
10001 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
10002 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
10003 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
10004 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
10005 break;
10006 }
10007 case 4:
10008 {
10009 /*
10010 SkewX.
10011 */
10012 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
10013 break;
10014 }
10015 case 5:
10016 {
10017 /*
10018 SkewY.
10019 */
10020 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
10021 break;
10022 }
10023 }
10024 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
10025 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
10026 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
10027 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
10028 draw_info->affine.tx=
10029 current.sx*affine.tx+current.ry*affine.ty+current.tx;
10030 draw_info->affine.ty=
10031 current.rx*affine.tx+current.sy*affine.ty+current.ty;
10032 }
10033 if (attribute_flag[6] != 0)
10034 image->interpolate=(PixelInterpolateMethod)
10035 argument_list[6].integer_reference;
10036 if (attribute_flag[7] != 0)
10037 QueryColorCompliance(argument_list[7].string_reference,
10038 AllCompliance,&image->background_color,exception);
10039 image=AffineTransformImage(image,&draw_info->affine,exception);
10040 draw_info=DestroyDrawInfo(draw_info);
10041 break;
10042 }
10043 case 76: /* Difference */
10044 {
10045 if (attribute_flag[0] == 0)
10046 {
10047 ThrowPerlException(exception,OptionError,
10048 "ReferenceImageRequired",PackageName);
10049 goto PerlException;
10050 }
10051 if (attribute_flag[1] != 0)
10052 image->fuzz=StringToDoubleInterval(
10053 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -050010054 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +000010055 exception);
10056 break;
10057 }
10058 case 77: /* AdaptiveThreshold */
10059 {
10060 if (attribute_flag[0] != 0)
10061 {
10062 flags=ParseGeometry(argument_list[0].string_reference,
10063 &geometry_info);
10064 if ((flags & PercentValue) != 0)
10065 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10066 }
10067 if (attribute_flag[1] != 0)
10068 geometry_info.rho=argument_list[1].integer_reference;
10069 if (attribute_flag[2] != 0)
10070 geometry_info.sigma=argument_list[2].integer_reference;
10071 if (attribute_flag[3] != 0)
10072 geometry_info.xi=argument_list[3].integer_reference;;
10073 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
10074 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
10075 break;
10076 }
10077 case 78: /* Resample */
10078 {
10079 size_t
10080 height,
10081 width;
10082
10083 if (attribute_flag[0] != 0)
10084 {
10085 flags=ParseGeometry(argument_list[0].string_reference,
10086 &geometry_info);
10087 if ((flags & SigmaValue) == 0)
10088 geometry_info.sigma=geometry_info.rho;
10089 }
10090 if (attribute_flag[1] != 0)
10091 geometry_info.rho=argument_list[1].real_reference;
10092 if (attribute_flag[2] != 0)
10093 geometry_info.sigma=argument_list[2].real_reference;
10094 if (attribute_flag[3] == 0)
10095 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10096 if (attribute_flag[4] == 0)
10097 SetImageArtifact(image,"filter:support",
10098 argument_list[4].string_reference);
10099 width=(size_t) (geometry_info.rho*image->columns/
10100 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10101 height=(size_t) (geometry_info.sigma*image->rows/
10102 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
Cristy8645e042016-02-03 16:35:29 -050010103 image=ResizeImage(image,width,height,(FilterType)
cristy4a3ce0a2013-08-03 20:06:59 +000010104 argument_list[3].integer_reference,exception);
10105 if (image != (Image *) NULL)
10106 {
10107 image->resolution.x=geometry_info.rho;
10108 image->resolution.y=geometry_info.sigma;
10109 }
10110 break;
10111 }
10112 case 79: /* Describe */
10113 {
10114 if (attribute_flag[0] == 0)
10115 argument_list[0].file_reference=(FILE *) NULL;
10116 if (attribute_flag[1] != 0)
10117 (void) SetImageArtifact(image,"identify:features",
10118 argument_list[1].string_reference);
Cristy798981a2020-02-17 12:07:15 -050010119 if (attribute_flag[2] != 0)
10120 (void) SetImageArtifact(image,"identify:moments",
10121 argument_list[2].string_reference);
10122 if (attribute_flag[3] != 0)
10123 (void) SetImageArtifact(image,"identify:unique-colors",
10124 argument_list[3].string_reference);
cristy4a3ce0a2013-08-03 20:06:59 +000010125 (void) IdentifyImage(image,argument_list[0].file_reference,
10126 MagickTrue,exception);
10127 break;
10128 }
10129 case 80: /* BlackThreshold */
10130 {
10131 if (attribute_flag[0] == 0)
10132 argument_list[0].string_reference="50%";
10133 if (attribute_flag[2] != 0)
10134 channel=(ChannelType) argument_list[2].integer_reference;
10135 channel_mask=SetImageChannelMask(image,channel);
10136 BlackThresholdImage(image,argument_list[0].string_reference,
10137 exception);
10138 (void) SetImageChannelMask(image,channel_mask);
10139 break;
10140 }
10141 case 81: /* WhiteThreshold */
10142 {
10143 if (attribute_flag[0] == 0)
10144 argument_list[0].string_reference="50%";
10145 if (attribute_flag[2] != 0)
10146 channel=(ChannelType) argument_list[2].integer_reference;
10147 channel_mask=SetImageChannelMask(image,channel);
10148 WhiteThresholdImage(image,argument_list[0].string_reference,
10149 exception);
10150 (void) SetImageChannelMask(image,channel_mask);
10151 break;
10152 }
cristy60c73c02014-03-25 12:09:58 +000010153 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010154 {
10155 if (attribute_flag[0] != 0)
10156 {
10157 flags=ParseGeometry(argument_list[0].string_reference,
10158 &geometry_info);
10159 }
10160 if (attribute_flag[1] != 0)
10161 geometry_info.rho=argument_list[1].real_reference;
10162 if (attribute_flag[2] != 0)
10163 channel=(ChannelType) argument_list[2].integer_reference;
10164 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010165 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010166 if (image != (Image *) NULL)
10167 (void) SetImageChannelMask(image,channel_mask);
10168 break;
10169 }
10170 case 83: /* Thumbnail */
10171 {
10172 if (attribute_flag[0] != 0)
10173 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10174 &geometry,exception);
10175 if (attribute_flag[1] != 0)
10176 geometry.width=argument_list[1].integer_reference;
10177 if (attribute_flag[2] != 0)
10178 geometry.height=argument_list[2].integer_reference;
10179 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10180 break;
10181 }
10182 case 84: /* Strip */
10183 {
10184 (void) StripImage(image,exception);
10185 break;
10186 }
10187 case 85: /* Tint */
10188 {
10189 PixelInfo
10190 tint;
10191
10192 GetPixelInfo(image,&tint);
10193 if (attribute_flag[0] != 0)
10194 (void) QueryColorCompliance(argument_list[0].string_reference,
10195 AllCompliance,&tint,exception);
10196 if (attribute_flag[1] == 0)
10197 argument_list[1].string_reference="100";
10198 image=TintImage(image,argument_list[1].string_reference,&tint,
10199 exception);
10200 break;
10201 }
10202 case 86: /* Channel */
10203 {
10204 if (attribute_flag[0] != 0)
10205 channel=(ChannelType) argument_list[0].integer_reference;
10206 image=SeparateImage(image,channel,exception);
10207 break;
10208 }
10209 case 87: /* Splice */
10210 {
cristy260bd762014-08-15 12:46:34 +000010211 if (attribute_flag[7] != 0)
10212 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010213 if (attribute_flag[0] != 0)
10214 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10215 &geometry,exception);
10216 if (attribute_flag[1] != 0)
10217 geometry.width=argument_list[1].integer_reference;
10218 if (attribute_flag[2] != 0)
10219 geometry.height=argument_list[2].integer_reference;
10220 if (attribute_flag[3] != 0)
10221 geometry.x=argument_list[3].integer_reference;
10222 if (attribute_flag[4] != 0)
10223 geometry.y=argument_list[4].integer_reference;
10224 if (attribute_flag[5] != 0)
10225 image->fuzz=StringToDoubleInterval(
10226 argument_list[5].string_reference,(double) QuantumRange+1.0);
10227 if (attribute_flag[6] != 0)
10228 (void) QueryColorCompliance(argument_list[6].string_reference,
10229 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010230 image=SpliceImage(image,&geometry,exception);
10231 break;
10232 }
10233 case 88: /* Posterize */
10234 {
10235 if (attribute_flag[0] == 0)
10236 argument_list[0].integer_reference=3;
10237 if (attribute_flag[1] == 0)
10238 argument_list[1].integer_reference=0;
10239 (void) PosterizeImage(image,argument_list[0].integer_reference,
10240 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10241 NoDitherMethod,exception);
10242 break;
10243 }
10244 case 89: /* Shadow */
10245 {
10246 if (attribute_flag[0] != 0)
10247 {
10248 flags=ParseGeometry(argument_list[0].string_reference,
10249 &geometry_info);
10250 if ((flags & SigmaValue) == 0)
10251 geometry_info.sigma=1.0;
10252 if ((flags & XiValue) == 0)
10253 geometry_info.xi=4.0;
10254 if ((flags & PsiValue) == 0)
10255 geometry_info.psi=4.0;
10256 }
10257 if (attribute_flag[1] != 0)
10258 geometry_info.rho=argument_list[1].real_reference;
10259 if (attribute_flag[2] != 0)
10260 geometry_info.sigma=argument_list[2].real_reference;
10261 if (attribute_flag[3] != 0)
10262 geometry_info.xi=argument_list[3].integer_reference;
10263 if (attribute_flag[4] != 0)
10264 geometry_info.psi=argument_list[4].integer_reference;
10265 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10266 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10267 ceil(geometry_info.psi-0.5),exception);
10268 break;
10269 }
10270 case 90: /* Identify */
10271 {
10272 if (attribute_flag[0] == 0)
10273 argument_list[0].file_reference=(FILE *) NULL;
10274 if (attribute_flag[1] != 0)
10275 (void) SetImageArtifact(image,"identify:features",
10276 argument_list[1].string_reference);
10277 if ((attribute_flag[2] != 0) &&
10278 (argument_list[2].integer_reference != 0))
10279 (void) SetImageArtifact(image,"identify:unique","true");
10280 (void) IdentifyImage(image,argument_list[0].file_reference,
10281 MagickTrue,exception);
10282 break;
10283 }
10284 case 91: /* SepiaTone */
10285 {
10286 if (attribute_flag[0] == 0)
10287 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10288 image=SepiaToneImage(image,argument_list[0].real_reference,
10289 exception);
10290 break;
10291 }
10292 case 92: /* SigmoidalContrast */
10293 {
10294 MagickBooleanType
10295 sharpen;
10296
10297 if (attribute_flag[0] != 0)
10298 {
10299 flags=ParseGeometry(argument_list[0].string_reference,
10300 &geometry_info);
10301 if ((flags & SigmaValue) == 0)
10302 geometry_info.sigma=QuantumRange/2.0;
10303 if ((flags & PercentValue) != 0)
10304 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10305 }
10306 if (attribute_flag[1] != 0)
10307 geometry_info.rho=argument_list[1].real_reference;
10308 if (attribute_flag[2] != 0)
10309 geometry_info.sigma=argument_list[2].real_reference;
10310 if (attribute_flag[3] != 0)
10311 channel=(ChannelType) argument_list[3].integer_reference;
10312 sharpen=MagickTrue;
10313 if (attribute_flag[4] != 0)
10314 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10315 MagickFalse;
10316 channel_mask=SetImageChannelMask(image,channel);
10317 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10318 geometry_info.sigma,exception);
10319 (void) SetImageChannelMask(image,channel_mask);
10320 break;
10321 }
10322 case 93: /* Extent */
10323 {
10324 if (attribute_flag[7] != 0)
10325 image->gravity=(GravityType) argument_list[7].integer_reference;
10326 if (attribute_flag[0] != 0)
10327 {
10328 int
10329 flags;
10330
10331 flags=ParseGravityGeometry(image,
10332 argument_list[0].string_reference,&geometry,exception);
10333 (void) flags;
10334 if (geometry.width == 0)
10335 geometry.width=image->columns;
10336 if (geometry.height == 0)
10337 geometry.height=image->rows;
10338 }
10339 if (attribute_flag[1] != 0)
10340 geometry.width=argument_list[1].integer_reference;
10341 if (attribute_flag[2] != 0)
10342 geometry.height=argument_list[2].integer_reference;
10343 if (attribute_flag[3] != 0)
10344 geometry.x=argument_list[3].integer_reference;
10345 if (attribute_flag[4] != 0)
10346 geometry.y=argument_list[4].integer_reference;
10347 if (attribute_flag[5] != 0)
10348 image->fuzz=StringToDoubleInterval(
10349 argument_list[5].string_reference,(double) QuantumRange+1.0);
10350 if (attribute_flag[6] != 0)
10351 (void) QueryColorCompliance(argument_list[6].string_reference,
10352 AllCompliance,&image->background_color,exception);
10353 image=ExtentImage(image,&geometry,exception);
10354 break;
10355 }
10356 case 94: /* Vignette */
10357 {
10358 if (attribute_flag[0] != 0)
10359 {
10360 flags=ParseGeometry(argument_list[0].string_reference,
10361 &geometry_info);
10362 if ((flags & SigmaValue) == 0)
10363 geometry_info.sigma=1.0;
10364 if ((flags & XiValue) == 0)
10365 geometry_info.xi=0.1*image->columns;
10366 if ((flags & PsiValue) == 0)
10367 geometry_info.psi=0.1*image->rows;
10368 }
10369 if (attribute_flag[1] != 0)
10370 geometry_info.rho=argument_list[1].real_reference;
10371 if (attribute_flag[2] != 0)
10372 geometry_info.sigma=argument_list[2].real_reference;
10373 if (attribute_flag[3] != 0)
10374 geometry_info.xi=argument_list[3].integer_reference;
10375 if (attribute_flag[4] != 0)
10376 geometry_info.psi=argument_list[4].integer_reference;
10377 if (attribute_flag[5] != 0)
10378 (void) QueryColorCompliance(argument_list[5].string_reference,
10379 AllCompliance,&image->background_color,exception);
10380 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10381 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10382 ceil(geometry_info.psi-0.5),exception);
10383 break;
10384 }
10385 case 95: /* ContrastStretch */
10386 {
10387 double
10388 black_point,
10389 white_point;
10390
10391 black_point=0.0;
10392 white_point=(double) image->columns*image->rows;
10393 if (attribute_flag[0] != 0)
10394 {
10395 flags=ParseGeometry(argument_list[0].string_reference,
10396 &geometry_info);
10397 black_point=geometry_info.rho;
10398 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10399 black_point;
10400 if ((flags & PercentValue) != 0)
10401 {
10402 black_point*=(double) image->columns*image->rows/100.0;
10403 white_point*=(double) image->columns*image->rows/100.0;
10404 }
10405 white_point=(double) image->columns*image->rows-
10406 white_point;
10407 }
10408 if (attribute_flag[1] != 0)
10409 black_point=argument_list[1].real_reference;
10410 if (attribute_flag[2] != 0)
10411 white_point=argument_list[2].real_reference;
10412 if (attribute_flag[4] != 0)
10413 channel=(ChannelType) argument_list[4].integer_reference;
10414 channel_mask=SetImageChannelMask(image,channel);
10415 (void) ContrastStretchImage(image,black_point,white_point,exception);
10416 (void) SetImageChannelMask(image,channel_mask);
10417 break;
10418 }
10419 case 96: /* Sans0 */
10420 {
10421 break;
10422 }
10423 case 97: /* Sans1 */
10424 {
10425 break;
10426 }
10427 case 98: /* AdaptiveSharpen */
10428 {
10429 if (attribute_flag[0] != 0)
10430 {
10431 flags=ParseGeometry(argument_list[0].string_reference,
10432 &geometry_info);
10433 if ((flags & SigmaValue) == 0)
10434 geometry_info.sigma=1.0;
10435 if ((flags & XiValue) == 0)
10436 geometry_info.xi=0.0;
10437 }
10438 if (attribute_flag[1] != 0)
10439 geometry_info.rho=argument_list[1].real_reference;
10440 if (attribute_flag[2] != 0)
10441 geometry_info.sigma=argument_list[2].real_reference;
10442 if (attribute_flag[3] != 0)
10443 geometry_info.xi=argument_list[3].real_reference;
10444 if (attribute_flag[4] != 0)
10445 channel=(ChannelType) argument_list[4].integer_reference;
10446 channel_mask=SetImageChannelMask(image,channel);
10447 image=AdaptiveSharpenImage(image,geometry_info.rho,
10448 geometry_info.sigma,exception);
10449 if (image != (Image *) NULL)
10450 (void) SetImageChannelMask(image,channel_mask);
10451 break;
10452 }
10453 case 99: /* Transpose */
10454 {
10455 image=TransposeImage(image,exception);
10456 break;
10457 }
10458 case 100: /* Tranverse */
10459 {
10460 image=TransverseImage(image,exception);
10461 break;
10462 }
10463 case 101: /* AutoOrient */
10464 {
10465 image=AutoOrientImage(image,image->orientation,exception);
10466 break;
10467 }
10468 case 102: /* AdaptiveBlur */
10469 {
10470 if (attribute_flag[0] != 0)
10471 {
10472 flags=ParseGeometry(argument_list[0].string_reference,
10473 &geometry_info);
10474 if ((flags & SigmaValue) == 0)
10475 geometry_info.sigma=1.0;
10476 if ((flags & XiValue) == 0)
10477 geometry_info.xi=0.0;
10478 }
10479 if (attribute_flag[1] != 0)
10480 geometry_info.rho=argument_list[1].real_reference;
10481 if (attribute_flag[2] != 0)
10482 geometry_info.sigma=argument_list[2].real_reference;
10483 if (attribute_flag[3] != 0)
10484 channel=(ChannelType) argument_list[3].integer_reference;
10485 channel_mask=SetImageChannelMask(image,channel);
10486 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10487 exception);
10488 if (image != (Image *) NULL)
10489 (void) SetImageChannelMask(image,channel_mask);
10490 break;
10491 }
10492 case 103: /* Sketch */
10493 {
10494 if (attribute_flag[0] != 0)
10495 {
10496 flags=ParseGeometry(argument_list[0].string_reference,
10497 &geometry_info);
10498 if ((flags & SigmaValue) == 0)
10499 geometry_info.sigma=1.0;
10500 if ((flags & XiValue) == 0)
10501 geometry_info.xi=1.0;
10502 }
10503 if (attribute_flag[1] != 0)
10504 geometry_info.rho=argument_list[1].real_reference;
10505 if (attribute_flag[2] != 0)
10506 geometry_info.sigma=argument_list[2].real_reference;
10507 if (attribute_flag[3] != 0)
10508 geometry_info.xi=argument_list[3].real_reference;
10509 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10510 geometry_info.xi,exception);
10511 break;
10512 }
10513 case 104: /* UniqueColors */
10514 {
10515 image=UniqueImageColors(image,exception);
10516 break;
10517 }
10518 case 105: /* AdaptiveResize */
10519 {
10520 if (attribute_flag[0] != 0)
10521 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10522 &geometry,exception);
10523 if (attribute_flag[1] != 0)
10524 geometry.width=argument_list[1].integer_reference;
10525 if (attribute_flag[2] != 0)
10526 geometry.height=argument_list[2].integer_reference;
10527 if (attribute_flag[3] != 0)
Cristy8645e042016-02-03 16:35:29 -050010528 image->filter=(FilterType) argument_list[4].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010529 if (attribute_flag[4] != 0)
10530 SetImageArtifact(image,"filter:support",
10531 argument_list[4].string_reference);
10532 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10533 exception);
10534 break;
10535 }
10536 case 106: /* ClipMask */
10537 {
10538 Image
10539 *mask_image;
10540
10541 if (attribute_flag[0] == 0)
10542 {
10543 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10544 PackageName);
10545 goto PerlException;
10546 }
10547 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10548 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010549 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010550 mask_image=DestroyImage(mask_image);
10551 break;
10552 }
10553 case 107: /* LinearStretch */
10554 {
10555 double
10556 black_point,
10557 white_point;
10558
10559 black_point=0.0;
10560 white_point=(double) image->columns*image->rows;
10561 if (attribute_flag[0] != 0)
10562 {
10563 flags=ParseGeometry(argument_list[0].string_reference,
10564 &geometry_info);
10565 if ((flags & SigmaValue) != 0)
10566 white_point=geometry_info.sigma;
10567 if ((flags & PercentValue) != 0)
10568 {
10569 black_point*=(double) image->columns*image->rows/100.0;
10570 white_point*=(double) image->columns*image->rows/100.0;
10571 }
10572 if ((flags & SigmaValue) == 0)
10573 white_point=(double) image->columns*image->rows-black_point;
10574 }
10575 if (attribute_flag[1] != 0)
10576 black_point=argument_list[1].real_reference;
10577 if (attribute_flag[2] != 0)
10578 white_point=argument_list[2].real_reference;
10579 (void) LinearStretchImage(image,black_point,white_point,exception);
10580 break;
10581 }
10582 case 108: /* ColorMatrix */
10583 {
10584 AV
10585 *av;
10586
10587 double
10588 *color_matrix;
10589
10590 KernelInfo
10591 *kernel_info;
10592
10593 size_t
10594 order;
10595
10596 if (attribute_flag[0] == 0)
10597 break;
10598 av=(AV *) argument_list[0].array_reference;
10599 order=(size_t) sqrt(av_len(av)+1);
10600 color_matrix=(double *) AcquireQuantumMemory(order,order*
10601 sizeof(*color_matrix));
10602 if (color_matrix == (double *) NULL)
10603 {
10604 ThrowPerlException(exception,ResourceLimitFatalError,
10605 "MemoryAllocationFailed",PackageName);
10606 goto PerlException;
10607 }
10608 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10609 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10610 for ( ; j < (ssize_t) (order*order); j++)
10611 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010612 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010613 if (kernel_info == (KernelInfo *) NULL)
10614 break;
10615 kernel_info->width=order;
10616 kernel_info->height=order;
10617 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10618 order*sizeof(*kernel_info->values));
10619 if (kernel_info->values != (MagickRealType *) NULL)
10620 {
10621 for (i=0; i < (ssize_t) (order*order); i++)
10622 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10623 image=ColorMatrixImage(image,kernel_info,exception);
10624 }
10625 kernel_info=DestroyKernelInfo(kernel_info);
10626 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10627 break;
10628 }
10629 case 109: /* Mask */
10630 {
10631 Image
10632 *mask_image;
10633
10634 if (attribute_flag[0] == 0)
10635 {
10636 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10637 PackageName);
10638 goto PerlException;
10639 }
10640 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10641 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010642 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010643 mask_image=DestroyImage(mask_image);
10644 break;
10645 }
10646 case 110: /* Polaroid */
10647 {
10648 char
10649 *caption;
10650
10651 DrawInfo
10652 *draw_info;
10653
10654 double
10655 angle;
10656
10657 PixelInterpolateMethod
10658 method;
10659
10660 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10661 (DrawInfo *) NULL);
10662 caption=(char *) NULL;
10663 if (attribute_flag[0] != 0)
10664 caption=InterpretImageProperties(info ? info->image_info :
10665 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10666 exception);
10667 angle=0.0;
10668 if (attribute_flag[1] != 0)
10669 angle=argument_list[1].real_reference;
10670 if (attribute_flag[2] != 0)
10671 (void) CloneString(&draw_info->font,
10672 argument_list[2].string_reference);
10673 if (attribute_flag[3] != 0)
10674 (void) QueryColorCompliance(argument_list[3].string_reference,
10675 AllCompliance,&draw_info->stroke,exception);
10676 if (attribute_flag[4] != 0)
10677 (void) QueryColorCompliance(argument_list[4].string_reference,
10678 AllCompliance,&draw_info->fill,exception);
10679 if (attribute_flag[5] != 0)
10680 draw_info->stroke_width=argument_list[5].real_reference;
10681 if (attribute_flag[6] != 0)
10682 draw_info->pointsize=argument_list[6].real_reference;
10683 if (attribute_flag[7] != 0)
10684 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10685 if (attribute_flag[8] != 0)
10686 (void) QueryColorCompliance(argument_list[8].string_reference,
10687 AllCompliance,&image->background_color,exception);
10688 method=UndefinedInterpolatePixel;
10689 if (attribute_flag[9] != 0)
10690 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10691 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10692 draw_info=DestroyDrawInfo(draw_info);
10693 if (caption != (char *) NULL)
10694 caption=DestroyString(caption);
10695 break;
10696 }
10697 case 111: /* FloodfillPaint */
10698 {
10699 DrawInfo
10700 *draw_info;
10701
10702 MagickBooleanType
10703 invert;
10704
10705 PixelInfo
10706 target;
10707
10708 draw_info=CloneDrawInfo(info ? info->image_info :
10709 (ImageInfo *) NULL,(DrawInfo *) NULL);
10710 if (attribute_flag[0] != 0)
10711 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10712 &geometry,exception);
10713 if (attribute_flag[1] != 0)
10714 geometry.x=argument_list[1].integer_reference;
10715 if (attribute_flag[2] != 0)
10716 geometry.y=argument_list[2].integer_reference;
10717 if (attribute_flag[3] != 0)
10718 (void) QueryColorCompliance(argument_list[3].string_reference,
10719 AllCompliance,&draw_info->fill,exception);
10720 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10721 geometry.x,geometry.y,&target,exception);
10722 if (attribute_flag[4] != 0)
10723 QueryColorCompliance(argument_list[4].string_reference,
10724 AllCompliance,&target,exception);
10725 if (attribute_flag[5] != 0)
10726 image->fuzz=StringToDoubleInterval(
10727 argument_list[5].string_reference,(double) QuantumRange+1.0);
10728 if (attribute_flag[6] != 0)
10729 channel=(ChannelType) argument_list[6].integer_reference;
10730 invert=MagickFalse;
10731 if (attribute_flag[7] != 0)
10732 invert=(MagickBooleanType) argument_list[7].integer_reference;
10733 channel_mask=SetImageChannelMask(image,channel);
10734 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10735 geometry.y,invert,exception);
10736 (void) SetImageChannelMask(image,channel_mask);
10737 draw_info=DestroyDrawInfo(draw_info);
10738 break;
10739 }
10740 case 112: /* Distort */
10741 {
10742 AV
10743 *av;
10744
10745 double
10746 *coordinates;
10747
Cristy8645e042016-02-03 16:35:29 -050010748 DistortMethod
cristy4a3ce0a2013-08-03 20:06:59 +000010749 method;
10750
10751 size_t
10752 number_coordinates;
10753
10754 VirtualPixelMethod
10755 virtual_pixel;
10756
10757 if (attribute_flag[0] == 0)
10758 break;
10759 method=UndefinedDistortion;
10760 if (attribute_flag[1] != 0)
Cristy8645e042016-02-03 16:35:29 -050010761 method=(DistortMethod) argument_list[1].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010762 av=(AV *) argument_list[0].array_reference;
10763 number_coordinates=(size_t) av_len(av)+1;
10764 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10765 sizeof(*coordinates));
10766 if (coordinates == (double *) NULL)
10767 {
10768 ThrowPerlException(exception,ResourceLimitFatalError,
10769 "MemoryAllocationFailed",PackageName);
10770 goto PerlException;
10771 }
10772 for (j=0; j < (ssize_t) number_coordinates; j++)
10773 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10774 virtual_pixel=UndefinedVirtualPixelMethod;
10775 if (attribute_flag[2] != 0)
10776 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10777 argument_list[2].integer_reference,exception);
10778 image=DistortImage(image,method,number_coordinates,coordinates,
10779 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10780 exception);
10781 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10782 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10783 exception);
10784 coordinates=(double *) RelinquishMagickMemory(coordinates);
10785 break;
10786 }
10787 case 113: /* Clut */
10788 {
10789 PixelInterpolateMethod
10790 method;
10791
10792 if (attribute_flag[0] == 0)
10793 {
10794 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10795 PackageName);
10796 goto PerlException;
10797 }
10798 method=UndefinedInterpolatePixel;
10799 if (attribute_flag[1] != 0)
10800 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10801 if (attribute_flag[2] != 0)
10802 channel=(ChannelType) argument_list[2].integer_reference;
10803 channel_mask=SetImageChannelMask(image,channel);
10804 (void) ClutImage(image,argument_list[0].image_reference,method,
10805 exception);
10806 (void) SetImageChannelMask(image,channel_mask);
10807 break;
10808 }
10809 case 114: /* LiquidRescale */
10810 {
10811 if (attribute_flag[0] != 0)
10812 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10813 &geometry,exception);
10814 if (attribute_flag[1] != 0)
10815 geometry.width=argument_list[1].integer_reference;
10816 if (attribute_flag[2] != 0)
10817 geometry.height=argument_list[2].integer_reference;
10818 if (attribute_flag[3] == 0)
10819 argument_list[3].real_reference=1.0;
10820 if (attribute_flag[4] == 0)
10821 argument_list[4].real_reference=0.0;
10822 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10823 argument_list[3].real_reference,argument_list[4].real_reference,
10824 exception);
10825 break;
10826 }
10827 case 115: /* EncipherImage */
10828 {
10829 (void) EncipherImage(image,argument_list[0].string_reference,
10830 exception);
10831 break;
10832 }
10833 case 116: /* DecipherImage */
10834 {
10835 (void) DecipherImage(image,argument_list[0].string_reference,
10836 exception);
10837 break;
10838 }
10839 case 117: /* Deskew */
10840 {
10841 geometry_info.rho=QuantumRange/2.0;
10842 if (attribute_flag[0] != 0)
10843 flags=ParseGeometry(argument_list[0].string_reference,
10844 &geometry_info);
10845 if (attribute_flag[1] != 0)
10846 geometry_info.rho=StringToDoubleInterval(
10847 argument_list[1].string_reference,(double) QuantumRange+1.0);
10848 image=DeskewImage(image,geometry_info.rho,exception);
10849 break;
10850 }
10851 case 118: /* Remap */
10852 {
10853 QuantizeInfo
10854 *quantize_info;
10855
10856 if (attribute_flag[0] == 0)
10857 {
10858 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10859 PackageName);
10860 goto PerlException;
10861 }
10862 quantize_info=AcquireQuantizeInfo(info->image_info);
10863 if (attribute_flag[1] != 0)
10864 quantize_info->dither_method=(DitherMethod)
10865 argument_list[1].integer_reference;
10866 (void) RemapImages(quantize_info,image,
10867 argument_list[0].image_reference,exception);
10868 quantize_info=DestroyQuantizeInfo(quantize_info);
10869 break;
10870 }
10871 case 119: /* SparseColor */
10872 {
10873 AV
10874 *av;
10875
10876 double
10877 *coordinates;
10878
10879 SparseColorMethod
10880 method;
10881
10882 size_t
10883 number_coordinates;
10884
10885 VirtualPixelMethod
10886 virtual_pixel;
10887
10888 if (attribute_flag[0] == 0)
10889 break;
10890 method=UndefinedColorInterpolate;
10891 if (attribute_flag[1] != 0)
10892 method=(SparseColorMethod) argument_list[1].integer_reference;
10893 av=(AV *) argument_list[0].array_reference;
10894 number_coordinates=(size_t) av_len(av)+1;
10895 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10896 sizeof(*coordinates));
10897 if (coordinates == (double *) NULL)
10898 {
10899 ThrowPerlException(exception,ResourceLimitFatalError,
10900 "MemoryAllocationFailed",PackageName);
10901 goto PerlException;
10902 }
10903 for (j=0; j < (ssize_t) number_coordinates; j++)
10904 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10905 virtual_pixel=UndefinedVirtualPixelMethod;
10906 if (attribute_flag[2] != 0)
10907 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10908 argument_list[2].integer_reference,exception);
10909 if (attribute_flag[3] != 0)
10910 channel=(ChannelType) argument_list[3].integer_reference;
10911 channel_mask=SetImageChannelMask(image,channel);
10912 image=SparseColorImage(image,method,number_coordinates,coordinates,
10913 exception);
10914 if (image != (Image *) NULL)
10915 (void) SetImageChannelMask(image,channel_mask);
10916 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10917 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10918 exception);
10919 coordinates=(double *) RelinquishMagickMemory(coordinates);
10920 break;
10921 }
10922 case 120: /* Function */
10923 {
10924 AV
10925 *av;
10926
10927 double
10928 *parameters;
10929
10930 MagickFunction
10931 function;
10932
10933 size_t
10934 number_parameters;
10935
10936 VirtualPixelMethod
10937 virtual_pixel;
10938
10939 if (attribute_flag[0] == 0)
10940 break;
10941 function=UndefinedFunction;
10942 if (attribute_flag[1] != 0)
10943 function=(MagickFunction) argument_list[1].integer_reference;
10944 av=(AV *) argument_list[0].array_reference;
10945 number_parameters=(size_t) av_len(av)+1;
10946 parameters=(double *) AcquireQuantumMemory(number_parameters,
10947 sizeof(*parameters));
10948 if (parameters == (double *) NULL)
10949 {
10950 ThrowPerlException(exception,ResourceLimitFatalError,
10951 "MemoryAllocationFailed",PackageName);
10952 goto PerlException;
10953 }
10954 for (j=0; j < (ssize_t) number_parameters; j++)
10955 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10956 virtual_pixel=UndefinedVirtualPixelMethod;
10957 if (attribute_flag[2] != 0)
10958 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10959 argument_list[2].integer_reference,exception);
10960 (void) FunctionImage(image,function,number_parameters,parameters,
10961 exception);
10962 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10963 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10964 exception);
10965 parameters=(double *) RelinquishMagickMemory(parameters);
10966 break;
10967 }
10968 case 121: /* SelectiveBlur */
10969 {
10970 if (attribute_flag[0] != 0)
10971 {
10972 flags=ParseGeometry(argument_list[0].string_reference,
10973 &geometry_info);
10974 if ((flags & SigmaValue) == 0)
10975 geometry_info.sigma=1.0;
10976 if ((flags & PercentValue) != 0)
10977 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10978 }
10979 if (attribute_flag[1] != 0)
10980 geometry_info.rho=argument_list[1].real_reference;
10981 if (attribute_flag[2] != 0)
10982 geometry_info.sigma=argument_list[2].real_reference;
10983 if (attribute_flag[3] != 0)
10984 geometry_info.xi=argument_list[3].integer_reference;;
10985 if (attribute_flag[5] != 0)
10986 channel=(ChannelType) argument_list[5].integer_reference;
10987 channel_mask=SetImageChannelMask(image,channel);
10988 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10989 geometry_info.xi,exception);
10990 if (image != (Image *) NULL)
10991 (void) SetImageChannelMask(image,channel_mask);
10992 break;
10993 }
10994 case 122: /* HaldClut */
10995 {
10996 if (attribute_flag[0] == 0)
10997 {
10998 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10999 PackageName);
11000 goto PerlException;
11001 }
11002 if (attribute_flag[1] != 0)
11003 channel=(ChannelType) argument_list[1].integer_reference;
11004 channel_mask=SetImageChannelMask(image,channel);
11005 (void) HaldClutImage(image,argument_list[0].image_reference,
11006 exception);
11007 (void) SetImageChannelMask(image,channel_mask);
11008 break;
11009 }
11010 case 123: /* BlueShift */
11011 {
11012 if (attribute_flag[0] != 0)
11013 (void) ParseGeometry(argument_list[0].string_reference,
11014 &geometry_info);
11015 image=BlueShiftImage(image,geometry_info.rho,exception);
11016 break;
11017 }
11018 case 124: /* ForwardFourierTransformImage */
11019 {
11020 image=ForwardFourierTransformImage(image,
11021 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11022 exception);
11023 break;
11024 }
11025 case 125: /* InverseFourierTransformImage */
11026 {
11027 image=InverseFourierTransformImage(image,image->next,
11028 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11029 exception);
11030 break;
11031 }
11032 case 126: /* ColorDecisionList */
11033 {
11034 if (attribute_flag[0] == 0)
11035 argument_list[0].string_reference=(char *) NULL;
11036 (void) ColorDecisionListImage(image,
11037 argument_list[0].string_reference,exception);
11038 break;
11039 }
11040 case 127: /* AutoGamma */
11041 {
11042 if (attribute_flag[0] != 0)
11043 channel=(ChannelType) argument_list[0].integer_reference;
11044 channel_mask=SetImageChannelMask(image,channel);
11045 (void) AutoGammaImage(image,exception);
11046 (void) SetImageChannelMask(image,channel_mask);
11047 break;
11048 }
11049 case 128: /* AutoLevel */
11050 {
11051 if (attribute_flag[0] != 0)
11052 channel=(ChannelType) argument_list[0].integer_reference;
11053 channel_mask=SetImageChannelMask(image,channel);
11054 (void) AutoLevelImage(image,exception);
11055 (void) SetImageChannelMask(image,channel_mask);
11056 break;
11057 }
11058 case 129: /* LevelColors */
11059 {
11060 PixelInfo
11061 black_point,
11062 white_point;
11063
11064 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
11065 exception);
11066 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
11067 exception);
11068 if (attribute_flag[1] != 0)
11069 (void) QueryColorCompliance(
11070 argument_list[1].string_reference,AllCompliance,&black_point,
11071 exception);
11072 if (attribute_flag[2] != 0)
11073 (void) QueryColorCompliance(
11074 argument_list[2].string_reference,AllCompliance,&white_point,
11075 exception);
11076 if (attribute_flag[3] != 0)
11077 channel=(ChannelType) argument_list[3].integer_reference;
11078 channel_mask=SetImageChannelMask(image,channel);
11079 (void) LevelImageColors(image,&black_point,&white_point,
11080 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11081 exception);
11082 (void) SetImageChannelMask(image,channel_mask);
11083 break;
11084 }
11085 case 130: /* Clamp */
11086 {
11087 if (attribute_flag[0] != 0)
11088 channel=(ChannelType) argument_list[0].integer_reference;
11089 channel_mask=SetImageChannelMask(image,channel);
11090 (void) ClampImage(image,exception);
11091 (void) SetImageChannelMask(image,channel_mask);
11092 break;
11093 }
11094 case 131: /* BrightnessContrast */
11095 {
11096 double
11097 brightness,
11098 contrast;
11099
11100 brightness=0.0;
11101 contrast=0.0;
11102 if (attribute_flag[0] != 0)
11103 {
11104 flags=ParseGeometry(argument_list[0].string_reference,
11105 &geometry_info);
11106 brightness=geometry_info.rho;
11107 if ((flags & SigmaValue) == 0)
11108 contrast=geometry_info.sigma;
11109 }
11110 if (attribute_flag[1] != 0)
11111 brightness=argument_list[1].real_reference;
11112 if (attribute_flag[2] != 0)
11113 contrast=argument_list[2].real_reference;
11114 if (attribute_flag[4] != 0)
11115 channel=(ChannelType) argument_list[4].integer_reference;
11116 channel_mask=SetImageChannelMask(image,channel);
11117 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11118 (void) SetImageChannelMask(image,channel_mask);
11119 break;
11120 }
11121 case 132: /* Morphology */
11122 {
11123 KernelInfo
11124 *kernel;
11125
11126 MorphologyMethod
11127 method;
11128
11129 ssize_t
11130 iterations;
11131
11132 if (attribute_flag[0] == 0)
11133 break;
cristy2c57b742014-10-31 00:40:34 +000011134 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011135 if (kernel == (KernelInfo *) NULL)
11136 break;
11137 if (attribute_flag[1] != 0)
11138 channel=(ChannelType) argument_list[1].integer_reference;
11139 method=UndefinedMorphology;
11140 if (attribute_flag[2] != 0)
11141 method=argument_list[2].integer_reference;
11142 iterations=1;
11143 if (attribute_flag[3] != 0)
11144 iterations=argument_list[3].integer_reference;
11145 channel_mask=SetImageChannelMask(image,channel);
11146 image=MorphologyImage(image,method,iterations,kernel,exception);
11147 if (image != (Image *) NULL)
11148 (void) SetImageChannelMask(image,channel_mask);
11149 kernel=DestroyKernelInfo(kernel);
11150 break;
11151 }
11152 case 133: /* Mode */
11153 {
11154 if (attribute_flag[0] != 0)
11155 {
11156 flags=ParseGeometry(argument_list[0].string_reference,
11157 &geometry_info);
11158 if ((flags & SigmaValue) == 0)
11159 geometry_info.sigma=1.0;
11160 }
11161 if (attribute_flag[1] != 0)
11162 geometry_info.rho=argument_list[1].real_reference;
11163 if (attribute_flag[2] != 0)
11164 geometry_info.sigma=argument_list[2].real_reference;
11165 if (attribute_flag[3] != 0)
11166 channel=(ChannelType) argument_list[3].integer_reference;
11167 channel_mask=SetImageChannelMask(image,channel);
11168 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11169 (size_t) geometry_info.sigma,exception);
11170 if (image != (Image *) NULL)
11171 (void) SetImageChannelMask(image,channel_mask);
11172 break;
11173 }
11174 case 134: /* Statistic */
11175 {
11176 StatisticType
11177 statistic;
11178
11179 statistic=UndefinedStatistic;
11180 if (attribute_flag[0] != 0)
11181 {
11182 flags=ParseGeometry(argument_list[0].string_reference,
11183 &geometry_info);
11184 if ((flags & SigmaValue) == 0)
11185 geometry_info.sigma=1.0;
11186 }
11187 if (attribute_flag[1] != 0)
11188 geometry_info.rho=argument_list[1].real_reference;
11189 if (attribute_flag[2] != 0)
11190 geometry_info.sigma=argument_list[2].real_reference;
11191 if (attribute_flag[3] != 0)
11192 channel=(ChannelType) argument_list[3].integer_reference;
11193 if (attribute_flag[4] != 0)
11194 statistic=(StatisticType) argument_list[4].integer_reference;
11195 channel_mask=SetImageChannelMask(image,channel);
11196 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11197 (size_t) geometry_info.sigma,exception);
11198 if (image != (Image *) NULL)
11199 (void) SetImageChannelMask(image,channel_mask);
11200 break;
11201 }
11202 case 135: /* Perceptible */
11203 {
11204 double
11205 epsilon;
11206
11207 epsilon=MagickEpsilon;
11208 if (attribute_flag[0] != 0)
11209 epsilon=argument_list[0].real_reference;
11210 if (attribute_flag[1] != 0)
11211 channel=(ChannelType) argument_list[1].integer_reference;
11212 channel_mask=SetImageChannelMask(image,channel);
11213 (void) PerceptibleImage(image,epsilon,exception);
11214 (void) SetImageChannelMask(image,channel_mask);
11215 break;
11216 }
11217 case 136: /* Poly */
11218 {
11219 AV
11220 *av;
11221
11222 double
11223 *terms;
11224
11225 size_t
11226 number_terms;
11227
11228 if (attribute_flag[0] == 0)
11229 break;
11230 if (attribute_flag[1] != 0)
11231 channel=(ChannelType) argument_list[1].integer_reference;
11232 av=(AV *) argument_list[0].array_reference;
11233 number_terms=(size_t) av_len(av);
11234 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11235 if (terms == (double *) NULL)
11236 {
11237 ThrowPerlException(exception,ResourceLimitFatalError,
11238 "MemoryAllocationFailed",PackageName);
11239 goto PerlException;
11240 }
11241 for (j=0; j < av_len(av); j++)
11242 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11243 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11244 terms=(double *) RelinquishMagickMemory(terms);
11245 break;
11246 }
11247 case 137: /* Grayscale */
11248 {
11249 PixelIntensityMethod
11250 method;
11251
11252 method=UndefinedPixelIntensityMethod;
11253 if (attribute_flag[0] != 0)
11254 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11255 (void) GrayscaleImage(image,method,exception);
11256 break;
11257 }
cristy4ceadb82014-03-29 15:30:43 +000011258 case 138: /* Canny */
11259 {
11260 if (attribute_flag[0] != 0)
11261 {
11262 flags=ParseGeometry(argument_list[0].string_reference,
11263 &geometry_info);
11264 if ((flags & SigmaValue) == 0)
11265 geometry_info.sigma=1.0;
11266 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011267 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011268 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011269 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011270 if ((flags & PercentValue) != 0)
11271 {
11272 geometry_info.xi/=100.0;
11273 geometry_info.psi/=100.0;
11274 }
cristy4ceadb82014-03-29 15:30:43 +000011275 }
11276 if (attribute_flag[1] != 0)
11277 geometry_info.rho=argument_list[1].real_reference;
11278 if (attribute_flag[2] != 0)
11279 geometry_info.sigma=argument_list[2].real_reference;
11280 if (attribute_flag[3] != 0)
11281 geometry_info.xi=argument_list[3].real_reference;
11282 if (attribute_flag[4] != 0)
11283 geometry_info.psi=argument_list[4].real_reference;
11284 if (attribute_flag[5] != 0)
11285 channel=(ChannelType) argument_list[5].integer_reference;
11286 channel_mask=SetImageChannelMask(image,channel);
11287 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11288 geometry_info.xi,geometry_info.psi,exception);
11289 if (image != (Image *) NULL)
11290 (void) SetImageChannelMask(image,channel_mask);
11291 break;
11292 }
cristy2fc10e52014-04-26 14:13:53 +000011293 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011294 {
11295 if (attribute_flag[0] != 0)
11296 {
11297 flags=ParseGeometry(argument_list[0].string_reference,
11298 &geometry_info);
11299 if ((flags & SigmaValue) == 0)
11300 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011301 if ((flags & XiValue) == 0)
11302 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011303 }
11304 if (attribute_flag[1] != 0)
11305 geometry_info.rho=(double) argument_list[1].integer_reference;
11306 if (attribute_flag[2] != 0)
11307 geometry_info.sigma=(double) argument_list[2].integer_reference;
11308 if (attribute_flag[3] != 0)
11309 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011310 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11311 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11312 break;
11313 }
11314 case 140: /* MeanShift */
11315 {
11316 if (attribute_flag[0] != 0)
11317 {
11318 flags=ParseGeometry(argument_list[0].string_reference,
11319 &geometry_info);
11320 if ((flags & SigmaValue) == 0)
11321 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011322 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011323 geometry_info.xi=0.10*QuantumRange;
11324 if ((flags & PercentValue) != 0)
11325 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011326 }
11327 if (attribute_flag[1] != 0)
11328 geometry_info.rho=(double) argument_list[1].integer_reference;
11329 if (attribute_flag[2] != 0)
11330 geometry_info.sigma=(double) argument_list[2].integer_reference;
11331 if (attribute_flag[3] != 0)
11332 geometry_info.xi=(double) argument_list[3].integer_reference;
11333 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011334 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011335 break;
11336 }
cristy3b207f82014-09-27 14:21:20 +000011337 case 141: /* Kuwahara */
11338 {
11339 if (attribute_flag[0] != 0)
11340 {
11341 flags=ParseGeometry(argument_list[0].string_reference,
11342 &geometry_info);
11343 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011344 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011345 }
11346 if (attribute_flag[1] != 0)
11347 geometry_info.rho=argument_list[1].real_reference;
11348 if (attribute_flag[2] != 0)
11349 geometry_info.sigma=argument_list[2].real_reference;
11350 if (attribute_flag[3] != 0)
11351 channel=(ChannelType) argument_list[3].integer_reference;
11352 channel_mask=SetImageChannelMask(image,channel);
11353 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11354 exception);
11355 if (image != (Image *) NULL)
11356 (void) SetImageChannelMask(image,channel_mask);
11357 break;
11358 }
Cristy0f5df812017-07-04 18:30:05 -040011359 case 142: /* ConnectedComponents */
cristy6e0b3bc2014-10-19 17:51:42 +000011360 {
11361 size_t
11362 connectivity;
11363
11364 connectivity=4;
11365 if (attribute_flag[0] != 0)
11366 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011367 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011368 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011369 break;
11370 }
cristy0b94b392015-06-22 18:56:37 +000011371 case 143: /* Copy */
11372 {
11373 Image
11374 *source_image;
11375
11376 OffsetInfo
11377 offset;
11378
cristy2ffdb092015-06-25 14:31:20 +000011379 RectangleInfo
11380 offset_geometry;
11381
cristyf3a724a2015-06-25 13:02:53 +000011382 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011383 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011384 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011385 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011386 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011387 flags=ParseGravityGeometry(source_image,
11388 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011389 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011390 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011391 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011392 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011393 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011394 geometry.x=argument_list[4].integer_reference;
11395 if (attribute_flag[5] != 0)
11396 geometry.y=argument_list[5].integer_reference;
11397 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011398 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011399 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011400 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011401 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11402 &offset_geometry,exception);
11403 offset.x=offset_geometry.x;
11404 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011405 if (attribute_flag[8] != 0)
11406 offset.x=argument_list[8].integer_reference;
11407 if (attribute_flag[9] != 0)
11408 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011409 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11410 exception);
cristy0b94b392015-06-22 18:56:37 +000011411 break;
11412 }
Cristy5488c982016-02-13 14:07:50 -050011413 case 144: /* Color */
11414 {
11415 PixelInfo
11416 color;
11417
Cristyf20e3562016-02-14 09:08:15 -050011418 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011419 if (attribute_flag[0] != 0)
Cristyf20e3562016-02-14 09:08:15 -050011420 (void) QueryColorCompliance(argument_list[0].string_reference,
11421 AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011422 (void) SetImageColor(image,&color,exception);
11423 break;
11424 }
Cristy2d830ed2016-02-21 10:54:16 -050011425 case 145: /* WaveletDenoise */
11426 {
Cristyc1759412016-02-27 12:17:58 -050011427 if (attribute_flag[0] != 0)
Cristyee21f7f2016-02-27 15:56:49 -050011428 {
11429 flags=ParseGeometry(argument_list[0].string_reference,
11430 &geometry_info);
11431 if ((flags & PercentValue) != 0)
Cristy23446632016-02-29 09:36:34 -050011432 {
11433 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11434 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
11435 }
Cristyee21f7f2016-02-27 15:56:49 -050011436 if ((flags & SigmaValue) == 0)
11437 geometry_info.sigma=0.0;
11438 }
Cristyc1759412016-02-27 12:17:58 -050011439 if (attribute_flag[1] != 0)
11440 geometry_info.rho=argument_list[1].real_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011441 if (attribute_flag[2] != 0)
Cristyc1759412016-02-27 12:17:58 -050011442 geometry_info.sigma=argument_list[2].real_reference;
11443 if (attribute_flag[3] != 0)
11444 channel=(ChannelType) argument_list[3].integer_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011445 channel_mask=SetImageChannelMask(image,channel);
Cristyc1759412016-02-27 12:17:58 -050011446 image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11447 exception);
Cristy2d830ed2016-02-21 10:54:16 -050011448 if (image != (Image *) NULL)
11449 (void) SetImageChannelMask(image,channel_mask);
11450 break;
11451 }
Cristy99a57162016-12-05 11:47:57 -050011452 case 146: /* Colorspace */
11453 {
11454 ColorspaceType
11455 colorspace;
11456
11457 colorspace=sRGBColorspace;
11458 if (attribute_flag[0] != 0)
11459 colorspace=(ColorspaceType) argument_list[0].integer_reference;
11460 (void) TransformImageColorspace(image,colorspace,exception);
11461 break;
11462 }
Cristy53353872017-07-02 12:24:24 -040011463 case 147: /* AutoThreshold */
11464 {
11465 AutoThresholdMethod
11466 method;
11467
11468 method=UndefinedThresholdMethod;
11469 if (attribute_flag[0] != 0)
Cristyb63e7752017-07-02 13:22:01 -040011470 method=(AutoThresholdMethod) argument_list[0].integer_reference;
Cristy53353872017-07-02 12:24:24 -040011471 (void) AutoThresholdImage(image,method,exception);
11472 break;
11473 }
Cristy532b3382018-08-05 17:56:56 -040011474 case 148: /* RangeThreshold */
11475 {
11476 if (attribute_flag[0] != 0)
11477 {
11478 flags=ParseGeometry(argument_list[0].string_reference,
11479 &geometry_info);
11480 if ((flags & SigmaValue) == 0)
11481 geometry_info.sigma=geometry_info.rho;
11482 if ((flags & XiValue) == 0)
11483 geometry_info.xi=geometry_info.sigma;
11484 if ((flags & PsiValue) == 0)
11485 geometry_info.psi=geometry_info.xi;
11486 }
11487 if (attribute_flag[1] != 0)
11488 geometry_info.rho=argument_list[1].real_reference;
11489 if (attribute_flag[2] != 0)
11490 geometry_info.sigma=argument_list[2].real_reference;
11491 if (attribute_flag[3] != 0)
11492 geometry_info.xi=argument_list[3].real_reference;
11493 if (attribute_flag[4] != 0)
11494 geometry_info.psi=argument_list[4].real_reference;
11495 if (attribute_flag[5] != 0)
11496 channel=(ChannelType) argument_list[5].integer_reference;
11497 channel_mask=SetImageChannelMask(image,channel);
Cristy9b220db2018-08-05 18:02:28 -040011498 (void) RangeThresholdImage(image,geometry_info.rho,
11499 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
Cristy532b3382018-08-05 17:56:56 -040011500 if (image != (Image *) NULL)
11501 (void) SetImageChannelMask(image,channel_mask);
11502 break;
11503 }
Cristy9f252542018-11-21 19:13:46 -050011504 case 149: /* CLAHE */
11505 {
11506 if (attribute_flag[0] != 0)
Cristy768e9002019-01-08 07:35:16 -050011507 {
11508 flags=ParseGeometry(argument_list[0].string_reference,
11509 &geometry_info);
11510 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
11511 &geometry,exception);
11512 }
Cristy9f252542018-11-21 19:13:46 -050011513 if (attribute_flag[1] != 0)
Cristy30263282018-12-11 16:40:25 -050011514 geometry.width=argument_list[1].integer_reference;
Cristy9f252542018-11-21 19:13:46 -050011515 if (attribute_flag[2] != 0)
Cristy30263282018-12-11 16:40:25 -050011516 geometry.height=argument_list[2].integer_reference;
Cristy9f252542018-11-21 19:13:46 -050011517 if (attribute_flag[3] != 0)
Cristy768e9002019-01-08 07:35:16 -050011518 geometry.x=argument_list[3].integer_reference;
Cristy9f252542018-11-21 19:13:46 -050011519 if (attribute_flag[4] != 0)
Cristy768e9002019-01-08 07:35:16 -050011520 geometry_info.psi=argument_list[4].real_reference;
Cristyd9b98812018-12-16 09:30:05 -050011521 (void) CLAHEImage(image,geometry.width,geometry.height,geometry.x,
Cristy768e9002019-01-08 07:35:16 -050011522 geometry_info.psi,exception);
Cristy9f252542018-11-21 19:13:46 -050011523 break;
11524 }
Cristyb4ab5192019-12-19 06:53:46 -050011525 case 150: /* Kmeans */
11526 {
11527 if (attribute_flag[0] != 0)
11528 {
11529 flags=ParseGeometry(argument_list[0].string_reference,
11530 &geometry_info);
11531 if ((flags & SigmaValue) == 0)
Cristyc809e482019-12-21 09:59:52 -050011532 geometry_info.sigma=100.0;
Cristyb4ab5192019-12-19 06:53:46 -050011533 if ((flags & XiValue) == 0)
Cristyc809e482019-12-21 09:59:52 -050011534 geometry_info.xi=0.01;
Cristyb4ab5192019-12-19 06:53:46 -050011535 }
11536 if (attribute_flag[1] != 0)
11537 geometry_info.rho=argument_list[1].integer_reference;
11538 if (attribute_flag[2] != 0)
11539 geometry_info.sigma=argument_list[2].integer_reference;
11540 if (attribute_flag[3] != 0)
11541 geometry_info.xi=(ChannelType) argument_list[3].real_reference;
11542 (void) KmeansImage(image,geometry_info.rho,geometry_info.sigma,
11543 geometry_info.xi,exception);
11544 break;
11545 }
cristy4a3ce0a2013-08-03 20:06:59 +000011546 }
11547 if (next != (Image *) NULL)
11548 (void) CatchImageException(next);
Cristy7e567962018-02-03 12:42:20 -050011549 if ((region_info.width*region_info.height) != 0)
11550 (void) SetImageRegionMask(image,WritePixelMask,
11551 (const RectangleInfo *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011552 if (image != (Image *) NULL)
11553 {
11554 number_images++;
11555 if (next && (next != image))
11556 {
11557 image->next=next->next;
11558 if (image->next != (Image *) NULL)
11559 image->next->previous=image;
11560 DeleteImageFromRegistry(*pv,next);
11561 }
11562 sv_setiv(*pv,PTR2IV(image));
11563 next=image;
11564 }
11565 if (*pv)
11566 pv++;
11567 }
11568
11569 PerlException:
11570 if (reference_vector)
11571 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11572 InheritPerlException(exception,perl_exception);
11573 exception=DestroyExceptionInfo(exception);
11574 sv_setiv(perl_exception,(IV) number_images);
11575 SvPOK_on(perl_exception);
11576 ST(0)=sv_2mortal(perl_exception);
11577 XSRETURN(1);
11578 }
11579
11580#
11581###############################################################################
11582# #
11583# #
11584# #
11585# M o n t a g e #
11586# #
11587# #
11588# #
11589###############################################################################
11590#
11591#
11592void
11593Montage(ref,...)
11594 Image::Magick ref=NO_INIT
11595 ALIAS:
11596 MontageImage = 1
11597 montage = 2
11598 montageimage = 3
11599 PPCODE:
11600 {
11601 AV
11602 *av;
11603
11604 char
11605 *attribute;
11606
11607 ExceptionInfo
11608 *exception;
11609
11610 HV
11611 *hv;
11612
11613 Image
11614 *image,
11615 *next;
11616
11617 PixelInfo
11618 transparent_color;
11619
11620 MontageInfo
11621 *montage_info;
11622
11623 register ssize_t
11624 i;
11625
11626 ssize_t
11627 sp;
11628
11629 struct PackageInfo
11630 *info;
11631
11632 SV
11633 *av_reference,
11634 *perl_exception,
11635 *reference,
11636 *rv,
11637 *sv;
11638
11639 PERL_UNUSED_VAR(ref);
11640 PERL_UNUSED_VAR(ix);
11641 exception=AcquireExceptionInfo();
11642 perl_exception=newSVpv("",0);
11643 sv=NULL;
11644 attribute=NULL;
11645 if (sv_isobject(ST(0)) == 0)
11646 {
11647 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11648 PackageName);
11649 goto PerlException;
11650 }
11651 reference=SvRV(ST(0));
11652 hv=SvSTASH(reference);
11653 av=newAV();
11654 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11655 SvREFCNT_dec(av);
11656 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11657 if (image == (Image *) NULL)
11658 {
11659 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11660 PackageName);
11661 goto PerlException;
11662 }
11663 /*
11664 Get options.
11665 */
11666 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11667 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11668 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11669 exception);
11670 for (i=2; i < items; i+=2)
11671 {
11672 attribute=(char *) SvPV(ST(i-1),na);
11673 switch (*attribute)
11674 {
11675 case 'B':
11676 case 'b':
11677 {
11678 if (LocaleCompare(attribute,"background") == 0)
11679 {
11680 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11681 &montage_info->background_color,exception);
11682 for (next=image; next; next=next->next)
11683 next->background_color=montage_info->background_color;
11684 break;
11685 }
11686 if (LocaleCompare(attribute,"border") == 0)
11687 {
11688 montage_info->border_width=SvIV(ST(i));
11689 break;
11690 }
11691 if (LocaleCompare(attribute,"bordercolor") == 0)
11692 {
11693 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11694 &montage_info->border_color,exception);
11695 for (next=image; next; next=next->next)
11696 next->border_color=montage_info->border_color;
11697 break;
11698 }
11699 if (LocaleCompare(attribute,"borderwidth") == 0)
11700 {
11701 montage_info->border_width=SvIV(ST(i));
11702 break;
11703 }
11704 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11705 attribute);
11706 break;
11707 }
11708 case 'C':
11709 case 'c':
11710 {
11711 if (LocaleCompare(attribute,"compose") == 0)
11712 {
11713 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11714 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11715 if (sp < 0)
11716 {
11717 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11718 SvPV(ST(i),na));
11719 break;
11720 }
11721 for (next=image; next; next=next->next)
11722 next->compose=(CompositeOperator) sp;
11723 break;
11724 }
11725 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11726 attribute);
11727 break;
11728 }
11729 case 'F':
11730 case 'f':
11731 {
11732 if (LocaleCompare(attribute,"fill") == 0)
11733 {
11734 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11735 &montage_info->fill,exception);
11736 break;
11737 }
11738 if (LocaleCompare(attribute,"font") == 0)
11739 {
11740 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11741 break;
11742 }
11743 if (LocaleCompare(attribute,"frame") == 0)
11744 {
11745 char
11746 *p;
11747
11748 p=SvPV(ST(i),na);
11749 if (IsGeometry(p) == MagickFalse)
11750 {
11751 ThrowPerlException(exception,OptionError,"MissingGeometry",
11752 p);
11753 break;
11754 }
11755 (void) CloneString(&montage_info->frame,p);
11756 if (*p == '\0')
11757 montage_info->frame=(char *) NULL;
11758 break;
11759 }
11760 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11761 attribute);
11762 break;
11763 }
11764 case 'G':
11765 case 'g':
11766 {
11767 if (LocaleCompare(attribute,"geometry") == 0)
11768 {
11769 char
11770 *p;
11771
11772 p=SvPV(ST(i),na);
11773 if (IsGeometry(p) == MagickFalse)
11774 {
11775 ThrowPerlException(exception,OptionError,"MissingGeometry",
11776 p);
11777 break;
11778 }
11779 (void) CloneString(&montage_info->geometry,p);
11780 if (*p == '\0')
11781 montage_info->geometry=(char *) NULL;
11782 break;
11783 }
11784 if (LocaleCompare(attribute,"gravity") == 0)
11785 {
11786 ssize_t
11787 in;
11788
11789 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11790 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11791 if (in < 0)
11792 {
11793 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11794 SvPV(ST(i),na));
11795 return;
11796 }
11797 montage_info->gravity=(GravityType) in;
11798 for (next=image; next; next=next->next)
11799 next->gravity=(GravityType) in;
11800 break;
11801 }
11802 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11803 attribute);
11804 break;
11805 }
11806 case 'L':
11807 case 'l':
11808 {
11809 if (LocaleCompare(attribute,"label") == 0)
11810 {
11811 for (next=image; next; next=next->next)
Cristy935a4052017-03-31 17:45:37 -040011812 (void) SetImageProperty(next,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +000011813 info ? info->image_info : (ImageInfo *) NULL,next,
Cristy935a4052017-03-31 17:45:37 -040011814 SvPV(ST(i),na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011815 break;
11816 }
11817 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11818 attribute);
11819 break;
11820 }
11821 case 'M':
11822 case 'm':
11823 {
11824 if (LocaleCompare(attribute,"mattecolor") == 0)
11825 {
11826 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
Cristy8645e042016-02-03 16:35:29 -050011827 &montage_info->alpha_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011828 for (next=image; next; next=next->next)
Cristy8645e042016-02-03 16:35:29 -050011829 next->alpha_color=montage_info->alpha_color;
cristy4a3ce0a2013-08-03 20:06:59 +000011830 break;
11831 }
11832 if (LocaleCompare(attribute,"mode") == 0)
11833 {
11834 ssize_t
11835 in;
11836
11837 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11838 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11839 switch (in)
11840 {
11841 default:
11842 {
11843 ThrowPerlException(exception,OptionError,
11844 "UnrecognizedModeType",SvPV(ST(i),na));
11845 break;
11846 }
11847 case FrameMode:
11848 {
11849 (void) CloneString(&montage_info->frame,"15x15+3+3");
11850 montage_info->shadow=MagickTrue;
11851 break;
11852 }
11853 case UnframeMode:
11854 {
11855 montage_info->frame=(char *) NULL;
11856 montage_info->shadow=MagickFalse;
11857 montage_info->border_width=0;
11858 break;
11859 }
11860 case ConcatenateMode:
11861 {
11862 montage_info->frame=(char *) NULL;
11863 montage_info->shadow=MagickFalse;
11864 (void) CloneString(&montage_info->geometry,"+0+0");
11865 montage_info->border_width=0;
11866 }
11867 }
11868 break;
11869 }
11870 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11871 attribute);
11872 break;
11873 }
11874 case 'P':
11875 case 'p':
11876 {
11877 if (LocaleCompare(attribute,"pointsize") == 0)
11878 {
11879 montage_info->pointsize=SvIV(ST(i));
11880 break;
11881 }
11882 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11883 attribute);
11884 break;
11885 }
11886 case 'S':
11887 case 's':
11888 {
11889 if (LocaleCompare(attribute,"shadow") == 0)
11890 {
11891 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11892 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11893 if (sp < 0)
11894 {
11895 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11896 SvPV(ST(i),na));
11897 break;
11898 }
11899 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11900 break;
11901 }
11902 if (LocaleCompare(attribute,"stroke") == 0)
11903 {
11904 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11905 &montage_info->stroke,exception);
11906 break;
11907 }
11908 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11909 attribute);
11910 break;
11911 }
11912 case 'T':
11913 case 't':
11914 {
11915 if (LocaleCompare(attribute,"texture") == 0)
11916 {
11917 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11918 break;
11919 }
11920 if (LocaleCompare(attribute,"tile") == 0)
11921 {
11922 char *p=SvPV(ST(i),na);
11923 if (IsGeometry(p) == MagickFalse)
11924 {
11925 ThrowPerlException(exception,OptionError,"MissingGeometry",
11926 p);
11927 break;
11928 }
11929 (void) CloneString(&montage_info->tile,p);
11930 if (*p == '\0')
11931 montage_info->tile=(char *) NULL;
11932 break;
11933 }
11934 if (LocaleCompare(attribute,"title") == 0)
11935 {
11936 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11937 break;
11938 }
11939 if (LocaleCompare(attribute,"transparent") == 0)
11940 {
11941 PixelInfo
11942 transparent_color;
11943
11944 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11945 &transparent_color,exception);
11946 for (next=image; next; next=next->next)
11947 (void) TransparentPaintImage(next,&transparent_color,
11948 TransparentAlpha,MagickFalse,exception);
11949 break;
11950 }
11951 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11952 attribute);
11953 break;
11954 }
11955 default:
11956 {
11957 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11958 attribute);
11959 break;
11960 }
11961 }
11962 }
11963 image=MontageImageList(info->image_info,montage_info,image,exception);
11964 montage_info=DestroyMontageInfo(montage_info);
11965 if (image == (Image *) NULL)
11966 goto PerlException;
11967 if (transparent_color.alpha != TransparentAlpha)
11968 for (next=image; next; next=next->next)
11969 (void) TransparentPaintImage(next,&transparent_color,
11970 TransparentAlpha,MagickFalse,exception);
11971 for ( ; image; image=image->next)
11972 {
11973 AddImageToRegistry(sv,image);
11974 rv=newRV(sv);
11975 av_push(av,sv_bless(rv,hv));
11976 SvREFCNT_dec(sv);
11977 }
11978 exception=DestroyExceptionInfo(exception);
11979 ST(0)=av_reference;
11980 SvREFCNT_dec(perl_exception);
11981 XSRETURN(1);
11982
11983 PerlException:
11984 InheritPerlException(exception,perl_exception);
11985 exception=DestroyExceptionInfo(exception);
11986 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11987 SvPOK_on(perl_exception);
11988 ST(0)=sv_2mortal(perl_exception);
11989 XSRETURN(1);
11990 }
11991
11992#
11993###############################################################################
11994# #
11995# #
11996# #
11997# M o r p h #
11998# #
11999# #
12000# #
12001###############################################################################
12002#
12003#
12004void
12005Morph(ref,...)
12006 Image::Magick ref=NO_INIT
12007 ALIAS:
12008 MorphImage = 1
12009 morph = 2
12010 morphimage = 3
12011 PPCODE:
12012 {
12013 AV
12014 *av;
12015
12016 char
12017 *attribute;
12018
12019 ExceptionInfo
12020 *exception;
12021
12022 HV
12023 *hv;
12024
12025 Image
12026 *image;
12027
12028 register ssize_t
12029 i;
12030
12031 ssize_t
12032 number_frames;
12033
12034 struct PackageInfo
12035 *info;
12036
12037 SV
12038 *av_reference,
12039 *perl_exception,
12040 *reference,
12041 *rv,
12042 *sv;
12043
12044 PERL_UNUSED_VAR(ref);
12045 PERL_UNUSED_VAR(ix);
12046 exception=AcquireExceptionInfo();
12047 perl_exception=newSVpv("",0);
12048 sv=NULL;
12049 av=NULL;
12050 attribute=NULL;
12051 if (sv_isobject(ST(0)) == 0)
12052 {
12053 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12054 PackageName);
12055 goto PerlException;
12056 }
12057 reference=SvRV(ST(0));
12058 hv=SvSTASH(reference);
12059 av=newAV();
12060 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12061 SvREFCNT_dec(av);
12062 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12063 if (image == (Image *) NULL)
12064 {
12065 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12066 PackageName);
12067 goto PerlException;
12068 }
12069 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12070 /*
12071 Get attribute.
12072 */
12073 number_frames=30;
12074 for (i=2; i < items; i+=2)
12075 {
12076 attribute=(char *) SvPV(ST(i-1),na);
12077 switch (*attribute)
12078 {
12079 case 'F':
12080 case 'f':
12081 {
12082 if (LocaleCompare(attribute,"frames") == 0)
12083 {
12084 number_frames=SvIV(ST(i));
12085 break;
12086 }
12087 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12088 attribute);
12089 break;
12090 }
12091 default:
12092 {
12093 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12094 attribute);
12095 break;
12096 }
12097 }
12098 }
12099 image=MorphImages(image,number_frames,exception);
12100 if (image == (Image *) NULL)
12101 goto PerlException;
12102 for ( ; image; image=image->next)
12103 {
12104 AddImageToRegistry(sv,image);
12105 rv=newRV(sv);
12106 av_push(av,sv_bless(rv,hv));
12107 SvREFCNT_dec(sv);
12108 }
12109 exception=DestroyExceptionInfo(exception);
12110 ST(0)=av_reference;
12111 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12112 XSRETURN(1);
12113
12114 PerlException:
12115 InheritPerlException(exception,perl_exception);
12116 exception=DestroyExceptionInfo(exception);
12117 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12118 SvPOK_on(perl_exception);
12119 ST(0)=sv_2mortal(perl_exception);
12120 XSRETURN(1);
12121 }
12122
12123#
12124###############################################################################
12125# #
12126# #
12127# #
12128# M o s a i c #
12129# #
12130# #
12131# #
12132###############################################################################
12133#
12134#
12135void
12136Mosaic(ref)
12137 Image::Magick ref=NO_INIT
12138 ALIAS:
12139 MosaicImage = 1
12140 mosaic = 2
12141 mosaicimage = 3
12142 PPCODE:
12143 {
12144 AV
12145 *av;
12146
12147 ExceptionInfo
12148 *exception;
12149
12150 HV
12151 *hv;
12152
12153 Image
12154 *image;
12155
12156 struct PackageInfo
12157 *info;
12158
12159 SV
12160 *perl_exception,
12161 *reference,
12162 *rv,
12163 *sv;
12164
12165 PERL_UNUSED_VAR(ref);
12166 PERL_UNUSED_VAR(ix);
12167 exception=AcquireExceptionInfo();
12168 perl_exception=newSVpv("",0);
12169 sv=NULL;
12170 if (sv_isobject(ST(0)) == 0)
12171 {
12172 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12173 PackageName);
12174 goto PerlException;
12175 }
12176 reference=SvRV(ST(0));
12177 hv=SvSTASH(reference);
12178 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12179 if (image == (Image *) NULL)
12180 {
12181 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12182 PackageName);
12183 goto PerlException;
12184 }
12185 image=MergeImageLayers(image,MosaicLayer,exception);
12186 /*
12187 Create blessed Perl array for the returned image.
12188 */
12189 av=newAV();
12190 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12191 SvREFCNT_dec(av);
12192 AddImageToRegistry(sv,image);
12193 rv=newRV(sv);
12194 av_push(av,sv_bless(rv,hv));
12195 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000012196 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000012197 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012198 SetImageInfo(info->image_info,0,exception);
12199 exception=DestroyExceptionInfo(exception);
12200 SvREFCNT_dec(perl_exception);
12201 XSRETURN(1);
12202
12203 PerlException:
12204 InheritPerlException(exception,perl_exception);
12205 exception=DestroyExceptionInfo(exception);
12206 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12207 SvPOK_on(perl_exception); /* return messages in string context */
12208 ST(0)=sv_2mortal(perl_exception);
12209 XSRETURN(1);
12210 }
12211
12212#
12213###############################################################################
12214# #
12215# #
12216# #
12217# P i n g #
12218# #
12219# #
12220# #
12221###############################################################################
12222#
12223#
12224void
12225Ping(ref,...)
12226 Image::Magick ref=NO_INIT
12227 ALIAS:
12228 PingImage = 1
12229 ping = 2
12230 pingimage = 3
12231 PPCODE:
12232 {
12233 AV
12234 *av;
12235
12236 char
12237 **keep,
12238 **list;
12239
12240 ExceptionInfo
12241 *exception;
12242
12243 Image
12244 *image,
12245 *next;
12246
12247 int
12248 n;
12249
12250 MagickBooleanType
12251 status;
12252
12253 register char
12254 **p;
12255
12256 register ssize_t
12257 i;
12258
12259 ssize_t
12260 ac;
12261
12262 STRLEN
12263 *length;
12264
12265 struct PackageInfo
12266 *info,
12267 *package_info;
12268
12269 SV
12270 *perl_exception,
12271 *reference;
12272
12273 size_t
12274 count;
12275
12276 PERL_UNUSED_VAR(ref);
12277 PERL_UNUSED_VAR(ix);
12278 exception=AcquireExceptionInfo();
12279 perl_exception=newSVpv("",0);
12280 package_info=(struct PackageInfo *) NULL;
12281 ac=(items < 2) ? 1 : items-1;
12282 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12283 keep=list;
12284 length=(STRLEN *) NULL;
12285 if (list == (char **) NULL)
12286 {
12287 ThrowPerlException(exception,ResourceLimitError,
12288 "MemoryAllocationFailed",PackageName);
12289 goto PerlException;
12290 }
12291 keep=list;
12292 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12293 if (length == (STRLEN *) NULL)
12294 {
12295 ThrowPerlException(exception,ResourceLimitError,
12296 "MemoryAllocationFailed",PackageName);
12297 goto PerlException;
12298 }
12299 if (sv_isobject(ST(0)) == 0)
12300 {
12301 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12302 PackageName);
12303 goto PerlException;
12304 }
12305 reference=SvRV(ST(0));
12306 if (SvTYPE(reference) != SVt_PVAV)
12307 {
12308 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12309 PackageName);
12310 goto PerlException;
12311 }
12312 av=(AV *) reference;
12313 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12314 exception);
12315 package_info=ClonePackageInfo(info,exception);
12316 n=1;
12317 if (items <= 1)
12318 *list=(char *) (*package_info->image_info->filename ?
12319 package_info->image_info->filename : "XC:black");
12320 else
12321 for (n=0, i=0; i < ac; i++)
12322 {
12323 list[n]=(char *) SvPV(ST(i+1),length[n]);
12324 if ((items >= 3) && strEQcase(list[n],"blob"))
12325 {
12326 void
12327 *blob;
12328
12329 i++;
12330 blob=(void *) (SvPV(ST(i+1),length[n]));
12331 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12332 }
12333 if ((items >= 3) && strEQcase(list[n],"filename"))
12334 continue;
12335 if ((items >= 3) && strEQcase(list[n],"file"))
12336 {
12337 FILE
12338 *file;
12339
12340 PerlIO
12341 *io_info;
12342
12343 i++;
12344 io_info=IoIFP(sv_2io(ST(i+1)));
12345 if (io_info == (PerlIO *) NULL)
12346 {
12347 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12348 PackageName);
12349 continue;
12350 }
12351 file=PerlIO_findFILE(io_info);
12352 if (file == (FILE *) NULL)
12353 {
12354 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12355 PackageName);
12356 continue;
12357 }
12358 SetImageInfoFile(package_info->image_info,file);
12359 }
12360 if ((items >= 3) && strEQcase(list[n],"magick"))
12361 continue;
12362 n++;
12363 }
12364 list[n]=(char *) NULL;
12365 keep=list;
12366 status=ExpandFilenames(&n,&list);
12367 if (status == MagickFalse)
12368 {
12369 ThrowPerlException(exception,ResourceLimitError,
12370 "MemoryAllocationFailed",PackageName);
12371 goto PerlException;
12372 }
12373 count=0;
12374 for (i=0; i < n; i++)
12375 {
12376 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012377 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012378 image=PingImage(package_info->image_info,exception);
12379 if (image == (Image *) NULL)
12380 break;
12381 if ((package_info->image_info->file != (FILE *) NULL) ||
12382 (package_info->image_info->blob != (void *) NULL))
12383 DisassociateImageStream(image);
12384 count+=GetImageListLength(image);
12385 EXTEND(sp,4*count);
12386 for (next=image; next; next=next->next)
12387 {
12388 PUSHs(sv_2mortal(newSViv(next->columns)));
12389 PUSHs(sv_2mortal(newSViv(next->rows)));
12390 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12391 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12392 }
12393 image=DestroyImageList(image);
12394 }
12395 /*
12396 Free resources.
12397 */
12398 for (i=0; i < n; i++)
12399 if (list[i] != (char *) NULL)
12400 for (p=keep; list[i] != *p++; )
12401 if (*p == NULL)
12402 {
12403 list[i]=(char *) RelinquishMagickMemory(list[i]);
12404 break;
12405 }
12406
12407 PerlException:
12408 if (package_info != (struct PackageInfo *) NULL)
12409 DestroyPackageInfo(package_info);
12410 if (list && (list != keep))
12411 list=(char **) RelinquishMagickMemory(list);
12412 if (keep)
12413 keep=(char **) RelinquishMagickMemory(keep);
12414 if (length)
12415 length=(STRLEN *) RelinquishMagickMemory(length);
12416 InheritPerlException(exception,perl_exception);
12417 exception=DestroyExceptionInfo(exception);
12418 SvREFCNT_dec(perl_exception); /* throw away all errors */
12419 }
12420
12421#
12422###############################################################################
12423# #
12424# #
12425# #
12426# P r e v i e w #
12427# #
12428# #
12429# #
12430###############################################################################
12431#
12432#
12433void
12434Preview(ref,...)
12435 Image::Magick ref=NO_INIT
12436 ALIAS:
12437 PreviewImage = 1
12438 preview = 2
12439 previewimage = 3
12440 PPCODE:
12441 {
12442 AV
12443 *av;
12444
12445 ExceptionInfo
12446 *exception;
12447
12448 HV
12449 *hv;
12450
12451 Image
12452 *image,
12453 *preview_image;
12454
12455 PreviewType
12456 preview_type;
12457
12458 struct PackageInfo
12459 *info;
12460
12461 SV
12462 *av_reference,
12463 *perl_exception,
12464 *reference,
12465 *rv,
12466 *sv;
12467
12468 PERL_UNUSED_VAR(ref);
12469 PERL_UNUSED_VAR(ix);
12470 exception=AcquireExceptionInfo();
12471 perl_exception=newSVpv("",0);
12472 sv=NULL;
12473 av=NULL;
12474 if (sv_isobject(ST(0)) == 0)
12475 {
12476 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12477 PackageName);
12478 goto PerlException;
12479 }
12480 reference=SvRV(ST(0));
12481 hv=SvSTASH(reference);
12482 av=newAV();
12483 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12484 SvREFCNT_dec(av);
12485 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12486 if (image == (Image *) NULL)
12487 {
12488 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12489 PackageName);
12490 goto PerlException;
12491 }
12492 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12493 preview_type=GammaPreview;
12494 if (items > 1)
12495 preview_type=(PreviewType)
12496 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12497 for ( ; image; image=image->next)
12498 {
12499 preview_image=PreviewImage(image,preview_type,exception);
12500 if (preview_image == (Image *) NULL)
12501 goto PerlException;
12502 AddImageToRegistry(sv,preview_image);
12503 rv=newRV(sv);
12504 av_push(av,sv_bless(rv,hv));
12505 SvREFCNT_dec(sv);
12506 }
12507 exception=DestroyExceptionInfo(exception);
12508 ST(0)=av_reference;
12509 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12510 XSRETURN(1);
12511
12512 PerlException:
12513 InheritPerlException(exception,perl_exception);
12514 exception=DestroyExceptionInfo(exception);
12515 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12516 SvPOK_on(perl_exception);
12517 ST(0)=sv_2mortal(perl_exception);
12518 XSRETURN(1);
12519 }
12520
12521#
12522###############################################################################
12523# #
12524# #
12525# #
12526# Q u e r y C o l o r #
12527# #
12528# #
12529# #
12530###############################################################################
12531#
12532#
12533void
12534QueryColor(ref,...)
12535 Image::Magick ref=NO_INIT
12536 ALIAS:
12537 querycolor = 1
12538 PPCODE:
12539 {
12540 char
12541 *name;
12542
12543 ExceptionInfo
12544 *exception;
12545
12546 PixelInfo
12547 color;
12548
12549 register ssize_t
12550 i;
12551
12552 SV
12553 *perl_exception;
12554
12555 PERL_UNUSED_VAR(ref);
12556 PERL_UNUSED_VAR(ix);
12557 exception=AcquireExceptionInfo();
12558 perl_exception=newSVpv("",0);
12559 if (items == 1)
12560 {
12561 const ColorInfo
12562 **colorlist;
12563
12564 size_t
12565 colors;
12566
12567 colorlist=GetColorInfoList("*",&colors,exception);
12568 EXTEND(sp,colors);
12569 for (i=0; i < (ssize_t) colors; i++)
12570 {
12571 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12572 }
12573 colorlist=(const ColorInfo **)
12574 RelinquishMagickMemory((ColorInfo **) colorlist);
12575 goto PerlException;
12576 }
12577 EXTEND(sp,5*items);
12578 for (i=1; i < items; i++)
12579 {
12580 name=(char *) SvPV(ST(i),na);
12581 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12582 {
12583 PUSHs(&sv_undef);
12584 continue;
12585 }
12586 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12587 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12588 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12589 if (color.colorspace == CMYKColorspace)
12590 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012591 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012592 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12593 }
12594
12595 PerlException:
12596 InheritPerlException(exception,perl_exception);
12597 exception=DestroyExceptionInfo(exception);
12598 SvREFCNT_dec(perl_exception);
12599 }
12600
12601#
12602###############################################################################
12603# #
12604# #
12605# #
12606# Q u e r y C o l o r N a m e #
12607# #
12608# #
12609# #
12610###############################################################################
12611#
12612#
12613void
12614QueryColorname(ref,...)
12615 Image::Magick ref=NO_INIT
12616 ALIAS:
12617 querycolorname = 1
12618 PPCODE:
12619 {
12620 AV
12621 *av;
12622
12623 char
cristy151b66d2015-04-15 10:50:31 +000012624 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012625
12626 ExceptionInfo
12627 *exception;
12628
12629 Image
12630 *image;
12631
12632 PixelInfo
12633 target_color;
12634
12635 register ssize_t
12636 i;
12637
12638 struct PackageInfo
12639 *info;
12640
12641 SV
12642 *perl_exception,
12643 *reference; /* reference is the SV* of ref=SvIV(reference) */
12644
12645 PERL_UNUSED_VAR(ref);
12646 PERL_UNUSED_VAR(ix);
12647 exception=AcquireExceptionInfo();
12648 perl_exception=newSVpv("",0);
12649 reference=SvRV(ST(0));
12650 av=(AV *) reference;
12651 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12652 exception);
12653 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12654 if (image == (Image *) NULL)
12655 {
12656 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12657 PackageName);
12658 goto PerlException;
12659 }
12660 EXTEND(sp,items);
12661 for (i=1; i < items; i++)
12662 {
12663 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12664 exception);
12665 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12666 exception);
12667 PUSHs(sv_2mortal(newSVpv(message,0)));
12668 }
12669
12670 PerlException:
12671 InheritPerlException(exception,perl_exception);
12672 exception=DestroyExceptionInfo(exception);
12673 SvREFCNT_dec(perl_exception);
12674 }
12675
12676#
12677###############################################################################
12678# #
12679# #
12680# #
12681# Q u e r y F o n t #
12682# #
12683# #
12684# #
12685###############################################################################
12686#
12687#
12688void
12689QueryFont(ref,...)
12690 Image::Magick ref=NO_INIT
12691 ALIAS:
12692 queryfont = 1
12693 PPCODE:
12694 {
12695 char
12696 *name,
cristy151b66d2015-04-15 10:50:31 +000012697 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012698
12699 ExceptionInfo
12700 *exception;
12701
12702 register ssize_t
12703 i;
12704
12705 SV
12706 *perl_exception;
12707
12708 volatile const TypeInfo
12709 *type_info;
12710
12711 PERL_UNUSED_VAR(ref);
12712 PERL_UNUSED_VAR(ix);
12713 exception=AcquireExceptionInfo();
12714 perl_exception=newSVpv("",0);
12715 if (items == 1)
12716 {
12717 const TypeInfo
12718 **typelist;
12719
12720 size_t
12721 types;
12722
12723 typelist=GetTypeInfoList("*",&types,exception);
12724 EXTEND(sp,types);
12725 for (i=0; i < (ssize_t) types; i++)
12726 {
12727 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12728 }
12729 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12730 typelist);
12731 goto PerlException;
12732 }
12733 EXTEND(sp,10*items);
12734 for (i=1; i < items; i++)
12735 {
12736 name=(char *) SvPV(ST(i),na);
12737 type_info=GetTypeInfo(name,exception);
12738 if (type_info == (TypeInfo *) NULL)
12739 {
12740 PUSHs(&sv_undef);
12741 continue;
12742 }
12743 if (type_info->name == (char *) NULL)
12744 PUSHs(&sv_undef);
12745 else
12746 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12747 if (type_info->description == (char *) NULL)
12748 PUSHs(&sv_undef);
12749 else
12750 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12751 if (type_info->family == (char *) NULL)
12752 PUSHs(&sv_undef);
12753 else
12754 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12755 if (type_info->style == UndefinedStyle)
12756 PUSHs(&sv_undef);
12757 else
12758 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12759 type_info->style),0)));
12760 if (type_info->stretch == UndefinedStretch)
12761 PUSHs(&sv_undef);
12762 else
12763 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12764 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012765 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012766 type_info->weight);
12767 PUSHs(sv_2mortal(newSVpv(message,0)));
12768 if (type_info->encoding == (char *) NULL)
12769 PUSHs(&sv_undef);
12770 else
12771 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12772 if (type_info->foundry == (char *) NULL)
12773 PUSHs(&sv_undef);
12774 else
12775 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12776 if (type_info->format == (char *) NULL)
12777 PUSHs(&sv_undef);
12778 else
12779 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12780 if (type_info->metrics == (char *) NULL)
12781 PUSHs(&sv_undef);
12782 else
12783 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12784 if (type_info->glyphs == (char *) NULL)
12785 PUSHs(&sv_undef);
12786 else
12787 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12788 }
12789
12790 PerlException:
12791 InheritPerlException(exception,perl_exception);
12792 exception=DestroyExceptionInfo(exception);
12793 SvREFCNT_dec(perl_exception);
12794 }
12795
12796#
12797###############################################################################
12798# #
12799# #
12800# #
12801# Q u e r y F o n t M e t r i c s #
12802# #
12803# #
12804# #
12805###############################################################################
12806#
12807#
12808void
12809QueryFontMetrics(ref,...)
12810 Image::Magick ref=NO_INIT
12811 ALIAS:
12812 queryfontmetrics = 1
12813 PPCODE:
12814 {
12815 AffineMatrix
12816 affine,
12817 current;
12818
12819 AV
12820 *av;
12821
12822 char
12823 *attribute;
12824
12825 double
12826 x,
12827 y;
12828
12829 DrawInfo
12830 *draw_info;
12831
12832 ExceptionInfo
12833 *exception;
12834
12835 GeometryInfo
12836 geometry_info;
12837
12838 Image
12839 *image;
12840
12841 MagickBooleanType
12842 status;
12843
12844 MagickStatusType
12845 flags;
12846
12847 register ssize_t
12848 i;
12849
12850 ssize_t
12851 type;
12852
12853 struct PackageInfo
12854 *info,
12855 *package_info;
12856
12857 SV
12858 *perl_exception,
12859 *reference; /* reference is the SV* of ref=SvIV(reference) */
12860
12861 TypeMetric
12862 metrics;
12863
12864 PERL_UNUSED_VAR(ref);
12865 PERL_UNUSED_VAR(ix);
12866 exception=AcquireExceptionInfo();
12867 package_info=(struct PackageInfo *) NULL;
12868 perl_exception=newSVpv("",0);
12869 reference=SvRV(ST(0));
12870 av=(AV *) reference;
12871 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12872 exception);
12873 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12874 if (image == (Image *) NULL)
12875 {
12876 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12877 PackageName);
12878 goto PerlException;
12879 }
12880 package_info=ClonePackageInfo(info,exception);
12881 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12882 CloneString(&draw_info->text,"");
12883 current=draw_info->affine;
12884 GetAffineMatrix(&affine);
12885 x=0.0;
12886 y=0.0;
12887 EXTEND(sp,7*items);
12888 for (i=2; i < items; i+=2)
12889 {
12890 attribute=(char *) SvPV(ST(i-1),na);
12891 switch (*attribute)
12892 {
12893 case 'A':
12894 case 'a':
12895 {
12896 if (LocaleCompare(attribute,"antialias") == 0)
12897 {
12898 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12899 SvPV(ST(i),na));
12900 if (type < 0)
12901 {
12902 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12903 SvPV(ST(i),na));
12904 break;
12905 }
12906 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12907 break;
12908 }
12909 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12910 attribute);
12911 break;
12912 }
12913 case 'd':
12914 case 'D':
12915 {
12916 if (LocaleCompare(attribute,"density") == 0)
12917 {
12918 CloneString(&draw_info->density,SvPV(ST(i),na));
12919 break;
12920 }
12921 if (LocaleCompare(attribute,"direction") == 0)
12922 {
12923 draw_info->direction=(DirectionType) ParseCommandOption(
12924 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12925 break;
12926 }
12927 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12928 attribute);
12929 break;
12930 }
12931 case 'e':
12932 case 'E':
12933 {
12934 if (LocaleCompare(attribute,"encoding") == 0)
12935 {
12936 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12937 break;
12938 }
12939 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12940 attribute);
12941 break;
12942 }
12943 case 'f':
12944 case 'F':
12945 {
12946 if (LocaleCompare(attribute,"family") == 0)
12947 {
12948 CloneString(&draw_info->family,SvPV(ST(i),na));
12949 break;
12950 }
12951 if (LocaleCompare(attribute,"fill") == 0)
12952 {
12953 if (info)
12954 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12955 &draw_info->fill,exception);
12956 break;
12957 }
12958 if (LocaleCompare(attribute,"font") == 0)
12959 {
12960 CloneString(&draw_info->font,SvPV(ST(i),na));
12961 break;
12962 }
12963 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12964 attribute);
12965 break;
12966 }
12967 case 'g':
12968 case 'G':
12969 {
12970 if (LocaleCompare(attribute,"geometry") == 0)
12971 {
12972 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12973 break;
12974 }
12975 if (LocaleCompare(attribute,"gravity") == 0)
12976 {
12977 draw_info->gravity=(GravityType) ParseCommandOption(
12978 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12979 break;
12980 }
12981 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12982 attribute);
12983 break;
12984 }
12985 case 'i':
12986 case 'I':
12987 {
12988 if (LocaleCompare(attribute,"interline-spacing") == 0)
12989 {
12990 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12991 draw_info->interline_spacing=geometry_info.rho;
12992 break;
12993 }
12994 if (LocaleCompare(attribute,"interword-spacing") == 0)
12995 {
12996 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12997 draw_info->interword_spacing=geometry_info.rho;
12998 break;
12999 }
13000 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13001 attribute);
13002 break;
13003 }
13004 case 'k':
13005 case 'K':
13006 {
13007 if (LocaleCompare(attribute,"kerning") == 0)
13008 {
13009 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13010 draw_info->kerning=geometry_info.rho;
13011 break;
13012 }
13013 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13014 attribute);
13015 break;
13016 }
13017 case 'p':
13018 case 'P':
13019 {
13020 if (LocaleCompare(attribute,"pointsize") == 0)
13021 {
13022 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13023 draw_info->pointsize=geometry_info.rho;
13024 break;
13025 }
13026 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13027 attribute);
13028 break;
13029 }
13030 case 'r':
13031 case 'R':
13032 {
13033 if (LocaleCompare(attribute,"rotate") == 0)
13034 {
13035 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13036 affine.rx=geometry_info.rho;
13037 affine.ry=geometry_info.sigma;
13038 if ((flags & SigmaValue) == 0)
13039 affine.ry=affine.rx;
13040 break;
13041 }
13042 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13043 attribute);
13044 break;
13045 }
13046 case 's':
13047 case 'S':
13048 {
13049 if (LocaleCompare(attribute,"scale") == 0)
13050 {
13051 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13052 affine.sx=geometry_info.rho;
13053 affine.sy=geometry_info.sigma;
13054 if ((flags & SigmaValue) == 0)
13055 affine.sy=affine.sx;
13056 break;
13057 }
13058 if (LocaleCompare(attribute,"skew") == 0)
13059 {
13060 double
13061 x_angle,
13062 y_angle;
13063
13064 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13065 x_angle=geometry_info.rho;
13066 y_angle=geometry_info.sigma;
13067 if ((flags & SigmaValue) == 0)
13068 y_angle=x_angle;
13069 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13070 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13071 break;
13072 }
13073 if (LocaleCompare(attribute,"stroke") == 0)
13074 {
13075 if (info)
13076 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13077 &draw_info->stroke,exception);
13078 break;
13079 }
13080 if (LocaleCompare(attribute,"style") == 0)
13081 {
13082 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13083 SvPV(ST(i),na));
13084 if (type < 0)
13085 {
13086 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13087 SvPV(ST(i),na));
13088 break;
13089 }
13090 draw_info->style=(StyleType) type;
13091 break;
13092 }
13093 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13094 attribute);
13095 break;
13096 }
13097 case 't':
13098 case 'T':
13099 {
13100 if (LocaleCompare(attribute,"text") == 0)
13101 {
13102 CloneString(&draw_info->text,SvPV(ST(i),na));
13103 break;
13104 }
13105 if (LocaleCompare(attribute,"translate") == 0)
13106 {
13107 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13108 affine.tx=geometry_info.rho;
13109 affine.ty=geometry_info.sigma;
13110 if ((flags & SigmaValue) == 0)
13111 affine.ty=affine.tx;
13112 break;
13113 }
13114 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13115 attribute);
13116 break;
13117 }
13118 case 'w':
13119 case 'W':
13120 {
13121 if (LocaleCompare(attribute,"weight") == 0)
13122 {
13123 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13124 draw_info->weight=(size_t) geometry_info.rho;
13125 break;
13126 }
13127 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13128 attribute);
13129 break;
13130 }
13131 case 'x':
13132 case 'X':
13133 {
13134 if (LocaleCompare(attribute,"x") == 0)
13135 {
13136 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13137 x=geometry_info.rho;
13138 break;
13139 }
13140 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13141 attribute);
13142 break;
13143 }
13144 case 'y':
13145 case 'Y':
13146 {
13147 if (LocaleCompare(attribute,"y") == 0)
13148 {
13149 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13150 y=geometry_info.rho;
13151 break;
13152 }
13153 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13154 attribute);
13155 break;
13156 }
13157 default:
13158 {
13159 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13160 attribute);
13161 break;
13162 }
13163 }
13164 }
13165 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13166 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13167 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13168 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13169 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13170 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13171 if (draw_info->geometry == (char *) NULL)
13172 {
13173 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013174 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013175 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013176 }
13177 status=GetTypeMetrics(image,draw_info,&metrics,exception);
13178 (void) CatchImageException(image);
13179 if (status == MagickFalse)
13180 PUSHs(&sv_undef);
13181 else
13182 {
13183 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13184 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13185 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13186 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13187 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13188 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13189 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13190 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13191 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13192 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13193 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13194 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13195 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13196 }
13197 draw_info=DestroyDrawInfo(draw_info);
13198
13199 PerlException:
13200 if (package_info != (struct PackageInfo *) NULL)
13201 DestroyPackageInfo(package_info);
13202 InheritPerlException(exception,perl_exception);
13203 exception=DestroyExceptionInfo(exception);
13204 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13205 }
13206
13207#
13208###############################################################################
13209# #
13210# #
13211# #
13212# 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 #
13213# #
13214# #
13215# #
13216###############################################################################
13217#
13218#
13219void
13220QueryMultilineFontMetrics(ref,...)
13221 Image::Magick ref=NO_INIT
13222 ALIAS:
13223 querymultilinefontmetrics = 1
13224 PPCODE:
13225 {
13226 AffineMatrix
13227 affine,
13228 current;
13229
13230 AV
13231 *av;
13232
13233 char
13234 *attribute;
13235
13236 double
13237 x,
13238 y;
13239
13240 DrawInfo
13241 *draw_info;
13242
13243 ExceptionInfo
13244 *exception;
13245
13246 GeometryInfo
13247 geometry_info;
13248
13249 Image
13250 *image;
13251
13252 MagickBooleanType
13253 status;
13254
13255 MagickStatusType
13256 flags;
13257
13258 register ssize_t
13259 i;
13260
13261 ssize_t
13262 type;
13263
13264 struct PackageInfo
13265 *info,
13266 *package_info;
13267
13268 SV
13269 *perl_exception,
13270 *reference; /* reference is the SV* of ref=SvIV(reference) */
13271
13272 TypeMetric
13273 metrics;
13274
13275 PERL_UNUSED_VAR(ref);
13276 PERL_UNUSED_VAR(ix);
13277 exception=AcquireExceptionInfo();
13278 package_info=(struct PackageInfo *) NULL;
13279 perl_exception=newSVpv("",0);
13280 reference=SvRV(ST(0));
13281 av=(AV *) reference;
13282 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13283 exception);
13284 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13285 if (image == (Image *) NULL)
13286 {
13287 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13288 PackageName);
13289 goto PerlException;
13290 }
13291 package_info=ClonePackageInfo(info,exception);
13292 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13293 CloneString(&draw_info->text,"");
13294 current=draw_info->affine;
13295 GetAffineMatrix(&affine);
13296 x=0.0;
13297 y=0.0;
13298 EXTEND(sp,7*items);
13299 for (i=2; i < items; i+=2)
13300 {
13301 attribute=(char *) SvPV(ST(i-1),na);
13302 switch (*attribute)
13303 {
13304 case 'A':
13305 case 'a':
13306 {
13307 if (LocaleCompare(attribute,"antialias") == 0)
13308 {
13309 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13310 SvPV(ST(i),na));
13311 if (type < 0)
13312 {
13313 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13314 SvPV(ST(i),na));
13315 break;
13316 }
13317 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13318 break;
13319 }
13320 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13321 attribute);
13322 break;
13323 }
13324 case 'd':
13325 case 'D':
13326 {
13327 if (LocaleCompare(attribute,"density") == 0)
13328 {
13329 CloneString(&draw_info->density,SvPV(ST(i),na));
13330 break;
13331 }
13332 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13333 attribute);
13334 break;
13335 }
13336 case 'e':
13337 case 'E':
13338 {
13339 if (LocaleCompare(attribute,"encoding") == 0)
13340 {
13341 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13342 break;
13343 }
13344 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13345 attribute);
13346 break;
13347 }
13348 case 'f':
13349 case 'F':
13350 {
13351 if (LocaleCompare(attribute,"family") == 0)
13352 {
13353 CloneString(&draw_info->family,SvPV(ST(i),na));
13354 break;
13355 }
13356 if (LocaleCompare(attribute,"fill") == 0)
13357 {
13358 if (info)
13359 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13360 &draw_info->fill,exception);
13361 break;
13362 }
13363 if (LocaleCompare(attribute,"font") == 0)
13364 {
13365 CloneString(&draw_info->font,SvPV(ST(i),na));
13366 break;
13367 }
13368 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13369 attribute);
13370 break;
13371 }
13372 case 'g':
13373 case 'G':
13374 {
13375 if (LocaleCompare(attribute,"geometry") == 0)
13376 {
13377 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13378 break;
13379 }
13380 if (LocaleCompare(attribute,"gravity") == 0)
13381 {
13382 draw_info->gravity=(GravityType) ParseCommandOption(
13383 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13384 break;
13385 }
13386 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13387 attribute);
13388 break;
13389 }
13390 case 'p':
13391 case 'P':
13392 {
13393 if (LocaleCompare(attribute,"pointsize") == 0)
13394 {
13395 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13396 draw_info->pointsize=geometry_info.rho;
13397 break;
13398 }
13399 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13400 attribute);
13401 break;
13402 }
13403 case 'r':
13404 case 'R':
13405 {
13406 if (LocaleCompare(attribute,"rotate") == 0)
13407 {
13408 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13409 affine.rx=geometry_info.rho;
13410 affine.ry=geometry_info.sigma;
13411 if ((flags & SigmaValue) == 0)
13412 affine.ry=affine.rx;
13413 break;
13414 }
13415 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13416 attribute);
13417 break;
13418 }
13419 case 's':
13420 case 'S':
13421 {
13422 if (LocaleCompare(attribute,"scale") == 0)
13423 {
13424 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13425 affine.sx=geometry_info.rho;
13426 affine.sy=geometry_info.sigma;
13427 if ((flags & SigmaValue) == 0)
13428 affine.sy=affine.sx;
13429 break;
13430 }
13431 if (LocaleCompare(attribute,"skew") == 0)
13432 {
13433 double
13434 x_angle,
13435 y_angle;
13436
13437 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13438 x_angle=geometry_info.rho;
13439 y_angle=geometry_info.sigma;
13440 if ((flags & SigmaValue) == 0)
13441 y_angle=x_angle;
13442 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13443 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13444 break;
13445 }
13446 if (LocaleCompare(attribute,"stroke") == 0)
13447 {
13448 if (info)
13449 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13450 &draw_info->stroke,exception);
13451 break;
13452 }
13453 if (LocaleCompare(attribute,"style") == 0)
13454 {
13455 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13456 SvPV(ST(i),na));
13457 if (type < 0)
13458 {
13459 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13460 SvPV(ST(i),na));
13461 break;
13462 }
13463 draw_info->style=(StyleType) type;
13464 break;
13465 }
13466 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13467 attribute);
13468 break;
13469 }
13470 case 't':
13471 case 'T':
13472 {
13473 if (LocaleCompare(attribute,"text") == 0)
13474 {
13475 CloneString(&draw_info->text,SvPV(ST(i),na));
13476 break;
13477 }
13478 if (LocaleCompare(attribute,"translate") == 0)
13479 {
13480 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13481 affine.tx=geometry_info.rho;
13482 affine.ty=geometry_info.sigma;
13483 if ((flags & SigmaValue) == 0)
13484 affine.ty=affine.tx;
13485 break;
13486 }
13487 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13488 attribute);
13489 break;
13490 }
13491 case 'w':
13492 case 'W':
13493 {
13494 if (LocaleCompare(attribute,"weight") == 0)
13495 {
13496 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13497 draw_info->weight=(size_t) geometry_info.rho;
13498 break;
13499 }
13500 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13501 attribute);
13502 break;
13503 }
13504 case 'x':
13505 case 'X':
13506 {
13507 if (LocaleCompare(attribute,"x") == 0)
13508 {
13509 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13510 x=geometry_info.rho;
13511 break;
13512 }
13513 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13514 attribute);
13515 break;
13516 }
13517 case 'y':
13518 case 'Y':
13519 {
13520 if (LocaleCompare(attribute,"y") == 0)
13521 {
13522 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13523 y=geometry_info.rho;
13524 break;
13525 }
13526 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13527 attribute);
13528 break;
13529 }
13530 default:
13531 {
13532 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13533 attribute);
13534 break;
13535 }
13536 }
13537 }
13538 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13539 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13540 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13541 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13542 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13543 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13544 if (draw_info->geometry == (char *) NULL)
13545 {
13546 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013547 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013548 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013549 }
13550 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13551 (void) CatchException(exception);
13552 if (status == MagickFalse)
13553 PUSHs(&sv_undef);
13554 else
13555 {
13556 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13557 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13558 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13559 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13560 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13561 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13562 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13563 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13564 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13565 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13566 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13567 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13568 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13569 }
13570 draw_info=DestroyDrawInfo(draw_info);
13571
13572 PerlException:
13573 if (package_info != (struct PackageInfo *) NULL)
13574 DestroyPackageInfo(package_info);
13575 InheritPerlException(exception,perl_exception);
13576 exception=DestroyExceptionInfo(exception);
13577 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13578 }
13579
13580#
13581###############################################################################
13582# #
13583# #
13584# #
13585# Q u e r y F o r m a t #
13586# #
13587# #
13588# #
13589###############################################################################
13590#
13591#
13592void
13593QueryFormat(ref,...)
13594 Image::Magick ref=NO_INIT
13595 ALIAS:
13596 queryformat = 1
13597 PPCODE:
13598 {
13599 char
13600 *name;
13601
13602 ExceptionInfo
13603 *exception;
13604
13605 register ssize_t
13606 i;
13607
13608 SV
13609 *perl_exception;
13610
13611 volatile const MagickInfo
13612 *magick_info;
13613
13614 PERL_UNUSED_VAR(ref);
13615 PERL_UNUSED_VAR(ix);
13616 exception=AcquireExceptionInfo();
13617 perl_exception=newSVpv("",0);
13618 if (items == 1)
13619 {
13620 char
cristy151b66d2015-04-15 10:50:31 +000013621 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013622
13623 const MagickInfo
13624 **format_list;
13625
13626 size_t
13627 types;
13628
13629 format_list=GetMagickInfoList("*",&types,exception);
13630 EXTEND(sp,types);
13631 for (i=0; i < (ssize_t) types; i++)
13632 {
cristy151b66d2015-04-15 10:50:31 +000013633 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013634 LocaleLower(format);
13635 PUSHs(sv_2mortal(newSVpv(format,0)));
13636 }
13637 format_list=(const MagickInfo **)
13638 RelinquishMagickMemory((MagickInfo *) format_list);
13639 goto PerlException;
13640 }
13641 EXTEND(sp,8*items);
13642 for (i=1; i < items; i++)
13643 {
13644 name=(char *) SvPV(ST(i),na);
13645 magick_info=GetMagickInfo(name,exception);
13646 if (magick_info == (const MagickInfo *) NULL)
13647 {
13648 PUSHs(&sv_undef);
13649 continue;
13650 }
cristy4a3ce0a2013-08-03 20:06:59 +000013651 if (magick_info->description == (char *) NULL)
13652 PUSHs(&sv_undef);
13653 else
13654 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
Cristy31756212019-07-31 15:55:08 -040013655 if (magick_info->magick_module == (char *) NULL)
cristy4a3ce0a2013-08-03 20:06:59 +000013656 PUSHs(&sv_undef);
13657 else
Cristy31756212019-07-31 15:55:08 -040013658 PUSHs(sv_2mortal(newSVpv(magick_info->magick_module,0)));
cristy4a3ce0a2013-08-03 20:06:59 +000013659 }
13660
13661 PerlException:
13662 InheritPerlException(exception,perl_exception);
13663 exception=DestroyExceptionInfo(exception);
13664 SvREFCNT_dec(perl_exception);
13665 }
13666
13667#
13668###############################################################################
13669# #
13670# #
13671# #
13672# Q u e r y O p t i o n #
13673# #
13674# #
13675# #
13676###############################################################################
13677#
13678#
13679void
13680QueryOption(ref,...)
13681 Image::Magick ref=NO_INIT
13682 ALIAS:
13683 queryoption = 1
13684 PPCODE:
13685 {
13686 char
13687 **options;
13688
13689 ExceptionInfo
13690 *exception;
13691
13692 register ssize_t
13693 i;
13694
13695 ssize_t
13696 j,
13697 option;
13698
13699 SV
13700 *perl_exception;
13701
13702 PERL_UNUSED_VAR(ref);
13703 PERL_UNUSED_VAR(ix);
13704 exception=AcquireExceptionInfo();
13705 perl_exception=newSVpv("",0);
13706 EXTEND(sp,8*items);
13707 for (i=1; i < items; i++)
13708 {
13709 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13710 SvPV(ST(i),na));
13711 options=GetCommandOptions((CommandOption) option);
13712 if (options == (char **) NULL)
13713 PUSHs(&sv_undef);
13714 else
13715 {
13716 for (j=0; options[j] != (char *) NULL; j++)
13717 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13718 options=DestroyStringList(options);
13719 }
13720 }
13721
13722 InheritPerlException(exception,perl_exception);
13723 exception=DestroyExceptionInfo(exception);
13724 SvREFCNT_dec(perl_exception);
13725 }
13726
13727#
13728###############################################################################
13729# #
13730# #
13731# #
13732# R e a d #
13733# #
13734# #
13735# #
13736###############################################################################
13737#
13738#
13739void
13740Read(ref,...)
13741 Image::Magick ref=NO_INIT
13742 ALIAS:
13743 ReadImage = 1
13744 read = 2
13745 readimage = 3
13746 PPCODE:
13747 {
13748 AV
13749 *av;
13750
13751 char
13752 **keep,
13753 **list;
13754
13755 ExceptionInfo
13756 *exception;
13757
13758 HV
13759 *hv;
13760
13761 Image
13762 *image;
13763
13764 int
13765 n;
13766
13767 MagickBooleanType
13768 status;
13769
13770 register char
13771 **p;
13772
13773 register ssize_t
13774 i;
13775
13776 ssize_t
13777 ac,
13778 number_images;
13779
13780 STRLEN
13781 *length;
13782
13783 struct PackageInfo
13784 *info,
13785 *package_info;
13786
13787 SV
13788 *perl_exception, /* Perl variable for storing messages */
13789 *reference,
13790 *rv,
13791 *sv;
13792
13793 PERL_UNUSED_VAR(ref);
13794 PERL_UNUSED_VAR(ix);
13795 exception=AcquireExceptionInfo();
13796 perl_exception=newSVpv("",0);
13797 sv=NULL;
13798 package_info=(struct PackageInfo *) NULL;
13799 number_images=0;
13800 ac=(items < 2) ? 1 : items-1;
13801 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13802 keep=list;
13803 length=(STRLEN *) NULL;
13804 if (list == (char **) NULL)
13805 {
13806 ThrowPerlException(exception,ResourceLimitError,
13807 "MemoryAllocationFailed",PackageName);
13808 goto PerlException;
13809 }
13810 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13811 if (length == (STRLEN *) NULL)
13812 {
13813 ThrowPerlException(exception,ResourceLimitError,
13814 "MemoryAllocationFailed",PackageName);
13815 goto PerlException;
13816 }
13817 if (sv_isobject(ST(0)) == 0)
13818 {
13819 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13820 PackageName);
13821 goto PerlException;
13822 }
13823 reference=SvRV(ST(0));
13824 hv=SvSTASH(reference);
13825 if (SvTYPE(reference) != SVt_PVAV)
13826 {
13827 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13828 PackageName);
13829 goto PerlException;
13830 }
13831 av=(AV *) reference;
13832 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13833 exception);
13834 package_info=ClonePackageInfo(info,exception);
13835 n=1;
13836 if (items <= 1)
13837 *list=(char *) (*package_info->image_info->filename ?
13838 package_info->image_info->filename : "XC:black");
13839 else
13840 for (n=0, i=0; i < ac; i++)
13841 {
13842 list[n]=(char *) SvPV(ST(i+1),length[n]);
13843 if ((items >= 3) && strEQcase(list[n],"blob"))
13844 {
13845 void
13846 *blob;
13847
13848 i++;
13849 blob=(void *) (SvPV(ST(i+1),length[n]));
13850 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13851 }
13852 if ((items >= 3) && strEQcase(list[n],"filename"))
13853 continue;
13854 if ((items >= 3) && strEQcase(list[n],"file"))
13855 {
13856 FILE
13857 *file;
13858
13859 PerlIO
13860 *io_info;
13861
13862 i++;
13863 io_info=IoIFP(sv_2io(ST(i+1)));
13864 if (io_info == (PerlIO *) NULL)
13865 {
13866 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13867 PackageName);
13868 continue;
13869 }
13870 file=PerlIO_findFILE(io_info);
13871 if (file == (FILE *) NULL)
13872 {
13873 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13874 PackageName);
13875 continue;
13876 }
13877 SetImageInfoFile(package_info->image_info,file);
13878 }
13879 if ((items >= 3) && strEQcase(list[n],"magick"))
13880 continue;
13881 n++;
13882 }
13883 list[n]=(char *) NULL;
13884 keep=list;
13885 status=ExpandFilenames(&n,&list);
13886 if (status == MagickFalse)
13887 {
13888 ThrowPerlException(exception,ResourceLimitError,
13889 "MemoryAllocationFailed",PackageName);
13890 goto PerlException;
13891 }
13892 number_images=0;
13893 for (i=0; i < n; i++)
13894 {
13895 if ((package_info->image_info->file == (FILE *) NULL) &&
13896 (package_info->image_info->blob == (void *) NULL))
13897 image=ReadImages(package_info->image_info,list[i],exception);
13898 else
13899 {
13900 image=ReadImages(package_info->image_info,
13901 package_info->image_info->filename,exception);
13902 if (image != (Image *) NULL)
13903 DisassociateImageStream(image);
13904 }
13905 if (image == (Image *) NULL)
13906 break;
13907 for ( ; image; image=image->next)
13908 {
13909 AddImageToRegistry(sv,image);
13910 rv=newRV(sv);
13911 av_push(av,sv_bless(rv,hv));
13912 SvREFCNT_dec(sv);
13913 number_images++;
13914 }
13915 }
13916 /*
13917 Free resources.
13918 */
13919 for (i=0; i < n; i++)
13920 if (list[i] != (char *) NULL)
13921 for (p=keep; list[i] != *p++; )
13922 if (*p == (char *) NULL)
13923 {
13924 list[i]=(char *) RelinquishMagickMemory(list[i]);
13925 break;
13926 }
13927
13928 PerlException:
13929 if (package_info != (struct PackageInfo *) NULL)
13930 DestroyPackageInfo(package_info);
13931 if (list && (list != keep))
13932 list=(char **) RelinquishMagickMemory(list);
13933 if (keep)
13934 keep=(char **) RelinquishMagickMemory(keep);
13935 if (length)
13936 length=(STRLEN *) RelinquishMagickMemory(length);
13937 InheritPerlException(exception,perl_exception);
13938 exception=DestroyExceptionInfo(exception);
13939 sv_setiv(perl_exception,(IV) number_images);
13940 SvPOK_on(perl_exception);
13941 ST(0)=sv_2mortal(perl_exception);
13942 XSRETURN(1);
13943 }
13944
13945#
13946###############################################################################
13947# #
13948# #
13949# #
13950# R e m o t e #
13951# #
13952# #
13953# #
13954###############################################################################
13955#
13956#
13957void
13958Remote(ref,...)
13959 Image::Magick ref=NO_INIT
13960 ALIAS:
13961 RemoteCommand = 1
13962 remote = 2
13963 remoteCommand = 3
13964 PPCODE:
13965 {
13966 AV
13967 *av;
13968
13969 ExceptionInfo
13970 *exception;
13971
13972 register ssize_t
13973 i;
13974
13975 SV
13976 *perl_exception,
13977 *reference;
13978
13979 struct PackageInfo
13980 *info;
13981
13982 PERL_UNUSED_VAR(ref);
13983 PERL_UNUSED_VAR(ix);
13984 exception=AcquireExceptionInfo();
13985 perl_exception=newSVpv("",0);
13986 reference=SvRV(ST(0));
13987 av=(AV *) reference;
13988 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13989 exception);
13990 for (i=1; i < items; i++)
13991 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13992 SvPV(ST(i),na),exception);
13993 InheritPerlException(exception,perl_exception);
13994 exception=DestroyExceptionInfo(exception);
13995 SvREFCNT_dec(perl_exception); /* throw away all errors */
13996 }
13997
13998#
13999###############################################################################
14000# #
14001# #
14002# #
14003# S e t #
14004# #
14005# #
14006# #
14007###############################################################################
14008#
14009#
14010void
14011Set(ref,...)
14012 Image::Magick ref=NO_INIT
14013 ALIAS:
14014 SetAttributes = 1
14015 SetAttribute = 2
14016 set = 3
14017 setattributes = 4
14018 setattribute = 5
14019 PPCODE:
14020 {
14021 ExceptionInfo
14022 *exception;
14023
14024 Image
14025 *image;
14026
14027 register ssize_t
14028 i;
14029
14030 struct PackageInfo
14031 *info;
14032
14033 SV
14034 *perl_exception,
14035 *reference; /* reference is the SV* of ref=SvIV(reference) */
14036
14037 PERL_UNUSED_VAR(ref);
14038 PERL_UNUSED_VAR(ix);
14039 exception=AcquireExceptionInfo();
14040 perl_exception=newSVpv("",0);
14041 if (sv_isobject(ST(0)) == 0)
14042 {
14043 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14044 PackageName);
14045 goto PerlException;
14046 }
14047 reference=SvRV(ST(0));
14048 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14049 if (items == 2)
14050 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
14051 else
14052 for (i=2; i < items; i+=2)
14053 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
14054
14055 PerlException:
14056 InheritPerlException(exception,perl_exception);
14057 exception=DestroyExceptionInfo(exception);
14058 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
14059 SvPOK_on(perl_exception);
14060 ST(0)=sv_2mortal(perl_exception);
14061 XSRETURN(1);
14062 }
14063
14064#
14065###############################################################################
14066# #
14067# #
14068# #
14069# S e t P i x e l #
14070# #
14071# #
14072# #
14073###############################################################################
14074#
14075#
14076void
14077SetPixel(ref,...)
14078 Image::Magick ref=NO_INIT
14079 ALIAS:
14080 setpixel = 1
14081 setPixel = 2
14082 PPCODE:
14083 {
14084 AV
14085 *av;
14086
14087 char
14088 *attribute;
14089
14090 ChannelType
14091 channel,
14092 channel_mask;
14093
14094 ExceptionInfo
14095 *exception;
14096
14097 Image
14098 *image;
14099
14100 MagickBooleanType
14101 normalize;
14102
14103 RectangleInfo
14104 region;
14105
14106 register ssize_t
14107 i;
14108
14109 register Quantum
14110 *q;
14111
14112 ssize_t
14113 option;
14114
14115 struct PackageInfo
14116 *info;
14117
14118 SV
14119 *perl_exception,
14120 *reference; /* reference is the SV* of ref=SvIV(reference) */
14121
14122 PERL_UNUSED_VAR(ref);
14123 PERL_UNUSED_VAR(ix);
14124 exception=AcquireExceptionInfo();
14125 perl_exception=newSVpv("",0);
14126 reference=SvRV(ST(0));
14127 av=(AV *) reference;
14128 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14129 exception);
14130 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14131 if (image == (Image *) NULL)
14132 {
14133 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14134 PackageName);
14135 goto PerlException;
14136 }
14137 av=(AV *) NULL;
14138 normalize=MagickTrue;
14139 region.x=0;
14140 region.y=0;
14141 region.width=image->columns;
14142 region.height=1;
14143 if (items == 1)
14144 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
14145 channel=DefaultChannels;
14146 for (i=2; i < items; i+=2)
14147 {
14148 attribute=(char *) SvPV(ST(i-1),na);
14149 switch (*attribute)
14150 {
14151 case 'C':
14152 case 'c':
14153 {
14154 if (LocaleCompare(attribute,"channel") == 0)
14155 {
14156 ssize_t
14157 option;
14158
14159 option=ParseChannelOption(SvPV(ST(i),na));
14160 if (option < 0)
14161 {
14162 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14163 SvPV(ST(i),na));
14164 return;
14165 }
14166 channel=(ChannelType) option;
14167 break;
14168 }
14169 if (LocaleCompare(attribute,"color") == 0)
14170 {
14171 if (SvTYPE(ST(i)) != SVt_RV)
14172 {
14173 char
cristy151b66d2015-04-15 10:50:31 +000014174 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014175
cristy151b66d2015-04-15 10:50:31 +000014176 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000014177 "invalid %.60s value",attribute);
14178 ThrowPerlException(exception,OptionError,message,
14179 SvPV(ST(i),na));
14180 }
14181 av=(AV *) SvRV(ST(i));
14182 break;
14183 }
14184 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14185 attribute);
14186 break;
14187 }
14188 case 'g':
14189 case 'G':
14190 {
14191 if (LocaleCompare(attribute,"geometry") == 0)
14192 {
14193 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14194 break;
14195 }
14196 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14197 attribute);
14198 break;
14199 }
14200 case 'N':
14201 case 'n':
14202 {
14203 if (LocaleCompare(attribute,"normalize") == 0)
14204 {
14205 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14206 SvPV(ST(i),na));
14207 if (option < 0)
14208 {
14209 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14210 SvPV(ST(i),na));
14211 break;
14212 }
14213 normalize=option != 0 ? MagickTrue : MagickFalse;
14214 break;
14215 }
14216 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14217 attribute);
14218 break;
14219 }
14220 case 'x':
14221 case 'X':
14222 {
14223 if (LocaleCompare(attribute,"x") == 0)
14224 {
14225 region.x=SvIV(ST(i));
14226 break;
14227 }
14228 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14229 attribute);
14230 break;
14231 }
14232 case 'y':
14233 case 'Y':
14234 {
14235 if (LocaleCompare(attribute,"y") == 0)
14236 {
14237 region.y=SvIV(ST(i));
14238 break;
14239 }
14240 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14241 attribute);
14242 break;
14243 }
14244 default:
14245 {
14246 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14247 attribute);
14248 break;
14249 }
14250 }
14251 }
14252 (void) SetImageStorageClass(image,DirectClass,exception);
14253 channel_mask=SetImageChannelMask(image,channel);
14254 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14255 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14256 (SvTYPE(av) != SVt_PVAV))
14257 PUSHs(&sv_undef);
14258 else
14259 {
14260 double
14261 scale;
14262
14263 register ssize_t
14264 i;
14265
14266 i=0;
14267 scale=1.0;
14268 if (normalize != MagickFalse)
14269 scale=QuantumRange;
14270 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14271 (i <= av_len(av)))
14272 {
14273 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14274 av_fetch(av,i,0)))),q);
14275 i++;
14276 }
14277 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14278 (i <= av_len(av)))
14279 {
14280 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14281 av_fetch(av,i,0)))),q);
14282 i++;
14283 }
14284 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14285 (i <= av_len(av)))
14286 {
14287 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14288 av_fetch(av,i,0)))),q);
14289 i++;
14290 }
14291 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14292 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14293 {
14294 SetPixelBlack(image,ClampToQuantum(scale*
14295 SvNV(*(av_fetch(av,i,0)))),q);
14296 i++;
14297 }
14298 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14299 (i <= av_len(av)))
14300 {
14301 SetPixelAlpha(image,ClampToQuantum(scale*
14302 SvNV(*(av_fetch(av,i,0)))),q);
14303 i++;
14304 }
14305 (void) SyncAuthenticPixels(image,exception);
14306 }
14307 (void) SetImageChannelMask(image,channel_mask);
14308
14309 PerlException:
14310 InheritPerlException(exception,perl_exception);
14311 exception=DestroyExceptionInfo(exception);
14312 SvREFCNT_dec(perl_exception);
14313 }
14314
14315#
14316###############################################################################
14317# #
14318# #
14319# #
Cristybba545b2018-07-04 15:00:12 -040014320# S e t P i x e l s #
14321# #
14322# #
14323# #
14324###############################################################################
14325#
14326#
14327void
14328SetPixels(ref,...)
14329 Image::Magick ref=NO_INIT
14330 ALIAS:
14331 setpixels = 1
14332 setPixels = 2
14333 PPCODE:
14334 {
14335 AV
14336 *av;
14337
14338 char
14339 *attribute;
14340
14341 ChannelType
14342 channel,
14343 channel_mask;
14344
14345 ExceptionInfo
14346 *exception;
14347
14348 Image
14349 *image;
14350
14351 RectangleInfo
14352 region;
14353
14354 register ssize_t
14355 i;
14356
14357 register Quantum
14358 *q;
14359
14360 struct PackageInfo
14361 *info;
14362
14363 SV
14364 *perl_exception,
14365 *reference; /* reference is the SV* of ref=SvIV(reference) */
14366
14367 PERL_UNUSED_VAR(ref);
14368 PERL_UNUSED_VAR(ix);
14369 exception=AcquireExceptionInfo();
14370 perl_exception=newSVpv("",0);
14371 reference=SvRV(ST(0));
14372 av=(AV *) reference;
14373 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14374 exception);
14375 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14376 if (image == (Image *) NULL)
14377 {
14378 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14379 PackageName);
14380 goto PerlException;
14381 }
14382 av=(AV *) NULL;
14383 region.x=0;
14384 region.y=0;
14385 region.width=image->columns;
14386 region.height=1;
14387 if (items == 1)
14388 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
14389 channel=DefaultChannels;
14390 for (i=2; i < items; i+=2)
14391 {
14392 attribute=(char *) SvPV(ST(i-1),na);
14393 switch (*attribute)
14394 {
14395 case 'C':
14396 case 'c':
14397 {
14398 if (LocaleCompare(attribute,"channel") == 0)
14399 {
14400 ssize_t
14401 option;
14402
14403 option=ParseChannelOption(SvPV(ST(i),na));
14404 if (option < 0)
14405 {
14406 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14407 SvPV(ST(i),na));
14408 return;
14409 }
14410 channel=(ChannelType) option;
14411 break;
14412 }
14413 if (LocaleCompare(attribute,"color") == 0)
14414 {
14415 if (SvTYPE(ST(i)) != SVt_RV)
14416 {
14417 char
14418 message[MagickPathExtent];
14419
14420 (void) FormatLocaleString(message,MagickPathExtent,
14421 "invalid %.60s value",attribute);
14422 ThrowPerlException(exception,OptionError,message,
14423 SvPV(ST(i),na));
14424 }
14425 av=(AV *) SvRV(ST(i));
14426 break;
14427 }
14428 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14429 attribute);
14430 break;
14431 }
14432 case 'g':
14433 case 'G':
14434 {
14435 if (LocaleCompare(attribute,"geometry") == 0)
14436 {
14437 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14438 break;
14439 }
14440 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14441 attribute);
14442 break;
14443 }
14444 case 'h':
14445 case 'H':
14446 {
14447 if (LocaleCompare(attribute,"height") == 0)
14448 {
14449 region.height=SvIV(ST(i));
14450 break;
14451 }
14452 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14453 attribute);
14454 break;
14455 }
14456 case 'w':
14457 case 'W':
14458 {
14459 if (LocaleCompare(attribute,"width") == 0)
14460 {
14461 region.width=SvIV(ST(i));
14462 break;
14463 }
14464 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14465 attribute);
14466 break;
14467 }
14468 case 'x':
14469 case 'X':
14470 {
14471 if (LocaleCompare(attribute,"x") == 0)
14472 {
14473 region.x=SvIV(ST(i));
14474 break;
14475 }
14476 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14477 attribute);
14478 break;
14479 }
14480 case 'y':
14481 case 'Y':
14482 {
14483 if (LocaleCompare(attribute,"y") == 0)
14484 {
14485 region.y=SvIV(ST(i));
14486 break;
14487 }
14488 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14489 attribute);
14490 break;
14491 }
14492 default:
14493 {
14494 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14495 attribute);
14496 break;
14497 }
14498 }
14499 }
14500 (void) SetImageStorageClass(image,DirectClass,exception);
14501 channel_mask=SetImageChannelMask(image,channel);
14502 q=GetAuthenticPixels(image,region.x,region.y,region.width,region.height,
14503 exception);
14504 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14505 (SvTYPE(av) != SVt_PVAV))
14506 PUSHs(&sv_undef);
14507 else
14508 {
14509 double
14510 scale;
14511
14512 register ssize_t
14513 i,
14514 n,
14515 number_pixels;
14516
14517 i=0;
14518 n=0;
14519 scale=(double) QuantumRange;
14520 number_pixels=region.width*region.height;
14521 while ((n < number_pixels) && (i < av_len(av)))
14522 {
14523 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14524 (i <= av_len(av)))
14525 {
14526 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14527 av_fetch(av,i,0)))),q);
14528 i++;
14529 }
14530 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14531 (i <= av_len(av)))
14532 {
14533 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14534 av_fetch(av,i,0)))),q);
14535 i++;
14536 }
14537 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14538 (i <= av_len(av)))
14539 {
14540 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14541 av_fetch(av,i,0)))),q);
14542 i++;
14543 }
14544 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14545 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14546 {
14547 SetPixelBlack(image,ClampToQuantum(scale*
14548 SvNV(*(av_fetch(av,i,0)))),q);
14549 i++;
14550 }
14551 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14552 (i <= av_len(av)))
14553 {
14554 SetPixelAlpha(image,ClampToQuantum(scale*
14555 SvNV(*(av_fetch(av,i,0)))),q);
14556 i++;
14557 }
14558 n++;
14559 q+=image->number_channels;
14560 }
14561 (void) SyncAuthenticPixels(image,exception);
14562 }
14563 (void) SetImageChannelMask(image,channel_mask);
14564
14565 PerlException:
14566 InheritPerlException(exception,perl_exception);
14567 exception=DestroyExceptionInfo(exception);
14568 SvREFCNT_dec(perl_exception);
14569 }
14570
14571#
14572###############################################################################
14573# #
14574# #
14575# #
cristy4a3ce0a2013-08-03 20:06:59 +000014576# S m u s h #
14577# #
14578# #
14579# #
14580###############################################################################
14581#
14582#
14583void
14584Smush(ref,...)
14585 Image::Magick ref=NO_INIT
14586 ALIAS:
14587 SmushImage = 1
14588 smush = 2
14589 smushimage = 3
14590 PPCODE:
14591 {
14592 AV
14593 *av;
14594
14595 char
14596 *attribute;
14597
14598 ExceptionInfo
14599 *exception;
14600
14601 HV
14602 *hv;
14603
14604 Image
14605 *image;
14606
14607 register ssize_t
14608 i;
14609
14610 ssize_t
14611 offset,
14612 stack;
14613
14614 struct PackageInfo
14615 *info;
14616
14617 SV
14618 *av_reference,
14619 *perl_exception,
14620 *reference,
14621 *rv,
14622 *sv;
14623
14624 PERL_UNUSED_VAR(ref);
14625 PERL_UNUSED_VAR(ix);
14626 exception=AcquireExceptionInfo();
14627 perl_exception=newSVpv("",0);
14628 sv=NULL;
14629 attribute=NULL;
14630 av=NULL;
14631 if (sv_isobject(ST(0)) == 0)
14632 {
14633 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14634 PackageName);
14635 goto PerlException;
14636 }
14637 reference=SvRV(ST(0));
14638 hv=SvSTASH(reference);
14639 av=newAV();
14640 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14641 SvREFCNT_dec(av);
14642 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14643 if (image == (Image *) NULL)
14644 {
14645 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14646 PackageName);
14647 goto PerlException;
14648 }
14649 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14650 /*
14651 Get options.
14652 */
14653 offset=0;
14654 stack=MagickTrue;
14655 for (i=2; i < items; i+=2)
14656 {
14657 attribute=(char *) SvPV(ST(i-1),na);
14658 switch (*attribute)
14659 {
14660 case 'O':
14661 case 'o':
14662 {
14663 if (LocaleCompare(attribute,"offset") == 0)
14664 {
14665 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14666 break;
14667 }
14668 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14669 attribute);
14670 break;
14671 }
14672 case 'S':
14673 case 's':
14674 {
14675 if (LocaleCompare(attribute,"stack") == 0)
14676 {
14677 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14678 SvPV(ST(i),na));
14679 if (stack < 0)
14680 {
14681 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14682 SvPV(ST(i),na));
14683 return;
14684 }
14685 break;
14686 }
14687 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14688 attribute);
14689 break;
14690 }
14691 default:
14692 {
14693 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14694 attribute);
14695 break;
14696 }
14697 }
14698 }
14699 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14700 exception);
14701 if (image == (Image *) NULL)
14702 goto PerlException;
14703 for ( ; image; image=image->next)
14704 {
14705 AddImageToRegistry(sv,image);
14706 rv=newRV(sv);
14707 av_push(av,sv_bless(rv,hv));
14708 SvREFCNT_dec(sv);
14709 }
14710 exception=DestroyExceptionInfo(exception);
14711 ST(0)=av_reference;
14712 SvREFCNT_dec(perl_exception);
14713 XSRETURN(1);
14714
14715 PerlException:
14716 InheritPerlException(exception,perl_exception);
14717 exception=DestroyExceptionInfo(exception);
14718 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14719 SvPOK_on(perl_exception);
14720 ST(0)=sv_2mortal(perl_exception);
14721 XSRETURN(1);
14722 }
14723
14724#
14725###############################################################################
14726# #
14727# #
14728# #
14729# S t a t i s t i c s #
14730# #
14731# #
14732# #
14733###############################################################################
14734#
14735#
14736void
14737Statistics(ref,...)
14738 Image::Magick ref=NO_INIT
14739 ALIAS:
14740 StatisticsImage = 1
14741 statistics = 2
14742 statisticsimage = 3
14743 PPCODE:
14744 {
14745#define ChannelStatistics(channel) \
14746{ \
cristy151b66d2015-04-15 10:50:31 +000014747 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014748 (double) channel_statistics[channel].depth); \
14749 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014750 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014751 channel_statistics[channel].minima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014752 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014753 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014754 channel_statistics[channel].maxima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014755 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014756 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014757 channel_statistics[channel].mean/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014758 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014759 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014760 channel_statistics[channel].standard_deviation/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014761 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014762 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014763 channel_statistics[channel].kurtosis); \
14764 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014765 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014766 channel_statistics[channel].skewness); \
14767 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014768 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy275bdd92014-11-08 23:45:03 +000014769 channel_statistics[channel].entropy); \
14770 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014771}
14772
14773 AV
14774 *av;
14775
14776 char
cristy151b66d2015-04-15 10:50:31 +000014777 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014778
14779 ChannelStatistics
14780 *channel_statistics;
14781
cristy4a3ce0a2013-08-03 20:06:59 +000014782 ExceptionInfo
14783 *exception;
14784
14785 Image
14786 *image;
14787
14788 ssize_t
14789 count;
14790
14791 struct PackageInfo
14792 *info;
14793
14794 SV
14795 *perl_exception,
14796 *reference;
14797
14798 PERL_UNUSED_VAR(ref);
14799 PERL_UNUSED_VAR(ix);
14800 exception=AcquireExceptionInfo();
14801 perl_exception=newSVpv("",0);
14802 av=NULL;
14803 if (sv_isobject(ST(0)) == 0)
14804 {
14805 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14806 PackageName);
14807 goto PerlException;
14808 }
14809 reference=SvRV(ST(0));
14810 av=newAV();
14811 SvREFCNT_dec(av);
14812 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14813 if (image == (Image *) NULL)
14814 {
14815 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14816 PackageName);
14817 goto PerlException;
14818 }
cristy4a3ce0a2013-08-03 20:06:59 +000014819 count=0;
14820 for ( ; image; image=image->next)
14821 {
Cristyb1710fe2017-02-11 13:51:48 -050014822 register size_t
14823 i;
14824
cristy4a3ce0a2013-08-03 20:06:59 +000014825 channel_statistics=GetImageStatistics(image,exception);
14826 if (channel_statistics == (ChannelStatistics *) NULL)
14827 continue;
14828 count++;
Cristyb1710fe2017-02-11 13:51:48 -050014829 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
14830 {
14831 PixelChannel channel=GetPixelChannelChannel(image,i);
14832 PixelTrait traits=GetPixelChannelTraits(image,channel);
Cristy5a854dc2017-02-11 15:43:46 -050014833 if (traits == UndefinedPixelTrait)
Cristyb1710fe2017-02-11 13:51:48 -050014834 continue;
Cristy5a854dc2017-02-11 15:43:46 -050014835 EXTEND(sp,8*(i+1)*count);
Cristyb1710fe2017-02-11 13:51:48 -050014836 ChannelStatistics(channel);
14837 }
Cristy25813902017-02-11 15:47:52 -050014838 EXTEND(sp,8*(i+1)*count);
14839 ChannelStatistics(CompositePixelChannel);
cristy4a3ce0a2013-08-03 20:06:59 +000014840 channel_statistics=(ChannelStatistics *)
14841 RelinquishMagickMemory(channel_statistics);
14842 }
14843
14844 PerlException:
14845 InheritPerlException(exception,perl_exception);
14846 exception=DestroyExceptionInfo(exception);
14847 SvREFCNT_dec(perl_exception);
14848 }
14849
14850#
14851###############################################################################
14852# #
14853# #
14854# #
14855# S y n c A u t h e n t i c P i x e l s #
14856# #
14857# #
14858# #
14859###############################################################################
14860#
14861#
14862void
14863SyncAuthenticPixels(ref,...)
14864 Image::Magick ref = NO_INIT
14865 ALIAS:
14866 Syncauthenticpixels = 1
14867 SyncImagePixels = 2
14868 syncimagepixels = 3
14869 CODE:
14870 {
14871 ExceptionInfo
14872 *exception;
14873
14874 Image
14875 *image;
14876
14877 MagickBooleanType
14878 status;
14879
14880 struct PackageInfo
14881 *info;
14882
14883 SV
14884 *perl_exception,
14885 *reference;
14886
14887 PERL_UNUSED_VAR(ref);
14888 PERL_UNUSED_VAR(ix);
14889 exception=AcquireExceptionInfo();
14890 perl_exception=newSVpv("",0);
14891 if (sv_isobject(ST(0)) == 0)
14892 {
14893 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14894 PackageName);
14895 goto PerlException;
14896 }
14897
14898 reference=SvRV(ST(0));
14899 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14900 if (image == (Image *) NULL)
14901 {
14902 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14903 PackageName);
14904 goto PerlException;
14905 }
14906
14907 status=SyncAuthenticPixels(image,exception);
14908 if (status != MagickFalse)
14909 return;
14910
14911 PerlException:
14912 InheritPerlException(exception,perl_exception);
14913 exception=DestroyExceptionInfo(exception);
14914 SvREFCNT_dec(perl_exception); /* throw away all errors */
14915 }
14916
14917#
14918###############################################################################
14919# #
14920# #
14921# #
cristy4a3ce0a2013-08-03 20:06:59 +000014922# W r i t e #
14923# #
14924# #
14925# #
14926###############################################################################
14927#
14928#
14929void
14930Write(ref,...)
14931 Image::Magick ref=NO_INIT
14932 ALIAS:
14933 WriteImage = 1
14934 write = 2
14935 writeimage = 3
14936 PPCODE:
14937 {
14938 char
cristy151b66d2015-04-15 10:50:31 +000014939 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014940
14941 ExceptionInfo
14942 *exception;
14943
14944 Image
14945 *image,
14946 *next;
14947
14948 register ssize_t
14949 i;
14950
14951 ssize_t
14952 number_images,
14953 scene;
14954
14955 struct PackageInfo
14956 *info,
14957 *package_info;
14958
14959 SV
14960 *perl_exception,
14961 *reference;
14962
14963 PERL_UNUSED_VAR(ref);
14964 PERL_UNUSED_VAR(ix);
14965 exception=AcquireExceptionInfo();
14966 perl_exception=newSVpv("",0);
14967 number_images=0;
14968 package_info=(struct PackageInfo *) NULL;
14969 if (sv_isobject(ST(0)) == 0)
14970 {
14971 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14972 PackageName);
14973 goto PerlException;
14974 }
14975 reference=SvRV(ST(0));
14976 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14977 if (image == (Image *) NULL)
14978 {
14979 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14980 PackageName);
14981 goto PerlException;
14982 }
Cristyb4ee45c2017-09-27 17:58:55 -040014983 scene=0;
14984 for (next=image; next; next=next->next)
14985 next->scene=scene++;
cristy4a3ce0a2013-08-03 20:06:59 +000014986 package_info=ClonePackageInfo(info,exception);
14987 if (items == 2)
14988 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14989 else
14990 if (items > 2)
14991 for (i=2; i < items; i+=2)
14992 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14993 exception);
14994 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014995 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014996 for (next=image; next; next=next->next)
cristy151b66d2015-04-15 10:50:31 +000014997 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy68bd79a2015-02-25 12:23:36 +000014998 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014999 SetImageInfo(package_info->image_info,(unsigned int)
15000 GetImageListLength(image),exception);
15001 for (next=image; next; next=next->next)
15002 {
15003 (void) WriteImage(package_info->image_info,next,exception);
15004 number_images++;
15005 if (package_info->image_info->adjoin)
15006 break;
15007 }
15008
15009 PerlException:
15010 if (package_info != (struct PackageInfo *) NULL)
15011 DestroyPackageInfo(package_info);
15012 InheritPerlException(exception,perl_exception);
15013 exception=DestroyExceptionInfo(exception);
15014 sv_setiv(perl_exception,(IV) number_images);
15015 SvPOK_on(perl_exception);
15016 ST(0)=sv_2mortal(perl_exception);
15017 XSRETURN(1);
15018 }