blob: 793cf21bfa4d2d6e8921f1af7f58f55047fdbe55 [file] [log] [blame]
cristy4a3ce0a2013-08-03 20:06:59 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% PPPP EEEEE RRRR L %
6% P P E R R L %
7% PPPP EEE RRRR L %
8% P E R R L %
9% P EEEEE R R LLLLL %
10% %
11% M M AAA GGGG IIIII CCCC K K %
12% MM MM A A G I C K K %
13% M M M AAAAA G GGG I C KKK %
14% M M A A G G I C K K %
15% M M A A GGGG IIIII CCCC K K %
16% %
17% %
18% Object-oriented Perl interface to ImageMagick %
19% %
20% Software Design %
21% Kyle Shorter %
cristyde984cd2013-12-01 14:49:27 +000022% Cristy %
cristy4a3ce0a2013-08-03 20:06:59 +000023% February 1997 %
24% %
25% %
Cristyf775a5c2019-11-26 14:27:47 -050026% Copyright 1999-2020 ImageMagick Studio LLC, a non-profit organization %
cristy4a3ce0a2013-08-03 20:06:59 +000027% dedicated to making software imaging solutions freely available. %
28% %
29% You may not use this file except in compliance with the License. You may %
30% obtain a copy of the License at %
31% %
Cristy0a176e12018-10-13 10:28:43 -040032% https://imagemagick.org/script/license.php %
cristy4a3ce0a2013-08-03 20:06:59 +000033% %
34% Unless required by applicable law or agreed to in writing, software %
35% distributed under the License is distributed on an "AS IS" BASIS, %
36% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
37% See the License for the specific language governing permissions and %
38% limitations under the License. %
39% %
40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41%
42% PerlMagick is an objected-oriented Perl interface to ImageMagick. Use
43% the module to read, manipulate, or write an image or image sequence from
44% within a Perl script. This makes PerlMagick suitable for Web CGI scripts.
45%
46*/
47
48/*
49 Include declarations.
50*/
51#if defined(__cplusplus) || defined(c_plusplus)
52extern "C" {
53#endif
54
55#define PERL_NO_GET_CONTEXT
dirk190cc1c2015-06-16 11:48:37 +000056#include <MagickCore/MagickCore.h>
cristy4a3ce0a2013-08-03 20:06:59 +000057#include "EXTERN.h"
58#include "perl.h"
59#include "XSUB.h"
60#include <math.h>
cristy4a3ce0a2013-08-03 20:06:59 +000061#undef tainted
62
63#if defined(__cplusplus) || defined(c_plusplus)
64}
65#endif
66
67/*
68 Define declarations.
69*/
70#ifndef aTHX_
71#define aTHX_
72#define pTHX_
73#define dTHX
74#endif
75#define DegreesToRadians(x) (MagickPI*(x)/180.0)
76#define EndOf(array) (&array[NumberOf(array)])
cristy3249b7b2014-02-09 21:43:14 +000077#define MagickPI 3.14159265358979323846264338327950288419716939937510
Cristy3d1de822019-02-15 18:06:30 -050078#define MaxArguments 34
cristy4a3ce0a2013-08-03 20:06:59 +000079#ifndef na
80#define na PL_na
81#endif
82#define NumberOf(array) (sizeof(array)/sizeof(*array))
83#define PackageName "Image::Magick"
84#if PERL_VERSION <= 6
85#define PerlIO FILE
86#define PerlIO_importFILE(f, fl) (f)
87#define PerlIO_findFILE(f) NULL
88#endif
89#ifndef sv_undef
90#define sv_undef PL_sv_undef
91#endif
92
93#define AddImageToRegistry(sv,image) \
94{ \
95 if (magick_registry != (SplayTreeInfo *) NULL) \
96 { \
97 (void) AddValueToSplayTree(magick_registry,image,image); \
98 (sv)=newSViv(PTR2IV(image)); \
99 } \
100}
101
102#define DeleteImageFromRegistry(reference,image) \
103{ \
104 if (magick_registry != (SplayTreeInfo *) NULL) \
105 { \
106 if (GetImageReferenceCount(image) == 1) \
107 (void) DeleteNodeByValueFromSplayTree(magick_registry,image); \
108 image=DestroyImage(image); \
109 sv_setiv(reference,0); \
110 } \
111}
112
113#define InheritPerlException(exception,perl_exception) \
114{ \
115 char \
cristy151b66d2015-04-15 10:50:31 +0000116 message[MagickPathExtent]; \
cristy4a3ce0a2013-08-03 20:06:59 +0000117 \
118 if ((exception)->severity != UndefinedException) \
119 { \
cristy151b66d2015-04-15 10:50:31 +0000120 (void) FormatLocaleString(message,MagickPathExtent,"Exception %d: %s%s%s%s",\
cristy4a3ce0a2013-08-03 20:06:59 +0000121 (exception)->severity, (exception)->reason ? \
122 GetLocaleExceptionMessage((exception)->severity,(exception)->reason) : \
123 "Unknown", (exception)->description ? " (" : "", \
124 (exception)->description ? GetLocaleExceptionMessage( \
125 (exception)->severity,(exception)->description) : "", \
126 (exception)->description ? ")" : ""); \
127 if ((perl_exception) != (SV *) NULL) \
128 { \
129 if (SvCUR(perl_exception)) \
130 sv_catpv(perl_exception,"\n"); \
131 sv_catpv(perl_exception,message); \
132 } \
133 } \
134}
135
136#define ThrowPerlException(exception,severity,tag,reason) \
137 (void) ThrowMagickException(exception,GetMagickModule(),severity, \
138 tag,"`%s'",reason); \
139
140/*
141 Typedef and structure declarations.
142*/
143typedef enum
144{
Cristya9a04772018-01-16 11:44:34 -0500145 NullReference = 0,
cristy4a3ce0a2013-08-03 20:06:59 +0000146 ArrayReference = (~0),
147 RealReference = (~0)-1,
148 FileReference = (~0)-2,
149 ImageReference = (~0)-3,
150 IntegerReference = (~0)-4,
151 StringReference = (~0)-5
152} MagickReference;
153
154typedef struct _Arguments
155{
156 const char
157 *method;
158
159 ssize_t
160 type;
161} Arguments;
162
163struct ArgumentList
164{
165 ssize_t
166 integer_reference;
167
168 double
169 real_reference;
170
171 const char
172 *string_reference;
173
174 Image
175 *image_reference;
176
177 SV
178 *array_reference;
179
180 FILE
181 *file_reference;
182
183 size_t
184 length;
185};
186
187struct PackageInfo
188{
189 ImageInfo
190 *image_info;
191};
192
193typedef void
194 *Image__Magick; /* data type for the Image::Magick package */
195
196/*
197 Static declarations.
198*/
199static struct
200 Methods
201 {
202 const char
203 *name;
204
205 Arguments
206 arguments[MaxArguments];
207 } Methods[] =
208 {
209 { "Comment", { {"comment", StringReference} } },
210 { "Label", { {"label", StringReference} } },
211 { "AddNoise", { {"noise", MagickNoiseOptions}, {"attenuate", RealReference},
212 {"channel", MagickChannelOptions} } },
213 { "Colorize", { {"fill", StringReference}, {"blend", StringReference} } },
214 { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
215 {"height", IntegerReference}, {"fill", StringReference},
216 {"bordercolor", StringReference}, {"color", StringReference},
217 {"compose", MagickComposeOptions} } },
218 { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
219 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
220 { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
221 {"height", IntegerReference}, {"x", IntegerReference},
cristy260bd762014-08-15 12:46:34 +0000222 {"y", IntegerReference}, {"gravity", MagickGravityOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000223 { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
224 {"height", IntegerReference}, {"x", IntegerReference},
225 {"y", IntegerReference}, {"fuzz", StringReference},
226 {"gravity", MagickGravityOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500227 { "Despeckle", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000228 { "Edge", { {"radius", RealReference} } },
229 { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
230 {"sigma", RealReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500231 { "Enhance", { { (const char *) NULL, NullReference } } },
232 { "Flip", { { (const char *) NULL, NullReference } } },
233 { "Flop", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000234 { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
235 {"height", IntegerReference}, {"inner", IntegerReference},
236 {"outer", IntegerReference}, {"fill", StringReference},
237 {"color", StringReference}, {"compose", MagickComposeOptions} } },
238 { "Implode", { {"amount", RealReference},
239 {"interpolate", MagickInterpolateOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500240 { "Magnify", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000241 { "MedianFilter", { {"geometry", StringReference},
242 {"width", IntegerReference}, {"height", IntegerReference},
243 {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500244 { "Minify", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000245 { "OilPaint", { {"radius", RealReference}, {"sigma", RealReference} } },
246 { "ReduceNoise", { {"geometry", StringReference},
247 {"width", IntegerReference},{"height", IntegerReference},
248 {"channel", MagickChannelOptions} } },
249 { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
250 {"y", IntegerReference} } },
cristy83a28a02013-08-03 20:25:48 +0000251 { "Rotate", { {"degrees", RealReference},
cristy4a3ce0a2013-08-03 20:06:59 +0000252 {"background", StringReference} } },
253 { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
254 {"height", IntegerReference} } },
255 { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
256 {"height", IntegerReference} } },
257 { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
258 {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
259 { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
260 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
261 { "Shear", { {"geometry", StringReference}, {"x", RealReference},
262 {"y", RealReference}, { "fill", StringReference},
263 {"color", StringReference} } },
Cristye3319c12015-08-24 07:11:48 -0400264 { "Spread", { {"radius", RealReference},
Cristy3ca633e2016-02-13 12:49:01 -0500265 {"interpolate", MagickInterpolateOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000266 { "Swirl", { {"degrees", RealReference},
267 {"interpolate", MagickInterpolateOptions} } },
268 { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
269 {"height", IntegerReference}, {"filter", MagickFilterOptions},
270 {"support", StringReference } } },
271 { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
272 {"height", IntegerReference}, {"filter", MagickFilterOptions},
273 {"support", RealReference } } },
274 { "Annotate", { {"text", StringReference}, {"font", StringReference},
275 {"pointsize", RealReference}, {"density", StringReference},
276 {"undercolor", StringReference}, {"stroke", StringReference},
277 {"fill", StringReference}, {"geometry", StringReference},
278 {"sans", StringReference}, {"x", RealReference},
279 {"y", RealReference}, {"gravity", MagickGravityOptions},
280 {"translate", StringReference}, {"scale", StringReference},
281 {"rotate", RealReference}, {"skewX", RealReference},
282 {"skewY", RealReference}, {"strokewidth", RealReference},
283 {"antialias", MagickBooleanOptions}, {"family", StringReference},
284 {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
285 {"weight", IntegerReference}, {"align", MagickAlignOptions},
286 {"encoding", StringReference}, {"affine", ArrayReference},
287 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
288 {"tile", ImageReference}, {"kerning", RealReference},
289 {"interline-spacing", RealReference},
290 {"interword-spacing", RealReference},
Cristy3d1de822019-02-15 18:06:30 -0500291 {"direction", MagickDirectionOptions},
292 {"decorate", MagickDecorateOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000293 { "ColorFloodfill", { {"geometry", StringReference},
294 {"x", IntegerReference}, {"y", IntegerReference},
295 {"fill", StringReference}, {"bordercolor", StringReference},
296 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
297 { "Composite", { {"image", ImageReference},
298 {"compose", MagickComposeOptions}, {"geometry", StringReference},
299 {"x", IntegerReference}, {"y", IntegerReference},
300 {"gravity", MagickGravityOptions}, {"opacity", StringReference},
301 {"tile", MagickBooleanOptions}, {"rotate", RealReference},
302 {"color", StringReference}, {"mask", ImageReference},
303 {"channel", MagickChannelOptions},
304 {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
Cristy74e39292018-07-08 13:13:20 -0400305 {"blend", StringReference}, {"clip-to-self", MagickBooleanOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000306 { "Contrast", { {"sharpen", MagickBooleanOptions} } },
307 { "CycleColormap", { {"display", IntegerReference} } },
308 { "Draw", { {"primitive", MagickPrimitiveOptions},
309 {"points", StringReference}, {"method", MagickMethodOptions},
310 {"stroke", StringReference}, {"fill", StringReference},
311 {"strokewidth", RealReference}, {"font", StringReference},
312 {"bordercolor", StringReference}, {"x", RealReference},
313 {"y", RealReference}, {"translate", StringReference},
314 {"scale", StringReference}, {"rotate", RealReference},
315 {"skewX", RealReference}, {"skewY", RealReference},
316 {"tile", ImageReference}, {"pointsize", RealReference},
317 {"antialias", MagickBooleanOptions}, {"density", StringReference},
318 {"linewidth", RealReference}, {"affine", ArrayReference},
319 {"stroke-dashoffset", RealReference},
320 {"stroke-dasharray", ArrayReference},
321 {"interpolate", MagickInterpolateOptions},
322 {"origin", StringReference}, {"text", StringReference},
323 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
324 {"vector-graphics", StringReference}, {"kerning", RealReference},
325 {"interline-spacing", RealReference},
326 {"interword-spacing", RealReference},
327 {"direction", MagickDirectionOptions} } },
328 { "Equalize", { {"channel", MagickChannelOptions} } },
329 { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
330 {"red", RealReference}, {"green", RealReference},
331 {"blue", RealReference} } },
332 { "Map", { {"image", ImageReference},
333 {"dither-method", MagickDitherOptions} } },
334 { "MatteFloodfill", { {"geometry", StringReference},
335 {"x", IntegerReference}, {"y", IntegerReference},
336 {"opacity", StringReference}, {"bordercolor", StringReference},
337 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
338 { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
339 {"saturation", RealReference}, {"whiteness", RealReference},
340 {"brightness", RealReference}, {"lightness", RealReference},
341 {"blackness", RealReference} } },
342 { "Negate", { {"gray", MagickBooleanOptions},
343 {"channel", MagickChannelOptions} } },
344 { "Normalize", { {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500345 { "NumberColors", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000346 { "Opaque", { {"color", StringReference}, {"fill", StringReference},
347 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
348 {"invert", MagickBooleanOptions} } },
349 { "Quantize", { {"colors", IntegerReference},
350 {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
351 {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
352 {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
353 {"dither-method", MagickDitherOptions} } },
354 { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
355 {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
356 { "Segment", { {"geometry", StringReference},
357 {"cluster-threshold", RealReference},
358 {"smoothing-threshold", RealReference},
359 {"colorspace", MagickColorspaceOptions},
360 {"verbose", MagickBooleanOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500361 { "Signature", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000362 { "Solarize", { {"geometry", StringReference},
363 {"threshold", StringReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500364 { "Sync", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000365 { "Texture", { {"texture", ImageReference} } },
366 { "Evaluate", { {"value", RealReference},
367 {"operator", MagickEvaluateOptions},
368 {"channel", MagickChannelOptions} } },
369 { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
370 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
371 { "Threshold", { {"threshold", StringReference},
372 {"channel", MagickChannelOptions} } },
373 { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
374 {"sigma", RealReference} } },
375 { "Trim", { {"fuzz", StringReference} } },
376 { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
377 {"wavelength", RealReference},
378 {"interpolate", MagickInterpolateOptions} } },
379 { "Separate", { {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500380 { "Condense", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000381 { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
382 {"y", IntegerReference} } },
383 { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500384 { "Deconstruct", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000385 { "GaussianBlur", { {"geometry", StringReference},
386 {"radius", RealReference}, {"sigma", RealReference},
387 {"channel", MagickChannelOptions} } },
388 { "Convolve", { {"coefficients", ArrayReference},
389 {"channel", MagickChannelOptions}, {"bias", StringReference},
390 {"kernel", StringReference} } },
391 { "Profile", { {"name", StringReference}, {"profile", StringReference},
392 { "rendering-intent", MagickIntentOptions},
393 { "black-point-compensation", MagickBooleanOptions} } },
394 { "UnsharpMask", { {"geometry", StringReference},
395 {"radius", RealReference}, {"sigma", RealReference},
396 {"gain", RealReference}, {"threshold", RealReference},
397 {"channel", MagickChannelOptions} } },
398 { "MotionBlur", { {"geometry", StringReference},
399 {"radius", RealReference}, {"sigma", RealReference},
400 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
401 { "OrderedDither", { {"threshold", StringReference},
402 {"channel", MagickChannelOptions} } },
403 { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
404 {"height", IntegerReference} } },
405 { "Level", { {"levels", StringReference}, {"black-point", RealReference},
406 {"white-point", RealReference}, {"gamma", RealReference},
407 {"channel", MagickChannelOptions}, {"level", StringReference} } },
408 { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
409 { "AffineTransform", { {"affine", ArrayReference},
410 {"translate", StringReference}, {"scale", StringReference},
411 {"rotate", RealReference}, {"skewX", RealReference},
412 {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
413 {"background", StringReference} } },
414 { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
415 { "AdaptiveThreshold", { {"geometry", StringReference},
Cristy9f252542018-11-21 19:13:46 -0500416 {"width", IntegerReference}, {"height", IntegerReference},
417 {"bias", RealReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000418 { "Resample", { {"density", StringReference}, {"x", RealReference},
419 {"y", RealReference}, {"filter", MagickFilterOptions},
420 {"support", RealReference } } },
421 { "Describe", { {"file", FileReference} } },
422 { "BlackThreshold", { {"threshold", StringReference},
423 {"channel", MagickChannelOptions} } },
424 { "WhiteThreshold", { {"threshold", StringReference},
425 {"channel", MagickChannelOptions} } },
cristy60c73c02014-03-25 12:09:58 +0000426 { "RotationalBlur", { {"geometry", StringReference},
427 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000428 { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
429 {"height", IntegerReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500430 { "Strip", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000431 { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
432 { "Channel", { {"channel", MagickChannelOptions} } },
433 { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
434 {"height", IntegerReference}, {"x", IntegerReference},
435 {"y", IntegerReference}, {"fuzz", StringReference},
436 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
437 { "Posterize", { {"levels", IntegerReference},
438 {"dither", MagickBooleanOptions} } },
439 { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
440 {"sigma", RealReference}, {"x", IntegerReference},
441 {"y", IntegerReference} } },
442 { "Identify", { {"file", FileReference}, {"features", StringReference},
Cristy8b3ffe62020-02-17 12:36:53 -0500443 {"moments", MagickBooleanOptions}, {"unique", MagickBooleanOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000444 { "SepiaTone", { {"threshold", RealReference} } },
445 { "SigmoidalContrast", { {"geometry", StringReference},
446 {"contrast", RealReference}, {"mid-point", RealReference},
447 {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
448 { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
449 {"height", IntegerReference}, {"x", IntegerReference},
450 {"y", IntegerReference}, {"fuzz", StringReference},
451 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
452 { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
453 {"sigma", RealReference}, {"x", IntegerReference},
454 {"y", IntegerReference}, {"background", StringReference} } },
455 { "ContrastStretch", { {"levels", StringReference},
456 {"black-point", RealReference},{"white-point", RealReference},
457 {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500458 { "Sans0", { { (const char *) NULL, NullReference } } },
459 { "Sans1", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000460 { "AdaptiveSharpen", { {"geometry", StringReference},
461 {"radius", RealReference}, {"sigma", RealReference},
462 {"bias", RealReference}, {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500463 { "Transpose", { { (const char *) NULL, NullReference } } },
464 { "Transverse", { { (const char *) NULL, NullReference } } },
465 { "AutoOrient", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000466 { "AdaptiveBlur", { {"geometry", StringReference},
467 {"radius", RealReference}, {"sigma", RealReference},
468 {"channel", MagickChannelOptions} } },
469 { "Sketch", { {"geometry", StringReference},
470 {"radius", RealReference}, {"sigma", RealReference},
471 {"angle", RealReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500472 { "UniqueColors", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000473 { "AdaptiveResize", { {"geometry", StringReference},
474 {"width", IntegerReference}, {"height", IntegerReference},
475 {"filter", MagickFilterOptions}, {"support", StringReference },
476 {"blur", RealReference } } },
477 { "ClipMask", { {"mask", ImageReference} } },
478 { "LinearStretch", { {"levels", StringReference},
479 {"black-point", RealReference},{"white-point", RealReference} } },
480 { "ColorMatrix", { {"matrix", ArrayReference} } },
481 { "Mask", { {"mask", ImageReference} } },
482 { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
483 {"font", StringReference}, {"stroke", StringReference},
484 {"fill", StringReference}, {"strokewidth", RealReference},
485 {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
486 {"background", StringReference},
487 {"interpolate", MagickInterpolateOptions} } },
488 { "FloodfillPaint", { {"geometry", StringReference},
489 {"x", IntegerReference}, {"y", IntegerReference},
490 {"fill", StringReference}, {"bordercolor", StringReference},
491 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
492 {"invert", MagickBooleanOptions} } },
493 { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
494 {"virtual-pixel", MagickVirtualPixelOptions},
495 {"best-fit", MagickBooleanOptions} } },
496 { "Clut", { {"image", ImageReference},
497 {"interpolate", MagickInterpolateOptions},
498 {"channel", MagickChannelOptions} } },
499 { "LiquidRescale", { {"geometry", StringReference},
500 {"width", IntegerReference}, {"height", IntegerReference},
501 {"delta-x", RealReference}, {"rigidity", RealReference } } },
502 { "Encipher", { {"passphrase", StringReference} } },
503 { "Decipher", { {"passphrase", StringReference} } },
504 { "Deskew", { {"geometry", StringReference},
505 {"threshold", StringReference} } },
506 { "Remap", { {"image", ImageReference},
507 {"dither-method", MagickDitherOptions} } },
508 { "SparseColor", { {"points", ArrayReference},
509 {"method", MagickSparseColorOptions},
510 {"virtual-pixel", MagickVirtualPixelOptions},
511 {"channel", MagickChannelOptions} } },
512 { "Function", { {"parameters", ArrayReference},
513 {"function", MagickFunctionOptions},
514 {"virtual-pixel", MagickVirtualPixelOptions} } },
515 { "SelectiveBlur", { {"geometry", StringReference},
516 {"radius", RealReference}, {"sigma", RealReference},
517 {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
518 { "HaldClut", { {"image", ImageReference},
519 {"channel", MagickChannelOptions} } },
520 { "BlueShift", { {"factor", StringReference} } },
521 { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
522 { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
523 { "ColorDecisionList", {
524 {"color-correction-collection", StringReference} } },
525 { "AutoGamma", { {"channel", MagickChannelOptions} } },
526 { "AutoLevel", { {"channel", MagickChannelOptions} } },
527 { "LevelColors", { {"invert", MagickBooleanOptions},
528 {"black-point", StringReference}, {"white-point", StringReference},
529 {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
530 { "Clamp", { {"channel", MagickChannelOptions} } },
531 { "BrightnessContrast", { {"levels", StringReference},
532 {"brightness", RealReference},{"contrast", RealReference},
533 {"channel", MagickChannelOptions} } },
534 { "Morphology", { {"kernel", StringReference},
535 {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
536 {"iterations", IntegerReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000537 { "Mode", { {"geometry", StringReference},
538 {"width", IntegerReference},{"height", IntegerReference},
539 {"channel", MagickChannelOptions} } },
540 { "Statistic", { {"geometry", StringReference},
541 {"width", IntegerReference},{"height", IntegerReference},
542 {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
543 { "Perceptible", { {"epsilon", RealReference},
544 {"channel", MagickChannelOptions} } },
545 { "Poly", { {"terms", ArrayReference},
546 {"channel", MagickChannelOptions} } },
547 { "Grayscale", { {"method", MagickNoiseOptions} } },
cristy4ceadb82014-03-29 15:30:43 +0000548 { "CannyEdge", { {"geometry", StringReference},
549 {"radius", RealReference}, {"sigma", RealReference},
cristycfe7bf02014-04-04 15:31:52 +0000550 {"lower-percent", RealReference}, {"upper-percent", RealReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000551 { "HoughLine", { {"geometry", StringReference},
cristy4e215022014-04-19 18:02:35 +0000552 {"width", IntegerReference}, {"height", IntegerReference},
553 {"threshold", IntegerReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000554 { "MeanShift", { {"geometry", StringReference},
555 {"width", IntegerReference}, {"height", IntegerReference},
cristy1309fc32014-04-26 18:48:37 +0000556 {"distance", RealReference} } },
cristy3b207f82014-09-27 14:21:20 +0000557 { "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
558 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
Cristy2ca0e9a2016-01-01 08:36:14 -0500559 { "ConnectedComponents", { {"connectivity", IntegerReference} } },
cristyf3a724a2015-06-25 13:02:53 +0000560 { "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
561 {"width", IntegerReference}, {"height", IntegerReference},
562 {"x", IntegerReference}, {"y", IntegerReference},
Cristy532b3382018-08-05 17:56:56 -0400563 {"gravity", MagickGravityOptions}, {"offset", StringReference},
cristyf3a724a2015-06-25 13:02:53 +0000564 {"dx", IntegerReference}, {"dy", IntegerReference} } },
Cristy5488c982016-02-13 14:07:50 -0500565 { "Color", { {"color", StringReference} } },
Cristyc1759412016-02-27 12:17:58 -0500566 { "WaveletDenoise", { {"geometry", StringReference},
567 {"threshold", RealReference}, {"softness", RealReference},
Cristy2d830ed2016-02-21 10:54:16 -0500568 {"channel", MagickChannelOptions} } },
Cristy99a57162016-12-05 11:47:57 -0500569 { "Colorspace", { {"colorspace", MagickColorspaceOptions} } },
Cristy53353872017-07-02 12:24:24 -0400570 { "AutoThreshold", { {"method", MagickAutoThresholdOptions} } },
Cristy532b3382018-08-05 17:56:56 -0400571 { "RangeThreshold", { {"geometry", StringReference},
Cristy72f24752018-08-14 20:17:26 -0400572 {"low-black", RealReference}, {"low-white", RealReference},
573 {"high-white", RealReference}, {"high-black", RealReference},
Cristy532b3382018-08-05 17:56:56 -0400574 {"channel", MagickChannelOptions} } },
Cristy30263282018-12-11 16:40:25 -0500575 { "CLAHE", { {"geometry", StringReference}, {"width", IntegerReference},
576 {"height", IntegerReference}, {"number-bins", IntegerReference},
Cristy768e9002019-01-08 07:35:16 -0500577 {"clip-limit", RealReference} } },
Cristyb4ab5192019-12-19 06:53:46 -0500578 { "Kmeans", { {"geometry", StringReference}, {"colors", IntegerReference},
Cristy1fce5c52019-12-31 09:51:14 -0500579 {"iterations", IntegerReference}, {"tolerance", RealReference} } },
Cristyca5ba782020-02-22 08:17:19 -0500580 { "ColorThreshold", { {"start-color", StringReference},
581 {"stop-color", StringReference}, {"channel", MagickChannelOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000582 };
583
584static SplayTreeInfo
585 *magick_registry = (SplayTreeInfo *) NULL;
586
587/*
588 Forward declarations.
589*/
590static Image
591 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
592
593static ssize_t
594 strEQcase(const char *,const char *);
595
596/*
597%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
598% %
599% %
600% %
601% C l o n e P a c k a g e I n f o %
602% %
603% %
604% %
605%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
606%
607% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
608% a new one.
609%
610% The format of the ClonePackageInfo routine is:
611%
612% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
613% exception)
614%
615% A description of each parameter follows:
616%
617% o info: a structure of type info.
618%
619% o exception: Return any errors or warnings in this structure.
620%
621*/
622static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
623 ExceptionInfo *exception)
624{
625 struct PackageInfo
626 *clone_info;
627
628 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
629 if (clone_info == (struct PackageInfo *) NULL)
630 {
631 ThrowPerlException(exception,ResourceLimitError,
632 "UnableToClonePackageInfo",PackageName);
633 return((struct PackageInfo *) NULL);
634 }
635 if (info == (struct PackageInfo *) NULL)
636 {
637 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
638 return(clone_info);
639 }
640 *clone_info=(*info);
641 clone_info->image_info=CloneImageInfo(info->image_info);
642 return(clone_info);
643}
644
645/*
646%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
647% %
648% %
649% %
650% c o n s t a n t %
651% %
652% %
653% %
654%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
655%
656% constant() returns a double value for the specified name.
657%
658% The format of the constant routine is:
659%
660% double constant(char *name,ssize_t sans)
661%
662% A description of each parameter follows:
663%
664% o value: Method constant returns a double value for the specified name.
665%
666% o name: The name of the constant.
667%
668% o sans: This integer value is not used.
669%
670*/
671static double constant(char *name,ssize_t sans)
672{
673 (void) sans;
674 errno=0;
675 switch (*name)
676 {
677 case 'B':
678 {
679 if (strEQ(name,"BlobError"))
680 return(BlobError);
681 if (strEQ(name,"BlobWarning"))
682 return(BlobWarning);
683 break;
684 }
685 case 'C':
686 {
687 if (strEQ(name,"CacheError"))
688 return(CacheError);
689 if (strEQ(name,"CacheWarning"))
690 return(CacheWarning);
691 if (strEQ(name,"CoderError"))
692 return(CoderError);
693 if (strEQ(name,"CoderWarning"))
694 return(CoderWarning);
695 if (strEQ(name,"ConfigureError"))
696 return(ConfigureError);
697 if (strEQ(name,"ConfigureWarning"))
698 return(ConfigureWarning);
699 if (strEQ(name,"CorruptImageError"))
700 return(CorruptImageError);
701 if (strEQ(name,"CorruptImageWarning"))
702 return(CorruptImageWarning);
703 break;
704 }
705 case 'D':
706 {
707 if (strEQ(name,"DelegateError"))
708 return(DelegateError);
709 if (strEQ(name,"DelegateWarning"))
710 return(DelegateWarning);
711 if (strEQ(name,"DrawError"))
712 return(DrawError);
713 if (strEQ(name,"DrawWarning"))
714 return(DrawWarning);
715 break;
716 }
717 case 'E':
718 {
719 if (strEQ(name,"ErrorException"))
720 return(ErrorException);
721 if (strEQ(name,"ExceptionError"))
722 return(CoderError);
723 if (strEQ(name,"ExceptionWarning"))
724 return(CoderWarning);
725 break;
726 }
727 case 'F':
728 {
729 if (strEQ(name,"FatalErrorException"))
730 return(FatalErrorException);
731 if (strEQ(name,"FileOpenError"))
732 return(FileOpenError);
733 if (strEQ(name,"FileOpenWarning"))
734 return(FileOpenWarning);
735 break;
736 }
737 case 'I':
738 {
739 if (strEQ(name,"ImageError"))
740 return(ImageError);
741 if (strEQ(name,"ImageWarning"))
742 return(ImageWarning);
743 break;
744 }
745 case 'M':
746 {
747 if (strEQ(name,"MaxRGB"))
748 return(QuantumRange);
749 if (strEQ(name,"MissingDelegateError"))
750 return(MissingDelegateError);
751 if (strEQ(name,"MissingDelegateWarning"))
752 return(MissingDelegateWarning);
753 if (strEQ(name,"ModuleError"))
754 return(ModuleError);
755 if (strEQ(name,"ModuleWarning"))
756 return(ModuleWarning);
757 break;
758 }
759 case 'O':
760 {
761 if (strEQ(name,"Opaque"))
762 return(OpaqueAlpha);
763 if (strEQ(name,"OptionError"))
764 return(OptionError);
765 if (strEQ(name,"OptionWarning"))
766 return(OptionWarning);
767 break;
768 }
769 case 'Q':
770 {
771 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
772 return(MAGICKCORE_QUANTUM_DEPTH);
773 if (strEQ(name,"QuantumDepth"))
774 return(MAGICKCORE_QUANTUM_DEPTH);
775 if (strEQ(name,"QuantumRange"))
776 return(QuantumRange);
777 break;
778 }
779 case 'R':
780 {
781 if (strEQ(name,"ResourceLimitError"))
782 return(ResourceLimitError);
783 if (strEQ(name,"ResourceLimitWarning"))
784 return(ResourceLimitWarning);
785 if (strEQ(name,"RegistryError"))
786 return(RegistryError);
787 if (strEQ(name,"RegistryWarning"))
788 return(RegistryWarning);
789 break;
790 }
791 case 'S':
792 {
793 if (strEQ(name,"StreamError"))
794 return(StreamError);
795 if (strEQ(name,"StreamWarning"))
796 return(StreamWarning);
797 if (strEQ(name,"Success"))
798 return(0);
799 break;
800 }
801 case 'T':
802 {
803 if (strEQ(name,"Transparent"))
804 return(TransparentAlpha);
805 if (strEQ(name,"TypeError"))
806 return(TypeError);
807 if (strEQ(name,"TypeWarning"))
808 return(TypeWarning);
809 break;
810 }
811 case 'W':
812 {
813 if (strEQ(name,"WarningException"))
814 return(WarningException);
815 break;
816 }
817 case 'X':
818 {
819 if (strEQ(name,"XServerError"))
820 return(XServerError);
821 if (strEQ(name,"XServerWarning"))
822 return(XServerWarning);
823 break;
824 }
825 }
826 errno=EINVAL;
827 return(0);
828}
829
830/*
831%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
832% %
833% %
834% %
835% D e s t r o y P a c k a g e I n f o %
836% %
837% %
838% %
839%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
840%
841% Method DestroyPackageInfo frees a previously created info structure.
842%
843% The format of the DestroyPackageInfo routine is:
844%
845% DestroyPackageInfo(struct PackageInfo *info)
846%
847% A description of each parameter follows:
848%
849% o info: a structure of type info.
850%
851*/
852static void DestroyPackageInfo(struct PackageInfo *info)
853{
854 info->image_info=DestroyImageInfo(info->image_info);
855 info=(struct PackageInfo *) RelinquishMagickMemory(info);
856}
857
858/*
859%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
860% %
861% %
862% %
863% G e t L i s t %
864% %
865% %
866% %
867%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
868%
869% Method GetList is recursively called by SetupList to traverse the
870% Image__Magick reference. If building an reference_vector (see SetupList),
871% *current is the current position in *reference_vector and *last is the final
872% entry in *reference_vector.
873%
874% The format of the GetList routine is:
875%
876% GetList(info)
877%
878% A description of each parameter follows:
879%
880% o info: a structure of type info.
881%
882*/
883static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
884 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
885{
886 Image
887 *image;
888
889 if (reference == (SV *) NULL)
890 return(NULL);
891 switch (SvTYPE(reference))
892 {
893 case SVt_PVAV:
894 {
895 AV
896 *av;
897
898 Image
899 *head,
900 *previous;
901
902 register ssize_t
903 i;
904
905 ssize_t
906 n;
907
908 /*
909 Array of images.
910 */
911 previous=(Image *) NULL;
912 head=(Image *) NULL;
913 av=(AV *) reference;
914 n=av_len(av);
915 for (i=0; i <= n; i++)
916 {
917 SV
918 **rv;
919
920 rv=av_fetch(av,i,0);
921 if (rv && *rv && sv_isobject(*rv))
922 {
923 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
924 exception);
925 if (image == (Image *) NULL)
926 continue;
927 if (image == previous)
928 {
929 image=CloneImage(image,0,0,MagickTrue,exception);
930 if (image == (Image *) NULL)
931 return(NULL);
932 }
933 image->previous=previous;
934 *(previous ? &previous->next : &head)=image;
935 for (previous=image; previous->next; previous=previous->next) ;
936 }
937 }
938 return(head);
939 }
940 case SVt_PVMG:
941 {
942 /*
943 Blessed scalar, one image.
944 */
945 image=INT2PTR(Image *,SvIV(reference));
946 if (image == (Image *) NULL)
947 return(NULL);
948 image->previous=(Image *) NULL;
949 image->next=(Image *) NULL;
950 if (reference_vector)
951 {
952 if (*current == *last)
953 {
954 *last+=256;
955 if (*reference_vector == (SV **) NULL)
956 *reference_vector=(SV **) AcquireQuantumMemory(*last,
957 sizeof(*reference_vector));
958 else
959 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
960 *last,sizeof(*reference_vector));
961 }
962 if (*reference_vector == (SV **) NULL)
963 {
964 ThrowPerlException(exception,ResourceLimitError,
965 "MemoryAllocationFailed",PackageName);
966 return((Image *) NULL);
967 }
968 (*reference_vector)[*current]=reference;
969 (*reference_vector)[++(*current)]=NULL;
970 }
971 return(image);
972 }
973 default:
974 break;
975 }
976 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
977 (double) SvTYPE(reference));
978 return((Image *) NULL);
979}
980
981/*
982%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
983% %
984% %
985% %
986% G e t P a c k a g e I n f o %
987% %
988% %
989% %
990%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
991%
992% Method GetPackageInfo looks up or creates an info structure for the given
993% Image__Magick reference. If it does create a new one, the information in
994% package_info is used to initialize it.
995%
996% The format of the GetPackageInfo routine is:
997%
998% struct PackageInfo *GetPackageInfo(void *reference,
999% struct PackageInfo *package_info,ExceptionInfo *exception)
1000%
1001% A description of each parameter follows:
1002%
1003% o info: a structure of type info.
1004%
1005% o exception: Return any errors or warnings in this structure.
1006%
1007*/
1008static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
1009 struct PackageInfo *package_info,ExceptionInfo *exception)
1010{
1011 char
cristy151b66d2015-04-15 10:50:31 +00001012 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00001013
1014 struct PackageInfo
1015 *clone_info;
1016
1017 SV
1018 *sv;
1019
cristy151b66d2015-04-15 10:50:31 +00001020 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00001021 PackageName,XS_VERSION,reference);
1022 sv=perl_get_sv(message,(TRUE | 0x02));
1023 if (sv == (SV *) NULL)
1024 {
1025 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1026 message);
1027 return(package_info);
1028 }
1029 if (SvREFCNT(sv) == 0)
1030 (void) SvREFCNT_inc(sv);
1031 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1032 return(clone_info);
1033 clone_info=ClonePackageInfo(package_info,exception);
1034 sv_setiv(sv,PTR2IV(clone_info));
1035 return(clone_info);
1036}
1037
1038/*
1039%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1040% %
1041% %
1042% %
1043% S e t A t t r i b u t e %
1044% %
1045% %
1046% %
1047%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1048%
1049% SetAttribute() sets the attribute to the value in sval. This can change
1050% either or both of image or info.
1051%
1052% The format of the SetAttribute routine is:
1053%
1054% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1055% SV *sval,ExceptionInfo *exception)
1056%
1057% A description of each parameter follows:
1058%
1059% o list: a list of strings.
1060%
1061% o string: a character string.
1062%
1063*/
1064
1065static double SiPrefixToDoubleInterval(const char *string,const double interval)
1066{
1067 char
1068 *q;
1069
1070 double
1071 value;
1072
1073 value=InterpretSiPrefixValue(string,&q);
1074 if (*q == '%')
1075 value*=interval/100.0;
1076 return(value);
1077}
1078
1079static inline double StringToDouble(const char *string,char **sentinal)
1080{
1081 return(InterpretLocaleValue(string,sentinal));
1082}
1083
1084static double StringToDoubleInterval(const char *string,const double interval)
1085{
1086 char
1087 *q;
1088
1089 double
1090 value;
1091
1092 value=InterpretLocaleValue(string,&q);
1093 if (*q == '%')
1094 value*=interval/100.0;
1095 return(value);
1096}
1097
1098static inline ssize_t StringToLong(const char *value)
1099{
1100 return(strtol(value,(char **) NULL,10));
1101}
1102
1103static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1104 const char *attribute,SV *sval,ExceptionInfo *exception)
1105{
1106 GeometryInfo
1107 geometry_info;
1108
1109 long
1110 x,
1111 y;
1112
1113 PixelInfo
1114 pixel;
1115
1116 MagickStatusType
1117 flags;
1118
1119 PixelInfo
1120 *color,
1121 target_color;
1122
1123 ssize_t
1124 sp;
1125
1126 switch (*attribute)
1127 {
1128 case 'A':
1129 case 'a':
1130 {
1131 if (LocaleCompare(attribute,"adjoin") == 0)
1132 {
1133 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1134 SvPV(sval,na)) : SvIV(sval);
1135 if (sp < 0)
1136 {
1137 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1138 SvPV(sval,na));
1139 break;
1140 }
1141 if (info)
1142 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1143 break;
1144 }
1145 if (LocaleCompare(attribute,"alpha") == 0)
1146 {
1147 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1148 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1149 if (sp < 0)
1150 {
1151 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1152 SvPV(sval,na));
1153 break;
1154 }
1155 for ( ; image; image=image->next)
1156 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1157 exception);
1158 break;
1159 }
1160 if (LocaleCompare(attribute,"antialias") == 0)
1161 {
1162 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1163 SvPV(sval,na)) : SvIV(sval);
1164 if (sp < 0)
1165 {
1166 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1167 SvPV(sval,na));
1168 break;
1169 }
1170 if (info)
1171 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1172 break;
1173 }
1174 if (LocaleCompare(attribute,"area-limit") == 0)
1175 {
1176 MagickSizeType
1177 limit;
1178
1179 limit=MagickResourceInfinity;
1180 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1181 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1182 100.0);
1183 (void) SetMagickResourceLimit(AreaResource,limit);
1184 break;
1185 }
1186 if (LocaleCompare(attribute,"attenuate") == 0)
1187 {
1188 if (info)
1189 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1190 break;
1191 }
1192 if (LocaleCompare(attribute,"authenticate") == 0)
1193 {
1194 if (info)
1195 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1196 break;
1197 }
1198 if (info)
1199 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1200 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001201 {
1202 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstra337c9bc2017-04-03 16:04:21 +02001203 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001204 }
cristy4a3ce0a2013-08-03 20:06:59 +00001205 break;
1206 }
1207 case 'B':
1208 case 'b':
1209 {
1210 if (LocaleCompare(attribute,"background") == 0)
1211 {
1212 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1213 exception);
1214 if (info)
1215 info->image_info->background_color=target_color;
1216 for ( ; image; image=image->next)
1217 image->background_color=target_color;
1218 break;
1219 }
1220 if (LocaleCompare(attribute,"blue-primary") == 0)
1221 {
1222 for ( ; image; image=image->next)
1223 {
1224 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1225 image->chromaticity.blue_primary.x=geometry_info.rho;
1226 image->chromaticity.blue_primary.y=geometry_info.sigma;
1227 if ((flags & SigmaValue) == 0)
1228 image->chromaticity.blue_primary.y=
1229 image->chromaticity.blue_primary.x;
1230 }
1231 break;
1232 }
1233 if (LocaleCompare(attribute,"bordercolor") == 0)
1234 {
1235 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1236 exception);
1237 if (info)
1238 info->image_info->border_color=target_color;
1239 for ( ; image; image=image->next)
1240 image->border_color=target_color;
1241 break;
1242 }
1243 if (info)
1244 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1245 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001246 {
1247 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001248 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001249 }
cristy4a3ce0a2013-08-03 20:06:59 +00001250 break;
1251 }
1252 case 'C':
1253 case 'c':
1254 {
1255 if (LocaleCompare(attribute,"cache-threshold") == 0)
1256 {
1257 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1258 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1259 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1260 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1261 break;
1262 }
1263 if (LocaleCompare(attribute,"clip-mask") == 0)
1264 {
1265 Image
1266 *clip_mask;
1267
1268 clip_mask=(Image *) NULL;
1269 if (SvPOK(sval))
1270 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1271 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001272 SetImageMask(image,ReadPixelMask,clip_mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001273 break;
1274 }
1275 if (LocaleNCompare(attribute,"colormap",8) == 0)
1276 {
1277 for ( ; image; image=image->next)
1278 {
1279 int
1280 items;
1281
1282 long
1283 i;
1284
1285 if (image->storage_class == DirectClass)
1286 continue;
1287 i=0;
1288 items=sscanf(attribute,"%*[^[][%ld",&i);
1289 (void) items;
1290 if (i > (ssize_t) image->colors)
1291 i%=image->colors;
1292 if ((strchr(SvPV(sval,na),',') == 0) ||
1293 (strchr(SvPV(sval,na),')') != 0))
1294 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1295 image->colormap+i,exception);
1296 else
1297 {
1298 color=image->colormap+i;
1299 pixel.red=color->red;
1300 pixel.green=color->green;
1301 pixel.blue=color->blue;
1302 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1303 pixel.red=geometry_info.rho;
1304 pixel.green=geometry_info.sigma;
1305 pixel.blue=geometry_info.xi;
1306 color->red=ClampToQuantum(pixel.red);
1307 color->green=ClampToQuantum(pixel.green);
1308 color->blue=ClampToQuantum(pixel.blue);
1309 }
1310 }
1311 break;
1312 }
1313 if (LocaleCompare(attribute,"colorspace") == 0)
1314 {
1315 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1316 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1317 if (sp < 0)
1318 {
1319 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1320 SvPV(sval,na));
1321 break;
1322 }
1323 for ( ; image; image=image->next)
Cristy59262d92016-12-05 15:21:50 -05001324 (void) SetImageColorspace(image,(ColorspaceType) sp,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001325 break;
1326 }
1327 if (LocaleCompare(attribute,"comment") == 0)
1328 {
1329 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001330 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001331 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001332 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001333 break;
1334 }
1335 if (LocaleCompare(attribute,"compression") == 0)
1336 {
1337 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1338 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1339 if (sp < 0)
1340 {
1341 ThrowPerlException(exception,OptionError,
1342 "UnrecognizedImageCompression",SvPV(sval,na));
1343 break;
1344 }
1345 if (info)
1346 info->image_info->compression=(CompressionType) sp;
1347 for ( ; image; image=image->next)
1348 image->compression=(CompressionType) sp;
1349 break;
1350 }
1351 if (info)
1352 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1353 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001354 {
1355 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001356 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001357 }
cristy4a3ce0a2013-08-03 20:06:59 +00001358 break;
1359 }
1360 case 'D':
1361 case 'd':
1362 {
1363 if (LocaleCompare(attribute,"debug") == 0)
1364 {
1365 SetLogEventMask(SvPV(sval,na));
1366 break;
1367 }
1368 if (LocaleCompare(attribute,"delay") == 0)
1369 {
1370 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1371 for ( ; image; image=image->next)
1372 {
1373 image->delay=(size_t) floor(geometry_info.rho+0.5);
1374 if ((flags & SigmaValue) != 0)
1375 image->ticks_per_second=(ssize_t)
1376 floor(geometry_info.sigma+0.5);
1377 }
1378 break;
1379 }
1380 if (LocaleCompare(attribute,"disk-limit") == 0)
1381 {
1382 MagickSizeType
1383 limit;
1384
1385 limit=MagickResourceInfinity;
1386 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1387 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1388 100.0);
1389 (void) SetMagickResourceLimit(DiskResource,limit);
1390 break;
1391 }
1392 if (LocaleCompare(attribute,"density") == 0)
1393 {
1394 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1395 {
1396 ThrowPerlException(exception,OptionError,"MissingGeometry",
1397 SvPV(sval,na));
1398 break;
1399 }
1400 if (info)
1401 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1402 for ( ; image; image=image->next)
1403 {
1404 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1405 image->resolution.x=geometry_info.rho;
1406 image->resolution.y=geometry_info.sigma;
1407 if ((flags & SigmaValue) == 0)
1408 image->resolution.y=image->resolution.x;
1409 }
1410 break;
1411 }
1412 if (LocaleCompare(attribute,"depth") == 0)
1413 {
1414 if (info)
1415 info->image_info->depth=SvIV(sval);
1416 for ( ; image; image=image->next)
1417 (void) SetImageDepth(image,SvIV(sval),exception);
1418 break;
1419 }
1420 if (LocaleCompare(attribute,"dispose") == 0)
1421 {
1422 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1423 SvPV(sval,na)) : SvIV(sval);
1424 if (sp < 0)
1425 {
1426 ThrowPerlException(exception,OptionError,
1427 "UnrecognizedDisposeMethod",SvPV(sval,na));
1428 break;
1429 }
1430 for ( ; image; image=image->next)
1431 image->dispose=(DisposeType) sp;
1432 break;
1433 }
1434 if (LocaleCompare(attribute,"dither") == 0)
1435 {
1436 if (info)
1437 {
1438 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1439 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1440 if (sp < 0)
1441 {
1442 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1443 SvPV(sval,na));
1444 break;
1445 }
1446 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1447 }
1448 break;
1449 }
1450 if (LocaleCompare(attribute,"display") == 0)
1451 {
1452 display:
1453 if (info)
1454 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1455 break;
1456 }
1457 if (info)
1458 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1459 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001460 {
1461 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001462 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001463 }
cristy4a3ce0a2013-08-03 20:06:59 +00001464 break;
1465 }
1466 case 'E':
1467 case 'e':
1468 {
1469 if (LocaleCompare(attribute,"endian") == 0)
1470 {
1471 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1472 SvPV(sval,na)) : SvIV(sval);
1473 if (sp < 0)
1474 {
1475 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1476 SvPV(sval,na));
1477 break;
1478 }
1479 if (info)
1480 info->image_info->endian=(EndianType) sp;
1481 for ( ; image; image=image->next)
1482 image->endian=(EndianType) sp;
1483 break;
1484 }
1485 if (LocaleCompare(attribute,"extract") == 0)
1486 {
1487 /*
1488 Set image extract geometry.
1489 */
1490 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1491 break;
1492 }
1493 if (info)
1494 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1495 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001496 {
1497 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001498 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001499 }
cristy4a3ce0a2013-08-03 20:06:59 +00001500 break;
1501 }
1502 case 'F':
1503 case 'f':
1504 {
1505 if (LocaleCompare(attribute,"filename") == 0)
1506 {
1507 if (info)
1508 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001509 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001510 for ( ; image; image=image->next)
1511 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001512 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001513 break;
1514 }
1515 if (LocaleCompare(attribute,"file") == 0)
1516 {
1517 FILE
1518 *file;
1519
1520 PerlIO
1521 *io_info;
1522
1523 if (info == (struct PackageInfo *) NULL)
1524 break;
1525 io_info=IoIFP(sv_2io(sval));
1526 if (io_info == (PerlIO *) NULL)
1527 {
1528 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1529 PackageName);
1530 break;
1531 }
1532 file=PerlIO_findFILE(io_info);
1533 if (file == (FILE *) NULL)
1534 {
1535 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1536 PackageName);
1537 break;
1538 }
1539 SetImageInfoFile(info->image_info,file);
1540 break;
1541 }
1542 if (LocaleCompare(attribute,"fill") == 0)
1543 {
1544 if (info)
1545 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1546 break;
1547 }
1548 if (LocaleCompare(attribute,"font") == 0)
1549 {
1550 if (info)
1551 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1552 break;
1553 }
1554 if (LocaleCompare(attribute,"foreground") == 0)
1555 break;
1556 if (LocaleCompare(attribute,"fuzz") == 0)
1557 {
1558 if (info)
1559 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1560 QuantumRange+1.0);
1561 for ( ; image; image=image->next)
1562 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1563 QuantumRange+1.0);
1564 break;
1565 }
1566 if (info)
1567 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1568 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001569 {
1570 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001571 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001572 }
cristy4a3ce0a2013-08-03 20:06:59 +00001573 break;
1574 }
1575 case 'G':
1576 case 'g':
1577 {
1578 if (LocaleCompare(attribute,"gamma") == 0)
1579 {
1580 for ( ; image; image=image->next)
1581 image->gamma=SvNV(sval);
1582 break;
1583 }
1584 if (LocaleCompare(attribute,"gravity") == 0)
1585 {
1586 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1587 SvPV(sval,na)) : SvIV(sval);
1588 if (sp < 0)
1589 {
1590 ThrowPerlException(exception,OptionError,
1591 "UnrecognizedGravityType",SvPV(sval,na));
1592 break;
1593 }
1594 if (info)
1595 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1596 for ( ; image; image=image->next)
1597 image->gravity=(GravityType) sp;
1598 break;
1599 }
1600 if (LocaleCompare(attribute,"green-primary") == 0)
1601 {
1602 for ( ; image; image=image->next)
1603 {
1604 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1605 image->chromaticity.green_primary.x=geometry_info.rho;
1606 image->chromaticity.green_primary.y=geometry_info.sigma;
1607 if ((flags & SigmaValue) == 0)
1608 image->chromaticity.green_primary.y=
1609 image->chromaticity.green_primary.x;
1610 }
1611 break;
1612 }
1613 if (info)
1614 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1615 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001616 {
1617 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001618 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001619 }
cristy4a3ce0a2013-08-03 20:06:59 +00001620 break;
1621 }
1622 case 'I':
1623 case 'i':
1624 {
1625 if (LocaleNCompare(attribute,"index",5) == 0)
1626 {
1627 int
1628 items;
1629
1630 long
1631 index;
1632
1633 register Quantum
1634 *q;
1635
1636 CacheView
1637 *image_view;
1638
1639 for ( ; image; image=image->next)
1640 {
1641 if (image->storage_class != PseudoClass)
1642 continue;
1643 x=0;
1644 y=0;
1645 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1646 (void) items;
1647 image_view=AcquireAuthenticCacheView(image,exception);
1648 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1649 if (q != (Quantum *) NULL)
1650 {
1651 items=sscanf(SvPV(sval,na),"%ld",&index);
1652 if ((index >= 0) && (index < (ssize_t) image->colors))
1653 SetPixelIndex(image,index,q);
1654 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1655 }
1656 image_view=DestroyCacheView(image_view);
1657 }
1658 break;
1659 }
1660 if (LocaleCompare(attribute,"iterations") == 0)
1661 {
1662 iterations:
1663 for ( ; image; image=image->next)
1664 image->iterations=SvIV(sval);
1665 break;
1666 }
1667 if (LocaleCompare(attribute,"interlace") == 0)
1668 {
1669 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1670 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1671 if (sp < 0)
1672 {
1673 ThrowPerlException(exception,OptionError,
1674 "UnrecognizedInterlaceType",SvPV(sval,na));
1675 break;
1676 }
1677 if (info)
1678 info->image_info->interlace=(InterlaceType) sp;
1679 for ( ; image; image=image->next)
1680 image->interlace=(InterlaceType) sp;
1681 break;
1682 }
1683 if (info)
1684 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1685 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001686 {
1687 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001688 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001689 }
cristy4a3ce0a2013-08-03 20:06:59 +00001690 break;
1691 }
1692 case 'L':
1693 case 'l':
1694 {
1695 if (LocaleCompare(attribute,"label") == 0)
1696 {
1697 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001698 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001699 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001700 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001701 break;
1702 }
1703 if (LocaleCompare(attribute,"loop") == 0)
1704 goto iterations;
1705 if (info)
1706 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1707 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001708 {
1709 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001710 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001711 }
cristy4a3ce0a2013-08-03 20:06:59 +00001712 break;
1713 }
1714 case 'M':
1715 case 'm':
1716 {
1717 if (LocaleCompare(attribute,"magick") == 0)
1718 {
1719 if (info)
Cristyb5b1f5d2017-03-31 16:42:35 -04001720 (void) FormatLocaleString(info->image_info->filename,
1721 MagickPathExtent,"%s:",SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001722 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001723 (void) CopyMagickString(image->magick,SvPV(sval,na),
1724 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001725 break;
1726 }
1727 if (LocaleCompare(attribute,"map-limit") == 0)
1728 {
1729 MagickSizeType
1730 limit;
1731
1732 limit=MagickResourceInfinity;
1733 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1734 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1735 100.0);
1736 (void) SetMagickResourceLimit(MapResource,limit);
1737 break;
1738 }
1739 if (LocaleCompare(attribute,"mask") == 0)
1740 {
1741 Image
1742 *mask;
1743
1744 mask=(Image *) NULL;
1745 if (SvPOK(sval))
1746 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1747 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001748 SetImageMask(image,ReadPixelMask,mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001749 break;
1750 }
1751 if (LocaleCompare(attribute,"mattecolor") == 0)
1752 {
1753 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1754 exception);
1755 if (info)
Cristy8645e042016-02-03 16:35:29 -05001756 info->image_info->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001757 for ( ; image; image=image->next)
Cristy8645e042016-02-03 16:35:29 -05001758 image->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001759 break;
1760 }
1761 if (LocaleCompare(attribute,"matte") == 0)
1762 {
1763 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1764 SvPV(sval,na)) : SvIV(sval);
1765 if (sp < 0)
1766 {
1767 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1768 SvPV(sval,na));
1769 break;
1770 }
1771 for ( ; image; image=image->next)
1772 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1773 break;
1774 }
1775 if (LocaleCompare(attribute,"memory-limit") == 0)
1776 {
1777 MagickSizeType
1778 limit;
1779
1780 limit=MagickResourceInfinity;
1781 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1782 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1783 100.0);
1784 (void) SetMagickResourceLimit(MemoryResource,limit);
1785 break;
1786 }
1787 if (LocaleCompare(attribute,"monochrome") == 0)
1788 {
1789 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1790 SvPV(sval,na)) : SvIV(sval);
1791 if (sp < 0)
1792 {
1793 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1794 SvPV(sval,na));
1795 break;
1796 }
1797 if (info)
1798 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1799 for ( ; image; image=image->next)
1800 (void) SetImageType(image,BilevelType,exception);
1801 break;
1802 }
1803 if (info)
1804 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1805 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001806 {
1807 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001808 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001809 }
cristy4a3ce0a2013-08-03 20:06:59 +00001810 break;
1811 }
1812 case 'O':
1813 case 'o':
1814 {
1815 if (LocaleCompare(attribute,"option") == 0)
1816 {
1817 if (info)
1818 DefineImageOption(info->image_info,SvPV(sval,na));
1819 break;
1820 }
1821 if (LocaleCompare(attribute,"orientation") == 0)
1822 {
1823 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1824 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1825 if (sp < 0)
1826 {
1827 ThrowPerlException(exception,OptionError,
1828 "UnrecognizedOrientationType",SvPV(sval,na));
1829 break;
1830 }
1831 if (info)
1832 info->image_info->orientation=(OrientationType) sp;
1833 for ( ; image; image=image->next)
1834 image->orientation=(OrientationType) sp;
1835 break;
1836 }
1837 if (info)
1838 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1839 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001840 {
1841 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001842 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001843 }
cristy4a3ce0a2013-08-03 20:06:59 +00001844 break;
1845 }
1846 case 'P':
1847 case 'p':
1848 {
1849 if (LocaleCompare(attribute,"page") == 0)
1850 {
1851 char
1852 *geometry;
1853
1854 geometry=GetPageGeometry(SvPV(sval,na));
1855 if (info)
1856 (void) CloneString(&info->image_info->page,geometry);
1857 for ( ; image; image=image->next)
1858 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1859 geometry=(char *) RelinquishMagickMemory(geometry);
1860 break;
1861 }
1862 if (LocaleNCompare(attribute,"pixel",5) == 0)
1863 {
1864 int
1865 items;
1866
1867 PixelInfo
1868 pixel;
1869
1870 register Quantum
1871 *q;
1872
1873 CacheView
1874 *image_view;
1875
1876 for ( ; image; image=image->next)
1877 {
1878 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1879 break;
1880 x=0;
1881 y=0;
1882 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1883 (void) items;
1884 image_view=AcquireVirtualCacheView(image,exception);
1885 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1886 if (q != (Quantum *) NULL)
1887 {
1888 if ((strchr(SvPV(sval,na),',') == 0) ||
1889 (strchr(SvPV(sval,na),')') != 0))
1890 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1891 &pixel,exception);
1892 else
1893 {
1894 GetPixelInfo(image,&pixel);
1895 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1896 pixel.red=geometry_info.rho;
1897 if ((flags & SigmaValue) != 0)
1898 pixel.green=geometry_info.sigma;
1899 if ((flags & XiValue) != 0)
1900 pixel.blue=geometry_info.xi;
1901 if ((flags & PsiValue) != 0)
1902 pixel.alpha=geometry_info.psi;
1903 if ((flags & ChiValue) != 0)
1904 pixel.black=geometry_info.chi;
1905 }
1906 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1907 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1908 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1909 if (image->colorspace == CMYKColorspace)
1910 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1911 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1912 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1913 }
1914 image_view=DestroyCacheView(image_view);
1915 }
1916 break;
1917 }
1918 if (LocaleCompare(attribute,"pointsize") == 0)
1919 {
1920 if (info)
1921 {
1922 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1923 info->image_info->pointsize=geometry_info.rho;
1924 }
1925 break;
1926 }
Cristy798981a2020-02-17 12:07:15 -05001927 if (LocaleCompare(attribute,"precision") == 0)
1928 {
1929 (void) SetMagickPrecision(SvIV(sval));
1930 break;
1931 }
cristy4a3ce0a2013-08-03 20:06:59 +00001932 if (info)
1933 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1934 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001935 {
1936 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001937 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001938 }
cristy4a3ce0a2013-08-03 20:06:59 +00001939 break;
1940 }
1941 case 'Q':
1942 case 'q':
1943 {
1944 if (LocaleCompare(attribute,"quality") == 0)
1945 {
1946 if (info)
1947 info->image_info->quality=SvIV(sval);
1948 for ( ; image; image=image->next)
1949 image->quality=SvIV(sval);
1950 break;
1951 }
1952 if (info)
1953 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1954 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001955 {
1956 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001957 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001958 }
cristy4a3ce0a2013-08-03 20:06:59 +00001959 break;
1960 }
1961 case 'R':
1962 case 'r':
1963 {
cristyc0fe4752015-07-27 18:02:39 +00001964 if (LocaleCompare(attribute,"read-mask") == 0)
1965 {
1966 Image
1967 *mask;
1968
1969 mask=(Image *) NULL;
1970 if (SvPOK(sval))
1971 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1972 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001973 SetImageMask(image,ReadPixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00001974 break;
1975 }
cristy4a3ce0a2013-08-03 20:06:59 +00001976 if (LocaleCompare(attribute,"red-primary") == 0)
1977 {
1978 for ( ; image; image=image->next)
1979 {
1980 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1981 image->chromaticity.red_primary.x=geometry_info.rho;
1982 image->chromaticity.red_primary.y=geometry_info.sigma;
1983 if ((flags & SigmaValue) == 0)
1984 image->chromaticity.red_primary.y=
1985 image->chromaticity.red_primary.x;
1986 }
1987 break;
1988 }
1989 if (LocaleCompare(attribute,"render") == 0)
1990 {
1991 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1992 SvPV(sval,na)) : SvIV(sval);
1993 if (sp < 0)
1994 {
1995 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1996 SvPV(sval,na));
1997 break;
1998 }
1999 for ( ; image; image=image->next)
2000 image->rendering_intent=(RenderingIntent) sp;
2001 break;
2002 }
2003 if (LocaleCompare(attribute,"repage") == 0)
2004 {
2005 RectangleInfo
2006 geometry;
2007
2008 for ( ; image; image=image->next)
2009 {
2010 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
2011 if ((flags & WidthValue) != 0)
2012 {
2013 if ((flags & HeightValue) == 0)
2014 geometry.height=geometry.width;
2015 image->page.width=geometry.width;
2016 image->page.height=geometry.height;
2017 }
2018 if ((flags & AspectValue) != 0)
2019 {
2020 if ((flags & XValue) != 0)
2021 image->page.x+=geometry.x;
2022 if ((flags & YValue) != 0)
2023 image->page.y+=geometry.y;
2024 }
2025 else
2026 {
2027 if ((flags & XValue) != 0)
2028 {
2029 image->page.x=geometry.x;
2030 if (((flags & WidthValue) != 0) && (geometry.x > 0))
2031 image->page.width=image->columns+geometry.x;
2032 }
2033 if ((flags & YValue) != 0)
2034 {
2035 image->page.y=geometry.y;
2036 if (((flags & HeightValue) != 0) && (geometry.y > 0))
2037 image->page.height=image->rows+geometry.y;
2038 }
2039 }
2040 }
2041 break;
2042 }
2043 if (info)
2044 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2045 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002046 {
2047 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002048 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002049 }
cristy4a3ce0a2013-08-03 20:06:59 +00002050 break;
2051 }
2052 case 'S':
2053 case 's':
2054 {
2055 if (LocaleCompare(attribute,"sampling-factor") == 0)
2056 {
2057 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2058 {
2059 ThrowPerlException(exception,OptionError,"MissingGeometry",
2060 SvPV(sval,na));
2061 break;
2062 }
2063 if (info)
2064 (void) CloneString(&info->image_info->sampling_factor,
2065 SvPV(sval,na));
2066 break;
2067 }
2068 if (LocaleCompare(attribute,"scene") == 0)
2069 {
2070 for ( ; image; image=image->next)
2071 image->scene=SvIV(sval);
2072 break;
2073 }
2074 if (LocaleCompare(attribute,"server") == 0)
2075 goto display;
2076 if (LocaleCompare(attribute,"size") == 0)
2077 {
2078 if (info)
2079 {
2080 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2081 {
2082 ThrowPerlException(exception,OptionError,"MissingGeometry",
2083 SvPV(sval,na));
2084 break;
2085 }
2086 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2087 }
2088 break;
2089 }
2090 if (LocaleCompare(attribute,"stroke") == 0)
2091 {
2092 if (info)
2093 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2094 break;
2095 }
2096 if (info)
2097 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2098 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002099 {
2100 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002101 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002102 }
cristy4a3ce0a2013-08-03 20:06:59 +00002103 break;
2104 }
2105 case 'T':
2106 case 't':
2107 {
2108 if (LocaleCompare(attribute,"texture") == 0)
2109 {
2110 if (info)
2111 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2112 break;
2113 }
2114 if (LocaleCompare(attribute,"thread-limit") == 0)
2115 {
2116 MagickSizeType
2117 limit;
2118
2119 limit=MagickResourceInfinity;
2120 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2121 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2122 100.0);
2123 (void) SetMagickResourceLimit(ThreadResource,limit);
2124 break;
2125 }
2126 if (LocaleCompare(attribute,"tile-offset") == 0)
2127 {
2128 char
2129 *geometry;
2130
2131 geometry=GetPageGeometry(SvPV(sval,na));
2132 if (info)
2133 (void) CloneString(&info->image_info->page,geometry);
2134 for ( ; image; image=image->next)
2135 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2136 exception);
2137 geometry=(char *) RelinquishMagickMemory(geometry);
2138 break;
2139 }
2140 if (LocaleCompare(attribute,"time-limit") == 0)
2141 {
2142 MagickSizeType
2143 limit;
2144
2145 limit=MagickResourceInfinity;
2146 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2147 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2148 100.0);
2149 (void) SetMagickResourceLimit(TimeResource,limit);
2150 break;
2151 }
2152 if (LocaleCompare(attribute,"transparent-color") == 0)
2153 {
2154 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2155 exception);
2156 if (info)
2157 info->image_info->transparent_color=target_color;
2158 for ( ; image; image=image->next)
2159 image->transparent_color=target_color;
2160 break;
2161 }
2162 if (LocaleCompare(attribute,"type") == 0)
2163 {
2164 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2165 SvPV(sval,na)) : SvIV(sval);
2166 if (sp < 0)
2167 {
2168 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2169 SvPV(sval,na));
2170 break;
2171 }
2172 if (info)
2173 info->image_info->type=(ImageType) sp;
2174 for ( ; image; image=image->next)
2175 SetImageType(image,(ImageType) sp,exception);
2176 break;
2177 }
2178 if (info)
2179 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2180 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002181 {
2182 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002183 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002184 }
cristy4a3ce0a2013-08-03 20:06:59 +00002185 break;
2186 }
2187 case 'U':
2188 case 'u':
2189 {
2190 if (LocaleCompare(attribute,"units") == 0)
2191 {
2192 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2193 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2194 if (sp < 0)
2195 {
2196 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2197 SvPV(sval,na));
2198 break;
2199 }
2200 if (info)
2201 info->image_info->units=(ResolutionType) sp;
2202 for ( ; image; image=image->next)
2203 {
2204 ResolutionType
2205 units;
2206
2207 units=(ResolutionType) sp;
2208 if (image->units != units)
2209 switch (image->units)
2210 {
2211 case UndefinedResolution:
2212 case PixelsPerInchResolution:
2213 {
2214 if (units == PixelsPerCentimeterResolution)
2215 {
2216 image->resolution.x*=2.54;
2217 image->resolution.y*=2.54;
2218 }
2219 break;
2220 }
2221 case PixelsPerCentimeterResolution:
2222 {
2223 if (units == PixelsPerInchResolution)
2224 {
2225 image->resolution.x/=2.54;
2226 image->resolution.y/=2.54;
2227 }
2228 break;
2229 }
2230 }
2231 image->units=units;
2232 }
2233 break;
2234 }
2235 if (info)
2236 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2237 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002238 {
2239 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002240 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002241 }
cristy4a3ce0a2013-08-03 20:06:59 +00002242 break;
2243 }
2244 case 'V':
2245 case 'v':
2246 {
2247 if (LocaleCompare(attribute,"verbose") == 0)
2248 {
2249 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2250 SvPV(sval,na)) : SvIV(sval);
2251 if (sp < 0)
2252 {
2253 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2254 SvPV(sval,na));
2255 break;
2256 }
2257 if (info)
2258 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2259 break;
2260 }
cristy4a3ce0a2013-08-03 20:06:59 +00002261 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2262 {
2263 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2264 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2265 if (sp < 0)
2266 {
2267 ThrowPerlException(exception,OptionError,
2268 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2269 break;
2270 }
2271 for ( ; image; image=image->next)
2272 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2273 break;
2274 }
2275 if (info)
2276 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2277 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002278 {
2279 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002280 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002281 }
cristy4a3ce0a2013-08-03 20:06:59 +00002282 break;
2283 }
2284 case 'W':
2285 case 'w':
2286 {
2287 if (LocaleCompare(attribute,"white-point") == 0)
2288 {
2289 for ( ; image; image=image->next)
2290 {
2291 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2292 image->chromaticity.white_point.x=geometry_info.rho;
2293 image->chromaticity.white_point.y=geometry_info.sigma;
2294 if ((flags & SigmaValue) == 0)
2295 image->chromaticity.white_point.y=
2296 image->chromaticity.white_point.x;
2297 }
2298 break;
2299 }
cristyc0fe4752015-07-27 18:02:39 +00002300 if (LocaleCompare(attribute,"write-mask") == 0)
2301 {
2302 Image
2303 *mask;
2304
2305 mask=(Image *) NULL;
2306 if (SvPOK(sval))
2307 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2308 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002309 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002310 break;
2311 }
cristy4a3ce0a2013-08-03 20:06:59 +00002312 if (info)
2313 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2314 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002315 {
2316 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002317 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002318 }
cristy4a3ce0a2013-08-03 20:06:59 +00002319 break;
2320 }
2321 default:
2322 {
2323 if (info)
2324 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2325 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002326 {
2327 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002328 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002329 }
cristy4a3ce0a2013-08-03 20:06:59 +00002330 break;
2331 }
2332 }
2333}
2334
2335/*
2336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2337% %
2338% %
2339% %
2340% S e t u p L i s t %
2341% %
2342% %
2343% %
2344%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2345%
2346% Method SetupList returns the list of all the images linked by their
2347% image->next and image->previous link lists for use with ImageMagick. If
2348% info is non-NULL, an info structure is returned in *info. If
2349% reference_vector is non-NULL,an array of SV* are returned in
2350% *reference_vector. Reference_vector is used when the images are going to be
2351% replaced with new Image*'s.
2352%
2353% The format of the SetupList routine is:
2354%
2355% Image *SetupList(SV *reference,struct PackageInfo **info,
2356% SV ***reference_vector,ExceptionInfo *exception)
2357%
2358% A description of each parameter follows:
2359%
2360% o list: a list of strings.
2361%
2362% o string: a character string.
2363%
2364% o exception: Return any errors or warnings in this structure.
2365%
2366*/
2367static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2368 SV ***reference_vector,ExceptionInfo *exception)
2369{
2370 Image
2371 *image;
2372
2373 ssize_t
2374 current,
2375 last;
2376
2377 if (reference_vector)
2378 *reference_vector=NULL;
2379 if (info)
2380 *info=NULL;
2381 current=0;
2382 last=0;
2383 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2384 if (info && (SvTYPE(reference) == SVt_PVAV))
2385 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2386 exception);
2387 return(image);
2388}
2389
2390/*
2391%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2392% %
2393% %
2394% %
2395% s t r E Q c a s e %
2396% %
2397% %
2398% %
2399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2400%
2401% strEQcase() compares two strings and returns 0 if they are the
2402% same or if the second string runs out first. The comparison is case
2403% insensitive.
2404%
2405% The format of the strEQcase routine is:
2406%
2407% ssize_t strEQcase(const char *p,const char *q)
2408%
2409% A description of each parameter follows:
2410%
2411% o p: a character string.
2412%
2413% o q: a character string.
2414%
2415%
2416*/
2417static ssize_t strEQcase(const char *p,const char *q)
2418{
2419 char
2420 c;
2421
2422 register ssize_t
2423 i;
2424
2425 for (i=0 ; (c=(*q)) != 0; i++)
2426 {
2427 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2428 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2429 return(0);
2430 p++;
2431 q++;
2432 }
2433 return(((*q == 0) && (*p == 0)) ? i : 0);
2434}
2435
2436/*
2437%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2438% %
2439% %
2440% %
2441% I m a g e : : M a g i c k %
2442% %
2443% %
2444% %
2445%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2446%
2447%
2448*/
2449MODULE = Image::Magick PACKAGE = Image::Magick
2450
2451PROTOTYPES: ENABLE
2452
2453BOOT:
2454 MagickCoreGenesis("PerlMagick",MagickFalse);
2455 SetWarningHandler(NULL);
2456 SetErrorHandler(NULL);
2457 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2458 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2459
2460void
2461UNLOAD()
2462 PPCODE:
2463 {
2464 if (magick_registry != (SplayTreeInfo *) NULL)
2465 magick_registry=DestroySplayTree(magick_registry);
2466 MagickCoreTerminus();
2467 }
2468
2469double
2470constant(name,argument)
2471 char *name
2472 ssize_t argument
2473
2474#
2475###############################################################################
2476# #
2477# #
2478# #
2479# A n i m a t e #
2480# #
2481# #
2482# #
2483###############################################################################
2484#
2485#
2486void
2487Animate(ref,...)
2488 Image::Magick ref=NO_INIT
2489 ALIAS:
2490 AnimateImage = 1
2491 animate = 2
2492 animateimage = 3
2493 PPCODE:
2494 {
2495 ExceptionInfo
2496 *exception;
2497
2498 Image
2499 *image;
2500
2501 register ssize_t
2502 i;
2503
2504 struct PackageInfo
2505 *info,
2506 *package_info;
2507
2508 SV
2509 *perl_exception,
2510 *reference;
2511
2512 PERL_UNUSED_VAR(ref);
2513 PERL_UNUSED_VAR(ix);
2514 exception=AcquireExceptionInfo();
2515 perl_exception=newSVpv("",0);
2516 package_info=(struct PackageInfo *) NULL;
2517 if (sv_isobject(ST(0)) == 0)
2518 {
2519 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2520 PackageName);
2521 goto PerlException;
2522 }
2523 reference=SvRV(ST(0));
2524 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2525 if (image == (Image *) NULL)
2526 {
2527 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2528 PackageName);
2529 goto PerlException;
2530 }
2531 package_info=ClonePackageInfo(info,exception);
2532 if (items == 2)
2533 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2534 else
2535 if (items > 2)
2536 for (i=2; i < items; i+=2)
2537 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2538 exception);
2539 (void) AnimateImages(package_info->image_info,image,exception);
2540 (void) CatchImageException(image);
2541
2542 PerlException:
2543 if (package_info != (struct PackageInfo *) NULL)
2544 DestroyPackageInfo(package_info);
2545 InheritPerlException(exception,perl_exception);
2546 exception=DestroyExceptionInfo(exception);
2547 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2548 SvPOK_on(perl_exception);
2549 ST(0)=sv_2mortal(perl_exception);
2550 XSRETURN(1);
2551 }
2552
2553#
2554###############################################################################
2555# #
2556# #
2557# #
2558# A p p e n d #
2559# #
2560# #
2561# #
2562###############################################################################
2563#
2564#
2565void
2566Append(ref,...)
2567 Image::Magick ref=NO_INIT
2568 ALIAS:
2569 AppendImage = 1
2570 append = 2
2571 appendimage = 3
2572 PPCODE:
2573 {
2574 AV
2575 *av;
2576
2577 char
2578 *attribute;
2579
2580 ExceptionInfo
2581 *exception;
2582
2583 HV
2584 *hv;
2585
2586 Image
2587 *image;
2588
2589 register ssize_t
2590 i;
2591
2592 ssize_t
2593 stack;
2594
2595 struct PackageInfo
2596 *info;
2597
2598 SV
2599 *av_reference,
2600 *perl_exception,
2601 *reference,
2602 *rv,
2603 *sv;
2604
2605 PERL_UNUSED_VAR(ref);
2606 PERL_UNUSED_VAR(ix);
2607 exception=AcquireExceptionInfo();
2608 perl_exception=newSVpv("",0);
2609 sv=NULL;
2610 attribute=NULL;
2611 av=NULL;
2612 if (sv_isobject(ST(0)) == 0)
2613 {
2614 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2615 PackageName);
2616 goto PerlException;
2617 }
2618 reference=SvRV(ST(0));
2619 hv=SvSTASH(reference);
2620 av=newAV();
2621 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2622 SvREFCNT_dec(av);
2623 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2624 if (image == (Image *) NULL)
2625 {
2626 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2627 PackageName);
2628 goto PerlException;
2629 }
2630 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2631 /*
2632 Get options.
2633 */
2634 stack=MagickTrue;
2635 for (i=2; i < items; i+=2)
2636 {
2637 attribute=(char *) SvPV(ST(i-1),na);
2638 switch (*attribute)
2639 {
2640 case 'S':
2641 case 's':
2642 {
2643 if (LocaleCompare(attribute,"stack") == 0)
2644 {
2645 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2646 SvPV(ST(i),na));
2647 if (stack < 0)
2648 {
2649 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2650 SvPV(ST(i),na));
2651 return;
2652 }
2653 break;
2654 }
2655 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2656 attribute);
2657 break;
2658 }
2659 default:
2660 {
2661 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2662 attribute);
2663 break;
2664 }
2665 }
2666 }
2667 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2668 if (image == (Image *) NULL)
2669 goto PerlException;
2670 for ( ; image; image=image->next)
2671 {
2672 AddImageToRegistry(sv,image);
2673 rv=newRV(sv);
2674 av_push(av,sv_bless(rv,hv));
2675 SvREFCNT_dec(sv);
2676 }
2677 exception=DestroyExceptionInfo(exception);
2678 ST(0)=av_reference;
2679 SvREFCNT_dec(perl_exception);
2680 XSRETURN(1);
2681
2682 PerlException:
2683 InheritPerlException(exception,perl_exception);
2684 exception=DestroyExceptionInfo(exception);
2685 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2686 SvPOK_on(perl_exception);
2687 ST(0)=sv_2mortal(perl_exception);
2688 XSRETURN(1);
2689 }
2690
2691#
2692###############################################################################
2693# #
2694# #
2695# #
2696# A v e r a g e #
2697# #
2698# #
2699# #
2700###############################################################################
2701#
2702#
2703void
2704Average(ref)
2705 Image::Magick ref=NO_INIT
2706 ALIAS:
2707 AverageImage = 1
2708 average = 2
2709 averageimage = 3
2710 PPCODE:
2711 {
2712 AV
2713 *av;
2714
2715 char
2716 *p;
2717
2718 ExceptionInfo
2719 *exception;
2720
2721 HV
2722 *hv;
2723
2724 Image
2725 *image;
2726
2727 struct PackageInfo
2728 *info;
2729
2730 SV
2731 *perl_exception,
2732 *reference,
2733 *rv,
2734 *sv;
2735
2736 PERL_UNUSED_VAR(ref);
2737 PERL_UNUSED_VAR(ix);
2738 exception=AcquireExceptionInfo();
2739 perl_exception=newSVpv("",0);
2740 sv=NULL;
2741 if (sv_isobject(ST(0)) == 0)
2742 {
2743 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2744 PackageName);
2745 goto PerlException;
2746 }
2747 reference=SvRV(ST(0));
2748 hv=SvSTASH(reference);
2749 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2750 if (image == (Image *) NULL)
2751 {
2752 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2753 PackageName);
2754 goto PerlException;
2755 }
2756 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2757 if (image == (Image *) NULL)
2758 goto PerlException;
2759 /*
2760 Create blessed Perl array for the returned image.
2761 */
2762 av=newAV();
2763 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2764 SvREFCNT_dec(av);
2765 AddImageToRegistry(sv,image);
2766 rv=newRV(sv);
2767 av_push(av,sv_bless(rv,hv));
2768 SvREFCNT_dec(sv);
2769 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002770 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2771 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002772 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2773 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002774 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002775 SetImageInfo(info->image_info,0,exception);
2776 exception=DestroyExceptionInfo(exception);
2777 SvREFCNT_dec(perl_exception);
2778 XSRETURN(1);
2779
2780 PerlException:
2781 InheritPerlException(exception,perl_exception);
2782 exception=DestroyExceptionInfo(exception);
2783 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2784 SvPOK_on(perl_exception);
2785 ST(0)=sv_2mortal(perl_exception);
2786 XSRETURN(1);
2787 }
2788
2789#
2790###############################################################################
2791# #
2792# #
2793# #
2794# B l o b T o I m a g e #
2795# #
2796# #
2797# #
2798###############################################################################
2799#
2800#
2801void
2802BlobToImage(ref,...)
2803 Image::Magick ref=NO_INIT
2804 ALIAS:
2805 BlobToImage = 1
2806 blobtoimage = 2
2807 blobto = 3
2808 PPCODE:
2809 {
2810 AV
2811 *av;
2812
2813 char
2814 **keep,
2815 **list;
2816
2817 ExceptionInfo
2818 *exception;
2819
2820 HV
2821 *hv;
2822
2823 Image
2824 *image;
2825
2826 register char
2827 **p;
2828
2829 register ssize_t
2830 i;
2831
2832 ssize_t
2833 ac,
2834 n,
2835 number_images;
2836
2837 STRLEN
2838 *length;
2839
2840 struct PackageInfo
2841 *info;
2842
2843 SV
2844 *perl_exception,
2845 *reference,
2846 *rv,
2847 *sv;
2848
2849 PERL_UNUSED_VAR(ref);
2850 PERL_UNUSED_VAR(ix);
2851 exception=AcquireExceptionInfo();
2852 perl_exception=newSVpv("",0);
2853 sv=NULL;
2854 number_images=0;
2855 ac=(items < 2) ? 1 : items-1;
2856 length=(STRLEN *) NULL;
2857 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2858 if (list == (char **) NULL)
2859 {
2860 ThrowPerlException(exception,ResourceLimitError,
2861 "MemoryAllocationFailed",PackageName);
2862 goto PerlException;
2863 }
2864 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2865 if (length == (STRLEN *) NULL)
2866 {
2867 ThrowPerlException(exception,ResourceLimitError,
2868 "MemoryAllocationFailed",PackageName);
2869 goto PerlException;
2870 }
2871 if (sv_isobject(ST(0)) == 0)
2872 {
2873 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2874 PackageName);
2875 goto PerlException;
2876 }
2877 reference=SvRV(ST(0));
2878 hv=SvSTASH(reference);
2879 if (SvTYPE(reference) != SVt_PVAV)
2880 {
2881 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2882 PackageName);
2883 goto PerlException;
2884 }
2885 av=(AV *) reference;
2886 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2887 exception);
2888 n=1;
2889 if (items <= 1)
2890 {
2891 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2892 goto PerlException;
2893 }
2894 for (n=0, i=0; i < ac; i++)
2895 {
2896 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2897 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2898 {
2899 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2900 continue;
2901 }
2902 n++;
2903 }
2904 list[n]=(char *) NULL;
2905 keep=list;
2906 for (i=number_images=0; i < n; i++)
2907 {
2908 image=BlobToImage(info->image_info,list[i],length[i],exception);
2909 if (image == (Image *) NULL)
2910 break;
2911 for ( ; image; image=image->next)
2912 {
2913 AddImageToRegistry(sv,image);
2914 rv=newRV(sv);
2915 av_push(av,sv_bless(rv,hv));
2916 SvREFCNT_dec(sv);
2917 number_images++;
2918 }
2919 }
2920 /*
2921 Free resources.
2922 */
2923 for (i=0; i < n; i++)
2924 if (list[i] != (char *) NULL)
2925 for (p=keep; list[i] != *p++; )
2926 if (*p == (char *) NULL)
2927 {
2928 list[i]=(char *) RelinquishMagickMemory(list[i]);
2929 break;
2930 }
2931
2932 PerlException:
2933 if (list)
2934 list=(char **) RelinquishMagickMemory(list);
2935 if (length)
2936 length=(STRLEN *) RelinquishMagickMemory(length);
2937 InheritPerlException(exception,perl_exception);
2938 exception=DestroyExceptionInfo(exception);
2939 sv_setiv(perl_exception,(IV) number_images);
2940 SvPOK_on(perl_exception);
2941 ST(0)=sv_2mortal(perl_exception);
2942 XSRETURN(1);
2943 }
2944
2945#
2946###############################################################################
2947# #
2948# #
2949# #
2950# C h a n n e l F x #
2951# #
2952# #
2953# #
2954###############################################################################
2955#
2956#
2957void
2958ChannelFx(ref,...)
2959 Image::Magick ref=NO_INIT
2960 ALIAS:
2961 ChannelFxImage = 1
2962 channelfx = 2
2963 channelfximage = 3
2964 PPCODE:
2965 {
2966 AV
2967 *av;
2968
2969 char
2970 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002971 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002972
2973 ChannelType
2974 channel,
2975 channel_mask;
2976
2977 ExceptionInfo
2978 *exception;
2979
2980 HV
2981 *hv;
2982
2983 Image
2984 *image;
2985
2986 register ssize_t
2987 i;
2988
2989 struct PackageInfo
2990 *info;
2991
2992 SV
2993 *av_reference,
2994 *perl_exception,
2995 *reference,
2996 *rv,
2997 *sv;
2998
2999 PERL_UNUSED_VAR(ref);
3000 PERL_UNUSED_VAR(ix);
3001 exception=AcquireExceptionInfo();
3002 perl_exception=newSVpv("",0);
3003 sv=NULL;
3004 attribute=NULL;
3005 av=NULL;
3006 if (sv_isobject(ST(0)) == 0)
3007 {
3008 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3009 PackageName);
3010 goto PerlException;
3011 }
3012 reference=SvRV(ST(0));
3013 hv=SvSTASH(reference);
3014 av=newAV();
3015 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3016 SvREFCNT_dec(av);
3017 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3018 if (image == (Image *) NULL)
3019 {
3020 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3021 PackageName);
3022 goto PerlException;
3023 }
3024 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3025 /*
3026 Get options.
3027 */
3028 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00003029 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003030 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00003031 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003032 else
3033 for (i=2; i < items; i+=2)
3034 {
3035 attribute=(char *) SvPV(ST(i-1),na);
3036 switch (*attribute)
3037 {
3038 case 'C':
3039 case 'c':
3040 {
3041 if (LocaleCompare(attribute,"channel") == 0)
3042 {
3043 ssize_t
3044 option;
3045
3046 option=ParseChannelOption(SvPV(ST(i),na));
3047 if (option < 0)
3048 {
3049 ThrowPerlException(exception,OptionError,
3050 "UnrecognizedType",SvPV(ST(i),na));
3051 return;
3052 }
3053 channel=(ChannelType) option;
3054 break;
3055 }
3056 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3057 attribute);
3058 break;
3059 }
3060 case 'E':
3061 case 'e':
3062 {
3063 if (LocaleCompare(attribute,"expression") == 0)
3064 {
3065 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00003066 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003067 break;
3068 }
3069 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3070 attribute);
3071 break;
3072 }
3073 default:
3074 {
3075 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3076 attribute);
3077 break;
3078 }
3079 }
3080 }
3081 channel_mask=SetImageChannelMask(image,channel);
3082 image=ChannelFxImage(image,expression,exception);
3083 if (image != (Image *) NULL)
3084 (void) SetImageChannelMask(image,channel_mask);
3085 if (image == (Image *) NULL)
3086 goto PerlException;
3087 for ( ; image; image=image->next)
3088 {
3089 AddImageToRegistry(sv,image);
3090 rv=newRV(sv);
3091 av_push(av,sv_bless(rv,hv));
3092 SvREFCNT_dec(sv);
3093 }
3094 exception=DestroyExceptionInfo(exception);
3095 ST(0)=av_reference;
3096 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3097 XSRETURN(1);
3098
3099 PerlException:
3100 InheritPerlException(exception,perl_exception);
3101 exception=DestroyExceptionInfo(exception);
3102 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3103 SvPOK_on(perl_exception);
3104 ST(0)=sv_2mortal(perl_exception);
3105 XSRETURN(1);
3106 }
3107
3108#
3109###############################################################################
3110# #
3111# #
3112# #
3113# C l o n e #
3114# #
3115# #
3116# #
3117###############################################################################
3118#
3119#
3120void
3121Clone(ref)
3122 Image::Magick ref=NO_INIT
3123 ALIAS:
3124 CopyImage = 1
3125 copy = 2
3126 copyimage = 3
3127 CloneImage = 4
3128 clone = 5
3129 cloneimage = 6
3130 Clone = 7
3131 PPCODE:
3132 {
3133 AV
3134 *av;
3135
3136 ExceptionInfo
3137 *exception;
3138
3139 HV
3140 *hv;
3141
3142 Image
3143 *clone,
3144 *image;
3145
3146 struct PackageInfo
3147 *info;
3148
3149 SV
3150 *perl_exception,
3151 *reference,
3152 *rv,
3153 *sv;
3154
3155 PERL_UNUSED_VAR(ref);
3156 PERL_UNUSED_VAR(ix);
3157 exception=AcquireExceptionInfo();
3158 perl_exception=newSVpv("",0);
3159 sv=NULL;
3160 if (sv_isobject(ST(0)) == 0)
3161 {
3162 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3163 PackageName);
3164 goto PerlException;
3165 }
3166 reference=SvRV(ST(0));
3167 hv=SvSTASH(reference);
3168 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3169 if (image == (Image *) NULL)
3170 {
3171 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3172 PackageName);
3173 goto PerlException;
3174 }
3175 /*
3176 Create blessed Perl array for the returned image.
3177 */
3178 av=newAV();
3179 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3180 SvREFCNT_dec(av);
3181 for ( ; image; image=image->next)
3182 {
3183 clone=CloneImage(image,0,0,MagickTrue,exception);
3184 if (clone == (Image *) NULL)
3185 break;
3186 AddImageToRegistry(sv,clone);
3187 rv=newRV(sv);
3188 av_push(av,sv_bless(rv,hv));
3189 SvREFCNT_dec(sv);
3190 }
3191 exception=DestroyExceptionInfo(exception);
3192 SvREFCNT_dec(perl_exception);
3193 XSRETURN(1);
3194
3195 PerlException:
3196 InheritPerlException(exception,perl_exception);
3197 exception=DestroyExceptionInfo(exception);
3198 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3199 SvPOK_on(perl_exception);
3200 ST(0)=sv_2mortal(perl_exception);
3201 XSRETURN(1);
3202 }
3203
3204#
3205###############################################################################
3206# #
3207# #
3208# #
3209# C L O N E #
3210# #
3211# #
3212# #
3213###############################################################################
3214#
3215#
3216void
3217CLONE(ref,...)
3218 SV *ref;
3219 CODE:
3220 {
3221 PERL_UNUSED_VAR(ref);
3222 if (magick_registry != (SplayTreeInfo *) NULL)
3223 {
3224 register Image
3225 *p;
3226
3227 ResetSplayTreeIterator(magick_registry);
3228 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3229 while (p != (Image *) NULL)
3230 {
3231 ReferenceImage(p);
3232 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3233 }
3234 }
3235 }
3236
3237#
3238###############################################################################
3239# #
3240# #
3241# #
3242# C o a l e s c e #
3243# #
3244# #
3245# #
3246###############################################################################
3247#
3248#
3249void
3250Coalesce(ref)
3251 Image::Magick ref=NO_INIT
3252 ALIAS:
3253 CoalesceImage = 1
3254 coalesce = 2
3255 coalesceimage = 3
3256 PPCODE:
3257 {
3258 AV
3259 *av;
3260
3261 ExceptionInfo
3262 *exception;
3263
3264 HV
3265 *hv;
3266
3267 Image
3268 *image;
3269
3270 struct PackageInfo
3271 *info;
3272
3273 SV
3274 *av_reference,
3275 *perl_exception,
3276 *reference,
3277 *rv,
3278 *sv;
3279
3280 PERL_UNUSED_VAR(ref);
3281 PERL_UNUSED_VAR(ix);
3282 exception=AcquireExceptionInfo();
3283 perl_exception=newSVpv("",0);
3284 sv=NULL;
3285 if (sv_isobject(ST(0)) == 0)
3286 {
3287 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3288 PackageName);
3289 goto PerlException;
3290 }
3291 reference=SvRV(ST(0));
3292 hv=SvSTASH(reference);
3293 av=newAV();
3294 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3295 SvREFCNT_dec(av);
3296 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3297 if (image == (Image *) NULL)
3298 {
3299 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3300 PackageName);
3301 goto PerlException;
3302 }
3303 image=CoalesceImages(image,exception);
3304 if (image == (Image *) NULL)
3305 goto PerlException;
3306 for ( ; image; image=image->next)
3307 {
3308 AddImageToRegistry(sv,image);
3309 rv=newRV(sv);
3310 av_push(av,sv_bless(rv,hv));
3311 SvREFCNT_dec(sv);
3312 }
3313 exception=DestroyExceptionInfo(exception);
3314 ST(0)=av_reference;
3315 SvREFCNT_dec(perl_exception);
3316 XSRETURN(1);
3317
3318 PerlException:
3319 InheritPerlException(exception,perl_exception);
3320 exception=DestroyExceptionInfo(exception);
3321 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3322 SvPOK_on(perl_exception);
3323 ST(0)=sv_2mortal(perl_exception);
3324 XSRETURN(1);
3325 }
3326
3327#
3328###############################################################################
3329# #
3330# #
3331# #
3332# C o m p a r e #
3333# #
3334# #
3335# #
3336###############################################################################
3337#
3338#
3339void
3340Compare(ref,...)
3341 Image::Magick ref=NO_INIT
3342 ALIAS:
3343 CompareImages = 1
3344 compare = 2
3345 compareimage = 3
3346 PPCODE:
3347 {
3348 AV
3349 *av;
3350
3351 char
3352 *attribute;
3353
3354 double
3355 distortion;
3356
3357 ExceptionInfo
3358 *exception;
3359
3360 HV
3361 *hv;
3362
3363 Image
3364 *difference_image,
3365 *image,
3366 *reconstruct_image;
3367
3368 MetricType
3369 metric;
3370
3371 register ssize_t
3372 i;
3373
3374 ssize_t
3375 option;
3376
3377 struct PackageInfo
3378 *info;
3379
3380 SV
3381 *av_reference,
3382 *perl_exception,
3383 *reference,
3384 *rv,
3385 *sv;
3386
3387 PERL_UNUSED_VAR(ref);
3388 PERL_UNUSED_VAR(ix);
3389 exception=AcquireExceptionInfo();
3390 perl_exception=newSVpv("",0);
3391 sv=NULL;
3392 av=NULL;
3393 attribute=NULL;
3394 if (sv_isobject(ST(0)) == 0)
3395 {
3396 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3397 PackageName);
3398 goto PerlException;
3399 }
3400 reference=SvRV(ST(0));
3401 hv=SvSTASH(reference);
3402 av=newAV();
3403 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3404 SvREFCNT_dec(av);
3405 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3406 if (image == (Image *) NULL)
3407 {
3408 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3409 PackageName);
3410 goto PerlException;
3411 }
3412 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3413 /*
3414 Get attribute.
3415 */
3416 reconstruct_image=image;
3417 metric=RootMeanSquaredErrorMetric;
3418 for (i=2; i < items; i+=2)
3419 {
3420 attribute=(char *) SvPV(ST(i-1),na);
3421 switch (*attribute)
3422 {
3423 case 'C':
3424 case 'c':
3425 {
3426 if (LocaleCompare(attribute,"channel") == 0)
3427 {
3428 ssize_t
3429 option;
3430
3431 option=ParseChannelOption(SvPV(ST(i),na));
3432 if (option < 0)
3433 {
3434 ThrowPerlException(exception,OptionError,
3435 "UnrecognizedType",SvPV(ST(i),na));
3436 return;
3437 }
cristybcd59342015-06-07 14:07:19 +00003438 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003439 break;
3440 }
3441 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3442 attribute);
3443 break;
3444 }
3445 case 'F':
3446 case 'f':
3447 {
3448 if (LocaleCompare(attribute,"fuzz") == 0)
3449 {
3450 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3451 break;
3452 }
3453 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3454 attribute);
3455 break;
3456 }
3457 case 'I':
3458 case 'i':
3459 {
3460 if (LocaleCompare(attribute,"image") == 0)
3461 {
3462 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3463 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3464 break;
3465 }
3466 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3467 attribute);
3468 break;
3469 }
3470 case 'M':
3471 case 'm':
3472 {
3473 if (LocaleCompare(attribute,"metric") == 0)
3474 {
3475 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3476 SvPV(ST(i),na));
3477 if (option < 0)
3478 {
3479 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3480 SvPV(ST(i),na));
3481 break;
3482 }
3483 metric=(MetricType) option;
3484 break;
3485 }
3486 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3487 attribute);
3488 break;
3489 }
3490 default:
3491 {
3492 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3493 attribute);
3494 break;
3495 }
3496 }
3497 }
3498 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3499 exception);
3500 if (difference_image != (Image *) NULL)
3501 {
3502 difference_image->error.mean_error_per_pixel=distortion;
3503 AddImageToRegistry(sv,difference_image);
3504 rv=newRV(sv);
3505 av_push(av,sv_bless(rv,hv));
3506 SvREFCNT_dec(sv);
3507 }
3508 exception=DestroyExceptionInfo(exception);
3509 ST(0)=av_reference;
3510 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3511 XSRETURN(1);
3512
3513 PerlException:
3514 InheritPerlException(exception,perl_exception);
3515 exception=DestroyExceptionInfo(exception);
3516 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3517 SvPOK_on(perl_exception);
3518 ST(0)=sv_2mortal(perl_exception);
3519 XSRETURN(1);
3520 }
3521
3522#
3523###############################################################################
3524# #
3525# #
3526# #
cristy15655332013-10-06 00:27:33 +00003527# C o m p l e x I m a g e s #
3528# #
3529# #
3530# #
3531###############################################################################
3532#
3533#
3534void
3535ComplexImages(ref)
3536 Image::Magick ref=NO_INIT
3537 ALIAS:
3538 ComplexImages = 1
3539 compleximages = 2
3540 PPCODE:
3541 {
3542 AV
3543 *av;
3544
3545 char
3546 *attribute,
3547 *p;
3548
cristyfa21e9e2013-10-07 10:37:38 +00003549 ComplexOperator
3550 op;
3551
cristy15655332013-10-06 00:27:33 +00003552 ExceptionInfo
3553 *exception;
3554
3555 HV
3556 *hv;
3557
3558 Image
3559 *image;
3560
cristy15655332013-10-06 00:27:33 +00003561 register ssize_t
3562 i;
3563
3564 struct PackageInfo
3565 *info;
3566
3567 SV
3568 *perl_exception,
3569 *reference,
3570 *rv,
3571 *sv;
3572
3573 PERL_UNUSED_VAR(ref);
3574 PERL_UNUSED_VAR(ix);
3575 exception=AcquireExceptionInfo();
3576 perl_exception=newSVpv("",0);
3577 sv=NULL;
3578 if (sv_isobject(ST(0)) == 0)
3579 {
3580 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3581 PackageName);
3582 goto PerlException;
3583 }
3584 reference=SvRV(ST(0));
3585 hv=SvSTASH(reference);
3586 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3587 if (image == (Image *) NULL)
3588 {
3589 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3590 PackageName);
3591 goto PerlException;
3592 }
cristyfd168722013-10-07 15:59:31 +00003593 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003594 if (items == 2)
3595 {
3596 ssize_t
3597 in;
3598
3599 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3600 SvPV(ST(1),na));
3601 if (in < 0)
3602 {
3603 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3604 SvPV(ST(1),na));
3605 return;
3606 }
cristyfa21e9e2013-10-07 10:37:38 +00003607 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003608 }
3609 else
3610 for (i=2; i < items; i+=2)
3611 {
3612 attribute=(char *) SvPV(ST(i-1),na);
3613 switch (*attribute)
3614 {
3615 case 'O':
3616 case 'o':
3617 {
3618 if (LocaleCompare(attribute,"operator") == 0)
3619 {
3620 ssize_t
3621 in;
3622
3623 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3624 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3625 if (in < 0)
3626 {
3627 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3628 SvPV(ST(i),na));
3629 return;
3630 }
cristyfa21e9e2013-10-07 10:37:38 +00003631 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003632 break;
3633 }
3634 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3635 attribute);
3636 break;
3637 }
3638 default:
3639 {
3640 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3641 attribute);
3642 break;
3643 }
3644 }
3645 }
3646 image=ComplexImages(image,op,exception);
3647 if (image == (Image *) NULL)
3648 goto PerlException;
3649 /*
3650 Create blessed Perl array for the returned image.
3651 */
3652 av=newAV();
3653 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3654 SvREFCNT_dec(av);
3655 AddImageToRegistry(sv,image);
3656 rv=newRV(sv);
3657 av_push(av,sv_bless(rv,hv));
3658 SvREFCNT_dec(sv);
3659 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003660 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3661 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003662 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3663 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003664 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003665 SetImageInfo(info->image_info,0,exception);
3666 exception=DestroyExceptionInfo(exception);
3667 SvREFCNT_dec(perl_exception);
3668 XSRETURN(1);
3669
3670 PerlException:
3671 InheritPerlException(exception,perl_exception);
3672 exception=DestroyExceptionInfo(exception);
3673 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3674 SvPOK_on(perl_exception);
3675 ST(0)=sv_2mortal(perl_exception);
3676 XSRETURN(1);
3677 }
3678
3679#
3680###############################################################################
3681# #
3682# #
3683# #
cristy4a3ce0a2013-08-03 20:06:59 +00003684# C o m p a r e L a y e r s #
3685# #
3686# #
3687# #
3688###############################################################################
3689#
3690#
3691void
3692CompareLayers(ref)
3693 Image::Magick ref=NO_INIT
3694 ALIAS:
3695 CompareImagesLayers = 1
3696 comparelayers = 2
3697 compareimagelayers = 3
3698 PPCODE:
3699 {
3700 AV
3701 *av;
3702
3703 char
3704 *attribute;
3705
3706 ExceptionInfo
3707 *exception;
3708
3709 HV
3710 *hv;
3711
3712 Image
3713 *image;
3714
3715 LayerMethod
3716 method;
3717
3718 register ssize_t
3719 i;
3720
3721 ssize_t
3722 option;
3723
3724 struct PackageInfo
3725 *info;
3726
3727 SV
3728 *av_reference,
3729 *perl_exception,
3730 *reference,
3731 *rv,
3732 *sv;
3733
3734 PERL_UNUSED_VAR(ref);
3735 PERL_UNUSED_VAR(ix);
3736 exception=AcquireExceptionInfo();
3737 perl_exception=newSVpv("",0);
3738 sv=NULL;
3739 if (sv_isobject(ST(0)) == 0)
3740 {
3741 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3742 PackageName);
3743 goto PerlException;
3744 }
3745 reference=SvRV(ST(0));
3746 hv=SvSTASH(reference);
3747 av=newAV();
3748 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3749 SvREFCNT_dec(av);
3750 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3751 if (image == (Image *) NULL)
3752 {
3753 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3754 PackageName);
3755 goto PerlException;
3756 }
3757 method=CompareAnyLayer;
3758 for (i=2; i < items; i+=2)
3759 {
3760 attribute=(char *) SvPV(ST(i-1),na);
3761 switch (*attribute)
3762 {
3763 case 'M':
3764 case 'm':
3765 {
3766 if (LocaleCompare(attribute,"method") == 0)
3767 {
3768 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3769 SvPV(ST(i),na));
3770 if (option < 0)
3771 {
3772 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3773 SvPV(ST(i),na));
3774 break;
3775 }
3776 method=(LayerMethod) option;
3777 break;
3778 }
3779 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3780 attribute);
3781 break;
3782 }
3783 default:
3784 {
3785 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3786 attribute);
3787 break;
3788 }
3789 }
3790 }
3791 image=CompareImagesLayers(image,method,exception);
3792 if (image == (Image *) NULL)
3793 goto PerlException;
3794 for ( ; image; image=image->next)
3795 {
3796 AddImageToRegistry(sv,image);
3797 rv=newRV(sv);
3798 av_push(av,sv_bless(rv,hv));
3799 SvREFCNT_dec(sv);
3800 }
3801 exception=DestroyExceptionInfo(exception);
3802 ST(0)=av_reference;
3803 SvREFCNT_dec(perl_exception);
3804 XSRETURN(1);
3805
3806 PerlException:
3807 InheritPerlException(exception,perl_exception);
3808 exception=DestroyExceptionInfo(exception);
3809 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3810 SvPOK_on(perl_exception);
3811 ST(0)=sv_2mortal(perl_exception);
3812 XSRETURN(1);
3813 }
3814
3815#
3816###############################################################################
3817# #
3818# #
3819# #
3820# D e s t r o y #
3821# #
3822# #
3823# #
3824###############################################################################
3825#
3826#
3827void
3828DESTROY(ref)
3829 Image::Magick ref=NO_INIT
3830 PPCODE:
3831 {
3832 SV
3833 *reference;
3834
3835 PERL_UNUSED_VAR(ref);
3836 if (sv_isobject(ST(0)) == 0)
3837 croak("ReferenceIsNotMyType");
3838 reference=SvRV(ST(0));
3839 switch (SvTYPE(reference))
3840 {
3841 case SVt_PVAV:
3842 {
3843 char
cristy151b66d2015-04-15 10:50:31 +00003844 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003845
3846 const SV
3847 *key;
3848
3849 HV
3850 *hv;
3851
3852 GV
3853 **gvp;
3854
3855 struct PackageInfo
3856 *info;
3857
3858 SV
3859 *sv;
3860
3861 /*
3862 Array (AV *) reference
3863 */
cristy151b66d2015-04-15 10:50:31 +00003864 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003865 XS_VERSION,reference);
3866 hv=gv_stashpv(PackageName, FALSE);
3867 if (!hv)
3868 break;
3869 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3870 if (!gvp)
3871 break;
3872 sv=GvSV(*gvp);
3873 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3874 {
3875 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3876 DestroyPackageInfo(info);
3877 }
3878 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3879 (void) key;
3880 break;
3881 }
3882 case SVt_PVMG:
3883 {
3884 Image
3885 *image;
3886
3887 /*
3888 Blessed scalar = (Image *) SvIV(reference)
3889 */
3890 image=INT2PTR(Image *,SvIV(reference));
3891 if (image != (Image *) NULL)
3892 DeleteImageFromRegistry(reference,image);
3893 break;
3894 }
3895 default:
3896 break;
3897 }
3898 }
3899
3900#
3901###############################################################################
3902# #
3903# #
3904# #
3905# D i s p l a y #
3906# #
3907# #
3908# #
3909###############################################################################
3910#
3911#
3912void
3913Display(ref,...)
3914 Image::Magick ref=NO_INIT
3915 ALIAS:
3916 DisplayImage = 1
3917 display = 2
3918 displayimage = 3
3919 PPCODE:
3920 {
3921 ExceptionInfo
3922 *exception;
3923
3924 Image
3925 *image;
3926
3927 register ssize_t
3928 i;
3929
3930 struct PackageInfo
3931 *info,
3932 *package_info;
3933
3934 SV
3935 *perl_exception,
3936 *reference;
3937
3938 PERL_UNUSED_VAR(ref);
3939 PERL_UNUSED_VAR(ix);
3940 exception=AcquireExceptionInfo();
3941 perl_exception=newSVpv("",0);
3942 package_info=(struct PackageInfo *) NULL;
3943 if (sv_isobject(ST(0)) == 0)
3944 {
3945 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3946 PackageName);
3947 goto PerlException;
3948 }
3949 reference=SvRV(ST(0));
3950 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3951 if (image == (Image *) NULL)
3952 {
3953 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3954 PackageName);
3955 goto PerlException;
3956 }
3957 package_info=ClonePackageInfo(info,exception);
3958 if (items == 2)
3959 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3960 else
3961 if (items > 2)
3962 for (i=2; i < items; i+=2)
3963 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3964 exception);
3965 (void) DisplayImages(package_info->image_info,image,exception);
3966 (void) CatchImageException(image);
3967
3968 PerlException:
3969 if (package_info != (struct PackageInfo *) NULL)
3970 DestroyPackageInfo(package_info);
3971 InheritPerlException(exception,perl_exception);
3972 exception=DestroyExceptionInfo(exception);
3973 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3974 SvPOK_on(perl_exception);
3975 ST(0)=sv_2mortal(perl_exception);
3976 XSRETURN(1);
3977 }
3978
3979#
3980###############################################################################
3981# #
3982# #
3983# #
3984# E v a l u a t e I m a g e s #
3985# #
3986# #
3987# #
3988###############################################################################
3989#
3990#
3991void
3992EvaluateImages(ref)
3993 Image::Magick ref=NO_INIT
3994 ALIAS:
3995 EvaluateImages = 1
3996 evaluateimages = 2
3997 PPCODE:
3998 {
3999 AV
4000 *av;
4001
4002 char
4003 *attribute,
4004 *p;
4005
4006 ExceptionInfo
4007 *exception;
4008
4009 HV
4010 *hv;
4011
4012 Image
4013 *image;
4014
4015 MagickEvaluateOperator
4016 op;
4017
4018 register ssize_t
4019 i;
4020
4021 struct PackageInfo
4022 *info;
4023
4024 SV
4025 *perl_exception,
4026 *reference,
4027 *rv,
4028 *sv;
4029
4030 PERL_UNUSED_VAR(ref);
4031 PERL_UNUSED_VAR(ix);
4032 exception=AcquireExceptionInfo();
4033 perl_exception=newSVpv("",0);
4034 sv=NULL;
4035 if (sv_isobject(ST(0)) == 0)
4036 {
4037 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4038 PackageName);
4039 goto PerlException;
4040 }
4041 reference=SvRV(ST(0));
4042 hv=SvSTASH(reference);
4043 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4044 if (image == (Image *) NULL)
4045 {
4046 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4047 PackageName);
4048 goto PerlException;
4049 }
4050 op=MeanEvaluateOperator;
4051 if (items == 2)
4052 {
4053 ssize_t
4054 in;
4055
4056 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
4057 SvPV(ST(1),na));
4058 if (in < 0)
4059 {
4060 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4061 SvPV(ST(1),na));
4062 return;
4063 }
4064 op=(MagickEvaluateOperator) in;
4065 }
4066 else
4067 for (i=2; i < items; i+=2)
4068 {
4069 attribute=(char *) SvPV(ST(i-1),na);
4070 switch (*attribute)
4071 {
4072 case 'O':
4073 case 'o':
4074 {
4075 if (LocaleCompare(attribute,"operator") == 0)
4076 {
4077 ssize_t
4078 in;
4079
4080 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4081 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4082 if (in < 0)
4083 {
4084 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4085 SvPV(ST(i),na));
4086 return;
4087 }
4088 op=(MagickEvaluateOperator) in;
4089 break;
4090 }
4091 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4092 attribute);
4093 break;
4094 }
4095 default:
4096 {
4097 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4098 attribute);
4099 break;
4100 }
4101 }
4102 }
4103 image=EvaluateImages(image,op,exception);
4104 if (image == (Image *) NULL)
4105 goto PerlException;
4106 /*
4107 Create blessed Perl array for the returned image.
4108 */
4109 av=newAV();
4110 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4111 SvREFCNT_dec(av);
4112 AddImageToRegistry(sv,image);
4113 rv=newRV(sv);
4114 av_push(av,sv_bless(rv,hv));
4115 SvREFCNT_dec(sv);
4116 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004117 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4118 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004119 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4120 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004121 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004122 SetImageInfo(info->image_info,0,exception);
4123 exception=DestroyExceptionInfo(exception);
4124 SvREFCNT_dec(perl_exception);
4125 XSRETURN(1);
4126
4127 PerlException:
4128 InheritPerlException(exception,perl_exception);
4129 exception=DestroyExceptionInfo(exception);
4130 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4131 SvPOK_on(perl_exception);
4132 ST(0)=sv_2mortal(perl_exception);
4133 XSRETURN(1);
4134 }
4135
4136#
4137###############################################################################
4138# #
4139# #
4140# #
4141# F e a t u r e s #
4142# #
4143# #
4144# #
4145###############################################################################
4146#
4147#
4148void
4149Features(ref,...)
4150 Image::Magick ref=NO_INIT
4151 ALIAS:
4152 FeaturesImage = 1
4153 features = 2
4154 featuresimage = 3
4155 PPCODE:
4156 {
4157#define ChannelFeatures(channel,direction) \
4158{ \
Cristyb1710fe2017-02-11 13:51:48 -05004159 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004160 channel_features[channel].angular_second_moment[direction]); \
4161 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004162 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004163 channel_features[channel].contrast[direction]); \
4164 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004165 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004166 channel_features[channel].contrast[direction]); \
4167 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004168 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004169 channel_features[channel].variance_sum_of_squares[direction]); \
4170 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004171 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004172 channel_features[channel].inverse_difference_moment[direction]); \
4173 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004174 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004175 channel_features[channel].sum_average[direction]); \
4176 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004177 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004178 channel_features[channel].sum_variance[direction]); \
4179 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004180 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004181 channel_features[channel].sum_entropy[direction]); \
4182 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004183 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004184 channel_features[channel].entropy[direction]); \
4185 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004186 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004187 channel_features[channel].difference_variance[direction]); \
4188 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004189 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004190 channel_features[channel].difference_entropy[direction]); \
4191 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004192 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004193 channel_features[channel].measure_of_correlation_1[direction]); \
4194 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004195 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004196 channel_features[channel].measure_of_correlation_2[direction]); \
4197 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004198 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004199 channel_features[channel].maximum_correlation_coefficient[direction]); \
4200 PUSHs(sv_2mortal(newSVpv(message,0))); \
4201}
4202
4203 AV
4204 *av;
4205
4206 char
4207 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004208 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004209
4210 ChannelFeatures
4211 *channel_features;
4212
4213 double
4214 distance;
4215
4216 ExceptionInfo
4217 *exception;
4218
4219 Image
4220 *image;
4221
4222 register ssize_t
4223 i;
4224
4225 ssize_t
4226 count;
4227
4228 struct PackageInfo
4229 *info;
4230
4231 SV
4232 *perl_exception,
4233 *reference;
4234
4235 PERL_UNUSED_VAR(ref);
4236 PERL_UNUSED_VAR(ix);
4237 exception=AcquireExceptionInfo();
4238 perl_exception=newSVpv("",0);
4239 av=NULL;
4240 if (sv_isobject(ST(0)) == 0)
4241 {
4242 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4243 PackageName);
4244 goto PerlException;
4245 }
4246 reference=SvRV(ST(0));
4247 av=newAV();
4248 SvREFCNT_dec(av);
4249 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4250 if (image == (Image *) NULL)
4251 {
4252 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4253 PackageName);
4254 goto PerlException;
4255 }
cristy7dbd9262014-07-02 17:53:42 +00004256 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004257 for (i=2; i < items; i+=2)
4258 {
4259 attribute=(char *) SvPV(ST(i-1),na);
4260 switch (*attribute)
4261 {
4262 case 'D':
4263 case 'd':
4264 {
4265 if (LocaleCompare(attribute,"distance") == 0)
4266 {
4267 distance=StringToLong((char *) SvPV(ST(1),na));
4268 break;
4269 }
4270 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4271 attribute);
4272 break;
4273 }
4274 default:
4275 {
4276 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4277 attribute);
4278 break;
4279 }
4280 }
4281 }
4282 count=0;
4283 for ( ; image; image=image->next)
4284 {
Cristy5a854dc2017-02-11 15:43:46 -05004285 register ssize_t
4286 j;
4287
cristy4a3ce0a2013-08-03 20:06:59 +00004288 channel_features=GetImageFeatures(image,distance,exception);
4289 if (channel_features == (ChannelFeatures *) NULL)
4290 continue;
4291 count++;
Cristy5a854dc2017-02-11 15:43:46 -05004292 for (j=0; j < 4; j++)
cristy4a3ce0a2013-08-03 20:06:59 +00004293 {
Cristy5a854dc2017-02-11 15:43:46 -05004294 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
4295 {
4296 PixelChannel channel=GetPixelChannelChannel(image,i);
4297 PixelTrait traits=GetPixelChannelTraits(image,channel);
4298 if (traits == UndefinedPixelTrait)
4299 continue;
4300 EXTEND(sp,14*(i+1)*count);
4301 ChannelFeatures(channel,j);
4302 }
cristy4a3ce0a2013-08-03 20:06:59 +00004303 }
4304 channel_features=(ChannelFeatures *)
4305 RelinquishMagickMemory(channel_features);
4306 }
4307
4308 PerlException:
4309 InheritPerlException(exception,perl_exception);
4310 exception=DestroyExceptionInfo(exception);
4311 SvREFCNT_dec(perl_exception);
4312 }
4313
4314#
4315###############################################################################
4316# #
4317# #
4318# #
4319# F l a t t e n #
4320# #
4321# #
4322# #
4323###############################################################################
4324#
4325#
4326void
4327Flatten(ref)
4328 Image::Magick ref=NO_INIT
4329 ALIAS:
4330 FlattenImage = 1
4331 flatten = 2
4332 flattenimage = 3
4333 PPCODE:
4334 {
4335 AV
4336 *av;
4337
4338 char
4339 *attribute,
4340 *p;
4341
4342 ExceptionInfo
4343 *exception;
4344
4345 HV
4346 *hv;
4347
4348 Image
4349 *image;
4350
4351 PixelInfo
4352 background_color;
4353
4354 register ssize_t
4355 i;
4356
4357 struct PackageInfo
4358 *info;
4359
4360 SV
4361 *perl_exception,
4362 *reference,
4363 *rv,
4364 *sv;
4365
4366 PERL_UNUSED_VAR(ref);
4367 PERL_UNUSED_VAR(ix);
4368 exception=AcquireExceptionInfo();
4369 perl_exception=newSVpv("",0);
4370 sv=NULL;
4371 if (sv_isobject(ST(0)) == 0)
4372 {
4373 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4374 PackageName);
4375 goto PerlException;
4376 }
4377 reference=SvRV(ST(0));
4378 hv=SvSTASH(reference);
4379 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4380 if (image == (Image *) NULL)
4381 {
4382 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4383 PackageName);
4384 goto PerlException;
4385 }
4386 background_color=image->background_color;
4387 if (items == 2)
4388 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4389 &background_color,exception);
4390 else
4391 for (i=2; i < items; i+=2)
4392 {
4393 attribute=(char *) SvPV(ST(i-1),na);
4394 switch (*attribute)
4395 {
4396 case 'B':
4397 case 'b':
4398 {
4399 if (LocaleCompare(attribute,"background") == 0)
4400 {
4401 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4402 AllCompliance,&background_color,exception);
4403 break;
4404 }
4405 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4406 attribute);
4407 break;
4408 }
4409 default:
4410 {
4411 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4412 attribute);
4413 break;
4414 }
4415 }
4416 }
4417 image->background_color=background_color;
4418 image=MergeImageLayers(image,FlattenLayer,exception);
4419 if (image == (Image *) NULL)
4420 goto PerlException;
4421 /*
4422 Create blessed Perl array for the returned image.
4423 */
4424 av=newAV();
4425 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4426 SvREFCNT_dec(av);
4427 AddImageToRegistry(sv,image);
4428 rv=newRV(sv);
4429 av_push(av,sv_bless(rv,hv));
4430 SvREFCNT_dec(sv);
4431 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004432 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4433 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004434 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4435 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004436 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004437 SetImageInfo(info->image_info,0,exception);
4438 exception=DestroyExceptionInfo(exception);
4439 SvREFCNT_dec(perl_exception);
4440 XSRETURN(1);
4441
4442 PerlException:
4443 InheritPerlException(exception,perl_exception);
4444 exception=DestroyExceptionInfo(exception);
4445 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4446 SvPOK_on(perl_exception); /* return messages in string context */
4447 ST(0)=sv_2mortal(perl_exception);
4448 XSRETURN(1);
4449 }
4450
4451#
4452###############################################################################
4453# #
4454# #
4455# #
4456# F x #
4457# #
4458# #
4459# #
4460###############################################################################
4461#
4462#
4463void
4464Fx(ref,...)
4465 Image::Magick ref=NO_INIT
4466 ALIAS:
4467 FxImage = 1
4468 fx = 2
4469 fximage = 3
4470 PPCODE:
4471 {
4472 AV
4473 *av;
4474
4475 char
4476 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004477 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004478
4479 ChannelType
4480 channel,
4481 channel_mask;
4482
4483 ExceptionInfo
4484 *exception;
4485
4486 HV
4487 *hv;
4488
4489 Image
4490 *image;
4491
4492 register ssize_t
4493 i;
4494
4495 struct PackageInfo
4496 *info;
4497
4498 SV
4499 *av_reference,
4500 *perl_exception,
4501 *reference,
4502 *rv,
4503 *sv;
4504
4505 PERL_UNUSED_VAR(ref);
4506 PERL_UNUSED_VAR(ix);
4507 exception=AcquireExceptionInfo();
4508 perl_exception=newSVpv("",0);
4509 sv=NULL;
4510 attribute=NULL;
4511 av=NULL;
4512 if (sv_isobject(ST(0)) == 0)
4513 {
4514 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4515 PackageName);
4516 goto PerlException;
4517 }
4518 reference=SvRV(ST(0));
4519 hv=SvSTASH(reference);
4520 av=newAV();
4521 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4522 SvREFCNT_dec(av);
4523 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4524 if (image == (Image *) NULL)
4525 {
4526 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4527 PackageName);
4528 goto PerlException;
4529 }
4530 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4531 /*
4532 Get options.
4533 */
4534 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004535 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004536 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004537 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004538 else
4539 for (i=2; i < items; i+=2)
4540 {
4541 attribute=(char *) SvPV(ST(i-1),na);
4542 switch (*attribute)
4543 {
4544 case 'C':
4545 case 'c':
4546 {
4547 if (LocaleCompare(attribute,"channel") == 0)
4548 {
4549 ssize_t
4550 option;
4551
4552 option=ParseChannelOption(SvPV(ST(i),na));
4553 if (option < 0)
4554 {
4555 ThrowPerlException(exception,OptionError,
4556 "UnrecognizedType",SvPV(ST(i),na));
4557 return;
4558 }
4559 channel=(ChannelType) option;
4560 break;
4561 }
4562 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4563 attribute);
4564 break;
4565 }
4566 case 'E':
4567 case 'e':
4568 {
4569 if (LocaleCompare(attribute,"expression") == 0)
4570 {
4571 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004572 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004573 break;
4574 }
4575 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4576 attribute);
4577 break;
4578 }
4579 default:
4580 {
4581 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4582 attribute);
4583 break;
4584 }
4585 }
4586 }
4587 channel_mask=SetImageChannelMask(image,channel);
4588 image=FxImage(image,expression,exception);
4589 if (image != (Image *) NULL)
4590 (void) SetImageChannelMask(image,channel_mask);
4591 if (image == (Image *) NULL)
4592 goto PerlException;
4593 for ( ; image; image=image->next)
4594 {
4595 AddImageToRegistry(sv,image);
4596 rv=newRV(sv);
4597 av_push(av,sv_bless(rv,hv));
4598 SvREFCNT_dec(sv);
4599 }
4600 exception=DestroyExceptionInfo(exception);
4601 ST(0)=av_reference;
4602 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4603 XSRETURN(1);
4604
4605 PerlException:
4606 InheritPerlException(exception,perl_exception);
4607 exception=DestroyExceptionInfo(exception);
4608 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4609 SvPOK_on(perl_exception);
4610 ST(0)=sv_2mortal(perl_exception);
4611 XSRETURN(1);
4612 }
4613
4614#
4615###############################################################################
4616# #
4617# #
4618# #
4619# G e t #
4620# #
4621# #
4622# #
4623###############################################################################
4624#
4625#
4626void
4627Get(ref,...)
4628 Image::Magick ref=NO_INIT
4629 ALIAS:
4630 GetAttributes = 1
4631 GetAttribute = 2
4632 get = 3
4633 getattributes = 4
4634 getattribute = 5
4635 PPCODE:
4636 {
4637 char
4638 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004639 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004640
4641 const char
4642 *value;
4643
4644 ExceptionInfo
4645 *exception;
4646
4647 Image
4648 *image;
4649
4650 long
4651 j;
4652
4653 register ssize_t
4654 i;
4655
4656 struct PackageInfo
4657 *info;
4658
4659 SV
4660 *perl_exception,
4661 *reference,
4662 *s;
4663
4664 PERL_UNUSED_VAR(ref);
4665 PERL_UNUSED_VAR(ix);
4666 exception=AcquireExceptionInfo();
4667 perl_exception=newSVpv("",0);
4668 if (sv_isobject(ST(0)) == 0)
4669 {
4670 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4671 PackageName);
4672 XSRETURN_EMPTY;
4673 }
4674 reference=SvRV(ST(0));
4675 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4676 if (image == (Image *) NULL && !info)
4677 XSRETURN_EMPTY;
4678 EXTEND(sp,items);
4679 for (i=1; i < items; i++)
4680 {
4681 attribute=(char *) SvPV(ST(i),na);
4682 s=NULL;
4683 switch (*attribute)
4684 {
4685 case 'A':
4686 case 'a':
4687 {
4688 if (LocaleCompare(attribute,"adjoin") == 0)
4689 {
4690 if (info)
4691 s=newSViv((ssize_t) info->image_info->adjoin);
4692 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4693 continue;
4694 }
4695 if (LocaleCompare(attribute,"antialias") == 0)
4696 {
4697 if (info)
4698 s=newSViv((ssize_t) info->image_info->antialias);
4699 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4700 continue;
4701 }
4702 if (LocaleCompare(attribute,"area") == 0)
4703 {
4704 s=newSViv(GetMagickResource(AreaResource));
4705 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4706 continue;
4707 }
4708 if (LocaleCompare(attribute,"attenuate") == 0)
4709 {
4710 const char
4711 *value;
4712
4713 value=GetImageProperty(image,attribute,exception);
4714 if (value != (const char *) NULL)
4715 s=newSVpv(value,0);
4716 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4717 continue;
4718 }
4719 if (LocaleCompare(attribute,"authenticate") == 0)
4720 {
4721 if (info)
4722 {
4723 const char
4724 *option;
4725
4726 option=GetImageOption(info->image_info,attribute);
4727 if (option != (const char *) NULL)
4728 s=newSVpv(option,0);
4729 }
4730 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4731 continue;
4732 }
4733 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4734 attribute);
4735 break;
4736 }
4737 case 'B':
4738 case 'b':
4739 {
4740 if (LocaleCompare(attribute,"background") == 0)
4741 {
4742 if (image == (Image *) NULL)
4743 break;
cristy151b66d2015-04-15 10:50:31 +00004744 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004745 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4746 (double) image->background_color.green,
4747 (double) image->background_color.blue,
4748 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004749 s=newSVpv(color,0);
4750 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4751 continue;
4752 }
4753 if (LocaleCompare(attribute,"base-columns") == 0)
4754 {
4755 if (image != (Image *) NULL)
4756 s=newSViv((ssize_t) image->magick_columns);
4757 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4758 continue;
4759 }
4760 if (LocaleCompare(attribute,"base-filename") == 0)
4761 {
4762 if (image != (Image *) NULL)
4763 s=newSVpv(image->magick_filename,0);
4764 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4765 continue;
4766 }
4767 if (LocaleCompare(attribute,"base-height") == 0)
4768 {
4769 if (image != (Image *) NULL)
4770 s=newSViv((ssize_t) image->magick_rows);
4771 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4772 continue;
4773 }
4774 if (LocaleCompare(attribute,"base-rows") == 0)
4775 {
4776 if (image != (Image *) NULL)
4777 s=newSViv((ssize_t) image->magick_rows);
4778 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4779 continue;
4780 }
4781 if (LocaleCompare(attribute,"base-width") == 0)
4782 {
4783 if (image != (Image *) NULL)
4784 s=newSViv((ssize_t) image->magick_columns);
4785 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4786 continue;
4787 }
4788 if (LocaleCompare(attribute,"blue-primary") == 0)
4789 {
4790 if (image == (Image *) NULL)
4791 break;
Cristyb1710fe2017-02-11 13:51:48 -05004792 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004793 image->chromaticity.blue_primary.x,
4794 image->chromaticity.blue_primary.y);
4795 s=newSVpv(color,0);
4796 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4797 continue;
4798 }
4799 if (LocaleCompare(attribute,"bordercolor") == 0)
4800 {
4801 if (image == (Image *) NULL)
4802 break;
cristy151b66d2015-04-15 10:50:31 +00004803 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004804 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4805 (double) image->border_color.green,
4806 (double) image->border_color.blue,
4807 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004808 s=newSVpv(color,0);
4809 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4810 continue;
4811 }
4812 if (LocaleCompare(attribute,"bounding-box") == 0)
4813 {
4814 char
cristy151b66d2015-04-15 10:50:31 +00004815 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004816
4817 RectangleInfo
4818 page;
4819
4820 if (image == (Image *) NULL)
4821 break;
4822 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004823 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004824 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4825 page.height,(double) page.x,(double) page.y);
4826 s=newSVpv(geometry,0);
4827 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4828 continue;
4829 }
4830 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4831 attribute);
4832 break;
4833 }
4834 case 'C':
4835 case 'c':
4836 {
4837 if (LocaleCompare(attribute,"class") == 0)
4838 {
4839 if (image == (Image *) NULL)
4840 break;
4841 s=newSViv(image->storage_class);
4842 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4843 image->storage_class));
4844 SvIOK_on(s);
4845 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4846 continue;
4847 }
4848 if (LocaleCompare(attribute,"clip-mask") == 0)
4849 {
4850 if (image != (Image *) NULL)
4851 {
4852 Image
4853 *mask_image;
4854
4855 SV
4856 *sv;
4857
4858 sv=NULL;
4859 if (image->read_mask == MagickFalse)
4860 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004861 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004862 if (mask_image != (Image *) NULL)
4863 {
4864 AddImageToRegistry(sv,mask_image);
4865 s=sv_bless(newRV(sv),SvSTASH(reference));
4866 }
4867 }
4868 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4869 continue;
4870 }
4871 if (LocaleCompare(attribute,"clip-path") == 0)
4872 {
4873 if (image != (Image *) NULL)
4874 {
4875 Image
4876 *mask_image;
4877
4878 SV
4879 *sv;
4880
4881 sv=NULL;
4882 if (image->read_mask != MagickFalse)
4883 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004884 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004885 if (mask_image != (Image *) NULL)
4886 {
4887 AddImageToRegistry(sv,mask_image);
4888 s=sv_bless(newRV(sv),SvSTASH(reference));
4889 }
4890 }
4891 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4892 continue;
4893 }
4894 if (LocaleCompare(attribute,"compression") == 0)
4895 {
4896 j=info ? info->image_info->compression : image ?
4897 image->compression : UndefinedCompression;
4898 if (info)
4899 if (info->image_info->compression == UndefinedCompression)
4900 j=image->compression;
4901 s=newSViv(j);
4902 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4903 j));
4904 SvIOK_on(s);
4905 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4906 continue;
4907 }
4908 if (LocaleCompare(attribute,"colorspace") == 0)
4909 {
4910 j=image ? image->colorspace : RGBColorspace;
4911 s=newSViv(j);
4912 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4913 j));
4914 SvIOK_on(s);
4915 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4916 continue;
4917 }
4918 if (LocaleCompare(attribute,"colors") == 0)
4919 {
4920 if (image != (Image *) NULL)
4921 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4922 exception));
4923 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4924 continue;
4925 }
4926 if (LocaleNCompare(attribute,"colormap",8) == 0)
4927 {
4928 int
4929 items;
4930
4931 if (image == (Image *) NULL || !image->colormap)
4932 break;
4933 j=0;
4934 items=sscanf(attribute,"%*[^[][%ld",&j);
4935 (void) items;
4936 if (j > (ssize_t) image->colors)
4937 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004938 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004939 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4940 (double) image->colormap[j].green,
4941 (double) image->colormap[j].blue,
4942 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004943 s=newSVpv(color,0);
4944 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4945 continue;
4946 }
4947 if (LocaleCompare(attribute,"columns") == 0)
4948 {
4949 if (image != (Image *) NULL)
4950 s=newSViv((ssize_t) image->columns);
4951 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4952 continue;
4953 }
4954 if (LocaleCompare(attribute,"comment") == 0)
4955 {
4956 const char
4957 *value;
4958
Cristy935a4052017-03-31 17:45:37 -04004959 value=GetImageProperty(image,attribute,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004960 if (value != (const char *) NULL)
4961 s=newSVpv(value,0);
4962 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4963 continue;
4964 }
4965 if (LocaleCompare(attribute,"copyright") == 0)
4966 {
4967 s=newSVpv(GetMagickCopyright(),0);
4968 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4969 continue;
4970 }
4971 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4972 attribute);
4973 break;
4974 }
4975 case 'D':
4976 case 'd':
4977 {
4978 if (LocaleCompare(attribute,"density") == 0)
4979 {
4980 char
cristy151b66d2015-04-15 10:50:31 +00004981 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004982
4983 if (image == (Image *) NULL)
4984 break;
Cristyb1710fe2017-02-11 13:51:48 -05004985 (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004986 image->resolution.x,image->resolution.y);
4987 s=newSVpv(geometry,0);
4988 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4989 continue;
4990 }
4991 if (LocaleCompare(attribute,"delay") == 0)
4992 {
4993 if (image != (Image *) NULL)
4994 s=newSViv((ssize_t) image->delay);
4995 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4996 continue;
4997 }
4998 if (LocaleCompare(attribute,"depth") == 0)
4999 {
5000 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5001 if (image != (Image *) NULL)
5002 s=newSViv((ssize_t) GetImageDepth(image,exception));
5003 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5004 continue;
5005 }
5006 if (LocaleCompare(attribute,"directory") == 0)
5007 {
5008 if (image && image->directory)
5009 s=newSVpv(image->directory,0);
5010 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5011 continue;
5012 }
5013 if (LocaleCompare(attribute,"dispose") == 0)
5014 {
5015 if (image == (Image *) NULL)
5016 break;
5017
5018 s=newSViv(image->dispose);
5019 (void) sv_setpv(s,
5020 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
5021 SvIOK_on(s);
5022 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5023 continue;
5024 }
5025 if (LocaleCompare(attribute,"disk") == 0)
5026 {
5027 s=newSViv(GetMagickResource(DiskResource));
5028 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5029 continue;
5030 }
5031 if (LocaleCompare(attribute,"dither") == 0)
5032 {
5033 if (info)
5034 s=newSViv((ssize_t) info->image_info->dither);
5035 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5036 continue;
5037 }
5038 if (LocaleCompare(attribute,"display") == 0) /* same as server */
5039 {
5040 if (info && info->image_info->server_name)
5041 s=newSVpv(info->image_info->server_name,0);
5042 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5043 continue;
5044 }
5045 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5046 attribute);
5047 break;
5048 }
5049 case 'E':
5050 case 'e':
5051 {
5052 if (LocaleCompare(attribute,"elapsed-time") == 0)
5053 {
5054 if (image != (Image *) NULL)
5055 s=newSVnv(GetElapsedTime(&image->timer));
5056 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5057 continue;
5058 }
5059 if (LocaleCompare(attribute,"endian") == 0)
5060 {
5061 j=info ? info->image_info->endian : image ? image->endian :
5062 UndefinedEndian;
5063 s=newSViv(j);
5064 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
5065 SvIOK_on(s);
5066 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5067 continue;
5068 }
5069 if (LocaleCompare(attribute,"error") == 0)
5070 {
5071 if (image != (Image *) NULL)
5072 s=newSVnv(image->error.mean_error_per_pixel);
5073 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5074 continue;
5075 }
5076 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5077 attribute);
5078 break;
5079 }
5080 case 'F':
5081 case 'f':
5082 {
5083 if (LocaleCompare(attribute,"filesize") == 0)
5084 {
5085 if (image != (Image *) NULL)
5086 s=newSViv((ssize_t) GetBlobSize(image));
5087 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5088 continue;
5089 }
5090 if (LocaleCompare(attribute,"filename") == 0)
5091 {
Cristy2273d6a2017-07-14 19:19:55 -04005092 if (info && *info->image_info->filename)
cristy4a3ce0a2013-08-03 20:06:59 +00005093 s=newSVpv(info->image_info->filename,0);
5094 if (image != (Image *) NULL)
5095 s=newSVpv(image->filename,0);
5096 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5097 continue;
5098 }
5099 if (LocaleCompare(attribute,"filter") == 0)
5100 {
5101 s=image ? newSViv(image->filter) : newSViv(0);
5102 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5103 image->filter));
5104 SvIOK_on(s);
5105 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5106 continue;
5107 }
5108 if (LocaleCompare(attribute,"font") == 0)
5109 {
5110 if (info && info->image_info->font)
5111 s=newSVpv(info->image_info->font,0);
5112 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5113 continue;
5114 }
5115 if (LocaleCompare(attribute,"foreground") == 0)
5116 continue;
5117 if (LocaleCompare(attribute,"format") == 0)
5118 {
5119 const MagickInfo
5120 *magick_info;
5121
5122 magick_info=(const MagickInfo *) NULL;
5123 if (info && (*info->image_info->magick != '\0'))
5124 magick_info=GetMagickInfo(info->image_info->magick,exception);
5125 if (image != (Image *) NULL)
5126 magick_info=GetMagickInfo(image->magick,exception);
5127 if ((magick_info != (const MagickInfo *) NULL) &&
5128 (*magick_info->description != '\0'))
5129 s=newSVpv((char *) magick_info->description,0);
5130 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5131 continue;
5132 }
5133 if (LocaleCompare(attribute,"fuzz") == 0)
5134 {
5135 if (info)
5136 s=newSVnv(info->image_info->fuzz);
5137 if (image != (Image *) NULL)
5138 s=newSVnv(image->fuzz);
5139 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5140 continue;
5141 }
5142 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5143 attribute);
5144 break;
5145 }
5146 case 'G':
5147 case 'g':
5148 {
5149 if (LocaleCompare(attribute,"gamma") == 0)
5150 {
5151 if (image != (Image *) NULL)
5152 s=newSVnv(image->gamma);
5153 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5154 continue;
5155 }
5156 if (LocaleCompare(attribute,"geometry") == 0)
5157 {
5158 if (image && image->geometry)
5159 s=newSVpv(image->geometry,0);
5160 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5161 continue;
5162 }
5163 if (LocaleCompare(attribute,"gravity") == 0)
5164 {
5165 s=image ? newSViv(image->gravity) : newSViv(0);
5166 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5167 image->gravity));
5168 SvIOK_on(s);
5169 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5170 continue;
5171 }
5172 if (LocaleCompare(attribute,"green-primary") == 0)
5173 {
5174 if (image == (Image *) NULL)
5175 break;
Cristyb1710fe2017-02-11 13:51:48 -05005176 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005177 image->chromaticity.green_primary.x,
5178 image->chromaticity.green_primary.y);
5179 s=newSVpv(color,0);
5180 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5181 continue;
5182 }
5183 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5184 attribute);
5185 break;
5186 }
5187 case 'H':
5188 case 'h':
5189 {
5190 if (LocaleCompare(attribute,"height") == 0)
5191 {
5192 if (image != (Image *) NULL)
5193 s=newSViv((ssize_t) image->rows);
5194 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5195 continue;
5196 }
5197 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5198 attribute);
5199 break;
5200 }
5201 case 'I':
5202 case 'i':
5203 {
5204 if (LocaleCompare(attribute,"icc") == 0)
5205 {
5206 if (image != (Image *) NULL)
5207 {
5208 const StringInfo
5209 *profile;
5210
5211 profile=GetImageProfile(image,"icc");
5212 if (profile != (StringInfo *) NULL)
5213 s=newSVpv((const char *) GetStringInfoDatum(profile),
5214 GetStringInfoLength(profile));
5215 }
5216 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5217 continue;
5218 }
5219 if (LocaleCompare(attribute,"icm") == 0)
5220 {
5221 if (image != (Image *) NULL)
5222 {
5223 const StringInfo
5224 *profile;
5225
5226 profile=GetImageProfile(image,"icm");
5227 if (profile != (const StringInfo *) NULL)
5228 s=newSVpv((const char *) GetStringInfoDatum(profile),
5229 GetStringInfoLength(profile));
5230 }
5231 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5232 continue;
5233 }
5234 if (LocaleCompare(attribute,"id") == 0)
5235 {
5236 if (image != (Image *) NULL)
5237 {
5238 char
cristy151b66d2015-04-15 10:50:31 +00005239 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005240
5241 MagickBooleanType
5242 status;
5243
5244 static ssize_t
5245 id = 0;
5246
cristy151b66d2015-04-15 10:50:31 +00005247 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005248 id);
5249 status=SetImageRegistry(ImageRegistryType,key,image,
5250 exception);
5251 (void) status;
5252 s=newSViv(id++);
5253 }
5254 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5255 continue;
5256 }
5257 if (LocaleNCompare(attribute,"index",5) == 0)
5258 {
5259 char
cristy151b66d2015-04-15 10:50:31 +00005260 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005261
5262 int
5263 items;
5264
5265 long
5266 x,
5267 y;
5268
5269 register const Quantum
5270 *p;
5271
5272 CacheView
5273 *image_view;
5274
5275 if (image == (Image *) NULL)
5276 break;
5277 if (image->storage_class != PseudoClass)
5278 break;
5279 x=0;
5280 y=0;
5281 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5282 (void) items;
5283 image_view=AcquireVirtualCacheView(image,exception);
5284 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5285 if (p != (const Quantum *) NULL)
5286 {
cristy151b66d2015-04-15 10:50:31 +00005287 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005288 GetPixelIndex(image,p));
5289 s=newSVpv(name,0);
5290 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5291 }
5292 image_view=DestroyCacheView(image_view);
5293 continue;
5294 }
5295 if (LocaleCompare(attribute,"iptc") == 0)
5296 {
5297 if (image != (Image *) NULL)
5298 {
5299 const StringInfo
5300 *profile;
5301
5302 profile=GetImageProfile(image,"iptc");
5303 if (profile != (const StringInfo *) NULL)
5304 s=newSVpv((const char *) GetStringInfoDatum(profile),
5305 GetStringInfoLength(profile));
5306 }
5307 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5308 continue;
5309 }
5310 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5311 {
5312 if (image != (Image *) NULL)
5313 s=newSViv((ssize_t) image->iterations);
5314 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5315 continue;
5316 }
5317 if (LocaleCompare(attribute,"interlace") == 0)
5318 {
5319 j=info ? info->image_info->interlace : image ? image->interlace :
5320 UndefinedInterlace;
5321 s=newSViv(j);
5322 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5323 j));
5324 SvIOK_on(s);
5325 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5326 continue;
5327 }
5328 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5329 attribute);
5330 break;
5331 }
5332 case 'L':
5333 case 'l':
5334 {
5335 if (LocaleCompare(attribute,"label") == 0)
5336 {
5337 const char
5338 *value;
5339
5340 if (image == (Image *) NULL)
5341 break;
Cristy935a4052017-03-31 17:45:37 -04005342 value=GetImageProperty(image,"Label",exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005343 if (value != (const char *) NULL)
5344 s=newSVpv(value,0);
5345 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5346 continue;
5347 }
5348 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5349 {
5350 if (image != (Image *) NULL)
5351 s=newSViv((ssize_t) image->iterations);
5352 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5353 continue;
5354 }
5355 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5356 attribute);
5357 break;
5358 }
5359 case 'M':
5360 case 'm':
5361 {
5362 if (LocaleCompare(attribute,"magick") == 0)
5363 {
5364 if (info && *info->image_info->magick)
5365 s=newSVpv(info->image_info->magick,0);
5366 if (image != (Image *) NULL)
5367 s=newSVpv(image->magick,0);
5368 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5369 continue;
5370 }
5371 if (LocaleCompare(attribute,"map") == 0)
5372 {
5373 s=newSViv(GetMagickResource(MapResource));
5374 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5375 continue;
5376 }
5377 if (LocaleCompare(attribute,"maximum-error") == 0)
5378 {
5379 if (image != (Image *) NULL)
5380 s=newSVnv(image->error.normalized_maximum_error);
5381 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5382 continue;
5383 }
5384 if (LocaleCompare(attribute,"memory") == 0)
5385 {
5386 s=newSViv(GetMagickResource(MemoryResource));
5387 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5388 continue;
5389 }
5390 if (LocaleCompare(attribute,"mean-error") == 0)
5391 {
5392 if (image != (Image *) NULL)
5393 s=newSVnv(image->error.normalized_mean_error);
5394 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5395 continue;
5396 }
5397 if (LocaleCompare(attribute,"mime") == 0)
5398 {
5399 if (info && *info->image_info->magick)
5400 s=newSVpv(MagickToMime(info->image_info->magick),0);
5401 if (image != (Image *) NULL)
5402 s=newSVpv(MagickToMime(image->magick),0);
5403 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5404 continue;
5405 }
5406 if (LocaleCompare(attribute,"mattecolor") == 0)
5407 {
5408 if (image == (Image *) NULL)
5409 break;
cristy151b66d2015-04-15 10:50:31 +00005410 (void) FormatLocaleString(color,MagickPathExtent,
Cristy8645e042016-02-03 16:35:29 -05005411 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5412 (double) image->alpha_color.green,
5413 (double) image->alpha_color.blue,
5414 (double) image->alpha_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005415 s=newSVpv(color,0);
5416 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5417 continue;
5418 }
5419 if (LocaleCompare(attribute,"matte") == 0)
5420 {
5421 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005422 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005423 1 : 0);
5424 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5425 continue;
5426 }
5427 if (LocaleCompare(attribute,"mime") == 0)
5428 {
5429 const char
5430 *magick;
5431
5432 magick=NULL;
5433 if (info && *info->image_info->magick)
5434 magick=info->image_info->magick;
5435 if (image != (Image *) NULL)
5436 magick=image->magick;
5437 if (magick)
5438 {
5439 char
5440 *mime;
5441
5442 mime=MagickToMime(magick);
5443 s=newSVpv(mime,0);
5444 mime=(char *) RelinquishMagickMemory(mime);
5445 }
5446 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5447 continue;
5448 }
5449 if (LocaleCompare(attribute,"monochrome") == 0)
5450 {
5451 if (image == (Image *) NULL)
5452 continue;
5453 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005454 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005455 s=newSViv(j);
5456 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5457 continue;
5458 }
5459 if (LocaleCompare(attribute,"montage") == 0)
5460 {
5461 if (image && image->montage)
5462 s=newSVpv(image->montage,0);
5463 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5464 continue;
5465 }
5466 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5467 attribute);
5468 break;
5469 }
5470 case 'O':
5471 case 'o':
5472 {
5473 if (LocaleCompare(attribute,"orientation") == 0)
5474 {
5475 j=info ? info->image_info->orientation : image ?
5476 image->orientation : UndefinedOrientation;
5477 s=newSViv(j);
5478 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5479 j));
5480 SvIOK_on(s);
5481 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5482 continue;
5483 }
5484 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5485 attribute);
5486 break;
5487 }
5488 case 'P':
5489 case 'p':
5490 {
5491 if (LocaleCompare(attribute,"page") == 0)
5492 {
5493 if (info && info->image_info->page)
5494 s=newSVpv(info->image_info->page,0);
5495 if (image != (Image *) NULL)
5496 {
5497 char
cristy151b66d2015-04-15 10:50:31 +00005498 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005499
cristy151b66d2015-04-15 10:50:31 +00005500 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005501 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5502 (double) image->page.height,(double) image->page.x,(double)
5503 image->page.y);
5504 s=newSVpv(geometry,0);
5505 }
5506 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5507 continue;
5508 }
5509 if (LocaleCompare(attribute,"page.x") == 0)
5510 {
5511 if (image != (Image *) NULL)
5512 s=newSViv((ssize_t) image->page.x);
5513 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5514 continue;
5515 }
5516 if (LocaleCompare(attribute,"page.y") == 0)
5517 {
5518 if (image != (Image *) NULL)
5519 s=newSViv((ssize_t) image->page.y);
5520 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5521 continue;
5522 }
5523 if (LocaleNCompare(attribute,"pixel",5) == 0)
5524 {
5525 char
cristy151b66d2015-04-15 10:50:31 +00005526 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005527
5528 int
5529 items;
5530
5531 long
5532 x,
5533 y;
5534
5535 register const Quantum
5536 *p;
5537
5538 if (image == (Image *) NULL)
5539 break;
5540 x=0;
5541 y=0;
5542 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5543 (void) items;
5544 p=GetVirtualPixels(image,x,y,1,1,exception);
5545 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005546 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005547 QuantumFormat "," QuantumFormat "," QuantumFormat,
5548 GetPixelRed(image,p),GetPixelGreen(image,p),
5549 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5550 else
cristy151b66d2015-04-15 10:50:31 +00005551 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005552 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5553 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5554 GetPixelBlue(image,p),GetPixelBlack(image,p),
5555 GetPixelAlpha(image,p));
5556 s=newSVpv(tuple,0);
5557 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5558 continue;
5559 }
5560 if (LocaleCompare(attribute,"pointsize") == 0)
5561 {
5562 if (info)
5563 s=newSViv((ssize_t) info->image_info->pointsize);
5564 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5565 continue;
5566 }
Cristy798981a2020-02-17 12:07:15 -05005567 if (LocaleCompare(attribute,"precision") == 0)
5568 {
5569 s=newSViv((ssize_t) GetMagickPrecision());
5570 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5571 continue;
5572 }
cristy4a3ce0a2013-08-03 20:06:59 +00005573 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5574 attribute);
5575 break;
5576 }
5577 case 'Q':
5578 case 'q':
5579 {
5580 if (LocaleCompare(attribute,"quality") == 0)
5581 {
5582 if (info)
5583 s=newSViv((ssize_t) info->image_info->quality);
5584 if (image != (Image *) NULL)
5585 s=newSViv((ssize_t) image->quality);
5586 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5587 continue;
5588 }
5589 if (LocaleCompare(attribute,"quantum") == 0)
5590 {
5591 if (info)
5592 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5593 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5594 continue;
5595 }
5596 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5597 attribute);
5598 break;
5599 }
5600 case 'R':
5601 case 'r':
5602 {
5603 if (LocaleCompare(attribute,"rendering-intent") == 0)
5604 {
5605 s=newSViv(image->rendering_intent);
5606 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5607 image->rendering_intent));
5608 SvIOK_on(s);
5609 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5610 continue;
5611 }
5612 if (LocaleCompare(attribute,"red-primary") == 0)
5613 {
5614 if (image == (Image *) NULL)
5615 break;
Cristyb1710fe2017-02-11 13:51:48 -05005616 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005617 image->chromaticity.red_primary.x,
5618 image->chromaticity.red_primary.y);
5619 s=newSVpv(color,0);
5620 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5621 continue;
5622 }
5623 if (LocaleCompare(attribute,"rows") == 0)
5624 {
5625 if (image != (Image *) NULL)
5626 s=newSViv((ssize_t) image->rows);
5627 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5628 continue;
5629 }
5630 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5631 attribute);
5632 break;
5633 }
5634 case 'S':
5635 case 's':
5636 {
5637 if (LocaleCompare(attribute,"sampling-factor") == 0)
5638 {
5639 if (info && info->image_info->sampling_factor)
5640 s=newSVpv(info->image_info->sampling_factor,0);
5641 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5642 continue;
5643 }
5644 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5645 {
5646 if (info && info->image_info->server_name)
5647 s=newSVpv(info->image_info->server_name,0);
5648 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5649 continue;
5650 }
5651 if (LocaleCompare(attribute,"size") == 0)
5652 {
5653 if (info && info->image_info->size)
5654 s=newSVpv(info->image_info->size,0);
5655 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5656 continue;
5657 }
5658 if (LocaleCompare(attribute,"scene") == 0)
5659 {
5660 if (image != (Image *) NULL)
5661 s=newSViv((ssize_t) image->scene);
5662 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5663 continue;
5664 }
5665 if (LocaleCompare(attribute,"scenes") == 0)
5666 {
5667 if (image != (Image *) NULL)
5668 s=newSViv((ssize_t) info->image_info->number_scenes);
5669 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5670 continue;
5671 }
5672 if (LocaleCompare(attribute,"signature") == 0)
5673 {
5674 const char
5675 *value;
5676
5677 if (image == (Image *) NULL)
5678 break;
5679 (void) SignatureImage(image,exception);
5680 value=GetImageProperty(image,"Signature",exception);
5681 if (value != (const char *) NULL)
5682 s=newSVpv(value,0);
5683 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5684 continue;
5685 }
5686 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5687 attribute);
5688 break;
5689 }
5690 case 'T':
5691 case 't':
5692 {
5693 if (LocaleCompare(attribute,"taint") == 0)
5694 {
5695 if (image != (Image *) NULL)
5696 s=newSViv((ssize_t) IsTaintImage(image));
5697 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5698 continue;
5699 }
5700 if (LocaleCompare(attribute,"texture") == 0)
5701 {
5702 if (info && info->image_info->texture)
5703 s=newSVpv(info->image_info->texture,0);
5704 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5705 continue;
5706 }
5707 if (LocaleCompare(attribute,"total-ink-density") == 0)
5708 {
5709 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5710 if (image != (Image *) NULL)
5711 s=newSVnv(GetImageTotalInkDensity(image,exception));
5712 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5713 continue;
5714 }
5715 if (LocaleCompare(attribute,"transparent-color") == 0)
5716 {
5717 if (image == (Image *) NULL)
5718 break;
cristy151b66d2015-04-15 10:50:31 +00005719 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005720 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5721 (double) image->transparent_color.green,
5722 (double) image->transparent_color.blue,
5723 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005724 s=newSVpv(color,0);
5725 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5726 continue;
5727 }
5728 if (LocaleCompare(attribute,"type") == 0)
5729 {
5730 if (image == (Image *) NULL)
5731 break;
cristya26f54c2015-07-29 12:26:12 +00005732 j=(ssize_t) GetImageType(image);
cristy4a3ce0a2013-08-03 20:06:59 +00005733 s=newSViv(j);
5734 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5735 SvIOK_on(s);
5736 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5737 continue;
5738 }
5739 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5740 attribute);
5741 break;
5742 }
5743 case 'U':
5744 case 'u':
5745 {
5746 if (LocaleCompare(attribute,"units") == 0)
5747 {
5748 j=info ? info->image_info->units : image ? image->units :
5749 UndefinedResolution;
5750 if (info && (info->image_info->units == UndefinedResolution))
5751 if (image)
5752 j=image->units;
5753 if (j == UndefinedResolution)
5754 s=newSVpv("undefined units",0);
5755 else
5756 if (j == PixelsPerInchResolution)
5757 s=newSVpv("pixels / inch",0);
5758 else
5759 s=newSVpv("pixels / centimeter",0);
5760 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5761 continue;
5762 }
5763 if (LocaleCompare(attribute,"user-time") == 0)
5764 {
5765 if (image != (Image *) NULL)
5766 s=newSVnv(GetUserTime(&image->timer));
5767 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5768 continue;
5769 }
5770 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5771 attribute);
5772 break;
5773 }
5774 case 'V':
5775 case 'v':
5776 {
5777 if (LocaleCompare(attribute,"verbose") == 0)
5778 {
5779 if (info)
5780 s=newSViv((ssize_t) info->image_info->verbose);
5781 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5782 continue;
5783 }
5784 if (LocaleCompare(attribute,"version") == 0)
5785 {
5786 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5787 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5788 continue;
5789 }
cristy4a3ce0a2013-08-03 20:06:59 +00005790 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5791 {
5792 if (image == (Image *) NULL)
5793 break;
5794 j=(ssize_t) GetImageVirtualPixelMethod(image);
5795 s=newSViv(j);
5796 (void) sv_setpv(s,CommandOptionToMnemonic(
5797 MagickVirtualPixelOptions,j));
5798 SvIOK_on(s);
5799 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5800 continue;
5801 }
5802 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5803 attribute);
5804 break;
5805 }
5806 case 'W':
5807 case 'w':
5808 {
5809 if (LocaleCompare(attribute,"white-point") == 0)
5810 {
5811 if (image == (Image *) NULL)
5812 break;
Cristyb1710fe2017-02-11 13:51:48 -05005813 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005814 image->chromaticity.white_point.x,
5815 image->chromaticity.white_point.y);
5816 s=newSVpv(color,0);
5817 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5818 continue;
5819 }
5820 if (LocaleCompare(attribute,"width") == 0)
5821 {
5822 if (image != (Image *) NULL)
5823 s=newSViv((ssize_t) image->columns);
5824 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5825 continue;
5826 }
5827 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5828 attribute);
5829 break;
5830 }
5831 case 'X':
5832 case 'x':
5833 {
Cristyc1f9f9f2016-01-05 08:19:28 -05005834 if (LocaleCompare(attribute,"xmp") == 0)
5835 {
5836 if (image != (Image *) NULL)
5837 {
5838 const StringInfo
5839 *profile;
5840
5841 profile=GetImageProfile(image,"xmp");
5842 if (profile != (StringInfo *) NULL)
5843 s=newSVpv((const char *) GetStringInfoDatum(profile),
5844 GetStringInfoLength(profile));
5845 }
5846 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5847 continue;
5848 }
cristy4a3ce0a2013-08-03 20:06:59 +00005849 if (LocaleCompare(attribute,"x-resolution") == 0)
5850 {
5851 if (image != (Image *) NULL)
5852 s=newSVnv(image->resolution.x);
5853 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5854 continue;
5855 }
5856 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5857 attribute);
5858 break;
5859 }
5860 case 'Y':
5861 case 'y':
5862 {
5863 if (LocaleCompare(attribute,"y-resolution") == 0)
5864 {
5865 if (image != (Image *) NULL)
5866 s=newSVnv(image->resolution.y);
5867 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5868 continue;
5869 }
5870 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5871 attribute);
5872 break;
5873 }
5874 default:
5875 break;
5876 }
5877 if (image == (Image *) NULL)
5878 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5879 attribute)
5880 else
5881 {
5882 value=GetImageProperty(image,attribute,exception);
5883 if (value != (const char *) NULL)
5884 {
5885 s=newSVpv(value,0);
5886 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5887 }
5888 else
5889 if (*attribute != '%')
5890 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5891 attribute)
5892 else
5893 {
5894 char
5895 *meta;
5896
5897 meta=InterpretImageProperties(info ? info->image_info :
5898 (ImageInfo *) NULL,image,attribute,exception);
5899 s=newSVpv(meta,0);
5900 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5901 meta=(char *) RelinquishMagickMemory(meta);
5902 }
5903 }
5904 }
5905 exception=DestroyExceptionInfo(exception);
5906 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5907 }
5908
5909#
5910###############################################################################
5911# #
5912# #
5913# #
5914# G e t A u t h e n t i c P i x e l s #
5915# #
5916# #
5917# #
5918###############################################################################
5919#
5920#
5921void *
5922GetAuthenticPixels(ref,...)
5923 Image::Magick ref = NO_INIT
5924 ALIAS:
5925 getauthenticpixels = 1
5926 GetImagePixels = 2
5927 getimagepixels = 3
5928 CODE:
5929 {
5930 char
5931 *attribute;
5932
5933 ExceptionInfo
5934 *exception;
5935
5936 Image
5937 *image;
5938
5939 RectangleInfo
5940 region;
5941
5942 ssize_t
5943 i;
5944
5945 struct PackageInfo
5946 *info;
5947
5948 SV
5949 *perl_exception,
5950 *reference;
5951
5952 void
5953 *blob = NULL;
5954
5955 PERL_UNUSED_VAR(ref);
5956 PERL_UNUSED_VAR(ix);
5957 exception=AcquireExceptionInfo();
5958 perl_exception=newSVpv("",0);
5959 if (sv_isobject(ST(0)) == 0)
5960 {
5961 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5962 PackageName);
5963 goto PerlException;
5964 }
5965 reference=SvRV(ST(0));
5966
5967 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5968 if (image == (Image *) NULL)
5969 {
5970 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5971 PackageName);
5972 goto PerlException;
5973 }
5974
5975 region.x=0;
5976 region.y=0;
5977 region.width=image->columns;
5978 region.height=1;
5979 if (items == 1)
5980 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5981 for (i=2; i < items; i+=2)
5982 {
5983 attribute=(char *) SvPV(ST(i-1),na);
5984 switch (*attribute)
5985 {
5986 case 'g':
5987 case 'G':
5988 {
5989 if (LocaleCompare(attribute,"geometry") == 0)
5990 {
5991 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5992 break;
5993 }
5994 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5995 attribute);
5996 break;
5997 }
5998 case 'H':
5999 case 'h':
6000 {
6001 if (LocaleCompare(attribute,"height") == 0)
6002 {
6003 region.height=SvIV(ST(i));
6004 continue;
6005 }
6006 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6007 attribute);
6008 break;
6009 }
6010 case 'X':
6011 case 'x':
6012 {
6013 if (LocaleCompare(attribute,"x") == 0)
6014 {
6015 region.x=SvIV(ST(i));
6016 continue;
6017 }
6018 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6019 attribute);
6020 break;
6021 }
6022 case 'Y':
6023 case 'y':
6024 {
6025 if (LocaleCompare(attribute,"y") == 0)
6026 {
6027 region.y=SvIV(ST(i));
6028 continue;
6029 }
6030 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6031 attribute);
6032 break;
6033 }
6034 case 'W':
6035 case 'w':
6036 {
6037 if (LocaleCompare(attribute,"width") == 0)
6038 {
6039 region.width=SvIV(ST(i));
6040 continue;
6041 }
6042 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6043 attribute);
6044 break;
6045 }
6046 }
6047 }
6048 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
6049 region.height,exception);
6050 if (blob != (void *) NULL)
6051 goto PerlEnd;
6052
6053 PerlException:
6054 InheritPerlException(exception,perl_exception);
6055 exception=DestroyExceptionInfo(exception);
6056 SvREFCNT_dec(perl_exception); /* throw away all errors */
6057
6058 PerlEnd:
6059 RETVAL = blob;
6060 }
6061 OUTPUT:
6062 RETVAL
6063
6064#
6065###############################################################################
6066# #
6067# #
6068# #
6069# G e t V i r t u a l P i x e l s #
6070# #
6071# #
6072# #
6073###############################################################################
6074#
6075#
6076void *
6077GetVirtualPixels(ref,...)
6078 Image::Magick ref = NO_INIT
6079 ALIAS:
6080 getvirtualpixels = 1
6081 AcquireImagePixels = 2
6082 acquireimagepixels = 3
6083 CODE:
6084 {
6085 char
6086 *attribute;
6087
6088 const void
6089 *blob = NULL;
6090
6091 ExceptionInfo
6092 *exception;
6093
6094 Image
6095 *image;
6096
6097 RectangleInfo
6098 region;
6099
6100 ssize_t
6101 i;
6102
6103 struct PackageInfo
6104 *info;
6105
6106 SV
6107 *perl_exception,
6108 *reference;
6109
6110 PERL_UNUSED_VAR(ref);
6111 PERL_UNUSED_VAR(ix);
6112 exception=AcquireExceptionInfo();
6113 perl_exception=newSVpv("",0);
6114 if (sv_isobject(ST(0)) == 0)
6115 {
6116 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6117 PackageName);
6118 goto PerlException;
6119 }
6120 reference=SvRV(ST(0));
6121
6122 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6123 if (image == (Image *) NULL)
6124 {
6125 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6126 PackageName);
6127 goto PerlException;
6128 }
6129
6130 region.x=0;
6131 region.y=0;
6132 region.width=image->columns;
6133 region.height=1;
6134 if (items == 1)
6135 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6136 for (i=2; i < items; i+=2)
6137 {
6138 attribute=(char *) SvPV(ST(i-1),na);
6139 switch (*attribute)
6140 {
6141 case 'g':
6142 case 'G':
6143 {
6144 if (LocaleCompare(attribute,"geometry") == 0)
6145 {
6146 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6147 break;
6148 }
6149 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6150 attribute);
6151 break;
6152 }
6153 case 'H':
6154 case 'h':
6155 {
6156 if (LocaleCompare(attribute,"height") == 0)
6157 {
6158 region.height=SvIV(ST(i));
6159 continue;
6160 }
6161 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6162 attribute);
6163 break;
6164 }
6165 case 'X':
6166 case 'x':
6167 {
6168 if (LocaleCompare(attribute,"x") == 0)
6169 {
6170 region.x=SvIV(ST(i));
6171 continue;
6172 }
6173 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6174 attribute);
6175 break;
6176 }
6177 case 'Y':
6178 case 'y':
6179 {
6180 if (LocaleCompare(attribute,"y") == 0)
6181 {
6182 region.y=SvIV(ST(i));
6183 continue;
6184 }
6185 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6186 attribute);
6187 break;
6188 }
6189 case 'W':
6190 case 'w':
6191 {
6192 if (LocaleCompare(attribute,"width") == 0)
6193 {
6194 region.width=SvIV(ST(i));
6195 continue;
6196 }
6197 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6198 attribute);
6199 break;
6200 }
6201 }
6202 }
6203 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6204 region.height,exception);
6205 if (blob != (void *) NULL)
6206 goto PerlEnd;
6207
6208 PerlException:
6209 InheritPerlException(exception,perl_exception);
6210 exception=DestroyExceptionInfo(exception);
6211 SvREFCNT_dec(perl_exception); /* throw away all errors */
6212
6213 PerlEnd:
6214 RETVAL = (void *) blob;
6215 }
6216 OUTPUT:
6217 RETVAL
6218
6219#
6220###############################################################################
6221# #
6222# #
6223# #
6224# G e t A u t h e n t i c M e t a c o n t e n t #
6225# #
6226# #
6227# #
6228###############################################################################
6229#
6230#
6231void *
6232GetAuthenticMetacontent(ref,...)
6233 Image::Magick ref = NO_INIT
6234 ALIAS:
6235 getauthenticmetacontent = 1
6236 GetMetacontent = 2
6237 getmetacontent = 3
6238 CODE:
6239 {
6240 ExceptionInfo
6241 *exception;
6242
6243 Image
6244 *image;
6245
6246 struct PackageInfo
6247 *info;
6248
6249 SV
6250 *perl_exception,
6251 *reference;
6252
6253 void
6254 *blob = NULL;
6255
6256 PERL_UNUSED_VAR(ref);
6257 PERL_UNUSED_VAR(ix);
6258 exception=AcquireExceptionInfo();
6259 perl_exception=newSVpv("",0);
6260 if (sv_isobject(ST(0)) == 0)
6261 {
6262 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6263 PackageName);
6264 goto PerlException;
6265 }
6266 reference=SvRV(ST(0));
6267
6268 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6269 if (image == (Image *) NULL)
6270 {
6271 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6272 PackageName);
6273 goto PerlException;
6274 }
6275
6276 blob=(void *) GetAuthenticMetacontent(image);
6277 if (blob != (void *) NULL)
6278 goto PerlEnd;
6279
6280 PerlException:
6281 InheritPerlException(exception,perl_exception);
6282 exception=DestroyExceptionInfo(exception);
6283 SvREFCNT_dec(perl_exception); /* throw away all errors */
6284
6285 PerlEnd:
6286 RETVAL = blob;
6287 }
6288 OUTPUT:
6289 RETVAL
6290
6291#
6292###############################################################################
6293# #
6294# #
6295# #
6296# G e t V i r t u a l M e t a c o n t e n t #
6297# #
6298# #
6299# #
6300###############################################################################
6301#
6302#
6303void *
6304GetVirtualMetacontent(ref,...)
6305 Image::Magick ref = NO_INIT
6306 ALIAS:
6307 getvirtualmetacontent = 1
6308 CODE:
6309 {
6310 ExceptionInfo
6311 *exception;
6312
6313 Image
6314 *image;
6315
6316 struct PackageInfo
6317 *info;
6318
6319 SV
6320 *perl_exception,
6321 *reference;
6322
6323 void
6324 *blob = NULL;
6325
6326 PERL_UNUSED_VAR(ref);
6327 PERL_UNUSED_VAR(ix);
6328 exception=AcquireExceptionInfo();
6329 perl_exception=newSVpv("",0);
6330 if (sv_isobject(ST(0)) == 0)
6331 {
6332 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6333 PackageName);
6334 goto PerlException;
6335 }
6336 reference=SvRV(ST(0));
6337
6338 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6339 if (image == (Image *) NULL)
6340 {
6341 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6342 PackageName);
6343 goto PerlException;
6344 }
6345
6346 blob=(void *) GetVirtualMetacontent(image);
6347 if (blob != (void *) NULL)
6348 goto PerlEnd;
6349
6350 PerlException:
6351 InheritPerlException(exception,perl_exception);
6352 exception=DestroyExceptionInfo(exception);
6353 SvREFCNT_dec(perl_exception); /* throw away all errors */
6354
6355 PerlEnd:
6356 RETVAL = blob;
6357 }
6358 OUTPUT:
6359 RETVAL
6360
6361#
6362###############################################################################
6363# #
6364# #
6365# #
6366# H i s t o g r a m #
6367# #
6368# #
6369# #
6370###############################################################################
6371#
6372#
6373void
6374Histogram(ref,...)
6375 Image::Magick ref=NO_INIT
6376 ALIAS:
6377 HistogramImage = 1
6378 histogram = 2
6379 histogramimage = 3
6380 PPCODE:
6381 {
6382 AV
6383 *av;
6384
6385 char
cristy151b66d2015-04-15 10:50:31 +00006386 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006387
6388 PixelInfo
6389 *histogram;
6390
6391 ExceptionInfo
6392 *exception;
6393
6394 Image
6395 *image;
6396
6397 register ssize_t
6398 i;
6399
6400 ssize_t
6401 count;
6402
6403 struct PackageInfo
6404 *info;
6405
6406 SV
6407 *perl_exception,
6408 *reference;
6409
6410 size_t
6411 number_colors;
6412
6413 PERL_UNUSED_VAR(ref);
6414 PERL_UNUSED_VAR(ix);
6415 exception=AcquireExceptionInfo();
6416 perl_exception=newSVpv("",0);
6417 av=NULL;
6418 if (sv_isobject(ST(0)) == 0)
6419 {
6420 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6421 PackageName);
6422 goto PerlException;
6423 }
6424 reference=SvRV(ST(0));
6425 av=newAV();
6426 SvREFCNT_dec(av);
6427 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6428 if (image == (Image *) NULL)
6429 {
6430 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6431 PackageName);
6432 goto PerlException;
6433 }
cristy4a3ce0a2013-08-03 20:06:59 +00006434 count=0;
6435 for ( ; image; image=image->next)
6436 {
6437 histogram=GetImageHistogram(image,&number_colors,exception);
6438 if (histogram == (PixelInfo *) NULL)
6439 continue;
6440 count+=(ssize_t) number_colors;
6441 EXTEND(sp,6*count);
6442 for (i=0; i < (ssize_t) number_colors; i++)
6443 {
cristy151b66d2015-04-15 10:50:31 +00006444 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006445 histogram[i].red);
6446 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006447 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006448 histogram[i].green);
6449 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006450 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006451 histogram[i].blue);
6452 PUSHs(sv_2mortal(newSVpv(message,0)));
6453 if (image->colorspace == CMYKColorspace)
6454 {
cristy151b66d2015-04-15 10:50:31 +00006455 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006456 histogram[i].black);
6457 PUSHs(sv_2mortal(newSVpv(message,0)));
6458 }
cristy151b66d2015-04-15 10:50:31 +00006459 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006460 histogram[i].alpha);
6461 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006462 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006463 histogram[i].count);
6464 PUSHs(sv_2mortal(newSVpv(message,0)));
6465 }
6466 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6467 }
6468
6469 PerlException:
6470 InheritPerlException(exception,perl_exception);
6471 exception=DestroyExceptionInfo(exception);
6472 SvREFCNT_dec(perl_exception);
6473 }
6474
6475#
6476###############################################################################
6477# #
6478# #
6479# #
6480# G e t P i x e l #
6481# #
6482# #
6483# #
6484###############################################################################
6485#
6486#
6487void
6488GetPixel(ref,...)
6489 Image::Magick ref=NO_INIT
6490 ALIAS:
6491 getpixel = 1
6492 getPixel = 2
6493 PPCODE:
6494 {
6495 AV
6496 *av;
6497
6498 char
6499 *attribute;
6500
6501 ExceptionInfo
6502 *exception;
6503
6504 Image
6505 *image;
6506
6507 MagickBooleanType
6508 normalize;
6509
6510 RectangleInfo
6511 region;
6512
6513 register const Quantum
6514 *p;
6515
6516 register ssize_t
6517 i;
6518
6519 ssize_t
6520 option;
6521
6522 struct PackageInfo
6523 *info;
6524
6525 SV
6526 *perl_exception,
6527 *reference; /* reference is the SV* of ref=SvIV(reference) */
6528
6529 PERL_UNUSED_VAR(ref);
6530 PERL_UNUSED_VAR(ix);
6531 exception=AcquireExceptionInfo();
6532 perl_exception=newSVpv("",0);
6533 reference=SvRV(ST(0));
6534 av=(AV *) reference;
6535 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6536 exception);
6537 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6538 if (image == (Image *) NULL)
6539 {
6540 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6541 PackageName);
6542 goto PerlException;
6543 }
6544 normalize=MagickTrue;
6545 region.x=0;
6546 region.y=0;
6547 region.width=image->columns;
6548 region.height=1;
6549 if (items == 1)
6550 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6551 for (i=2; i < items; i+=2)
6552 {
6553 attribute=(char *) SvPV(ST(i-1),na);
6554 switch (*attribute)
6555 {
6556 case 'C':
6557 case 'c':
6558 {
6559 if (LocaleCompare(attribute,"channel") == 0)
6560 {
6561 ssize_t
6562 option;
6563
6564 option=ParseChannelOption(SvPV(ST(i),na));
6565 if (option < 0)
6566 {
6567 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6568 SvPV(ST(i),na));
6569 return;
6570 }
cristybcd59342015-06-07 14:07:19 +00006571 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00006572 break;
6573 }
6574 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6575 attribute);
6576 break;
6577 }
6578 case 'g':
6579 case 'G':
6580 {
6581 if (LocaleCompare(attribute,"geometry") == 0)
6582 {
6583 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6584 break;
6585 }
6586 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6587 attribute);
6588 break;
6589 }
6590 case 'N':
6591 case 'n':
6592 {
6593 if (LocaleCompare(attribute,"normalize") == 0)
6594 {
6595 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6596 SvPV(ST(i),na));
6597 if (option < 0)
6598 {
6599 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6600 SvPV(ST(i),na));
6601 break;
6602 }
6603 normalize=option != 0 ? MagickTrue : MagickFalse;
6604 break;
6605 }
6606 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6607 attribute);
6608 break;
6609 }
6610 case 'x':
6611 case 'X':
6612 {
6613 if (LocaleCompare(attribute,"x") == 0)
6614 {
6615 region.x=SvIV(ST(i));
6616 break;
6617 }
6618 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6619 attribute);
6620 break;
6621 }
6622 case 'y':
6623 case 'Y':
6624 {
6625 if (LocaleCompare(attribute,"y") == 0)
6626 {
6627 region.y=SvIV(ST(i));
6628 break;
6629 }
6630 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6631 attribute);
6632 break;
6633 }
6634 default:
6635 {
6636 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6637 attribute);
6638 break;
6639 }
6640 }
6641 }
6642 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6643 if (p == (const Quantum *) NULL)
6644 PUSHs(&sv_undef);
6645 else
6646 {
6647 double
6648 scale;
6649
6650 scale=1.0;
6651 if (normalize != MagickFalse)
6652 scale=1.0/QuantumRange;
6653 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6654 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6655 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6656 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6657 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6658 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6659 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6660 (image->colorspace == CMYKColorspace))
6661 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6662 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6663 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6664 }
6665
6666 PerlException:
6667 InheritPerlException(exception,perl_exception);
6668 exception=DestroyExceptionInfo(exception);
6669 SvREFCNT_dec(perl_exception);
6670 }
6671
6672#
6673###############################################################################
6674# #
6675# #
6676# #
6677# G e t P i x e l s #
6678# #
6679# #
6680# #
6681###############################################################################
6682#
6683#
6684void
6685GetPixels(ref,...)
6686 Image::Magick ref=NO_INIT
6687 ALIAS:
6688 getpixels = 1
6689 getPixels = 2
6690 PPCODE:
6691 {
6692 AV
6693 *av;
6694
6695 char
6696 *attribute;
6697
6698 const char
6699 *map;
6700
6701 ExceptionInfo
6702 *exception;
6703
6704 Image
6705 *image;
6706
6707 MagickBooleanType
6708 normalize,
6709 status;
6710
6711 RectangleInfo
6712 region;
6713
6714 register ssize_t
6715 i;
6716
6717 ssize_t
6718 option;
6719
6720 struct PackageInfo
6721 *info;
6722
6723 SV
6724 *perl_exception,
6725 *reference; /* reference is the SV* of ref=SvIV(reference) */
6726
6727 PERL_UNUSED_VAR(ref);
6728 PERL_UNUSED_VAR(ix);
6729 exception=AcquireExceptionInfo();
6730 perl_exception=newSVpv("",0);
6731 reference=SvRV(ST(0));
6732 av=(AV *) reference;
6733 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6734 exception);
6735 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6736 if (image == (Image *) NULL)
6737 {
6738 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6739 PackageName);
6740 goto PerlException;
6741 }
6742 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006743 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006744 map="RGBA";
6745 if (image->colorspace == CMYKColorspace)
6746 {
6747 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006748 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006749 map="CMYKA";
6750 }
6751 normalize=MagickFalse;
6752 region.x=0;
6753 region.y=0;
6754 region.width=image->columns;
6755 region.height=1;
6756 if (items == 1)
6757 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6758 for (i=2; i < items; i+=2)
6759 {
6760 attribute=(char *) SvPV(ST(i-1),na);
6761 switch (*attribute)
6762 {
6763 case 'g':
6764 case 'G':
6765 {
6766 if (LocaleCompare(attribute,"geometry") == 0)
6767 {
6768 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6769 break;
6770 }
6771 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6772 attribute);
6773 break;
6774 }
6775 case 'H':
6776 case 'h':
6777 {
6778 if (LocaleCompare(attribute,"height") == 0)
6779 {
6780 region.height=SvIV(ST(i));
6781 break;
6782 }
6783 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6784 attribute);
6785 break;
6786 }
6787 case 'M':
6788 case 'm':
6789 {
6790 if (LocaleCompare(attribute,"map") == 0)
6791 {
6792 map=SvPV(ST(i),na);
6793 break;
6794 }
6795 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6796 attribute);
6797 break;
6798 }
6799 case 'N':
6800 case 'n':
6801 {
6802 if (LocaleCompare(attribute,"normalize") == 0)
6803 {
6804 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6805 SvPV(ST(i),na));
6806 if (option < 0)
6807 {
6808 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6809 SvPV(ST(i),na));
6810 break;
6811 }
6812 normalize=option != 0 ? MagickTrue : MagickFalse;
6813 break;
6814 }
6815 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6816 attribute);
6817 break;
6818 }
6819 case 'W':
6820 case 'w':
6821 {
6822 if (LocaleCompare(attribute,"width") == 0)
6823 {
6824 region.width=SvIV(ST(i));
6825 break;
6826 }
6827 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6828 attribute);
6829 break;
6830 }
6831 case 'x':
6832 case 'X':
6833 {
6834 if (LocaleCompare(attribute,"x") == 0)
6835 {
6836 region.x=SvIV(ST(i));
6837 break;
6838 }
6839 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6840 attribute);
6841 break;
6842 }
6843 case 'y':
6844 case 'Y':
6845 {
6846 if (LocaleCompare(attribute,"y") == 0)
6847 {
6848 region.y=SvIV(ST(i));
6849 break;
6850 }
6851 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6852 attribute);
6853 break;
6854 }
6855 default:
6856 {
6857 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6858 attribute);
6859 break;
6860 }
6861 }
6862 }
6863 if (normalize != MagickFalse)
6864 {
6865 float
6866 *pixels;
6867
6868 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6869 region.height*sizeof(*pixels));
6870 if (pixels == (float *) NULL)
6871 {
6872 ThrowPerlException(exception,ResourceLimitError,
6873 "MemoryAllocationFailed",PackageName);
6874 goto PerlException;
6875 }
6876 status=ExportImagePixels(image,region.x,region.y,region.width,
6877 region.height,map,FloatPixel,pixels,exception);
6878 if (status == MagickFalse)
6879 PUSHs(&sv_undef);
6880 else
6881 {
6882 EXTEND(sp,strlen(map)*region.width*region.height);
6883 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6884 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6885 }
6886 pixels=(float *) RelinquishMagickMemory(pixels);
6887 }
6888 else
6889 {
6890 Quantum
6891 *pixels;
6892
6893 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6894 region.height*sizeof(*pixels));
6895 if (pixels == (Quantum *) NULL)
6896 {
6897 ThrowPerlException(exception,ResourceLimitError,
6898 "MemoryAllocationFailed",PackageName);
6899 goto PerlException;
6900 }
6901 status=ExportImagePixels(image,region.x,region.y,region.width,
6902 region.height,map,QuantumPixel,pixels,exception);
6903 if (status == MagickFalse)
6904 PUSHs(&sv_undef);
6905 else
6906 {
6907 EXTEND(sp,strlen(map)*region.width*region.height);
6908 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6909 PUSHs(sv_2mortal(newSViv(pixels[i])));
6910 }
6911 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6912 }
6913
6914 PerlException:
6915 InheritPerlException(exception,perl_exception);
6916 exception=DestroyExceptionInfo(exception);
6917 SvREFCNT_dec(perl_exception);
6918 }
6919
6920#
6921###############################################################################
6922# #
6923# #
6924# #
6925# I m a g e T o B l o b #
6926# #
6927# #
6928# #
6929###############################################################################
6930#
6931#
6932void
6933ImageToBlob(ref,...)
6934 Image::Magick ref=NO_INIT
6935 ALIAS:
6936 ImageToBlob = 1
6937 imagetoblob = 2
6938 toblob = 3
6939 blob = 4
6940 PPCODE:
6941 {
6942 char
cristy151b66d2015-04-15 10:50:31 +00006943 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006944
6945 ExceptionInfo
6946 *exception;
6947
6948 Image
6949 *image,
6950 *next;
6951
6952 register ssize_t
6953 i;
6954
6955 struct PackageInfo
6956 *info,
6957 *package_info;
6958
6959 size_t
6960 length;
6961
6962 ssize_t
6963 scene;
6964
6965 SV
6966 *perl_exception,
6967 *reference;
6968
6969 void
6970 *blob;
6971
6972 PERL_UNUSED_VAR(ref);
6973 PERL_UNUSED_VAR(ix);
6974 exception=AcquireExceptionInfo();
6975 perl_exception=newSVpv("",0);
6976 package_info=(struct PackageInfo *) NULL;
6977 if (sv_isobject(ST(0)) == 0)
6978 {
6979 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6980 PackageName);
6981 goto PerlException;
6982 }
6983 reference=SvRV(ST(0));
6984 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6985 if (image == (Image *) NULL)
6986 {
6987 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6988 PackageName);
6989 goto PerlException;
6990 }
6991 package_info=ClonePackageInfo(info,exception);
6992 for (i=2; i < items; i+=2)
6993 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6994 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006995 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006996 scene=0;
6997 for (next=image; next; next=next->next)
6998 {
cristy151b66d2015-04-15 10:50:31 +00006999 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00007000 next->scene=scene++;
7001 }
7002 SetImageInfo(package_info->image_info,(unsigned int)
7003 GetImageListLength(image),exception);
7004 EXTEND(sp,(ssize_t) GetImageListLength(image));
7005 for ( ; image; image=image->next)
7006 {
7007 length=0;
7008 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
7009 if (blob != (char *) NULL)
7010 {
7011 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
7012 blob=(unsigned char *) RelinquishMagickMemory(blob);
7013 }
7014 if (package_info->image_info->adjoin)
7015 break;
7016 }
7017
7018 PerlException:
7019 if (package_info != (struct PackageInfo *) NULL)
7020 DestroyPackageInfo(package_info);
7021 InheritPerlException(exception,perl_exception);
7022 exception=DestroyExceptionInfo(exception);
7023 SvREFCNT_dec(perl_exception); /* throw away all errors */
7024 }
7025
7026#
7027###############################################################################
7028# #
7029# #
7030# #
7031# L a y e r s #
7032# #
7033# #
7034# #
7035###############################################################################
7036#
7037#
7038void
7039Layers(ref,...)
7040 Image::Magick ref=NO_INIT
7041 ALIAS:
7042 Layers = 1
7043 layers = 2
7044 OptimizeImageLayers = 3
7045 optimizelayers = 4
7046 optimizeimagelayers = 5
7047 PPCODE:
7048 {
7049 AV
7050 *av;
7051
7052 char
7053 *attribute;
7054
7055 CompositeOperator
7056 compose;
7057
7058 ExceptionInfo
7059 *exception;
7060
7061 HV
7062 *hv;
7063
7064 Image
7065 *image,
7066 *layers;
7067
7068 LayerMethod
7069 method;
7070
7071 register ssize_t
7072 i;
7073
7074 ssize_t
7075 option,
7076 sp;
7077
7078 struct PackageInfo
7079 *info;
7080
7081 SV
7082 *av_reference,
7083 *perl_exception,
7084 *reference,
7085 *rv,
7086 *sv;
7087
7088 PERL_UNUSED_VAR(ref);
7089 PERL_UNUSED_VAR(ix);
7090 exception=AcquireExceptionInfo();
7091 perl_exception=newSVpv("",0);
7092 sv=NULL;
7093 if (sv_isobject(ST(0)) == 0)
7094 {
7095 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7096 PackageName);
7097 goto PerlException;
7098 }
7099 reference=SvRV(ST(0));
7100 hv=SvSTASH(reference);
7101 av=newAV();
7102 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7103 SvREFCNT_dec(av);
7104 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7105 if (image == (Image *) NULL)
7106 {
7107 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7108 PackageName);
7109 goto PerlException;
7110 }
7111 compose=image->compose;
7112 method=OptimizeLayer;
7113 for (i=2; i < items; i+=2)
7114 {
7115 attribute=(char *) SvPV(ST(i-1),na);
7116 switch (*attribute)
7117 {
7118 case 'C':
7119 case 'c':
7120 {
7121 if (LocaleCompare(attribute,"compose") == 0)
7122 {
7123 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7124 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7125 if (sp < 0)
7126 {
7127 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7128 SvPV(ST(i),na));
7129 break;
7130 }
7131 compose=(CompositeOperator) sp;
7132 break;
7133 }
7134 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7135 attribute);
7136 break;
7137 }
7138 case 'M':
7139 case 'm':
7140 {
7141 if (LocaleCompare(attribute,"method") == 0)
7142 {
7143 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7144 SvPV(ST(i),na));
7145 if (option < 0)
7146 {
7147 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7148 SvPV(ST(i),na));
7149 break;
7150 }
7151 method=(LayerMethod) option;
7152 break;
7153 }
7154 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7155 attribute);
7156 break;
7157 }
7158 default:
7159 {
7160 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7161 attribute);
7162 break;
7163 }
7164 }
7165 }
7166 layers=(Image *) NULL;
7167 switch (method)
7168 {
7169 case CompareAnyLayer:
7170 case CompareClearLayer:
7171 case CompareOverlayLayer:
7172 default:
7173 {
7174 layers=CompareImagesLayers(image,method,exception);
7175 break;
7176 }
7177 case MergeLayer:
7178 case FlattenLayer:
7179 case MosaicLayer:
7180 {
7181 layers=MergeImageLayers(image,method,exception);
7182 break;
7183 }
7184 case DisposeLayer:
7185 {
7186 layers=DisposeImages(image,exception);
7187 break;
7188 }
7189 case OptimizeImageLayer:
7190 {
7191 layers=OptimizeImageLayers(image,exception);
7192 break;
7193 }
7194 case OptimizePlusLayer:
7195 {
7196 layers=OptimizePlusImageLayers(image,exception);
7197 break;
7198 }
7199 case OptimizeTransLayer:
7200 {
7201 OptimizeImageTransparency(image,exception);
7202 break;
7203 }
7204 case RemoveDupsLayer:
7205 {
7206 RemoveDuplicateLayers(&image,exception);
7207 break;
7208 }
7209 case RemoveZeroLayer:
7210 {
7211 RemoveZeroDelayLayers(&image,exception);
7212 break;
7213 }
7214 case OptimizeLayer:
7215 {
7216 QuantizeInfo
7217 *quantize_info;
7218
7219 /*
7220 General Purpose, GIF Animation Optimizer.
7221 */
7222 layers=CoalesceImages(image,exception);
7223 if (layers == (Image *) NULL)
7224 break;
7225 image=layers;
7226 layers=OptimizeImageLayers(image,exception);
7227 if (layers == (Image *) NULL)
7228 break;
7229 image=DestroyImageList(image);
7230 image=layers;
7231 layers=(Image *) NULL;
7232 OptimizeImageTransparency(image,exception);
7233 quantize_info=AcquireQuantizeInfo(info->image_info);
7234 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7235 quantize_info=DestroyQuantizeInfo(quantize_info);
7236 break;
7237 }
7238 case CompositeLayer:
7239 {
7240 Image
7241 *source;
7242
7243 RectangleInfo
7244 geometry;
7245
7246 /*
7247 Split image sequence at the first 'NULL:' image.
7248 */
7249 source=image;
7250 while (source != (Image *) NULL)
7251 {
7252 source=GetNextImageInList(source);
7253 if ((source != (Image *) NULL) &&
7254 (LocaleCompare(source->magick,"NULL") == 0))
7255 break;
7256 }
7257 if (source != (Image *) NULL)
7258 {
7259 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7260 (GetNextImageInList(source) == (Image *) NULL))
7261 source=(Image *) NULL;
7262 else
7263 {
7264 /*
7265 Separate the two lists, junk the null: image.
7266 */
7267 source=SplitImageList(source->previous);
7268 DeleteImageFromList(&source);
7269 }
7270 }
7271 if (source == (Image *) NULL)
7272 {
7273 (void) ThrowMagickException(exception,GetMagickModule(),
7274 OptionError,"MissingNullSeparator","layers Composite");
7275 break;
7276 }
7277 /*
7278 Adjust offset with gravity and virtual canvas.
7279 */
7280 SetGeometry(image,&geometry);
7281 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7282 geometry.width=source->page.width != 0 ? source->page.width :
7283 source->columns;
7284 geometry.height=source->page.height != 0 ? source->page.height :
7285 source->rows;
7286 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7287 image->columns,image->page.height != 0 ? image->page.height :
7288 image->rows,image->gravity,&geometry);
7289 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7290 source=DestroyImageList(source);
7291 break;
7292 }
7293 }
7294 if (layers != (Image *) NULL)
7295 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007296 else
7297 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007298 if (image == (Image *) NULL)
7299 goto PerlException;
7300 for ( ; image; image=image->next)
7301 {
7302 AddImageToRegistry(sv,image);
7303 rv=newRV(sv);
7304 av_push(av,sv_bless(rv,hv));
7305 SvREFCNT_dec(sv);
7306 }
7307 exception=DestroyExceptionInfo(exception);
7308 ST(0)=av_reference;
7309 SvREFCNT_dec(perl_exception);
7310 XSRETURN(1);
7311
7312 PerlException:
7313 InheritPerlException(exception,perl_exception);
7314 exception=DestroyExceptionInfo(exception);
7315 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7316 SvPOK_on(perl_exception);
7317 ST(0)=sv_2mortal(perl_exception);
7318 XSRETURN(1);
7319 }
7320
7321#
7322###############################################################################
7323# #
7324# #
7325# #
7326# M a g i c k T o M i m e #
7327# #
7328# #
7329# #
7330###############################################################################
7331#
7332#
7333SV *
7334MagickToMime(ref,name)
7335 Image::Magick ref=NO_INIT
7336 char *name
7337 ALIAS:
7338 magicktomime = 1
7339 CODE:
7340 {
7341 char
7342 *mime;
7343
7344 PERL_UNUSED_VAR(ref);
7345 PERL_UNUSED_VAR(ix);
7346 mime=MagickToMime(name);
7347 RETVAL=newSVpv(mime,0);
7348 mime=(char *) RelinquishMagickMemory(mime);
7349 }
7350 OUTPUT:
7351 RETVAL
7352
7353#
7354###############################################################################
7355# #
7356# #
7357# #
7358# M o g r i f y #
7359# #
7360# #
7361# #
7362###############################################################################
7363#
7364#
7365void
7366Mogrify(ref,...)
7367 Image::Magick ref=NO_INIT
7368 ALIAS:
7369 Comment = 1
7370 CommentImage = 2
7371 Label = 3
7372 LabelImage = 4
7373 AddNoise = 5
7374 AddNoiseImage = 6
7375 Colorize = 7
7376 ColorizeImage = 8
7377 Border = 9
7378 BorderImage = 10
7379 Blur = 11
7380 BlurImage = 12
7381 Chop = 13
7382 ChopImage = 14
7383 Crop = 15
7384 CropImage = 16
7385 Despeckle = 17
7386 DespeckleImage = 18
7387 Edge = 19
7388 EdgeImage = 20
7389 Emboss = 21
7390 EmbossImage = 22
7391 Enhance = 23
7392 EnhanceImage = 24
7393 Flip = 25
7394 FlipImage = 26
7395 Flop = 27
7396 FlopImage = 28
7397 Frame = 29
7398 FrameImage = 30
7399 Implode = 31
7400 ImplodeImage = 32
7401 Magnify = 33
7402 MagnifyImage = 34
7403 MedianFilter = 35
7404 MedianConvolveImage = 36
7405 Minify = 37
7406 MinifyImage = 38
7407 OilPaint = 39
7408 OilPaintImage = 40
7409 ReduceNoise = 41
7410 ReduceNoiseImage = 42
7411 Roll = 43
7412 RollImage = 44
7413 Rotate = 45
7414 RotateImage = 46
7415 Sample = 47
7416 SampleImage = 48
7417 Scale = 49
7418 ScaleImage = 50
7419 Shade = 51
7420 ShadeImage = 52
7421 Sharpen = 53
7422 SharpenImage = 54
7423 Shear = 55
7424 ShearImage = 56
7425 Spread = 57
7426 SpreadImage = 58
7427 Swirl = 59
7428 SwirlImage = 60
7429 Resize = 61
7430 ResizeImage = 62
7431 Zoom = 63
7432 ZoomImage = 64
7433 Annotate = 65
7434 AnnotateImage = 66
7435 ColorFloodfill = 67
7436 ColorFloodfillImage= 68
7437 Composite = 69
7438 CompositeImage = 70
7439 Contrast = 71
7440 ContrastImage = 72
7441 CycleColormap = 73
7442 CycleColormapImage = 74
7443 Draw = 75
7444 DrawImage = 76
7445 Equalize = 77
7446 EqualizeImage = 78
7447 Gamma = 79
7448 GammaImage = 80
7449 Map = 81
7450 MapImage = 82
7451 MatteFloodfill = 83
7452 MatteFloodfillImage= 84
7453 Modulate = 85
7454 ModulateImage = 86
7455 Negate = 87
7456 NegateImage = 88
7457 Normalize = 89
7458 NormalizeImage = 90
7459 NumberColors = 91
7460 NumberColorsImage = 92
7461 Opaque = 93
7462 OpaqueImage = 94
7463 Quantize = 95
7464 QuantizeImage = 96
7465 Raise = 97
7466 RaiseImage = 98
7467 Segment = 99
7468 SegmentImage = 100
7469 Signature = 101
7470 SignatureImage = 102
7471 Solarize = 103
7472 SolarizeImage = 104
7473 Sync = 105
7474 SyncImage = 106
7475 Texture = 107
7476 TextureImage = 108
7477 Evaluate = 109
7478 EvaluateImage = 110
7479 Transparent = 111
7480 TransparentImage = 112
7481 Threshold = 113
7482 ThresholdImage = 114
7483 Charcoal = 115
7484 CharcoalImage = 116
7485 Trim = 117
7486 TrimImage = 118
7487 Wave = 119
7488 WaveImage = 120
7489 Separate = 121
7490 SeparateImage = 122
7491 Stereo = 125
7492 StereoImage = 126
7493 Stegano = 127
7494 SteganoImage = 128
7495 Deconstruct = 129
7496 DeconstructImage = 130
7497 GaussianBlur = 131
7498 GaussianBlurImage = 132
7499 Convolve = 133
7500 ConvolveImage = 134
7501 Profile = 135
7502 ProfileImage = 136
7503 UnsharpMask = 137
7504 UnsharpMaskImage = 138
7505 MotionBlur = 139
7506 MotionBlurImage = 140
7507 OrderedDither = 141
7508 OrderedDitherImage = 142
7509 Shave = 143
7510 ShaveImage = 144
7511 Level = 145
7512 LevelImage = 146
7513 Clip = 147
7514 ClipImage = 148
7515 AffineTransform = 149
7516 AffineTransformImage = 150
7517 Difference = 151
7518 DifferenceImage = 152
7519 AdaptiveThreshold = 153
7520 AdaptiveThresholdImage = 154
7521 Resample = 155
7522 ResampleImage = 156
7523 Describe = 157
7524 DescribeImage = 158
7525 BlackThreshold = 159
7526 BlackThresholdImage= 160
7527 WhiteThreshold = 161
7528 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007529 RotationalBlur = 163
7530 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007531 Thumbnail = 165
7532 ThumbnailImage = 166
7533 Strip = 167
7534 StripImage = 168
7535 Tint = 169
7536 TintImage = 170
7537 Channel = 171
7538 ChannelImage = 172
7539 Splice = 173
7540 SpliceImage = 174
7541 Posterize = 175
7542 PosterizeImage = 176
7543 Shadow = 177
7544 ShadowImage = 178
7545 Identify = 179
7546 IdentifyImage = 180
7547 SepiaTone = 181
7548 SepiaToneImage = 182
7549 SigmoidalContrast = 183
7550 SigmoidalContrastImage = 184
7551 Extent = 185
7552 ExtentImage = 186
7553 Vignette = 187
7554 VignetteImage = 188
7555 ContrastStretch = 189
7556 ContrastStretchImage = 190
7557 Sans0 = 191
7558 Sans0Image = 192
7559 Sans1 = 193
7560 Sans1Image = 194
7561 AdaptiveSharpen = 195
7562 AdaptiveSharpenImage = 196
7563 Transpose = 197
7564 TransposeImage = 198
7565 Transverse = 199
7566 TransverseImage = 200
7567 AutoOrient = 201
7568 AutoOrientImage = 202
7569 AdaptiveBlur = 203
7570 AdaptiveBlurImage = 204
7571 Sketch = 205
7572 SketchImage = 206
7573 UniqueColors = 207
7574 UniqueColorsImage = 208
7575 AdaptiveResize = 209
7576 AdaptiveResizeImage= 210
7577 ClipMask = 211
7578 ClipMaskImage = 212
7579 LinearStretch = 213
7580 LinearStretchImage = 214
7581 ColorMatrix = 215
7582 ColorMatrixImage = 216
7583 Mask = 217
7584 MaskImage = 218
7585 Polaroid = 219
7586 PolaroidImage = 220
7587 FloodfillPaint = 221
7588 FloodfillPaintImage= 222
7589 Distort = 223
7590 DistortImage = 224
7591 Clut = 225
7592 ClutImage = 226
7593 LiquidRescale = 227
7594 LiquidRescaleImage = 228
7595 Encipher = 229
7596 EncipherImage = 230
7597 Decipher = 231
7598 DecipherImage = 232
7599 Deskew = 233
7600 DeskewImage = 234
7601 Remap = 235
7602 RemapImage = 236
7603 SparseColor = 237
7604 SparseColorImage = 238
7605 Function = 239
7606 FunctionImage = 240
7607 SelectiveBlur = 241
7608 SelectiveBlurImage = 242
7609 HaldClut = 243
7610 HaldClutImage = 244
7611 BlueShift = 245
7612 BlueShiftImage = 246
7613 ForwardFourierTransform = 247
7614 ForwardFourierTransformImage = 248
7615 InverseFourierTransform = 249
7616 InverseFourierTransformImage = 250
7617 ColorDecisionList = 251
7618 ColorDecisionListImage = 252
7619 AutoGamma = 253
7620 AutoGammaImage = 254
7621 AutoLevel = 255
7622 AutoLevelImage = 256
7623 LevelColors = 257
7624 LevelImageColors = 258
7625 Clamp = 259
7626 ClampImage = 260
7627 BrightnessContrast = 261
7628 BrightnessContrastImage = 262
7629 Morphology = 263
7630 MorphologyImage = 264
Cristy3ca633e2016-02-13 12:49:01 -05007631 Mode = 265
7632 ModeImage = 266
7633 Statistic = 267
7634 StatisticImage = 268
7635 Perceptible = 269
7636 PerceptibleImage = 270
7637 Poly = 271
7638 PolyImage = 272
7639 Grayscale = 273
7640 GrayscaleImage = 274
7641 CannyEdge = 275
7642 CannyEdgeImage = 276
7643 HoughLine = 277
7644 HoughLineImage = 278
7645 MeanShift = 279
7646 MeanShiftImage = 280
7647 Kuwahara = 281
7648 KuwaharaImage = 282
Cristy0f5df812017-07-04 18:30:05 -04007649 ConnectedComponents = 283
7650 ConnectedComponentsImage = 284
Cristy3ca633e2016-02-13 12:49:01 -05007651 CopyPixels = 285
7652 CopyImagePixels = 286
Cristy5488c982016-02-13 14:07:50 -05007653 Color = 287
7654 ColorImage = 288
Cristy2d830ed2016-02-21 10:54:16 -05007655 WaveletDenoise = 289
7656 WaveletDenoiseImage= 290
Cristy99a57162016-12-05 11:47:57 -05007657 Colorspace = 291
7658 ColorspaceImage = 292
Cristy53353872017-07-02 12:24:24 -04007659 AutoThreshold = 293
7660 AutoThresholdImage = 294
Cristy532b3382018-08-05 17:56:56 -04007661 RangeThreshold = 295
7662 RangeThresholdImage= 296
Cristy9f252542018-11-21 19:13:46 -05007663 CLAHE = 297
7664 CLAHEImage = 298
Cristyb4ab5192019-12-19 06:53:46 -05007665 Kmeans = 299
7666 KMeansImage = 300
Cristy89b4db02020-02-21 20:57:40 -05007667 ColorThreshold = 301
7668 ColorThresholdImage= 302
cristy4a3ce0a2013-08-03 20:06:59 +00007669 MogrifyRegion = 666
7670 PPCODE:
7671 {
7672 AffineMatrix
7673 affine,
7674 current;
7675
7676 char
7677 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007678 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007679
7680 ChannelType
7681 channel,
7682 channel_mask;
7683
7684 CompositeOperator
7685 compose;
7686
7687 const char
7688 *attribute,
7689 *value;
7690
7691 double
7692 angle;
7693
7694 ExceptionInfo
7695 *exception;
7696
7697 GeometryInfo
7698 geometry_info;
7699
7700 Image
7701 *image,
Cristy7e567962018-02-03 12:42:20 -05007702 *next;
cristy4a3ce0a2013-08-03 20:06:59 +00007703
cristy4a3ce0a2013-08-03 20:06:59 +00007704 MagickStatusType
7705 flags;
7706
7707 PixelInfo
7708 fill_color;
7709
7710 RectangleInfo
7711 geometry,
7712 region_info;
7713
7714 register ssize_t
7715 i;
7716
7717 ssize_t
7718 base,
7719 j,
7720 number_images;
7721
7722 struct Methods
7723 *rp;
7724
7725 struct PackageInfo
7726 *info;
7727
7728 SV
7729 *perl_exception,
7730 **pv,
7731 *reference,
7732 **reference_vector;
7733
7734 struct ArgumentList
7735 argument_list[MaxArguments];
7736
7737 PERL_UNUSED_VAR(ref);
7738 PERL_UNUSED_VAR(ix);
7739 exception=AcquireExceptionInfo();
7740 perl_exception=newSVpv("",0);
7741 reference_vector=NULL;
cristy4a3ce0a2013-08-03 20:06:59 +00007742 number_images=0;
7743 base=2;
7744 if (sv_isobject(ST(0)) == 0)
7745 {
7746 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7747 PackageName);
7748 goto PerlException;
7749 }
7750 reference=SvRV(ST(0));
7751 region_info.width=0;
7752 region_info.height=0;
7753 region_info.x=0;
7754 region_info.y=0;
cristy4a3ce0a2013-08-03 20:06:59 +00007755 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7756 if (ix && (ix != 666))
7757 {
7758 /*
7759 Called as Method(...)
7760 */
7761 ix=(ix+1)/2;
7762 rp=(&Methods[ix-1]);
7763 attribute=rp->name;
7764 }
7765 else
7766 {
7767 /*
7768 Called as Mogrify("Method",...)
7769 */
7770 attribute=(char *) SvPV(ST(1),na);
7771 if (ix)
7772 {
7773 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7774 attribute=(char *) SvPV(ST(2),na);
7775 base++;
7776 }
7777 for (rp=Methods; ; rp++)
7778 {
7779 if (rp >= EndOf(Methods))
7780 {
7781 ThrowPerlException(exception,OptionError,
7782 "UnrecognizedPerlMagickMethod",attribute);
7783 goto PerlException;
7784 }
7785 if (strEQcase(attribute,rp->name))
7786 break;
7787 }
7788 ix=rp-Methods+1;
7789 base++;
7790 }
7791 if (image == (Image *) NULL)
7792 {
7793 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7794 goto PerlException;
7795 }
7796 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7797 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7798 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7799 {
7800 Arguments
7801 *pp,
7802 *qq;
7803
7804 ssize_t
7805 ssize_test;
7806
7807 struct ArgumentList
7808 *al;
7809
7810 SV
7811 *sv;
7812
7813 sv=NULL;
7814 ssize_test=0;
7815 pp=(Arguments *) NULL;
7816 qq=rp->arguments;
7817 if (i == items)
7818 {
7819 pp=rp->arguments,
7820 sv=ST(i-1);
7821 }
7822 else
7823 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7824 {
7825 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7826 break;
7827 if (strEQcase(attribute,qq->method) > ssize_test)
7828 {
7829 pp=qq;
7830 ssize_test=strEQcase(attribute,qq->method);
7831 }
7832 }
7833 if (pp == (Arguments *) NULL)
7834 {
7835 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7836 attribute);
7837 goto continue_outer_loop;
7838 }
7839 al=(&argument_list[pp-rp->arguments]);
7840 switch (pp->type)
7841 {
7842 case ArrayReference:
7843 {
7844 if (SvTYPE(sv) != SVt_RV)
7845 {
cristy151b66d2015-04-15 10:50:31 +00007846 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007847 "invalid %.60s value",pp->method);
7848 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7849 goto continue_outer_loop;
7850 }
7851 al->array_reference=SvRV(sv);
7852 break;
7853 }
7854 case RealReference:
7855 {
7856 al->real_reference=SvNV(sv);
7857 break;
7858 }
7859 case FileReference:
7860 {
7861 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7862 break;
7863 }
7864 case ImageReference:
7865 {
7866 if (!sv_isobject(sv) ||
7867 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7868 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7869 {
7870 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7871 PackageName);
7872 goto PerlException;
7873 }
7874 break;
7875 }
7876 case IntegerReference:
7877 {
7878 al->integer_reference=SvIV(sv);
7879 break;
7880 }
7881 case StringReference:
7882 {
7883 al->string_reference=(char *) SvPV(sv,al->length);
7884 if (sv_isobject(sv))
7885 al->image_reference=SetupList(aTHX_ SvRV(sv),
7886 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7887 break;
7888 }
7889 default:
7890 {
7891 /*
7892 Is a string; look up name.
7893 */
7894 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7895 {
7896 al->string_reference=(char *) SvPV(sv,al->length);
7897 al->integer_reference=(-1);
7898 break;
7899 }
7900 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7901 MagickFalse,SvPV(sv,na));
7902 if (pp->type == MagickChannelOptions)
7903 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7904 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7905 {
cristy151b66d2015-04-15 10:50:31 +00007906 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007907 "invalid %.60s value",pp->method);
7908 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7909 goto continue_outer_loop;
7910 }
7911 break;
7912 }
7913 }
7914 attribute_flag[pp-rp->arguments]++;
7915 continue_outer_loop: ;
7916 }
7917 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7918 pv=reference_vector;
7919 SetGeometryInfo(&geometry_info);
7920 channel=DefaultChannels;
7921 for (next=image; next; next=next->next)
7922 {
7923 image=next;
7924 SetGeometry(image,&geometry);
7925 if ((region_info.width*region_info.height) != 0)
Cristy7e567962018-02-03 12:42:20 -05007926 (void) SetImageRegionMask(image,WritePixelMask,&region_info,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007927 switch (ix)
7928 {
7929 default:
7930 {
cristy151b66d2015-04-15 10:50:31 +00007931 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007932 ThrowPerlException(exception,OptionError,
7933 "UnrecognizedPerlMagickMethod",message);
7934 goto PerlException;
7935 }
7936 case 1: /* Comment */
7937 {
7938 if (attribute_flag[0] == 0)
7939 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007940 (void) SetImageProperty(image,"comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007941 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007942 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007943 break;
7944 }
7945 case 2: /* Label */
7946 {
7947 if (attribute_flag[0] == 0)
7948 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007949 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007950 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007951 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007952 break;
7953 }
7954 case 3: /* AddNoise */
7955 {
7956 double
7957 attenuate;
7958
7959 if (attribute_flag[0] == 0)
7960 argument_list[0].integer_reference=UniformNoise;
7961 attenuate=1.0;
7962 if (attribute_flag[1] != 0)
7963 attenuate=argument_list[1].real_reference;
7964 if (attribute_flag[2] != 0)
7965 channel=(ChannelType) argument_list[2].integer_reference;
7966 channel_mask=SetImageChannelMask(image,channel);
7967 image=AddNoiseImage(image,(NoiseType)
7968 argument_list[0].integer_reference,attenuate,exception);
7969 if (image != (Image *) NULL)
7970 (void) SetImageChannelMask(image,channel_mask);
7971 break;
7972 }
7973 case 4: /* Colorize */
7974 {
7975 PixelInfo
7976 target;
7977
7978 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7979 0,0,&target,exception);
7980 if (attribute_flag[0] != 0)
7981 (void) QueryColorCompliance(argument_list[0].string_reference,
7982 AllCompliance,&target,exception);
7983 if (attribute_flag[1] == 0)
7984 argument_list[1].string_reference="100%";
7985 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7986 exception);
7987 break;
7988 }
7989 case 5: /* Border */
7990 {
7991 CompositeOperator
7992 compose;
7993
7994 geometry.width=0;
7995 geometry.height=0;
7996 if (attribute_flag[0] != 0)
7997 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7998 &geometry,exception);
7999 if (attribute_flag[1] != 0)
8000 geometry.width=argument_list[1].integer_reference;
8001 if (attribute_flag[2] != 0)
8002 geometry.height=argument_list[2].integer_reference;
8003 if (attribute_flag[3] != 0)
8004 QueryColorCompliance(argument_list[3].string_reference,
8005 AllCompliance,&image->border_color,exception);
8006 if (attribute_flag[4] != 0)
8007 QueryColorCompliance(argument_list[4].string_reference,
8008 AllCompliance,&image->border_color,exception);
8009 if (attribute_flag[5] != 0)
8010 QueryColorCompliance(argument_list[5].string_reference,
8011 AllCompliance,&image->border_color,exception);
8012 compose=image->compose;
8013 if (attribute_flag[6] != 0)
8014 compose=(CompositeOperator) argument_list[6].integer_reference;
8015 image=BorderImage(image,&geometry,compose,exception);
8016 break;
8017 }
8018 case 6: /* Blur */
8019 {
8020 if (attribute_flag[0] != 0)
8021 {
8022 flags=ParseGeometry(argument_list[0].string_reference,
8023 &geometry_info);
8024 if ((flags & SigmaValue) == 0)
8025 geometry_info.sigma=1.0;
8026 }
8027 if (attribute_flag[1] != 0)
8028 geometry_info.rho=argument_list[1].real_reference;
8029 if (attribute_flag[2] != 0)
8030 geometry_info.sigma=argument_list[2].real_reference;
8031 if (attribute_flag[3] != 0)
8032 channel=(ChannelType) argument_list[3].integer_reference;
8033 channel_mask=SetImageChannelMask(image,channel);
8034 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
8035 exception);
8036 if (image != (Image *) NULL)
8037 (void) SetImageChannelMask(image,channel_mask);
8038 break;
8039 }
8040 case 7: /* Chop */
8041 {
cristy260bd762014-08-15 12:46:34 +00008042 if (attribute_flag[5] != 0)
8043 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00008044 if (attribute_flag[0] != 0)
8045 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8046 &geometry,exception);
8047 if (attribute_flag[1] != 0)
8048 geometry.width=argument_list[1].integer_reference;
8049 if (attribute_flag[2] != 0)
8050 geometry.height=argument_list[2].integer_reference;
8051 if (attribute_flag[3] != 0)
8052 geometry.x=argument_list[3].integer_reference;
8053 if (attribute_flag[4] != 0)
8054 geometry.y=argument_list[4].integer_reference;
8055 image=ChopImage(image,&geometry,exception);
8056 break;
8057 }
8058 case 8: /* Crop */
8059 {
8060 if (attribute_flag[6] != 0)
8061 image->gravity=(GravityType) argument_list[6].integer_reference;
8062 if (attribute_flag[0] != 0)
8063 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8064 &geometry,exception);
8065 if (attribute_flag[1] != 0)
8066 geometry.width=argument_list[1].integer_reference;
8067 if (attribute_flag[2] != 0)
8068 geometry.height=argument_list[2].integer_reference;
8069 if (attribute_flag[3] != 0)
8070 geometry.x=argument_list[3].integer_reference;
8071 if (attribute_flag[4] != 0)
8072 geometry.y=argument_list[4].integer_reference;
8073 if (attribute_flag[5] != 0)
8074 image->fuzz=StringToDoubleInterval(
8075 argument_list[5].string_reference,(double) QuantumRange+1.0);
8076 image=CropImage(image,&geometry,exception);
8077 break;
8078 }
8079 case 9: /* Despeckle */
8080 {
8081 image=DespeckleImage(image,exception);
8082 break;
8083 }
8084 case 10: /* Edge */
8085 {
8086 if (attribute_flag[0] != 0)
8087 geometry_info.rho=argument_list[0].real_reference;
8088 image=EdgeImage(image,geometry_info.rho,exception);
8089 break;
8090 }
8091 case 11: /* Emboss */
8092 {
8093 if (attribute_flag[0] != 0)
8094 {
8095 flags=ParseGeometry(argument_list[0].string_reference,
8096 &geometry_info);
8097 if ((flags & SigmaValue) == 0)
8098 geometry_info.sigma=1.0;
8099 }
8100 if (attribute_flag[1] != 0)
8101 geometry_info.rho=argument_list[1].real_reference;
8102 if (attribute_flag[2] != 0)
8103 geometry_info.sigma=argument_list[2].real_reference;
8104 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8105 exception);
8106 break;
8107 }
8108 case 12: /* Enhance */
8109 {
8110 image=EnhanceImage(image,exception);
8111 break;
8112 }
8113 case 13: /* Flip */
8114 {
8115 image=FlipImage(image,exception);
8116 break;
8117 }
8118 case 14: /* Flop */
8119 {
8120 image=FlopImage(image,exception);
8121 break;
8122 }
8123 case 15: /* Frame */
8124 {
8125 CompositeOperator
8126 compose;
8127
8128 FrameInfo
8129 frame_info;
8130
8131 if (attribute_flag[0] != 0)
8132 {
8133 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8134 &geometry,exception);
8135 frame_info.width=geometry.width;
8136 frame_info.height=geometry.height;
8137 frame_info.outer_bevel=geometry.x;
8138 frame_info.inner_bevel=geometry.y;
8139 }
8140 if (attribute_flag[1] != 0)
8141 frame_info.width=argument_list[1].integer_reference;
8142 if (attribute_flag[2] != 0)
8143 frame_info.height=argument_list[2].integer_reference;
8144 if (attribute_flag[3] != 0)
8145 frame_info.inner_bevel=argument_list[3].integer_reference;
8146 if (attribute_flag[4] != 0)
8147 frame_info.outer_bevel=argument_list[4].integer_reference;
8148 if (attribute_flag[5] != 0)
8149 QueryColorCompliance(argument_list[5].string_reference,
8150 AllCompliance,&fill_color,exception);
8151 if (attribute_flag[6] != 0)
8152 QueryColorCompliance(argument_list[6].string_reference,
8153 AllCompliance,&fill_color,exception);
8154 frame_info.x=(ssize_t) frame_info.width;
8155 frame_info.y=(ssize_t) frame_info.height;
8156 frame_info.width=image->columns+2*frame_info.x;
8157 frame_info.height=image->rows+2*frame_info.y;
8158 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
Cristy8645e042016-02-03 16:35:29 -05008159 image->alpha_color=fill_color;
cristy4a3ce0a2013-08-03 20:06:59 +00008160 compose=image->compose;
8161 if (attribute_flag[7] != 0)
8162 compose=(CompositeOperator) argument_list[7].integer_reference;
8163 image=FrameImage(image,&frame_info,compose,exception);
8164 break;
8165 }
8166 case 16: /* Implode */
8167 {
8168 PixelInterpolateMethod
8169 method;
8170
8171 if (attribute_flag[0] == 0)
8172 argument_list[0].real_reference=0.5;
8173 method=UndefinedInterpolatePixel;
8174 if (attribute_flag[1] != 0)
8175 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8176 image=ImplodeImage(image,argument_list[0].real_reference,
8177 method,exception);
8178 break;
8179 }
8180 case 17: /* Magnify */
8181 {
8182 image=MagnifyImage(image,exception);
8183 break;
8184 }
8185 case 18: /* MedianFilter */
8186 {
8187 if (attribute_flag[0] != 0)
8188 {
8189 flags=ParseGeometry(argument_list[0].string_reference,
8190 &geometry_info);
8191 if ((flags & SigmaValue) == 0)
8192 geometry_info.sigma=geometry_info.rho;
8193 }
8194 if (attribute_flag[1] != 0)
8195 geometry_info.rho=argument_list[1].real_reference;
8196 if (attribute_flag[2] != 0)
8197 geometry_info.sigma=argument_list[2].real_reference;
8198 if (attribute_flag[3] != 0)
8199 channel=(ChannelType) argument_list[3].integer_reference;
8200 channel_mask=SetImageChannelMask(image,channel);
8201 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8202 (size_t) geometry_info.sigma,exception);
8203 if (image != (Image *) NULL)
8204 (void) SetImageChannelMask(image,channel_mask);
8205 break;
8206 }
8207 case 19: /* Minify */
8208 {
8209 image=MinifyImage(image,exception);
8210 break;
8211 }
8212 case 20: /* OilPaint */
8213 {
8214 if (attribute_flag[0] == 0)
8215 argument_list[0].real_reference=0.0;
8216 if (attribute_flag[1] == 0)
8217 argument_list[1].real_reference=1.0;
8218 image=OilPaintImage(image,argument_list[0].real_reference,
8219 argument_list[1].real_reference,exception);
8220 break;
8221 }
8222 case 21: /* ReduceNoise */
8223 {
8224 if (attribute_flag[0] != 0)
8225 {
8226 flags=ParseGeometry(argument_list[0].string_reference,
8227 &geometry_info);
8228 if ((flags & SigmaValue) == 0)
8229 geometry_info.sigma=1.0;
8230 }
8231 if (attribute_flag[1] != 0)
8232 geometry_info.rho=argument_list[1].real_reference;
8233 if (attribute_flag[2] != 0)
8234 geometry_info.sigma=argument_list[2].real_reference;
8235 if (attribute_flag[3] != 0)
8236 channel=(ChannelType) argument_list[3].integer_reference;
8237 channel_mask=SetImageChannelMask(image,channel);
8238 image=StatisticImage(image,NonpeakStatistic,(size_t)
8239 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8240 if (image != (Image *) NULL)
8241 (void) SetImageChannelMask(image,channel_mask);
8242 break;
8243 }
8244 case 22: /* Roll */
8245 {
8246 if (attribute_flag[0] != 0)
Cristyf94b0842017-07-14 07:05:02 -04008247 {
8248 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8249 &geometry,exception);
8250 if ((flags & PercentValue) != 0)
8251 {
8252 geometry.x*=(double) image->columns/100.0;
8253 geometry.y*=(double) image->rows/100.0;
8254 }
8255 }
cristy4a3ce0a2013-08-03 20:06:59 +00008256 if (attribute_flag[1] != 0)
8257 geometry.x=argument_list[1].integer_reference;
8258 if (attribute_flag[2] != 0)
8259 geometry.y=argument_list[2].integer_reference;
8260 image=RollImage(image,geometry.x,geometry.y,exception);
8261 break;
8262 }
8263 case 23: /* Rotate */
8264 {
8265 if (attribute_flag[0] == 0)
8266 argument_list[0].real_reference=90.0;
8267 if (attribute_flag[1] != 0)
8268 {
8269 QueryColorCompliance(argument_list[1].string_reference,
8270 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008271 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8272 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008273 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8274 }
8275 image=RotateImage(image,argument_list[0].real_reference,exception);
8276 break;
8277 }
8278 case 24: /* Sample */
8279 {
8280 if (attribute_flag[0] != 0)
8281 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8282 &geometry,exception);
8283 if (attribute_flag[1] != 0)
8284 geometry.width=argument_list[1].integer_reference;
8285 if (attribute_flag[2] != 0)
8286 geometry.height=argument_list[2].integer_reference;
8287 image=SampleImage(image,geometry.width,geometry.height,exception);
8288 break;
8289 }
8290 case 25: /* Scale */
8291 {
8292 if (attribute_flag[0] != 0)
8293 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8294 &geometry,exception);
8295 if (attribute_flag[1] != 0)
8296 geometry.width=argument_list[1].integer_reference;
8297 if (attribute_flag[2] != 0)
8298 geometry.height=argument_list[2].integer_reference;
8299 image=ScaleImage(image,geometry.width,geometry.height,exception);
8300 break;
8301 }
8302 case 26: /* Shade */
8303 {
8304 if (attribute_flag[0] != 0)
8305 {
8306 flags=ParseGeometry(argument_list[0].string_reference,
8307 &geometry_info);
8308 if ((flags & SigmaValue) == 0)
8309 geometry_info.sigma=0.0;
8310 }
8311 if (attribute_flag[1] != 0)
8312 geometry_info.rho=argument_list[1].real_reference;
8313 if (attribute_flag[2] != 0)
8314 geometry_info.sigma=argument_list[2].real_reference;
8315 image=ShadeImage(image,
8316 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8317 geometry_info.rho,geometry_info.sigma,exception);
8318 break;
8319 }
8320 case 27: /* Sharpen */
8321 {
8322 if (attribute_flag[0] != 0)
8323 {
8324 flags=ParseGeometry(argument_list[0].string_reference,
8325 &geometry_info);
8326 if ((flags & SigmaValue) == 0)
8327 geometry_info.sigma=1.0;
8328 }
8329 if (attribute_flag[1] != 0)
8330 geometry_info.rho=argument_list[1].real_reference;
8331 if (attribute_flag[2] != 0)
8332 geometry_info.sigma=argument_list[2].real_reference;
8333 if (attribute_flag[3] != 0)
8334 channel=(ChannelType) argument_list[3].integer_reference;
8335 channel_mask=SetImageChannelMask(image,channel);
8336 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8337 exception);
8338 if (image != (Image *) NULL)
8339 (void) SetImageChannelMask(image,channel_mask);
8340 break;
8341 }
8342 case 28: /* Shear */
8343 {
8344 if (attribute_flag[0] != 0)
8345 {
8346 flags=ParseGeometry(argument_list[0].string_reference,
8347 &geometry_info);
8348 if ((flags & SigmaValue) == 0)
8349 geometry_info.sigma=geometry_info.rho;
8350 }
8351 if (attribute_flag[1] != 0)
8352 geometry_info.rho=argument_list[1].real_reference;
8353 if (attribute_flag[2] != 0)
8354 geometry_info.sigma=argument_list[2].real_reference;
8355 if (attribute_flag[3] != 0)
8356 QueryColorCompliance(argument_list[3].string_reference,
8357 AllCompliance,&image->background_color,exception);
8358 if (attribute_flag[4] != 0)
8359 QueryColorCompliance(argument_list[4].string_reference,
8360 AllCompliance,&image->background_color,exception);
8361 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8362 exception);
8363 break;
8364 }
8365 case 29: /* Spread */
8366 {
Cristye3319c12015-08-24 07:11:48 -04008367 PixelInterpolateMethod
8368 method;
8369
cristy4a3ce0a2013-08-03 20:06:59 +00008370 if (attribute_flag[0] == 0)
8371 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008372 method=UndefinedInterpolatePixel;
8373 if (attribute_flag[1] != 0)
8374 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8375 image=SpreadImage(image,method,argument_list[0].real_reference,
8376 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008377 break;
8378 }
8379 case 30: /* Swirl */
8380 {
8381 PixelInterpolateMethod
8382 method;
8383
8384 if (attribute_flag[0] == 0)
8385 argument_list[0].real_reference=50.0;
8386 method=UndefinedInterpolatePixel;
8387 if (attribute_flag[1] != 0)
8388 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8389 image=SwirlImage(image,argument_list[0].real_reference,
8390 method,exception);
8391 break;
8392 }
8393 case 31: /* Resize */
8394 case 32: /* Zoom */
8395 {
8396 if (attribute_flag[0] != 0)
8397 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8398 &geometry,exception);
8399 if (attribute_flag[1] != 0)
8400 geometry.width=argument_list[1].integer_reference;
8401 if (attribute_flag[2] != 0)
8402 geometry.height=argument_list[2].integer_reference;
8403 if (attribute_flag[3] == 0)
8404 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8405 if (attribute_flag[4] != 0)
8406 SetImageArtifact(image,"filter:support",
8407 argument_list[4].string_reference);
8408 image=ResizeImage(image,geometry.width,geometry.height,
Cristy8645e042016-02-03 16:35:29 -05008409 (FilterType) argument_list[3].integer_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00008410 exception);
8411 break;
8412 }
8413 case 33: /* Annotate */
8414 {
8415 DrawInfo
8416 *draw_info;
8417
8418 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8419 (DrawInfo *) NULL);
8420 if (attribute_flag[0] != 0)
8421 {
8422 char
8423 *text;
8424
8425 text=InterpretImageProperties(info ? info->image_info :
8426 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8427 exception);
8428 (void) CloneString(&draw_info->text,text);
8429 text=DestroyString(text);
8430 }
8431 if (attribute_flag[1] != 0)
8432 (void) CloneString(&draw_info->font,
8433 argument_list[1].string_reference);
8434 if (attribute_flag[2] != 0)
8435 draw_info->pointsize=argument_list[2].real_reference;
8436 if (attribute_flag[3] != 0)
8437 (void) CloneString(&draw_info->density,
8438 argument_list[3].string_reference);
8439 if (attribute_flag[4] != 0)
8440 (void) QueryColorCompliance(argument_list[4].string_reference,
8441 AllCompliance,&draw_info->undercolor,exception);
8442 if (attribute_flag[5] != 0)
8443 {
8444 (void) QueryColorCompliance(argument_list[5].string_reference,
8445 AllCompliance,&draw_info->stroke,exception);
8446 if (argument_list[5].image_reference != (Image *) NULL)
8447 draw_info->stroke_pattern=CloneImage(
8448 argument_list[5].image_reference,0,0,MagickTrue,exception);
8449 }
8450 if (attribute_flag[6] != 0)
8451 {
8452 (void) QueryColorCompliance(argument_list[6].string_reference,
8453 AllCompliance,&draw_info->fill,exception);
8454 if (argument_list[6].image_reference != (Image *) NULL)
8455 draw_info->fill_pattern=CloneImage(
8456 argument_list[6].image_reference,0,0,MagickTrue,exception);
8457 }
8458 if (attribute_flag[7] != 0)
8459 {
8460 (void) CloneString(&draw_info->geometry,
8461 argument_list[7].string_reference);
8462 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8463 &geometry,exception);
8464 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8465 geometry_info.sigma=geometry_info.xi;
8466 }
8467 if (attribute_flag[8] != 0)
8468 (void) QueryColorCompliance(argument_list[8].string_reference,
8469 AllCompliance,&draw_info->fill,exception);
8470 if (attribute_flag[11] != 0)
8471 draw_info->gravity=(GravityType)
8472 argument_list[11].integer_reference;
8473 if (attribute_flag[25] != 0)
8474 {
8475 AV
8476 *av;
8477
8478 av=(AV *) argument_list[25].array_reference;
8479 if ((av_len(av) != 3) && (av_len(av) != 5))
8480 {
8481 ThrowPerlException(exception,OptionError,
8482 "affine matrix must have 4 or 6 elements",PackageName);
8483 goto PerlException;
8484 }
8485 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8486 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8487 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8488 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8489 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8490 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8491 {
8492 ThrowPerlException(exception,OptionError,
8493 "affine matrix is singular",PackageName);
8494 goto PerlException;
8495 }
8496 if (av_len(av) == 5)
8497 {
8498 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8499 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8500 }
8501 }
8502 for (j=12; j < 17; j++)
8503 {
8504 if (attribute_flag[j] == 0)
8505 continue;
8506 value=argument_list[j].string_reference;
8507 angle=argument_list[j].real_reference;
8508 current=draw_info->affine;
8509 GetAffineMatrix(&affine);
8510 switch (j)
8511 {
8512 case 12:
8513 {
8514 /*
8515 Translate.
8516 */
8517 flags=ParseGeometry(value,&geometry_info);
8518 affine.tx=geometry_info.xi;
8519 affine.ty=geometry_info.psi;
8520 if ((flags & PsiValue) == 0)
8521 affine.ty=affine.tx;
8522 break;
8523 }
8524 case 13:
8525 {
8526 /*
8527 Scale.
8528 */
8529 flags=ParseGeometry(value,&geometry_info);
8530 affine.sx=geometry_info.rho;
8531 affine.sy=geometry_info.sigma;
8532 if ((flags & SigmaValue) == 0)
8533 affine.sy=affine.sx;
8534 break;
8535 }
8536 case 14:
8537 {
8538 /*
8539 Rotate.
8540 */
8541 if (angle == 0.0)
8542 break;
8543 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8544 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8545 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8546 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8547 break;
8548 }
8549 case 15:
8550 {
8551 /*
8552 SkewX.
8553 */
8554 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8555 break;
8556 }
8557 case 16:
8558 {
8559 /*
8560 SkewY.
8561 */
8562 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8563 break;
8564 }
8565 }
8566 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8567 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8568 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8569 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8570 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8571 current.tx;
8572 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8573 current.ty;
8574 }
8575 if (attribute_flag[9] == 0)
8576 argument_list[9].real_reference=0.0;
8577 if (attribute_flag[10] == 0)
8578 argument_list[10].real_reference=0.0;
8579 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8580 {
8581 char
cristy151b66d2015-04-15 10:50:31 +00008582 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008583
cristy151b66d2015-04-15 10:50:31 +00008584 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008585 (double) argument_list[9].real_reference+draw_info->affine.tx,
8586 (double) argument_list[10].real_reference+draw_info->affine.ty);
8587 (void) CloneString(&draw_info->geometry,geometry);
8588 }
8589 if (attribute_flag[17] != 0)
8590 draw_info->stroke_width=argument_list[17].real_reference;
8591 if (attribute_flag[18] != 0)
8592 {
8593 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8594 MagickTrue : MagickFalse;
8595 draw_info->stroke_antialias=draw_info->text_antialias;
8596 }
8597 if (attribute_flag[19] != 0)
8598 (void) CloneString(&draw_info->family,
8599 argument_list[19].string_reference);
8600 if (attribute_flag[20] != 0)
8601 draw_info->style=(StyleType) argument_list[20].integer_reference;
8602 if (attribute_flag[21] != 0)
8603 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8604 if (attribute_flag[22] != 0)
8605 draw_info->weight=argument_list[22].integer_reference;
8606 if (attribute_flag[23] != 0)
8607 draw_info->align=(AlignType) argument_list[23].integer_reference;
8608 if (attribute_flag[24] != 0)
8609 (void) CloneString(&draw_info->encoding,
8610 argument_list[24].string_reference);
8611 if (attribute_flag[25] != 0)
8612 draw_info->fill_pattern=CloneImage(
8613 argument_list[25].image_reference,0,0,MagickTrue,exception);
8614 if (attribute_flag[26] != 0)
8615 draw_info->fill_pattern=CloneImage(
8616 argument_list[26].image_reference,0,0,MagickTrue,exception);
8617 if (attribute_flag[27] != 0)
8618 draw_info->stroke_pattern=CloneImage(
8619 argument_list[27].image_reference,0,0,MagickTrue,exception);
8620 if (attribute_flag[29] != 0)
8621 draw_info->kerning=argument_list[29].real_reference;
8622 if (attribute_flag[30] != 0)
8623 draw_info->interline_spacing=argument_list[30].real_reference;
8624 if (attribute_flag[31] != 0)
8625 draw_info->interword_spacing=argument_list[31].real_reference;
8626 if (attribute_flag[32] != 0)
8627 draw_info->direction=(DirectionType)
8628 argument_list[32].integer_reference;
Cristy3d1de822019-02-15 18:06:30 -05008629 if (attribute_flag[33] != 0)
8630 draw_info->decorate=(DecorationType)
8631 argument_list[33].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00008632 (void) AnnotateImage(image,draw_info,exception);
8633 draw_info=DestroyDrawInfo(draw_info);
8634 break;
8635 }
8636 case 34: /* ColorFloodfill */
8637 {
8638 DrawInfo
8639 *draw_info;
8640
8641 MagickBooleanType
8642 invert;
8643
8644 PixelInfo
8645 target;
8646
8647 draw_info=CloneDrawInfo(info ? info->image_info :
8648 (ImageInfo *) NULL,(DrawInfo *) NULL);
8649 if (attribute_flag[0] != 0)
8650 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8651 &geometry,exception);
8652 if (attribute_flag[1] != 0)
8653 geometry.x=argument_list[1].integer_reference;
8654 if (attribute_flag[2] != 0)
8655 geometry.y=argument_list[2].integer_reference;
8656 if (attribute_flag[3] != 0)
8657 (void) QueryColorCompliance(argument_list[3].string_reference,
8658 AllCompliance,&draw_info->fill,exception);
8659 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8660 geometry.x,geometry.y,&target,exception);
8661 invert=MagickFalse;
8662 if (attribute_flag[4] != 0)
8663 {
8664 QueryColorCompliance(argument_list[4].string_reference,
8665 AllCompliance,&target,exception);
8666 invert=MagickTrue;
8667 }
8668 if (attribute_flag[5] != 0)
8669 image->fuzz=StringToDoubleInterval(
8670 argument_list[5].string_reference,(double) QuantumRange+1.0);
8671 if (attribute_flag[6] != 0)
8672 invert=(MagickBooleanType) argument_list[6].integer_reference;
8673 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8674 geometry.y,invert,exception);
8675 draw_info=DestroyDrawInfo(draw_info);
8676 break;
8677 }
8678 case 35: /* Composite */
8679 {
8680 char
cristy151b66d2015-04-15 10:50:31 +00008681 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008682
8683 Image
8684 *composite_image,
8685 *rotate_image;
8686
8687 MagickBooleanType
8688 clip_to_self;
8689
8690 compose=OverCompositeOp;
8691 if (attribute_flag[0] != 0)
8692 composite_image=argument_list[0].image_reference;
8693 else
8694 {
8695 ThrowPerlException(exception,OptionError,
8696 "CompositeImageRequired",PackageName);
8697 goto PerlException;
8698 }
8699 /*
8700 Parameter Handling used for BOTH normal and tiled composition.
8701 */
8702 if (attribute_flag[1] != 0) /* compose */
8703 compose=(CompositeOperator) argument_list[1].integer_reference;
8704 if (attribute_flag[6] != 0) /* opacity */
8705 {
8706 if (compose != DissolveCompositeOp)
8707 (void) SetImageAlpha(composite_image,(Quantum)
8708 StringToDoubleInterval(argument_list[6].string_reference,
8709 (double) QuantumRange+1.0),exception);
8710 else
8711 {
8712 CacheView
8713 *composite_view;
8714
8715 double
8716 opacity;
8717
8718 MagickBooleanType
8719 sync;
8720
8721 register ssize_t
8722 x;
8723
8724 register Quantum
8725 *q;
8726
8727 ssize_t
8728 y;
8729
8730 /*
8731 Handle dissolve composite operator (patch by
8732 Kevin A. McGrail).
8733 */
8734 (void) CloneString(&image->geometry,
8735 argument_list[6].string_reference);
8736 opacity=(Quantum) StringToDoubleInterval(
8737 argument_list[6].string_reference,(double) QuantumRange+
8738 1.0);
cristy17f11b02014-12-20 19:37:04 +00008739 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008740 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8741 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8742 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8743 {
8744 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8745 composite_image->columns,1,exception);
8746 for (x=0; x < (ssize_t) composite_image->columns; x++)
8747 {
8748 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8749 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8750 q);
8751 q+=GetPixelChannels(composite_image);
8752 }
8753 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8754 if (sync == MagickFalse)
8755 break;
8756 }
8757 composite_view=DestroyCacheView(composite_view);
8758 }
8759 }
8760 if (attribute_flag[9] != 0) /* "color=>" */
8761 QueryColorCompliance(argument_list[9].string_reference,
8762 AllCompliance,&composite_image->background_color,exception);
8763 if (attribute_flag[12] != 0) /* "interpolate=>" */
8764 image->interpolate=(PixelInterpolateMethod)
8765 argument_list[12].integer_reference;
8766 if (attribute_flag[13] != 0) /* "args=>" */
8767 (void) SetImageArtifact(composite_image,"compose:args",
8768 argument_list[13].string_reference);
8769 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8770 (void) SetImageArtifact(composite_image,"compose:args",
8771 argument_list[14].string_reference);
Cristy72aed842018-07-08 18:25:50 -04008772 clip_to_self=MagickTrue;
8773 switch (compose)
8774 {
8775 case ClearCompositeOp:
8776 case SrcCompositeOp:
8777 case InCompositeOp:
8778 case SrcInCompositeOp:
8779 case OutCompositeOp:
8780 case SrcOutCompositeOp:
8781 case DstInCompositeOp:
8782 case DstAtopCompositeOp:
Cristy901f5212018-07-08 18:43:34 -04008783 case CopyAlphaCompositeOp:
Cristy72aed842018-07-08 18:25:50 -04008784 case ChangeMaskCompositeOp:
8785 case DissolveCompositeOp:
8786 case BlendCompositeOp:
8787 {
Cristy901f5212018-07-08 18:43:34 -04008788 clip_to_self=MagickFalse;
Cristy72aed842018-07-08 18:25:50 -04008789 break;
8790 }
8791 default:
8792 break;
8793 }
cristy4a3ce0a2013-08-03 20:06:59 +00008794 if (attribute_flag[15] != 0)
8795 clip_to_self=(MagickBooleanType)
8796 argument_list[15].integer_reference;
8797 /*
8798 Tiling Composition (with orthogonal rotate).
8799 */
8800 rotate_image=(Image *) NULL;
8801 if (attribute_flag[8] != 0) /* "rotate=>" */
8802 {
8803 /*
8804 Rotate image.
8805 */
8806 rotate_image=RotateImage(composite_image,
8807 argument_list[8].real_reference,exception);
8808 if (rotate_image == (Image *) NULL)
8809 break;
8810 }
8811 if ((attribute_flag[7] != 0) &&
8812 (argument_list[7].integer_reference != 0)) /* tile */
8813 {
8814 ssize_t
8815 x,
8816 y;
8817
8818 /*
8819 Tile the composite image.
8820 */
cristy4a3ce0a2013-08-03 20:06:59 +00008821 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8822 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8823 {
8824 if (attribute_flag[8] != 0) /* rotate */
8825 (void) CompositeImage(image,rotate_image,compose,
Cristyde6c67d2018-07-08 19:14:08 -04008826 MagickTrue,x,y,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008827 else
8828 (void) CompositeImage(image,composite_image,compose,
Cristyde6c67d2018-07-08 19:14:08 -04008829 MagickTrue,x,y,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008830 }
8831 if (attribute_flag[8] != 0) /* rotate */
8832 rotate_image=DestroyImage(rotate_image);
8833 break;
8834 }
8835 /*
8836 Parameter Handling used used ONLY for normal composition.
8837 */
8838 if (attribute_flag[5] != 0) /* gravity */
8839 image->gravity=(GravityType) argument_list[5].integer_reference;
8840 if (attribute_flag[2] != 0) /* geometry offset */
8841 {
8842 SetGeometry(image,&geometry);
8843 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8844 &geometry);
8845 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8846 &geometry);
8847 }
8848 if (attribute_flag[3] != 0) /* x offset */
8849 geometry.x=argument_list[3].integer_reference;
8850 if (attribute_flag[4] != 0) /* y offset */
8851 geometry.y=argument_list[4].integer_reference;
8852 if (attribute_flag[10] != 0) /* mask */
8853 {
8854 if ((image->compose == DisplaceCompositeOp) ||
8855 (image->compose == DistortCompositeOp))
8856 {
8857 /*
8858 Merge Y displacement into X displacement image.
8859 */
8860 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8861 exception);
8862 (void) CompositeImage(composite_image,
8863 argument_list[10].image_reference,CopyGreenCompositeOp,
Cristy74e39292018-07-08 13:13:20 -04008864 clip_to_self,0,0,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008865 }
8866 else
8867 {
8868 Image
8869 *mask_image;
8870
8871 /*
8872 Set a blending mask for the composition.
8873 */
8874 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8875 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008876 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008877 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008878 mask_image=DestroyImage(mask_image);
8879 }
8880 }
8881 if (attribute_flag[11] != 0) /* channel */
8882 channel=(ChannelType) argument_list[11].integer_reference;
8883 /*
8884 Composite two images (normal composition).
8885 */
cristy151b66d2015-04-15 10:50:31 +00008886 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008887 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8888 (double) composite_image->rows,(double) geometry.x,(double)
8889 geometry.y);
8890 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8891 exception);
8892 channel_mask=SetImageChannelMask(image,channel);
8893 if (attribute_flag[8] == 0) /* no rotate */
8894 CompositeImage(image,composite_image,compose,clip_to_self,
8895 geometry.x,geometry.y,exception);
8896 else
8897 {
8898 /*
8899 Position adjust rotated image then composite.
8900 */
8901 geometry.x-=(ssize_t) (rotate_image->columns-
8902 composite_image->columns)/2;
8903 geometry.y-=(ssize_t) (rotate_image->rows-
8904 composite_image->rows)/2;
8905 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8906 geometry.y,exception);
8907 rotate_image=DestroyImage(rotate_image);
8908 }
8909 if (attribute_flag[10] != 0) /* mask */
8910 {
8911 if ((image->compose == DisplaceCompositeOp) ||
8912 (image->compose == DistortCompositeOp))
8913 composite_image=DestroyImage(composite_image);
8914 else
cristy1f7ffb72015-07-29 11:07:03 +00008915 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008916 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008917 }
8918 (void) SetImageChannelMask(image,channel_mask);
8919 break;
8920 }
8921 case 36: /* Contrast */
8922 {
8923 if (attribute_flag[0] == 0)
8924 argument_list[0].integer_reference=0;
8925 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8926 MagickTrue : MagickFalse,exception);
8927 break;
8928 }
8929 case 37: /* CycleColormap */
8930 {
8931 if (attribute_flag[0] == 0)
8932 argument_list[0].integer_reference=6;
8933 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8934 exception);
8935 break;
8936 }
8937 case 38: /* Draw */
8938 {
8939 DrawInfo
8940 *draw_info;
8941
8942 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8943 (DrawInfo *) NULL);
8944 (void) CloneString(&draw_info->primitive,"point");
8945 if (attribute_flag[0] != 0)
8946 {
8947 if (argument_list[0].integer_reference < 0)
8948 (void) CloneString(&draw_info->primitive,
8949 argument_list[0].string_reference);
8950 else
8951 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8952 MagickPrimitiveOptions,argument_list[0].integer_reference));
8953 }
8954 if (attribute_flag[1] != 0)
8955 {
8956 if (LocaleCompare(draw_info->primitive,"path") == 0)
8957 {
8958 (void) ConcatenateString(&draw_info->primitive," '");
8959 ConcatenateString(&draw_info->primitive,
8960 argument_list[1].string_reference);
8961 (void) ConcatenateString(&draw_info->primitive,"'");
8962 }
8963 else
8964 {
8965 (void) ConcatenateString(&draw_info->primitive," ");
8966 ConcatenateString(&draw_info->primitive,
8967 argument_list[1].string_reference);
8968 }
8969 }
8970 if (attribute_flag[2] != 0)
8971 {
8972 (void) ConcatenateString(&draw_info->primitive," ");
8973 (void) ConcatenateString(&draw_info->primitive,
8974 CommandOptionToMnemonic(MagickMethodOptions,
8975 argument_list[2].integer_reference));
8976 }
8977 if (attribute_flag[3] != 0)
8978 {
8979 (void) QueryColorCompliance(argument_list[3].string_reference,
8980 AllCompliance,&draw_info->stroke,exception);
8981 if (argument_list[3].image_reference != (Image *) NULL)
8982 draw_info->stroke_pattern=CloneImage(
8983 argument_list[3].image_reference,0,0,MagickTrue,exception);
8984 }
8985 if (attribute_flag[4] != 0)
8986 {
8987 (void) QueryColorCompliance(argument_list[4].string_reference,
8988 AllCompliance,&draw_info->fill,exception);
8989 if (argument_list[4].image_reference != (Image *) NULL)
8990 draw_info->fill_pattern=CloneImage(
8991 argument_list[4].image_reference,0,0,MagickTrue,exception);
8992 }
8993 if (attribute_flag[5] != 0)
8994 draw_info->stroke_width=argument_list[5].real_reference;
8995 if (attribute_flag[6] != 0)
8996 (void) CloneString(&draw_info->font,
8997 argument_list[6].string_reference);
8998 if (attribute_flag[7] != 0)
8999 (void) QueryColorCompliance(argument_list[7].string_reference,
9000 AllCompliance,&draw_info->border_color,exception);
9001 if (attribute_flag[8] != 0)
9002 draw_info->affine.tx=argument_list[8].real_reference;
9003 if (attribute_flag[9] != 0)
9004 draw_info->affine.ty=argument_list[9].real_reference;
9005 if (attribute_flag[20] != 0)
9006 {
9007 AV
9008 *av;
9009
9010 av=(AV *) argument_list[20].array_reference;
9011 if ((av_len(av) != 3) && (av_len(av) != 5))
9012 {
9013 ThrowPerlException(exception,OptionError,
9014 "affine matrix must have 4 or 6 elements",PackageName);
9015 goto PerlException;
9016 }
9017 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9018 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9019 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9020 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9021 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9022 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9023 {
9024 ThrowPerlException(exception,OptionError,
9025 "affine matrix is singular",PackageName);
9026 goto PerlException;
9027 }
9028 if (av_len(av) == 5)
9029 {
9030 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9031 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9032 }
9033 }
9034 for (j=10; j < 15; j++)
9035 {
9036 if (attribute_flag[j] == 0)
9037 continue;
9038 value=argument_list[j].string_reference;
9039 angle=argument_list[j].real_reference;
9040 current=draw_info->affine;
9041 GetAffineMatrix(&affine);
9042 switch (j)
9043 {
9044 case 10:
9045 {
9046 /*
9047 Translate.
9048 */
9049 flags=ParseGeometry(value,&geometry_info);
9050 affine.tx=geometry_info.xi;
9051 affine.ty=geometry_info.psi;
9052 if ((flags & PsiValue) == 0)
9053 affine.ty=affine.tx;
9054 break;
9055 }
9056 case 11:
9057 {
9058 /*
9059 Scale.
9060 */
9061 flags=ParseGeometry(value,&geometry_info);
9062 affine.sx=geometry_info.rho;
9063 affine.sy=geometry_info.sigma;
9064 if ((flags & SigmaValue) == 0)
9065 affine.sy=affine.sx;
9066 break;
9067 }
9068 case 12:
9069 {
9070 /*
9071 Rotate.
9072 */
9073 if (angle == 0.0)
9074 break;
9075 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9076 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9077 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9078 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9079 break;
9080 }
9081 case 13:
9082 {
9083 /*
9084 SkewX.
9085 */
9086 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9087 break;
9088 }
9089 case 14:
9090 {
9091 /*
9092 SkewY.
9093 */
9094 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9095 break;
9096 }
9097 }
9098 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9099 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9100 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9101 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9102 draw_info->affine.tx=
9103 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9104 draw_info->affine.ty=
9105 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9106 }
9107 if (attribute_flag[15] != 0)
9108 draw_info->fill_pattern=CloneImage(
9109 argument_list[15].image_reference,0,0,MagickTrue,exception);
9110 if (attribute_flag[16] != 0)
9111 draw_info->pointsize=argument_list[16].real_reference;
9112 if (attribute_flag[17] != 0)
9113 {
Cristy36c30b62018-11-22 09:33:30 -05009114 draw_info->stroke_antialias=argument_list[17].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009115 draw_info->text_antialias=draw_info->stroke_antialias;
9116 }
9117 if (attribute_flag[18] != 0)
9118 (void) CloneString(&draw_info->density,
9119 argument_list[18].string_reference);
9120 if (attribute_flag[19] != 0)
9121 draw_info->stroke_width=argument_list[19].real_reference;
9122 if (attribute_flag[21] != 0)
9123 draw_info->dash_offset=argument_list[21].real_reference;
9124 if (attribute_flag[22] != 0)
9125 {
9126 AV
9127 *av;
9128
9129 av=(AV *) argument_list[22].array_reference;
9130 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9131 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9132 if (draw_info->dash_pattern != (double *) NULL)
9133 {
9134 for (i=0; i <= av_len(av); i++)
9135 draw_info->dash_pattern[i]=(double)
9136 SvNV(*(av_fetch(av,i,0)));
9137 draw_info->dash_pattern[i]=0.0;
9138 }
9139 }
9140 if (attribute_flag[23] != 0)
9141 image->interpolate=(PixelInterpolateMethod)
9142 argument_list[23].integer_reference;
9143 if ((attribute_flag[24] != 0) &&
9144 (draw_info->fill_pattern != (Image *) NULL))
9145 flags=ParsePageGeometry(draw_info->fill_pattern,
9146 argument_list[24].string_reference,
9147 &draw_info->fill_pattern->tile_offset,exception);
9148 if (attribute_flag[25] != 0)
9149 {
9150 (void) ConcatenateString(&draw_info->primitive," '");
9151 (void) ConcatenateString(&draw_info->primitive,
9152 argument_list[25].string_reference);
9153 (void) ConcatenateString(&draw_info->primitive,"'");
9154 }
9155 if (attribute_flag[26] != 0)
9156 draw_info->fill_pattern=CloneImage(
9157 argument_list[26].image_reference,0,0,MagickTrue,exception);
9158 if (attribute_flag[27] != 0)
9159 draw_info->stroke_pattern=CloneImage(
9160 argument_list[27].image_reference,0,0,MagickTrue,exception);
9161 if (attribute_flag[28] != 0)
9162 (void) CloneString(&draw_info->primitive,
9163 argument_list[28].string_reference);
9164 if (attribute_flag[29] != 0)
9165 draw_info->kerning=argument_list[29].real_reference;
9166 if (attribute_flag[30] != 0)
9167 draw_info->interline_spacing=argument_list[30].real_reference;
9168 if (attribute_flag[31] != 0)
9169 draw_info->interword_spacing=argument_list[31].real_reference;
9170 if (attribute_flag[32] != 0)
9171 draw_info->direction=(DirectionType)
9172 argument_list[32].integer_reference;
Cristy36c30b62018-11-22 09:33:30 -05009173 (void) DrawImage(image,draw_info,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009174 draw_info=DestroyDrawInfo(draw_info);
9175 break;
9176 }
9177 case 39: /* Equalize */
9178 {
9179 if (attribute_flag[0] != 0)
9180 channel=(ChannelType) argument_list[0].integer_reference;
9181 channel_mask=SetImageChannelMask(image,channel);
Cristy36c30b62018-11-22 09:33:30 -05009182 (void) EqualizeImage(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009183 (void) SetImageChannelMask(image,channel_mask);
9184 break;
9185 }
9186 case 40: /* Gamma */
9187 {
9188 if (attribute_flag[1] != 0)
9189 channel=(ChannelType) argument_list[1].integer_reference;
9190 if (attribute_flag[2] == 0)
9191 argument_list[2].real_reference=1.0;
9192 if (attribute_flag[3] == 0)
9193 argument_list[3].real_reference=1.0;
9194 if (attribute_flag[4] == 0)
9195 argument_list[4].real_reference=1.0;
9196 if (attribute_flag[0] == 0)
9197 {
cristy151b66d2015-04-15 10:50:31 +00009198 (void) FormatLocaleString(message,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -05009199 "%.20g,%.20g,%.20g",(double) argument_list[2].real_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009200 (double) argument_list[3].real_reference,
9201 (double) argument_list[4].real_reference);
9202 argument_list[0].string_reference=message;
9203 }
9204 (void) GammaImage(image,StringToDouble(
9205 argument_list[0].string_reference,(char **) NULL),exception);
9206 break;
9207 }
9208 case 41: /* Map */
9209 {
9210 QuantizeInfo
9211 *quantize_info;
9212
9213 if (attribute_flag[0] == 0)
9214 {
9215 ThrowPerlException(exception,OptionError,"MapImageRequired",
9216 PackageName);
9217 goto PerlException;
9218 }
9219 quantize_info=AcquireQuantizeInfo(info->image_info);
9220 if (attribute_flag[1] != 0)
9221 quantize_info->dither_method=(DitherMethod)
9222 argument_list[1].integer_reference;
9223 (void) RemapImages(quantize_info,image,
9224 argument_list[0].image_reference,exception);
9225 quantize_info=DestroyQuantizeInfo(quantize_info);
9226 break;
9227 }
9228 case 42: /* MatteFloodfill */
9229 {
9230 DrawInfo
9231 *draw_info;
9232
9233 MagickBooleanType
9234 invert;
9235
9236 PixelInfo
9237 target;
9238
9239 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9240 (DrawInfo *) NULL);
9241 if (attribute_flag[0] != 0)
9242 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9243 &geometry,exception);
9244 if (attribute_flag[1] != 0)
9245 geometry.x=argument_list[1].integer_reference;
9246 if (attribute_flag[2] != 0)
9247 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009248 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009249 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9250 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9251 geometry.x,geometry.y,&target,exception);
9252 if (attribute_flag[4] != 0)
9253 QueryColorCompliance(argument_list[4].string_reference,
9254 AllCompliance,&target,exception);
9255 if (attribute_flag[3] != 0)
9256 target.alpha=StringToDoubleInterval(
9257 argument_list[3].string_reference,(double) (double) QuantumRange+
9258 1.0);
9259 if (attribute_flag[5] != 0)
9260 image->fuzz=StringToDoubleInterval(
9261 argument_list[5].string_reference,(double) QuantumRange+1.0);
9262 invert=MagickFalse;
9263 if (attribute_flag[6] != 0)
9264 invert=(MagickBooleanType) argument_list[6].integer_reference;
9265 channel_mask=SetImageChannelMask(image,AlphaChannel);
9266 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9267 geometry.y,invert,exception);
9268 (void) SetImageChannelMask(image,channel_mask);
9269 draw_info=DestroyDrawInfo(draw_info);
9270 break;
9271 }
9272 case 43: /* Modulate */
9273 {
9274 char
cristy151b66d2015-04-15 10:50:31 +00009275 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009276
9277 geometry_info.rho=100.0;
9278 geometry_info.sigma=100.0;
9279 geometry_info.xi=100.0;
9280 if (attribute_flag[0] != 0)
9281 (void)ParseGeometry(argument_list[0].string_reference,
9282 &geometry_info);
9283 if (attribute_flag[1] != 0)
9284 geometry_info.xi=argument_list[1].real_reference;
9285 if (attribute_flag[2] != 0)
9286 geometry_info.sigma=argument_list[2].real_reference;
9287 if (attribute_flag[3] != 0)
9288 {
9289 geometry_info.sigma=argument_list[3].real_reference;
9290 SetImageArtifact(image,"modulate:colorspace","HWB");
9291 }
9292 if (attribute_flag[4] != 0)
9293 {
9294 geometry_info.rho=argument_list[4].real_reference;
9295 SetImageArtifact(image,"modulate:colorspace","HSB");
9296 }
9297 if (attribute_flag[5] != 0)
9298 {
9299 geometry_info.sigma=argument_list[5].real_reference;
9300 SetImageArtifact(image,"modulate:colorspace","HSL");
9301 }
9302 if (attribute_flag[6] != 0)
9303 {
9304 geometry_info.rho=argument_list[6].real_reference;
9305 SetImageArtifact(image,"modulate:colorspace","HWB");
9306 }
Cristy935a4052017-03-31 17:45:37 -04009307 (void) FormatLocaleString(modulate,MagickPathExtent,"%.20g,%.20g,%.20g",
9308 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy4a3ce0a2013-08-03 20:06:59 +00009309 (void) ModulateImage(image,modulate,exception);
9310 break;
9311 }
9312 case 44: /* Negate */
9313 {
9314 if (attribute_flag[0] == 0)
9315 argument_list[0].integer_reference=0;
9316 if (attribute_flag[1] != 0)
9317 channel=(ChannelType) argument_list[1].integer_reference;
9318 channel_mask=SetImageChannelMask(image,channel);
9319 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9320 MagickTrue : MagickFalse,exception);
9321 (void) SetImageChannelMask(image,channel_mask);
9322 break;
9323 }
9324 case 45: /* Normalize */
9325 {
9326 if (attribute_flag[0] != 0)
9327 channel=(ChannelType) argument_list[0].integer_reference;
9328 channel_mask=SetImageChannelMask(image,channel);
9329 NormalizeImage(image,exception);
9330 (void) SetImageChannelMask(image,channel_mask);
9331 break;
9332 }
9333 case 46: /* NumberColors */
9334 break;
9335 case 47: /* Opaque */
9336 {
9337 MagickBooleanType
9338 invert;
9339
9340 PixelInfo
9341 fill_color,
9342 target;
9343
9344 (void) QueryColorCompliance("none",AllCompliance,&target,
9345 exception);
9346 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9347 exception);
9348 if (attribute_flag[0] != 0)
9349 (void) QueryColorCompliance(argument_list[0].string_reference,
9350 AllCompliance,&target,exception);
9351 if (attribute_flag[1] != 0)
9352 (void) QueryColorCompliance(argument_list[1].string_reference,
9353 AllCompliance,&fill_color,exception);
9354 if (attribute_flag[2] != 0)
9355 image->fuzz=StringToDoubleInterval(
9356 argument_list[2].string_reference,(double) QuantumRange+1.0);
9357 if (attribute_flag[3] != 0)
9358 channel=(ChannelType) argument_list[3].integer_reference;
9359 invert=MagickFalse;
9360 if (attribute_flag[4] != 0)
9361 invert=(MagickBooleanType) argument_list[4].integer_reference;
9362 channel_mask=SetImageChannelMask(image,channel);
9363 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9364 (void) SetImageChannelMask(image,channel_mask);
9365 break;
9366 }
9367 case 48: /* Quantize */
9368 {
9369 QuantizeInfo
9370 *quantize_info;
9371
9372 quantize_info=AcquireQuantizeInfo(info->image_info);
9373 if (attribute_flag[0] != 0)
9374 quantize_info->number_colors=(size_t)
9375 argument_list[0].integer_reference;
9376 if (attribute_flag[1] != 0)
9377 quantize_info->tree_depth=(size_t)
9378 argument_list[1].integer_reference;
9379 if (attribute_flag[2] != 0)
9380 quantize_info->colorspace=(ColorspaceType)
9381 argument_list[2].integer_reference;
9382 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009383 quantize_info->dither_method=(DitherMethod)
9384 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009385 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009386 quantize_info->measure_error=
9387 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009388 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009389 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009390 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009391 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009392 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009393 argument_list[7].integer_reference;
9394 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009395 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009396 else
cristyf7563392014-03-25 13:54:04 +00009397 if ((image->storage_class == DirectClass) ||
9398 (image->colors > quantize_info->number_colors) ||
9399 (quantize_info->colorspace == GRAYColorspace))
9400 (void) QuantizeImage(quantize_info,image,exception);
9401 else
9402 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009403 quantize_info=DestroyQuantizeInfo(quantize_info);
9404 break;
9405 }
9406 case 49: /* Raise */
9407 {
9408 if (attribute_flag[0] != 0)
9409 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9410 &geometry,exception);
9411 if (attribute_flag[1] != 0)
9412 geometry.width=argument_list[1].integer_reference;
9413 if (attribute_flag[2] != 0)
9414 geometry.height=argument_list[2].integer_reference;
9415 if (attribute_flag[3] == 0)
9416 argument_list[3].integer_reference=1;
9417 (void) RaiseImage(image,&geometry,
9418 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9419 exception);
9420 break;
9421 }
9422 case 50: /* Segment */
9423 {
9424 ColorspaceType
9425 colorspace;
9426
9427 double
9428 cluster_threshold,
9429 smoothing_threshold;
9430
9431 MagickBooleanType
9432 verbose;
9433
9434 cluster_threshold=1.0;
9435 smoothing_threshold=1.5;
9436 colorspace=sRGBColorspace;
9437 verbose=MagickFalse;
9438 if (attribute_flag[0] != 0)
9439 {
9440 flags=ParseGeometry(argument_list[0].string_reference,
9441 &geometry_info);
9442 cluster_threshold=geometry_info.rho;
9443 if (flags & SigmaValue)
9444 smoothing_threshold=geometry_info.sigma;
9445 }
9446 if (attribute_flag[1] != 0)
9447 cluster_threshold=argument_list[1].real_reference;
9448 if (attribute_flag[2] != 0)
9449 smoothing_threshold=argument_list[2].real_reference;
9450 if (attribute_flag[3] != 0)
9451 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9452 if (attribute_flag[4] != 0)
9453 verbose=argument_list[4].integer_reference != 0 ?
9454 MagickTrue : MagickFalse;
9455 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9456 smoothing_threshold,exception);
9457 break;
9458 }
9459 case 51: /* Signature */
9460 {
9461 (void) SignatureImage(image,exception);
9462 break;
9463 }
9464 case 52: /* Solarize */
9465 {
9466 geometry_info.rho=QuantumRange/2.0;
9467 if (attribute_flag[0] != 0)
9468 flags=ParseGeometry(argument_list[0].string_reference,
9469 &geometry_info);
9470 if (attribute_flag[1] != 0)
9471 geometry_info.rho=StringToDoubleInterval(
9472 argument_list[1].string_reference,(double) QuantumRange+1.0);
9473 (void) SolarizeImage(image,geometry_info.rho,exception);
9474 break;
9475 }
9476 case 53: /* Sync */
9477 {
9478 (void) SyncImage(image,exception);
9479 break;
9480 }
9481 case 54: /* Texture */
9482 {
9483 if (attribute_flag[0] == 0)
9484 break;
9485 TextureImage(image,argument_list[0].image_reference,exception);
9486 break;
9487 }
9488 case 55: /* Evalute */
9489 {
9490 MagickEvaluateOperator
9491 op;
9492
9493 op=SetEvaluateOperator;
9494 if (attribute_flag[0] == MagickFalse)
9495 argument_list[0].real_reference=0.0;
9496 if (attribute_flag[1] != MagickFalse)
9497 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9498 if (attribute_flag[2] != MagickFalse)
9499 channel=(ChannelType) argument_list[2].integer_reference;
9500 channel_mask=SetImageChannelMask(image,channel);
9501 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9502 exception);
9503 (void) SetImageChannelMask(image,channel_mask);
9504 break;
9505 }
9506 case 56: /* Transparent */
9507 {
9508 double
9509 opacity;
9510
9511 MagickBooleanType
9512 invert;
9513
9514 PixelInfo
9515 target;
9516
9517 (void) QueryColorCompliance("none",AllCompliance,&target,
9518 exception);
9519 if (attribute_flag[0] != 0)
9520 (void) QueryColorCompliance(argument_list[0].string_reference,
9521 AllCompliance,&target,exception);
9522 opacity=TransparentAlpha;
9523 if (attribute_flag[1] != 0)
9524 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9525 (double) QuantumRange+1.0);
9526 if (attribute_flag[2] != 0)
9527 image->fuzz=StringToDoubleInterval(
9528 argument_list[2].string_reference,(double) QuantumRange+1.0);
9529 if (attribute_flag[3] == 0)
9530 argument_list[3].integer_reference=0;
9531 invert=MagickFalse;
9532 if (attribute_flag[3] != 0)
9533 invert=(MagickBooleanType) argument_list[3].integer_reference;
9534 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9535 invert,exception);
9536 break;
9537 }
9538 case 57: /* Threshold */
9539 {
9540 double
9541 threshold;
9542
9543 if (attribute_flag[0] == 0)
9544 argument_list[0].string_reference="50%";
9545 if (attribute_flag[1] != 0)
9546 channel=(ChannelType) argument_list[1].integer_reference;
9547 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9548 (double) QuantumRange+1.0);
9549 channel_mask=SetImageChannelMask(image,channel);
9550 (void) BilevelImage(image,threshold,exception);
9551 (void) SetImageChannelMask(image,channel_mask);
9552 break;
9553 }
9554 case 58: /* Charcoal */
9555 {
9556 if (attribute_flag[0] != 0)
9557 {
9558 flags=ParseGeometry(argument_list[0].string_reference,
9559 &geometry_info);
9560 if ((flags & SigmaValue) == 0)
9561 geometry_info.sigma=1.0;
9562 }
9563 if (attribute_flag[1] != 0)
9564 geometry_info.rho=argument_list[1].real_reference;
9565 if (attribute_flag[2] != 0)
9566 geometry_info.sigma=argument_list[2].real_reference;
9567 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9568 exception);
9569 break;
9570 }
9571 case 59: /* Trim */
9572 {
9573 if (attribute_flag[0] != 0)
9574 image->fuzz=StringToDoubleInterval(
9575 argument_list[0].string_reference,(double) QuantumRange+1.0);
9576 image=TrimImage(image,exception);
9577 break;
9578 }
9579 case 60: /* Wave */
9580 {
9581 PixelInterpolateMethod
9582 method;
9583
9584 if (attribute_flag[0] != 0)
9585 {
9586 flags=ParseGeometry(argument_list[0].string_reference,
9587 &geometry_info);
9588 if ((flags & SigmaValue) == 0)
9589 geometry_info.sigma=1.0;
9590 }
9591 if (attribute_flag[1] != 0)
9592 geometry_info.rho=argument_list[1].real_reference;
9593 if (attribute_flag[2] != 0)
9594 geometry_info.sigma=argument_list[2].real_reference;
9595 method=UndefinedInterpolatePixel;
9596 if (attribute_flag[3] != 0)
9597 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9598 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9599 method,exception);
9600 break;
9601 }
9602 case 61: /* Separate */
9603 {
9604 if (attribute_flag[0] != 0)
9605 channel=(ChannelType) argument_list[0].integer_reference;
9606 image=SeparateImage(image,channel,exception);
9607 break;
9608 }
9609 case 63: /* Stereo */
9610 {
9611 if (attribute_flag[0] == 0)
9612 {
9613 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9614 PackageName);
9615 goto PerlException;
9616 }
9617 if (attribute_flag[1] != 0)
9618 geometry.x=argument_list[1].integer_reference;
9619 if (attribute_flag[2] != 0)
9620 geometry.y=argument_list[2].integer_reference;
9621 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9622 geometry.x,geometry.y,exception);
9623 break;
9624 }
9625 case 64: /* Stegano */
9626 {
9627 if (attribute_flag[0] == 0)
9628 {
9629 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9630 PackageName);
9631 goto PerlException;
9632 }
9633 if (attribute_flag[1] == 0)
9634 argument_list[1].integer_reference=0;
9635 image->offset=argument_list[1].integer_reference;
9636 image=SteganoImage(image,argument_list[0].image_reference,exception);
9637 break;
9638 }
9639 case 65: /* Deconstruct */
9640 {
9641 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9642 break;
9643 }
9644 case 66: /* GaussianBlur */
9645 {
9646 if (attribute_flag[0] != 0)
9647 {
9648 flags=ParseGeometry(argument_list[0].string_reference,
9649 &geometry_info);
9650 if ((flags & SigmaValue) == 0)
9651 geometry_info.sigma=1.0;
9652 }
9653 if (attribute_flag[1] != 0)
9654 geometry_info.rho=argument_list[1].real_reference;
9655 if (attribute_flag[2] != 0)
9656 geometry_info.sigma=argument_list[2].real_reference;
9657 if (attribute_flag[3] != 0)
9658 channel=(ChannelType) argument_list[3].integer_reference;
9659 channel_mask=SetImageChannelMask(image,channel);
9660 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9661 exception);
9662 if (image != (Image *) NULL)
9663 (void) SetImageChannelMask(image,channel_mask);
9664 break;
9665 }
9666 case 67: /* Convolve */
9667 {
9668 KernelInfo
9669 *kernel;
9670
9671 kernel=(KernelInfo *) NULL;
9672 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9673 break;
9674 if (attribute_flag[0] != 0)
9675 {
9676 AV
9677 *av;
9678
9679 size_t
9680 order;
9681
cristy2c57b742014-10-31 00:40:34 +00009682 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009683 if (kernel == (KernelInfo *) NULL)
9684 break;
9685 av=(AV *) argument_list[0].array_reference;
9686 order=(size_t) sqrt(av_len(av)+1);
9687 kernel->width=order;
9688 kernel->height=order;
9689 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9690 order*sizeof(*kernel->values));
9691 if (kernel->values == (MagickRealType *) NULL)
9692 {
9693 kernel=DestroyKernelInfo(kernel);
9694 ThrowPerlException(exception,ResourceLimitFatalError,
9695 "MemoryAllocationFailed",PackageName);
9696 goto PerlException;
9697 }
9698 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9699 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9700 for ( ; j < (ssize_t) (order*order); j++)
9701 kernel->values[j]=0.0;
9702 }
9703 if (attribute_flag[1] != 0)
9704 channel=(ChannelType) argument_list[1].integer_reference;
9705 if (attribute_flag[2] != 0)
Cristyc4ff6bd2017-07-05 21:00:11 -04009706 SetImageArtifact(image,"convolve:bias",
cristy4a3ce0a2013-08-03 20:06:59 +00009707 argument_list[2].string_reference);
9708 if (attribute_flag[3] != 0)
9709 {
cristy2c57b742014-10-31 00:40:34 +00009710 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9711 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009712 if (kernel == (KernelInfo *) NULL)
9713 break;
9714 }
9715 channel_mask=SetImageChannelMask(image,channel);
9716 image=ConvolveImage(image,kernel,exception);
9717 if (image != (Image *) NULL)
9718 (void) SetImageChannelMask(image,channel_mask);
9719 kernel=DestroyKernelInfo(kernel);
9720 break;
9721 }
9722 case 68: /* Profile */
9723 {
9724 const char
9725 *name;
9726
9727 Image
9728 *profile_image;
9729
9730 ImageInfo
9731 *profile_info;
9732
9733 StringInfo
9734 *profile;
9735
9736 name="*";
9737 if (attribute_flag[0] != 0)
9738 name=argument_list[0].string_reference;
9739 if (attribute_flag[2] != 0)
9740 image->rendering_intent=(RenderingIntent)
9741 argument_list[2].integer_reference;
9742 if (attribute_flag[3] != 0)
9743 image->black_point_compensation=
9744 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9745 if (attribute_flag[1] != 0)
9746 {
9747 if (argument_list[1].length == 0)
9748 {
9749 /*
9750 Remove a profile from the image.
9751 */
9752 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9753 exception);
9754 break;
9755 }
9756 /*
9757 Associate user supplied profile with the image.
9758 */
9759 profile=AcquireStringInfo(argument_list[1].length);
9760 SetStringInfoDatum(profile,(const unsigned char *)
9761 argument_list[1].string_reference);
9762 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9763 (size_t) GetStringInfoLength(profile),exception);
9764 profile=DestroyStringInfo(profile);
9765 break;
9766 }
9767 /*
9768 Associate a profile with the image.
9769 */
9770 profile_info=CloneImageInfo(info ? info->image_info :
9771 (ImageInfo *) NULL);
9772 profile_image=ReadImages(profile_info,name,exception);
9773 if (profile_image == (Image *) NULL)
9774 break;
9775 ResetImageProfileIterator(profile_image);
9776 name=GetNextImageProfile(profile_image);
9777 while (name != (const char *) NULL)
9778 {
9779 const StringInfo
9780 *profile;
9781
9782 profile=GetImageProfile(profile_image,name);
9783 if (profile != (const StringInfo *) NULL)
9784 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9785 (size_t) GetStringInfoLength(profile),exception);
9786 name=GetNextImageProfile(profile_image);
9787 }
9788 profile_image=DestroyImage(profile_image);
9789 profile_info=DestroyImageInfo(profile_info);
9790 break;
9791 }
9792 case 69: /* UnsharpMask */
9793 {
9794 if (attribute_flag[0] != 0)
9795 {
9796 flags=ParseGeometry(argument_list[0].string_reference,
9797 &geometry_info);
9798 if ((flags & SigmaValue) == 0)
9799 geometry_info.sigma=1.0;
9800 if ((flags & XiValue) == 0)
9801 geometry_info.xi=1.0;
9802 if ((flags & PsiValue) == 0)
9803 geometry_info.psi=0.5;
9804 }
9805 if (attribute_flag[1] != 0)
9806 geometry_info.rho=argument_list[1].real_reference;
9807 if (attribute_flag[2] != 0)
9808 geometry_info.sigma=argument_list[2].real_reference;
9809 if (attribute_flag[3] != 0)
9810 geometry_info.xi=argument_list[3].real_reference;
9811 if (attribute_flag[4] != 0)
9812 geometry_info.psi=argument_list[4].real_reference;
9813 if (attribute_flag[5] != 0)
9814 channel=(ChannelType) argument_list[5].integer_reference;
9815 channel_mask=SetImageChannelMask(image,channel);
9816 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9817 geometry_info.xi,geometry_info.psi,exception);
9818 if (image != (Image *) NULL)
9819 (void) SetImageChannelMask(image,channel_mask);
9820 break;
9821 }
9822 case 70: /* MotionBlur */
9823 {
9824 if (attribute_flag[0] != 0)
9825 {
9826 flags=ParseGeometry(argument_list[0].string_reference,
9827 &geometry_info);
9828 if ((flags & SigmaValue) == 0)
9829 geometry_info.sigma=1.0;
9830 if ((flags & XiValue) == 0)
9831 geometry_info.xi=1.0;
9832 }
9833 if (attribute_flag[1] != 0)
9834 geometry_info.rho=argument_list[1].real_reference;
9835 if (attribute_flag[2] != 0)
9836 geometry_info.sigma=argument_list[2].real_reference;
9837 if (attribute_flag[3] != 0)
9838 geometry_info.xi=argument_list[3].real_reference;
9839 if (attribute_flag[4] != 0)
9840 channel=(ChannelType) argument_list[4].integer_reference;
9841 channel_mask=SetImageChannelMask(image,channel);
9842 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9843 geometry_info.xi,exception);
9844 if (image != (Image *) NULL)
9845 (void) SetImageChannelMask(image,channel_mask);
9846 break;
9847 }
9848 case 71: /* OrderedDither */
9849 {
9850 if (attribute_flag[0] == 0)
9851 argument_list[0].string_reference="o8x8";
9852 if (attribute_flag[1] != 0)
9853 channel=(ChannelType) argument_list[1].integer_reference;
9854 channel_mask=SetImageChannelMask(image,channel);
Cristy6b93c072016-02-04 07:45:48 -05009855 (void) OrderedDitherImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009856 exception);
9857 (void) SetImageChannelMask(image,channel_mask);
9858 break;
9859 }
9860 case 72: /* Shave */
9861 {
9862 if (attribute_flag[0] != 0)
9863 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9864 &geometry,exception);
9865 if (attribute_flag[1] != 0)
9866 geometry.width=argument_list[1].integer_reference;
9867 if (attribute_flag[2] != 0)
9868 geometry.height=argument_list[2].integer_reference;
9869 image=ShaveImage(image,&geometry,exception);
9870 break;
9871 }
9872 case 73: /* Level */
9873 {
9874 double
9875 black_point,
9876 gamma,
9877 white_point;
9878
9879 black_point=0.0;
9880 white_point=(double) image->columns*image->rows;
9881 gamma=1.0;
9882 if (attribute_flag[0] != 0)
9883 {
9884 flags=ParseGeometry(argument_list[0].string_reference,
9885 &geometry_info);
9886 black_point=geometry_info.rho;
9887 if ((flags & SigmaValue) != 0)
9888 white_point=geometry_info.sigma;
9889 if ((flags & XiValue) != 0)
9890 gamma=geometry_info.xi;
9891 if ((flags & PercentValue) != 0)
9892 {
9893 black_point*=(double) (QuantumRange/100.0);
9894 white_point*=(double) (QuantumRange/100.0);
9895 }
9896 if ((flags & SigmaValue) == 0)
9897 white_point=(double) QuantumRange-black_point;
9898 }
9899 if (attribute_flag[1] != 0)
9900 black_point=argument_list[1].real_reference;
9901 if (attribute_flag[2] != 0)
9902 white_point=argument_list[2].real_reference;
9903 if (attribute_flag[3] != 0)
9904 gamma=argument_list[3].real_reference;
9905 if (attribute_flag[4] != 0)
9906 channel=(ChannelType) argument_list[4].integer_reference;
9907 if (attribute_flag[5] != 0)
9908 {
9909 argument_list[0].real_reference=argument_list[5].real_reference;
9910 attribute_flag[0]=attribute_flag[5];
9911 }
9912 channel_mask=SetImageChannelMask(image,channel);
9913 (void) LevelImage(image,black_point,white_point,gamma,exception);
9914 (void) SetImageChannelMask(image,channel_mask);
9915 break;
9916 }
9917 case 74: /* Clip */
9918 {
9919 if (attribute_flag[0] == 0)
9920 argument_list[0].string_reference="#1";
9921 if (attribute_flag[1] == 0)
9922 argument_list[1].integer_reference=MagickTrue;
9923 (void) ClipImagePath(image,argument_list[0].string_reference,
9924 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9925 exception);
9926 break;
9927 }
9928 case 75: /* AffineTransform */
9929 {
9930 DrawInfo
9931 *draw_info;
9932
9933 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9934 (DrawInfo *) NULL);
9935 if (attribute_flag[0] != 0)
9936 {
9937 AV
9938 *av;
9939
9940 av=(AV *) argument_list[0].array_reference;
9941 if ((av_len(av) != 3) && (av_len(av) != 5))
9942 {
9943 ThrowPerlException(exception,OptionError,
9944 "affine matrix must have 4 or 6 elements",PackageName);
9945 goto PerlException;
9946 }
9947 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9948 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9949 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9950 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9951 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9952 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9953 {
9954 ThrowPerlException(exception,OptionError,
9955 "affine matrix is singular",PackageName);
9956 goto PerlException;
9957 }
9958 if (av_len(av) == 5)
9959 {
9960 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9961 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9962 }
9963 }
9964 for (j=1; j < 6; j++)
9965 {
9966 if (attribute_flag[j] == 0)
9967 continue;
9968 value=argument_list[j].string_reference;
9969 angle=argument_list[j].real_reference;
9970 current=draw_info->affine;
9971 GetAffineMatrix(&affine);
9972 switch (j)
9973 {
9974 case 1:
9975 {
9976 /*
9977 Translate.
9978 */
9979 flags=ParseGeometry(value,&geometry_info);
9980 affine.tx=geometry_info.xi;
9981 affine.ty=geometry_info.psi;
9982 if ((flags & PsiValue) == 0)
9983 affine.ty=affine.tx;
9984 break;
9985 }
9986 case 2:
9987 {
9988 /*
9989 Scale.
9990 */
9991 flags=ParseGeometry(value,&geometry_info);
9992 affine.sx=geometry_info.rho;
9993 affine.sy=geometry_info.sigma;
9994 if ((flags & SigmaValue) == 0)
9995 affine.sy=affine.sx;
9996 break;
9997 }
9998 case 3:
9999 {
10000 /*
10001 Rotate.
10002 */
10003 if (angle == 0.0)
10004 break;
10005 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
10006 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
10007 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
10008 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
10009 break;
10010 }
10011 case 4:
10012 {
10013 /*
10014 SkewX.
10015 */
10016 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
10017 break;
10018 }
10019 case 5:
10020 {
10021 /*
10022 SkewY.
10023 */
10024 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
10025 break;
10026 }
10027 }
10028 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
10029 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
10030 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
10031 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
10032 draw_info->affine.tx=
10033 current.sx*affine.tx+current.ry*affine.ty+current.tx;
10034 draw_info->affine.ty=
10035 current.rx*affine.tx+current.sy*affine.ty+current.ty;
10036 }
10037 if (attribute_flag[6] != 0)
10038 image->interpolate=(PixelInterpolateMethod)
10039 argument_list[6].integer_reference;
10040 if (attribute_flag[7] != 0)
10041 QueryColorCompliance(argument_list[7].string_reference,
10042 AllCompliance,&image->background_color,exception);
10043 image=AffineTransformImage(image,&draw_info->affine,exception);
10044 draw_info=DestroyDrawInfo(draw_info);
10045 break;
10046 }
10047 case 76: /* Difference */
10048 {
10049 if (attribute_flag[0] == 0)
10050 {
10051 ThrowPerlException(exception,OptionError,
10052 "ReferenceImageRequired",PackageName);
10053 goto PerlException;
10054 }
10055 if (attribute_flag[1] != 0)
10056 image->fuzz=StringToDoubleInterval(
10057 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -050010058 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +000010059 exception);
10060 break;
10061 }
10062 case 77: /* AdaptiveThreshold */
10063 {
10064 if (attribute_flag[0] != 0)
10065 {
10066 flags=ParseGeometry(argument_list[0].string_reference,
10067 &geometry_info);
10068 if ((flags & PercentValue) != 0)
10069 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10070 }
10071 if (attribute_flag[1] != 0)
10072 geometry_info.rho=argument_list[1].integer_reference;
10073 if (attribute_flag[2] != 0)
10074 geometry_info.sigma=argument_list[2].integer_reference;
10075 if (attribute_flag[3] != 0)
10076 geometry_info.xi=argument_list[3].integer_reference;;
10077 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
10078 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
10079 break;
10080 }
10081 case 78: /* Resample */
10082 {
10083 size_t
10084 height,
10085 width;
10086
10087 if (attribute_flag[0] != 0)
10088 {
10089 flags=ParseGeometry(argument_list[0].string_reference,
10090 &geometry_info);
10091 if ((flags & SigmaValue) == 0)
10092 geometry_info.sigma=geometry_info.rho;
10093 }
10094 if (attribute_flag[1] != 0)
10095 geometry_info.rho=argument_list[1].real_reference;
10096 if (attribute_flag[2] != 0)
10097 geometry_info.sigma=argument_list[2].real_reference;
10098 if (attribute_flag[3] == 0)
10099 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10100 if (attribute_flag[4] == 0)
10101 SetImageArtifact(image,"filter:support",
10102 argument_list[4].string_reference);
10103 width=(size_t) (geometry_info.rho*image->columns/
10104 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10105 height=(size_t) (geometry_info.sigma*image->rows/
10106 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
Cristy8645e042016-02-03 16:35:29 -050010107 image=ResizeImage(image,width,height,(FilterType)
cristy4a3ce0a2013-08-03 20:06:59 +000010108 argument_list[3].integer_reference,exception);
10109 if (image != (Image *) NULL)
10110 {
10111 image->resolution.x=geometry_info.rho;
10112 image->resolution.y=geometry_info.sigma;
10113 }
10114 break;
10115 }
10116 case 79: /* Describe */
10117 {
10118 if (attribute_flag[0] == 0)
10119 argument_list[0].file_reference=(FILE *) NULL;
cristy4a3ce0a2013-08-03 20:06:59 +000010120 (void) IdentifyImage(image,argument_list[0].file_reference,
10121 MagickTrue,exception);
10122 break;
10123 }
10124 case 80: /* BlackThreshold */
10125 {
10126 if (attribute_flag[0] == 0)
10127 argument_list[0].string_reference="50%";
10128 if (attribute_flag[2] != 0)
10129 channel=(ChannelType) argument_list[2].integer_reference;
10130 channel_mask=SetImageChannelMask(image,channel);
Cristy89b4db02020-02-21 20:57:40 -050010131 (void) BlackThresholdImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +000010132 exception);
10133 (void) SetImageChannelMask(image,channel_mask);
10134 break;
10135 }
10136 case 81: /* WhiteThreshold */
10137 {
10138 if (attribute_flag[0] == 0)
10139 argument_list[0].string_reference="50%";
10140 if (attribute_flag[2] != 0)
10141 channel=(ChannelType) argument_list[2].integer_reference;
10142 channel_mask=SetImageChannelMask(image,channel);
10143 WhiteThresholdImage(image,argument_list[0].string_reference,
10144 exception);
10145 (void) SetImageChannelMask(image,channel_mask);
10146 break;
10147 }
cristy60c73c02014-03-25 12:09:58 +000010148 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010149 {
10150 if (attribute_flag[0] != 0)
10151 {
10152 flags=ParseGeometry(argument_list[0].string_reference,
10153 &geometry_info);
10154 }
10155 if (attribute_flag[1] != 0)
10156 geometry_info.rho=argument_list[1].real_reference;
10157 if (attribute_flag[2] != 0)
10158 channel=(ChannelType) argument_list[2].integer_reference;
10159 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010160 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010161 if (image != (Image *) NULL)
10162 (void) SetImageChannelMask(image,channel_mask);
10163 break;
10164 }
10165 case 83: /* Thumbnail */
10166 {
10167 if (attribute_flag[0] != 0)
10168 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10169 &geometry,exception);
10170 if (attribute_flag[1] != 0)
10171 geometry.width=argument_list[1].integer_reference;
10172 if (attribute_flag[2] != 0)
10173 geometry.height=argument_list[2].integer_reference;
10174 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10175 break;
10176 }
10177 case 84: /* Strip */
10178 {
10179 (void) StripImage(image,exception);
10180 break;
10181 }
10182 case 85: /* Tint */
10183 {
10184 PixelInfo
10185 tint;
10186
10187 GetPixelInfo(image,&tint);
10188 if (attribute_flag[0] != 0)
10189 (void) QueryColorCompliance(argument_list[0].string_reference,
10190 AllCompliance,&tint,exception);
10191 if (attribute_flag[1] == 0)
10192 argument_list[1].string_reference="100";
10193 image=TintImage(image,argument_list[1].string_reference,&tint,
10194 exception);
10195 break;
10196 }
10197 case 86: /* Channel */
10198 {
10199 if (attribute_flag[0] != 0)
10200 channel=(ChannelType) argument_list[0].integer_reference;
10201 image=SeparateImage(image,channel,exception);
10202 break;
10203 }
10204 case 87: /* Splice */
10205 {
cristy260bd762014-08-15 12:46:34 +000010206 if (attribute_flag[7] != 0)
10207 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010208 if (attribute_flag[0] != 0)
10209 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10210 &geometry,exception);
10211 if (attribute_flag[1] != 0)
10212 geometry.width=argument_list[1].integer_reference;
10213 if (attribute_flag[2] != 0)
10214 geometry.height=argument_list[2].integer_reference;
10215 if (attribute_flag[3] != 0)
10216 geometry.x=argument_list[3].integer_reference;
10217 if (attribute_flag[4] != 0)
10218 geometry.y=argument_list[4].integer_reference;
10219 if (attribute_flag[5] != 0)
10220 image->fuzz=StringToDoubleInterval(
10221 argument_list[5].string_reference,(double) QuantumRange+1.0);
10222 if (attribute_flag[6] != 0)
10223 (void) QueryColorCompliance(argument_list[6].string_reference,
10224 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010225 image=SpliceImage(image,&geometry,exception);
10226 break;
10227 }
10228 case 88: /* Posterize */
10229 {
10230 if (attribute_flag[0] == 0)
10231 argument_list[0].integer_reference=3;
10232 if (attribute_flag[1] == 0)
10233 argument_list[1].integer_reference=0;
10234 (void) PosterizeImage(image,argument_list[0].integer_reference,
10235 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10236 NoDitherMethod,exception);
10237 break;
10238 }
10239 case 89: /* Shadow */
10240 {
10241 if (attribute_flag[0] != 0)
10242 {
10243 flags=ParseGeometry(argument_list[0].string_reference,
10244 &geometry_info);
10245 if ((flags & SigmaValue) == 0)
10246 geometry_info.sigma=1.0;
10247 if ((flags & XiValue) == 0)
10248 geometry_info.xi=4.0;
10249 if ((flags & PsiValue) == 0)
10250 geometry_info.psi=4.0;
10251 }
10252 if (attribute_flag[1] != 0)
10253 geometry_info.rho=argument_list[1].real_reference;
10254 if (attribute_flag[2] != 0)
10255 geometry_info.sigma=argument_list[2].real_reference;
10256 if (attribute_flag[3] != 0)
10257 geometry_info.xi=argument_list[3].integer_reference;
10258 if (attribute_flag[4] != 0)
10259 geometry_info.psi=argument_list[4].integer_reference;
10260 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10261 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10262 ceil(geometry_info.psi-0.5),exception);
10263 break;
10264 }
10265 case 90: /* Identify */
10266 {
10267 if (attribute_flag[0] == 0)
10268 argument_list[0].file_reference=(FILE *) NULL;
10269 if (attribute_flag[1] != 0)
10270 (void) SetImageArtifact(image,"identify:features",
10271 argument_list[1].string_reference);
10272 if ((attribute_flag[2] != 0) &&
10273 (argument_list[2].integer_reference != 0))
Cristy8b3ffe62020-02-17 12:36:53 -050010274 (void) SetImageArtifact(image,"identify:moments","true");
10275 if ((attribute_flag[3] != 0) &&
10276 (argument_list[3].integer_reference != 0))
cristy4a3ce0a2013-08-03 20:06:59 +000010277 (void) SetImageArtifact(image,"identify:unique","true");
10278 (void) IdentifyImage(image,argument_list[0].file_reference,
10279 MagickTrue,exception);
10280 break;
10281 }
10282 case 91: /* SepiaTone */
10283 {
10284 if (attribute_flag[0] == 0)
10285 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10286 image=SepiaToneImage(image,argument_list[0].real_reference,
10287 exception);
10288 break;
10289 }
10290 case 92: /* SigmoidalContrast */
10291 {
10292 MagickBooleanType
10293 sharpen;
10294
10295 if (attribute_flag[0] != 0)
10296 {
10297 flags=ParseGeometry(argument_list[0].string_reference,
10298 &geometry_info);
10299 if ((flags & SigmaValue) == 0)
10300 geometry_info.sigma=QuantumRange/2.0;
10301 if ((flags & PercentValue) != 0)
10302 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10303 }
10304 if (attribute_flag[1] != 0)
10305 geometry_info.rho=argument_list[1].real_reference;
10306 if (attribute_flag[2] != 0)
10307 geometry_info.sigma=argument_list[2].real_reference;
10308 if (attribute_flag[3] != 0)
10309 channel=(ChannelType) argument_list[3].integer_reference;
10310 sharpen=MagickTrue;
10311 if (attribute_flag[4] != 0)
10312 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10313 MagickFalse;
10314 channel_mask=SetImageChannelMask(image,channel);
10315 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10316 geometry_info.sigma,exception);
10317 (void) SetImageChannelMask(image,channel_mask);
10318 break;
10319 }
10320 case 93: /* Extent */
10321 {
10322 if (attribute_flag[7] != 0)
10323 image->gravity=(GravityType) argument_list[7].integer_reference;
10324 if (attribute_flag[0] != 0)
10325 {
10326 int
10327 flags;
10328
10329 flags=ParseGravityGeometry(image,
10330 argument_list[0].string_reference,&geometry,exception);
10331 (void) flags;
10332 if (geometry.width == 0)
10333 geometry.width=image->columns;
10334 if (geometry.height == 0)
10335 geometry.height=image->rows;
10336 }
10337 if (attribute_flag[1] != 0)
10338 geometry.width=argument_list[1].integer_reference;
10339 if (attribute_flag[2] != 0)
10340 geometry.height=argument_list[2].integer_reference;
10341 if (attribute_flag[3] != 0)
10342 geometry.x=argument_list[3].integer_reference;
10343 if (attribute_flag[4] != 0)
10344 geometry.y=argument_list[4].integer_reference;
10345 if (attribute_flag[5] != 0)
10346 image->fuzz=StringToDoubleInterval(
10347 argument_list[5].string_reference,(double) QuantumRange+1.0);
10348 if (attribute_flag[6] != 0)
10349 (void) QueryColorCompliance(argument_list[6].string_reference,
10350 AllCompliance,&image->background_color,exception);
10351 image=ExtentImage(image,&geometry,exception);
10352 break;
10353 }
10354 case 94: /* Vignette */
10355 {
10356 if (attribute_flag[0] != 0)
10357 {
10358 flags=ParseGeometry(argument_list[0].string_reference,
10359 &geometry_info);
10360 if ((flags & SigmaValue) == 0)
10361 geometry_info.sigma=1.0;
10362 if ((flags & XiValue) == 0)
10363 geometry_info.xi=0.1*image->columns;
10364 if ((flags & PsiValue) == 0)
10365 geometry_info.psi=0.1*image->rows;
10366 }
10367 if (attribute_flag[1] != 0)
10368 geometry_info.rho=argument_list[1].real_reference;
10369 if (attribute_flag[2] != 0)
10370 geometry_info.sigma=argument_list[2].real_reference;
10371 if (attribute_flag[3] != 0)
10372 geometry_info.xi=argument_list[3].integer_reference;
10373 if (attribute_flag[4] != 0)
10374 geometry_info.psi=argument_list[4].integer_reference;
10375 if (attribute_flag[5] != 0)
10376 (void) QueryColorCompliance(argument_list[5].string_reference,
10377 AllCompliance,&image->background_color,exception);
10378 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10379 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10380 ceil(geometry_info.psi-0.5),exception);
10381 break;
10382 }
10383 case 95: /* ContrastStretch */
10384 {
10385 double
10386 black_point,
10387 white_point;
10388
10389 black_point=0.0;
10390 white_point=(double) image->columns*image->rows;
10391 if (attribute_flag[0] != 0)
10392 {
10393 flags=ParseGeometry(argument_list[0].string_reference,
10394 &geometry_info);
10395 black_point=geometry_info.rho;
10396 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10397 black_point;
10398 if ((flags & PercentValue) != 0)
10399 {
10400 black_point*=(double) image->columns*image->rows/100.0;
10401 white_point*=(double) image->columns*image->rows/100.0;
10402 }
10403 white_point=(double) image->columns*image->rows-
10404 white_point;
10405 }
10406 if (attribute_flag[1] != 0)
10407 black_point=argument_list[1].real_reference;
10408 if (attribute_flag[2] != 0)
10409 white_point=argument_list[2].real_reference;
10410 if (attribute_flag[4] != 0)
10411 channel=(ChannelType) argument_list[4].integer_reference;
10412 channel_mask=SetImageChannelMask(image,channel);
10413 (void) ContrastStretchImage(image,black_point,white_point,exception);
10414 (void) SetImageChannelMask(image,channel_mask);
10415 break;
10416 }
10417 case 96: /* Sans0 */
10418 {
10419 break;
10420 }
10421 case 97: /* Sans1 */
10422 {
10423 break;
10424 }
10425 case 98: /* AdaptiveSharpen */
10426 {
10427 if (attribute_flag[0] != 0)
10428 {
10429 flags=ParseGeometry(argument_list[0].string_reference,
10430 &geometry_info);
10431 if ((flags & SigmaValue) == 0)
10432 geometry_info.sigma=1.0;
10433 if ((flags & XiValue) == 0)
10434 geometry_info.xi=0.0;
10435 }
10436 if (attribute_flag[1] != 0)
10437 geometry_info.rho=argument_list[1].real_reference;
10438 if (attribute_flag[2] != 0)
10439 geometry_info.sigma=argument_list[2].real_reference;
10440 if (attribute_flag[3] != 0)
10441 geometry_info.xi=argument_list[3].real_reference;
10442 if (attribute_flag[4] != 0)
10443 channel=(ChannelType) argument_list[4].integer_reference;
10444 channel_mask=SetImageChannelMask(image,channel);
10445 image=AdaptiveSharpenImage(image,geometry_info.rho,
10446 geometry_info.sigma,exception);
10447 if (image != (Image *) NULL)
10448 (void) SetImageChannelMask(image,channel_mask);
10449 break;
10450 }
10451 case 99: /* Transpose */
10452 {
10453 image=TransposeImage(image,exception);
10454 break;
10455 }
10456 case 100: /* Tranverse */
10457 {
10458 image=TransverseImage(image,exception);
10459 break;
10460 }
10461 case 101: /* AutoOrient */
10462 {
10463 image=AutoOrientImage(image,image->orientation,exception);
10464 break;
10465 }
10466 case 102: /* AdaptiveBlur */
10467 {
10468 if (attribute_flag[0] != 0)
10469 {
10470 flags=ParseGeometry(argument_list[0].string_reference,
10471 &geometry_info);
10472 if ((flags & SigmaValue) == 0)
10473 geometry_info.sigma=1.0;
10474 if ((flags & XiValue) == 0)
10475 geometry_info.xi=0.0;
10476 }
10477 if (attribute_flag[1] != 0)
10478 geometry_info.rho=argument_list[1].real_reference;
10479 if (attribute_flag[2] != 0)
10480 geometry_info.sigma=argument_list[2].real_reference;
10481 if (attribute_flag[3] != 0)
10482 channel=(ChannelType) argument_list[3].integer_reference;
10483 channel_mask=SetImageChannelMask(image,channel);
10484 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10485 exception);
10486 if (image != (Image *) NULL)
10487 (void) SetImageChannelMask(image,channel_mask);
10488 break;
10489 }
10490 case 103: /* Sketch */
10491 {
10492 if (attribute_flag[0] != 0)
10493 {
10494 flags=ParseGeometry(argument_list[0].string_reference,
10495 &geometry_info);
10496 if ((flags & SigmaValue) == 0)
10497 geometry_info.sigma=1.0;
10498 if ((flags & XiValue) == 0)
10499 geometry_info.xi=1.0;
10500 }
10501 if (attribute_flag[1] != 0)
10502 geometry_info.rho=argument_list[1].real_reference;
10503 if (attribute_flag[2] != 0)
10504 geometry_info.sigma=argument_list[2].real_reference;
10505 if (attribute_flag[3] != 0)
10506 geometry_info.xi=argument_list[3].real_reference;
10507 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10508 geometry_info.xi,exception);
10509 break;
10510 }
10511 case 104: /* UniqueColors */
10512 {
10513 image=UniqueImageColors(image,exception);
10514 break;
10515 }
10516 case 105: /* AdaptiveResize */
10517 {
10518 if (attribute_flag[0] != 0)
10519 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10520 &geometry,exception);
10521 if (attribute_flag[1] != 0)
10522 geometry.width=argument_list[1].integer_reference;
10523 if (attribute_flag[2] != 0)
10524 geometry.height=argument_list[2].integer_reference;
10525 if (attribute_flag[3] != 0)
Cristy8645e042016-02-03 16:35:29 -050010526 image->filter=(FilterType) argument_list[4].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010527 if (attribute_flag[4] != 0)
10528 SetImageArtifact(image,"filter:support",
10529 argument_list[4].string_reference);
10530 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10531 exception);
10532 break;
10533 }
10534 case 106: /* ClipMask */
10535 {
10536 Image
10537 *mask_image;
10538
10539 if (attribute_flag[0] == 0)
10540 {
10541 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10542 PackageName);
10543 goto PerlException;
10544 }
10545 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10546 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010547 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010548 mask_image=DestroyImage(mask_image);
10549 break;
10550 }
10551 case 107: /* LinearStretch */
10552 {
10553 double
10554 black_point,
10555 white_point;
10556
10557 black_point=0.0;
10558 white_point=(double) image->columns*image->rows;
10559 if (attribute_flag[0] != 0)
10560 {
10561 flags=ParseGeometry(argument_list[0].string_reference,
10562 &geometry_info);
10563 if ((flags & SigmaValue) != 0)
10564 white_point=geometry_info.sigma;
10565 if ((flags & PercentValue) != 0)
10566 {
10567 black_point*=(double) image->columns*image->rows/100.0;
10568 white_point*=(double) image->columns*image->rows/100.0;
10569 }
10570 if ((flags & SigmaValue) == 0)
10571 white_point=(double) image->columns*image->rows-black_point;
10572 }
10573 if (attribute_flag[1] != 0)
10574 black_point=argument_list[1].real_reference;
10575 if (attribute_flag[2] != 0)
10576 white_point=argument_list[2].real_reference;
10577 (void) LinearStretchImage(image,black_point,white_point,exception);
10578 break;
10579 }
10580 case 108: /* ColorMatrix */
10581 {
10582 AV
10583 *av;
10584
10585 double
10586 *color_matrix;
10587
10588 KernelInfo
10589 *kernel_info;
10590
10591 size_t
10592 order;
10593
10594 if (attribute_flag[0] == 0)
10595 break;
10596 av=(AV *) argument_list[0].array_reference;
10597 order=(size_t) sqrt(av_len(av)+1);
10598 color_matrix=(double *) AcquireQuantumMemory(order,order*
10599 sizeof(*color_matrix));
10600 if (color_matrix == (double *) NULL)
10601 {
10602 ThrowPerlException(exception,ResourceLimitFatalError,
10603 "MemoryAllocationFailed",PackageName);
10604 goto PerlException;
10605 }
10606 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10607 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10608 for ( ; j < (ssize_t) (order*order); j++)
10609 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010610 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010611 if (kernel_info == (KernelInfo *) NULL)
10612 break;
10613 kernel_info->width=order;
10614 kernel_info->height=order;
10615 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10616 order*sizeof(*kernel_info->values));
10617 if (kernel_info->values != (MagickRealType *) NULL)
10618 {
10619 for (i=0; i < (ssize_t) (order*order); i++)
10620 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10621 image=ColorMatrixImage(image,kernel_info,exception);
10622 }
10623 kernel_info=DestroyKernelInfo(kernel_info);
10624 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10625 break;
10626 }
10627 case 109: /* Mask */
10628 {
10629 Image
10630 *mask_image;
10631
10632 if (attribute_flag[0] == 0)
10633 {
10634 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10635 PackageName);
10636 goto PerlException;
10637 }
10638 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10639 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010640 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010641 mask_image=DestroyImage(mask_image);
10642 break;
10643 }
10644 case 110: /* Polaroid */
10645 {
10646 char
10647 *caption;
10648
10649 DrawInfo
10650 *draw_info;
10651
10652 double
10653 angle;
10654
10655 PixelInterpolateMethod
10656 method;
10657
10658 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10659 (DrawInfo *) NULL);
10660 caption=(char *) NULL;
10661 if (attribute_flag[0] != 0)
10662 caption=InterpretImageProperties(info ? info->image_info :
10663 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10664 exception);
10665 angle=0.0;
10666 if (attribute_flag[1] != 0)
10667 angle=argument_list[1].real_reference;
10668 if (attribute_flag[2] != 0)
10669 (void) CloneString(&draw_info->font,
10670 argument_list[2].string_reference);
10671 if (attribute_flag[3] != 0)
10672 (void) QueryColorCompliance(argument_list[3].string_reference,
10673 AllCompliance,&draw_info->stroke,exception);
10674 if (attribute_flag[4] != 0)
10675 (void) QueryColorCompliance(argument_list[4].string_reference,
10676 AllCompliance,&draw_info->fill,exception);
10677 if (attribute_flag[5] != 0)
10678 draw_info->stroke_width=argument_list[5].real_reference;
10679 if (attribute_flag[6] != 0)
10680 draw_info->pointsize=argument_list[6].real_reference;
10681 if (attribute_flag[7] != 0)
10682 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10683 if (attribute_flag[8] != 0)
10684 (void) QueryColorCompliance(argument_list[8].string_reference,
10685 AllCompliance,&image->background_color,exception);
10686 method=UndefinedInterpolatePixel;
10687 if (attribute_flag[9] != 0)
10688 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10689 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10690 draw_info=DestroyDrawInfo(draw_info);
10691 if (caption != (char *) NULL)
10692 caption=DestroyString(caption);
10693 break;
10694 }
10695 case 111: /* FloodfillPaint */
10696 {
10697 DrawInfo
10698 *draw_info;
10699
10700 MagickBooleanType
10701 invert;
10702
10703 PixelInfo
10704 target;
10705
10706 draw_info=CloneDrawInfo(info ? info->image_info :
10707 (ImageInfo *) NULL,(DrawInfo *) NULL);
10708 if (attribute_flag[0] != 0)
10709 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10710 &geometry,exception);
10711 if (attribute_flag[1] != 0)
10712 geometry.x=argument_list[1].integer_reference;
10713 if (attribute_flag[2] != 0)
10714 geometry.y=argument_list[2].integer_reference;
10715 if (attribute_flag[3] != 0)
10716 (void) QueryColorCompliance(argument_list[3].string_reference,
10717 AllCompliance,&draw_info->fill,exception);
10718 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10719 geometry.x,geometry.y,&target,exception);
10720 if (attribute_flag[4] != 0)
10721 QueryColorCompliance(argument_list[4].string_reference,
10722 AllCompliance,&target,exception);
10723 if (attribute_flag[5] != 0)
10724 image->fuzz=StringToDoubleInterval(
10725 argument_list[5].string_reference,(double) QuantumRange+1.0);
10726 if (attribute_flag[6] != 0)
10727 channel=(ChannelType) argument_list[6].integer_reference;
10728 invert=MagickFalse;
10729 if (attribute_flag[7] != 0)
10730 invert=(MagickBooleanType) argument_list[7].integer_reference;
10731 channel_mask=SetImageChannelMask(image,channel);
10732 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10733 geometry.y,invert,exception);
10734 (void) SetImageChannelMask(image,channel_mask);
10735 draw_info=DestroyDrawInfo(draw_info);
10736 break;
10737 }
10738 case 112: /* Distort */
10739 {
10740 AV
10741 *av;
10742
10743 double
10744 *coordinates;
10745
Cristy8645e042016-02-03 16:35:29 -050010746 DistortMethod
cristy4a3ce0a2013-08-03 20:06:59 +000010747 method;
10748
10749 size_t
10750 number_coordinates;
10751
10752 VirtualPixelMethod
10753 virtual_pixel;
10754
10755 if (attribute_flag[0] == 0)
10756 break;
10757 method=UndefinedDistortion;
10758 if (attribute_flag[1] != 0)
Cristy8645e042016-02-03 16:35:29 -050010759 method=(DistortMethod) argument_list[1].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010760 av=(AV *) argument_list[0].array_reference;
10761 number_coordinates=(size_t) av_len(av)+1;
10762 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10763 sizeof(*coordinates));
10764 if (coordinates == (double *) NULL)
10765 {
10766 ThrowPerlException(exception,ResourceLimitFatalError,
10767 "MemoryAllocationFailed",PackageName);
10768 goto PerlException;
10769 }
10770 for (j=0; j < (ssize_t) number_coordinates; j++)
10771 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10772 virtual_pixel=UndefinedVirtualPixelMethod;
10773 if (attribute_flag[2] != 0)
10774 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10775 argument_list[2].integer_reference,exception);
10776 image=DistortImage(image,method,number_coordinates,coordinates,
10777 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10778 exception);
10779 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10780 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10781 exception);
10782 coordinates=(double *) RelinquishMagickMemory(coordinates);
10783 break;
10784 }
10785 case 113: /* Clut */
10786 {
10787 PixelInterpolateMethod
10788 method;
10789
10790 if (attribute_flag[0] == 0)
10791 {
10792 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10793 PackageName);
10794 goto PerlException;
10795 }
10796 method=UndefinedInterpolatePixel;
10797 if (attribute_flag[1] != 0)
10798 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10799 if (attribute_flag[2] != 0)
10800 channel=(ChannelType) argument_list[2].integer_reference;
10801 channel_mask=SetImageChannelMask(image,channel);
10802 (void) ClutImage(image,argument_list[0].image_reference,method,
10803 exception);
10804 (void) SetImageChannelMask(image,channel_mask);
10805 break;
10806 }
10807 case 114: /* LiquidRescale */
10808 {
10809 if (attribute_flag[0] != 0)
10810 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10811 &geometry,exception);
10812 if (attribute_flag[1] != 0)
10813 geometry.width=argument_list[1].integer_reference;
10814 if (attribute_flag[2] != 0)
10815 geometry.height=argument_list[2].integer_reference;
10816 if (attribute_flag[3] == 0)
10817 argument_list[3].real_reference=1.0;
10818 if (attribute_flag[4] == 0)
10819 argument_list[4].real_reference=0.0;
10820 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10821 argument_list[3].real_reference,argument_list[4].real_reference,
10822 exception);
10823 break;
10824 }
10825 case 115: /* EncipherImage */
10826 {
10827 (void) EncipherImage(image,argument_list[0].string_reference,
10828 exception);
10829 break;
10830 }
10831 case 116: /* DecipherImage */
10832 {
10833 (void) DecipherImage(image,argument_list[0].string_reference,
10834 exception);
10835 break;
10836 }
10837 case 117: /* Deskew */
10838 {
10839 geometry_info.rho=QuantumRange/2.0;
10840 if (attribute_flag[0] != 0)
10841 flags=ParseGeometry(argument_list[0].string_reference,
10842 &geometry_info);
10843 if (attribute_flag[1] != 0)
10844 geometry_info.rho=StringToDoubleInterval(
10845 argument_list[1].string_reference,(double) QuantumRange+1.0);
10846 image=DeskewImage(image,geometry_info.rho,exception);
10847 break;
10848 }
10849 case 118: /* Remap */
10850 {
10851 QuantizeInfo
10852 *quantize_info;
10853
10854 if (attribute_flag[0] == 0)
10855 {
10856 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10857 PackageName);
10858 goto PerlException;
10859 }
10860 quantize_info=AcquireQuantizeInfo(info->image_info);
10861 if (attribute_flag[1] != 0)
10862 quantize_info->dither_method=(DitherMethod)
10863 argument_list[1].integer_reference;
10864 (void) RemapImages(quantize_info,image,
10865 argument_list[0].image_reference,exception);
10866 quantize_info=DestroyQuantizeInfo(quantize_info);
10867 break;
10868 }
10869 case 119: /* SparseColor */
10870 {
10871 AV
10872 *av;
10873
10874 double
10875 *coordinates;
10876
10877 SparseColorMethod
10878 method;
10879
10880 size_t
10881 number_coordinates;
10882
10883 VirtualPixelMethod
10884 virtual_pixel;
10885
10886 if (attribute_flag[0] == 0)
10887 break;
10888 method=UndefinedColorInterpolate;
10889 if (attribute_flag[1] != 0)
10890 method=(SparseColorMethod) argument_list[1].integer_reference;
10891 av=(AV *) argument_list[0].array_reference;
10892 number_coordinates=(size_t) av_len(av)+1;
10893 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10894 sizeof(*coordinates));
10895 if (coordinates == (double *) NULL)
10896 {
10897 ThrowPerlException(exception,ResourceLimitFatalError,
10898 "MemoryAllocationFailed",PackageName);
10899 goto PerlException;
10900 }
10901 for (j=0; j < (ssize_t) number_coordinates; j++)
10902 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10903 virtual_pixel=UndefinedVirtualPixelMethod;
10904 if (attribute_flag[2] != 0)
10905 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10906 argument_list[2].integer_reference,exception);
10907 if (attribute_flag[3] != 0)
10908 channel=(ChannelType) argument_list[3].integer_reference;
10909 channel_mask=SetImageChannelMask(image,channel);
10910 image=SparseColorImage(image,method,number_coordinates,coordinates,
10911 exception);
10912 if (image != (Image *) NULL)
10913 (void) SetImageChannelMask(image,channel_mask);
10914 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10915 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10916 exception);
10917 coordinates=(double *) RelinquishMagickMemory(coordinates);
10918 break;
10919 }
10920 case 120: /* Function */
10921 {
10922 AV
10923 *av;
10924
10925 double
10926 *parameters;
10927
10928 MagickFunction
10929 function;
10930
10931 size_t
10932 number_parameters;
10933
10934 VirtualPixelMethod
10935 virtual_pixel;
10936
10937 if (attribute_flag[0] == 0)
10938 break;
10939 function=UndefinedFunction;
10940 if (attribute_flag[1] != 0)
10941 function=(MagickFunction) argument_list[1].integer_reference;
10942 av=(AV *) argument_list[0].array_reference;
10943 number_parameters=(size_t) av_len(av)+1;
10944 parameters=(double *) AcquireQuantumMemory(number_parameters,
10945 sizeof(*parameters));
10946 if (parameters == (double *) NULL)
10947 {
10948 ThrowPerlException(exception,ResourceLimitFatalError,
10949 "MemoryAllocationFailed",PackageName);
10950 goto PerlException;
10951 }
10952 for (j=0; j < (ssize_t) number_parameters; j++)
10953 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10954 virtual_pixel=UndefinedVirtualPixelMethod;
10955 if (attribute_flag[2] != 0)
10956 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10957 argument_list[2].integer_reference,exception);
10958 (void) FunctionImage(image,function,number_parameters,parameters,
10959 exception);
10960 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10961 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10962 exception);
10963 parameters=(double *) RelinquishMagickMemory(parameters);
10964 break;
10965 }
10966 case 121: /* SelectiveBlur */
10967 {
10968 if (attribute_flag[0] != 0)
10969 {
10970 flags=ParseGeometry(argument_list[0].string_reference,
10971 &geometry_info);
10972 if ((flags & SigmaValue) == 0)
10973 geometry_info.sigma=1.0;
10974 if ((flags & PercentValue) != 0)
10975 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10976 }
10977 if (attribute_flag[1] != 0)
10978 geometry_info.rho=argument_list[1].real_reference;
10979 if (attribute_flag[2] != 0)
10980 geometry_info.sigma=argument_list[2].real_reference;
10981 if (attribute_flag[3] != 0)
10982 geometry_info.xi=argument_list[3].integer_reference;;
10983 if (attribute_flag[5] != 0)
10984 channel=(ChannelType) argument_list[5].integer_reference;
10985 channel_mask=SetImageChannelMask(image,channel);
10986 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10987 geometry_info.xi,exception);
10988 if (image != (Image *) NULL)
10989 (void) SetImageChannelMask(image,channel_mask);
10990 break;
10991 }
10992 case 122: /* HaldClut */
10993 {
10994 if (attribute_flag[0] == 0)
10995 {
10996 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10997 PackageName);
10998 goto PerlException;
10999 }
11000 if (attribute_flag[1] != 0)
11001 channel=(ChannelType) argument_list[1].integer_reference;
11002 channel_mask=SetImageChannelMask(image,channel);
11003 (void) HaldClutImage(image,argument_list[0].image_reference,
11004 exception);
11005 (void) SetImageChannelMask(image,channel_mask);
11006 break;
11007 }
11008 case 123: /* BlueShift */
11009 {
11010 if (attribute_flag[0] != 0)
11011 (void) ParseGeometry(argument_list[0].string_reference,
11012 &geometry_info);
11013 image=BlueShiftImage(image,geometry_info.rho,exception);
11014 break;
11015 }
11016 case 124: /* ForwardFourierTransformImage */
11017 {
11018 image=ForwardFourierTransformImage(image,
11019 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11020 exception);
11021 break;
11022 }
11023 case 125: /* InverseFourierTransformImage */
11024 {
11025 image=InverseFourierTransformImage(image,image->next,
11026 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11027 exception);
11028 break;
11029 }
11030 case 126: /* ColorDecisionList */
11031 {
11032 if (attribute_flag[0] == 0)
11033 argument_list[0].string_reference=(char *) NULL;
11034 (void) ColorDecisionListImage(image,
11035 argument_list[0].string_reference,exception);
11036 break;
11037 }
11038 case 127: /* AutoGamma */
11039 {
11040 if (attribute_flag[0] != 0)
11041 channel=(ChannelType) argument_list[0].integer_reference;
11042 channel_mask=SetImageChannelMask(image,channel);
11043 (void) AutoGammaImage(image,exception);
11044 (void) SetImageChannelMask(image,channel_mask);
11045 break;
11046 }
11047 case 128: /* AutoLevel */
11048 {
11049 if (attribute_flag[0] != 0)
11050 channel=(ChannelType) argument_list[0].integer_reference;
11051 channel_mask=SetImageChannelMask(image,channel);
11052 (void) AutoLevelImage(image,exception);
11053 (void) SetImageChannelMask(image,channel_mask);
11054 break;
11055 }
11056 case 129: /* LevelColors */
11057 {
11058 PixelInfo
11059 black_point,
11060 white_point;
11061
11062 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
11063 exception);
11064 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
11065 exception);
11066 if (attribute_flag[1] != 0)
11067 (void) QueryColorCompliance(
11068 argument_list[1].string_reference,AllCompliance,&black_point,
11069 exception);
11070 if (attribute_flag[2] != 0)
11071 (void) QueryColorCompliance(
11072 argument_list[2].string_reference,AllCompliance,&white_point,
11073 exception);
11074 if (attribute_flag[3] != 0)
11075 channel=(ChannelType) argument_list[3].integer_reference;
11076 channel_mask=SetImageChannelMask(image,channel);
11077 (void) LevelImageColors(image,&black_point,&white_point,
11078 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11079 exception);
11080 (void) SetImageChannelMask(image,channel_mask);
11081 break;
11082 }
11083 case 130: /* Clamp */
11084 {
11085 if (attribute_flag[0] != 0)
11086 channel=(ChannelType) argument_list[0].integer_reference;
11087 channel_mask=SetImageChannelMask(image,channel);
11088 (void) ClampImage(image,exception);
11089 (void) SetImageChannelMask(image,channel_mask);
11090 break;
11091 }
11092 case 131: /* BrightnessContrast */
11093 {
11094 double
11095 brightness,
11096 contrast;
11097
11098 brightness=0.0;
11099 contrast=0.0;
11100 if (attribute_flag[0] != 0)
11101 {
11102 flags=ParseGeometry(argument_list[0].string_reference,
11103 &geometry_info);
11104 brightness=geometry_info.rho;
11105 if ((flags & SigmaValue) == 0)
11106 contrast=geometry_info.sigma;
11107 }
11108 if (attribute_flag[1] != 0)
11109 brightness=argument_list[1].real_reference;
11110 if (attribute_flag[2] != 0)
11111 contrast=argument_list[2].real_reference;
11112 if (attribute_flag[4] != 0)
11113 channel=(ChannelType) argument_list[4].integer_reference;
11114 channel_mask=SetImageChannelMask(image,channel);
11115 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11116 (void) SetImageChannelMask(image,channel_mask);
11117 break;
11118 }
11119 case 132: /* Morphology */
11120 {
11121 KernelInfo
11122 *kernel;
11123
11124 MorphologyMethod
11125 method;
11126
11127 ssize_t
11128 iterations;
11129
11130 if (attribute_flag[0] == 0)
11131 break;
cristy2c57b742014-10-31 00:40:34 +000011132 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011133 if (kernel == (KernelInfo *) NULL)
11134 break;
11135 if (attribute_flag[1] != 0)
11136 channel=(ChannelType) argument_list[1].integer_reference;
11137 method=UndefinedMorphology;
11138 if (attribute_flag[2] != 0)
11139 method=argument_list[2].integer_reference;
11140 iterations=1;
11141 if (attribute_flag[3] != 0)
11142 iterations=argument_list[3].integer_reference;
11143 channel_mask=SetImageChannelMask(image,channel);
11144 image=MorphologyImage(image,method,iterations,kernel,exception);
11145 if (image != (Image *) NULL)
11146 (void) SetImageChannelMask(image,channel_mask);
11147 kernel=DestroyKernelInfo(kernel);
11148 break;
11149 }
11150 case 133: /* Mode */
11151 {
11152 if (attribute_flag[0] != 0)
11153 {
11154 flags=ParseGeometry(argument_list[0].string_reference,
11155 &geometry_info);
11156 if ((flags & SigmaValue) == 0)
11157 geometry_info.sigma=1.0;
11158 }
11159 if (attribute_flag[1] != 0)
11160 geometry_info.rho=argument_list[1].real_reference;
11161 if (attribute_flag[2] != 0)
11162 geometry_info.sigma=argument_list[2].real_reference;
11163 if (attribute_flag[3] != 0)
11164 channel=(ChannelType) argument_list[3].integer_reference;
11165 channel_mask=SetImageChannelMask(image,channel);
11166 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11167 (size_t) geometry_info.sigma,exception);
11168 if (image != (Image *) NULL)
11169 (void) SetImageChannelMask(image,channel_mask);
11170 break;
11171 }
11172 case 134: /* Statistic */
11173 {
11174 StatisticType
11175 statistic;
11176
11177 statistic=UndefinedStatistic;
11178 if (attribute_flag[0] != 0)
11179 {
11180 flags=ParseGeometry(argument_list[0].string_reference,
11181 &geometry_info);
11182 if ((flags & SigmaValue) == 0)
11183 geometry_info.sigma=1.0;
11184 }
11185 if (attribute_flag[1] != 0)
11186 geometry_info.rho=argument_list[1].real_reference;
11187 if (attribute_flag[2] != 0)
11188 geometry_info.sigma=argument_list[2].real_reference;
11189 if (attribute_flag[3] != 0)
11190 channel=(ChannelType) argument_list[3].integer_reference;
11191 if (attribute_flag[4] != 0)
11192 statistic=(StatisticType) argument_list[4].integer_reference;
11193 channel_mask=SetImageChannelMask(image,channel);
11194 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11195 (size_t) geometry_info.sigma,exception);
11196 if (image != (Image *) NULL)
11197 (void) SetImageChannelMask(image,channel_mask);
11198 break;
11199 }
11200 case 135: /* Perceptible */
11201 {
11202 double
11203 epsilon;
11204
11205 epsilon=MagickEpsilon;
11206 if (attribute_flag[0] != 0)
11207 epsilon=argument_list[0].real_reference;
11208 if (attribute_flag[1] != 0)
11209 channel=(ChannelType) argument_list[1].integer_reference;
11210 channel_mask=SetImageChannelMask(image,channel);
11211 (void) PerceptibleImage(image,epsilon,exception);
11212 (void) SetImageChannelMask(image,channel_mask);
11213 break;
11214 }
11215 case 136: /* Poly */
11216 {
11217 AV
11218 *av;
11219
11220 double
11221 *terms;
11222
11223 size_t
11224 number_terms;
11225
11226 if (attribute_flag[0] == 0)
11227 break;
11228 if (attribute_flag[1] != 0)
11229 channel=(ChannelType) argument_list[1].integer_reference;
11230 av=(AV *) argument_list[0].array_reference;
11231 number_terms=(size_t) av_len(av);
11232 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11233 if (terms == (double *) NULL)
11234 {
11235 ThrowPerlException(exception,ResourceLimitFatalError,
11236 "MemoryAllocationFailed",PackageName);
11237 goto PerlException;
11238 }
11239 for (j=0; j < av_len(av); j++)
11240 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11241 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11242 terms=(double *) RelinquishMagickMemory(terms);
11243 break;
11244 }
11245 case 137: /* Grayscale */
11246 {
11247 PixelIntensityMethod
11248 method;
11249
11250 method=UndefinedPixelIntensityMethod;
11251 if (attribute_flag[0] != 0)
11252 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11253 (void) GrayscaleImage(image,method,exception);
11254 break;
11255 }
cristy4ceadb82014-03-29 15:30:43 +000011256 case 138: /* Canny */
11257 {
11258 if (attribute_flag[0] != 0)
11259 {
11260 flags=ParseGeometry(argument_list[0].string_reference,
11261 &geometry_info);
11262 if ((flags & SigmaValue) == 0)
11263 geometry_info.sigma=1.0;
11264 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011265 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011266 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011267 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011268 if ((flags & PercentValue) != 0)
11269 {
11270 geometry_info.xi/=100.0;
11271 geometry_info.psi/=100.0;
11272 }
cristy4ceadb82014-03-29 15:30:43 +000011273 }
11274 if (attribute_flag[1] != 0)
11275 geometry_info.rho=argument_list[1].real_reference;
11276 if (attribute_flag[2] != 0)
11277 geometry_info.sigma=argument_list[2].real_reference;
11278 if (attribute_flag[3] != 0)
11279 geometry_info.xi=argument_list[3].real_reference;
11280 if (attribute_flag[4] != 0)
11281 geometry_info.psi=argument_list[4].real_reference;
11282 if (attribute_flag[5] != 0)
11283 channel=(ChannelType) argument_list[5].integer_reference;
11284 channel_mask=SetImageChannelMask(image,channel);
11285 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11286 geometry_info.xi,geometry_info.psi,exception);
11287 if (image != (Image *) NULL)
11288 (void) SetImageChannelMask(image,channel_mask);
11289 break;
11290 }
cristy2fc10e52014-04-26 14:13:53 +000011291 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011292 {
11293 if (attribute_flag[0] != 0)
11294 {
11295 flags=ParseGeometry(argument_list[0].string_reference,
11296 &geometry_info);
11297 if ((flags & SigmaValue) == 0)
11298 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011299 if ((flags & XiValue) == 0)
11300 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011301 }
11302 if (attribute_flag[1] != 0)
11303 geometry_info.rho=(double) argument_list[1].integer_reference;
11304 if (attribute_flag[2] != 0)
11305 geometry_info.sigma=(double) argument_list[2].integer_reference;
11306 if (attribute_flag[3] != 0)
11307 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011308 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11309 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11310 break;
11311 }
11312 case 140: /* MeanShift */
11313 {
11314 if (attribute_flag[0] != 0)
11315 {
11316 flags=ParseGeometry(argument_list[0].string_reference,
11317 &geometry_info);
11318 if ((flags & SigmaValue) == 0)
11319 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011320 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011321 geometry_info.xi=0.10*QuantumRange;
11322 if ((flags & PercentValue) != 0)
11323 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011324 }
11325 if (attribute_flag[1] != 0)
11326 geometry_info.rho=(double) argument_list[1].integer_reference;
11327 if (attribute_flag[2] != 0)
11328 geometry_info.sigma=(double) argument_list[2].integer_reference;
11329 if (attribute_flag[3] != 0)
11330 geometry_info.xi=(double) argument_list[3].integer_reference;
11331 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011332 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011333 break;
11334 }
cristy3b207f82014-09-27 14:21:20 +000011335 case 141: /* Kuwahara */
11336 {
11337 if (attribute_flag[0] != 0)
11338 {
11339 flags=ParseGeometry(argument_list[0].string_reference,
11340 &geometry_info);
11341 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011342 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011343 }
11344 if (attribute_flag[1] != 0)
11345 geometry_info.rho=argument_list[1].real_reference;
11346 if (attribute_flag[2] != 0)
11347 geometry_info.sigma=argument_list[2].real_reference;
11348 if (attribute_flag[3] != 0)
11349 channel=(ChannelType) argument_list[3].integer_reference;
11350 channel_mask=SetImageChannelMask(image,channel);
11351 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11352 exception);
11353 if (image != (Image *) NULL)
11354 (void) SetImageChannelMask(image,channel_mask);
11355 break;
11356 }
Cristy0f5df812017-07-04 18:30:05 -040011357 case 142: /* ConnectedComponents */
cristy6e0b3bc2014-10-19 17:51:42 +000011358 {
11359 size_t
11360 connectivity;
11361
11362 connectivity=4;
11363 if (attribute_flag[0] != 0)
11364 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011365 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011366 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011367 break;
11368 }
cristy0b94b392015-06-22 18:56:37 +000011369 case 143: /* Copy */
11370 {
11371 Image
11372 *source_image;
11373
11374 OffsetInfo
11375 offset;
11376
cristy2ffdb092015-06-25 14:31:20 +000011377 RectangleInfo
11378 offset_geometry;
11379
cristyf3a724a2015-06-25 13:02:53 +000011380 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011381 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011382 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011383 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011384 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011385 flags=ParseGravityGeometry(source_image,
11386 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011387 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011388 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011389 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011390 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011391 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011392 geometry.x=argument_list[4].integer_reference;
11393 if (attribute_flag[5] != 0)
11394 geometry.y=argument_list[5].integer_reference;
11395 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011396 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011397 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011398 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011399 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11400 &offset_geometry,exception);
11401 offset.x=offset_geometry.x;
11402 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011403 if (attribute_flag[8] != 0)
11404 offset.x=argument_list[8].integer_reference;
11405 if (attribute_flag[9] != 0)
11406 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011407 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11408 exception);
cristy0b94b392015-06-22 18:56:37 +000011409 break;
11410 }
Cristy5488c982016-02-13 14:07:50 -050011411 case 144: /* Color */
11412 {
11413 PixelInfo
11414 color;
11415
Cristyf20e3562016-02-14 09:08:15 -050011416 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011417 if (attribute_flag[0] != 0)
Cristyf20e3562016-02-14 09:08:15 -050011418 (void) QueryColorCompliance(argument_list[0].string_reference,
11419 AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011420 (void) SetImageColor(image,&color,exception);
11421 break;
11422 }
Cristy2d830ed2016-02-21 10:54:16 -050011423 case 145: /* WaveletDenoise */
11424 {
Cristyc1759412016-02-27 12:17:58 -050011425 if (attribute_flag[0] != 0)
Cristyee21f7f2016-02-27 15:56:49 -050011426 {
11427 flags=ParseGeometry(argument_list[0].string_reference,
11428 &geometry_info);
11429 if ((flags & PercentValue) != 0)
Cristy23446632016-02-29 09:36:34 -050011430 {
11431 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11432 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
11433 }
Cristyee21f7f2016-02-27 15:56:49 -050011434 if ((flags & SigmaValue) == 0)
11435 geometry_info.sigma=0.0;
11436 }
Cristyc1759412016-02-27 12:17:58 -050011437 if (attribute_flag[1] != 0)
11438 geometry_info.rho=argument_list[1].real_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011439 if (attribute_flag[2] != 0)
Cristyc1759412016-02-27 12:17:58 -050011440 geometry_info.sigma=argument_list[2].real_reference;
11441 if (attribute_flag[3] != 0)
11442 channel=(ChannelType) argument_list[3].integer_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011443 channel_mask=SetImageChannelMask(image,channel);
Cristyc1759412016-02-27 12:17:58 -050011444 image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11445 exception);
Cristy2d830ed2016-02-21 10:54:16 -050011446 if (image != (Image *) NULL)
11447 (void) SetImageChannelMask(image,channel_mask);
11448 break;
11449 }
Cristy99a57162016-12-05 11:47:57 -050011450 case 146: /* Colorspace */
11451 {
11452 ColorspaceType
11453 colorspace;
11454
11455 colorspace=sRGBColorspace;
11456 if (attribute_flag[0] != 0)
11457 colorspace=(ColorspaceType) argument_list[0].integer_reference;
11458 (void) TransformImageColorspace(image,colorspace,exception);
11459 break;
11460 }
Cristy53353872017-07-02 12:24:24 -040011461 case 147: /* AutoThreshold */
11462 {
11463 AutoThresholdMethod
11464 method;
11465
11466 method=UndefinedThresholdMethod;
11467 if (attribute_flag[0] != 0)
Cristyb63e7752017-07-02 13:22:01 -040011468 method=(AutoThresholdMethod) argument_list[0].integer_reference;
Cristy53353872017-07-02 12:24:24 -040011469 (void) AutoThresholdImage(image,method,exception);
11470 break;
11471 }
Cristy532b3382018-08-05 17:56:56 -040011472 case 148: /* RangeThreshold */
11473 {
11474 if (attribute_flag[0] != 0)
11475 {
11476 flags=ParseGeometry(argument_list[0].string_reference,
11477 &geometry_info);
11478 if ((flags & SigmaValue) == 0)
11479 geometry_info.sigma=geometry_info.rho;
11480 if ((flags & XiValue) == 0)
11481 geometry_info.xi=geometry_info.sigma;
11482 if ((flags & PsiValue) == 0)
11483 geometry_info.psi=geometry_info.xi;
11484 }
11485 if (attribute_flag[1] != 0)
11486 geometry_info.rho=argument_list[1].real_reference;
11487 if (attribute_flag[2] != 0)
11488 geometry_info.sigma=argument_list[2].real_reference;
11489 if (attribute_flag[3] != 0)
11490 geometry_info.xi=argument_list[3].real_reference;
11491 if (attribute_flag[4] != 0)
11492 geometry_info.psi=argument_list[4].real_reference;
11493 if (attribute_flag[5] != 0)
11494 channel=(ChannelType) argument_list[5].integer_reference;
11495 channel_mask=SetImageChannelMask(image,channel);
Cristy9b220db2018-08-05 18:02:28 -040011496 (void) RangeThresholdImage(image,geometry_info.rho,
11497 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
Cristy532b3382018-08-05 17:56:56 -040011498 if (image != (Image *) NULL)
11499 (void) SetImageChannelMask(image,channel_mask);
11500 break;
11501 }
Cristy9f252542018-11-21 19:13:46 -050011502 case 149: /* CLAHE */
11503 {
11504 if (attribute_flag[0] != 0)
Cristy768e9002019-01-08 07:35:16 -050011505 {
11506 flags=ParseGeometry(argument_list[0].string_reference,
11507 &geometry_info);
11508 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
11509 &geometry,exception);
11510 }
Cristy9f252542018-11-21 19:13:46 -050011511 if (attribute_flag[1] != 0)
Cristy30263282018-12-11 16:40:25 -050011512 geometry.width=argument_list[1].integer_reference;
Cristy9f252542018-11-21 19:13:46 -050011513 if (attribute_flag[2] != 0)
Cristy30263282018-12-11 16:40:25 -050011514 geometry.height=argument_list[2].integer_reference;
Cristy9f252542018-11-21 19:13:46 -050011515 if (attribute_flag[3] != 0)
Cristy768e9002019-01-08 07:35:16 -050011516 geometry.x=argument_list[3].integer_reference;
Cristy9f252542018-11-21 19:13:46 -050011517 if (attribute_flag[4] != 0)
Cristy768e9002019-01-08 07:35:16 -050011518 geometry_info.psi=argument_list[4].real_reference;
Cristyd9b98812018-12-16 09:30:05 -050011519 (void) CLAHEImage(image,geometry.width,geometry.height,geometry.x,
Cristy768e9002019-01-08 07:35:16 -050011520 geometry_info.psi,exception);
Cristy9f252542018-11-21 19:13:46 -050011521 break;
11522 }
Cristyb4ab5192019-12-19 06:53:46 -050011523 case 150: /* Kmeans */
11524 {
11525 if (attribute_flag[0] != 0)
11526 {
11527 flags=ParseGeometry(argument_list[0].string_reference,
11528 &geometry_info);
11529 if ((flags & SigmaValue) == 0)
Cristyc809e482019-12-21 09:59:52 -050011530 geometry_info.sigma=100.0;
Cristyb4ab5192019-12-19 06:53:46 -050011531 if ((flags & XiValue) == 0)
Cristyc809e482019-12-21 09:59:52 -050011532 geometry_info.xi=0.01;
Cristyb4ab5192019-12-19 06:53:46 -050011533 }
11534 if (attribute_flag[1] != 0)
11535 geometry_info.rho=argument_list[1].integer_reference;
11536 if (attribute_flag[2] != 0)
11537 geometry_info.sigma=argument_list[2].integer_reference;
11538 if (attribute_flag[3] != 0)
11539 geometry_info.xi=(ChannelType) argument_list[3].real_reference;
11540 (void) KmeansImage(image,geometry_info.rho,geometry_info.sigma,
11541 geometry_info.xi,exception);
11542 break;
11543 }
Cristy89b4db02020-02-21 20:57:40 -050011544 case 151: /* ColorThreshold */
11545 {
Cristyca5ba782020-02-22 08:17:19 -050011546 PixelInfo
11547 start_color,
11548 stop_color;
11549
11550 (void) QueryColorCompliance("black",AllCompliance,&start_color,
11551 exception);
11552 (void) QueryColorCompliance("white",AllCompliance,&stop_color,
11553 exception);
11554 if (attribute_flag[0] != 0)
11555 (void) QueryColorCompliance(argument_list[0].string_reference,
11556 AllCompliance,&start_color,exception);
11557 if (attribute_flag[1] != 0)
11558 (void) QueryColorCompliance(argument_list[1].string_reference,
11559 AllCompliance,&stop_color,exception);
Cristy89b4db02020-02-21 20:57:40 -050011560 channel_mask=SetImageChannelMask(image,channel);
Cristy563beb72020-02-22 09:52:06 -050011561 (void) ColorThresholdImage(image,&start_color,&stop_color,exception);
Cristy89b4db02020-02-21 20:57:40 -050011562 (void) SetImageChannelMask(image,channel_mask);
11563 break;
11564 }
cristy4a3ce0a2013-08-03 20:06:59 +000011565 }
11566 if (next != (Image *) NULL)
11567 (void) CatchImageException(next);
Cristy7e567962018-02-03 12:42:20 -050011568 if ((region_info.width*region_info.height) != 0)
11569 (void) SetImageRegionMask(image,WritePixelMask,
11570 (const RectangleInfo *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011571 if (image != (Image *) NULL)
11572 {
11573 number_images++;
11574 if (next && (next != image))
11575 {
11576 image->next=next->next;
11577 if (image->next != (Image *) NULL)
11578 image->next->previous=image;
11579 DeleteImageFromRegistry(*pv,next);
11580 }
11581 sv_setiv(*pv,PTR2IV(image));
11582 next=image;
11583 }
11584 if (*pv)
11585 pv++;
11586 }
11587
11588 PerlException:
11589 if (reference_vector)
11590 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11591 InheritPerlException(exception,perl_exception);
11592 exception=DestroyExceptionInfo(exception);
11593 sv_setiv(perl_exception,(IV) number_images);
11594 SvPOK_on(perl_exception);
11595 ST(0)=sv_2mortal(perl_exception);
11596 XSRETURN(1);
11597 }
11598
11599#
11600###############################################################################
11601# #
11602# #
11603# #
11604# M o n t a g e #
11605# #
11606# #
11607# #
11608###############################################################################
11609#
11610#
11611void
11612Montage(ref,...)
11613 Image::Magick ref=NO_INIT
11614 ALIAS:
11615 MontageImage = 1
11616 montage = 2
11617 montageimage = 3
11618 PPCODE:
11619 {
11620 AV
11621 *av;
11622
11623 char
11624 *attribute;
11625
11626 ExceptionInfo
11627 *exception;
11628
11629 HV
11630 *hv;
11631
11632 Image
11633 *image,
11634 *next;
11635
11636 PixelInfo
11637 transparent_color;
11638
11639 MontageInfo
11640 *montage_info;
11641
11642 register ssize_t
11643 i;
11644
11645 ssize_t
11646 sp;
11647
11648 struct PackageInfo
11649 *info;
11650
11651 SV
11652 *av_reference,
11653 *perl_exception,
11654 *reference,
11655 *rv,
11656 *sv;
11657
11658 PERL_UNUSED_VAR(ref);
11659 PERL_UNUSED_VAR(ix);
11660 exception=AcquireExceptionInfo();
11661 perl_exception=newSVpv("",0);
11662 sv=NULL;
11663 attribute=NULL;
11664 if (sv_isobject(ST(0)) == 0)
11665 {
11666 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11667 PackageName);
11668 goto PerlException;
11669 }
11670 reference=SvRV(ST(0));
11671 hv=SvSTASH(reference);
11672 av=newAV();
11673 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11674 SvREFCNT_dec(av);
11675 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11676 if (image == (Image *) NULL)
11677 {
11678 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11679 PackageName);
11680 goto PerlException;
11681 }
11682 /*
11683 Get options.
11684 */
11685 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11686 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11687 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11688 exception);
11689 for (i=2; i < items; i+=2)
11690 {
11691 attribute=(char *) SvPV(ST(i-1),na);
11692 switch (*attribute)
11693 {
11694 case 'B':
11695 case 'b':
11696 {
11697 if (LocaleCompare(attribute,"background") == 0)
11698 {
11699 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11700 &montage_info->background_color,exception);
11701 for (next=image; next; next=next->next)
11702 next->background_color=montage_info->background_color;
11703 break;
11704 }
11705 if (LocaleCompare(attribute,"border") == 0)
11706 {
11707 montage_info->border_width=SvIV(ST(i));
11708 break;
11709 }
11710 if (LocaleCompare(attribute,"bordercolor") == 0)
11711 {
11712 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11713 &montage_info->border_color,exception);
11714 for (next=image; next; next=next->next)
11715 next->border_color=montage_info->border_color;
11716 break;
11717 }
11718 if (LocaleCompare(attribute,"borderwidth") == 0)
11719 {
11720 montage_info->border_width=SvIV(ST(i));
11721 break;
11722 }
11723 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11724 attribute);
11725 break;
11726 }
11727 case 'C':
11728 case 'c':
11729 {
11730 if (LocaleCompare(attribute,"compose") == 0)
11731 {
11732 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11733 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11734 if (sp < 0)
11735 {
11736 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11737 SvPV(ST(i),na));
11738 break;
11739 }
11740 for (next=image; next; next=next->next)
11741 next->compose=(CompositeOperator) sp;
11742 break;
11743 }
11744 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11745 attribute);
11746 break;
11747 }
11748 case 'F':
11749 case 'f':
11750 {
11751 if (LocaleCompare(attribute,"fill") == 0)
11752 {
11753 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11754 &montage_info->fill,exception);
11755 break;
11756 }
11757 if (LocaleCompare(attribute,"font") == 0)
11758 {
11759 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11760 break;
11761 }
11762 if (LocaleCompare(attribute,"frame") == 0)
11763 {
11764 char
11765 *p;
11766
11767 p=SvPV(ST(i),na);
11768 if (IsGeometry(p) == MagickFalse)
11769 {
11770 ThrowPerlException(exception,OptionError,"MissingGeometry",
11771 p);
11772 break;
11773 }
11774 (void) CloneString(&montage_info->frame,p);
11775 if (*p == '\0')
11776 montage_info->frame=(char *) NULL;
11777 break;
11778 }
11779 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11780 attribute);
11781 break;
11782 }
11783 case 'G':
11784 case 'g':
11785 {
11786 if (LocaleCompare(attribute,"geometry") == 0)
11787 {
11788 char
11789 *p;
11790
11791 p=SvPV(ST(i),na);
11792 if (IsGeometry(p) == MagickFalse)
11793 {
11794 ThrowPerlException(exception,OptionError,"MissingGeometry",
11795 p);
11796 break;
11797 }
11798 (void) CloneString(&montage_info->geometry,p);
11799 if (*p == '\0')
11800 montage_info->geometry=(char *) NULL;
11801 break;
11802 }
11803 if (LocaleCompare(attribute,"gravity") == 0)
11804 {
11805 ssize_t
11806 in;
11807
11808 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11809 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11810 if (in < 0)
11811 {
11812 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11813 SvPV(ST(i),na));
11814 return;
11815 }
11816 montage_info->gravity=(GravityType) in;
11817 for (next=image; next; next=next->next)
11818 next->gravity=(GravityType) in;
11819 break;
11820 }
11821 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11822 attribute);
11823 break;
11824 }
11825 case 'L':
11826 case 'l':
11827 {
11828 if (LocaleCompare(attribute,"label") == 0)
11829 {
11830 for (next=image; next; next=next->next)
Cristy935a4052017-03-31 17:45:37 -040011831 (void) SetImageProperty(next,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +000011832 info ? info->image_info : (ImageInfo *) NULL,next,
Cristy935a4052017-03-31 17:45:37 -040011833 SvPV(ST(i),na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011834 break;
11835 }
11836 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11837 attribute);
11838 break;
11839 }
11840 case 'M':
11841 case 'm':
11842 {
11843 if (LocaleCompare(attribute,"mattecolor") == 0)
11844 {
11845 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
Cristy8645e042016-02-03 16:35:29 -050011846 &montage_info->alpha_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011847 for (next=image; next; next=next->next)
Cristy8645e042016-02-03 16:35:29 -050011848 next->alpha_color=montage_info->alpha_color;
cristy4a3ce0a2013-08-03 20:06:59 +000011849 break;
11850 }
11851 if (LocaleCompare(attribute,"mode") == 0)
11852 {
11853 ssize_t
11854 in;
11855
11856 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11857 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11858 switch (in)
11859 {
11860 default:
11861 {
11862 ThrowPerlException(exception,OptionError,
11863 "UnrecognizedModeType",SvPV(ST(i),na));
11864 break;
11865 }
11866 case FrameMode:
11867 {
11868 (void) CloneString(&montage_info->frame,"15x15+3+3");
11869 montage_info->shadow=MagickTrue;
11870 break;
11871 }
11872 case UnframeMode:
11873 {
11874 montage_info->frame=(char *) NULL;
11875 montage_info->shadow=MagickFalse;
11876 montage_info->border_width=0;
11877 break;
11878 }
11879 case ConcatenateMode:
11880 {
11881 montage_info->frame=(char *) NULL;
11882 montage_info->shadow=MagickFalse;
11883 (void) CloneString(&montage_info->geometry,"+0+0");
11884 montage_info->border_width=0;
11885 }
11886 }
11887 break;
11888 }
11889 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11890 attribute);
11891 break;
11892 }
11893 case 'P':
11894 case 'p':
11895 {
11896 if (LocaleCompare(attribute,"pointsize") == 0)
11897 {
11898 montage_info->pointsize=SvIV(ST(i));
11899 break;
11900 }
11901 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11902 attribute);
11903 break;
11904 }
11905 case 'S':
11906 case 's':
11907 {
11908 if (LocaleCompare(attribute,"shadow") == 0)
11909 {
11910 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11911 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11912 if (sp < 0)
11913 {
11914 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11915 SvPV(ST(i),na));
11916 break;
11917 }
11918 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11919 break;
11920 }
11921 if (LocaleCompare(attribute,"stroke") == 0)
11922 {
11923 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11924 &montage_info->stroke,exception);
11925 break;
11926 }
11927 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11928 attribute);
11929 break;
11930 }
11931 case 'T':
11932 case 't':
11933 {
11934 if (LocaleCompare(attribute,"texture") == 0)
11935 {
11936 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11937 break;
11938 }
11939 if (LocaleCompare(attribute,"tile") == 0)
11940 {
11941 char *p=SvPV(ST(i),na);
11942 if (IsGeometry(p) == MagickFalse)
11943 {
11944 ThrowPerlException(exception,OptionError,"MissingGeometry",
11945 p);
11946 break;
11947 }
11948 (void) CloneString(&montage_info->tile,p);
11949 if (*p == '\0')
11950 montage_info->tile=(char *) NULL;
11951 break;
11952 }
11953 if (LocaleCompare(attribute,"title") == 0)
11954 {
11955 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11956 break;
11957 }
11958 if (LocaleCompare(attribute,"transparent") == 0)
11959 {
11960 PixelInfo
11961 transparent_color;
11962
11963 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11964 &transparent_color,exception);
11965 for (next=image; next; next=next->next)
11966 (void) TransparentPaintImage(next,&transparent_color,
11967 TransparentAlpha,MagickFalse,exception);
11968 break;
11969 }
11970 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11971 attribute);
11972 break;
11973 }
11974 default:
11975 {
11976 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11977 attribute);
11978 break;
11979 }
11980 }
11981 }
11982 image=MontageImageList(info->image_info,montage_info,image,exception);
11983 montage_info=DestroyMontageInfo(montage_info);
11984 if (image == (Image *) NULL)
11985 goto PerlException;
11986 if (transparent_color.alpha != TransparentAlpha)
11987 for (next=image; next; next=next->next)
11988 (void) TransparentPaintImage(next,&transparent_color,
11989 TransparentAlpha,MagickFalse,exception);
11990 for ( ; image; image=image->next)
11991 {
11992 AddImageToRegistry(sv,image);
11993 rv=newRV(sv);
11994 av_push(av,sv_bless(rv,hv));
11995 SvREFCNT_dec(sv);
11996 }
11997 exception=DestroyExceptionInfo(exception);
11998 ST(0)=av_reference;
11999 SvREFCNT_dec(perl_exception);
12000 XSRETURN(1);
12001
12002 PerlException:
12003 InheritPerlException(exception,perl_exception);
12004 exception=DestroyExceptionInfo(exception);
12005 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12006 SvPOK_on(perl_exception);
12007 ST(0)=sv_2mortal(perl_exception);
12008 XSRETURN(1);
12009 }
12010
12011#
12012###############################################################################
12013# #
12014# #
12015# #
12016# M o r p h #
12017# #
12018# #
12019# #
12020###############################################################################
12021#
12022#
12023void
12024Morph(ref,...)
12025 Image::Magick ref=NO_INIT
12026 ALIAS:
12027 MorphImage = 1
12028 morph = 2
12029 morphimage = 3
12030 PPCODE:
12031 {
12032 AV
12033 *av;
12034
12035 char
12036 *attribute;
12037
12038 ExceptionInfo
12039 *exception;
12040
12041 HV
12042 *hv;
12043
12044 Image
12045 *image;
12046
12047 register ssize_t
12048 i;
12049
12050 ssize_t
12051 number_frames;
12052
12053 struct PackageInfo
12054 *info;
12055
12056 SV
12057 *av_reference,
12058 *perl_exception,
12059 *reference,
12060 *rv,
12061 *sv;
12062
12063 PERL_UNUSED_VAR(ref);
12064 PERL_UNUSED_VAR(ix);
12065 exception=AcquireExceptionInfo();
12066 perl_exception=newSVpv("",0);
12067 sv=NULL;
12068 av=NULL;
12069 attribute=NULL;
12070 if (sv_isobject(ST(0)) == 0)
12071 {
12072 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12073 PackageName);
12074 goto PerlException;
12075 }
12076 reference=SvRV(ST(0));
12077 hv=SvSTASH(reference);
12078 av=newAV();
12079 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12080 SvREFCNT_dec(av);
12081 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12082 if (image == (Image *) NULL)
12083 {
12084 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12085 PackageName);
12086 goto PerlException;
12087 }
12088 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12089 /*
12090 Get attribute.
12091 */
12092 number_frames=30;
12093 for (i=2; i < items; i+=2)
12094 {
12095 attribute=(char *) SvPV(ST(i-1),na);
12096 switch (*attribute)
12097 {
12098 case 'F':
12099 case 'f':
12100 {
12101 if (LocaleCompare(attribute,"frames") == 0)
12102 {
12103 number_frames=SvIV(ST(i));
12104 break;
12105 }
12106 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12107 attribute);
12108 break;
12109 }
12110 default:
12111 {
12112 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12113 attribute);
12114 break;
12115 }
12116 }
12117 }
12118 image=MorphImages(image,number_frames,exception);
12119 if (image == (Image *) NULL)
12120 goto PerlException;
12121 for ( ; image; image=image->next)
12122 {
12123 AddImageToRegistry(sv,image);
12124 rv=newRV(sv);
12125 av_push(av,sv_bless(rv,hv));
12126 SvREFCNT_dec(sv);
12127 }
12128 exception=DestroyExceptionInfo(exception);
12129 ST(0)=av_reference;
12130 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12131 XSRETURN(1);
12132
12133 PerlException:
12134 InheritPerlException(exception,perl_exception);
12135 exception=DestroyExceptionInfo(exception);
12136 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12137 SvPOK_on(perl_exception);
12138 ST(0)=sv_2mortal(perl_exception);
12139 XSRETURN(1);
12140 }
12141
12142#
12143###############################################################################
12144# #
12145# #
12146# #
12147# M o s a i c #
12148# #
12149# #
12150# #
12151###############################################################################
12152#
12153#
12154void
12155Mosaic(ref)
12156 Image::Magick ref=NO_INIT
12157 ALIAS:
12158 MosaicImage = 1
12159 mosaic = 2
12160 mosaicimage = 3
12161 PPCODE:
12162 {
12163 AV
12164 *av;
12165
12166 ExceptionInfo
12167 *exception;
12168
12169 HV
12170 *hv;
12171
12172 Image
12173 *image;
12174
12175 struct PackageInfo
12176 *info;
12177
12178 SV
12179 *perl_exception,
12180 *reference,
12181 *rv,
12182 *sv;
12183
12184 PERL_UNUSED_VAR(ref);
12185 PERL_UNUSED_VAR(ix);
12186 exception=AcquireExceptionInfo();
12187 perl_exception=newSVpv("",0);
12188 sv=NULL;
12189 if (sv_isobject(ST(0)) == 0)
12190 {
12191 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12192 PackageName);
12193 goto PerlException;
12194 }
12195 reference=SvRV(ST(0));
12196 hv=SvSTASH(reference);
12197 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12198 if (image == (Image *) NULL)
12199 {
12200 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12201 PackageName);
12202 goto PerlException;
12203 }
12204 image=MergeImageLayers(image,MosaicLayer,exception);
12205 /*
12206 Create blessed Perl array for the returned image.
12207 */
12208 av=newAV();
12209 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12210 SvREFCNT_dec(av);
12211 AddImageToRegistry(sv,image);
12212 rv=newRV(sv);
12213 av_push(av,sv_bless(rv,hv));
12214 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000012215 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000012216 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012217 SetImageInfo(info->image_info,0,exception);
12218 exception=DestroyExceptionInfo(exception);
12219 SvREFCNT_dec(perl_exception);
12220 XSRETURN(1);
12221
12222 PerlException:
12223 InheritPerlException(exception,perl_exception);
12224 exception=DestroyExceptionInfo(exception);
12225 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12226 SvPOK_on(perl_exception); /* return messages in string context */
12227 ST(0)=sv_2mortal(perl_exception);
12228 XSRETURN(1);
12229 }
12230
12231#
12232###############################################################################
12233# #
12234# #
12235# #
12236# P i n g #
12237# #
12238# #
12239# #
12240###############################################################################
12241#
12242#
12243void
12244Ping(ref,...)
12245 Image::Magick ref=NO_INIT
12246 ALIAS:
12247 PingImage = 1
12248 ping = 2
12249 pingimage = 3
12250 PPCODE:
12251 {
12252 AV
12253 *av;
12254
12255 char
12256 **keep,
12257 **list;
12258
12259 ExceptionInfo
12260 *exception;
12261
12262 Image
12263 *image,
12264 *next;
12265
12266 int
12267 n;
12268
12269 MagickBooleanType
12270 status;
12271
12272 register char
12273 **p;
12274
12275 register ssize_t
12276 i;
12277
12278 ssize_t
12279 ac;
12280
12281 STRLEN
12282 *length;
12283
12284 struct PackageInfo
12285 *info,
12286 *package_info;
12287
12288 SV
12289 *perl_exception,
12290 *reference;
12291
12292 size_t
12293 count;
12294
12295 PERL_UNUSED_VAR(ref);
12296 PERL_UNUSED_VAR(ix);
12297 exception=AcquireExceptionInfo();
12298 perl_exception=newSVpv("",0);
12299 package_info=(struct PackageInfo *) NULL;
12300 ac=(items < 2) ? 1 : items-1;
12301 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12302 keep=list;
12303 length=(STRLEN *) NULL;
12304 if (list == (char **) NULL)
12305 {
12306 ThrowPerlException(exception,ResourceLimitError,
12307 "MemoryAllocationFailed",PackageName);
12308 goto PerlException;
12309 }
12310 keep=list;
12311 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12312 if (length == (STRLEN *) NULL)
12313 {
12314 ThrowPerlException(exception,ResourceLimitError,
12315 "MemoryAllocationFailed",PackageName);
12316 goto PerlException;
12317 }
12318 if (sv_isobject(ST(0)) == 0)
12319 {
12320 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12321 PackageName);
12322 goto PerlException;
12323 }
12324 reference=SvRV(ST(0));
12325 if (SvTYPE(reference) != SVt_PVAV)
12326 {
12327 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12328 PackageName);
12329 goto PerlException;
12330 }
12331 av=(AV *) reference;
12332 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12333 exception);
12334 package_info=ClonePackageInfo(info,exception);
12335 n=1;
12336 if (items <= 1)
12337 *list=(char *) (*package_info->image_info->filename ?
12338 package_info->image_info->filename : "XC:black");
12339 else
12340 for (n=0, i=0; i < ac; i++)
12341 {
12342 list[n]=(char *) SvPV(ST(i+1),length[n]);
12343 if ((items >= 3) && strEQcase(list[n],"blob"))
12344 {
12345 void
12346 *blob;
12347
12348 i++;
12349 blob=(void *) (SvPV(ST(i+1),length[n]));
12350 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12351 }
12352 if ((items >= 3) && strEQcase(list[n],"filename"))
12353 continue;
12354 if ((items >= 3) && strEQcase(list[n],"file"))
12355 {
12356 FILE
12357 *file;
12358
12359 PerlIO
12360 *io_info;
12361
12362 i++;
12363 io_info=IoIFP(sv_2io(ST(i+1)));
12364 if (io_info == (PerlIO *) NULL)
12365 {
12366 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12367 PackageName);
12368 continue;
12369 }
12370 file=PerlIO_findFILE(io_info);
12371 if (file == (FILE *) NULL)
12372 {
12373 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12374 PackageName);
12375 continue;
12376 }
12377 SetImageInfoFile(package_info->image_info,file);
12378 }
12379 if ((items >= 3) && strEQcase(list[n],"magick"))
12380 continue;
12381 n++;
12382 }
12383 list[n]=(char *) NULL;
12384 keep=list;
12385 status=ExpandFilenames(&n,&list);
12386 if (status == MagickFalse)
12387 {
12388 ThrowPerlException(exception,ResourceLimitError,
12389 "MemoryAllocationFailed",PackageName);
12390 goto PerlException;
12391 }
12392 count=0;
12393 for (i=0; i < n; i++)
12394 {
12395 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012396 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012397 image=PingImage(package_info->image_info,exception);
12398 if (image == (Image *) NULL)
12399 break;
12400 if ((package_info->image_info->file != (FILE *) NULL) ||
12401 (package_info->image_info->blob != (void *) NULL))
12402 DisassociateImageStream(image);
12403 count+=GetImageListLength(image);
12404 EXTEND(sp,4*count);
12405 for (next=image; next; next=next->next)
12406 {
12407 PUSHs(sv_2mortal(newSViv(next->columns)));
12408 PUSHs(sv_2mortal(newSViv(next->rows)));
12409 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12410 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12411 }
12412 image=DestroyImageList(image);
12413 }
12414 /*
12415 Free resources.
12416 */
12417 for (i=0; i < n; i++)
12418 if (list[i] != (char *) NULL)
12419 for (p=keep; list[i] != *p++; )
12420 if (*p == NULL)
12421 {
12422 list[i]=(char *) RelinquishMagickMemory(list[i]);
12423 break;
12424 }
12425
12426 PerlException:
12427 if (package_info != (struct PackageInfo *) NULL)
12428 DestroyPackageInfo(package_info);
12429 if (list && (list != keep))
12430 list=(char **) RelinquishMagickMemory(list);
12431 if (keep)
12432 keep=(char **) RelinquishMagickMemory(keep);
12433 if (length)
12434 length=(STRLEN *) RelinquishMagickMemory(length);
12435 InheritPerlException(exception,perl_exception);
12436 exception=DestroyExceptionInfo(exception);
12437 SvREFCNT_dec(perl_exception); /* throw away all errors */
12438 }
12439
12440#
12441###############################################################################
12442# #
12443# #
12444# #
12445# P r e v i e w #
12446# #
12447# #
12448# #
12449###############################################################################
12450#
12451#
12452void
12453Preview(ref,...)
12454 Image::Magick ref=NO_INIT
12455 ALIAS:
12456 PreviewImage = 1
12457 preview = 2
12458 previewimage = 3
12459 PPCODE:
12460 {
12461 AV
12462 *av;
12463
12464 ExceptionInfo
12465 *exception;
12466
12467 HV
12468 *hv;
12469
12470 Image
12471 *image,
12472 *preview_image;
12473
12474 PreviewType
12475 preview_type;
12476
12477 struct PackageInfo
12478 *info;
12479
12480 SV
12481 *av_reference,
12482 *perl_exception,
12483 *reference,
12484 *rv,
12485 *sv;
12486
12487 PERL_UNUSED_VAR(ref);
12488 PERL_UNUSED_VAR(ix);
12489 exception=AcquireExceptionInfo();
12490 perl_exception=newSVpv("",0);
12491 sv=NULL;
12492 av=NULL;
12493 if (sv_isobject(ST(0)) == 0)
12494 {
12495 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12496 PackageName);
12497 goto PerlException;
12498 }
12499 reference=SvRV(ST(0));
12500 hv=SvSTASH(reference);
12501 av=newAV();
12502 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12503 SvREFCNT_dec(av);
12504 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12505 if (image == (Image *) NULL)
12506 {
12507 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12508 PackageName);
12509 goto PerlException;
12510 }
12511 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12512 preview_type=GammaPreview;
12513 if (items > 1)
12514 preview_type=(PreviewType)
12515 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12516 for ( ; image; image=image->next)
12517 {
12518 preview_image=PreviewImage(image,preview_type,exception);
12519 if (preview_image == (Image *) NULL)
12520 goto PerlException;
12521 AddImageToRegistry(sv,preview_image);
12522 rv=newRV(sv);
12523 av_push(av,sv_bless(rv,hv));
12524 SvREFCNT_dec(sv);
12525 }
12526 exception=DestroyExceptionInfo(exception);
12527 ST(0)=av_reference;
12528 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12529 XSRETURN(1);
12530
12531 PerlException:
12532 InheritPerlException(exception,perl_exception);
12533 exception=DestroyExceptionInfo(exception);
12534 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12535 SvPOK_on(perl_exception);
12536 ST(0)=sv_2mortal(perl_exception);
12537 XSRETURN(1);
12538 }
12539
12540#
12541###############################################################################
12542# #
12543# #
12544# #
12545# Q u e r y C o l o r #
12546# #
12547# #
12548# #
12549###############################################################################
12550#
12551#
12552void
12553QueryColor(ref,...)
12554 Image::Magick ref=NO_INIT
12555 ALIAS:
12556 querycolor = 1
12557 PPCODE:
12558 {
12559 char
12560 *name;
12561
12562 ExceptionInfo
12563 *exception;
12564
12565 PixelInfo
12566 color;
12567
12568 register ssize_t
12569 i;
12570
12571 SV
12572 *perl_exception;
12573
12574 PERL_UNUSED_VAR(ref);
12575 PERL_UNUSED_VAR(ix);
12576 exception=AcquireExceptionInfo();
12577 perl_exception=newSVpv("",0);
12578 if (items == 1)
12579 {
12580 const ColorInfo
12581 **colorlist;
12582
12583 size_t
12584 colors;
12585
12586 colorlist=GetColorInfoList("*",&colors,exception);
12587 EXTEND(sp,colors);
12588 for (i=0; i < (ssize_t) colors; i++)
12589 {
12590 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12591 }
12592 colorlist=(const ColorInfo **)
12593 RelinquishMagickMemory((ColorInfo **) colorlist);
12594 goto PerlException;
12595 }
12596 EXTEND(sp,5*items);
12597 for (i=1; i < items; i++)
12598 {
12599 name=(char *) SvPV(ST(i),na);
12600 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12601 {
12602 PUSHs(&sv_undef);
12603 continue;
12604 }
12605 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12606 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12607 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12608 if (color.colorspace == CMYKColorspace)
12609 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012610 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012611 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12612 }
12613
12614 PerlException:
12615 InheritPerlException(exception,perl_exception);
12616 exception=DestroyExceptionInfo(exception);
12617 SvREFCNT_dec(perl_exception);
12618 }
12619
12620#
12621###############################################################################
12622# #
12623# #
12624# #
12625# Q u e r y C o l o r N a m e #
12626# #
12627# #
12628# #
12629###############################################################################
12630#
12631#
12632void
12633QueryColorname(ref,...)
12634 Image::Magick ref=NO_INIT
12635 ALIAS:
12636 querycolorname = 1
12637 PPCODE:
12638 {
12639 AV
12640 *av;
12641
12642 char
cristy151b66d2015-04-15 10:50:31 +000012643 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012644
12645 ExceptionInfo
12646 *exception;
12647
12648 Image
12649 *image;
12650
12651 PixelInfo
12652 target_color;
12653
12654 register ssize_t
12655 i;
12656
12657 struct PackageInfo
12658 *info;
12659
12660 SV
12661 *perl_exception,
12662 *reference; /* reference is the SV* of ref=SvIV(reference) */
12663
12664 PERL_UNUSED_VAR(ref);
12665 PERL_UNUSED_VAR(ix);
12666 exception=AcquireExceptionInfo();
12667 perl_exception=newSVpv("",0);
12668 reference=SvRV(ST(0));
12669 av=(AV *) reference;
12670 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12671 exception);
12672 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12673 if (image == (Image *) NULL)
12674 {
12675 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12676 PackageName);
12677 goto PerlException;
12678 }
12679 EXTEND(sp,items);
12680 for (i=1; i < items; i++)
12681 {
12682 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12683 exception);
12684 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12685 exception);
12686 PUSHs(sv_2mortal(newSVpv(message,0)));
12687 }
12688
12689 PerlException:
12690 InheritPerlException(exception,perl_exception);
12691 exception=DestroyExceptionInfo(exception);
12692 SvREFCNT_dec(perl_exception);
12693 }
12694
12695#
12696###############################################################################
12697# #
12698# #
12699# #
12700# Q u e r y F o n t #
12701# #
12702# #
12703# #
12704###############################################################################
12705#
12706#
12707void
12708QueryFont(ref,...)
12709 Image::Magick ref=NO_INIT
12710 ALIAS:
12711 queryfont = 1
12712 PPCODE:
12713 {
12714 char
12715 *name,
cristy151b66d2015-04-15 10:50:31 +000012716 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012717
12718 ExceptionInfo
12719 *exception;
12720
12721 register ssize_t
12722 i;
12723
12724 SV
12725 *perl_exception;
12726
12727 volatile const TypeInfo
12728 *type_info;
12729
12730 PERL_UNUSED_VAR(ref);
12731 PERL_UNUSED_VAR(ix);
12732 exception=AcquireExceptionInfo();
12733 perl_exception=newSVpv("",0);
12734 if (items == 1)
12735 {
12736 const TypeInfo
12737 **typelist;
12738
12739 size_t
12740 types;
12741
12742 typelist=GetTypeInfoList("*",&types,exception);
12743 EXTEND(sp,types);
12744 for (i=0; i < (ssize_t) types; i++)
12745 {
12746 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12747 }
12748 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12749 typelist);
12750 goto PerlException;
12751 }
12752 EXTEND(sp,10*items);
12753 for (i=1; i < items; i++)
12754 {
12755 name=(char *) SvPV(ST(i),na);
12756 type_info=GetTypeInfo(name,exception);
12757 if (type_info == (TypeInfo *) NULL)
12758 {
12759 PUSHs(&sv_undef);
12760 continue;
12761 }
12762 if (type_info->name == (char *) NULL)
12763 PUSHs(&sv_undef);
12764 else
12765 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12766 if (type_info->description == (char *) NULL)
12767 PUSHs(&sv_undef);
12768 else
12769 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12770 if (type_info->family == (char *) NULL)
12771 PUSHs(&sv_undef);
12772 else
12773 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12774 if (type_info->style == UndefinedStyle)
12775 PUSHs(&sv_undef);
12776 else
12777 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12778 type_info->style),0)));
12779 if (type_info->stretch == UndefinedStretch)
12780 PUSHs(&sv_undef);
12781 else
12782 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12783 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012784 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012785 type_info->weight);
12786 PUSHs(sv_2mortal(newSVpv(message,0)));
12787 if (type_info->encoding == (char *) NULL)
12788 PUSHs(&sv_undef);
12789 else
12790 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12791 if (type_info->foundry == (char *) NULL)
12792 PUSHs(&sv_undef);
12793 else
12794 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12795 if (type_info->format == (char *) NULL)
12796 PUSHs(&sv_undef);
12797 else
12798 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12799 if (type_info->metrics == (char *) NULL)
12800 PUSHs(&sv_undef);
12801 else
12802 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12803 if (type_info->glyphs == (char *) NULL)
12804 PUSHs(&sv_undef);
12805 else
12806 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12807 }
12808
12809 PerlException:
12810 InheritPerlException(exception,perl_exception);
12811 exception=DestroyExceptionInfo(exception);
12812 SvREFCNT_dec(perl_exception);
12813 }
12814
12815#
12816###############################################################################
12817# #
12818# #
12819# #
12820# Q u e r y F o n t M e t r i c s #
12821# #
12822# #
12823# #
12824###############################################################################
12825#
12826#
12827void
12828QueryFontMetrics(ref,...)
12829 Image::Magick ref=NO_INIT
12830 ALIAS:
12831 queryfontmetrics = 1
12832 PPCODE:
12833 {
12834 AffineMatrix
12835 affine,
12836 current;
12837
12838 AV
12839 *av;
12840
12841 char
12842 *attribute;
12843
12844 double
12845 x,
12846 y;
12847
12848 DrawInfo
12849 *draw_info;
12850
12851 ExceptionInfo
12852 *exception;
12853
12854 GeometryInfo
12855 geometry_info;
12856
12857 Image
12858 *image;
12859
12860 MagickBooleanType
12861 status;
12862
12863 MagickStatusType
12864 flags;
12865
12866 register ssize_t
12867 i;
12868
12869 ssize_t
12870 type;
12871
12872 struct PackageInfo
12873 *info,
12874 *package_info;
12875
12876 SV
12877 *perl_exception,
12878 *reference; /* reference is the SV* of ref=SvIV(reference) */
12879
12880 TypeMetric
12881 metrics;
12882
12883 PERL_UNUSED_VAR(ref);
12884 PERL_UNUSED_VAR(ix);
12885 exception=AcquireExceptionInfo();
12886 package_info=(struct PackageInfo *) NULL;
12887 perl_exception=newSVpv("",0);
12888 reference=SvRV(ST(0));
12889 av=(AV *) reference;
12890 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12891 exception);
12892 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12893 if (image == (Image *) NULL)
12894 {
12895 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12896 PackageName);
12897 goto PerlException;
12898 }
12899 package_info=ClonePackageInfo(info,exception);
12900 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12901 CloneString(&draw_info->text,"");
12902 current=draw_info->affine;
12903 GetAffineMatrix(&affine);
12904 x=0.0;
12905 y=0.0;
12906 EXTEND(sp,7*items);
12907 for (i=2; i < items; i+=2)
12908 {
12909 attribute=(char *) SvPV(ST(i-1),na);
12910 switch (*attribute)
12911 {
12912 case 'A':
12913 case 'a':
12914 {
12915 if (LocaleCompare(attribute,"antialias") == 0)
12916 {
12917 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12918 SvPV(ST(i),na));
12919 if (type < 0)
12920 {
12921 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12922 SvPV(ST(i),na));
12923 break;
12924 }
12925 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12926 break;
12927 }
12928 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12929 attribute);
12930 break;
12931 }
12932 case 'd':
12933 case 'D':
12934 {
12935 if (LocaleCompare(attribute,"density") == 0)
12936 {
12937 CloneString(&draw_info->density,SvPV(ST(i),na));
12938 break;
12939 }
12940 if (LocaleCompare(attribute,"direction") == 0)
12941 {
12942 draw_info->direction=(DirectionType) ParseCommandOption(
12943 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12944 break;
12945 }
12946 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12947 attribute);
12948 break;
12949 }
12950 case 'e':
12951 case 'E':
12952 {
12953 if (LocaleCompare(attribute,"encoding") == 0)
12954 {
12955 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12956 break;
12957 }
12958 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12959 attribute);
12960 break;
12961 }
12962 case 'f':
12963 case 'F':
12964 {
12965 if (LocaleCompare(attribute,"family") == 0)
12966 {
12967 CloneString(&draw_info->family,SvPV(ST(i),na));
12968 break;
12969 }
12970 if (LocaleCompare(attribute,"fill") == 0)
12971 {
12972 if (info)
12973 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12974 &draw_info->fill,exception);
12975 break;
12976 }
12977 if (LocaleCompare(attribute,"font") == 0)
12978 {
12979 CloneString(&draw_info->font,SvPV(ST(i),na));
12980 break;
12981 }
12982 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12983 attribute);
12984 break;
12985 }
12986 case 'g':
12987 case 'G':
12988 {
12989 if (LocaleCompare(attribute,"geometry") == 0)
12990 {
12991 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12992 break;
12993 }
12994 if (LocaleCompare(attribute,"gravity") == 0)
12995 {
12996 draw_info->gravity=(GravityType) ParseCommandOption(
12997 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12998 break;
12999 }
13000 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13001 attribute);
13002 break;
13003 }
13004 case 'i':
13005 case 'I':
13006 {
13007 if (LocaleCompare(attribute,"interline-spacing") == 0)
13008 {
13009 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13010 draw_info->interline_spacing=geometry_info.rho;
13011 break;
13012 }
13013 if (LocaleCompare(attribute,"interword-spacing") == 0)
13014 {
13015 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13016 draw_info->interword_spacing=geometry_info.rho;
13017 break;
13018 }
13019 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13020 attribute);
13021 break;
13022 }
13023 case 'k':
13024 case 'K':
13025 {
13026 if (LocaleCompare(attribute,"kerning") == 0)
13027 {
13028 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13029 draw_info->kerning=geometry_info.rho;
13030 break;
13031 }
13032 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13033 attribute);
13034 break;
13035 }
13036 case 'p':
13037 case 'P':
13038 {
13039 if (LocaleCompare(attribute,"pointsize") == 0)
13040 {
13041 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13042 draw_info->pointsize=geometry_info.rho;
13043 break;
13044 }
13045 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13046 attribute);
13047 break;
13048 }
13049 case 'r':
13050 case 'R':
13051 {
13052 if (LocaleCompare(attribute,"rotate") == 0)
13053 {
13054 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13055 affine.rx=geometry_info.rho;
13056 affine.ry=geometry_info.sigma;
13057 if ((flags & SigmaValue) == 0)
13058 affine.ry=affine.rx;
13059 break;
13060 }
13061 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13062 attribute);
13063 break;
13064 }
13065 case 's':
13066 case 'S':
13067 {
13068 if (LocaleCompare(attribute,"scale") == 0)
13069 {
13070 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13071 affine.sx=geometry_info.rho;
13072 affine.sy=geometry_info.sigma;
13073 if ((flags & SigmaValue) == 0)
13074 affine.sy=affine.sx;
13075 break;
13076 }
13077 if (LocaleCompare(attribute,"skew") == 0)
13078 {
13079 double
13080 x_angle,
13081 y_angle;
13082
13083 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13084 x_angle=geometry_info.rho;
13085 y_angle=geometry_info.sigma;
13086 if ((flags & SigmaValue) == 0)
13087 y_angle=x_angle;
13088 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13089 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13090 break;
13091 }
13092 if (LocaleCompare(attribute,"stroke") == 0)
13093 {
13094 if (info)
13095 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13096 &draw_info->stroke,exception);
13097 break;
13098 }
13099 if (LocaleCompare(attribute,"style") == 0)
13100 {
13101 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13102 SvPV(ST(i),na));
13103 if (type < 0)
13104 {
13105 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13106 SvPV(ST(i),na));
13107 break;
13108 }
13109 draw_info->style=(StyleType) type;
13110 break;
13111 }
13112 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13113 attribute);
13114 break;
13115 }
13116 case 't':
13117 case 'T':
13118 {
13119 if (LocaleCompare(attribute,"text") == 0)
13120 {
13121 CloneString(&draw_info->text,SvPV(ST(i),na));
13122 break;
13123 }
13124 if (LocaleCompare(attribute,"translate") == 0)
13125 {
13126 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13127 affine.tx=geometry_info.rho;
13128 affine.ty=geometry_info.sigma;
13129 if ((flags & SigmaValue) == 0)
13130 affine.ty=affine.tx;
13131 break;
13132 }
13133 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13134 attribute);
13135 break;
13136 }
13137 case 'w':
13138 case 'W':
13139 {
13140 if (LocaleCompare(attribute,"weight") == 0)
13141 {
13142 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13143 draw_info->weight=(size_t) geometry_info.rho;
13144 break;
13145 }
13146 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13147 attribute);
13148 break;
13149 }
13150 case 'x':
13151 case 'X':
13152 {
13153 if (LocaleCompare(attribute,"x") == 0)
13154 {
13155 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13156 x=geometry_info.rho;
13157 break;
13158 }
13159 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13160 attribute);
13161 break;
13162 }
13163 case 'y':
13164 case 'Y':
13165 {
13166 if (LocaleCompare(attribute,"y") == 0)
13167 {
13168 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13169 y=geometry_info.rho;
13170 break;
13171 }
13172 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13173 attribute);
13174 break;
13175 }
13176 default:
13177 {
13178 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13179 attribute);
13180 break;
13181 }
13182 }
13183 }
13184 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13185 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13186 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13187 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13188 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13189 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13190 if (draw_info->geometry == (char *) NULL)
13191 {
13192 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013193 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013194 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013195 }
13196 status=GetTypeMetrics(image,draw_info,&metrics,exception);
13197 (void) CatchImageException(image);
13198 if (status == MagickFalse)
13199 PUSHs(&sv_undef);
13200 else
13201 {
13202 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13203 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13204 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13205 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13206 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13207 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13208 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13209 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13210 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13211 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13212 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13213 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13214 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13215 }
13216 draw_info=DestroyDrawInfo(draw_info);
13217
13218 PerlException:
13219 if (package_info != (struct PackageInfo *) NULL)
13220 DestroyPackageInfo(package_info);
13221 InheritPerlException(exception,perl_exception);
13222 exception=DestroyExceptionInfo(exception);
13223 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13224 }
13225
13226#
13227###############################################################################
13228# #
13229# #
13230# #
13231# 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 #
13232# #
13233# #
13234# #
13235###############################################################################
13236#
13237#
13238void
13239QueryMultilineFontMetrics(ref,...)
13240 Image::Magick ref=NO_INIT
13241 ALIAS:
13242 querymultilinefontmetrics = 1
13243 PPCODE:
13244 {
13245 AffineMatrix
13246 affine,
13247 current;
13248
13249 AV
13250 *av;
13251
13252 char
13253 *attribute;
13254
13255 double
13256 x,
13257 y;
13258
13259 DrawInfo
13260 *draw_info;
13261
13262 ExceptionInfo
13263 *exception;
13264
13265 GeometryInfo
13266 geometry_info;
13267
13268 Image
13269 *image;
13270
13271 MagickBooleanType
13272 status;
13273
13274 MagickStatusType
13275 flags;
13276
13277 register ssize_t
13278 i;
13279
13280 ssize_t
13281 type;
13282
13283 struct PackageInfo
13284 *info,
13285 *package_info;
13286
13287 SV
13288 *perl_exception,
13289 *reference; /* reference is the SV* of ref=SvIV(reference) */
13290
13291 TypeMetric
13292 metrics;
13293
13294 PERL_UNUSED_VAR(ref);
13295 PERL_UNUSED_VAR(ix);
13296 exception=AcquireExceptionInfo();
13297 package_info=(struct PackageInfo *) NULL;
13298 perl_exception=newSVpv("",0);
13299 reference=SvRV(ST(0));
13300 av=(AV *) reference;
13301 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13302 exception);
13303 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13304 if (image == (Image *) NULL)
13305 {
13306 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13307 PackageName);
13308 goto PerlException;
13309 }
13310 package_info=ClonePackageInfo(info,exception);
13311 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13312 CloneString(&draw_info->text,"");
13313 current=draw_info->affine;
13314 GetAffineMatrix(&affine);
13315 x=0.0;
13316 y=0.0;
13317 EXTEND(sp,7*items);
13318 for (i=2; i < items; i+=2)
13319 {
13320 attribute=(char *) SvPV(ST(i-1),na);
13321 switch (*attribute)
13322 {
13323 case 'A':
13324 case 'a':
13325 {
13326 if (LocaleCompare(attribute,"antialias") == 0)
13327 {
13328 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13329 SvPV(ST(i),na));
13330 if (type < 0)
13331 {
13332 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13333 SvPV(ST(i),na));
13334 break;
13335 }
13336 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13337 break;
13338 }
13339 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13340 attribute);
13341 break;
13342 }
13343 case 'd':
13344 case 'D':
13345 {
13346 if (LocaleCompare(attribute,"density") == 0)
13347 {
13348 CloneString(&draw_info->density,SvPV(ST(i),na));
13349 break;
13350 }
13351 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13352 attribute);
13353 break;
13354 }
13355 case 'e':
13356 case 'E':
13357 {
13358 if (LocaleCompare(attribute,"encoding") == 0)
13359 {
13360 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13361 break;
13362 }
13363 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13364 attribute);
13365 break;
13366 }
13367 case 'f':
13368 case 'F':
13369 {
13370 if (LocaleCompare(attribute,"family") == 0)
13371 {
13372 CloneString(&draw_info->family,SvPV(ST(i),na));
13373 break;
13374 }
13375 if (LocaleCompare(attribute,"fill") == 0)
13376 {
13377 if (info)
13378 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13379 &draw_info->fill,exception);
13380 break;
13381 }
13382 if (LocaleCompare(attribute,"font") == 0)
13383 {
13384 CloneString(&draw_info->font,SvPV(ST(i),na));
13385 break;
13386 }
13387 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13388 attribute);
13389 break;
13390 }
13391 case 'g':
13392 case 'G':
13393 {
13394 if (LocaleCompare(attribute,"geometry") == 0)
13395 {
13396 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13397 break;
13398 }
13399 if (LocaleCompare(attribute,"gravity") == 0)
13400 {
13401 draw_info->gravity=(GravityType) ParseCommandOption(
13402 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13403 break;
13404 }
13405 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13406 attribute);
13407 break;
13408 }
13409 case 'p':
13410 case 'P':
13411 {
13412 if (LocaleCompare(attribute,"pointsize") == 0)
13413 {
13414 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13415 draw_info->pointsize=geometry_info.rho;
13416 break;
13417 }
13418 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13419 attribute);
13420 break;
13421 }
13422 case 'r':
13423 case 'R':
13424 {
13425 if (LocaleCompare(attribute,"rotate") == 0)
13426 {
13427 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13428 affine.rx=geometry_info.rho;
13429 affine.ry=geometry_info.sigma;
13430 if ((flags & SigmaValue) == 0)
13431 affine.ry=affine.rx;
13432 break;
13433 }
13434 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13435 attribute);
13436 break;
13437 }
13438 case 's':
13439 case 'S':
13440 {
13441 if (LocaleCompare(attribute,"scale") == 0)
13442 {
13443 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13444 affine.sx=geometry_info.rho;
13445 affine.sy=geometry_info.sigma;
13446 if ((flags & SigmaValue) == 0)
13447 affine.sy=affine.sx;
13448 break;
13449 }
13450 if (LocaleCompare(attribute,"skew") == 0)
13451 {
13452 double
13453 x_angle,
13454 y_angle;
13455
13456 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13457 x_angle=geometry_info.rho;
13458 y_angle=geometry_info.sigma;
13459 if ((flags & SigmaValue) == 0)
13460 y_angle=x_angle;
13461 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13462 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13463 break;
13464 }
13465 if (LocaleCompare(attribute,"stroke") == 0)
13466 {
13467 if (info)
13468 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13469 &draw_info->stroke,exception);
13470 break;
13471 }
13472 if (LocaleCompare(attribute,"style") == 0)
13473 {
13474 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13475 SvPV(ST(i),na));
13476 if (type < 0)
13477 {
13478 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13479 SvPV(ST(i),na));
13480 break;
13481 }
13482 draw_info->style=(StyleType) type;
13483 break;
13484 }
13485 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13486 attribute);
13487 break;
13488 }
13489 case 't':
13490 case 'T':
13491 {
13492 if (LocaleCompare(attribute,"text") == 0)
13493 {
13494 CloneString(&draw_info->text,SvPV(ST(i),na));
13495 break;
13496 }
13497 if (LocaleCompare(attribute,"translate") == 0)
13498 {
13499 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13500 affine.tx=geometry_info.rho;
13501 affine.ty=geometry_info.sigma;
13502 if ((flags & SigmaValue) == 0)
13503 affine.ty=affine.tx;
13504 break;
13505 }
13506 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13507 attribute);
13508 break;
13509 }
13510 case 'w':
13511 case 'W':
13512 {
13513 if (LocaleCompare(attribute,"weight") == 0)
13514 {
13515 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13516 draw_info->weight=(size_t) geometry_info.rho;
13517 break;
13518 }
13519 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13520 attribute);
13521 break;
13522 }
13523 case 'x':
13524 case 'X':
13525 {
13526 if (LocaleCompare(attribute,"x") == 0)
13527 {
13528 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13529 x=geometry_info.rho;
13530 break;
13531 }
13532 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13533 attribute);
13534 break;
13535 }
13536 case 'y':
13537 case 'Y':
13538 {
13539 if (LocaleCompare(attribute,"y") == 0)
13540 {
13541 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13542 y=geometry_info.rho;
13543 break;
13544 }
13545 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13546 attribute);
13547 break;
13548 }
13549 default:
13550 {
13551 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13552 attribute);
13553 break;
13554 }
13555 }
13556 }
13557 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13558 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13559 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13560 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13561 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13562 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13563 if (draw_info->geometry == (char *) NULL)
13564 {
13565 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013566 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013567 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013568 }
13569 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13570 (void) CatchException(exception);
13571 if (status == MagickFalse)
13572 PUSHs(&sv_undef);
13573 else
13574 {
13575 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13576 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13577 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13578 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13579 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13580 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13581 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13582 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13583 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13584 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13585 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13586 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13587 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13588 }
13589 draw_info=DestroyDrawInfo(draw_info);
13590
13591 PerlException:
13592 if (package_info != (struct PackageInfo *) NULL)
13593 DestroyPackageInfo(package_info);
13594 InheritPerlException(exception,perl_exception);
13595 exception=DestroyExceptionInfo(exception);
13596 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13597 }
13598
13599#
13600###############################################################################
13601# #
13602# #
13603# #
13604# Q u e r y F o r m a t #
13605# #
13606# #
13607# #
13608###############################################################################
13609#
13610#
13611void
13612QueryFormat(ref,...)
13613 Image::Magick ref=NO_INIT
13614 ALIAS:
13615 queryformat = 1
13616 PPCODE:
13617 {
13618 char
13619 *name;
13620
13621 ExceptionInfo
13622 *exception;
13623
13624 register ssize_t
13625 i;
13626
13627 SV
13628 *perl_exception;
13629
13630 volatile const MagickInfo
13631 *magick_info;
13632
13633 PERL_UNUSED_VAR(ref);
13634 PERL_UNUSED_VAR(ix);
13635 exception=AcquireExceptionInfo();
13636 perl_exception=newSVpv("",0);
13637 if (items == 1)
13638 {
13639 char
cristy151b66d2015-04-15 10:50:31 +000013640 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013641
13642 const MagickInfo
13643 **format_list;
13644
13645 size_t
13646 types;
13647
13648 format_list=GetMagickInfoList("*",&types,exception);
13649 EXTEND(sp,types);
13650 for (i=0; i < (ssize_t) types; i++)
13651 {
cristy151b66d2015-04-15 10:50:31 +000013652 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013653 LocaleLower(format);
13654 PUSHs(sv_2mortal(newSVpv(format,0)));
13655 }
13656 format_list=(const MagickInfo **)
13657 RelinquishMagickMemory((MagickInfo *) format_list);
13658 goto PerlException;
13659 }
13660 EXTEND(sp,8*items);
13661 for (i=1; i < items; i++)
13662 {
13663 name=(char *) SvPV(ST(i),na);
13664 magick_info=GetMagickInfo(name,exception);
13665 if (magick_info == (const MagickInfo *) NULL)
13666 {
13667 PUSHs(&sv_undef);
13668 continue;
13669 }
cristy4a3ce0a2013-08-03 20:06:59 +000013670 if (magick_info->description == (char *) NULL)
13671 PUSHs(&sv_undef);
13672 else
13673 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
Cristy31756212019-07-31 15:55:08 -040013674 if (magick_info->magick_module == (char *) NULL)
cristy4a3ce0a2013-08-03 20:06:59 +000013675 PUSHs(&sv_undef);
13676 else
Cristy31756212019-07-31 15:55:08 -040013677 PUSHs(sv_2mortal(newSVpv(magick_info->magick_module,0)));
cristy4a3ce0a2013-08-03 20:06:59 +000013678 }
13679
13680 PerlException:
13681 InheritPerlException(exception,perl_exception);
13682 exception=DestroyExceptionInfo(exception);
13683 SvREFCNT_dec(perl_exception);
13684 }
13685
13686#
13687###############################################################################
13688# #
13689# #
13690# #
13691# Q u e r y O p t i o n #
13692# #
13693# #
13694# #
13695###############################################################################
13696#
13697#
13698void
13699QueryOption(ref,...)
13700 Image::Magick ref=NO_INIT
13701 ALIAS:
13702 queryoption = 1
13703 PPCODE:
13704 {
13705 char
13706 **options;
13707
13708 ExceptionInfo
13709 *exception;
13710
13711 register ssize_t
13712 i;
13713
13714 ssize_t
13715 j,
13716 option;
13717
13718 SV
13719 *perl_exception;
13720
13721 PERL_UNUSED_VAR(ref);
13722 PERL_UNUSED_VAR(ix);
13723 exception=AcquireExceptionInfo();
13724 perl_exception=newSVpv("",0);
13725 EXTEND(sp,8*items);
13726 for (i=1; i < items; i++)
13727 {
13728 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13729 SvPV(ST(i),na));
13730 options=GetCommandOptions((CommandOption) option);
13731 if (options == (char **) NULL)
13732 PUSHs(&sv_undef);
13733 else
13734 {
13735 for (j=0; options[j] != (char *) NULL; j++)
13736 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13737 options=DestroyStringList(options);
13738 }
13739 }
13740
13741 InheritPerlException(exception,perl_exception);
13742 exception=DestroyExceptionInfo(exception);
13743 SvREFCNT_dec(perl_exception);
13744 }
13745
13746#
13747###############################################################################
13748# #
13749# #
13750# #
13751# R e a d #
13752# #
13753# #
13754# #
13755###############################################################################
13756#
13757#
13758void
13759Read(ref,...)
13760 Image::Magick ref=NO_INIT
13761 ALIAS:
13762 ReadImage = 1
13763 read = 2
13764 readimage = 3
13765 PPCODE:
13766 {
13767 AV
13768 *av;
13769
13770 char
13771 **keep,
13772 **list;
13773
13774 ExceptionInfo
13775 *exception;
13776
13777 HV
13778 *hv;
13779
13780 Image
13781 *image;
13782
13783 int
13784 n;
13785
13786 MagickBooleanType
13787 status;
13788
13789 register char
13790 **p;
13791
13792 register ssize_t
13793 i;
13794
13795 ssize_t
13796 ac,
13797 number_images;
13798
13799 STRLEN
13800 *length;
13801
13802 struct PackageInfo
13803 *info,
13804 *package_info;
13805
13806 SV
13807 *perl_exception, /* Perl variable for storing messages */
13808 *reference,
13809 *rv,
13810 *sv;
13811
13812 PERL_UNUSED_VAR(ref);
13813 PERL_UNUSED_VAR(ix);
13814 exception=AcquireExceptionInfo();
13815 perl_exception=newSVpv("",0);
13816 sv=NULL;
13817 package_info=(struct PackageInfo *) NULL;
13818 number_images=0;
13819 ac=(items < 2) ? 1 : items-1;
13820 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13821 keep=list;
13822 length=(STRLEN *) NULL;
13823 if (list == (char **) NULL)
13824 {
13825 ThrowPerlException(exception,ResourceLimitError,
13826 "MemoryAllocationFailed",PackageName);
13827 goto PerlException;
13828 }
13829 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13830 if (length == (STRLEN *) NULL)
13831 {
13832 ThrowPerlException(exception,ResourceLimitError,
13833 "MemoryAllocationFailed",PackageName);
13834 goto PerlException;
13835 }
13836 if (sv_isobject(ST(0)) == 0)
13837 {
13838 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13839 PackageName);
13840 goto PerlException;
13841 }
13842 reference=SvRV(ST(0));
13843 hv=SvSTASH(reference);
13844 if (SvTYPE(reference) != SVt_PVAV)
13845 {
13846 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13847 PackageName);
13848 goto PerlException;
13849 }
13850 av=(AV *) reference;
13851 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13852 exception);
13853 package_info=ClonePackageInfo(info,exception);
13854 n=1;
13855 if (items <= 1)
13856 *list=(char *) (*package_info->image_info->filename ?
13857 package_info->image_info->filename : "XC:black");
13858 else
13859 for (n=0, i=0; i < ac; i++)
13860 {
13861 list[n]=(char *) SvPV(ST(i+1),length[n]);
13862 if ((items >= 3) && strEQcase(list[n],"blob"))
13863 {
13864 void
13865 *blob;
13866
13867 i++;
13868 blob=(void *) (SvPV(ST(i+1),length[n]));
13869 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13870 }
13871 if ((items >= 3) && strEQcase(list[n],"filename"))
13872 continue;
13873 if ((items >= 3) && strEQcase(list[n],"file"))
13874 {
13875 FILE
13876 *file;
13877
13878 PerlIO
13879 *io_info;
13880
13881 i++;
13882 io_info=IoIFP(sv_2io(ST(i+1)));
13883 if (io_info == (PerlIO *) NULL)
13884 {
13885 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13886 PackageName);
13887 continue;
13888 }
13889 file=PerlIO_findFILE(io_info);
13890 if (file == (FILE *) NULL)
13891 {
13892 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13893 PackageName);
13894 continue;
13895 }
13896 SetImageInfoFile(package_info->image_info,file);
13897 }
13898 if ((items >= 3) && strEQcase(list[n],"magick"))
13899 continue;
13900 n++;
13901 }
13902 list[n]=(char *) NULL;
13903 keep=list;
13904 status=ExpandFilenames(&n,&list);
13905 if (status == MagickFalse)
13906 {
13907 ThrowPerlException(exception,ResourceLimitError,
13908 "MemoryAllocationFailed",PackageName);
13909 goto PerlException;
13910 }
13911 number_images=0;
13912 for (i=0; i < n; i++)
13913 {
13914 if ((package_info->image_info->file == (FILE *) NULL) &&
13915 (package_info->image_info->blob == (void *) NULL))
13916 image=ReadImages(package_info->image_info,list[i],exception);
13917 else
13918 {
13919 image=ReadImages(package_info->image_info,
13920 package_info->image_info->filename,exception);
13921 if (image != (Image *) NULL)
13922 DisassociateImageStream(image);
13923 }
13924 if (image == (Image *) NULL)
13925 break;
13926 for ( ; image; image=image->next)
13927 {
13928 AddImageToRegistry(sv,image);
13929 rv=newRV(sv);
13930 av_push(av,sv_bless(rv,hv));
13931 SvREFCNT_dec(sv);
13932 number_images++;
13933 }
13934 }
13935 /*
13936 Free resources.
13937 */
13938 for (i=0; i < n; i++)
13939 if (list[i] != (char *) NULL)
13940 for (p=keep; list[i] != *p++; )
13941 if (*p == (char *) NULL)
13942 {
13943 list[i]=(char *) RelinquishMagickMemory(list[i]);
13944 break;
13945 }
13946
13947 PerlException:
13948 if (package_info != (struct PackageInfo *) NULL)
13949 DestroyPackageInfo(package_info);
13950 if (list && (list != keep))
13951 list=(char **) RelinquishMagickMemory(list);
13952 if (keep)
13953 keep=(char **) RelinquishMagickMemory(keep);
13954 if (length)
13955 length=(STRLEN *) RelinquishMagickMemory(length);
13956 InheritPerlException(exception,perl_exception);
13957 exception=DestroyExceptionInfo(exception);
13958 sv_setiv(perl_exception,(IV) number_images);
13959 SvPOK_on(perl_exception);
13960 ST(0)=sv_2mortal(perl_exception);
13961 XSRETURN(1);
13962 }
13963
13964#
13965###############################################################################
13966# #
13967# #
13968# #
13969# R e m o t e #
13970# #
13971# #
13972# #
13973###############################################################################
13974#
13975#
13976void
13977Remote(ref,...)
13978 Image::Magick ref=NO_INIT
13979 ALIAS:
13980 RemoteCommand = 1
13981 remote = 2
13982 remoteCommand = 3
13983 PPCODE:
13984 {
13985 AV
13986 *av;
13987
13988 ExceptionInfo
13989 *exception;
13990
13991 register ssize_t
13992 i;
13993
13994 SV
13995 *perl_exception,
13996 *reference;
13997
13998 struct PackageInfo
13999 *info;
14000
14001 PERL_UNUSED_VAR(ref);
14002 PERL_UNUSED_VAR(ix);
14003 exception=AcquireExceptionInfo();
14004 perl_exception=newSVpv("",0);
14005 reference=SvRV(ST(0));
14006 av=(AV *) reference;
14007 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14008 exception);
14009 for (i=1; i < items; i++)
14010 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
14011 SvPV(ST(i),na),exception);
14012 InheritPerlException(exception,perl_exception);
14013 exception=DestroyExceptionInfo(exception);
14014 SvREFCNT_dec(perl_exception); /* throw away all errors */
14015 }
14016
14017#
14018###############################################################################
14019# #
14020# #
14021# #
14022# S e t #
14023# #
14024# #
14025# #
14026###############################################################################
14027#
14028#
14029void
14030Set(ref,...)
14031 Image::Magick ref=NO_INIT
14032 ALIAS:
14033 SetAttributes = 1
14034 SetAttribute = 2
14035 set = 3
14036 setattributes = 4
14037 setattribute = 5
14038 PPCODE:
14039 {
14040 ExceptionInfo
14041 *exception;
14042
14043 Image
14044 *image;
14045
14046 register ssize_t
14047 i;
14048
14049 struct PackageInfo
14050 *info;
14051
14052 SV
14053 *perl_exception,
14054 *reference; /* reference is the SV* of ref=SvIV(reference) */
14055
14056 PERL_UNUSED_VAR(ref);
14057 PERL_UNUSED_VAR(ix);
14058 exception=AcquireExceptionInfo();
14059 perl_exception=newSVpv("",0);
14060 if (sv_isobject(ST(0)) == 0)
14061 {
14062 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14063 PackageName);
14064 goto PerlException;
14065 }
14066 reference=SvRV(ST(0));
14067 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14068 if (items == 2)
14069 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
14070 else
14071 for (i=2; i < items; i+=2)
14072 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
14073
14074 PerlException:
14075 InheritPerlException(exception,perl_exception);
14076 exception=DestroyExceptionInfo(exception);
14077 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
14078 SvPOK_on(perl_exception);
14079 ST(0)=sv_2mortal(perl_exception);
14080 XSRETURN(1);
14081 }
14082
14083#
14084###############################################################################
14085# #
14086# #
14087# #
14088# S e t P i x e l #
14089# #
14090# #
14091# #
14092###############################################################################
14093#
14094#
14095void
14096SetPixel(ref,...)
14097 Image::Magick ref=NO_INIT
14098 ALIAS:
14099 setpixel = 1
14100 setPixel = 2
14101 PPCODE:
14102 {
14103 AV
14104 *av;
14105
14106 char
14107 *attribute;
14108
14109 ChannelType
14110 channel,
14111 channel_mask;
14112
14113 ExceptionInfo
14114 *exception;
14115
14116 Image
14117 *image;
14118
14119 MagickBooleanType
14120 normalize;
14121
14122 RectangleInfo
14123 region;
14124
14125 register ssize_t
14126 i;
14127
14128 register Quantum
14129 *q;
14130
14131 ssize_t
14132 option;
14133
14134 struct PackageInfo
14135 *info;
14136
14137 SV
14138 *perl_exception,
14139 *reference; /* reference is the SV* of ref=SvIV(reference) */
14140
14141 PERL_UNUSED_VAR(ref);
14142 PERL_UNUSED_VAR(ix);
14143 exception=AcquireExceptionInfo();
14144 perl_exception=newSVpv("",0);
14145 reference=SvRV(ST(0));
14146 av=(AV *) reference;
14147 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14148 exception);
14149 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14150 if (image == (Image *) NULL)
14151 {
14152 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14153 PackageName);
14154 goto PerlException;
14155 }
14156 av=(AV *) NULL;
14157 normalize=MagickTrue;
14158 region.x=0;
14159 region.y=0;
14160 region.width=image->columns;
14161 region.height=1;
14162 if (items == 1)
14163 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
14164 channel=DefaultChannels;
14165 for (i=2; i < items; i+=2)
14166 {
14167 attribute=(char *) SvPV(ST(i-1),na);
14168 switch (*attribute)
14169 {
14170 case 'C':
14171 case 'c':
14172 {
14173 if (LocaleCompare(attribute,"channel") == 0)
14174 {
14175 ssize_t
14176 option;
14177
14178 option=ParseChannelOption(SvPV(ST(i),na));
14179 if (option < 0)
14180 {
14181 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14182 SvPV(ST(i),na));
14183 return;
14184 }
14185 channel=(ChannelType) option;
14186 break;
14187 }
14188 if (LocaleCompare(attribute,"color") == 0)
14189 {
14190 if (SvTYPE(ST(i)) != SVt_RV)
14191 {
14192 char
cristy151b66d2015-04-15 10:50:31 +000014193 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014194
cristy151b66d2015-04-15 10:50:31 +000014195 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000014196 "invalid %.60s value",attribute);
14197 ThrowPerlException(exception,OptionError,message,
14198 SvPV(ST(i),na));
14199 }
14200 av=(AV *) SvRV(ST(i));
14201 break;
14202 }
14203 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14204 attribute);
14205 break;
14206 }
14207 case 'g':
14208 case 'G':
14209 {
14210 if (LocaleCompare(attribute,"geometry") == 0)
14211 {
14212 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14213 break;
14214 }
14215 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14216 attribute);
14217 break;
14218 }
14219 case 'N':
14220 case 'n':
14221 {
14222 if (LocaleCompare(attribute,"normalize") == 0)
14223 {
14224 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14225 SvPV(ST(i),na));
14226 if (option < 0)
14227 {
14228 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14229 SvPV(ST(i),na));
14230 break;
14231 }
14232 normalize=option != 0 ? MagickTrue : MagickFalse;
14233 break;
14234 }
14235 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14236 attribute);
14237 break;
14238 }
14239 case 'x':
14240 case 'X':
14241 {
14242 if (LocaleCompare(attribute,"x") == 0)
14243 {
14244 region.x=SvIV(ST(i));
14245 break;
14246 }
14247 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14248 attribute);
14249 break;
14250 }
14251 case 'y':
14252 case 'Y':
14253 {
14254 if (LocaleCompare(attribute,"y") == 0)
14255 {
14256 region.y=SvIV(ST(i));
14257 break;
14258 }
14259 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14260 attribute);
14261 break;
14262 }
14263 default:
14264 {
14265 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14266 attribute);
14267 break;
14268 }
14269 }
14270 }
14271 (void) SetImageStorageClass(image,DirectClass,exception);
14272 channel_mask=SetImageChannelMask(image,channel);
14273 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14274 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14275 (SvTYPE(av) != SVt_PVAV))
14276 PUSHs(&sv_undef);
14277 else
14278 {
14279 double
14280 scale;
14281
14282 register ssize_t
14283 i;
14284
14285 i=0;
14286 scale=1.0;
14287 if (normalize != MagickFalse)
14288 scale=QuantumRange;
14289 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14290 (i <= av_len(av)))
14291 {
14292 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14293 av_fetch(av,i,0)))),q);
14294 i++;
14295 }
14296 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14297 (i <= av_len(av)))
14298 {
14299 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14300 av_fetch(av,i,0)))),q);
14301 i++;
14302 }
14303 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14304 (i <= av_len(av)))
14305 {
14306 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14307 av_fetch(av,i,0)))),q);
14308 i++;
14309 }
14310 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14311 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14312 {
14313 SetPixelBlack(image,ClampToQuantum(scale*
14314 SvNV(*(av_fetch(av,i,0)))),q);
14315 i++;
14316 }
14317 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14318 (i <= av_len(av)))
14319 {
14320 SetPixelAlpha(image,ClampToQuantum(scale*
14321 SvNV(*(av_fetch(av,i,0)))),q);
14322 i++;
14323 }
14324 (void) SyncAuthenticPixels(image,exception);
14325 }
14326 (void) SetImageChannelMask(image,channel_mask);
14327
14328 PerlException:
14329 InheritPerlException(exception,perl_exception);
14330 exception=DestroyExceptionInfo(exception);
14331 SvREFCNT_dec(perl_exception);
14332 }
14333
14334#
14335###############################################################################
14336# #
14337# #
14338# #
Cristybba545b2018-07-04 15:00:12 -040014339# S e t P i x e l s #
14340# #
14341# #
14342# #
14343###############################################################################
14344#
14345#
14346void
14347SetPixels(ref,...)
14348 Image::Magick ref=NO_INIT
14349 ALIAS:
14350 setpixels = 1
14351 setPixels = 2
14352 PPCODE:
14353 {
14354 AV
14355 *av;
14356
14357 char
14358 *attribute;
14359
14360 ChannelType
14361 channel,
14362 channel_mask;
14363
14364 ExceptionInfo
14365 *exception;
14366
14367 Image
14368 *image;
14369
14370 RectangleInfo
14371 region;
14372
14373 register ssize_t
14374 i;
14375
14376 register Quantum
14377 *q;
14378
14379 struct PackageInfo
14380 *info;
14381
14382 SV
14383 *perl_exception,
14384 *reference; /* reference is the SV* of ref=SvIV(reference) */
14385
14386 PERL_UNUSED_VAR(ref);
14387 PERL_UNUSED_VAR(ix);
14388 exception=AcquireExceptionInfo();
14389 perl_exception=newSVpv("",0);
14390 reference=SvRV(ST(0));
14391 av=(AV *) reference;
14392 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14393 exception);
14394 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14395 if (image == (Image *) NULL)
14396 {
14397 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14398 PackageName);
14399 goto PerlException;
14400 }
14401 av=(AV *) NULL;
14402 region.x=0;
14403 region.y=0;
14404 region.width=image->columns;
14405 region.height=1;
14406 if (items == 1)
14407 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
14408 channel=DefaultChannels;
14409 for (i=2; i < items; i+=2)
14410 {
14411 attribute=(char *) SvPV(ST(i-1),na);
14412 switch (*attribute)
14413 {
14414 case 'C':
14415 case 'c':
14416 {
14417 if (LocaleCompare(attribute,"channel") == 0)
14418 {
14419 ssize_t
14420 option;
14421
14422 option=ParseChannelOption(SvPV(ST(i),na));
14423 if (option < 0)
14424 {
14425 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14426 SvPV(ST(i),na));
14427 return;
14428 }
14429 channel=(ChannelType) option;
14430 break;
14431 }
14432 if (LocaleCompare(attribute,"color") == 0)
14433 {
14434 if (SvTYPE(ST(i)) != SVt_RV)
14435 {
14436 char
14437 message[MagickPathExtent];
14438
14439 (void) FormatLocaleString(message,MagickPathExtent,
14440 "invalid %.60s value",attribute);
14441 ThrowPerlException(exception,OptionError,message,
14442 SvPV(ST(i),na));
14443 }
14444 av=(AV *) SvRV(ST(i));
14445 break;
14446 }
14447 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14448 attribute);
14449 break;
14450 }
14451 case 'g':
14452 case 'G':
14453 {
14454 if (LocaleCompare(attribute,"geometry") == 0)
14455 {
14456 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14457 break;
14458 }
14459 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14460 attribute);
14461 break;
14462 }
14463 case 'h':
14464 case 'H':
14465 {
14466 if (LocaleCompare(attribute,"height") == 0)
14467 {
14468 region.height=SvIV(ST(i));
14469 break;
14470 }
14471 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14472 attribute);
14473 break;
14474 }
14475 case 'w':
14476 case 'W':
14477 {
14478 if (LocaleCompare(attribute,"width") == 0)
14479 {
14480 region.width=SvIV(ST(i));
14481 break;
14482 }
14483 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14484 attribute);
14485 break;
14486 }
14487 case 'x':
14488 case 'X':
14489 {
14490 if (LocaleCompare(attribute,"x") == 0)
14491 {
14492 region.x=SvIV(ST(i));
14493 break;
14494 }
14495 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14496 attribute);
14497 break;
14498 }
14499 case 'y':
14500 case 'Y':
14501 {
14502 if (LocaleCompare(attribute,"y") == 0)
14503 {
14504 region.y=SvIV(ST(i));
14505 break;
14506 }
14507 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14508 attribute);
14509 break;
14510 }
14511 default:
14512 {
14513 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14514 attribute);
14515 break;
14516 }
14517 }
14518 }
14519 (void) SetImageStorageClass(image,DirectClass,exception);
14520 channel_mask=SetImageChannelMask(image,channel);
14521 q=GetAuthenticPixels(image,region.x,region.y,region.width,region.height,
14522 exception);
14523 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14524 (SvTYPE(av) != SVt_PVAV))
14525 PUSHs(&sv_undef);
14526 else
14527 {
14528 double
14529 scale;
14530
14531 register ssize_t
14532 i,
14533 n,
14534 number_pixels;
14535
14536 i=0;
14537 n=0;
14538 scale=(double) QuantumRange;
14539 number_pixels=region.width*region.height;
14540 while ((n < number_pixels) && (i < av_len(av)))
14541 {
14542 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14543 (i <= av_len(av)))
14544 {
14545 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14546 av_fetch(av,i,0)))),q);
14547 i++;
14548 }
14549 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14550 (i <= av_len(av)))
14551 {
14552 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14553 av_fetch(av,i,0)))),q);
14554 i++;
14555 }
14556 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14557 (i <= av_len(av)))
14558 {
14559 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14560 av_fetch(av,i,0)))),q);
14561 i++;
14562 }
14563 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14564 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14565 {
14566 SetPixelBlack(image,ClampToQuantum(scale*
14567 SvNV(*(av_fetch(av,i,0)))),q);
14568 i++;
14569 }
14570 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14571 (i <= av_len(av)))
14572 {
14573 SetPixelAlpha(image,ClampToQuantum(scale*
14574 SvNV(*(av_fetch(av,i,0)))),q);
14575 i++;
14576 }
14577 n++;
14578 q+=image->number_channels;
14579 }
14580 (void) SyncAuthenticPixels(image,exception);
14581 }
14582 (void) SetImageChannelMask(image,channel_mask);
14583
14584 PerlException:
14585 InheritPerlException(exception,perl_exception);
14586 exception=DestroyExceptionInfo(exception);
14587 SvREFCNT_dec(perl_exception);
14588 }
14589
14590#
14591###############################################################################
14592# #
14593# #
14594# #
cristy4a3ce0a2013-08-03 20:06:59 +000014595# S m u s h #
14596# #
14597# #
14598# #
14599###############################################################################
14600#
14601#
14602void
14603Smush(ref,...)
14604 Image::Magick ref=NO_INIT
14605 ALIAS:
14606 SmushImage = 1
14607 smush = 2
14608 smushimage = 3
14609 PPCODE:
14610 {
14611 AV
14612 *av;
14613
14614 char
14615 *attribute;
14616
14617 ExceptionInfo
14618 *exception;
14619
14620 HV
14621 *hv;
14622
14623 Image
14624 *image;
14625
14626 register ssize_t
14627 i;
14628
14629 ssize_t
14630 offset,
14631 stack;
14632
14633 struct PackageInfo
14634 *info;
14635
14636 SV
14637 *av_reference,
14638 *perl_exception,
14639 *reference,
14640 *rv,
14641 *sv;
14642
14643 PERL_UNUSED_VAR(ref);
14644 PERL_UNUSED_VAR(ix);
14645 exception=AcquireExceptionInfo();
14646 perl_exception=newSVpv("",0);
14647 sv=NULL;
14648 attribute=NULL;
14649 av=NULL;
14650 if (sv_isobject(ST(0)) == 0)
14651 {
14652 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14653 PackageName);
14654 goto PerlException;
14655 }
14656 reference=SvRV(ST(0));
14657 hv=SvSTASH(reference);
14658 av=newAV();
14659 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14660 SvREFCNT_dec(av);
14661 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14662 if (image == (Image *) NULL)
14663 {
14664 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14665 PackageName);
14666 goto PerlException;
14667 }
14668 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14669 /*
14670 Get options.
14671 */
14672 offset=0;
14673 stack=MagickTrue;
14674 for (i=2; i < items; i+=2)
14675 {
14676 attribute=(char *) SvPV(ST(i-1),na);
14677 switch (*attribute)
14678 {
14679 case 'O':
14680 case 'o':
14681 {
14682 if (LocaleCompare(attribute,"offset") == 0)
14683 {
14684 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14685 break;
14686 }
14687 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14688 attribute);
14689 break;
14690 }
14691 case 'S':
14692 case 's':
14693 {
14694 if (LocaleCompare(attribute,"stack") == 0)
14695 {
14696 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14697 SvPV(ST(i),na));
14698 if (stack < 0)
14699 {
14700 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14701 SvPV(ST(i),na));
14702 return;
14703 }
14704 break;
14705 }
14706 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14707 attribute);
14708 break;
14709 }
14710 default:
14711 {
14712 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14713 attribute);
14714 break;
14715 }
14716 }
14717 }
14718 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14719 exception);
14720 if (image == (Image *) NULL)
14721 goto PerlException;
14722 for ( ; image; image=image->next)
14723 {
14724 AddImageToRegistry(sv,image);
14725 rv=newRV(sv);
14726 av_push(av,sv_bless(rv,hv));
14727 SvREFCNT_dec(sv);
14728 }
14729 exception=DestroyExceptionInfo(exception);
14730 ST(0)=av_reference;
14731 SvREFCNT_dec(perl_exception);
14732 XSRETURN(1);
14733
14734 PerlException:
14735 InheritPerlException(exception,perl_exception);
14736 exception=DestroyExceptionInfo(exception);
14737 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14738 SvPOK_on(perl_exception);
14739 ST(0)=sv_2mortal(perl_exception);
14740 XSRETURN(1);
14741 }
14742
14743#
14744###############################################################################
14745# #
14746# #
14747# #
14748# S t a t i s t i c s #
14749# #
14750# #
14751# #
14752###############################################################################
14753#
14754#
14755void
14756Statistics(ref,...)
14757 Image::Magick ref=NO_INIT
14758 ALIAS:
14759 StatisticsImage = 1
14760 statistics = 2
14761 statisticsimage = 3
14762 PPCODE:
14763 {
14764#define ChannelStatistics(channel) \
14765{ \
cristy151b66d2015-04-15 10:50:31 +000014766 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014767 (double) channel_statistics[channel].depth); \
14768 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014769 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014770 channel_statistics[channel].minima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014771 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014772 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014773 channel_statistics[channel].maxima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014774 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014775 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014776 channel_statistics[channel].mean/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014777 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014778 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014779 channel_statistics[channel].standard_deviation/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014780 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014781 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014782 channel_statistics[channel].kurtosis); \
14783 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014784 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014785 channel_statistics[channel].skewness); \
14786 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014787 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy275bdd92014-11-08 23:45:03 +000014788 channel_statistics[channel].entropy); \
14789 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014790}
14791
14792 AV
14793 *av;
14794
14795 char
cristy151b66d2015-04-15 10:50:31 +000014796 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014797
14798 ChannelStatistics
14799 *channel_statistics;
14800
cristy4a3ce0a2013-08-03 20:06:59 +000014801 ExceptionInfo
14802 *exception;
14803
14804 Image
14805 *image;
14806
14807 ssize_t
14808 count;
14809
14810 struct PackageInfo
14811 *info;
14812
14813 SV
14814 *perl_exception,
14815 *reference;
14816
14817 PERL_UNUSED_VAR(ref);
14818 PERL_UNUSED_VAR(ix);
14819 exception=AcquireExceptionInfo();
14820 perl_exception=newSVpv("",0);
14821 av=NULL;
14822 if (sv_isobject(ST(0)) == 0)
14823 {
14824 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14825 PackageName);
14826 goto PerlException;
14827 }
14828 reference=SvRV(ST(0));
14829 av=newAV();
14830 SvREFCNT_dec(av);
14831 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14832 if (image == (Image *) NULL)
14833 {
14834 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14835 PackageName);
14836 goto PerlException;
14837 }
cristy4a3ce0a2013-08-03 20:06:59 +000014838 count=0;
14839 for ( ; image; image=image->next)
14840 {
Cristyb1710fe2017-02-11 13:51:48 -050014841 register size_t
14842 i;
14843
cristy4a3ce0a2013-08-03 20:06:59 +000014844 channel_statistics=GetImageStatistics(image,exception);
14845 if (channel_statistics == (ChannelStatistics *) NULL)
14846 continue;
14847 count++;
Cristyb1710fe2017-02-11 13:51:48 -050014848 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
14849 {
14850 PixelChannel channel=GetPixelChannelChannel(image,i);
14851 PixelTrait traits=GetPixelChannelTraits(image,channel);
Cristy5a854dc2017-02-11 15:43:46 -050014852 if (traits == UndefinedPixelTrait)
Cristyb1710fe2017-02-11 13:51:48 -050014853 continue;
Cristy5a854dc2017-02-11 15:43:46 -050014854 EXTEND(sp,8*(i+1)*count);
Cristyb1710fe2017-02-11 13:51:48 -050014855 ChannelStatistics(channel);
14856 }
Cristy25813902017-02-11 15:47:52 -050014857 EXTEND(sp,8*(i+1)*count);
14858 ChannelStatistics(CompositePixelChannel);
cristy4a3ce0a2013-08-03 20:06:59 +000014859 channel_statistics=(ChannelStatistics *)
14860 RelinquishMagickMemory(channel_statistics);
14861 }
14862
14863 PerlException:
14864 InheritPerlException(exception,perl_exception);
14865 exception=DestroyExceptionInfo(exception);
14866 SvREFCNT_dec(perl_exception);
14867 }
14868
14869#
14870###############################################################################
14871# #
14872# #
14873# #
14874# S y n c A u t h e n t i c P i x e l s #
14875# #
14876# #
14877# #
14878###############################################################################
14879#
14880#
14881void
14882SyncAuthenticPixels(ref,...)
14883 Image::Magick ref = NO_INIT
14884 ALIAS:
14885 Syncauthenticpixels = 1
14886 SyncImagePixels = 2
14887 syncimagepixels = 3
14888 CODE:
14889 {
14890 ExceptionInfo
14891 *exception;
14892
14893 Image
14894 *image;
14895
14896 MagickBooleanType
14897 status;
14898
14899 struct PackageInfo
14900 *info;
14901
14902 SV
14903 *perl_exception,
14904 *reference;
14905
14906 PERL_UNUSED_VAR(ref);
14907 PERL_UNUSED_VAR(ix);
14908 exception=AcquireExceptionInfo();
14909 perl_exception=newSVpv("",0);
14910 if (sv_isobject(ST(0)) == 0)
14911 {
14912 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14913 PackageName);
14914 goto PerlException;
14915 }
14916
14917 reference=SvRV(ST(0));
14918 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14919 if (image == (Image *) NULL)
14920 {
14921 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14922 PackageName);
14923 goto PerlException;
14924 }
14925
14926 status=SyncAuthenticPixels(image,exception);
14927 if (status != MagickFalse)
14928 return;
14929
14930 PerlException:
14931 InheritPerlException(exception,perl_exception);
14932 exception=DestroyExceptionInfo(exception);
14933 SvREFCNT_dec(perl_exception); /* throw away all errors */
14934 }
14935
14936#
14937###############################################################################
14938# #
14939# #
14940# #
cristy4a3ce0a2013-08-03 20:06:59 +000014941# W r i t e #
14942# #
14943# #
14944# #
14945###############################################################################
14946#
14947#
14948void
14949Write(ref,...)
14950 Image::Magick ref=NO_INIT
14951 ALIAS:
14952 WriteImage = 1
14953 write = 2
14954 writeimage = 3
14955 PPCODE:
14956 {
14957 char
cristy151b66d2015-04-15 10:50:31 +000014958 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014959
14960 ExceptionInfo
14961 *exception;
14962
14963 Image
14964 *image,
14965 *next;
14966
14967 register ssize_t
14968 i;
14969
14970 ssize_t
14971 number_images,
14972 scene;
14973
14974 struct PackageInfo
14975 *info,
14976 *package_info;
14977
14978 SV
14979 *perl_exception,
14980 *reference;
14981
14982 PERL_UNUSED_VAR(ref);
14983 PERL_UNUSED_VAR(ix);
14984 exception=AcquireExceptionInfo();
14985 perl_exception=newSVpv("",0);
14986 number_images=0;
14987 package_info=(struct PackageInfo *) NULL;
14988 if (sv_isobject(ST(0)) == 0)
14989 {
14990 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14991 PackageName);
14992 goto PerlException;
14993 }
14994 reference=SvRV(ST(0));
14995 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14996 if (image == (Image *) NULL)
14997 {
14998 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14999 PackageName);
15000 goto PerlException;
15001 }
Cristyb4ee45c2017-09-27 17:58:55 -040015002 scene=0;
15003 for (next=image; next; next=next->next)
15004 next->scene=scene++;
cristy4a3ce0a2013-08-03 20:06:59 +000015005 package_info=ClonePackageInfo(info,exception);
15006 if (items == 2)
15007 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
15008 else
15009 if (items > 2)
15010 for (i=2; i < items; i+=2)
15011 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
15012 exception);
15013 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000015014 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000015015 for (next=image; next; next=next->next)
cristy151b66d2015-04-15 10:50:31 +000015016 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy68bd79a2015-02-25 12:23:36 +000015017 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000015018 SetImageInfo(package_info->image_info,(unsigned int)
15019 GetImageListLength(image),exception);
15020 for (next=image; next; next=next->next)
15021 {
15022 (void) WriteImage(package_info->image_info,next,exception);
15023 number_images++;
15024 if (package_info->image_info->adjoin)
15025 break;
15026 }
15027
15028 PerlException:
15029 if (package_info != (struct PackageInfo *) NULL)
15030 DestroyPackageInfo(package_info);
15031 InheritPerlException(exception,perl_exception);
15032 exception=DestroyExceptionInfo(exception);
15033 sv_setiv(perl_exception,(IV) number_images);
15034 SvPOK_on(perl_exception);
15035 ST(0)=sv_2mortal(perl_exception);
15036 XSRETURN(1);
15037 }