blob: 727369ee756faf5adaa6eab9889729a11109db82 [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% %
Cristy93b707b2017-12-06 07:05:51 -050026% Copyright 1999-2018 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% %
32% http://www.imagemagick.org/script/license.php %
33% %
34% Unless required by applicable law or agreed to in writing, software %
35% distributed under the License is distributed on an "AS IS" BASIS, %
36% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
37% See the License for the specific language governing permissions and %
38% limitations under the License. %
39% %
40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41%
42% PerlMagick is an objected-oriented Perl interface to ImageMagick. Use
43% the module to read, manipulate, or write an image or image sequence from
44% within a Perl script. This makes PerlMagick suitable for Web CGI scripts.
45%
46*/
47
48/*
49 Include declarations.
50*/
51#if defined(__cplusplus) || defined(c_plusplus)
52extern "C" {
53#endif
54
55#define PERL_NO_GET_CONTEXT
dirk190cc1c2015-06-16 11:48:37 +000056#include <MagickCore/MagickCore.h>
cristy4a3ce0a2013-08-03 20:06:59 +000057#include "EXTERN.h"
58#include "perl.h"
59#include "XSUB.h"
60#include <math.h>
cristy4a3ce0a2013-08-03 20:06:59 +000061#undef tainted
62
63#if defined(__cplusplus) || defined(c_plusplus)
64}
65#endif
66
67/*
68 Define declarations.
69*/
70#ifndef aTHX_
71#define aTHX_
72#define pTHX_
73#define dTHX
74#endif
75#define DegreesToRadians(x) (MagickPI*(x)/180.0)
76#define EndOf(array) (&array[NumberOf(array)])
cristy3249b7b2014-02-09 21:43:14 +000077#define MagickPI 3.14159265358979323846264338327950288419716939937510
cristy4a3ce0a2013-08-03 20:06:59 +000078#define MaxArguments 33
79#ifndef na
80#define na PL_na
81#endif
82#define NumberOf(array) (sizeof(array)/sizeof(*array))
83#define PackageName "Image::Magick"
84#if PERL_VERSION <= 6
85#define PerlIO FILE
86#define PerlIO_importFILE(f, fl) (f)
87#define PerlIO_findFILE(f) NULL
88#endif
89#ifndef sv_undef
90#define sv_undef PL_sv_undef
91#endif
92
93#define AddImageToRegistry(sv,image) \
94{ \
95 if (magick_registry != (SplayTreeInfo *) NULL) \
96 { \
97 (void) AddValueToSplayTree(magick_registry,image,image); \
98 (sv)=newSViv(PTR2IV(image)); \
99 } \
100}
101
102#define DeleteImageFromRegistry(reference,image) \
103{ \
104 if (magick_registry != (SplayTreeInfo *) NULL) \
105 { \
106 if (GetImageReferenceCount(image) == 1) \
107 (void) DeleteNodeByValueFromSplayTree(magick_registry,image); \
108 image=DestroyImage(image); \
109 sv_setiv(reference,0); \
110 } \
111}
112
113#define InheritPerlException(exception,perl_exception) \
114{ \
115 char \
cristy151b66d2015-04-15 10:50:31 +0000116 message[MagickPathExtent]; \
cristy4a3ce0a2013-08-03 20:06:59 +0000117 \
118 if ((exception)->severity != UndefinedException) \
119 { \
cristy151b66d2015-04-15 10:50:31 +0000120 (void) FormatLocaleString(message,MagickPathExtent,"Exception %d: %s%s%s%s",\
cristy4a3ce0a2013-08-03 20:06:59 +0000121 (exception)->severity, (exception)->reason ? \
122 GetLocaleExceptionMessage((exception)->severity,(exception)->reason) : \
123 "Unknown", (exception)->description ? " (" : "", \
124 (exception)->description ? GetLocaleExceptionMessage( \
125 (exception)->severity,(exception)->description) : "", \
126 (exception)->description ? ")" : ""); \
127 if ((perl_exception) != (SV *) NULL) \
128 { \
129 if (SvCUR(perl_exception)) \
130 sv_catpv(perl_exception,"\n"); \
131 sv_catpv(perl_exception,message); \
132 } \
133 } \
134}
135
136#define ThrowPerlException(exception,severity,tag,reason) \
137 (void) ThrowMagickException(exception,GetMagickModule(),severity, \
138 tag,"`%s'",reason); \
139
140/*
141 Typedef and structure declarations.
142*/
143typedef enum
144{
Cristya9a04772018-01-16 11:44:34 -0500145 NullReference = 0,
cristy4a3ce0a2013-08-03 20:06:59 +0000146 ArrayReference = (~0),
147 RealReference = (~0)-1,
148 FileReference = (~0)-2,
149 ImageReference = (~0)-3,
150 IntegerReference = (~0)-4,
151 StringReference = (~0)-5
152} MagickReference;
153
154typedef struct _Arguments
155{
156 const char
157 *method;
158
159 ssize_t
160 type;
161} Arguments;
162
163struct ArgumentList
164{
165 ssize_t
166 integer_reference;
167
168 double
169 real_reference;
170
171 const char
172 *string_reference;
173
174 Image
175 *image_reference;
176
177 SV
178 *array_reference;
179
180 FILE
181 *file_reference;
182
183 size_t
184 length;
185};
186
187struct PackageInfo
188{
189 ImageInfo
190 *image_info;
191};
192
193typedef void
194 *Image__Magick; /* data type for the Image::Magick package */
195
196/*
197 Static declarations.
198*/
199static struct
200 Methods
201 {
202 const char
203 *name;
204
205 Arguments
206 arguments[MaxArguments];
207 } Methods[] =
208 {
209 { "Comment", { {"comment", StringReference} } },
210 { "Label", { {"label", StringReference} } },
211 { "AddNoise", { {"noise", MagickNoiseOptions}, {"attenuate", RealReference},
212 {"channel", MagickChannelOptions} } },
213 { "Colorize", { {"fill", StringReference}, {"blend", StringReference} } },
214 { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
215 {"height", IntegerReference}, {"fill", StringReference},
216 {"bordercolor", StringReference}, {"color", StringReference},
217 {"compose", MagickComposeOptions} } },
218 { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
219 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
220 { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
221 {"height", IntegerReference}, {"x", IntegerReference},
cristy260bd762014-08-15 12:46:34 +0000222 {"y", IntegerReference}, {"gravity", MagickGravityOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000223 { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
224 {"height", IntegerReference}, {"x", IntegerReference},
225 {"y", IntegerReference}, {"fuzz", StringReference},
226 {"gravity", MagickGravityOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500227 { "Despeckle", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000228 { "Edge", { {"radius", RealReference} } },
229 { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
230 {"sigma", RealReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500231 { "Enhance", { { (const char *) NULL, NullReference } } },
232 { "Flip", { { (const char *) NULL, NullReference } } },
233 { "Flop", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000234 { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
235 {"height", IntegerReference}, {"inner", IntegerReference},
236 {"outer", IntegerReference}, {"fill", StringReference},
237 {"color", StringReference}, {"compose", MagickComposeOptions} } },
238 { "Implode", { {"amount", RealReference},
239 {"interpolate", MagickInterpolateOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500240 { "Magnify", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000241 { "MedianFilter", { {"geometry", StringReference},
242 {"width", IntegerReference}, {"height", IntegerReference},
243 {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500244 { "Minify", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000245 { "OilPaint", { {"radius", RealReference}, {"sigma", RealReference} } },
246 { "ReduceNoise", { {"geometry", StringReference},
247 {"width", IntegerReference},{"height", IntegerReference},
248 {"channel", MagickChannelOptions} } },
249 { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
250 {"y", IntegerReference} } },
cristy83a28a02013-08-03 20:25:48 +0000251 { "Rotate", { {"degrees", RealReference},
cristy4a3ce0a2013-08-03 20:06:59 +0000252 {"background", StringReference} } },
253 { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
254 {"height", IntegerReference} } },
255 { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
256 {"height", IntegerReference} } },
257 { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
258 {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
259 { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
260 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
261 { "Shear", { {"geometry", StringReference}, {"x", RealReference},
262 {"y", RealReference}, { "fill", StringReference},
263 {"color", StringReference} } },
Cristye3319c12015-08-24 07:11:48 -0400264 { "Spread", { {"radius", RealReference},
Cristy3ca633e2016-02-13 12:49:01 -0500265 {"interpolate", MagickInterpolateOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000266 { "Swirl", { {"degrees", RealReference},
267 {"interpolate", MagickInterpolateOptions} } },
268 { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
269 {"height", IntegerReference}, {"filter", MagickFilterOptions},
270 {"support", StringReference } } },
271 { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
272 {"height", IntegerReference}, {"filter", MagickFilterOptions},
273 {"support", RealReference } } },
274 { "Annotate", { {"text", StringReference}, {"font", StringReference},
275 {"pointsize", RealReference}, {"density", StringReference},
276 {"undercolor", StringReference}, {"stroke", StringReference},
277 {"fill", StringReference}, {"geometry", StringReference},
278 {"sans", StringReference}, {"x", RealReference},
279 {"y", RealReference}, {"gravity", MagickGravityOptions},
280 {"translate", StringReference}, {"scale", StringReference},
281 {"rotate", RealReference}, {"skewX", RealReference},
282 {"skewY", RealReference}, {"strokewidth", RealReference},
283 {"antialias", MagickBooleanOptions}, {"family", StringReference},
284 {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
285 {"weight", IntegerReference}, {"align", MagickAlignOptions},
286 {"encoding", StringReference}, {"affine", ArrayReference},
287 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
288 {"tile", ImageReference}, {"kerning", RealReference},
289 {"interline-spacing", RealReference},
290 {"interword-spacing", RealReference},
291 {"direction", MagickDirectionOptions} } },
292 { "ColorFloodfill", { {"geometry", StringReference},
293 {"x", IntegerReference}, {"y", IntegerReference},
294 {"fill", StringReference}, {"bordercolor", StringReference},
295 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
296 { "Composite", { {"image", ImageReference},
297 {"compose", MagickComposeOptions}, {"geometry", StringReference},
298 {"x", IntegerReference}, {"y", IntegerReference},
299 {"gravity", MagickGravityOptions}, {"opacity", StringReference},
300 {"tile", MagickBooleanOptions}, {"rotate", RealReference},
301 {"color", StringReference}, {"mask", ImageReference},
302 {"channel", MagickChannelOptions},
303 {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
Cristy74e39292018-07-08 13:13:20 -0400304 {"blend", StringReference}, {"clip-to-self", MagickBooleanOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000305 { "Contrast", { {"sharpen", MagickBooleanOptions} } },
306 { "CycleColormap", { {"display", IntegerReference} } },
307 { "Draw", { {"primitive", MagickPrimitiveOptions},
308 {"points", StringReference}, {"method", MagickMethodOptions},
309 {"stroke", StringReference}, {"fill", StringReference},
310 {"strokewidth", RealReference}, {"font", StringReference},
311 {"bordercolor", StringReference}, {"x", RealReference},
312 {"y", RealReference}, {"translate", StringReference},
313 {"scale", StringReference}, {"rotate", RealReference},
314 {"skewX", RealReference}, {"skewY", RealReference},
315 {"tile", ImageReference}, {"pointsize", RealReference},
316 {"antialias", MagickBooleanOptions}, {"density", StringReference},
317 {"linewidth", RealReference}, {"affine", ArrayReference},
318 {"stroke-dashoffset", RealReference},
319 {"stroke-dasharray", ArrayReference},
320 {"interpolate", MagickInterpolateOptions},
321 {"origin", StringReference}, {"text", StringReference},
322 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
323 {"vector-graphics", StringReference}, {"kerning", RealReference},
324 {"interline-spacing", RealReference},
325 {"interword-spacing", RealReference},
326 {"direction", MagickDirectionOptions} } },
327 { "Equalize", { {"channel", MagickChannelOptions} } },
328 { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
329 {"red", RealReference}, {"green", RealReference},
330 {"blue", RealReference} } },
331 { "Map", { {"image", ImageReference},
332 {"dither-method", MagickDitherOptions} } },
333 { "MatteFloodfill", { {"geometry", StringReference},
334 {"x", IntegerReference}, {"y", IntegerReference},
335 {"opacity", StringReference}, {"bordercolor", StringReference},
336 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
337 { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
338 {"saturation", RealReference}, {"whiteness", RealReference},
339 {"brightness", RealReference}, {"lightness", RealReference},
340 {"blackness", RealReference} } },
341 { "Negate", { {"gray", MagickBooleanOptions},
342 {"channel", MagickChannelOptions} } },
343 { "Normalize", { {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500344 { "NumberColors", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000345 { "Opaque", { {"color", StringReference}, {"fill", StringReference},
346 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
347 {"invert", MagickBooleanOptions} } },
348 { "Quantize", { {"colors", IntegerReference},
349 {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
350 {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
351 {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
352 {"dither-method", MagickDitherOptions} } },
353 { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
354 {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
355 { "Segment", { {"geometry", StringReference},
356 {"cluster-threshold", RealReference},
357 {"smoothing-threshold", RealReference},
358 {"colorspace", MagickColorspaceOptions},
359 {"verbose", MagickBooleanOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500360 { "Signature", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000361 { "Solarize", { {"geometry", StringReference},
362 {"threshold", StringReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500363 { "Sync", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000364 { "Texture", { {"texture", ImageReference} } },
365 { "Evaluate", { {"value", RealReference},
366 {"operator", MagickEvaluateOptions},
367 {"channel", MagickChannelOptions} } },
368 { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
369 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
370 { "Threshold", { {"threshold", StringReference},
371 {"channel", MagickChannelOptions} } },
372 { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
373 {"sigma", RealReference} } },
374 { "Trim", { {"fuzz", StringReference} } },
375 { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
376 {"wavelength", RealReference},
377 {"interpolate", MagickInterpolateOptions} } },
378 { "Separate", { {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500379 { "Condense", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000380 { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
381 {"y", IntegerReference} } },
382 { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500383 { "Deconstruct", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000384 { "GaussianBlur", { {"geometry", StringReference},
385 {"radius", RealReference}, {"sigma", RealReference},
386 {"channel", MagickChannelOptions} } },
387 { "Convolve", { {"coefficients", ArrayReference},
388 {"channel", MagickChannelOptions}, {"bias", StringReference},
389 {"kernel", StringReference} } },
390 { "Profile", { {"name", StringReference}, {"profile", StringReference},
391 { "rendering-intent", MagickIntentOptions},
392 { "black-point-compensation", MagickBooleanOptions} } },
393 { "UnsharpMask", { {"geometry", StringReference},
394 {"radius", RealReference}, {"sigma", RealReference},
395 {"gain", RealReference}, {"threshold", RealReference},
396 {"channel", MagickChannelOptions} } },
397 { "MotionBlur", { {"geometry", StringReference},
398 {"radius", RealReference}, {"sigma", RealReference},
399 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
400 { "OrderedDither", { {"threshold", StringReference},
401 {"channel", MagickChannelOptions} } },
402 { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
403 {"height", IntegerReference} } },
404 { "Level", { {"levels", StringReference}, {"black-point", RealReference},
405 {"white-point", RealReference}, {"gamma", RealReference},
406 {"channel", MagickChannelOptions}, {"level", StringReference} } },
407 { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
408 { "AffineTransform", { {"affine", ArrayReference},
409 {"translate", StringReference}, {"scale", StringReference},
410 {"rotate", RealReference}, {"skewX", RealReference},
411 {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
412 {"background", StringReference} } },
413 { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
414 { "AdaptiveThreshold", { {"geometry", StringReference},
415 {"width", IntegerReference}, {"height", IntegerReference} } },
416 { "Resample", { {"density", StringReference}, {"x", RealReference},
417 {"y", RealReference}, {"filter", MagickFilterOptions},
418 {"support", RealReference } } },
419 { "Describe", { {"file", FileReference} } },
420 { "BlackThreshold", { {"threshold", StringReference},
421 {"channel", MagickChannelOptions} } },
422 { "WhiteThreshold", { {"threshold", StringReference},
423 {"channel", MagickChannelOptions} } },
cristy60c73c02014-03-25 12:09:58 +0000424 { "RotationalBlur", { {"geometry", StringReference},
425 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000426 { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
427 {"height", IntegerReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500428 { "Strip", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000429 { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
430 { "Channel", { {"channel", MagickChannelOptions} } },
431 { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
432 {"height", IntegerReference}, {"x", IntegerReference},
433 {"y", IntegerReference}, {"fuzz", StringReference},
434 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
435 { "Posterize", { {"levels", IntegerReference},
436 {"dither", MagickBooleanOptions} } },
437 { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
438 {"sigma", RealReference}, {"x", IntegerReference},
439 {"y", IntegerReference} } },
440 { "Identify", { {"file", FileReference}, {"features", StringReference},
441 {"unique", MagickBooleanOptions} } },
442 { "SepiaTone", { {"threshold", RealReference} } },
443 { "SigmoidalContrast", { {"geometry", StringReference},
444 {"contrast", RealReference}, {"mid-point", RealReference},
445 {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
446 { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
447 {"height", IntegerReference}, {"x", IntegerReference},
448 {"y", IntegerReference}, {"fuzz", StringReference},
449 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
450 { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
451 {"sigma", RealReference}, {"x", IntegerReference},
452 {"y", IntegerReference}, {"background", StringReference} } },
453 { "ContrastStretch", { {"levels", StringReference},
454 {"black-point", RealReference},{"white-point", RealReference},
455 {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500456 { "Sans0", { { (const char *) NULL, NullReference } } },
457 { "Sans1", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000458 { "AdaptiveSharpen", { {"geometry", StringReference},
459 {"radius", RealReference}, {"sigma", RealReference},
460 {"bias", RealReference}, {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500461 { "Transpose", { { (const char *) NULL, NullReference } } },
462 { "Transverse", { { (const char *) NULL, NullReference } } },
463 { "AutoOrient", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000464 { "AdaptiveBlur", { {"geometry", StringReference},
465 {"radius", RealReference}, {"sigma", RealReference},
466 {"channel", MagickChannelOptions} } },
467 { "Sketch", { {"geometry", StringReference},
468 {"radius", RealReference}, {"sigma", RealReference},
469 {"angle", RealReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500470 { "UniqueColors", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000471 { "AdaptiveResize", { {"geometry", StringReference},
472 {"width", IntegerReference}, {"height", IntegerReference},
473 {"filter", MagickFilterOptions}, {"support", StringReference },
474 {"blur", RealReference } } },
475 { "ClipMask", { {"mask", ImageReference} } },
476 { "LinearStretch", { {"levels", StringReference},
477 {"black-point", RealReference},{"white-point", RealReference} } },
478 { "ColorMatrix", { {"matrix", ArrayReference} } },
479 { "Mask", { {"mask", ImageReference} } },
480 { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
481 {"font", StringReference}, {"stroke", StringReference},
482 {"fill", StringReference}, {"strokewidth", RealReference},
483 {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
484 {"background", StringReference},
485 {"interpolate", MagickInterpolateOptions} } },
486 { "FloodfillPaint", { {"geometry", StringReference},
487 {"x", IntegerReference}, {"y", IntegerReference},
488 {"fill", StringReference}, {"bordercolor", StringReference},
489 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
490 {"invert", MagickBooleanOptions} } },
491 { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
492 {"virtual-pixel", MagickVirtualPixelOptions},
493 {"best-fit", MagickBooleanOptions} } },
494 { "Clut", { {"image", ImageReference},
495 {"interpolate", MagickInterpolateOptions},
496 {"channel", MagickChannelOptions} } },
497 { "LiquidRescale", { {"geometry", StringReference},
498 {"width", IntegerReference}, {"height", IntegerReference},
499 {"delta-x", RealReference}, {"rigidity", RealReference } } },
500 { "Encipher", { {"passphrase", StringReference} } },
501 { "Decipher", { {"passphrase", StringReference} } },
502 { "Deskew", { {"geometry", StringReference},
503 {"threshold", StringReference} } },
504 { "Remap", { {"image", ImageReference},
505 {"dither-method", MagickDitherOptions} } },
506 { "SparseColor", { {"points", ArrayReference},
507 {"method", MagickSparseColorOptions},
508 {"virtual-pixel", MagickVirtualPixelOptions},
509 {"channel", MagickChannelOptions} } },
510 { "Function", { {"parameters", ArrayReference},
511 {"function", MagickFunctionOptions},
512 {"virtual-pixel", MagickVirtualPixelOptions} } },
513 { "SelectiveBlur", { {"geometry", StringReference},
514 {"radius", RealReference}, {"sigma", RealReference},
515 {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
516 { "HaldClut", { {"image", ImageReference},
517 {"channel", MagickChannelOptions} } },
518 { "BlueShift", { {"factor", StringReference} } },
519 { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
520 { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
521 { "ColorDecisionList", {
522 {"color-correction-collection", StringReference} } },
523 { "AutoGamma", { {"channel", MagickChannelOptions} } },
524 { "AutoLevel", { {"channel", MagickChannelOptions} } },
525 { "LevelColors", { {"invert", MagickBooleanOptions},
526 {"black-point", StringReference}, {"white-point", StringReference},
527 {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
528 { "Clamp", { {"channel", MagickChannelOptions} } },
529 { "BrightnessContrast", { {"levels", StringReference},
530 {"brightness", RealReference},{"contrast", RealReference},
531 {"channel", MagickChannelOptions} } },
532 { "Morphology", { {"kernel", StringReference},
533 {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
534 {"iterations", IntegerReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000535 { "Mode", { {"geometry", StringReference},
536 {"width", IntegerReference},{"height", IntegerReference},
537 {"channel", MagickChannelOptions} } },
538 { "Statistic", { {"geometry", StringReference},
539 {"width", IntegerReference},{"height", IntegerReference},
540 {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
541 { "Perceptible", { {"epsilon", RealReference},
542 {"channel", MagickChannelOptions} } },
543 { "Poly", { {"terms", ArrayReference},
544 {"channel", MagickChannelOptions} } },
545 { "Grayscale", { {"method", MagickNoiseOptions} } },
cristy4ceadb82014-03-29 15:30:43 +0000546 { "CannyEdge", { {"geometry", StringReference},
547 {"radius", RealReference}, {"sigma", RealReference},
cristycfe7bf02014-04-04 15:31:52 +0000548 {"lower-percent", RealReference}, {"upper-percent", RealReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000549 { "HoughLine", { {"geometry", StringReference},
cristy4e215022014-04-19 18:02:35 +0000550 {"width", IntegerReference}, {"height", IntegerReference},
551 {"threshold", IntegerReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000552 { "MeanShift", { {"geometry", StringReference},
553 {"width", IntegerReference}, {"height", IntegerReference},
cristy1309fc32014-04-26 18:48:37 +0000554 {"distance", RealReference} } },
cristy3b207f82014-09-27 14:21:20 +0000555 { "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
556 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
Cristy2ca0e9a2016-01-01 08:36:14 -0500557 { "ConnectedComponents", { {"connectivity", IntegerReference} } },
cristyf3a724a2015-06-25 13:02:53 +0000558 { "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
559 {"width", IntegerReference}, {"height", IntegerReference},
560 {"x", IntegerReference}, {"y", IntegerReference},
561 {"gravity", MagickGravityOptions}, {"offset", StringReference},
562 {"dx", IntegerReference}, {"dy", IntegerReference} } },
Cristy5488c982016-02-13 14:07:50 -0500563 { "Color", { {"color", StringReference} } },
Cristyc1759412016-02-27 12:17:58 -0500564 { "WaveletDenoise", { {"geometry", StringReference},
565 {"threshold", RealReference}, {"softness", RealReference},
Cristy2d830ed2016-02-21 10:54:16 -0500566 {"channel", MagickChannelOptions} } },
Cristy99a57162016-12-05 11:47:57 -0500567 { "Colorspace", { {"colorspace", MagickColorspaceOptions} } },
Cristy53353872017-07-02 12:24:24 -0400568 { "AutoThreshold", { {"method", MagickAutoThresholdOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000569 };
570
571static SplayTreeInfo
572 *magick_registry = (SplayTreeInfo *) NULL;
573
574/*
575 Forward declarations.
576*/
577static Image
578 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
579
580static ssize_t
581 strEQcase(const char *,const char *);
582
583/*
584%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
585% %
586% %
587% %
588% C l o n e P a c k a g e I n f o %
589% %
590% %
591% %
592%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
593%
594% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
595% a new one.
596%
597% The format of the ClonePackageInfo routine is:
598%
599% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
600% exception)
601%
602% A description of each parameter follows:
603%
604% o info: a structure of type info.
605%
606% o exception: Return any errors or warnings in this structure.
607%
608*/
609static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
610 ExceptionInfo *exception)
611{
612 struct PackageInfo
613 *clone_info;
614
615 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
616 if (clone_info == (struct PackageInfo *) NULL)
617 {
618 ThrowPerlException(exception,ResourceLimitError,
619 "UnableToClonePackageInfo",PackageName);
620 return((struct PackageInfo *) NULL);
621 }
622 if (info == (struct PackageInfo *) NULL)
623 {
624 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
625 return(clone_info);
626 }
627 *clone_info=(*info);
628 clone_info->image_info=CloneImageInfo(info->image_info);
629 return(clone_info);
630}
631
632/*
633%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
634% %
635% %
636% %
637% c o n s t a n t %
638% %
639% %
640% %
641%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
642%
643% constant() returns a double value for the specified name.
644%
645% The format of the constant routine is:
646%
647% double constant(char *name,ssize_t sans)
648%
649% A description of each parameter follows:
650%
651% o value: Method constant returns a double value for the specified name.
652%
653% o name: The name of the constant.
654%
655% o sans: This integer value is not used.
656%
657*/
658static double constant(char *name,ssize_t sans)
659{
660 (void) sans;
661 errno=0;
662 switch (*name)
663 {
664 case 'B':
665 {
666 if (strEQ(name,"BlobError"))
667 return(BlobError);
668 if (strEQ(name,"BlobWarning"))
669 return(BlobWarning);
670 break;
671 }
672 case 'C':
673 {
674 if (strEQ(name,"CacheError"))
675 return(CacheError);
676 if (strEQ(name,"CacheWarning"))
677 return(CacheWarning);
678 if (strEQ(name,"CoderError"))
679 return(CoderError);
680 if (strEQ(name,"CoderWarning"))
681 return(CoderWarning);
682 if (strEQ(name,"ConfigureError"))
683 return(ConfigureError);
684 if (strEQ(name,"ConfigureWarning"))
685 return(ConfigureWarning);
686 if (strEQ(name,"CorruptImageError"))
687 return(CorruptImageError);
688 if (strEQ(name,"CorruptImageWarning"))
689 return(CorruptImageWarning);
690 break;
691 }
692 case 'D':
693 {
694 if (strEQ(name,"DelegateError"))
695 return(DelegateError);
696 if (strEQ(name,"DelegateWarning"))
697 return(DelegateWarning);
698 if (strEQ(name,"DrawError"))
699 return(DrawError);
700 if (strEQ(name,"DrawWarning"))
701 return(DrawWarning);
702 break;
703 }
704 case 'E':
705 {
706 if (strEQ(name,"ErrorException"))
707 return(ErrorException);
708 if (strEQ(name,"ExceptionError"))
709 return(CoderError);
710 if (strEQ(name,"ExceptionWarning"))
711 return(CoderWarning);
712 break;
713 }
714 case 'F':
715 {
716 if (strEQ(name,"FatalErrorException"))
717 return(FatalErrorException);
718 if (strEQ(name,"FileOpenError"))
719 return(FileOpenError);
720 if (strEQ(name,"FileOpenWarning"))
721 return(FileOpenWarning);
722 break;
723 }
724 case 'I':
725 {
726 if (strEQ(name,"ImageError"))
727 return(ImageError);
728 if (strEQ(name,"ImageWarning"))
729 return(ImageWarning);
730 break;
731 }
732 case 'M':
733 {
734 if (strEQ(name,"MaxRGB"))
735 return(QuantumRange);
736 if (strEQ(name,"MissingDelegateError"))
737 return(MissingDelegateError);
738 if (strEQ(name,"MissingDelegateWarning"))
739 return(MissingDelegateWarning);
740 if (strEQ(name,"ModuleError"))
741 return(ModuleError);
742 if (strEQ(name,"ModuleWarning"))
743 return(ModuleWarning);
744 break;
745 }
746 case 'O':
747 {
748 if (strEQ(name,"Opaque"))
749 return(OpaqueAlpha);
750 if (strEQ(name,"OptionError"))
751 return(OptionError);
752 if (strEQ(name,"OptionWarning"))
753 return(OptionWarning);
754 break;
755 }
756 case 'Q':
757 {
758 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
759 return(MAGICKCORE_QUANTUM_DEPTH);
760 if (strEQ(name,"QuantumDepth"))
761 return(MAGICKCORE_QUANTUM_DEPTH);
762 if (strEQ(name,"QuantumRange"))
763 return(QuantumRange);
764 break;
765 }
766 case 'R':
767 {
768 if (strEQ(name,"ResourceLimitError"))
769 return(ResourceLimitError);
770 if (strEQ(name,"ResourceLimitWarning"))
771 return(ResourceLimitWarning);
772 if (strEQ(name,"RegistryError"))
773 return(RegistryError);
774 if (strEQ(name,"RegistryWarning"))
775 return(RegistryWarning);
776 break;
777 }
778 case 'S':
779 {
780 if (strEQ(name,"StreamError"))
781 return(StreamError);
782 if (strEQ(name,"StreamWarning"))
783 return(StreamWarning);
784 if (strEQ(name,"Success"))
785 return(0);
786 break;
787 }
788 case 'T':
789 {
790 if (strEQ(name,"Transparent"))
791 return(TransparentAlpha);
792 if (strEQ(name,"TypeError"))
793 return(TypeError);
794 if (strEQ(name,"TypeWarning"))
795 return(TypeWarning);
796 break;
797 }
798 case 'W':
799 {
800 if (strEQ(name,"WarningException"))
801 return(WarningException);
802 break;
803 }
804 case 'X':
805 {
806 if (strEQ(name,"XServerError"))
807 return(XServerError);
808 if (strEQ(name,"XServerWarning"))
809 return(XServerWarning);
810 break;
811 }
812 }
813 errno=EINVAL;
814 return(0);
815}
816
817/*
818%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
819% %
820% %
821% %
822% D e s t r o y P a c k a g e I n f o %
823% %
824% %
825% %
826%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
827%
828% Method DestroyPackageInfo frees a previously created info structure.
829%
830% The format of the DestroyPackageInfo routine is:
831%
832% DestroyPackageInfo(struct PackageInfo *info)
833%
834% A description of each parameter follows:
835%
836% o info: a structure of type info.
837%
838*/
839static void DestroyPackageInfo(struct PackageInfo *info)
840{
841 info->image_info=DestroyImageInfo(info->image_info);
842 info=(struct PackageInfo *) RelinquishMagickMemory(info);
843}
844
845/*
846%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
847% %
848% %
849% %
850% G e t L i s t %
851% %
852% %
853% %
854%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
855%
856% Method GetList is recursively called by SetupList to traverse the
857% Image__Magick reference. If building an reference_vector (see SetupList),
858% *current is the current position in *reference_vector and *last is the final
859% entry in *reference_vector.
860%
861% The format of the GetList routine is:
862%
863% GetList(info)
864%
865% A description of each parameter follows:
866%
867% o info: a structure of type info.
868%
869*/
870static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
871 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
872{
873 Image
874 *image;
875
876 if (reference == (SV *) NULL)
877 return(NULL);
878 switch (SvTYPE(reference))
879 {
880 case SVt_PVAV:
881 {
882 AV
883 *av;
884
885 Image
886 *head,
887 *previous;
888
889 register ssize_t
890 i;
891
892 ssize_t
893 n;
894
895 /*
896 Array of images.
897 */
898 previous=(Image *) NULL;
899 head=(Image *) NULL;
900 av=(AV *) reference;
901 n=av_len(av);
902 for (i=0; i <= n; i++)
903 {
904 SV
905 **rv;
906
907 rv=av_fetch(av,i,0);
908 if (rv && *rv && sv_isobject(*rv))
909 {
910 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
911 exception);
912 if (image == (Image *) NULL)
913 continue;
914 if (image == previous)
915 {
916 image=CloneImage(image,0,0,MagickTrue,exception);
917 if (image == (Image *) NULL)
918 return(NULL);
919 }
920 image->previous=previous;
921 *(previous ? &previous->next : &head)=image;
922 for (previous=image; previous->next; previous=previous->next) ;
923 }
924 }
925 return(head);
926 }
927 case SVt_PVMG:
928 {
929 /*
930 Blessed scalar, one image.
931 */
932 image=INT2PTR(Image *,SvIV(reference));
933 if (image == (Image *) NULL)
934 return(NULL);
935 image->previous=(Image *) NULL;
936 image->next=(Image *) NULL;
937 if (reference_vector)
938 {
939 if (*current == *last)
940 {
941 *last+=256;
942 if (*reference_vector == (SV **) NULL)
943 *reference_vector=(SV **) AcquireQuantumMemory(*last,
944 sizeof(*reference_vector));
945 else
946 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
947 *last,sizeof(*reference_vector));
948 }
949 if (*reference_vector == (SV **) NULL)
950 {
951 ThrowPerlException(exception,ResourceLimitError,
952 "MemoryAllocationFailed",PackageName);
953 return((Image *) NULL);
954 }
955 (*reference_vector)[*current]=reference;
956 (*reference_vector)[++(*current)]=NULL;
957 }
958 return(image);
959 }
960 default:
961 break;
962 }
963 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
964 (double) SvTYPE(reference));
965 return((Image *) NULL);
966}
967
968/*
969%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
970% %
971% %
972% %
973% G e t P a c k a g e I n f o %
974% %
975% %
976% %
977%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
978%
979% Method GetPackageInfo looks up or creates an info structure for the given
980% Image__Magick reference. If it does create a new one, the information in
981% package_info is used to initialize it.
982%
983% The format of the GetPackageInfo routine is:
984%
985% struct PackageInfo *GetPackageInfo(void *reference,
986% struct PackageInfo *package_info,ExceptionInfo *exception)
987%
988% A description of each parameter follows:
989%
990% o info: a structure of type info.
991%
992% o exception: Return any errors or warnings in this structure.
993%
994*/
995static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
996 struct PackageInfo *package_info,ExceptionInfo *exception)
997{
998 char
cristy151b66d2015-04-15 10:50:31 +0000999 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00001000
1001 struct PackageInfo
1002 *clone_info;
1003
1004 SV
1005 *sv;
1006
cristy151b66d2015-04-15 10:50:31 +00001007 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00001008 PackageName,XS_VERSION,reference);
1009 sv=perl_get_sv(message,(TRUE | 0x02));
1010 if (sv == (SV *) NULL)
1011 {
1012 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1013 message);
1014 return(package_info);
1015 }
1016 if (SvREFCNT(sv) == 0)
1017 (void) SvREFCNT_inc(sv);
1018 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1019 return(clone_info);
1020 clone_info=ClonePackageInfo(package_info,exception);
1021 sv_setiv(sv,PTR2IV(clone_info));
1022 return(clone_info);
1023}
1024
1025/*
1026%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1027% %
1028% %
1029% %
1030% S e t A t t r i b u t e %
1031% %
1032% %
1033% %
1034%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1035%
1036% SetAttribute() sets the attribute to the value in sval. This can change
1037% either or both of image or info.
1038%
1039% The format of the SetAttribute routine is:
1040%
1041% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1042% SV *sval,ExceptionInfo *exception)
1043%
1044% A description of each parameter follows:
1045%
1046% o list: a list of strings.
1047%
1048% o string: a character string.
1049%
1050*/
1051
1052static double SiPrefixToDoubleInterval(const char *string,const double interval)
1053{
1054 char
1055 *q;
1056
1057 double
1058 value;
1059
1060 value=InterpretSiPrefixValue(string,&q);
1061 if (*q == '%')
1062 value*=interval/100.0;
1063 return(value);
1064}
1065
1066static inline double StringToDouble(const char *string,char **sentinal)
1067{
1068 return(InterpretLocaleValue(string,sentinal));
1069}
1070
1071static double StringToDoubleInterval(const char *string,const double interval)
1072{
1073 char
1074 *q;
1075
1076 double
1077 value;
1078
1079 value=InterpretLocaleValue(string,&q);
1080 if (*q == '%')
1081 value*=interval/100.0;
1082 return(value);
1083}
1084
1085static inline ssize_t StringToLong(const char *value)
1086{
1087 return(strtol(value,(char **) NULL,10));
1088}
1089
1090static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1091 const char *attribute,SV *sval,ExceptionInfo *exception)
1092{
1093 GeometryInfo
1094 geometry_info;
1095
1096 long
1097 x,
1098 y;
1099
1100 PixelInfo
1101 pixel;
1102
1103 MagickStatusType
1104 flags;
1105
1106 PixelInfo
1107 *color,
1108 target_color;
1109
1110 ssize_t
1111 sp;
1112
1113 switch (*attribute)
1114 {
1115 case 'A':
1116 case 'a':
1117 {
1118 if (LocaleCompare(attribute,"adjoin") == 0)
1119 {
1120 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1121 SvPV(sval,na)) : SvIV(sval);
1122 if (sp < 0)
1123 {
1124 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1125 SvPV(sval,na));
1126 break;
1127 }
1128 if (info)
1129 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1130 break;
1131 }
1132 if (LocaleCompare(attribute,"alpha") == 0)
1133 {
1134 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1135 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1136 if (sp < 0)
1137 {
1138 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1139 SvPV(sval,na));
1140 break;
1141 }
1142 for ( ; image; image=image->next)
1143 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1144 exception);
1145 break;
1146 }
1147 if (LocaleCompare(attribute,"antialias") == 0)
1148 {
1149 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1150 SvPV(sval,na)) : SvIV(sval);
1151 if (sp < 0)
1152 {
1153 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1154 SvPV(sval,na));
1155 break;
1156 }
1157 if (info)
1158 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1159 break;
1160 }
1161 if (LocaleCompare(attribute,"area-limit") == 0)
1162 {
1163 MagickSizeType
1164 limit;
1165
1166 limit=MagickResourceInfinity;
1167 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1168 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1169 100.0);
1170 (void) SetMagickResourceLimit(AreaResource,limit);
1171 break;
1172 }
1173 if (LocaleCompare(attribute,"attenuate") == 0)
1174 {
1175 if (info)
1176 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1177 break;
1178 }
1179 if (LocaleCompare(attribute,"authenticate") == 0)
1180 {
1181 if (info)
1182 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1183 break;
1184 }
1185 if (info)
1186 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1187 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001188 {
1189 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstra337c9bc2017-04-03 16:04:21 +02001190 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001191 }
cristy4a3ce0a2013-08-03 20:06:59 +00001192 break;
1193 }
1194 case 'B':
1195 case 'b':
1196 {
1197 if (LocaleCompare(attribute,"background") == 0)
1198 {
1199 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1200 exception);
1201 if (info)
1202 info->image_info->background_color=target_color;
1203 for ( ; image; image=image->next)
1204 image->background_color=target_color;
1205 break;
1206 }
1207 if (LocaleCompare(attribute,"blue-primary") == 0)
1208 {
1209 for ( ; image; image=image->next)
1210 {
1211 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1212 image->chromaticity.blue_primary.x=geometry_info.rho;
1213 image->chromaticity.blue_primary.y=geometry_info.sigma;
1214 if ((flags & SigmaValue) == 0)
1215 image->chromaticity.blue_primary.y=
1216 image->chromaticity.blue_primary.x;
1217 }
1218 break;
1219 }
1220 if (LocaleCompare(attribute,"bordercolor") == 0)
1221 {
1222 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1223 exception);
1224 if (info)
1225 info->image_info->border_color=target_color;
1226 for ( ; image; image=image->next)
1227 image->border_color=target_color;
1228 break;
1229 }
1230 if (info)
1231 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1232 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001233 {
1234 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001235 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001236 }
cristy4a3ce0a2013-08-03 20:06:59 +00001237 break;
1238 }
1239 case 'C':
1240 case 'c':
1241 {
1242 if (LocaleCompare(attribute,"cache-threshold") == 0)
1243 {
1244 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1245 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1246 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1247 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1248 break;
1249 }
1250 if (LocaleCompare(attribute,"clip-mask") == 0)
1251 {
1252 Image
1253 *clip_mask;
1254
1255 clip_mask=(Image *) NULL;
1256 if (SvPOK(sval))
1257 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1258 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001259 SetImageMask(image,ReadPixelMask,clip_mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001260 break;
1261 }
1262 if (LocaleNCompare(attribute,"colormap",8) == 0)
1263 {
1264 for ( ; image; image=image->next)
1265 {
1266 int
1267 items;
1268
1269 long
1270 i;
1271
1272 if (image->storage_class == DirectClass)
1273 continue;
1274 i=0;
1275 items=sscanf(attribute,"%*[^[][%ld",&i);
1276 (void) items;
1277 if (i > (ssize_t) image->colors)
1278 i%=image->colors;
1279 if ((strchr(SvPV(sval,na),',') == 0) ||
1280 (strchr(SvPV(sval,na),')') != 0))
1281 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1282 image->colormap+i,exception);
1283 else
1284 {
1285 color=image->colormap+i;
1286 pixel.red=color->red;
1287 pixel.green=color->green;
1288 pixel.blue=color->blue;
1289 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1290 pixel.red=geometry_info.rho;
1291 pixel.green=geometry_info.sigma;
1292 pixel.blue=geometry_info.xi;
1293 color->red=ClampToQuantum(pixel.red);
1294 color->green=ClampToQuantum(pixel.green);
1295 color->blue=ClampToQuantum(pixel.blue);
1296 }
1297 }
1298 break;
1299 }
1300 if (LocaleCompare(attribute,"colorspace") == 0)
1301 {
1302 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1303 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1304 if (sp < 0)
1305 {
1306 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1307 SvPV(sval,na));
1308 break;
1309 }
1310 for ( ; image; image=image->next)
Cristy59262d92016-12-05 15:21:50 -05001311 (void) SetImageColorspace(image,(ColorspaceType) sp,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001312 break;
1313 }
1314 if (LocaleCompare(attribute,"comment") == 0)
1315 {
1316 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001317 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001318 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001319 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001320 break;
1321 }
1322 if (LocaleCompare(attribute,"compression") == 0)
1323 {
1324 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1325 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1326 if (sp < 0)
1327 {
1328 ThrowPerlException(exception,OptionError,
1329 "UnrecognizedImageCompression",SvPV(sval,na));
1330 break;
1331 }
1332 if (info)
1333 info->image_info->compression=(CompressionType) sp;
1334 for ( ; image; image=image->next)
1335 image->compression=(CompressionType) sp;
1336 break;
1337 }
1338 if (info)
1339 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1340 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001341 {
1342 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001343 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001344 }
cristy4a3ce0a2013-08-03 20:06:59 +00001345 break;
1346 }
1347 case 'D':
1348 case 'd':
1349 {
1350 if (LocaleCompare(attribute,"debug") == 0)
1351 {
1352 SetLogEventMask(SvPV(sval,na));
1353 break;
1354 }
1355 if (LocaleCompare(attribute,"delay") == 0)
1356 {
1357 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1358 for ( ; image; image=image->next)
1359 {
1360 image->delay=(size_t) floor(geometry_info.rho+0.5);
1361 if ((flags & SigmaValue) != 0)
1362 image->ticks_per_second=(ssize_t)
1363 floor(geometry_info.sigma+0.5);
1364 }
1365 break;
1366 }
1367 if (LocaleCompare(attribute,"disk-limit") == 0)
1368 {
1369 MagickSizeType
1370 limit;
1371
1372 limit=MagickResourceInfinity;
1373 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1374 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1375 100.0);
1376 (void) SetMagickResourceLimit(DiskResource,limit);
1377 break;
1378 }
1379 if (LocaleCompare(attribute,"density") == 0)
1380 {
1381 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1382 {
1383 ThrowPerlException(exception,OptionError,"MissingGeometry",
1384 SvPV(sval,na));
1385 break;
1386 }
1387 if (info)
1388 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1389 for ( ; image; image=image->next)
1390 {
1391 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1392 image->resolution.x=geometry_info.rho;
1393 image->resolution.y=geometry_info.sigma;
1394 if ((flags & SigmaValue) == 0)
1395 image->resolution.y=image->resolution.x;
1396 }
1397 break;
1398 }
1399 if (LocaleCompare(attribute,"depth") == 0)
1400 {
1401 if (info)
1402 info->image_info->depth=SvIV(sval);
1403 for ( ; image; image=image->next)
1404 (void) SetImageDepth(image,SvIV(sval),exception);
1405 break;
1406 }
1407 if (LocaleCompare(attribute,"dispose") == 0)
1408 {
1409 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1410 SvPV(sval,na)) : SvIV(sval);
1411 if (sp < 0)
1412 {
1413 ThrowPerlException(exception,OptionError,
1414 "UnrecognizedDisposeMethod",SvPV(sval,na));
1415 break;
1416 }
1417 for ( ; image; image=image->next)
1418 image->dispose=(DisposeType) sp;
1419 break;
1420 }
1421 if (LocaleCompare(attribute,"dither") == 0)
1422 {
1423 if (info)
1424 {
1425 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1426 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1427 if (sp < 0)
1428 {
1429 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1430 SvPV(sval,na));
1431 break;
1432 }
1433 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1434 }
1435 break;
1436 }
1437 if (LocaleCompare(attribute,"display") == 0)
1438 {
1439 display:
1440 if (info)
1441 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1442 break;
1443 }
1444 if (info)
1445 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1446 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001447 {
1448 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001449 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001450 }
cristy4a3ce0a2013-08-03 20:06:59 +00001451 break;
1452 }
1453 case 'E':
1454 case 'e':
1455 {
1456 if (LocaleCompare(attribute,"endian") == 0)
1457 {
1458 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1459 SvPV(sval,na)) : SvIV(sval);
1460 if (sp < 0)
1461 {
1462 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1463 SvPV(sval,na));
1464 break;
1465 }
1466 if (info)
1467 info->image_info->endian=(EndianType) sp;
1468 for ( ; image; image=image->next)
1469 image->endian=(EndianType) sp;
1470 break;
1471 }
1472 if (LocaleCompare(attribute,"extract") == 0)
1473 {
1474 /*
1475 Set image extract geometry.
1476 */
1477 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1478 break;
1479 }
1480 if (info)
1481 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1482 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001483 {
1484 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001485 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001486 }
cristy4a3ce0a2013-08-03 20:06:59 +00001487 break;
1488 }
1489 case 'F':
1490 case 'f':
1491 {
1492 if (LocaleCompare(attribute,"filename") == 0)
1493 {
1494 if (info)
1495 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001496 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001497 for ( ; image; image=image->next)
1498 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001499 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001500 break;
1501 }
1502 if (LocaleCompare(attribute,"file") == 0)
1503 {
1504 FILE
1505 *file;
1506
1507 PerlIO
1508 *io_info;
1509
1510 if (info == (struct PackageInfo *) NULL)
1511 break;
1512 io_info=IoIFP(sv_2io(sval));
1513 if (io_info == (PerlIO *) NULL)
1514 {
1515 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1516 PackageName);
1517 break;
1518 }
1519 file=PerlIO_findFILE(io_info);
1520 if (file == (FILE *) NULL)
1521 {
1522 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1523 PackageName);
1524 break;
1525 }
1526 SetImageInfoFile(info->image_info,file);
1527 break;
1528 }
1529 if (LocaleCompare(attribute,"fill") == 0)
1530 {
1531 if (info)
1532 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1533 break;
1534 }
1535 if (LocaleCompare(attribute,"font") == 0)
1536 {
1537 if (info)
1538 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1539 break;
1540 }
1541 if (LocaleCompare(attribute,"foreground") == 0)
1542 break;
1543 if (LocaleCompare(attribute,"fuzz") == 0)
1544 {
1545 if (info)
1546 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1547 QuantumRange+1.0);
1548 for ( ; image; image=image->next)
1549 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1550 QuantumRange+1.0);
1551 break;
1552 }
1553 if (info)
1554 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1555 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001556 {
1557 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001558 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001559 }
cristy4a3ce0a2013-08-03 20:06:59 +00001560 break;
1561 }
1562 case 'G':
1563 case 'g':
1564 {
1565 if (LocaleCompare(attribute,"gamma") == 0)
1566 {
1567 for ( ; image; image=image->next)
1568 image->gamma=SvNV(sval);
1569 break;
1570 }
1571 if (LocaleCompare(attribute,"gravity") == 0)
1572 {
1573 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1574 SvPV(sval,na)) : SvIV(sval);
1575 if (sp < 0)
1576 {
1577 ThrowPerlException(exception,OptionError,
1578 "UnrecognizedGravityType",SvPV(sval,na));
1579 break;
1580 }
1581 if (info)
1582 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1583 for ( ; image; image=image->next)
1584 image->gravity=(GravityType) sp;
1585 break;
1586 }
1587 if (LocaleCompare(attribute,"green-primary") == 0)
1588 {
1589 for ( ; image; image=image->next)
1590 {
1591 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1592 image->chromaticity.green_primary.x=geometry_info.rho;
1593 image->chromaticity.green_primary.y=geometry_info.sigma;
1594 if ((flags & SigmaValue) == 0)
1595 image->chromaticity.green_primary.y=
1596 image->chromaticity.green_primary.x;
1597 }
1598 break;
1599 }
1600 if (info)
1601 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1602 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001603 {
1604 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001605 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001606 }
cristy4a3ce0a2013-08-03 20:06:59 +00001607 break;
1608 }
1609 case 'I':
1610 case 'i':
1611 {
1612 if (LocaleNCompare(attribute,"index",5) == 0)
1613 {
1614 int
1615 items;
1616
1617 long
1618 index;
1619
1620 register Quantum
1621 *q;
1622
1623 CacheView
1624 *image_view;
1625
1626 for ( ; image; image=image->next)
1627 {
1628 if (image->storage_class != PseudoClass)
1629 continue;
1630 x=0;
1631 y=0;
1632 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1633 (void) items;
1634 image_view=AcquireAuthenticCacheView(image,exception);
1635 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1636 if (q != (Quantum *) NULL)
1637 {
1638 items=sscanf(SvPV(sval,na),"%ld",&index);
1639 if ((index >= 0) && (index < (ssize_t) image->colors))
1640 SetPixelIndex(image,index,q);
1641 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1642 }
1643 image_view=DestroyCacheView(image_view);
1644 }
1645 break;
1646 }
1647 if (LocaleCompare(attribute,"iterations") == 0)
1648 {
1649 iterations:
1650 for ( ; image; image=image->next)
1651 image->iterations=SvIV(sval);
1652 break;
1653 }
1654 if (LocaleCompare(attribute,"interlace") == 0)
1655 {
1656 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1657 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1658 if (sp < 0)
1659 {
1660 ThrowPerlException(exception,OptionError,
1661 "UnrecognizedInterlaceType",SvPV(sval,na));
1662 break;
1663 }
1664 if (info)
1665 info->image_info->interlace=(InterlaceType) sp;
1666 for ( ; image; image=image->next)
1667 image->interlace=(InterlaceType) sp;
1668 break;
1669 }
1670 if (info)
1671 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1672 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001673 {
1674 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001675 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001676 }
cristy4a3ce0a2013-08-03 20:06:59 +00001677 break;
1678 }
1679 case 'L':
1680 case 'l':
1681 {
1682 if (LocaleCompare(attribute,"label") == 0)
1683 {
1684 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001685 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001686 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001687 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001688 break;
1689 }
1690 if (LocaleCompare(attribute,"loop") == 0)
1691 goto iterations;
1692 if (info)
1693 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1694 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001695 {
1696 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001697 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001698 }
cristy4a3ce0a2013-08-03 20:06:59 +00001699 break;
1700 }
1701 case 'M':
1702 case 'm':
1703 {
1704 if (LocaleCompare(attribute,"magick") == 0)
1705 {
1706 if (info)
Cristyb5b1f5d2017-03-31 16:42:35 -04001707 (void) FormatLocaleString(info->image_info->filename,
1708 MagickPathExtent,"%s:",SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001709 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001710 (void) CopyMagickString(image->magick,SvPV(sval,na),
1711 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001712 break;
1713 }
1714 if (LocaleCompare(attribute,"map-limit") == 0)
1715 {
1716 MagickSizeType
1717 limit;
1718
1719 limit=MagickResourceInfinity;
1720 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1721 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1722 100.0);
1723 (void) SetMagickResourceLimit(MapResource,limit);
1724 break;
1725 }
1726 if (LocaleCompare(attribute,"mask") == 0)
1727 {
1728 Image
1729 *mask;
1730
1731 mask=(Image *) NULL;
1732 if (SvPOK(sval))
1733 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1734 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001735 SetImageMask(image,ReadPixelMask,mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001736 break;
1737 }
1738 if (LocaleCompare(attribute,"mattecolor") == 0)
1739 {
1740 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1741 exception);
1742 if (info)
Cristy8645e042016-02-03 16:35:29 -05001743 info->image_info->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001744 for ( ; image; image=image->next)
Cristy8645e042016-02-03 16:35:29 -05001745 image->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001746 break;
1747 }
1748 if (LocaleCompare(attribute,"matte") == 0)
1749 {
1750 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1751 SvPV(sval,na)) : SvIV(sval);
1752 if (sp < 0)
1753 {
1754 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1755 SvPV(sval,na));
1756 break;
1757 }
1758 for ( ; image; image=image->next)
1759 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1760 break;
1761 }
1762 if (LocaleCompare(attribute,"memory-limit") == 0)
1763 {
1764 MagickSizeType
1765 limit;
1766
1767 limit=MagickResourceInfinity;
1768 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1769 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1770 100.0);
1771 (void) SetMagickResourceLimit(MemoryResource,limit);
1772 break;
1773 }
1774 if (LocaleCompare(attribute,"monochrome") == 0)
1775 {
1776 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1777 SvPV(sval,na)) : SvIV(sval);
1778 if (sp < 0)
1779 {
1780 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1781 SvPV(sval,na));
1782 break;
1783 }
1784 if (info)
1785 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1786 for ( ; image; image=image->next)
1787 (void) SetImageType(image,BilevelType,exception);
1788 break;
1789 }
1790 if (info)
1791 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1792 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001793 {
1794 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001795 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001796 }
cristy4a3ce0a2013-08-03 20:06:59 +00001797 break;
1798 }
1799 case 'O':
1800 case 'o':
1801 {
1802 if (LocaleCompare(attribute,"option") == 0)
1803 {
1804 if (info)
1805 DefineImageOption(info->image_info,SvPV(sval,na));
1806 break;
1807 }
1808 if (LocaleCompare(attribute,"orientation") == 0)
1809 {
1810 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1811 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1812 if (sp < 0)
1813 {
1814 ThrowPerlException(exception,OptionError,
1815 "UnrecognizedOrientationType",SvPV(sval,na));
1816 break;
1817 }
1818 if (info)
1819 info->image_info->orientation=(OrientationType) sp;
1820 for ( ; image; image=image->next)
1821 image->orientation=(OrientationType) sp;
1822 break;
1823 }
1824 if (info)
1825 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1826 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001827 {
1828 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001829 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001830 }
cristy4a3ce0a2013-08-03 20:06:59 +00001831 break;
1832 }
1833 case 'P':
1834 case 'p':
1835 {
1836 if (LocaleCompare(attribute,"page") == 0)
1837 {
1838 char
1839 *geometry;
1840
1841 geometry=GetPageGeometry(SvPV(sval,na));
1842 if (info)
1843 (void) CloneString(&info->image_info->page,geometry);
1844 for ( ; image; image=image->next)
1845 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1846 geometry=(char *) RelinquishMagickMemory(geometry);
1847 break;
1848 }
1849 if (LocaleNCompare(attribute,"pixel",5) == 0)
1850 {
1851 int
1852 items;
1853
1854 PixelInfo
1855 pixel;
1856
1857 register Quantum
1858 *q;
1859
1860 CacheView
1861 *image_view;
1862
1863 for ( ; image; image=image->next)
1864 {
1865 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1866 break;
1867 x=0;
1868 y=0;
1869 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1870 (void) items;
1871 image_view=AcquireVirtualCacheView(image,exception);
1872 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1873 if (q != (Quantum *) NULL)
1874 {
1875 if ((strchr(SvPV(sval,na),',') == 0) ||
1876 (strchr(SvPV(sval,na),')') != 0))
1877 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1878 &pixel,exception);
1879 else
1880 {
1881 GetPixelInfo(image,&pixel);
1882 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1883 pixel.red=geometry_info.rho;
1884 if ((flags & SigmaValue) != 0)
1885 pixel.green=geometry_info.sigma;
1886 if ((flags & XiValue) != 0)
1887 pixel.blue=geometry_info.xi;
1888 if ((flags & PsiValue) != 0)
1889 pixel.alpha=geometry_info.psi;
1890 if ((flags & ChiValue) != 0)
1891 pixel.black=geometry_info.chi;
1892 }
1893 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1894 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1895 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1896 if (image->colorspace == CMYKColorspace)
1897 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1898 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1899 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1900 }
1901 image_view=DestroyCacheView(image_view);
1902 }
1903 break;
1904 }
1905 if (LocaleCompare(attribute,"pointsize") == 0)
1906 {
1907 if (info)
1908 {
1909 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1910 info->image_info->pointsize=geometry_info.rho;
1911 }
1912 break;
1913 }
cristy4a3ce0a2013-08-03 20:06:59 +00001914 if (info)
1915 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1916 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001917 {
1918 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001919 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001920 }
cristy4a3ce0a2013-08-03 20:06:59 +00001921 break;
1922 }
1923 case 'Q':
1924 case 'q':
1925 {
1926 if (LocaleCompare(attribute,"quality") == 0)
1927 {
1928 if (info)
1929 info->image_info->quality=SvIV(sval);
1930 for ( ; image; image=image->next)
1931 image->quality=SvIV(sval);
1932 break;
1933 }
1934 if (info)
1935 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1936 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001937 {
1938 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001939 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001940 }
cristy4a3ce0a2013-08-03 20:06:59 +00001941 break;
1942 }
1943 case 'R':
1944 case 'r':
1945 {
cristyc0fe4752015-07-27 18:02:39 +00001946 if (LocaleCompare(attribute,"read-mask") == 0)
1947 {
1948 Image
1949 *mask;
1950
1951 mask=(Image *) NULL;
1952 if (SvPOK(sval))
1953 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1954 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001955 SetImageMask(image,ReadPixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00001956 break;
1957 }
cristy4a3ce0a2013-08-03 20:06:59 +00001958 if (LocaleCompare(attribute,"red-primary") == 0)
1959 {
1960 for ( ; image; image=image->next)
1961 {
1962 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1963 image->chromaticity.red_primary.x=geometry_info.rho;
1964 image->chromaticity.red_primary.y=geometry_info.sigma;
1965 if ((flags & SigmaValue) == 0)
1966 image->chromaticity.red_primary.y=
1967 image->chromaticity.red_primary.x;
1968 }
1969 break;
1970 }
1971 if (LocaleCompare(attribute,"render") == 0)
1972 {
1973 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1974 SvPV(sval,na)) : SvIV(sval);
1975 if (sp < 0)
1976 {
1977 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1978 SvPV(sval,na));
1979 break;
1980 }
1981 for ( ; image; image=image->next)
1982 image->rendering_intent=(RenderingIntent) sp;
1983 break;
1984 }
1985 if (LocaleCompare(attribute,"repage") == 0)
1986 {
1987 RectangleInfo
1988 geometry;
1989
1990 for ( ; image; image=image->next)
1991 {
1992 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1993 if ((flags & WidthValue) != 0)
1994 {
1995 if ((flags & HeightValue) == 0)
1996 geometry.height=geometry.width;
1997 image->page.width=geometry.width;
1998 image->page.height=geometry.height;
1999 }
2000 if ((flags & AspectValue) != 0)
2001 {
2002 if ((flags & XValue) != 0)
2003 image->page.x+=geometry.x;
2004 if ((flags & YValue) != 0)
2005 image->page.y+=geometry.y;
2006 }
2007 else
2008 {
2009 if ((flags & XValue) != 0)
2010 {
2011 image->page.x=geometry.x;
2012 if (((flags & WidthValue) != 0) && (geometry.x > 0))
2013 image->page.width=image->columns+geometry.x;
2014 }
2015 if ((flags & YValue) != 0)
2016 {
2017 image->page.y=geometry.y;
2018 if (((flags & HeightValue) != 0) && (geometry.y > 0))
2019 image->page.height=image->rows+geometry.y;
2020 }
2021 }
2022 }
2023 break;
2024 }
2025 if (info)
2026 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2027 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002028 {
2029 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002030 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002031 }
cristy4a3ce0a2013-08-03 20:06:59 +00002032 break;
2033 }
2034 case 'S':
2035 case 's':
2036 {
2037 if (LocaleCompare(attribute,"sampling-factor") == 0)
2038 {
2039 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2040 {
2041 ThrowPerlException(exception,OptionError,"MissingGeometry",
2042 SvPV(sval,na));
2043 break;
2044 }
2045 if (info)
2046 (void) CloneString(&info->image_info->sampling_factor,
2047 SvPV(sval,na));
2048 break;
2049 }
2050 if (LocaleCompare(attribute,"scene") == 0)
2051 {
2052 for ( ; image; image=image->next)
2053 image->scene=SvIV(sval);
2054 break;
2055 }
2056 if (LocaleCompare(attribute,"server") == 0)
2057 goto display;
2058 if (LocaleCompare(attribute,"size") == 0)
2059 {
2060 if (info)
2061 {
2062 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2063 {
2064 ThrowPerlException(exception,OptionError,"MissingGeometry",
2065 SvPV(sval,na));
2066 break;
2067 }
2068 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2069 }
2070 break;
2071 }
2072 if (LocaleCompare(attribute,"stroke") == 0)
2073 {
2074 if (info)
2075 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2076 break;
2077 }
2078 if (info)
2079 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2080 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002081 {
2082 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002083 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002084 }
cristy4a3ce0a2013-08-03 20:06:59 +00002085 break;
2086 }
2087 case 'T':
2088 case 't':
2089 {
2090 if (LocaleCompare(attribute,"texture") == 0)
2091 {
2092 if (info)
2093 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2094 break;
2095 }
2096 if (LocaleCompare(attribute,"thread-limit") == 0)
2097 {
2098 MagickSizeType
2099 limit;
2100
2101 limit=MagickResourceInfinity;
2102 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2103 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2104 100.0);
2105 (void) SetMagickResourceLimit(ThreadResource,limit);
2106 break;
2107 }
2108 if (LocaleCompare(attribute,"tile-offset") == 0)
2109 {
2110 char
2111 *geometry;
2112
2113 geometry=GetPageGeometry(SvPV(sval,na));
2114 if (info)
2115 (void) CloneString(&info->image_info->page,geometry);
2116 for ( ; image; image=image->next)
2117 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2118 exception);
2119 geometry=(char *) RelinquishMagickMemory(geometry);
2120 break;
2121 }
2122 if (LocaleCompare(attribute,"time-limit") == 0)
2123 {
2124 MagickSizeType
2125 limit;
2126
2127 limit=MagickResourceInfinity;
2128 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2129 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2130 100.0);
2131 (void) SetMagickResourceLimit(TimeResource,limit);
2132 break;
2133 }
2134 if (LocaleCompare(attribute,"transparent-color") == 0)
2135 {
2136 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2137 exception);
2138 if (info)
2139 info->image_info->transparent_color=target_color;
2140 for ( ; image; image=image->next)
2141 image->transparent_color=target_color;
2142 break;
2143 }
2144 if (LocaleCompare(attribute,"type") == 0)
2145 {
2146 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2147 SvPV(sval,na)) : SvIV(sval);
2148 if (sp < 0)
2149 {
2150 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2151 SvPV(sval,na));
2152 break;
2153 }
2154 if (info)
2155 info->image_info->type=(ImageType) sp;
2156 for ( ; image; image=image->next)
2157 SetImageType(image,(ImageType) sp,exception);
2158 break;
2159 }
2160 if (info)
2161 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2162 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002163 {
2164 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002165 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002166 }
cristy4a3ce0a2013-08-03 20:06:59 +00002167 break;
2168 }
2169 case 'U':
2170 case 'u':
2171 {
2172 if (LocaleCompare(attribute,"units") == 0)
2173 {
2174 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2175 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2176 if (sp < 0)
2177 {
2178 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2179 SvPV(sval,na));
2180 break;
2181 }
2182 if (info)
2183 info->image_info->units=(ResolutionType) sp;
2184 for ( ; image; image=image->next)
2185 {
2186 ResolutionType
2187 units;
2188
2189 units=(ResolutionType) sp;
2190 if (image->units != units)
2191 switch (image->units)
2192 {
2193 case UndefinedResolution:
2194 case PixelsPerInchResolution:
2195 {
2196 if (units == PixelsPerCentimeterResolution)
2197 {
2198 image->resolution.x*=2.54;
2199 image->resolution.y*=2.54;
2200 }
2201 break;
2202 }
2203 case PixelsPerCentimeterResolution:
2204 {
2205 if (units == PixelsPerInchResolution)
2206 {
2207 image->resolution.x/=2.54;
2208 image->resolution.y/=2.54;
2209 }
2210 break;
2211 }
2212 }
2213 image->units=units;
2214 }
2215 break;
2216 }
2217 if (info)
2218 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2219 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002220 {
2221 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002222 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002223 }
cristy4a3ce0a2013-08-03 20:06:59 +00002224 break;
2225 }
2226 case 'V':
2227 case 'v':
2228 {
2229 if (LocaleCompare(attribute,"verbose") == 0)
2230 {
2231 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2232 SvPV(sval,na)) : SvIV(sval);
2233 if (sp < 0)
2234 {
2235 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2236 SvPV(sval,na));
2237 break;
2238 }
2239 if (info)
2240 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2241 break;
2242 }
cristy4a3ce0a2013-08-03 20:06:59 +00002243 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2244 {
2245 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2246 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2247 if (sp < 0)
2248 {
2249 ThrowPerlException(exception,OptionError,
2250 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2251 break;
2252 }
2253 for ( ; image; image=image->next)
2254 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2255 break;
2256 }
2257 if (info)
2258 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2259 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002260 {
2261 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002262 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002263 }
cristy4a3ce0a2013-08-03 20:06:59 +00002264 break;
2265 }
2266 case 'W':
2267 case 'w':
2268 {
2269 if (LocaleCompare(attribute,"white-point") == 0)
2270 {
2271 for ( ; image; image=image->next)
2272 {
2273 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2274 image->chromaticity.white_point.x=geometry_info.rho;
2275 image->chromaticity.white_point.y=geometry_info.sigma;
2276 if ((flags & SigmaValue) == 0)
2277 image->chromaticity.white_point.y=
2278 image->chromaticity.white_point.x;
2279 }
2280 break;
2281 }
cristyc0fe4752015-07-27 18:02:39 +00002282 if (LocaleCompare(attribute,"write-mask") == 0)
2283 {
2284 Image
2285 *mask;
2286
2287 mask=(Image *) NULL;
2288 if (SvPOK(sval))
2289 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2290 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002291 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002292 break;
2293 }
cristy4a3ce0a2013-08-03 20:06:59 +00002294 if (info)
2295 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2296 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002297 {
2298 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002299 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002300 }
cristy4a3ce0a2013-08-03 20:06:59 +00002301 break;
2302 }
2303 default:
2304 {
2305 if (info)
2306 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2307 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002308 {
2309 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002310 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002311 }
cristy4a3ce0a2013-08-03 20:06:59 +00002312 break;
2313 }
2314 }
2315}
2316
2317/*
2318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2319% %
2320% %
2321% %
2322% S e t u p L i s t %
2323% %
2324% %
2325% %
2326%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2327%
2328% Method SetupList returns the list of all the images linked by their
2329% image->next and image->previous link lists for use with ImageMagick. If
2330% info is non-NULL, an info structure is returned in *info. If
2331% reference_vector is non-NULL,an array of SV* are returned in
2332% *reference_vector. Reference_vector is used when the images are going to be
2333% replaced with new Image*'s.
2334%
2335% The format of the SetupList routine is:
2336%
2337% Image *SetupList(SV *reference,struct PackageInfo **info,
2338% SV ***reference_vector,ExceptionInfo *exception)
2339%
2340% A description of each parameter follows:
2341%
2342% o list: a list of strings.
2343%
2344% o string: a character string.
2345%
2346% o exception: Return any errors or warnings in this structure.
2347%
2348*/
2349static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2350 SV ***reference_vector,ExceptionInfo *exception)
2351{
2352 Image
2353 *image;
2354
2355 ssize_t
2356 current,
2357 last;
2358
2359 if (reference_vector)
2360 *reference_vector=NULL;
2361 if (info)
2362 *info=NULL;
2363 current=0;
2364 last=0;
2365 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2366 if (info && (SvTYPE(reference) == SVt_PVAV))
2367 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2368 exception);
2369 return(image);
2370}
2371
2372/*
2373%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2374% %
2375% %
2376% %
2377% s t r E Q c a s e %
2378% %
2379% %
2380% %
2381%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2382%
2383% strEQcase() compares two strings and returns 0 if they are the
2384% same or if the second string runs out first. The comparison is case
2385% insensitive.
2386%
2387% The format of the strEQcase routine is:
2388%
2389% ssize_t strEQcase(const char *p,const char *q)
2390%
2391% A description of each parameter follows:
2392%
2393% o p: a character string.
2394%
2395% o q: a character string.
2396%
2397%
2398*/
2399static ssize_t strEQcase(const char *p,const char *q)
2400{
2401 char
2402 c;
2403
2404 register ssize_t
2405 i;
2406
2407 for (i=0 ; (c=(*q)) != 0; i++)
2408 {
2409 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2410 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2411 return(0);
2412 p++;
2413 q++;
2414 }
2415 return(((*q == 0) && (*p == 0)) ? i : 0);
2416}
2417
2418/*
2419%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2420% %
2421% %
2422% %
2423% I m a g e : : M a g i c k %
2424% %
2425% %
2426% %
2427%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2428%
2429%
2430*/
2431MODULE = Image::Magick PACKAGE = Image::Magick
2432
2433PROTOTYPES: ENABLE
2434
2435BOOT:
2436 MagickCoreGenesis("PerlMagick",MagickFalse);
2437 SetWarningHandler(NULL);
2438 SetErrorHandler(NULL);
2439 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2440 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2441
2442void
2443UNLOAD()
2444 PPCODE:
2445 {
2446 if (magick_registry != (SplayTreeInfo *) NULL)
2447 magick_registry=DestroySplayTree(magick_registry);
2448 MagickCoreTerminus();
2449 }
2450
2451double
2452constant(name,argument)
2453 char *name
2454 ssize_t argument
2455
2456#
2457###############################################################################
2458# #
2459# #
2460# #
2461# A n i m a t e #
2462# #
2463# #
2464# #
2465###############################################################################
2466#
2467#
2468void
2469Animate(ref,...)
2470 Image::Magick ref=NO_INIT
2471 ALIAS:
2472 AnimateImage = 1
2473 animate = 2
2474 animateimage = 3
2475 PPCODE:
2476 {
2477 ExceptionInfo
2478 *exception;
2479
2480 Image
2481 *image;
2482
2483 register ssize_t
2484 i;
2485
2486 struct PackageInfo
2487 *info,
2488 *package_info;
2489
2490 SV
2491 *perl_exception,
2492 *reference;
2493
2494 PERL_UNUSED_VAR(ref);
2495 PERL_UNUSED_VAR(ix);
2496 exception=AcquireExceptionInfo();
2497 perl_exception=newSVpv("",0);
2498 package_info=(struct PackageInfo *) NULL;
2499 if (sv_isobject(ST(0)) == 0)
2500 {
2501 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2502 PackageName);
2503 goto PerlException;
2504 }
2505 reference=SvRV(ST(0));
2506 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2507 if (image == (Image *) NULL)
2508 {
2509 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2510 PackageName);
2511 goto PerlException;
2512 }
2513 package_info=ClonePackageInfo(info,exception);
2514 if (items == 2)
2515 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2516 else
2517 if (items > 2)
2518 for (i=2; i < items; i+=2)
2519 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2520 exception);
2521 (void) AnimateImages(package_info->image_info,image,exception);
2522 (void) CatchImageException(image);
2523
2524 PerlException:
2525 if (package_info != (struct PackageInfo *) NULL)
2526 DestroyPackageInfo(package_info);
2527 InheritPerlException(exception,perl_exception);
2528 exception=DestroyExceptionInfo(exception);
2529 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2530 SvPOK_on(perl_exception);
2531 ST(0)=sv_2mortal(perl_exception);
2532 XSRETURN(1);
2533 }
2534
2535#
2536###############################################################################
2537# #
2538# #
2539# #
2540# A p p e n d #
2541# #
2542# #
2543# #
2544###############################################################################
2545#
2546#
2547void
2548Append(ref,...)
2549 Image::Magick ref=NO_INIT
2550 ALIAS:
2551 AppendImage = 1
2552 append = 2
2553 appendimage = 3
2554 PPCODE:
2555 {
2556 AV
2557 *av;
2558
2559 char
2560 *attribute;
2561
2562 ExceptionInfo
2563 *exception;
2564
2565 HV
2566 *hv;
2567
2568 Image
2569 *image;
2570
2571 register ssize_t
2572 i;
2573
2574 ssize_t
2575 stack;
2576
2577 struct PackageInfo
2578 *info;
2579
2580 SV
2581 *av_reference,
2582 *perl_exception,
2583 *reference,
2584 *rv,
2585 *sv;
2586
2587 PERL_UNUSED_VAR(ref);
2588 PERL_UNUSED_VAR(ix);
2589 exception=AcquireExceptionInfo();
2590 perl_exception=newSVpv("",0);
2591 sv=NULL;
2592 attribute=NULL;
2593 av=NULL;
2594 if (sv_isobject(ST(0)) == 0)
2595 {
2596 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2597 PackageName);
2598 goto PerlException;
2599 }
2600 reference=SvRV(ST(0));
2601 hv=SvSTASH(reference);
2602 av=newAV();
2603 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2604 SvREFCNT_dec(av);
2605 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2606 if (image == (Image *) NULL)
2607 {
2608 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2609 PackageName);
2610 goto PerlException;
2611 }
2612 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2613 /*
2614 Get options.
2615 */
2616 stack=MagickTrue;
2617 for (i=2; i < items; i+=2)
2618 {
2619 attribute=(char *) SvPV(ST(i-1),na);
2620 switch (*attribute)
2621 {
2622 case 'S':
2623 case 's':
2624 {
2625 if (LocaleCompare(attribute,"stack") == 0)
2626 {
2627 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2628 SvPV(ST(i),na));
2629 if (stack < 0)
2630 {
2631 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2632 SvPV(ST(i),na));
2633 return;
2634 }
2635 break;
2636 }
2637 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2638 attribute);
2639 break;
2640 }
2641 default:
2642 {
2643 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2644 attribute);
2645 break;
2646 }
2647 }
2648 }
2649 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2650 if (image == (Image *) NULL)
2651 goto PerlException;
2652 for ( ; image; image=image->next)
2653 {
2654 AddImageToRegistry(sv,image);
2655 rv=newRV(sv);
2656 av_push(av,sv_bless(rv,hv));
2657 SvREFCNT_dec(sv);
2658 }
2659 exception=DestroyExceptionInfo(exception);
2660 ST(0)=av_reference;
2661 SvREFCNT_dec(perl_exception);
2662 XSRETURN(1);
2663
2664 PerlException:
2665 InheritPerlException(exception,perl_exception);
2666 exception=DestroyExceptionInfo(exception);
2667 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2668 SvPOK_on(perl_exception);
2669 ST(0)=sv_2mortal(perl_exception);
2670 XSRETURN(1);
2671 }
2672
2673#
2674###############################################################################
2675# #
2676# #
2677# #
2678# A v e r a g e #
2679# #
2680# #
2681# #
2682###############################################################################
2683#
2684#
2685void
2686Average(ref)
2687 Image::Magick ref=NO_INIT
2688 ALIAS:
2689 AverageImage = 1
2690 average = 2
2691 averageimage = 3
2692 PPCODE:
2693 {
2694 AV
2695 *av;
2696
2697 char
2698 *p;
2699
2700 ExceptionInfo
2701 *exception;
2702
2703 HV
2704 *hv;
2705
2706 Image
2707 *image;
2708
2709 struct PackageInfo
2710 *info;
2711
2712 SV
2713 *perl_exception,
2714 *reference,
2715 *rv,
2716 *sv;
2717
2718 PERL_UNUSED_VAR(ref);
2719 PERL_UNUSED_VAR(ix);
2720 exception=AcquireExceptionInfo();
2721 perl_exception=newSVpv("",0);
2722 sv=NULL;
2723 if (sv_isobject(ST(0)) == 0)
2724 {
2725 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2726 PackageName);
2727 goto PerlException;
2728 }
2729 reference=SvRV(ST(0));
2730 hv=SvSTASH(reference);
2731 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2732 if (image == (Image *) NULL)
2733 {
2734 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2735 PackageName);
2736 goto PerlException;
2737 }
2738 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2739 if (image == (Image *) NULL)
2740 goto PerlException;
2741 /*
2742 Create blessed Perl array for the returned image.
2743 */
2744 av=newAV();
2745 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2746 SvREFCNT_dec(av);
2747 AddImageToRegistry(sv,image);
2748 rv=newRV(sv);
2749 av_push(av,sv_bless(rv,hv));
2750 SvREFCNT_dec(sv);
2751 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002752 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2753 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002754 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2755 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002756 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002757 SetImageInfo(info->image_info,0,exception);
2758 exception=DestroyExceptionInfo(exception);
2759 SvREFCNT_dec(perl_exception);
2760 XSRETURN(1);
2761
2762 PerlException:
2763 InheritPerlException(exception,perl_exception);
2764 exception=DestroyExceptionInfo(exception);
2765 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2766 SvPOK_on(perl_exception);
2767 ST(0)=sv_2mortal(perl_exception);
2768 XSRETURN(1);
2769 }
2770
2771#
2772###############################################################################
2773# #
2774# #
2775# #
2776# B l o b T o I m a g e #
2777# #
2778# #
2779# #
2780###############################################################################
2781#
2782#
2783void
2784BlobToImage(ref,...)
2785 Image::Magick ref=NO_INIT
2786 ALIAS:
2787 BlobToImage = 1
2788 blobtoimage = 2
2789 blobto = 3
2790 PPCODE:
2791 {
2792 AV
2793 *av;
2794
2795 char
2796 **keep,
2797 **list;
2798
2799 ExceptionInfo
2800 *exception;
2801
2802 HV
2803 *hv;
2804
2805 Image
2806 *image;
2807
2808 register char
2809 **p;
2810
2811 register ssize_t
2812 i;
2813
2814 ssize_t
2815 ac,
2816 n,
2817 number_images;
2818
2819 STRLEN
2820 *length;
2821
2822 struct PackageInfo
2823 *info;
2824
2825 SV
2826 *perl_exception,
2827 *reference,
2828 *rv,
2829 *sv;
2830
2831 PERL_UNUSED_VAR(ref);
2832 PERL_UNUSED_VAR(ix);
2833 exception=AcquireExceptionInfo();
2834 perl_exception=newSVpv("",0);
2835 sv=NULL;
2836 number_images=0;
2837 ac=(items < 2) ? 1 : items-1;
2838 length=(STRLEN *) NULL;
2839 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2840 if (list == (char **) NULL)
2841 {
2842 ThrowPerlException(exception,ResourceLimitError,
2843 "MemoryAllocationFailed",PackageName);
2844 goto PerlException;
2845 }
2846 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2847 if (length == (STRLEN *) NULL)
2848 {
2849 ThrowPerlException(exception,ResourceLimitError,
2850 "MemoryAllocationFailed",PackageName);
2851 goto PerlException;
2852 }
2853 if (sv_isobject(ST(0)) == 0)
2854 {
2855 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2856 PackageName);
2857 goto PerlException;
2858 }
2859 reference=SvRV(ST(0));
2860 hv=SvSTASH(reference);
2861 if (SvTYPE(reference) != SVt_PVAV)
2862 {
2863 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2864 PackageName);
2865 goto PerlException;
2866 }
2867 av=(AV *) reference;
2868 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2869 exception);
2870 n=1;
2871 if (items <= 1)
2872 {
2873 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2874 goto PerlException;
2875 }
2876 for (n=0, i=0; i < ac; i++)
2877 {
2878 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2879 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2880 {
2881 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2882 continue;
2883 }
2884 n++;
2885 }
2886 list[n]=(char *) NULL;
2887 keep=list;
2888 for (i=number_images=0; i < n; i++)
2889 {
2890 image=BlobToImage(info->image_info,list[i],length[i],exception);
2891 if (image == (Image *) NULL)
2892 break;
2893 for ( ; image; image=image->next)
2894 {
2895 AddImageToRegistry(sv,image);
2896 rv=newRV(sv);
2897 av_push(av,sv_bless(rv,hv));
2898 SvREFCNT_dec(sv);
2899 number_images++;
2900 }
2901 }
2902 /*
2903 Free resources.
2904 */
2905 for (i=0; i < n; i++)
2906 if (list[i] != (char *) NULL)
2907 for (p=keep; list[i] != *p++; )
2908 if (*p == (char *) NULL)
2909 {
2910 list[i]=(char *) RelinquishMagickMemory(list[i]);
2911 break;
2912 }
2913
2914 PerlException:
2915 if (list)
2916 list=(char **) RelinquishMagickMemory(list);
2917 if (length)
2918 length=(STRLEN *) RelinquishMagickMemory(length);
2919 InheritPerlException(exception,perl_exception);
2920 exception=DestroyExceptionInfo(exception);
2921 sv_setiv(perl_exception,(IV) number_images);
2922 SvPOK_on(perl_exception);
2923 ST(0)=sv_2mortal(perl_exception);
2924 XSRETURN(1);
2925 }
2926
2927#
2928###############################################################################
2929# #
2930# #
2931# #
2932# C h a n n e l F x #
2933# #
2934# #
2935# #
2936###############################################################################
2937#
2938#
2939void
2940ChannelFx(ref,...)
2941 Image::Magick ref=NO_INIT
2942 ALIAS:
2943 ChannelFxImage = 1
2944 channelfx = 2
2945 channelfximage = 3
2946 PPCODE:
2947 {
2948 AV
2949 *av;
2950
2951 char
2952 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002953 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002954
2955 ChannelType
2956 channel,
2957 channel_mask;
2958
2959 ExceptionInfo
2960 *exception;
2961
2962 HV
2963 *hv;
2964
2965 Image
2966 *image;
2967
2968 register ssize_t
2969 i;
2970
2971 struct PackageInfo
2972 *info;
2973
2974 SV
2975 *av_reference,
2976 *perl_exception,
2977 *reference,
2978 *rv,
2979 *sv;
2980
2981 PERL_UNUSED_VAR(ref);
2982 PERL_UNUSED_VAR(ix);
2983 exception=AcquireExceptionInfo();
2984 perl_exception=newSVpv("",0);
2985 sv=NULL;
2986 attribute=NULL;
2987 av=NULL;
2988 if (sv_isobject(ST(0)) == 0)
2989 {
2990 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2991 PackageName);
2992 goto PerlException;
2993 }
2994 reference=SvRV(ST(0));
2995 hv=SvSTASH(reference);
2996 av=newAV();
2997 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2998 SvREFCNT_dec(av);
2999 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3000 if (image == (Image *) NULL)
3001 {
3002 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3003 PackageName);
3004 goto PerlException;
3005 }
3006 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3007 /*
3008 Get options.
3009 */
3010 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00003011 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003012 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00003013 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003014 else
3015 for (i=2; i < items; i+=2)
3016 {
3017 attribute=(char *) SvPV(ST(i-1),na);
3018 switch (*attribute)
3019 {
3020 case 'C':
3021 case 'c':
3022 {
3023 if (LocaleCompare(attribute,"channel") == 0)
3024 {
3025 ssize_t
3026 option;
3027
3028 option=ParseChannelOption(SvPV(ST(i),na));
3029 if (option < 0)
3030 {
3031 ThrowPerlException(exception,OptionError,
3032 "UnrecognizedType",SvPV(ST(i),na));
3033 return;
3034 }
3035 channel=(ChannelType) option;
3036 break;
3037 }
3038 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3039 attribute);
3040 break;
3041 }
3042 case 'E':
3043 case 'e':
3044 {
3045 if (LocaleCompare(attribute,"expression") == 0)
3046 {
3047 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00003048 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003049 break;
3050 }
3051 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3052 attribute);
3053 break;
3054 }
3055 default:
3056 {
3057 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3058 attribute);
3059 break;
3060 }
3061 }
3062 }
3063 channel_mask=SetImageChannelMask(image,channel);
3064 image=ChannelFxImage(image,expression,exception);
3065 if (image != (Image *) NULL)
3066 (void) SetImageChannelMask(image,channel_mask);
3067 if (image == (Image *) NULL)
3068 goto PerlException;
3069 for ( ; image; image=image->next)
3070 {
3071 AddImageToRegistry(sv,image);
3072 rv=newRV(sv);
3073 av_push(av,sv_bless(rv,hv));
3074 SvREFCNT_dec(sv);
3075 }
3076 exception=DestroyExceptionInfo(exception);
3077 ST(0)=av_reference;
3078 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3079 XSRETURN(1);
3080
3081 PerlException:
3082 InheritPerlException(exception,perl_exception);
3083 exception=DestroyExceptionInfo(exception);
3084 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3085 SvPOK_on(perl_exception);
3086 ST(0)=sv_2mortal(perl_exception);
3087 XSRETURN(1);
3088 }
3089
3090#
3091###############################################################################
3092# #
3093# #
3094# #
3095# C l o n e #
3096# #
3097# #
3098# #
3099###############################################################################
3100#
3101#
3102void
3103Clone(ref)
3104 Image::Magick ref=NO_INIT
3105 ALIAS:
3106 CopyImage = 1
3107 copy = 2
3108 copyimage = 3
3109 CloneImage = 4
3110 clone = 5
3111 cloneimage = 6
3112 Clone = 7
3113 PPCODE:
3114 {
3115 AV
3116 *av;
3117
3118 ExceptionInfo
3119 *exception;
3120
3121 HV
3122 *hv;
3123
3124 Image
3125 *clone,
3126 *image;
3127
3128 struct PackageInfo
3129 *info;
3130
3131 SV
3132 *perl_exception,
3133 *reference,
3134 *rv,
3135 *sv;
3136
3137 PERL_UNUSED_VAR(ref);
3138 PERL_UNUSED_VAR(ix);
3139 exception=AcquireExceptionInfo();
3140 perl_exception=newSVpv("",0);
3141 sv=NULL;
3142 if (sv_isobject(ST(0)) == 0)
3143 {
3144 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3145 PackageName);
3146 goto PerlException;
3147 }
3148 reference=SvRV(ST(0));
3149 hv=SvSTASH(reference);
3150 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3151 if (image == (Image *) NULL)
3152 {
3153 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3154 PackageName);
3155 goto PerlException;
3156 }
3157 /*
3158 Create blessed Perl array for the returned image.
3159 */
3160 av=newAV();
3161 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3162 SvREFCNT_dec(av);
3163 for ( ; image; image=image->next)
3164 {
3165 clone=CloneImage(image,0,0,MagickTrue,exception);
3166 if (clone == (Image *) NULL)
3167 break;
3168 AddImageToRegistry(sv,clone);
3169 rv=newRV(sv);
3170 av_push(av,sv_bless(rv,hv));
3171 SvREFCNT_dec(sv);
3172 }
3173 exception=DestroyExceptionInfo(exception);
3174 SvREFCNT_dec(perl_exception);
3175 XSRETURN(1);
3176
3177 PerlException:
3178 InheritPerlException(exception,perl_exception);
3179 exception=DestroyExceptionInfo(exception);
3180 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3181 SvPOK_on(perl_exception);
3182 ST(0)=sv_2mortal(perl_exception);
3183 XSRETURN(1);
3184 }
3185
3186#
3187###############################################################################
3188# #
3189# #
3190# #
3191# C L O N E #
3192# #
3193# #
3194# #
3195###############################################################################
3196#
3197#
3198void
3199CLONE(ref,...)
3200 SV *ref;
3201 CODE:
3202 {
3203 PERL_UNUSED_VAR(ref);
3204 if (magick_registry != (SplayTreeInfo *) NULL)
3205 {
3206 register Image
3207 *p;
3208
3209 ResetSplayTreeIterator(magick_registry);
3210 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3211 while (p != (Image *) NULL)
3212 {
3213 ReferenceImage(p);
3214 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3215 }
3216 }
3217 }
3218
3219#
3220###############################################################################
3221# #
3222# #
3223# #
3224# C o a l e s c e #
3225# #
3226# #
3227# #
3228###############################################################################
3229#
3230#
3231void
3232Coalesce(ref)
3233 Image::Magick ref=NO_INIT
3234 ALIAS:
3235 CoalesceImage = 1
3236 coalesce = 2
3237 coalesceimage = 3
3238 PPCODE:
3239 {
3240 AV
3241 *av;
3242
3243 ExceptionInfo
3244 *exception;
3245
3246 HV
3247 *hv;
3248
3249 Image
3250 *image;
3251
3252 struct PackageInfo
3253 *info;
3254
3255 SV
3256 *av_reference,
3257 *perl_exception,
3258 *reference,
3259 *rv,
3260 *sv;
3261
3262 PERL_UNUSED_VAR(ref);
3263 PERL_UNUSED_VAR(ix);
3264 exception=AcquireExceptionInfo();
3265 perl_exception=newSVpv("",0);
3266 sv=NULL;
3267 if (sv_isobject(ST(0)) == 0)
3268 {
3269 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3270 PackageName);
3271 goto PerlException;
3272 }
3273 reference=SvRV(ST(0));
3274 hv=SvSTASH(reference);
3275 av=newAV();
3276 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3277 SvREFCNT_dec(av);
3278 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3279 if (image == (Image *) NULL)
3280 {
3281 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3282 PackageName);
3283 goto PerlException;
3284 }
3285 image=CoalesceImages(image,exception);
3286 if (image == (Image *) NULL)
3287 goto PerlException;
3288 for ( ; image; image=image->next)
3289 {
3290 AddImageToRegistry(sv,image);
3291 rv=newRV(sv);
3292 av_push(av,sv_bless(rv,hv));
3293 SvREFCNT_dec(sv);
3294 }
3295 exception=DestroyExceptionInfo(exception);
3296 ST(0)=av_reference;
3297 SvREFCNT_dec(perl_exception);
3298 XSRETURN(1);
3299
3300 PerlException:
3301 InheritPerlException(exception,perl_exception);
3302 exception=DestroyExceptionInfo(exception);
3303 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3304 SvPOK_on(perl_exception);
3305 ST(0)=sv_2mortal(perl_exception);
3306 XSRETURN(1);
3307 }
3308
3309#
3310###############################################################################
3311# #
3312# #
3313# #
3314# C o m p a r e #
3315# #
3316# #
3317# #
3318###############################################################################
3319#
3320#
3321void
3322Compare(ref,...)
3323 Image::Magick ref=NO_INIT
3324 ALIAS:
3325 CompareImages = 1
3326 compare = 2
3327 compareimage = 3
3328 PPCODE:
3329 {
3330 AV
3331 *av;
3332
3333 char
3334 *attribute;
3335
3336 double
3337 distortion;
3338
3339 ExceptionInfo
3340 *exception;
3341
3342 HV
3343 *hv;
3344
3345 Image
3346 *difference_image,
3347 *image,
3348 *reconstruct_image;
3349
3350 MetricType
3351 metric;
3352
3353 register ssize_t
3354 i;
3355
3356 ssize_t
3357 option;
3358
3359 struct PackageInfo
3360 *info;
3361
3362 SV
3363 *av_reference,
3364 *perl_exception,
3365 *reference,
3366 *rv,
3367 *sv;
3368
3369 PERL_UNUSED_VAR(ref);
3370 PERL_UNUSED_VAR(ix);
3371 exception=AcquireExceptionInfo();
3372 perl_exception=newSVpv("",0);
3373 sv=NULL;
3374 av=NULL;
3375 attribute=NULL;
3376 if (sv_isobject(ST(0)) == 0)
3377 {
3378 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3379 PackageName);
3380 goto PerlException;
3381 }
3382 reference=SvRV(ST(0));
3383 hv=SvSTASH(reference);
3384 av=newAV();
3385 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3386 SvREFCNT_dec(av);
3387 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3388 if (image == (Image *) NULL)
3389 {
3390 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3391 PackageName);
3392 goto PerlException;
3393 }
3394 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3395 /*
3396 Get attribute.
3397 */
3398 reconstruct_image=image;
3399 metric=RootMeanSquaredErrorMetric;
3400 for (i=2; i < items; i+=2)
3401 {
3402 attribute=(char *) SvPV(ST(i-1),na);
3403 switch (*attribute)
3404 {
3405 case 'C':
3406 case 'c':
3407 {
3408 if (LocaleCompare(attribute,"channel") == 0)
3409 {
3410 ssize_t
3411 option;
3412
3413 option=ParseChannelOption(SvPV(ST(i),na));
3414 if (option < 0)
3415 {
3416 ThrowPerlException(exception,OptionError,
3417 "UnrecognizedType",SvPV(ST(i),na));
3418 return;
3419 }
cristybcd59342015-06-07 14:07:19 +00003420 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003421 break;
3422 }
3423 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3424 attribute);
3425 break;
3426 }
3427 case 'F':
3428 case 'f':
3429 {
3430 if (LocaleCompare(attribute,"fuzz") == 0)
3431 {
3432 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3433 break;
3434 }
3435 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3436 attribute);
3437 break;
3438 }
3439 case 'I':
3440 case 'i':
3441 {
3442 if (LocaleCompare(attribute,"image") == 0)
3443 {
3444 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3445 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3446 break;
3447 }
3448 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3449 attribute);
3450 break;
3451 }
3452 case 'M':
3453 case 'm':
3454 {
3455 if (LocaleCompare(attribute,"metric") == 0)
3456 {
3457 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3458 SvPV(ST(i),na));
3459 if (option < 0)
3460 {
3461 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3462 SvPV(ST(i),na));
3463 break;
3464 }
3465 metric=(MetricType) option;
3466 break;
3467 }
3468 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3469 attribute);
3470 break;
3471 }
3472 default:
3473 {
3474 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3475 attribute);
3476 break;
3477 }
3478 }
3479 }
3480 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3481 exception);
3482 if (difference_image != (Image *) NULL)
3483 {
3484 difference_image->error.mean_error_per_pixel=distortion;
3485 AddImageToRegistry(sv,difference_image);
3486 rv=newRV(sv);
3487 av_push(av,sv_bless(rv,hv));
3488 SvREFCNT_dec(sv);
3489 }
3490 exception=DestroyExceptionInfo(exception);
3491 ST(0)=av_reference;
3492 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3493 XSRETURN(1);
3494
3495 PerlException:
3496 InheritPerlException(exception,perl_exception);
3497 exception=DestroyExceptionInfo(exception);
3498 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3499 SvPOK_on(perl_exception);
3500 ST(0)=sv_2mortal(perl_exception);
3501 XSRETURN(1);
3502 }
3503
3504#
3505###############################################################################
3506# #
3507# #
3508# #
cristy15655332013-10-06 00:27:33 +00003509# C o m p l e x I m a g e s #
3510# #
3511# #
3512# #
3513###############################################################################
3514#
3515#
3516void
3517ComplexImages(ref)
3518 Image::Magick ref=NO_INIT
3519 ALIAS:
3520 ComplexImages = 1
3521 compleximages = 2
3522 PPCODE:
3523 {
3524 AV
3525 *av;
3526
3527 char
3528 *attribute,
3529 *p;
3530
cristyfa21e9e2013-10-07 10:37:38 +00003531 ComplexOperator
3532 op;
3533
cristy15655332013-10-06 00:27:33 +00003534 ExceptionInfo
3535 *exception;
3536
3537 HV
3538 *hv;
3539
3540 Image
3541 *image;
3542
cristy15655332013-10-06 00:27:33 +00003543 register ssize_t
3544 i;
3545
3546 struct PackageInfo
3547 *info;
3548
3549 SV
3550 *perl_exception,
3551 *reference,
3552 *rv,
3553 *sv;
3554
3555 PERL_UNUSED_VAR(ref);
3556 PERL_UNUSED_VAR(ix);
3557 exception=AcquireExceptionInfo();
3558 perl_exception=newSVpv("",0);
3559 sv=NULL;
3560 if (sv_isobject(ST(0)) == 0)
3561 {
3562 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3563 PackageName);
3564 goto PerlException;
3565 }
3566 reference=SvRV(ST(0));
3567 hv=SvSTASH(reference);
3568 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3569 if (image == (Image *) NULL)
3570 {
3571 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3572 PackageName);
3573 goto PerlException;
3574 }
cristyfd168722013-10-07 15:59:31 +00003575 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003576 if (items == 2)
3577 {
3578 ssize_t
3579 in;
3580
3581 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3582 SvPV(ST(1),na));
3583 if (in < 0)
3584 {
3585 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3586 SvPV(ST(1),na));
3587 return;
3588 }
cristyfa21e9e2013-10-07 10:37:38 +00003589 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003590 }
3591 else
3592 for (i=2; i < items; i+=2)
3593 {
3594 attribute=(char *) SvPV(ST(i-1),na);
3595 switch (*attribute)
3596 {
3597 case 'O':
3598 case 'o':
3599 {
3600 if (LocaleCompare(attribute,"operator") == 0)
3601 {
3602 ssize_t
3603 in;
3604
3605 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3606 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3607 if (in < 0)
3608 {
3609 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3610 SvPV(ST(i),na));
3611 return;
3612 }
cristyfa21e9e2013-10-07 10:37:38 +00003613 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003614 break;
3615 }
3616 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3617 attribute);
3618 break;
3619 }
3620 default:
3621 {
3622 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3623 attribute);
3624 break;
3625 }
3626 }
3627 }
3628 image=ComplexImages(image,op,exception);
3629 if (image == (Image *) NULL)
3630 goto PerlException;
3631 /*
3632 Create blessed Perl array for the returned image.
3633 */
3634 av=newAV();
3635 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3636 SvREFCNT_dec(av);
3637 AddImageToRegistry(sv,image);
3638 rv=newRV(sv);
3639 av_push(av,sv_bless(rv,hv));
3640 SvREFCNT_dec(sv);
3641 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003642 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3643 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003644 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3645 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003646 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003647 SetImageInfo(info->image_info,0,exception);
3648 exception=DestroyExceptionInfo(exception);
3649 SvREFCNT_dec(perl_exception);
3650 XSRETURN(1);
3651
3652 PerlException:
3653 InheritPerlException(exception,perl_exception);
3654 exception=DestroyExceptionInfo(exception);
3655 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3656 SvPOK_on(perl_exception);
3657 ST(0)=sv_2mortal(perl_exception);
3658 XSRETURN(1);
3659 }
3660
3661#
3662###############################################################################
3663# #
3664# #
3665# #
cristy4a3ce0a2013-08-03 20:06:59 +00003666# C o m p a r e L a y e r s #
3667# #
3668# #
3669# #
3670###############################################################################
3671#
3672#
3673void
3674CompareLayers(ref)
3675 Image::Magick ref=NO_INIT
3676 ALIAS:
3677 CompareImagesLayers = 1
3678 comparelayers = 2
3679 compareimagelayers = 3
3680 PPCODE:
3681 {
3682 AV
3683 *av;
3684
3685 char
3686 *attribute;
3687
3688 ExceptionInfo
3689 *exception;
3690
3691 HV
3692 *hv;
3693
3694 Image
3695 *image;
3696
3697 LayerMethod
3698 method;
3699
3700 register ssize_t
3701 i;
3702
3703 ssize_t
3704 option;
3705
3706 struct PackageInfo
3707 *info;
3708
3709 SV
3710 *av_reference,
3711 *perl_exception,
3712 *reference,
3713 *rv,
3714 *sv;
3715
3716 PERL_UNUSED_VAR(ref);
3717 PERL_UNUSED_VAR(ix);
3718 exception=AcquireExceptionInfo();
3719 perl_exception=newSVpv("",0);
3720 sv=NULL;
3721 if (sv_isobject(ST(0)) == 0)
3722 {
3723 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3724 PackageName);
3725 goto PerlException;
3726 }
3727 reference=SvRV(ST(0));
3728 hv=SvSTASH(reference);
3729 av=newAV();
3730 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3731 SvREFCNT_dec(av);
3732 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3733 if (image == (Image *) NULL)
3734 {
3735 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3736 PackageName);
3737 goto PerlException;
3738 }
3739 method=CompareAnyLayer;
3740 for (i=2; i < items; i+=2)
3741 {
3742 attribute=(char *) SvPV(ST(i-1),na);
3743 switch (*attribute)
3744 {
3745 case 'M':
3746 case 'm':
3747 {
3748 if (LocaleCompare(attribute,"method") == 0)
3749 {
3750 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3751 SvPV(ST(i),na));
3752 if (option < 0)
3753 {
3754 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3755 SvPV(ST(i),na));
3756 break;
3757 }
3758 method=(LayerMethod) option;
3759 break;
3760 }
3761 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3762 attribute);
3763 break;
3764 }
3765 default:
3766 {
3767 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3768 attribute);
3769 break;
3770 }
3771 }
3772 }
3773 image=CompareImagesLayers(image,method,exception);
3774 if (image == (Image *) NULL)
3775 goto PerlException;
3776 for ( ; image; image=image->next)
3777 {
3778 AddImageToRegistry(sv,image);
3779 rv=newRV(sv);
3780 av_push(av,sv_bless(rv,hv));
3781 SvREFCNT_dec(sv);
3782 }
3783 exception=DestroyExceptionInfo(exception);
3784 ST(0)=av_reference;
3785 SvREFCNT_dec(perl_exception);
3786 XSRETURN(1);
3787
3788 PerlException:
3789 InheritPerlException(exception,perl_exception);
3790 exception=DestroyExceptionInfo(exception);
3791 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3792 SvPOK_on(perl_exception);
3793 ST(0)=sv_2mortal(perl_exception);
3794 XSRETURN(1);
3795 }
3796
3797#
3798###############################################################################
3799# #
3800# #
3801# #
3802# D e s t r o y #
3803# #
3804# #
3805# #
3806###############################################################################
3807#
3808#
3809void
3810DESTROY(ref)
3811 Image::Magick ref=NO_INIT
3812 PPCODE:
3813 {
3814 SV
3815 *reference;
3816
3817 PERL_UNUSED_VAR(ref);
3818 if (sv_isobject(ST(0)) == 0)
3819 croak("ReferenceIsNotMyType");
3820 reference=SvRV(ST(0));
3821 switch (SvTYPE(reference))
3822 {
3823 case SVt_PVAV:
3824 {
3825 char
cristy151b66d2015-04-15 10:50:31 +00003826 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003827
3828 const SV
3829 *key;
3830
3831 HV
3832 *hv;
3833
3834 GV
3835 **gvp;
3836
3837 struct PackageInfo
3838 *info;
3839
3840 SV
3841 *sv;
3842
3843 /*
3844 Array (AV *) reference
3845 */
cristy151b66d2015-04-15 10:50:31 +00003846 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003847 XS_VERSION,reference);
3848 hv=gv_stashpv(PackageName, FALSE);
3849 if (!hv)
3850 break;
3851 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3852 if (!gvp)
3853 break;
3854 sv=GvSV(*gvp);
3855 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3856 {
3857 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3858 DestroyPackageInfo(info);
3859 }
3860 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3861 (void) key;
3862 break;
3863 }
3864 case SVt_PVMG:
3865 {
3866 Image
3867 *image;
3868
3869 /*
3870 Blessed scalar = (Image *) SvIV(reference)
3871 */
3872 image=INT2PTR(Image *,SvIV(reference));
3873 if (image != (Image *) NULL)
3874 DeleteImageFromRegistry(reference,image);
3875 break;
3876 }
3877 default:
3878 break;
3879 }
3880 }
3881
3882#
3883###############################################################################
3884# #
3885# #
3886# #
3887# D i s p l a y #
3888# #
3889# #
3890# #
3891###############################################################################
3892#
3893#
3894void
3895Display(ref,...)
3896 Image::Magick ref=NO_INIT
3897 ALIAS:
3898 DisplayImage = 1
3899 display = 2
3900 displayimage = 3
3901 PPCODE:
3902 {
3903 ExceptionInfo
3904 *exception;
3905
3906 Image
3907 *image;
3908
3909 register ssize_t
3910 i;
3911
3912 struct PackageInfo
3913 *info,
3914 *package_info;
3915
3916 SV
3917 *perl_exception,
3918 *reference;
3919
3920 PERL_UNUSED_VAR(ref);
3921 PERL_UNUSED_VAR(ix);
3922 exception=AcquireExceptionInfo();
3923 perl_exception=newSVpv("",0);
3924 package_info=(struct PackageInfo *) NULL;
3925 if (sv_isobject(ST(0)) == 0)
3926 {
3927 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3928 PackageName);
3929 goto PerlException;
3930 }
3931 reference=SvRV(ST(0));
3932 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3933 if (image == (Image *) NULL)
3934 {
3935 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3936 PackageName);
3937 goto PerlException;
3938 }
3939 package_info=ClonePackageInfo(info,exception);
3940 if (items == 2)
3941 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3942 else
3943 if (items > 2)
3944 for (i=2; i < items; i+=2)
3945 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3946 exception);
3947 (void) DisplayImages(package_info->image_info,image,exception);
3948 (void) CatchImageException(image);
3949
3950 PerlException:
3951 if (package_info != (struct PackageInfo *) NULL)
3952 DestroyPackageInfo(package_info);
3953 InheritPerlException(exception,perl_exception);
3954 exception=DestroyExceptionInfo(exception);
3955 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3956 SvPOK_on(perl_exception);
3957 ST(0)=sv_2mortal(perl_exception);
3958 XSRETURN(1);
3959 }
3960
3961#
3962###############################################################################
3963# #
3964# #
3965# #
3966# E v a l u a t e I m a g e s #
3967# #
3968# #
3969# #
3970###############################################################################
3971#
3972#
3973void
3974EvaluateImages(ref)
3975 Image::Magick ref=NO_INIT
3976 ALIAS:
3977 EvaluateImages = 1
3978 evaluateimages = 2
3979 PPCODE:
3980 {
3981 AV
3982 *av;
3983
3984 char
3985 *attribute,
3986 *p;
3987
3988 ExceptionInfo
3989 *exception;
3990
3991 HV
3992 *hv;
3993
3994 Image
3995 *image;
3996
3997 MagickEvaluateOperator
3998 op;
3999
4000 register ssize_t
4001 i;
4002
4003 struct PackageInfo
4004 *info;
4005
4006 SV
4007 *perl_exception,
4008 *reference,
4009 *rv,
4010 *sv;
4011
4012 PERL_UNUSED_VAR(ref);
4013 PERL_UNUSED_VAR(ix);
4014 exception=AcquireExceptionInfo();
4015 perl_exception=newSVpv("",0);
4016 sv=NULL;
4017 if (sv_isobject(ST(0)) == 0)
4018 {
4019 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4020 PackageName);
4021 goto PerlException;
4022 }
4023 reference=SvRV(ST(0));
4024 hv=SvSTASH(reference);
4025 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4026 if (image == (Image *) NULL)
4027 {
4028 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4029 PackageName);
4030 goto PerlException;
4031 }
4032 op=MeanEvaluateOperator;
4033 if (items == 2)
4034 {
4035 ssize_t
4036 in;
4037
4038 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
4039 SvPV(ST(1),na));
4040 if (in < 0)
4041 {
4042 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4043 SvPV(ST(1),na));
4044 return;
4045 }
4046 op=(MagickEvaluateOperator) in;
4047 }
4048 else
4049 for (i=2; i < items; i+=2)
4050 {
4051 attribute=(char *) SvPV(ST(i-1),na);
4052 switch (*attribute)
4053 {
4054 case 'O':
4055 case 'o':
4056 {
4057 if (LocaleCompare(attribute,"operator") == 0)
4058 {
4059 ssize_t
4060 in;
4061
4062 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4063 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4064 if (in < 0)
4065 {
4066 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4067 SvPV(ST(i),na));
4068 return;
4069 }
4070 op=(MagickEvaluateOperator) in;
4071 break;
4072 }
4073 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4074 attribute);
4075 break;
4076 }
4077 default:
4078 {
4079 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4080 attribute);
4081 break;
4082 }
4083 }
4084 }
4085 image=EvaluateImages(image,op,exception);
4086 if (image == (Image *) NULL)
4087 goto PerlException;
4088 /*
4089 Create blessed Perl array for the returned image.
4090 */
4091 av=newAV();
4092 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4093 SvREFCNT_dec(av);
4094 AddImageToRegistry(sv,image);
4095 rv=newRV(sv);
4096 av_push(av,sv_bless(rv,hv));
4097 SvREFCNT_dec(sv);
4098 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004099 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4100 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004101 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4102 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004103 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004104 SetImageInfo(info->image_info,0,exception);
4105 exception=DestroyExceptionInfo(exception);
4106 SvREFCNT_dec(perl_exception);
4107 XSRETURN(1);
4108
4109 PerlException:
4110 InheritPerlException(exception,perl_exception);
4111 exception=DestroyExceptionInfo(exception);
4112 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4113 SvPOK_on(perl_exception);
4114 ST(0)=sv_2mortal(perl_exception);
4115 XSRETURN(1);
4116 }
4117
4118#
4119###############################################################################
4120# #
4121# #
4122# #
4123# F e a t u r e s #
4124# #
4125# #
4126# #
4127###############################################################################
4128#
4129#
4130void
4131Features(ref,...)
4132 Image::Magick ref=NO_INIT
4133 ALIAS:
4134 FeaturesImage = 1
4135 features = 2
4136 featuresimage = 3
4137 PPCODE:
4138 {
4139#define ChannelFeatures(channel,direction) \
4140{ \
Cristyb1710fe2017-02-11 13:51:48 -05004141 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004142 channel_features[channel].angular_second_moment[direction]); \
4143 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004144 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004145 channel_features[channel].contrast[direction]); \
4146 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004147 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004148 channel_features[channel].contrast[direction]); \
4149 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004150 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004151 channel_features[channel].variance_sum_of_squares[direction]); \
4152 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004153 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004154 channel_features[channel].inverse_difference_moment[direction]); \
4155 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004156 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004157 channel_features[channel].sum_average[direction]); \
4158 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004159 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004160 channel_features[channel].sum_variance[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].sum_entropy[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].entropy[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].difference_variance[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].difference_entropy[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].measure_of_correlation_1[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].measure_of_correlation_2[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].maximum_correlation_coefficient[direction]); \
4182 PUSHs(sv_2mortal(newSVpv(message,0))); \
4183}
4184
4185 AV
4186 *av;
4187
4188 char
4189 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004190 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004191
4192 ChannelFeatures
4193 *channel_features;
4194
4195 double
4196 distance;
4197
4198 ExceptionInfo
4199 *exception;
4200
4201 Image
4202 *image;
4203
4204 register ssize_t
4205 i;
4206
4207 ssize_t
4208 count;
4209
4210 struct PackageInfo
4211 *info;
4212
4213 SV
4214 *perl_exception,
4215 *reference;
4216
4217 PERL_UNUSED_VAR(ref);
4218 PERL_UNUSED_VAR(ix);
4219 exception=AcquireExceptionInfo();
4220 perl_exception=newSVpv("",0);
4221 av=NULL;
4222 if (sv_isobject(ST(0)) == 0)
4223 {
4224 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4225 PackageName);
4226 goto PerlException;
4227 }
4228 reference=SvRV(ST(0));
4229 av=newAV();
4230 SvREFCNT_dec(av);
4231 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4232 if (image == (Image *) NULL)
4233 {
4234 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4235 PackageName);
4236 goto PerlException;
4237 }
cristy7dbd9262014-07-02 17:53:42 +00004238 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004239 for (i=2; i < items; i+=2)
4240 {
4241 attribute=(char *) SvPV(ST(i-1),na);
4242 switch (*attribute)
4243 {
4244 case 'D':
4245 case 'd':
4246 {
4247 if (LocaleCompare(attribute,"distance") == 0)
4248 {
4249 distance=StringToLong((char *) SvPV(ST(1),na));
4250 break;
4251 }
4252 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4253 attribute);
4254 break;
4255 }
4256 default:
4257 {
4258 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4259 attribute);
4260 break;
4261 }
4262 }
4263 }
4264 count=0;
4265 for ( ; image; image=image->next)
4266 {
Cristy5a854dc2017-02-11 15:43:46 -05004267 register ssize_t
4268 j;
4269
cristy4a3ce0a2013-08-03 20:06:59 +00004270 channel_features=GetImageFeatures(image,distance,exception);
4271 if (channel_features == (ChannelFeatures *) NULL)
4272 continue;
4273 count++;
Cristy5a854dc2017-02-11 15:43:46 -05004274 for (j=0; j < 4; j++)
cristy4a3ce0a2013-08-03 20:06:59 +00004275 {
Cristy5a854dc2017-02-11 15:43:46 -05004276 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
4277 {
4278 PixelChannel channel=GetPixelChannelChannel(image,i);
4279 PixelTrait traits=GetPixelChannelTraits(image,channel);
4280 if (traits == UndefinedPixelTrait)
4281 continue;
4282 EXTEND(sp,14*(i+1)*count);
4283 ChannelFeatures(channel,j);
4284 }
cristy4a3ce0a2013-08-03 20:06:59 +00004285 }
4286 channel_features=(ChannelFeatures *)
4287 RelinquishMagickMemory(channel_features);
4288 }
4289
4290 PerlException:
4291 InheritPerlException(exception,perl_exception);
4292 exception=DestroyExceptionInfo(exception);
4293 SvREFCNT_dec(perl_exception);
4294 }
4295
4296#
4297###############################################################################
4298# #
4299# #
4300# #
4301# F l a t t e n #
4302# #
4303# #
4304# #
4305###############################################################################
4306#
4307#
4308void
4309Flatten(ref)
4310 Image::Magick ref=NO_INIT
4311 ALIAS:
4312 FlattenImage = 1
4313 flatten = 2
4314 flattenimage = 3
4315 PPCODE:
4316 {
4317 AV
4318 *av;
4319
4320 char
4321 *attribute,
4322 *p;
4323
4324 ExceptionInfo
4325 *exception;
4326
4327 HV
4328 *hv;
4329
4330 Image
4331 *image;
4332
4333 PixelInfo
4334 background_color;
4335
4336 register ssize_t
4337 i;
4338
4339 struct PackageInfo
4340 *info;
4341
4342 SV
4343 *perl_exception,
4344 *reference,
4345 *rv,
4346 *sv;
4347
4348 PERL_UNUSED_VAR(ref);
4349 PERL_UNUSED_VAR(ix);
4350 exception=AcquireExceptionInfo();
4351 perl_exception=newSVpv("",0);
4352 sv=NULL;
4353 if (sv_isobject(ST(0)) == 0)
4354 {
4355 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4356 PackageName);
4357 goto PerlException;
4358 }
4359 reference=SvRV(ST(0));
4360 hv=SvSTASH(reference);
4361 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4362 if (image == (Image *) NULL)
4363 {
4364 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4365 PackageName);
4366 goto PerlException;
4367 }
4368 background_color=image->background_color;
4369 if (items == 2)
4370 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4371 &background_color,exception);
4372 else
4373 for (i=2; i < items; i+=2)
4374 {
4375 attribute=(char *) SvPV(ST(i-1),na);
4376 switch (*attribute)
4377 {
4378 case 'B':
4379 case 'b':
4380 {
4381 if (LocaleCompare(attribute,"background") == 0)
4382 {
4383 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4384 AllCompliance,&background_color,exception);
4385 break;
4386 }
4387 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4388 attribute);
4389 break;
4390 }
4391 default:
4392 {
4393 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4394 attribute);
4395 break;
4396 }
4397 }
4398 }
4399 image->background_color=background_color;
4400 image=MergeImageLayers(image,FlattenLayer,exception);
4401 if (image == (Image *) NULL)
4402 goto PerlException;
4403 /*
4404 Create blessed Perl array for the returned image.
4405 */
4406 av=newAV();
4407 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4408 SvREFCNT_dec(av);
4409 AddImageToRegistry(sv,image);
4410 rv=newRV(sv);
4411 av_push(av,sv_bless(rv,hv));
4412 SvREFCNT_dec(sv);
4413 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004414 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4415 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004416 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4417 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004418 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004419 SetImageInfo(info->image_info,0,exception);
4420 exception=DestroyExceptionInfo(exception);
4421 SvREFCNT_dec(perl_exception);
4422 XSRETURN(1);
4423
4424 PerlException:
4425 InheritPerlException(exception,perl_exception);
4426 exception=DestroyExceptionInfo(exception);
4427 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4428 SvPOK_on(perl_exception); /* return messages in string context */
4429 ST(0)=sv_2mortal(perl_exception);
4430 XSRETURN(1);
4431 }
4432
4433#
4434###############################################################################
4435# #
4436# #
4437# #
4438# F x #
4439# #
4440# #
4441# #
4442###############################################################################
4443#
4444#
4445void
4446Fx(ref,...)
4447 Image::Magick ref=NO_INIT
4448 ALIAS:
4449 FxImage = 1
4450 fx = 2
4451 fximage = 3
4452 PPCODE:
4453 {
4454 AV
4455 *av;
4456
4457 char
4458 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004459 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004460
4461 ChannelType
4462 channel,
4463 channel_mask;
4464
4465 ExceptionInfo
4466 *exception;
4467
4468 HV
4469 *hv;
4470
4471 Image
4472 *image;
4473
4474 register ssize_t
4475 i;
4476
4477 struct PackageInfo
4478 *info;
4479
4480 SV
4481 *av_reference,
4482 *perl_exception,
4483 *reference,
4484 *rv,
4485 *sv;
4486
4487 PERL_UNUSED_VAR(ref);
4488 PERL_UNUSED_VAR(ix);
4489 exception=AcquireExceptionInfo();
4490 perl_exception=newSVpv("",0);
4491 sv=NULL;
4492 attribute=NULL;
4493 av=NULL;
4494 if (sv_isobject(ST(0)) == 0)
4495 {
4496 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4497 PackageName);
4498 goto PerlException;
4499 }
4500 reference=SvRV(ST(0));
4501 hv=SvSTASH(reference);
4502 av=newAV();
4503 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4504 SvREFCNT_dec(av);
4505 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4506 if (image == (Image *) NULL)
4507 {
4508 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4509 PackageName);
4510 goto PerlException;
4511 }
4512 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4513 /*
4514 Get options.
4515 */
4516 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004517 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004518 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004519 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004520 else
4521 for (i=2; i < items; i+=2)
4522 {
4523 attribute=(char *) SvPV(ST(i-1),na);
4524 switch (*attribute)
4525 {
4526 case 'C':
4527 case 'c':
4528 {
4529 if (LocaleCompare(attribute,"channel") == 0)
4530 {
4531 ssize_t
4532 option;
4533
4534 option=ParseChannelOption(SvPV(ST(i),na));
4535 if (option < 0)
4536 {
4537 ThrowPerlException(exception,OptionError,
4538 "UnrecognizedType",SvPV(ST(i),na));
4539 return;
4540 }
4541 channel=(ChannelType) option;
4542 break;
4543 }
4544 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4545 attribute);
4546 break;
4547 }
4548 case 'E':
4549 case 'e':
4550 {
4551 if (LocaleCompare(attribute,"expression") == 0)
4552 {
4553 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004554 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004555 break;
4556 }
4557 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4558 attribute);
4559 break;
4560 }
4561 default:
4562 {
4563 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4564 attribute);
4565 break;
4566 }
4567 }
4568 }
4569 channel_mask=SetImageChannelMask(image,channel);
4570 image=FxImage(image,expression,exception);
4571 if (image != (Image *) NULL)
4572 (void) SetImageChannelMask(image,channel_mask);
4573 if (image == (Image *) NULL)
4574 goto PerlException;
4575 for ( ; image; image=image->next)
4576 {
4577 AddImageToRegistry(sv,image);
4578 rv=newRV(sv);
4579 av_push(av,sv_bless(rv,hv));
4580 SvREFCNT_dec(sv);
4581 }
4582 exception=DestroyExceptionInfo(exception);
4583 ST(0)=av_reference;
4584 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4585 XSRETURN(1);
4586
4587 PerlException:
4588 InheritPerlException(exception,perl_exception);
4589 exception=DestroyExceptionInfo(exception);
4590 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4591 SvPOK_on(perl_exception);
4592 ST(0)=sv_2mortal(perl_exception);
4593 XSRETURN(1);
4594 }
4595
4596#
4597###############################################################################
4598# #
4599# #
4600# #
4601# G e t #
4602# #
4603# #
4604# #
4605###############################################################################
4606#
4607#
4608void
4609Get(ref,...)
4610 Image::Magick ref=NO_INIT
4611 ALIAS:
4612 GetAttributes = 1
4613 GetAttribute = 2
4614 get = 3
4615 getattributes = 4
4616 getattribute = 5
4617 PPCODE:
4618 {
4619 char
4620 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004621 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004622
4623 const char
4624 *value;
4625
4626 ExceptionInfo
4627 *exception;
4628
4629 Image
4630 *image;
4631
4632 long
4633 j;
4634
4635 register ssize_t
4636 i;
4637
4638 struct PackageInfo
4639 *info;
4640
4641 SV
4642 *perl_exception,
4643 *reference,
4644 *s;
4645
4646 PERL_UNUSED_VAR(ref);
4647 PERL_UNUSED_VAR(ix);
4648 exception=AcquireExceptionInfo();
4649 perl_exception=newSVpv("",0);
4650 if (sv_isobject(ST(0)) == 0)
4651 {
4652 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4653 PackageName);
4654 XSRETURN_EMPTY;
4655 }
4656 reference=SvRV(ST(0));
4657 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4658 if (image == (Image *) NULL && !info)
4659 XSRETURN_EMPTY;
4660 EXTEND(sp,items);
4661 for (i=1; i < items; i++)
4662 {
4663 attribute=(char *) SvPV(ST(i),na);
4664 s=NULL;
4665 switch (*attribute)
4666 {
4667 case 'A':
4668 case 'a':
4669 {
4670 if (LocaleCompare(attribute,"adjoin") == 0)
4671 {
4672 if (info)
4673 s=newSViv((ssize_t) info->image_info->adjoin);
4674 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4675 continue;
4676 }
4677 if (LocaleCompare(attribute,"antialias") == 0)
4678 {
4679 if (info)
4680 s=newSViv((ssize_t) info->image_info->antialias);
4681 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4682 continue;
4683 }
4684 if (LocaleCompare(attribute,"area") == 0)
4685 {
4686 s=newSViv(GetMagickResource(AreaResource));
4687 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4688 continue;
4689 }
4690 if (LocaleCompare(attribute,"attenuate") == 0)
4691 {
4692 const char
4693 *value;
4694
4695 value=GetImageProperty(image,attribute,exception);
4696 if (value != (const char *) NULL)
4697 s=newSVpv(value,0);
4698 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4699 continue;
4700 }
4701 if (LocaleCompare(attribute,"authenticate") == 0)
4702 {
4703 if (info)
4704 {
4705 const char
4706 *option;
4707
4708 option=GetImageOption(info->image_info,attribute);
4709 if (option != (const char *) NULL)
4710 s=newSVpv(option,0);
4711 }
4712 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4713 continue;
4714 }
4715 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4716 attribute);
4717 break;
4718 }
4719 case 'B':
4720 case 'b':
4721 {
4722 if (LocaleCompare(attribute,"background") == 0)
4723 {
4724 if (image == (Image *) NULL)
4725 break;
cristy151b66d2015-04-15 10:50:31 +00004726 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004727 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4728 (double) image->background_color.green,
4729 (double) image->background_color.blue,
4730 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004731 s=newSVpv(color,0);
4732 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4733 continue;
4734 }
4735 if (LocaleCompare(attribute,"base-columns") == 0)
4736 {
4737 if (image != (Image *) NULL)
4738 s=newSViv((ssize_t) image->magick_columns);
4739 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4740 continue;
4741 }
4742 if (LocaleCompare(attribute,"base-filename") == 0)
4743 {
4744 if (image != (Image *) NULL)
4745 s=newSVpv(image->magick_filename,0);
4746 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4747 continue;
4748 }
4749 if (LocaleCompare(attribute,"base-height") == 0)
4750 {
4751 if (image != (Image *) NULL)
4752 s=newSViv((ssize_t) image->magick_rows);
4753 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4754 continue;
4755 }
4756 if (LocaleCompare(attribute,"base-rows") == 0)
4757 {
4758 if (image != (Image *) NULL)
4759 s=newSViv((ssize_t) image->magick_rows);
4760 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4761 continue;
4762 }
4763 if (LocaleCompare(attribute,"base-width") == 0)
4764 {
4765 if (image != (Image *) NULL)
4766 s=newSViv((ssize_t) image->magick_columns);
4767 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4768 continue;
4769 }
4770 if (LocaleCompare(attribute,"blue-primary") == 0)
4771 {
4772 if (image == (Image *) NULL)
4773 break;
Cristyb1710fe2017-02-11 13:51:48 -05004774 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004775 image->chromaticity.blue_primary.x,
4776 image->chromaticity.blue_primary.y);
4777 s=newSVpv(color,0);
4778 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4779 continue;
4780 }
4781 if (LocaleCompare(attribute,"bordercolor") == 0)
4782 {
4783 if (image == (Image *) NULL)
4784 break;
cristy151b66d2015-04-15 10:50:31 +00004785 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004786 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4787 (double) image->border_color.green,
4788 (double) image->border_color.blue,
4789 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004790 s=newSVpv(color,0);
4791 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4792 continue;
4793 }
4794 if (LocaleCompare(attribute,"bounding-box") == 0)
4795 {
4796 char
cristy151b66d2015-04-15 10:50:31 +00004797 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004798
4799 RectangleInfo
4800 page;
4801
4802 if (image == (Image *) NULL)
4803 break;
4804 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004805 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004806 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4807 page.height,(double) page.x,(double) page.y);
4808 s=newSVpv(geometry,0);
4809 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4810 continue;
4811 }
4812 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4813 attribute);
4814 break;
4815 }
4816 case 'C':
4817 case 'c':
4818 {
4819 if (LocaleCompare(attribute,"class") == 0)
4820 {
4821 if (image == (Image *) NULL)
4822 break;
4823 s=newSViv(image->storage_class);
4824 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4825 image->storage_class));
4826 SvIOK_on(s);
4827 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4828 continue;
4829 }
4830 if (LocaleCompare(attribute,"clip-mask") == 0)
4831 {
4832 if (image != (Image *) NULL)
4833 {
4834 Image
4835 *mask_image;
4836
4837 SV
4838 *sv;
4839
4840 sv=NULL;
4841 if (image->read_mask == MagickFalse)
4842 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004843 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004844 if (mask_image != (Image *) NULL)
4845 {
4846 AddImageToRegistry(sv,mask_image);
4847 s=sv_bless(newRV(sv),SvSTASH(reference));
4848 }
4849 }
4850 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4851 continue;
4852 }
4853 if (LocaleCompare(attribute,"clip-path") == 0)
4854 {
4855 if (image != (Image *) NULL)
4856 {
4857 Image
4858 *mask_image;
4859
4860 SV
4861 *sv;
4862
4863 sv=NULL;
4864 if (image->read_mask != MagickFalse)
4865 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004866 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004867 if (mask_image != (Image *) NULL)
4868 {
4869 AddImageToRegistry(sv,mask_image);
4870 s=sv_bless(newRV(sv),SvSTASH(reference));
4871 }
4872 }
4873 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4874 continue;
4875 }
4876 if (LocaleCompare(attribute,"compression") == 0)
4877 {
4878 j=info ? info->image_info->compression : image ?
4879 image->compression : UndefinedCompression;
4880 if (info)
4881 if (info->image_info->compression == UndefinedCompression)
4882 j=image->compression;
4883 s=newSViv(j);
4884 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4885 j));
4886 SvIOK_on(s);
4887 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4888 continue;
4889 }
4890 if (LocaleCompare(attribute,"colorspace") == 0)
4891 {
4892 j=image ? image->colorspace : RGBColorspace;
4893 s=newSViv(j);
4894 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4895 j));
4896 SvIOK_on(s);
4897 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4898 continue;
4899 }
4900 if (LocaleCompare(attribute,"colors") == 0)
4901 {
4902 if (image != (Image *) NULL)
4903 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4904 exception));
4905 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4906 continue;
4907 }
4908 if (LocaleNCompare(attribute,"colormap",8) == 0)
4909 {
4910 int
4911 items;
4912
4913 if (image == (Image *) NULL || !image->colormap)
4914 break;
4915 j=0;
4916 items=sscanf(attribute,"%*[^[][%ld",&j);
4917 (void) items;
4918 if (j > (ssize_t) image->colors)
4919 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004920 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004921 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4922 (double) image->colormap[j].green,
4923 (double) image->colormap[j].blue,
4924 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004925 s=newSVpv(color,0);
4926 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4927 continue;
4928 }
4929 if (LocaleCompare(attribute,"columns") == 0)
4930 {
4931 if (image != (Image *) NULL)
4932 s=newSViv((ssize_t) image->columns);
4933 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4934 continue;
4935 }
4936 if (LocaleCompare(attribute,"comment") == 0)
4937 {
4938 const char
4939 *value;
4940
Cristy935a4052017-03-31 17:45:37 -04004941 value=GetImageProperty(image,attribute,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004942 if (value != (const char *) NULL)
4943 s=newSVpv(value,0);
4944 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4945 continue;
4946 }
4947 if (LocaleCompare(attribute,"copyright") == 0)
4948 {
4949 s=newSVpv(GetMagickCopyright(),0);
4950 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4951 continue;
4952 }
4953 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4954 attribute);
4955 break;
4956 }
4957 case 'D':
4958 case 'd':
4959 {
4960 if (LocaleCompare(attribute,"density") == 0)
4961 {
4962 char
cristy151b66d2015-04-15 10:50:31 +00004963 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004964
4965 if (image == (Image *) NULL)
4966 break;
Cristyb1710fe2017-02-11 13:51:48 -05004967 (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004968 image->resolution.x,image->resolution.y);
4969 s=newSVpv(geometry,0);
4970 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4971 continue;
4972 }
4973 if (LocaleCompare(attribute,"delay") == 0)
4974 {
4975 if (image != (Image *) NULL)
4976 s=newSViv((ssize_t) image->delay);
4977 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4978 continue;
4979 }
4980 if (LocaleCompare(attribute,"depth") == 0)
4981 {
4982 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4983 if (image != (Image *) NULL)
4984 s=newSViv((ssize_t) GetImageDepth(image,exception));
4985 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4986 continue;
4987 }
4988 if (LocaleCompare(attribute,"directory") == 0)
4989 {
4990 if (image && image->directory)
4991 s=newSVpv(image->directory,0);
4992 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4993 continue;
4994 }
4995 if (LocaleCompare(attribute,"dispose") == 0)
4996 {
4997 if (image == (Image *) NULL)
4998 break;
4999
5000 s=newSViv(image->dispose);
5001 (void) sv_setpv(s,
5002 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
5003 SvIOK_on(s);
5004 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5005 continue;
5006 }
5007 if (LocaleCompare(attribute,"disk") == 0)
5008 {
5009 s=newSViv(GetMagickResource(DiskResource));
5010 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5011 continue;
5012 }
5013 if (LocaleCompare(attribute,"dither") == 0)
5014 {
5015 if (info)
5016 s=newSViv((ssize_t) info->image_info->dither);
5017 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5018 continue;
5019 }
5020 if (LocaleCompare(attribute,"display") == 0) /* same as server */
5021 {
5022 if (info && info->image_info->server_name)
5023 s=newSVpv(info->image_info->server_name,0);
5024 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5025 continue;
5026 }
5027 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5028 attribute);
5029 break;
5030 }
5031 case 'E':
5032 case 'e':
5033 {
5034 if (LocaleCompare(attribute,"elapsed-time") == 0)
5035 {
5036 if (image != (Image *) NULL)
5037 s=newSVnv(GetElapsedTime(&image->timer));
5038 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5039 continue;
5040 }
5041 if (LocaleCompare(attribute,"endian") == 0)
5042 {
5043 j=info ? info->image_info->endian : image ? image->endian :
5044 UndefinedEndian;
5045 s=newSViv(j);
5046 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
5047 SvIOK_on(s);
5048 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5049 continue;
5050 }
5051 if (LocaleCompare(attribute,"error") == 0)
5052 {
5053 if (image != (Image *) NULL)
5054 s=newSVnv(image->error.mean_error_per_pixel);
5055 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5056 continue;
5057 }
5058 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5059 attribute);
5060 break;
5061 }
5062 case 'F':
5063 case 'f':
5064 {
5065 if (LocaleCompare(attribute,"filesize") == 0)
5066 {
5067 if (image != (Image *) NULL)
5068 s=newSViv((ssize_t) GetBlobSize(image));
5069 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5070 continue;
5071 }
5072 if (LocaleCompare(attribute,"filename") == 0)
5073 {
Cristy2273d6a2017-07-14 19:19:55 -04005074 if (info && *info->image_info->filename)
cristy4a3ce0a2013-08-03 20:06:59 +00005075 s=newSVpv(info->image_info->filename,0);
5076 if (image != (Image *) NULL)
5077 s=newSVpv(image->filename,0);
5078 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5079 continue;
5080 }
5081 if (LocaleCompare(attribute,"filter") == 0)
5082 {
5083 s=image ? newSViv(image->filter) : newSViv(0);
5084 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5085 image->filter));
5086 SvIOK_on(s);
5087 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5088 continue;
5089 }
5090 if (LocaleCompare(attribute,"font") == 0)
5091 {
5092 if (info && info->image_info->font)
5093 s=newSVpv(info->image_info->font,0);
5094 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5095 continue;
5096 }
5097 if (LocaleCompare(attribute,"foreground") == 0)
5098 continue;
5099 if (LocaleCompare(attribute,"format") == 0)
5100 {
5101 const MagickInfo
5102 *magick_info;
5103
5104 magick_info=(const MagickInfo *) NULL;
5105 if (info && (*info->image_info->magick != '\0'))
5106 magick_info=GetMagickInfo(info->image_info->magick,exception);
5107 if (image != (Image *) NULL)
5108 magick_info=GetMagickInfo(image->magick,exception);
5109 if ((magick_info != (const MagickInfo *) NULL) &&
5110 (*magick_info->description != '\0'))
5111 s=newSVpv((char *) magick_info->description,0);
5112 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5113 continue;
5114 }
5115 if (LocaleCompare(attribute,"fuzz") == 0)
5116 {
5117 if (info)
5118 s=newSVnv(info->image_info->fuzz);
5119 if (image != (Image *) NULL)
5120 s=newSVnv(image->fuzz);
5121 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5122 continue;
5123 }
5124 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5125 attribute);
5126 break;
5127 }
5128 case 'G':
5129 case 'g':
5130 {
5131 if (LocaleCompare(attribute,"gamma") == 0)
5132 {
5133 if (image != (Image *) NULL)
5134 s=newSVnv(image->gamma);
5135 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5136 continue;
5137 }
5138 if (LocaleCompare(attribute,"geometry") == 0)
5139 {
5140 if (image && image->geometry)
5141 s=newSVpv(image->geometry,0);
5142 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5143 continue;
5144 }
5145 if (LocaleCompare(attribute,"gravity") == 0)
5146 {
5147 s=image ? newSViv(image->gravity) : newSViv(0);
5148 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5149 image->gravity));
5150 SvIOK_on(s);
5151 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5152 continue;
5153 }
5154 if (LocaleCompare(attribute,"green-primary") == 0)
5155 {
5156 if (image == (Image *) NULL)
5157 break;
Cristyb1710fe2017-02-11 13:51:48 -05005158 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005159 image->chromaticity.green_primary.x,
5160 image->chromaticity.green_primary.y);
5161 s=newSVpv(color,0);
5162 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5163 continue;
5164 }
5165 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5166 attribute);
5167 break;
5168 }
5169 case 'H':
5170 case 'h':
5171 {
5172 if (LocaleCompare(attribute,"height") == 0)
5173 {
5174 if (image != (Image *) NULL)
5175 s=newSViv((ssize_t) image->rows);
5176 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5177 continue;
5178 }
5179 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5180 attribute);
5181 break;
5182 }
5183 case 'I':
5184 case 'i':
5185 {
5186 if (LocaleCompare(attribute,"icc") == 0)
5187 {
5188 if (image != (Image *) NULL)
5189 {
5190 const StringInfo
5191 *profile;
5192
5193 profile=GetImageProfile(image,"icc");
5194 if (profile != (StringInfo *) NULL)
5195 s=newSVpv((const char *) GetStringInfoDatum(profile),
5196 GetStringInfoLength(profile));
5197 }
5198 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5199 continue;
5200 }
5201 if (LocaleCompare(attribute,"icm") == 0)
5202 {
5203 if (image != (Image *) NULL)
5204 {
5205 const StringInfo
5206 *profile;
5207
5208 profile=GetImageProfile(image,"icm");
5209 if (profile != (const StringInfo *) NULL)
5210 s=newSVpv((const char *) GetStringInfoDatum(profile),
5211 GetStringInfoLength(profile));
5212 }
5213 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5214 continue;
5215 }
5216 if (LocaleCompare(attribute,"id") == 0)
5217 {
5218 if (image != (Image *) NULL)
5219 {
5220 char
cristy151b66d2015-04-15 10:50:31 +00005221 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005222
5223 MagickBooleanType
5224 status;
5225
5226 static ssize_t
5227 id = 0;
5228
cristy151b66d2015-04-15 10:50:31 +00005229 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005230 id);
5231 status=SetImageRegistry(ImageRegistryType,key,image,
5232 exception);
5233 (void) status;
5234 s=newSViv(id++);
5235 }
5236 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5237 continue;
5238 }
5239 if (LocaleNCompare(attribute,"index",5) == 0)
5240 {
5241 char
cristy151b66d2015-04-15 10:50:31 +00005242 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005243
5244 int
5245 items;
5246
5247 long
5248 x,
5249 y;
5250
5251 register const Quantum
5252 *p;
5253
5254 CacheView
5255 *image_view;
5256
5257 if (image == (Image *) NULL)
5258 break;
5259 if (image->storage_class != PseudoClass)
5260 break;
5261 x=0;
5262 y=0;
5263 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5264 (void) items;
5265 image_view=AcquireVirtualCacheView(image,exception);
5266 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5267 if (p != (const Quantum *) NULL)
5268 {
cristy151b66d2015-04-15 10:50:31 +00005269 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005270 GetPixelIndex(image,p));
5271 s=newSVpv(name,0);
5272 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5273 }
5274 image_view=DestroyCacheView(image_view);
5275 continue;
5276 }
5277 if (LocaleCompare(attribute,"iptc") == 0)
5278 {
5279 if (image != (Image *) NULL)
5280 {
5281 const StringInfo
5282 *profile;
5283
5284 profile=GetImageProfile(image,"iptc");
5285 if (profile != (const StringInfo *) NULL)
5286 s=newSVpv((const char *) GetStringInfoDatum(profile),
5287 GetStringInfoLength(profile));
5288 }
5289 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5290 continue;
5291 }
5292 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5293 {
5294 if (image != (Image *) NULL)
5295 s=newSViv((ssize_t) image->iterations);
5296 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5297 continue;
5298 }
5299 if (LocaleCompare(attribute,"interlace") == 0)
5300 {
5301 j=info ? info->image_info->interlace : image ? image->interlace :
5302 UndefinedInterlace;
5303 s=newSViv(j);
5304 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5305 j));
5306 SvIOK_on(s);
5307 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5308 continue;
5309 }
5310 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5311 attribute);
5312 break;
5313 }
5314 case 'L':
5315 case 'l':
5316 {
5317 if (LocaleCompare(attribute,"label") == 0)
5318 {
5319 const char
5320 *value;
5321
5322 if (image == (Image *) NULL)
5323 break;
Cristy935a4052017-03-31 17:45:37 -04005324 value=GetImageProperty(image,"Label",exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005325 if (value != (const char *) NULL)
5326 s=newSVpv(value,0);
5327 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5328 continue;
5329 }
5330 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5331 {
5332 if (image != (Image *) NULL)
5333 s=newSViv((ssize_t) image->iterations);
5334 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5335 continue;
5336 }
5337 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5338 attribute);
5339 break;
5340 }
5341 case 'M':
5342 case 'm':
5343 {
5344 if (LocaleCompare(attribute,"magick") == 0)
5345 {
5346 if (info && *info->image_info->magick)
5347 s=newSVpv(info->image_info->magick,0);
5348 if (image != (Image *) NULL)
5349 s=newSVpv(image->magick,0);
5350 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5351 continue;
5352 }
5353 if (LocaleCompare(attribute,"map") == 0)
5354 {
5355 s=newSViv(GetMagickResource(MapResource));
5356 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5357 continue;
5358 }
5359 if (LocaleCompare(attribute,"maximum-error") == 0)
5360 {
5361 if (image != (Image *) NULL)
5362 s=newSVnv(image->error.normalized_maximum_error);
5363 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5364 continue;
5365 }
5366 if (LocaleCompare(attribute,"memory") == 0)
5367 {
5368 s=newSViv(GetMagickResource(MemoryResource));
5369 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5370 continue;
5371 }
5372 if (LocaleCompare(attribute,"mean-error") == 0)
5373 {
5374 if (image != (Image *) NULL)
5375 s=newSVnv(image->error.normalized_mean_error);
5376 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5377 continue;
5378 }
5379 if (LocaleCompare(attribute,"mime") == 0)
5380 {
5381 if (info && *info->image_info->magick)
5382 s=newSVpv(MagickToMime(info->image_info->magick),0);
5383 if (image != (Image *) NULL)
5384 s=newSVpv(MagickToMime(image->magick),0);
5385 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5386 continue;
5387 }
5388 if (LocaleCompare(attribute,"mattecolor") == 0)
5389 {
5390 if (image == (Image *) NULL)
5391 break;
cristy151b66d2015-04-15 10:50:31 +00005392 (void) FormatLocaleString(color,MagickPathExtent,
Cristy8645e042016-02-03 16:35:29 -05005393 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5394 (double) image->alpha_color.green,
5395 (double) image->alpha_color.blue,
5396 (double) image->alpha_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005397 s=newSVpv(color,0);
5398 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5399 continue;
5400 }
5401 if (LocaleCompare(attribute,"matte") == 0)
5402 {
5403 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005404 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005405 1 : 0);
5406 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5407 continue;
5408 }
5409 if (LocaleCompare(attribute,"mime") == 0)
5410 {
5411 const char
5412 *magick;
5413
5414 magick=NULL;
5415 if (info && *info->image_info->magick)
5416 magick=info->image_info->magick;
5417 if (image != (Image *) NULL)
5418 magick=image->magick;
5419 if (magick)
5420 {
5421 char
5422 *mime;
5423
5424 mime=MagickToMime(magick);
5425 s=newSVpv(mime,0);
5426 mime=(char *) RelinquishMagickMemory(mime);
5427 }
5428 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5429 continue;
5430 }
5431 if (LocaleCompare(attribute,"monochrome") == 0)
5432 {
5433 if (image == (Image *) NULL)
5434 continue;
5435 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005436 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005437 s=newSViv(j);
5438 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5439 continue;
5440 }
5441 if (LocaleCompare(attribute,"montage") == 0)
5442 {
5443 if (image && image->montage)
5444 s=newSVpv(image->montage,0);
5445 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5446 continue;
5447 }
5448 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5449 attribute);
5450 break;
5451 }
5452 case 'O':
5453 case 'o':
5454 {
5455 if (LocaleCompare(attribute,"orientation") == 0)
5456 {
5457 j=info ? info->image_info->orientation : image ?
5458 image->orientation : UndefinedOrientation;
5459 s=newSViv(j);
5460 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5461 j));
5462 SvIOK_on(s);
5463 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5464 continue;
5465 }
5466 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5467 attribute);
5468 break;
5469 }
5470 case 'P':
5471 case 'p':
5472 {
5473 if (LocaleCompare(attribute,"page") == 0)
5474 {
5475 if (info && info->image_info->page)
5476 s=newSVpv(info->image_info->page,0);
5477 if (image != (Image *) NULL)
5478 {
5479 char
cristy151b66d2015-04-15 10:50:31 +00005480 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005481
cristy151b66d2015-04-15 10:50:31 +00005482 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005483 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5484 (double) image->page.height,(double) image->page.x,(double)
5485 image->page.y);
5486 s=newSVpv(geometry,0);
5487 }
5488 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5489 continue;
5490 }
5491 if (LocaleCompare(attribute,"page.x") == 0)
5492 {
5493 if (image != (Image *) NULL)
5494 s=newSViv((ssize_t) image->page.x);
5495 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5496 continue;
5497 }
5498 if (LocaleCompare(attribute,"page.y") == 0)
5499 {
5500 if (image != (Image *) NULL)
5501 s=newSViv((ssize_t) image->page.y);
5502 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5503 continue;
5504 }
5505 if (LocaleNCompare(attribute,"pixel",5) == 0)
5506 {
5507 char
cristy151b66d2015-04-15 10:50:31 +00005508 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005509
5510 int
5511 items;
5512
5513 long
5514 x,
5515 y;
5516
5517 register const Quantum
5518 *p;
5519
5520 if (image == (Image *) NULL)
5521 break;
5522 x=0;
5523 y=0;
5524 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5525 (void) items;
5526 p=GetVirtualPixels(image,x,y,1,1,exception);
5527 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005528 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005529 QuantumFormat "," QuantumFormat "," QuantumFormat,
5530 GetPixelRed(image,p),GetPixelGreen(image,p),
5531 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5532 else
cristy151b66d2015-04-15 10:50:31 +00005533 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005534 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5535 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5536 GetPixelBlue(image,p),GetPixelBlack(image,p),
5537 GetPixelAlpha(image,p));
5538 s=newSVpv(tuple,0);
5539 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5540 continue;
5541 }
5542 if (LocaleCompare(attribute,"pointsize") == 0)
5543 {
5544 if (info)
5545 s=newSViv((ssize_t) info->image_info->pointsize);
5546 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5547 continue;
5548 }
cristy4a3ce0a2013-08-03 20:06:59 +00005549 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5550 attribute);
5551 break;
5552 }
5553 case 'Q':
5554 case 'q':
5555 {
5556 if (LocaleCompare(attribute,"quality") == 0)
5557 {
5558 if (info)
5559 s=newSViv((ssize_t) info->image_info->quality);
5560 if (image != (Image *) NULL)
5561 s=newSViv((ssize_t) image->quality);
5562 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5563 continue;
5564 }
5565 if (LocaleCompare(attribute,"quantum") == 0)
5566 {
5567 if (info)
5568 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5569 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5570 continue;
5571 }
5572 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5573 attribute);
5574 break;
5575 }
5576 case 'R':
5577 case 'r':
5578 {
5579 if (LocaleCompare(attribute,"rendering-intent") == 0)
5580 {
5581 s=newSViv(image->rendering_intent);
5582 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5583 image->rendering_intent));
5584 SvIOK_on(s);
5585 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5586 continue;
5587 }
5588 if (LocaleCompare(attribute,"red-primary") == 0)
5589 {
5590 if (image == (Image *) NULL)
5591 break;
Cristyb1710fe2017-02-11 13:51:48 -05005592 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005593 image->chromaticity.red_primary.x,
5594 image->chromaticity.red_primary.y);
5595 s=newSVpv(color,0);
5596 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5597 continue;
5598 }
5599 if (LocaleCompare(attribute,"rows") == 0)
5600 {
5601 if (image != (Image *) NULL)
5602 s=newSViv((ssize_t) image->rows);
5603 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5604 continue;
5605 }
5606 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5607 attribute);
5608 break;
5609 }
5610 case 'S':
5611 case 's':
5612 {
5613 if (LocaleCompare(attribute,"sampling-factor") == 0)
5614 {
5615 if (info && info->image_info->sampling_factor)
5616 s=newSVpv(info->image_info->sampling_factor,0);
5617 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5618 continue;
5619 }
5620 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5621 {
5622 if (info && info->image_info->server_name)
5623 s=newSVpv(info->image_info->server_name,0);
5624 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5625 continue;
5626 }
5627 if (LocaleCompare(attribute,"size") == 0)
5628 {
5629 if (info && info->image_info->size)
5630 s=newSVpv(info->image_info->size,0);
5631 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5632 continue;
5633 }
5634 if (LocaleCompare(attribute,"scene") == 0)
5635 {
5636 if (image != (Image *) NULL)
5637 s=newSViv((ssize_t) image->scene);
5638 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5639 continue;
5640 }
5641 if (LocaleCompare(attribute,"scenes") == 0)
5642 {
5643 if (image != (Image *) NULL)
5644 s=newSViv((ssize_t) info->image_info->number_scenes);
5645 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5646 continue;
5647 }
5648 if (LocaleCompare(attribute,"signature") == 0)
5649 {
5650 const char
5651 *value;
5652
5653 if (image == (Image *) NULL)
5654 break;
5655 (void) SignatureImage(image,exception);
5656 value=GetImageProperty(image,"Signature",exception);
5657 if (value != (const char *) NULL)
5658 s=newSVpv(value,0);
5659 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5660 continue;
5661 }
5662 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5663 attribute);
5664 break;
5665 }
5666 case 'T':
5667 case 't':
5668 {
5669 if (LocaleCompare(attribute,"taint") == 0)
5670 {
5671 if (image != (Image *) NULL)
5672 s=newSViv((ssize_t) IsTaintImage(image));
5673 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5674 continue;
5675 }
5676 if (LocaleCompare(attribute,"texture") == 0)
5677 {
5678 if (info && info->image_info->texture)
5679 s=newSVpv(info->image_info->texture,0);
5680 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5681 continue;
5682 }
5683 if (LocaleCompare(attribute,"total-ink-density") == 0)
5684 {
5685 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5686 if (image != (Image *) NULL)
5687 s=newSVnv(GetImageTotalInkDensity(image,exception));
5688 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5689 continue;
5690 }
5691 if (LocaleCompare(attribute,"transparent-color") == 0)
5692 {
5693 if (image == (Image *) NULL)
5694 break;
cristy151b66d2015-04-15 10:50:31 +00005695 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005696 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5697 (double) image->transparent_color.green,
5698 (double) image->transparent_color.blue,
5699 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005700 s=newSVpv(color,0);
5701 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5702 continue;
5703 }
5704 if (LocaleCompare(attribute,"type") == 0)
5705 {
5706 if (image == (Image *) NULL)
5707 break;
cristya26f54c2015-07-29 12:26:12 +00005708 j=(ssize_t) GetImageType(image);
cristy4a3ce0a2013-08-03 20:06:59 +00005709 s=newSViv(j);
5710 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5711 SvIOK_on(s);
5712 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5713 continue;
5714 }
5715 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5716 attribute);
5717 break;
5718 }
5719 case 'U':
5720 case 'u':
5721 {
5722 if (LocaleCompare(attribute,"units") == 0)
5723 {
5724 j=info ? info->image_info->units : image ? image->units :
5725 UndefinedResolution;
5726 if (info && (info->image_info->units == UndefinedResolution))
5727 if (image)
5728 j=image->units;
5729 if (j == UndefinedResolution)
5730 s=newSVpv("undefined units",0);
5731 else
5732 if (j == PixelsPerInchResolution)
5733 s=newSVpv("pixels / inch",0);
5734 else
5735 s=newSVpv("pixels / centimeter",0);
5736 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5737 continue;
5738 }
5739 if (LocaleCompare(attribute,"user-time") == 0)
5740 {
5741 if (image != (Image *) NULL)
5742 s=newSVnv(GetUserTime(&image->timer));
5743 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5744 continue;
5745 }
5746 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5747 attribute);
5748 break;
5749 }
5750 case 'V':
5751 case 'v':
5752 {
5753 if (LocaleCompare(attribute,"verbose") == 0)
5754 {
5755 if (info)
5756 s=newSViv((ssize_t) info->image_info->verbose);
5757 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5758 continue;
5759 }
5760 if (LocaleCompare(attribute,"version") == 0)
5761 {
5762 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5763 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5764 continue;
5765 }
cristy4a3ce0a2013-08-03 20:06:59 +00005766 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5767 {
5768 if (image == (Image *) NULL)
5769 break;
5770 j=(ssize_t) GetImageVirtualPixelMethod(image);
5771 s=newSViv(j);
5772 (void) sv_setpv(s,CommandOptionToMnemonic(
5773 MagickVirtualPixelOptions,j));
5774 SvIOK_on(s);
5775 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5776 continue;
5777 }
5778 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5779 attribute);
5780 break;
5781 }
5782 case 'W':
5783 case 'w':
5784 {
5785 if (LocaleCompare(attribute,"white-point") == 0)
5786 {
5787 if (image == (Image *) NULL)
5788 break;
Cristyb1710fe2017-02-11 13:51:48 -05005789 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005790 image->chromaticity.white_point.x,
5791 image->chromaticity.white_point.y);
5792 s=newSVpv(color,0);
5793 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5794 continue;
5795 }
5796 if (LocaleCompare(attribute,"width") == 0)
5797 {
5798 if (image != (Image *) NULL)
5799 s=newSViv((ssize_t) image->columns);
5800 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5801 continue;
5802 }
5803 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5804 attribute);
5805 break;
5806 }
5807 case 'X':
5808 case 'x':
5809 {
Cristyc1f9f9f2016-01-05 08:19:28 -05005810 if (LocaleCompare(attribute,"xmp") == 0)
5811 {
5812 if (image != (Image *) NULL)
5813 {
5814 const StringInfo
5815 *profile;
5816
5817 profile=GetImageProfile(image,"xmp");
5818 if (profile != (StringInfo *) NULL)
5819 s=newSVpv((const char *) GetStringInfoDatum(profile),
5820 GetStringInfoLength(profile));
5821 }
5822 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5823 continue;
5824 }
cristy4a3ce0a2013-08-03 20:06:59 +00005825 if (LocaleCompare(attribute,"x-resolution") == 0)
5826 {
5827 if (image != (Image *) NULL)
5828 s=newSVnv(image->resolution.x);
5829 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5830 continue;
5831 }
5832 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5833 attribute);
5834 break;
5835 }
5836 case 'Y':
5837 case 'y':
5838 {
5839 if (LocaleCompare(attribute,"y-resolution") == 0)
5840 {
5841 if (image != (Image *) NULL)
5842 s=newSVnv(image->resolution.y);
5843 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5844 continue;
5845 }
5846 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5847 attribute);
5848 break;
5849 }
5850 default:
5851 break;
5852 }
5853 if (image == (Image *) NULL)
5854 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5855 attribute)
5856 else
5857 {
5858 value=GetImageProperty(image,attribute,exception);
5859 if (value != (const char *) NULL)
5860 {
5861 s=newSVpv(value,0);
5862 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5863 }
5864 else
5865 if (*attribute != '%')
5866 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5867 attribute)
5868 else
5869 {
5870 char
5871 *meta;
5872
5873 meta=InterpretImageProperties(info ? info->image_info :
5874 (ImageInfo *) NULL,image,attribute,exception);
5875 s=newSVpv(meta,0);
5876 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5877 meta=(char *) RelinquishMagickMemory(meta);
5878 }
5879 }
5880 }
5881 exception=DestroyExceptionInfo(exception);
5882 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5883 }
5884
5885#
5886###############################################################################
5887# #
5888# #
5889# #
5890# G e t A u t h e n t i c P i x e l s #
5891# #
5892# #
5893# #
5894###############################################################################
5895#
5896#
5897void *
5898GetAuthenticPixels(ref,...)
5899 Image::Magick ref = NO_INIT
5900 ALIAS:
5901 getauthenticpixels = 1
5902 GetImagePixels = 2
5903 getimagepixels = 3
5904 CODE:
5905 {
5906 char
5907 *attribute;
5908
5909 ExceptionInfo
5910 *exception;
5911
5912 Image
5913 *image;
5914
5915 RectangleInfo
5916 region;
5917
5918 ssize_t
5919 i;
5920
5921 struct PackageInfo
5922 *info;
5923
5924 SV
5925 *perl_exception,
5926 *reference;
5927
5928 void
5929 *blob = NULL;
5930
5931 PERL_UNUSED_VAR(ref);
5932 PERL_UNUSED_VAR(ix);
5933 exception=AcquireExceptionInfo();
5934 perl_exception=newSVpv("",0);
5935 if (sv_isobject(ST(0)) == 0)
5936 {
5937 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5938 PackageName);
5939 goto PerlException;
5940 }
5941 reference=SvRV(ST(0));
5942
5943 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5944 if (image == (Image *) NULL)
5945 {
5946 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5947 PackageName);
5948 goto PerlException;
5949 }
5950
5951 region.x=0;
5952 region.y=0;
5953 region.width=image->columns;
5954 region.height=1;
5955 if (items == 1)
5956 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5957 for (i=2; i < items; i+=2)
5958 {
5959 attribute=(char *) SvPV(ST(i-1),na);
5960 switch (*attribute)
5961 {
5962 case 'g':
5963 case 'G':
5964 {
5965 if (LocaleCompare(attribute,"geometry") == 0)
5966 {
5967 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5968 break;
5969 }
5970 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5971 attribute);
5972 break;
5973 }
5974 case 'H':
5975 case 'h':
5976 {
5977 if (LocaleCompare(attribute,"height") == 0)
5978 {
5979 region.height=SvIV(ST(i));
5980 continue;
5981 }
5982 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5983 attribute);
5984 break;
5985 }
5986 case 'X':
5987 case 'x':
5988 {
5989 if (LocaleCompare(attribute,"x") == 0)
5990 {
5991 region.x=SvIV(ST(i));
5992 continue;
5993 }
5994 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5995 attribute);
5996 break;
5997 }
5998 case 'Y':
5999 case 'y':
6000 {
6001 if (LocaleCompare(attribute,"y") == 0)
6002 {
6003 region.y=SvIV(ST(i));
6004 continue;
6005 }
6006 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6007 attribute);
6008 break;
6009 }
6010 case 'W':
6011 case 'w':
6012 {
6013 if (LocaleCompare(attribute,"width") == 0)
6014 {
6015 region.width=SvIV(ST(i));
6016 continue;
6017 }
6018 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6019 attribute);
6020 break;
6021 }
6022 }
6023 }
6024 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
6025 region.height,exception);
6026 if (blob != (void *) NULL)
6027 goto PerlEnd;
6028
6029 PerlException:
6030 InheritPerlException(exception,perl_exception);
6031 exception=DestroyExceptionInfo(exception);
6032 SvREFCNT_dec(perl_exception); /* throw away all errors */
6033
6034 PerlEnd:
6035 RETVAL = blob;
6036 }
6037 OUTPUT:
6038 RETVAL
6039
6040#
6041###############################################################################
6042# #
6043# #
6044# #
6045# G e t V i r t u a l P i x e l s #
6046# #
6047# #
6048# #
6049###############################################################################
6050#
6051#
6052void *
6053GetVirtualPixels(ref,...)
6054 Image::Magick ref = NO_INIT
6055 ALIAS:
6056 getvirtualpixels = 1
6057 AcquireImagePixels = 2
6058 acquireimagepixels = 3
6059 CODE:
6060 {
6061 char
6062 *attribute;
6063
6064 const void
6065 *blob = NULL;
6066
6067 ExceptionInfo
6068 *exception;
6069
6070 Image
6071 *image;
6072
6073 RectangleInfo
6074 region;
6075
6076 ssize_t
6077 i;
6078
6079 struct PackageInfo
6080 *info;
6081
6082 SV
6083 *perl_exception,
6084 *reference;
6085
6086 PERL_UNUSED_VAR(ref);
6087 PERL_UNUSED_VAR(ix);
6088 exception=AcquireExceptionInfo();
6089 perl_exception=newSVpv("",0);
6090 if (sv_isobject(ST(0)) == 0)
6091 {
6092 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6093 PackageName);
6094 goto PerlException;
6095 }
6096 reference=SvRV(ST(0));
6097
6098 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6099 if (image == (Image *) NULL)
6100 {
6101 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6102 PackageName);
6103 goto PerlException;
6104 }
6105
6106 region.x=0;
6107 region.y=0;
6108 region.width=image->columns;
6109 region.height=1;
6110 if (items == 1)
6111 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6112 for (i=2; i < items; i+=2)
6113 {
6114 attribute=(char *) SvPV(ST(i-1),na);
6115 switch (*attribute)
6116 {
6117 case 'g':
6118 case 'G':
6119 {
6120 if (LocaleCompare(attribute,"geometry") == 0)
6121 {
6122 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6123 break;
6124 }
6125 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6126 attribute);
6127 break;
6128 }
6129 case 'H':
6130 case 'h':
6131 {
6132 if (LocaleCompare(attribute,"height") == 0)
6133 {
6134 region.height=SvIV(ST(i));
6135 continue;
6136 }
6137 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6138 attribute);
6139 break;
6140 }
6141 case 'X':
6142 case 'x':
6143 {
6144 if (LocaleCompare(attribute,"x") == 0)
6145 {
6146 region.x=SvIV(ST(i));
6147 continue;
6148 }
6149 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6150 attribute);
6151 break;
6152 }
6153 case 'Y':
6154 case 'y':
6155 {
6156 if (LocaleCompare(attribute,"y") == 0)
6157 {
6158 region.y=SvIV(ST(i));
6159 continue;
6160 }
6161 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6162 attribute);
6163 break;
6164 }
6165 case 'W':
6166 case 'w':
6167 {
6168 if (LocaleCompare(attribute,"width") == 0)
6169 {
6170 region.width=SvIV(ST(i));
6171 continue;
6172 }
6173 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6174 attribute);
6175 break;
6176 }
6177 }
6178 }
6179 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6180 region.height,exception);
6181 if (blob != (void *) NULL)
6182 goto PerlEnd;
6183
6184 PerlException:
6185 InheritPerlException(exception,perl_exception);
6186 exception=DestroyExceptionInfo(exception);
6187 SvREFCNT_dec(perl_exception); /* throw away all errors */
6188
6189 PerlEnd:
6190 RETVAL = (void *) blob;
6191 }
6192 OUTPUT:
6193 RETVAL
6194
6195#
6196###############################################################################
6197# #
6198# #
6199# #
6200# G e t A u t h e n t i c M e t a c o n t e n t #
6201# #
6202# #
6203# #
6204###############################################################################
6205#
6206#
6207void *
6208GetAuthenticMetacontent(ref,...)
6209 Image::Magick ref = NO_INIT
6210 ALIAS:
6211 getauthenticmetacontent = 1
6212 GetMetacontent = 2
6213 getmetacontent = 3
6214 CODE:
6215 {
6216 ExceptionInfo
6217 *exception;
6218
6219 Image
6220 *image;
6221
6222 struct PackageInfo
6223 *info;
6224
6225 SV
6226 *perl_exception,
6227 *reference;
6228
6229 void
6230 *blob = NULL;
6231
6232 PERL_UNUSED_VAR(ref);
6233 PERL_UNUSED_VAR(ix);
6234 exception=AcquireExceptionInfo();
6235 perl_exception=newSVpv("",0);
6236 if (sv_isobject(ST(0)) == 0)
6237 {
6238 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6239 PackageName);
6240 goto PerlException;
6241 }
6242 reference=SvRV(ST(0));
6243
6244 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6245 if (image == (Image *) NULL)
6246 {
6247 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6248 PackageName);
6249 goto PerlException;
6250 }
6251
6252 blob=(void *) GetAuthenticMetacontent(image);
6253 if (blob != (void *) NULL)
6254 goto PerlEnd;
6255
6256 PerlException:
6257 InheritPerlException(exception,perl_exception);
6258 exception=DestroyExceptionInfo(exception);
6259 SvREFCNT_dec(perl_exception); /* throw away all errors */
6260
6261 PerlEnd:
6262 RETVAL = blob;
6263 }
6264 OUTPUT:
6265 RETVAL
6266
6267#
6268###############################################################################
6269# #
6270# #
6271# #
6272# G e t V i r t u a l M e t a c o n t e n t #
6273# #
6274# #
6275# #
6276###############################################################################
6277#
6278#
6279void *
6280GetVirtualMetacontent(ref,...)
6281 Image::Magick ref = NO_INIT
6282 ALIAS:
6283 getvirtualmetacontent = 1
6284 CODE:
6285 {
6286 ExceptionInfo
6287 *exception;
6288
6289 Image
6290 *image;
6291
6292 struct PackageInfo
6293 *info;
6294
6295 SV
6296 *perl_exception,
6297 *reference;
6298
6299 void
6300 *blob = NULL;
6301
6302 PERL_UNUSED_VAR(ref);
6303 PERL_UNUSED_VAR(ix);
6304 exception=AcquireExceptionInfo();
6305 perl_exception=newSVpv("",0);
6306 if (sv_isobject(ST(0)) == 0)
6307 {
6308 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6309 PackageName);
6310 goto PerlException;
6311 }
6312 reference=SvRV(ST(0));
6313
6314 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6315 if (image == (Image *) NULL)
6316 {
6317 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6318 PackageName);
6319 goto PerlException;
6320 }
6321
6322 blob=(void *) GetVirtualMetacontent(image);
6323 if (blob != (void *) NULL)
6324 goto PerlEnd;
6325
6326 PerlException:
6327 InheritPerlException(exception,perl_exception);
6328 exception=DestroyExceptionInfo(exception);
6329 SvREFCNT_dec(perl_exception); /* throw away all errors */
6330
6331 PerlEnd:
6332 RETVAL = blob;
6333 }
6334 OUTPUT:
6335 RETVAL
6336
6337#
6338###############################################################################
6339# #
6340# #
6341# #
6342# H i s t o g r a m #
6343# #
6344# #
6345# #
6346###############################################################################
6347#
6348#
6349void
6350Histogram(ref,...)
6351 Image::Magick ref=NO_INIT
6352 ALIAS:
6353 HistogramImage = 1
6354 histogram = 2
6355 histogramimage = 3
6356 PPCODE:
6357 {
6358 AV
6359 *av;
6360
6361 char
cristy151b66d2015-04-15 10:50:31 +00006362 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006363
6364 PixelInfo
6365 *histogram;
6366
6367 ExceptionInfo
6368 *exception;
6369
6370 Image
6371 *image;
6372
6373 register ssize_t
6374 i;
6375
6376 ssize_t
6377 count;
6378
6379 struct PackageInfo
6380 *info;
6381
6382 SV
6383 *perl_exception,
6384 *reference;
6385
6386 size_t
6387 number_colors;
6388
6389 PERL_UNUSED_VAR(ref);
6390 PERL_UNUSED_VAR(ix);
6391 exception=AcquireExceptionInfo();
6392 perl_exception=newSVpv("",0);
6393 av=NULL;
6394 if (sv_isobject(ST(0)) == 0)
6395 {
6396 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6397 PackageName);
6398 goto PerlException;
6399 }
6400 reference=SvRV(ST(0));
6401 av=newAV();
6402 SvREFCNT_dec(av);
6403 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6404 if (image == (Image *) NULL)
6405 {
6406 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6407 PackageName);
6408 goto PerlException;
6409 }
cristy4a3ce0a2013-08-03 20:06:59 +00006410 count=0;
6411 for ( ; image; image=image->next)
6412 {
6413 histogram=GetImageHistogram(image,&number_colors,exception);
6414 if (histogram == (PixelInfo *) NULL)
6415 continue;
6416 count+=(ssize_t) number_colors;
6417 EXTEND(sp,6*count);
6418 for (i=0; i < (ssize_t) number_colors; i++)
6419 {
cristy151b66d2015-04-15 10:50:31 +00006420 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006421 histogram[i].red);
6422 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006423 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006424 histogram[i].green);
6425 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006426 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006427 histogram[i].blue);
6428 PUSHs(sv_2mortal(newSVpv(message,0)));
6429 if (image->colorspace == CMYKColorspace)
6430 {
cristy151b66d2015-04-15 10:50:31 +00006431 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006432 histogram[i].black);
6433 PUSHs(sv_2mortal(newSVpv(message,0)));
6434 }
cristy151b66d2015-04-15 10:50:31 +00006435 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006436 histogram[i].alpha);
6437 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006438 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006439 histogram[i].count);
6440 PUSHs(sv_2mortal(newSVpv(message,0)));
6441 }
6442 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6443 }
6444
6445 PerlException:
6446 InheritPerlException(exception,perl_exception);
6447 exception=DestroyExceptionInfo(exception);
6448 SvREFCNT_dec(perl_exception);
6449 }
6450
6451#
6452###############################################################################
6453# #
6454# #
6455# #
6456# G e t P i x e l #
6457# #
6458# #
6459# #
6460###############################################################################
6461#
6462#
6463void
6464GetPixel(ref,...)
6465 Image::Magick ref=NO_INIT
6466 ALIAS:
6467 getpixel = 1
6468 getPixel = 2
6469 PPCODE:
6470 {
6471 AV
6472 *av;
6473
6474 char
6475 *attribute;
6476
6477 ExceptionInfo
6478 *exception;
6479
6480 Image
6481 *image;
6482
6483 MagickBooleanType
6484 normalize;
6485
6486 RectangleInfo
6487 region;
6488
6489 register const Quantum
6490 *p;
6491
6492 register ssize_t
6493 i;
6494
6495 ssize_t
6496 option;
6497
6498 struct PackageInfo
6499 *info;
6500
6501 SV
6502 *perl_exception,
6503 *reference; /* reference is the SV* of ref=SvIV(reference) */
6504
6505 PERL_UNUSED_VAR(ref);
6506 PERL_UNUSED_VAR(ix);
6507 exception=AcquireExceptionInfo();
6508 perl_exception=newSVpv("",0);
6509 reference=SvRV(ST(0));
6510 av=(AV *) reference;
6511 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6512 exception);
6513 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6514 if (image == (Image *) NULL)
6515 {
6516 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6517 PackageName);
6518 goto PerlException;
6519 }
6520 normalize=MagickTrue;
6521 region.x=0;
6522 region.y=0;
6523 region.width=image->columns;
6524 region.height=1;
6525 if (items == 1)
6526 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6527 for (i=2; i < items; i+=2)
6528 {
6529 attribute=(char *) SvPV(ST(i-1),na);
6530 switch (*attribute)
6531 {
6532 case 'C':
6533 case 'c':
6534 {
6535 if (LocaleCompare(attribute,"channel") == 0)
6536 {
6537 ssize_t
6538 option;
6539
6540 option=ParseChannelOption(SvPV(ST(i),na));
6541 if (option < 0)
6542 {
6543 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6544 SvPV(ST(i),na));
6545 return;
6546 }
cristybcd59342015-06-07 14:07:19 +00006547 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00006548 break;
6549 }
6550 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6551 attribute);
6552 break;
6553 }
6554 case 'g':
6555 case 'G':
6556 {
6557 if (LocaleCompare(attribute,"geometry") == 0)
6558 {
6559 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6560 break;
6561 }
6562 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6563 attribute);
6564 break;
6565 }
6566 case 'N':
6567 case 'n':
6568 {
6569 if (LocaleCompare(attribute,"normalize") == 0)
6570 {
6571 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6572 SvPV(ST(i),na));
6573 if (option < 0)
6574 {
6575 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6576 SvPV(ST(i),na));
6577 break;
6578 }
6579 normalize=option != 0 ? MagickTrue : MagickFalse;
6580 break;
6581 }
6582 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6583 attribute);
6584 break;
6585 }
6586 case 'x':
6587 case 'X':
6588 {
6589 if (LocaleCompare(attribute,"x") == 0)
6590 {
6591 region.x=SvIV(ST(i));
6592 break;
6593 }
6594 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6595 attribute);
6596 break;
6597 }
6598 case 'y':
6599 case 'Y':
6600 {
6601 if (LocaleCompare(attribute,"y") == 0)
6602 {
6603 region.y=SvIV(ST(i));
6604 break;
6605 }
6606 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6607 attribute);
6608 break;
6609 }
6610 default:
6611 {
6612 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6613 attribute);
6614 break;
6615 }
6616 }
6617 }
6618 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6619 if (p == (const Quantum *) NULL)
6620 PUSHs(&sv_undef);
6621 else
6622 {
6623 double
6624 scale;
6625
6626 scale=1.0;
6627 if (normalize != MagickFalse)
6628 scale=1.0/QuantumRange;
6629 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6630 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6631 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6632 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6633 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6634 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6635 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6636 (image->colorspace == CMYKColorspace))
6637 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6638 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6639 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6640 }
6641
6642 PerlException:
6643 InheritPerlException(exception,perl_exception);
6644 exception=DestroyExceptionInfo(exception);
6645 SvREFCNT_dec(perl_exception);
6646 }
6647
6648#
6649###############################################################################
6650# #
6651# #
6652# #
6653# G e t P i x e l s #
6654# #
6655# #
6656# #
6657###############################################################################
6658#
6659#
6660void
6661GetPixels(ref,...)
6662 Image::Magick ref=NO_INIT
6663 ALIAS:
6664 getpixels = 1
6665 getPixels = 2
6666 PPCODE:
6667 {
6668 AV
6669 *av;
6670
6671 char
6672 *attribute;
6673
6674 const char
6675 *map;
6676
6677 ExceptionInfo
6678 *exception;
6679
6680 Image
6681 *image;
6682
6683 MagickBooleanType
6684 normalize,
6685 status;
6686
6687 RectangleInfo
6688 region;
6689
6690 register ssize_t
6691 i;
6692
6693 ssize_t
6694 option;
6695
6696 struct PackageInfo
6697 *info;
6698
6699 SV
6700 *perl_exception,
6701 *reference; /* reference is the SV* of ref=SvIV(reference) */
6702
6703 PERL_UNUSED_VAR(ref);
6704 PERL_UNUSED_VAR(ix);
6705 exception=AcquireExceptionInfo();
6706 perl_exception=newSVpv("",0);
6707 reference=SvRV(ST(0));
6708 av=(AV *) reference;
6709 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6710 exception);
6711 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6712 if (image == (Image *) NULL)
6713 {
6714 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6715 PackageName);
6716 goto PerlException;
6717 }
6718 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006719 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006720 map="RGBA";
6721 if (image->colorspace == CMYKColorspace)
6722 {
6723 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006724 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006725 map="CMYKA";
6726 }
6727 normalize=MagickFalse;
6728 region.x=0;
6729 region.y=0;
6730 region.width=image->columns;
6731 region.height=1;
6732 if (items == 1)
6733 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6734 for (i=2; i < items; i+=2)
6735 {
6736 attribute=(char *) SvPV(ST(i-1),na);
6737 switch (*attribute)
6738 {
6739 case 'g':
6740 case 'G':
6741 {
6742 if (LocaleCompare(attribute,"geometry") == 0)
6743 {
6744 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6745 break;
6746 }
6747 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6748 attribute);
6749 break;
6750 }
6751 case 'H':
6752 case 'h':
6753 {
6754 if (LocaleCompare(attribute,"height") == 0)
6755 {
6756 region.height=SvIV(ST(i));
6757 break;
6758 }
6759 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6760 attribute);
6761 break;
6762 }
6763 case 'M':
6764 case 'm':
6765 {
6766 if (LocaleCompare(attribute,"map") == 0)
6767 {
6768 map=SvPV(ST(i),na);
6769 break;
6770 }
6771 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6772 attribute);
6773 break;
6774 }
6775 case 'N':
6776 case 'n':
6777 {
6778 if (LocaleCompare(attribute,"normalize") == 0)
6779 {
6780 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6781 SvPV(ST(i),na));
6782 if (option < 0)
6783 {
6784 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6785 SvPV(ST(i),na));
6786 break;
6787 }
6788 normalize=option != 0 ? MagickTrue : MagickFalse;
6789 break;
6790 }
6791 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6792 attribute);
6793 break;
6794 }
6795 case 'W':
6796 case 'w':
6797 {
6798 if (LocaleCompare(attribute,"width") == 0)
6799 {
6800 region.width=SvIV(ST(i));
6801 break;
6802 }
6803 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6804 attribute);
6805 break;
6806 }
6807 case 'x':
6808 case 'X':
6809 {
6810 if (LocaleCompare(attribute,"x") == 0)
6811 {
6812 region.x=SvIV(ST(i));
6813 break;
6814 }
6815 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6816 attribute);
6817 break;
6818 }
6819 case 'y':
6820 case 'Y':
6821 {
6822 if (LocaleCompare(attribute,"y") == 0)
6823 {
6824 region.y=SvIV(ST(i));
6825 break;
6826 }
6827 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6828 attribute);
6829 break;
6830 }
6831 default:
6832 {
6833 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6834 attribute);
6835 break;
6836 }
6837 }
6838 }
6839 if (normalize != MagickFalse)
6840 {
6841 float
6842 *pixels;
6843
6844 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6845 region.height*sizeof(*pixels));
6846 if (pixels == (float *) NULL)
6847 {
6848 ThrowPerlException(exception,ResourceLimitError,
6849 "MemoryAllocationFailed",PackageName);
6850 goto PerlException;
6851 }
6852 status=ExportImagePixels(image,region.x,region.y,region.width,
6853 region.height,map,FloatPixel,pixels,exception);
6854 if (status == MagickFalse)
6855 PUSHs(&sv_undef);
6856 else
6857 {
6858 EXTEND(sp,strlen(map)*region.width*region.height);
6859 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6860 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6861 }
6862 pixels=(float *) RelinquishMagickMemory(pixels);
6863 }
6864 else
6865 {
6866 Quantum
6867 *pixels;
6868
6869 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6870 region.height*sizeof(*pixels));
6871 if (pixels == (Quantum *) NULL)
6872 {
6873 ThrowPerlException(exception,ResourceLimitError,
6874 "MemoryAllocationFailed",PackageName);
6875 goto PerlException;
6876 }
6877 status=ExportImagePixels(image,region.x,region.y,region.width,
6878 region.height,map,QuantumPixel,pixels,exception);
6879 if (status == MagickFalse)
6880 PUSHs(&sv_undef);
6881 else
6882 {
6883 EXTEND(sp,strlen(map)*region.width*region.height);
6884 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6885 PUSHs(sv_2mortal(newSViv(pixels[i])));
6886 }
6887 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6888 }
6889
6890 PerlException:
6891 InheritPerlException(exception,perl_exception);
6892 exception=DestroyExceptionInfo(exception);
6893 SvREFCNT_dec(perl_exception);
6894 }
6895
6896#
6897###############################################################################
6898# #
6899# #
6900# #
6901# I m a g e T o B l o b #
6902# #
6903# #
6904# #
6905###############################################################################
6906#
6907#
6908void
6909ImageToBlob(ref,...)
6910 Image::Magick ref=NO_INIT
6911 ALIAS:
6912 ImageToBlob = 1
6913 imagetoblob = 2
6914 toblob = 3
6915 blob = 4
6916 PPCODE:
6917 {
6918 char
cristy151b66d2015-04-15 10:50:31 +00006919 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006920
6921 ExceptionInfo
6922 *exception;
6923
6924 Image
6925 *image,
6926 *next;
6927
6928 register ssize_t
6929 i;
6930
6931 struct PackageInfo
6932 *info,
6933 *package_info;
6934
6935 size_t
6936 length;
6937
6938 ssize_t
6939 scene;
6940
6941 SV
6942 *perl_exception,
6943 *reference;
6944
6945 void
6946 *blob;
6947
6948 PERL_UNUSED_VAR(ref);
6949 PERL_UNUSED_VAR(ix);
6950 exception=AcquireExceptionInfo();
6951 perl_exception=newSVpv("",0);
6952 package_info=(struct PackageInfo *) NULL;
6953 if (sv_isobject(ST(0)) == 0)
6954 {
6955 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6956 PackageName);
6957 goto PerlException;
6958 }
6959 reference=SvRV(ST(0));
6960 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6961 if (image == (Image *) NULL)
6962 {
6963 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6964 PackageName);
6965 goto PerlException;
6966 }
6967 package_info=ClonePackageInfo(info,exception);
6968 for (i=2; i < items; i+=2)
6969 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6970 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006971 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006972 scene=0;
6973 for (next=image; next; next=next->next)
6974 {
cristy151b66d2015-04-15 10:50:31 +00006975 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006976 next->scene=scene++;
6977 }
6978 SetImageInfo(package_info->image_info,(unsigned int)
6979 GetImageListLength(image),exception);
6980 EXTEND(sp,(ssize_t) GetImageListLength(image));
6981 for ( ; image; image=image->next)
6982 {
6983 length=0;
6984 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6985 if (blob != (char *) NULL)
6986 {
6987 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6988 blob=(unsigned char *) RelinquishMagickMemory(blob);
6989 }
6990 if (package_info->image_info->adjoin)
6991 break;
6992 }
6993
6994 PerlException:
6995 if (package_info != (struct PackageInfo *) NULL)
6996 DestroyPackageInfo(package_info);
6997 InheritPerlException(exception,perl_exception);
6998 exception=DestroyExceptionInfo(exception);
6999 SvREFCNT_dec(perl_exception); /* throw away all errors */
7000 }
7001
7002#
7003###############################################################################
7004# #
7005# #
7006# #
7007# L a y e r s #
7008# #
7009# #
7010# #
7011###############################################################################
7012#
7013#
7014void
7015Layers(ref,...)
7016 Image::Magick ref=NO_INIT
7017 ALIAS:
7018 Layers = 1
7019 layers = 2
7020 OptimizeImageLayers = 3
7021 optimizelayers = 4
7022 optimizeimagelayers = 5
7023 PPCODE:
7024 {
7025 AV
7026 *av;
7027
7028 char
7029 *attribute;
7030
7031 CompositeOperator
7032 compose;
7033
7034 ExceptionInfo
7035 *exception;
7036
7037 HV
7038 *hv;
7039
7040 Image
7041 *image,
7042 *layers;
7043
7044 LayerMethod
7045 method;
7046
7047 register ssize_t
7048 i;
7049
7050 ssize_t
7051 option,
7052 sp;
7053
7054 struct PackageInfo
7055 *info;
7056
7057 SV
7058 *av_reference,
7059 *perl_exception,
7060 *reference,
7061 *rv,
7062 *sv;
7063
7064 PERL_UNUSED_VAR(ref);
7065 PERL_UNUSED_VAR(ix);
7066 exception=AcquireExceptionInfo();
7067 perl_exception=newSVpv("",0);
7068 sv=NULL;
7069 if (sv_isobject(ST(0)) == 0)
7070 {
7071 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7072 PackageName);
7073 goto PerlException;
7074 }
7075 reference=SvRV(ST(0));
7076 hv=SvSTASH(reference);
7077 av=newAV();
7078 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7079 SvREFCNT_dec(av);
7080 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7081 if (image == (Image *) NULL)
7082 {
7083 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7084 PackageName);
7085 goto PerlException;
7086 }
7087 compose=image->compose;
7088 method=OptimizeLayer;
7089 for (i=2; i < items; i+=2)
7090 {
7091 attribute=(char *) SvPV(ST(i-1),na);
7092 switch (*attribute)
7093 {
7094 case 'C':
7095 case 'c':
7096 {
7097 if (LocaleCompare(attribute,"compose") == 0)
7098 {
7099 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7100 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7101 if (sp < 0)
7102 {
7103 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7104 SvPV(ST(i),na));
7105 break;
7106 }
7107 compose=(CompositeOperator) sp;
7108 break;
7109 }
7110 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7111 attribute);
7112 break;
7113 }
7114 case 'M':
7115 case 'm':
7116 {
7117 if (LocaleCompare(attribute,"method") == 0)
7118 {
7119 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7120 SvPV(ST(i),na));
7121 if (option < 0)
7122 {
7123 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7124 SvPV(ST(i),na));
7125 break;
7126 }
7127 method=(LayerMethod) option;
7128 break;
7129 }
7130 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7131 attribute);
7132 break;
7133 }
7134 default:
7135 {
7136 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7137 attribute);
7138 break;
7139 }
7140 }
7141 }
7142 layers=(Image *) NULL;
7143 switch (method)
7144 {
7145 case CompareAnyLayer:
7146 case CompareClearLayer:
7147 case CompareOverlayLayer:
7148 default:
7149 {
7150 layers=CompareImagesLayers(image,method,exception);
7151 break;
7152 }
7153 case MergeLayer:
7154 case FlattenLayer:
7155 case MosaicLayer:
7156 {
7157 layers=MergeImageLayers(image,method,exception);
7158 break;
7159 }
7160 case DisposeLayer:
7161 {
7162 layers=DisposeImages(image,exception);
7163 break;
7164 }
7165 case OptimizeImageLayer:
7166 {
7167 layers=OptimizeImageLayers(image,exception);
7168 break;
7169 }
7170 case OptimizePlusLayer:
7171 {
7172 layers=OptimizePlusImageLayers(image,exception);
7173 break;
7174 }
7175 case OptimizeTransLayer:
7176 {
7177 OptimizeImageTransparency(image,exception);
7178 break;
7179 }
7180 case RemoveDupsLayer:
7181 {
7182 RemoveDuplicateLayers(&image,exception);
7183 break;
7184 }
7185 case RemoveZeroLayer:
7186 {
7187 RemoveZeroDelayLayers(&image,exception);
7188 break;
7189 }
7190 case OptimizeLayer:
7191 {
7192 QuantizeInfo
7193 *quantize_info;
7194
7195 /*
7196 General Purpose, GIF Animation Optimizer.
7197 */
7198 layers=CoalesceImages(image,exception);
7199 if (layers == (Image *) NULL)
7200 break;
7201 image=layers;
7202 layers=OptimizeImageLayers(image,exception);
7203 if (layers == (Image *) NULL)
7204 break;
7205 image=DestroyImageList(image);
7206 image=layers;
7207 layers=(Image *) NULL;
7208 OptimizeImageTransparency(image,exception);
7209 quantize_info=AcquireQuantizeInfo(info->image_info);
7210 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7211 quantize_info=DestroyQuantizeInfo(quantize_info);
7212 break;
7213 }
7214 case CompositeLayer:
7215 {
7216 Image
7217 *source;
7218
7219 RectangleInfo
7220 geometry;
7221
7222 /*
7223 Split image sequence at the first 'NULL:' image.
7224 */
7225 source=image;
7226 while (source != (Image *) NULL)
7227 {
7228 source=GetNextImageInList(source);
7229 if ((source != (Image *) NULL) &&
7230 (LocaleCompare(source->magick,"NULL") == 0))
7231 break;
7232 }
7233 if (source != (Image *) NULL)
7234 {
7235 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7236 (GetNextImageInList(source) == (Image *) NULL))
7237 source=(Image *) NULL;
7238 else
7239 {
7240 /*
7241 Separate the two lists, junk the null: image.
7242 */
7243 source=SplitImageList(source->previous);
7244 DeleteImageFromList(&source);
7245 }
7246 }
7247 if (source == (Image *) NULL)
7248 {
7249 (void) ThrowMagickException(exception,GetMagickModule(),
7250 OptionError,"MissingNullSeparator","layers Composite");
7251 break;
7252 }
7253 /*
7254 Adjust offset with gravity and virtual canvas.
7255 */
7256 SetGeometry(image,&geometry);
7257 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7258 geometry.width=source->page.width != 0 ? source->page.width :
7259 source->columns;
7260 geometry.height=source->page.height != 0 ? source->page.height :
7261 source->rows;
7262 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7263 image->columns,image->page.height != 0 ? image->page.height :
7264 image->rows,image->gravity,&geometry);
7265 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7266 source=DestroyImageList(source);
7267 break;
7268 }
7269 }
7270 if (layers != (Image *) NULL)
7271 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007272 else
7273 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007274 if (image == (Image *) NULL)
7275 goto PerlException;
7276 for ( ; image; image=image->next)
7277 {
7278 AddImageToRegistry(sv,image);
7279 rv=newRV(sv);
7280 av_push(av,sv_bless(rv,hv));
7281 SvREFCNT_dec(sv);
7282 }
7283 exception=DestroyExceptionInfo(exception);
7284 ST(0)=av_reference;
7285 SvREFCNT_dec(perl_exception);
7286 XSRETURN(1);
7287
7288 PerlException:
7289 InheritPerlException(exception,perl_exception);
7290 exception=DestroyExceptionInfo(exception);
7291 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7292 SvPOK_on(perl_exception);
7293 ST(0)=sv_2mortal(perl_exception);
7294 XSRETURN(1);
7295 }
7296
7297#
7298###############################################################################
7299# #
7300# #
7301# #
7302# M a g i c k T o M i m e #
7303# #
7304# #
7305# #
7306###############################################################################
7307#
7308#
7309SV *
7310MagickToMime(ref,name)
7311 Image::Magick ref=NO_INIT
7312 char *name
7313 ALIAS:
7314 magicktomime = 1
7315 CODE:
7316 {
7317 char
7318 *mime;
7319
7320 PERL_UNUSED_VAR(ref);
7321 PERL_UNUSED_VAR(ix);
7322 mime=MagickToMime(name);
7323 RETVAL=newSVpv(mime,0);
7324 mime=(char *) RelinquishMagickMemory(mime);
7325 }
7326 OUTPUT:
7327 RETVAL
7328
7329#
7330###############################################################################
7331# #
7332# #
7333# #
7334# M o g r i f y #
7335# #
7336# #
7337# #
7338###############################################################################
7339#
7340#
7341void
7342Mogrify(ref,...)
7343 Image::Magick ref=NO_INIT
7344 ALIAS:
7345 Comment = 1
7346 CommentImage = 2
7347 Label = 3
7348 LabelImage = 4
7349 AddNoise = 5
7350 AddNoiseImage = 6
7351 Colorize = 7
7352 ColorizeImage = 8
7353 Border = 9
7354 BorderImage = 10
7355 Blur = 11
7356 BlurImage = 12
7357 Chop = 13
7358 ChopImage = 14
7359 Crop = 15
7360 CropImage = 16
7361 Despeckle = 17
7362 DespeckleImage = 18
7363 Edge = 19
7364 EdgeImage = 20
7365 Emboss = 21
7366 EmbossImage = 22
7367 Enhance = 23
7368 EnhanceImage = 24
7369 Flip = 25
7370 FlipImage = 26
7371 Flop = 27
7372 FlopImage = 28
7373 Frame = 29
7374 FrameImage = 30
7375 Implode = 31
7376 ImplodeImage = 32
7377 Magnify = 33
7378 MagnifyImage = 34
7379 MedianFilter = 35
7380 MedianConvolveImage = 36
7381 Minify = 37
7382 MinifyImage = 38
7383 OilPaint = 39
7384 OilPaintImage = 40
7385 ReduceNoise = 41
7386 ReduceNoiseImage = 42
7387 Roll = 43
7388 RollImage = 44
7389 Rotate = 45
7390 RotateImage = 46
7391 Sample = 47
7392 SampleImage = 48
7393 Scale = 49
7394 ScaleImage = 50
7395 Shade = 51
7396 ShadeImage = 52
7397 Sharpen = 53
7398 SharpenImage = 54
7399 Shear = 55
7400 ShearImage = 56
7401 Spread = 57
7402 SpreadImage = 58
7403 Swirl = 59
7404 SwirlImage = 60
7405 Resize = 61
7406 ResizeImage = 62
7407 Zoom = 63
7408 ZoomImage = 64
7409 Annotate = 65
7410 AnnotateImage = 66
7411 ColorFloodfill = 67
7412 ColorFloodfillImage= 68
7413 Composite = 69
7414 CompositeImage = 70
7415 Contrast = 71
7416 ContrastImage = 72
7417 CycleColormap = 73
7418 CycleColormapImage = 74
7419 Draw = 75
7420 DrawImage = 76
7421 Equalize = 77
7422 EqualizeImage = 78
7423 Gamma = 79
7424 GammaImage = 80
7425 Map = 81
7426 MapImage = 82
7427 MatteFloodfill = 83
7428 MatteFloodfillImage= 84
7429 Modulate = 85
7430 ModulateImage = 86
7431 Negate = 87
7432 NegateImage = 88
7433 Normalize = 89
7434 NormalizeImage = 90
7435 NumberColors = 91
7436 NumberColorsImage = 92
7437 Opaque = 93
7438 OpaqueImage = 94
7439 Quantize = 95
7440 QuantizeImage = 96
7441 Raise = 97
7442 RaiseImage = 98
7443 Segment = 99
7444 SegmentImage = 100
7445 Signature = 101
7446 SignatureImage = 102
7447 Solarize = 103
7448 SolarizeImage = 104
7449 Sync = 105
7450 SyncImage = 106
7451 Texture = 107
7452 TextureImage = 108
7453 Evaluate = 109
7454 EvaluateImage = 110
7455 Transparent = 111
7456 TransparentImage = 112
7457 Threshold = 113
7458 ThresholdImage = 114
7459 Charcoal = 115
7460 CharcoalImage = 116
7461 Trim = 117
7462 TrimImage = 118
7463 Wave = 119
7464 WaveImage = 120
7465 Separate = 121
7466 SeparateImage = 122
7467 Stereo = 125
7468 StereoImage = 126
7469 Stegano = 127
7470 SteganoImage = 128
7471 Deconstruct = 129
7472 DeconstructImage = 130
7473 GaussianBlur = 131
7474 GaussianBlurImage = 132
7475 Convolve = 133
7476 ConvolveImage = 134
7477 Profile = 135
7478 ProfileImage = 136
7479 UnsharpMask = 137
7480 UnsharpMaskImage = 138
7481 MotionBlur = 139
7482 MotionBlurImage = 140
7483 OrderedDither = 141
7484 OrderedDitherImage = 142
7485 Shave = 143
7486 ShaveImage = 144
7487 Level = 145
7488 LevelImage = 146
7489 Clip = 147
7490 ClipImage = 148
7491 AffineTransform = 149
7492 AffineTransformImage = 150
7493 Difference = 151
7494 DifferenceImage = 152
7495 AdaptiveThreshold = 153
7496 AdaptiveThresholdImage = 154
7497 Resample = 155
7498 ResampleImage = 156
7499 Describe = 157
7500 DescribeImage = 158
7501 BlackThreshold = 159
7502 BlackThresholdImage= 160
7503 WhiteThreshold = 161
7504 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007505 RotationalBlur = 163
7506 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007507 Thumbnail = 165
7508 ThumbnailImage = 166
7509 Strip = 167
7510 StripImage = 168
7511 Tint = 169
7512 TintImage = 170
7513 Channel = 171
7514 ChannelImage = 172
7515 Splice = 173
7516 SpliceImage = 174
7517 Posterize = 175
7518 PosterizeImage = 176
7519 Shadow = 177
7520 ShadowImage = 178
7521 Identify = 179
7522 IdentifyImage = 180
7523 SepiaTone = 181
7524 SepiaToneImage = 182
7525 SigmoidalContrast = 183
7526 SigmoidalContrastImage = 184
7527 Extent = 185
7528 ExtentImage = 186
7529 Vignette = 187
7530 VignetteImage = 188
7531 ContrastStretch = 189
7532 ContrastStretchImage = 190
7533 Sans0 = 191
7534 Sans0Image = 192
7535 Sans1 = 193
7536 Sans1Image = 194
7537 AdaptiveSharpen = 195
7538 AdaptiveSharpenImage = 196
7539 Transpose = 197
7540 TransposeImage = 198
7541 Transverse = 199
7542 TransverseImage = 200
7543 AutoOrient = 201
7544 AutoOrientImage = 202
7545 AdaptiveBlur = 203
7546 AdaptiveBlurImage = 204
7547 Sketch = 205
7548 SketchImage = 206
7549 UniqueColors = 207
7550 UniqueColorsImage = 208
7551 AdaptiveResize = 209
7552 AdaptiveResizeImage= 210
7553 ClipMask = 211
7554 ClipMaskImage = 212
7555 LinearStretch = 213
7556 LinearStretchImage = 214
7557 ColorMatrix = 215
7558 ColorMatrixImage = 216
7559 Mask = 217
7560 MaskImage = 218
7561 Polaroid = 219
7562 PolaroidImage = 220
7563 FloodfillPaint = 221
7564 FloodfillPaintImage= 222
7565 Distort = 223
7566 DistortImage = 224
7567 Clut = 225
7568 ClutImage = 226
7569 LiquidRescale = 227
7570 LiquidRescaleImage = 228
7571 Encipher = 229
7572 EncipherImage = 230
7573 Decipher = 231
7574 DecipherImage = 232
7575 Deskew = 233
7576 DeskewImage = 234
7577 Remap = 235
7578 RemapImage = 236
7579 SparseColor = 237
7580 SparseColorImage = 238
7581 Function = 239
7582 FunctionImage = 240
7583 SelectiveBlur = 241
7584 SelectiveBlurImage = 242
7585 HaldClut = 243
7586 HaldClutImage = 244
7587 BlueShift = 245
7588 BlueShiftImage = 246
7589 ForwardFourierTransform = 247
7590 ForwardFourierTransformImage = 248
7591 InverseFourierTransform = 249
7592 InverseFourierTransformImage = 250
7593 ColorDecisionList = 251
7594 ColorDecisionListImage = 252
7595 AutoGamma = 253
7596 AutoGammaImage = 254
7597 AutoLevel = 255
7598 AutoLevelImage = 256
7599 LevelColors = 257
7600 LevelImageColors = 258
7601 Clamp = 259
7602 ClampImage = 260
7603 BrightnessContrast = 261
7604 BrightnessContrastImage = 262
7605 Morphology = 263
7606 MorphologyImage = 264
Cristy3ca633e2016-02-13 12:49:01 -05007607 Mode = 265
7608 ModeImage = 266
7609 Statistic = 267
7610 StatisticImage = 268
7611 Perceptible = 269
7612 PerceptibleImage = 270
7613 Poly = 271
7614 PolyImage = 272
7615 Grayscale = 273
7616 GrayscaleImage = 274
7617 CannyEdge = 275
7618 CannyEdgeImage = 276
7619 HoughLine = 277
7620 HoughLineImage = 278
7621 MeanShift = 279
7622 MeanShiftImage = 280
7623 Kuwahara = 281
7624 KuwaharaImage = 282
Cristy0f5df812017-07-04 18:30:05 -04007625 ConnectedComponents = 283
7626 ConnectedComponentsImage = 284
Cristy3ca633e2016-02-13 12:49:01 -05007627 CopyPixels = 285
7628 CopyImagePixels = 286
Cristy5488c982016-02-13 14:07:50 -05007629 Color = 287
7630 ColorImage = 288
Cristy2d830ed2016-02-21 10:54:16 -05007631 WaveletDenoise = 289
7632 WaveletDenoiseImage= 290
Cristy99a57162016-12-05 11:47:57 -05007633 Colorspace = 291
7634 ColorspaceImage = 292
Cristy53353872017-07-02 12:24:24 -04007635 AutoThreshold = 293
7636 AutoThresholdImage = 294
cristy4a3ce0a2013-08-03 20:06:59 +00007637 MogrifyRegion = 666
7638 PPCODE:
7639 {
7640 AffineMatrix
7641 affine,
7642 current;
7643
7644 char
7645 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007646 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007647
7648 ChannelType
7649 channel,
7650 channel_mask;
7651
7652 CompositeOperator
7653 compose;
7654
7655 const char
7656 *attribute,
7657 *value;
7658
7659 double
7660 angle;
7661
7662 ExceptionInfo
7663 *exception;
7664
7665 GeometryInfo
7666 geometry_info;
7667
7668 Image
7669 *image,
Cristy7e567962018-02-03 12:42:20 -05007670 *next;
cristy4a3ce0a2013-08-03 20:06:59 +00007671
7672 MagickBooleanType
7673 status;
7674
7675 MagickStatusType
7676 flags;
7677
7678 PixelInfo
7679 fill_color;
7680
7681 RectangleInfo
7682 geometry,
7683 region_info;
7684
7685 register ssize_t
7686 i;
7687
7688 ssize_t
7689 base,
7690 j,
7691 number_images;
7692
7693 struct Methods
7694 *rp;
7695
7696 struct PackageInfo
7697 *info;
7698
7699 SV
7700 *perl_exception,
7701 **pv,
7702 *reference,
7703 **reference_vector;
7704
7705 struct ArgumentList
7706 argument_list[MaxArguments];
7707
7708 PERL_UNUSED_VAR(ref);
7709 PERL_UNUSED_VAR(ix);
7710 exception=AcquireExceptionInfo();
7711 perl_exception=newSVpv("",0);
7712 reference_vector=NULL;
cristy4a3ce0a2013-08-03 20:06:59 +00007713 number_images=0;
7714 base=2;
7715 if (sv_isobject(ST(0)) == 0)
7716 {
7717 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7718 PackageName);
7719 goto PerlException;
7720 }
7721 reference=SvRV(ST(0));
7722 region_info.width=0;
7723 region_info.height=0;
7724 region_info.x=0;
7725 region_info.y=0;
cristy4a3ce0a2013-08-03 20:06:59 +00007726 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7727 if (ix && (ix != 666))
7728 {
7729 /*
7730 Called as Method(...)
7731 */
7732 ix=(ix+1)/2;
7733 rp=(&Methods[ix-1]);
7734 attribute=rp->name;
7735 }
7736 else
7737 {
7738 /*
7739 Called as Mogrify("Method",...)
7740 */
7741 attribute=(char *) SvPV(ST(1),na);
7742 if (ix)
7743 {
7744 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7745 attribute=(char *) SvPV(ST(2),na);
7746 base++;
7747 }
7748 for (rp=Methods; ; rp++)
7749 {
7750 if (rp >= EndOf(Methods))
7751 {
7752 ThrowPerlException(exception,OptionError,
7753 "UnrecognizedPerlMagickMethod",attribute);
7754 goto PerlException;
7755 }
7756 if (strEQcase(attribute,rp->name))
7757 break;
7758 }
7759 ix=rp-Methods+1;
7760 base++;
7761 }
7762 if (image == (Image *) NULL)
7763 {
7764 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7765 goto PerlException;
7766 }
7767 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7768 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7769 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7770 {
7771 Arguments
7772 *pp,
7773 *qq;
7774
7775 ssize_t
7776 ssize_test;
7777
7778 struct ArgumentList
7779 *al;
7780
7781 SV
7782 *sv;
7783
7784 sv=NULL;
7785 ssize_test=0;
7786 pp=(Arguments *) NULL;
7787 qq=rp->arguments;
7788 if (i == items)
7789 {
7790 pp=rp->arguments,
7791 sv=ST(i-1);
7792 }
7793 else
7794 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7795 {
7796 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7797 break;
7798 if (strEQcase(attribute,qq->method) > ssize_test)
7799 {
7800 pp=qq;
7801 ssize_test=strEQcase(attribute,qq->method);
7802 }
7803 }
7804 if (pp == (Arguments *) NULL)
7805 {
7806 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7807 attribute);
7808 goto continue_outer_loop;
7809 }
7810 al=(&argument_list[pp-rp->arguments]);
7811 switch (pp->type)
7812 {
7813 case ArrayReference:
7814 {
7815 if (SvTYPE(sv) != SVt_RV)
7816 {
cristy151b66d2015-04-15 10:50:31 +00007817 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007818 "invalid %.60s value",pp->method);
7819 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7820 goto continue_outer_loop;
7821 }
7822 al->array_reference=SvRV(sv);
7823 break;
7824 }
7825 case RealReference:
7826 {
7827 al->real_reference=SvNV(sv);
7828 break;
7829 }
7830 case FileReference:
7831 {
7832 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7833 break;
7834 }
7835 case ImageReference:
7836 {
7837 if (!sv_isobject(sv) ||
7838 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7839 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7840 {
7841 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7842 PackageName);
7843 goto PerlException;
7844 }
7845 break;
7846 }
7847 case IntegerReference:
7848 {
7849 al->integer_reference=SvIV(sv);
7850 break;
7851 }
7852 case StringReference:
7853 {
7854 al->string_reference=(char *) SvPV(sv,al->length);
7855 if (sv_isobject(sv))
7856 al->image_reference=SetupList(aTHX_ SvRV(sv),
7857 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7858 break;
7859 }
7860 default:
7861 {
7862 /*
7863 Is a string; look up name.
7864 */
7865 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7866 {
7867 al->string_reference=(char *) SvPV(sv,al->length);
7868 al->integer_reference=(-1);
7869 break;
7870 }
7871 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7872 MagickFalse,SvPV(sv,na));
7873 if (pp->type == MagickChannelOptions)
7874 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7875 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7876 {
cristy151b66d2015-04-15 10:50:31 +00007877 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007878 "invalid %.60s value",pp->method);
7879 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7880 goto continue_outer_loop;
7881 }
7882 break;
7883 }
7884 }
7885 attribute_flag[pp-rp->arguments]++;
7886 continue_outer_loop: ;
7887 }
7888 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7889 pv=reference_vector;
7890 SetGeometryInfo(&geometry_info);
7891 channel=DefaultChannels;
7892 for (next=image; next; next=next->next)
7893 {
7894 image=next;
7895 SetGeometry(image,&geometry);
7896 if ((region_info.width*region_info.height) != 0)
Cristy7e567962018-02-03 12:42:20 -05007897 (void) SetImageRegionMask(image,WritePixelMask,&region_info,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007898 switch (ix)
7899 {
7900 default:
7901 {
cristy151b66d2015-04-15 10:50:31 +00007902 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007903 ThrowPerlException(exception,OptionError,
7904 "UnrecognizedPerlMagickMethod",message);
7905 goto PerlException;
7906 }
7907 case 1: /* Comment */
7908 {
7909 if (attribute_flag[0] == 0)
7910 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007911 (void) SetImageProperty(image,"comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007912 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007913 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007914 break;
7915 }
7916 case 2: /* Label */
7917 {
7918 if (attribute_flag[0] == 0)
7919 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007920 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007921 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007922 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007923 break;
7924 }
7925 case 3: /* AddNoise */
7926 {
7927 double
7928 attenuate;
7929
7930 if (attribute_flag[0] == 0)
7931 argument_list[0].integer_reference=UniformNoise;
7932 attenuate=1.0;
7933 if (attribute_flag[1] != 0)
7934 attenuate=argument_list[1].real_reference;
7935 if (attribute_flag[2] != 0)
7936 channel=(ChannelType) argument_list[2].integer_reference;
7937 channel_mask=SetImageChannelMask(image,channel);
7938 image=AddNoiseImage(image,(NoiseType)
7939 argument_list[0].integer_reference,attenuate,exception);
7940 if (image != (Image *) NULL)
7941 (void) SetImageChannelMask(image,channel_mask);
7942 break;
7943 }
7944 case 4: /* Colorize */
7945 {
7946 PixelInfo
7947 target;
7948
7949 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7950 0,0,&target,exception);
7951 if (attribute_flag[0] != 0)
7952 (void) QueryColorCompliance(argument_list[0].string_reference,
7953 AllCompliance,&target,exception);
7954 if (attribute_flag[1] == 0)
7955 argument_list[1].string_reference="100%";
7956 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7957 exception);
7958 break;
7959 }
7960 case 5: /* Border */
7961 {
7962 CompositeOperator
7963 compose;
7964
7965 geometry.width=0;
7966 geometry.height=0;
7967 if (attribute_flag[0] != 0)
7968 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7969 &geometry,exception);
7970 if (attribute_flag[1] != 0)
7971 geometry.width=argument_list[1].integer_reference;
7972 if (attribute_flag[2] != 0)
7973 geometry.height=argument_list[2].integer_reference;
7974 if (attribute_flag[3] != 0)
7975 QueryColorCompliance(argument_list[3].string_reference,
7976 AllCompliance,&image->border_color,exception);
7977 if (attribute_flag[4] != 0)
7978 QueryColorCompliance(argument_list[4].string_reference,
7979 AllCompliance,&image->border_color,exception);
7980 if (attribute_flag[5] != 0)
7981 QueryColorCompliance(argument_list[5].string_reference,
7982 AllCompliance,&image->border_color,exception);
7983 compose=image->compose;
7984 if (attribute_flag[6] != 0)
7985 compose=(CompositeOperator) argument_list[6].integer_reference;
7986 image=BorderImage(image,&geometry,compose,exception);
7987 break;
7988 }
7989 case 6: /* Blur */
7990 {
7991 if (attribute_flag[0] != 0)
7992 {
7993 flags=ParseGeometry(argument_list[0].string_reference,
7994 &geometry_info);
7995 if ((flags & SigmaValue) == 0)
7996 geometry_info.sigma=1.0;
7997 }
7998 if (attribute_flag[1] != 0)
7999 geometry_info.rho=argument_list[1].real_reference;
8000 if (attribute_flag[2] != 0)
8001 geometry_info.sigma=argument_list[2].real_reference;
8002 if (attribute_flag[3] != 0)
8003 channel=(ChannelType) argument_list[3].integer_reference;
8004 channel_mask=SetImageChannelMask(image,channel);
8005 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
8006 exception);
8007 if (image != (Image *) NULL)
8008 (void) SetImageChannelMask(image,channel_mask);
8009 break;
8010 }
8011 case 7: /* Chop */
8012 {
cristy260bd762014-08-15 12:46:34 +00008013 if (attribute_flag[5] != 0)
8014 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00008015 if (attribute_flag[0] != 0)
8016 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8017 &geometry,exception);
8018 if (attribute_flag[1] != 0)
8019 geometry.width=argument_list[1].integer_reference;
8020 if (attribute_flag[2] != 0)
8021 geometry.height=argument_list[2].integer_reference;
8022 if (attribute_flag[3] != 0)
8023 geometry.x=argument_list[3].integer_reference;
8024 if (attribute_flag[4] != 0)
8025 geometry.y=argument_list[4].integer_reference;
8026 image=ChopImage(image,&geometry,exception);
8027 break;
8028 }
8029 case 8: /* Crop */
8030 {
8031 if (attribute_flag[6] != 0)
8032 image->gravity=(GravityType) argument_list[6].integer_reference;
8033 if (attribute_flag[0] != 0)
8034 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8035 &geometry,exception);
8036 if (attribute_flag[1] != 0)
8037 geometry.width=argument_list[1].integer_reference;
8038 if (attribute_flag[2] != 0)
8039 geometry.height=argument_list[2].integer_reference;
8040 if (attribute_flag[3] != 0)
8041 geometry.x=argument_list[3].integer_reference;
8042 if (attribute_flag[4] != 0)
8043 geometry.y=argument_list[4].integer_reference;
8044 if (attribute_flag[5] != 0)
8045 image->fuzz=StringToDoubleInterval(
8046 argument_list[5].string_reference,(double) QuantumRange+1.0);
8047 image=CropImage(image,&geometry,exception);
8048 break;
8049 }
8050 case 9: /* Despeckle */
8051 {
8052 image=DespeckleImage(image,exception);
8053 break;
8054 }
8055 case 10: /* Edge */
8056 {
8057 if (attribute_flag[0] != 0)
8058 geometry_info.rho=argument_list[0].real_reference;
8059 image=EdgeImage(image,geometry_info.rho,exception);
8060 break;
8061 }
8062 case 11: /* Emboss */
8063 {
8064 if (attribute_flag[0] != 0)
8065 {
8066 flags=ParseGeometry(argument_list[0].string_reference,
8067 &geometry_info);
8068 if ((flags & SigmaValue) == 0)
8069 geometry_info.sigma=1.0;
8070 }
8071 if (attribute_flag[1] != 0)
8072 geometry_info.rho=argument_list[1].real_reference;
8073 if (attribute_flag[2] != 0)
8074 geometry_info.sigma=argument_list[2].real_reference;
8075 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8076 exception);
8077 break;
8078 }
8079 case 12: /* Enhance */
8080 {
8081 image=EnhanceImage(image,exception);
8082 break;
8083 }
8084 case 13: /* Flip */
8085 {
8086 image=FlipImage(image,exception);
8087 break;
8088 }
8089 case 14: /* Flop */
8090 {
8091 image=FlopImage(image,exception);
8092 break;
8093 }
8094 case 15: /* Frame */
8095 {
8096 CompositeOperator
8097 compose;
8098
8099 FrameInfo
8100 frame_info;
8101
8102 if (attribute_flag[0] != 0)
8103 {
8104 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8105 &geometry,exception);
8106 frame_info.width=geometry.width;
8107 frame_info.height=geometry.height;
8108 frame_info.outer_bevel=geometry.x;
8109 frame_info.inner_bevel=geometry.y;
8110 }
8111 if (attribute_flag[1] != 0)
8112 frame_info.width=argument_list[1].integer_reference;
8113 if (attribute_flag[2] != 0)
8114 frame_info.height=argument_list[2].integer_reference;
8115 if (attribute_flag[3] != 0)
8116 frame_info.inner_bevel=argument_list[3].integer_reference;
8117 if (attribute_flag[4] != 0)
8118 frame_info.outer_bevel=argument_list[4].integer_reference;
8119 if (attribute_flag[5] != 0)
8120 QueryColorCompliance(argument_list[5].string_reference,
8121 AllCompliance,&fill_color,exception);
8122 if (attribute_flag[6] != 0)
8123 QueryColorCompliance(argument_list[6].string_reference,
8124 AllCompliance,&fill_color,exception);
8125 frame_info.x=(ssize_t) frame_info.width;
8126 frame_info.y=(ssize_t) frame_info.height;
8127 frame_info.width=image->columns+2*frame_info.x;
8128 frame_info.height=image->rows+2*frame_info.y;
8129 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
Cristy8645e042016-02-03 16:35:29 -05008130 image->alpha_color=fill_color;
cristy4a3ce0a2013-08-03 20:06:59 +00008131 compose=image->compose;
8132 if (attribute_flag[7] != 0)
8133 compose=(CompositeOperator) argument_list[7].integer_reference;
8134 image=FrameImage(image,&frame_info,compose,exception);
8135 break;
8136 }
8137 case 16: /* Implode */
8138 {
8139 PixelInterpolateMethod
8140 method;
8141
8142 if (attribute_flag[0] == 0)
8143 argument_list[0].real_reference=0.5;
8144 method=UndefinedInterpolatePixel;
8145 if (attribute_flag[1] != 0)
8146 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8147 image=ImplodeImage(image,argument_list[0].real_reference,
8148 method,exception);
8149 break;
8150 }
8151 case 17: /* Magnify */
8152 {
8153 image=MagnifyImage(image,exception);
8154 break;
8155 }
8156 case 18: /* MedianFilter */
8157 {
8158 if (attribute_flag[0] != 0)
8159 {
8160 flags=ParseGeometry(argument_list[0].string_reference,
8161 &geometry_info);
8162 if ((flags & SigmaValue) == 0)
8163 geometry_info.sigma=geometry_info.rho;
8164 }
8165 if (attribute_flag[1] != 0)
8166 geometry_info.rho=argument_list[1].real_reference;
8167 if (attribute_flag[2] != 0)
8168 geometry_info.sigma=argument_list[2].real_reference;
8169 if (attribute_flag[3] != 0)
8170 channel=(ChannelType) argument_list[3].integer_reference;
8171 channel_mask=SetImageChannelMask(image,channel);
8172 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8173 (size_t) geometry_info.sigma,exception);
8174 if (image != (Image *) NULL)
8175 (void) SetImageChannelMask(image,channel_mask);
8176 break;
8177 }
8178 case 19: /* Minify */
8179 {
8180 image=MinifyImage(image,exception);
8181 break;
8182 }
8183 case 20: /* OilPaint */
8184 {
8185 if (attribute_flag[0] == 0)
8186 argument_list[0].real_reference=0.0;
8187 if (attribute_flag[1] == 0)
8188 argument_list[1].real_reference=1.0;
8189 image=OilPaintImage(image,argument_list[0].real_reference,
8190 argument_list[1].real_reference,exception);
8191 break;
8192 }
8193 case 21: /* ReduceNoise */
8194 {
8195 if (attribute_flag[0] != 0)
8196 {
8197 flags=ParseGeometry(argument_list[0].string_reference,
8198 &geometry_info);
8199 if ((flags & SigmaValue) == 0)
8200 geometry_info.sigma=1.0;
8201 }
8202 if (attribute_flag[1] != 0)
8203 geometry_info.rho=argument_list[1].real_reference;
8204 if (attribute_flag[2] != 0)
8205 geometry_info.sigma=argument_list[2].real_reference;
8206 if (attribute_flag[3] != 0)
8207 channel=(ChannelType) argument_list[3].integer_reference;
8208 channel_mask=SetImageChannelMask(image,channel);
8209 image=StatisticImage(image,NonpeakStatistic,(size_t)
8210 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8211 if (image != (Image *) NULL)
8212 (void) SetImageChannelMask(image,channel_mask);
8213 break;
8214 }
8215 case 22: /* Roll */
8216 {
8217 if (attribute_flag[0] != 0)
Cristyf94b0842017-07-14 07:05:02 -04008218 {
8219 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8220 &geometry,exception);
8221 if ((flags & PercentValue) != 0)
8222 {
8223 geometry.x*=(double) image->columns/100.0;
8224 geometry.y*=(double) image->rows/100.0;
8225 }
8226 }
cristy4a3ce0a2013-08-03 20:06:59 +00008227 if (attribute_flag[1] != 0)
8228 geometry.x=argument_list[1].integer_reference;
8229 if (attribute_flag[2] != 0)
8230 geometry.y=argument_list[2].integer_reference;
8231 image=RollImage(image,geometry.x,geometry.y,exception);
8232 break;
8233 }
8234 case 23: /* Rotate */
8235 {
8236 if (attribute_flag[0] == 0)
8237 argument_list[0].real_reference=90.0;
8238 if (attribute_flag[1] != 0)
8239 {
8240 QueryColorCompliance(argument_list[1].string_reference,
8241 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008242 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8243 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008244 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8245 }
8246 image=RotateImage(image,argument_list[0].real_reference,exception);
8247 break;
8248 }
8249 case 24: /* Sample */
8250 {
8251 if (attribute_flag[0] != 0)
8252 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8253 &geometry,exception);
8254 if (attribute_flag[1] != 0)
8255 geometry.width=argument_list[1].integer_reference;
8256 if (attribute_flag[2] != 0)
8257 geometry.height=argument_list[2].integer_reference;
8258 image=SampleImage(image,geometry.width,geometry.height,exception);
8259 break;
8260 }
8261 case 25: /* Scale */
8262 {
8263 if (attribute_flag[0] != 0)
8264 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8265 &geometry,exception);
8266 if (attribute_flag[1] != 0)
8267 geometry.width=argument_list[1].integer_reference;
8268 if (attribute_flag[2] != 0)
8269 geometry.height=argument_list[2].integer_reference;
8270 image=ScaleImage(image,geometry.width,geometry.height,exception);
8271 break;
8272 }
8273 case 26: /* Shade */
8274 {
8275 if (attribute_flag[0] != 0)
8276 {
8277 flags=ParseGeometry(argument_list[0].string_reference,
8278 &geometry_info);
8279 if ((flags & SigmaValue) == 0)
8280 geometry_info.sigma=0.0;
8281 }
8282 if (attribute_flag[1] != 0)
8283 geometry_info.rho=argument_list[1].real_reference;
8284 if (attribute_flag[2] != 0)
8285 geometry_info.sigma=argument_list[2].real_reference;
8286 image=ShadeImage(image,
8287 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8288 geometry_info.rho,geometry_info.sigma,exception);
8289 break;
8290 }
8291 case 27: /* Sharpen */
8292 {
8293 if (attribute_flag[0] != 0)
8294 {
8295 flags=ParseGeometry(argument_list[0].string_reference,
8296 &geometry_info);
8297 if ((flags & SigmaValue) == 0)
8298 geometry_info.sigma=1.0;
8299 }
8300 if (attribute_flag[1] != 0)
8301 geometry_info.rho=argument_list[1].real_reference;
8302 if (attribute_flag[2] != 0)
8303 geometry_info.sigma=argument_list[2].real_reference;
8304 if (attribute_flag[3] != 0)
8305 channel=(ChannelType) argument_list[3].integer_reference;
8306 channel_mask=SetImageChannelMask(image,channel);
8307 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8308 exception);
8309 if (image != (Image *) NULL)
8310 (void) SetImageChannelMask(image,channel_mask);
8311 break;
8312 }
8313 case 28: /* Shear */
8314 {
8315 if (attribute_flag[0] != 0)
8316 {
8317 flags=ParseGeometry(argument_list[0].string_reference,
8318 &geometry_info);
8319 if ((flags & SigmaValue) == 0)
8320 geometry_info.sigma=geometry_info.rho;
8321 }
8322 if (attribute_flag[1] != 0)
8323 geometry_info.rho=argument_list[1].real_reference;
8324 if (attribute_flag[2] != 0)
8325 geometry_info.sigma=argument_list[2].real_reference;
8326 if (attribute_flag[3] != 0)
8327 QueryColorCompliance(argument_list[3].string_reference,
8328 AllCompliance,&image->background_color,exception);
8329 if (attribute_flag[4] != 0)
8330 QueryColorCompliance(argument_list[4].string_reference,
8331 AllCompliance,&image->background_color,exception);
8332 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8333 exception);
8334 break;
8335 }
8336 case 29: /* Spread */
8337 {
Cristye3319c12015-08-24 07:11:48 -04008338 PixelInterpolateMethod
8339 method;
8340
cristy4a3ce0a2013-08-03 20:06:59 +00008341 if (attribute_flag[0] == 0)
8342 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008343 method=UndefinedInterpolatePixel;
8344 if (attribute_flag[1] != 0)
8345 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8346 image=SpreadImage(image,method,argument_list[0].real_reference,
8347 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008348 break;
8349 }
8350 case 30: /* Swirl */
8351 {
8352 PixelInterpolateMethod
8353 method;
8354
8355 if (attribute_flag[0] == 0)
8356 argument_list[0].real_reference=50.0;
8357 method=UndefinedInterpolatePixel;
8358 if (attribute_flag[1] != 0)
8359 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8360 image=SwirlImage(image,argument_list[0].real_reference,
8361 method,exception);
8362 break;
8363 }
8364 case 31: /* Resize */
8365 case 32: /* Zoom */
8366 {
8367 if (attribute_flag[0] != 0)
8368 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8369 &geometry,exception);
8370 if (attribute_flag[1] != 0)
8371 geometry.width=argument_list[1].integer_reference;
8372 if (attribute_flag[2] != 0)
8373 geometry.height=argument_list[2].integer_reference;
8374 if (attribute_flag[3] == 0)
8375 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8376 if (attribute_flag[4] != 0)
8377 SetImageArtifact(image,"filter:support",
8378 argument_list[4].string_reference);
8379 image=ResizeImage(image,geometry.width,geometry.height,
Cristy8645e042016-02-03 16:35:29 -05008380 (FilterType) argument_list[3].integer_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00008381 exception);
8382 break;
8383 }
8384 case 33: /* Annotate */
8385 {
8386 DrawInfo
8387 *draw_info;
8388
8389 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8390 (DrawInfo *) NULL);
8391 if (attribute_flag[0] != 0)
8392 {
8393 char
8394 *text;
8395
8396 text=InterpretImageProperties(info ? info->image_info :
8397 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8398 exception);
8399 (void) CloneString(&draw_info->text,text);
8400 text=DestroyString(text);
8401 }
8402 if (attribute_flag[1] != 0)
8403 (void) CloneString(&draw_info->font,
8404 argument_list[1].string_reference);
8405 if (attribute_flag[2] != 0)
8406 draw_info->pointsize=argument_list[2].real_reference;
8407 if (attribute_flag[3] != 0)
8408 (void) CloneString(&draw_info->density,
8409 argument_list[3].string_reference);
8410 if (attribute_flag[4] != 0)
8411 (void) QueryColorCompliance(argument_list[4].string_reference,
8412 AllCompliance,&draw_info->undercolor,exception);
8413 if (attribute_flag[5] != 0)
8414 {
8415 (void) QueryColorCompliance(argument_list[5].string_reference,
8416 AllCompliance,&draw_info->stroke,exception);
8417 if (argument_list[5].image_reference != (Image *) NULL)
8418 draw_info->stroke_pattern=CloneImage(
8419 argument_list[5].image_reference,0,0,MagickTrue,exception);
8420 }
8421 if (attribute_flag[6] != 0)
8422 {
8423 (void) QueryColorCompliance(argument_list[6].string_reference,
8424 AllCompliance,&draw_info->fill,exception);
8425 if (argument_list[6].image_reference != (Image *) NULL)
8426 draw_info->fill_pattern=CloneImage(
8427 argument_list[6].image_reference,0,0,MagickTrue,exception);
8428 }
8429 if (attribute_flag[7] != 0)
8430 {
8431 (void) CloneString(&draw_info->geometry,
8432 argument_list[7].string_reference);
8433 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8434 &geometry,exception);
8435 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8436 geometry_info.sigma=geometry_info.xi;
8437 }
8438 if (attribute_flag[8] != 0)
8439 (void) QueryColorCompliance(argument_list[8].string_reference,
8440 AllCompliance,&draw_info->fill,exception);
8441 if (attribute_flag[11] != 0)
8442 draw_info->gravity=(GravityType)
8443 argument_list[11].integer_reference;
8444 if (attribute_flag[25] != 0)
8445 {
8446 AV
8447 *av;
8448
8449 av=(AV *) argument_list[25].array_reference;
8450 if ((av_len(av) != 3) && (av_len(av) != 5))
8451 {
8452 ThrowPerlException(exception,OptionError,
8453 "affine matrix must have 4 or 6 elements",PackageName);
8454 goto PerlException;
8455 }
8456 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8457 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8458 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8459 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8460 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8461 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8462 {
8463 ThrowPerlException(exception,OptionError,
8464 "affine matrix is singular",PackageName);
8465 goto PerlException;
8466 }
8467 if (av_len(av) == 5)
8468 {
8469 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8470 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8471 }
8472 }
8473 for (j=12; j < 17; j++)
8474 {
8475 if (attribute_flag[j] == 0)
8476 continue;
8477 value=argument_list[j].string_reference;
8478 angle=argument_list[j].real_reference;
8479 current=draw_info->affine;
8480 GetAffineMatrix(&affine);
8481 switch (j)
8482 {
8483 case 12:
8484 {
8485 /*
8486 Translate.
8487 */
8488 flags=ParseGeometry(value,&geometry_info);
8489 affine.tx=geometry_info.xi;
8490 affine.ty=geometry_info.psi;
8491 if ((flags & PsiValue) == 0)
8492 affine.ty=affine.tx;
8493 break;
8494 }
8495 case 13:
8496 {
8497 /*
8498 Scale.
8499 */
8500 flags=ParseGeometry(value,&geometry_info);
8501 affine.sx=geometry_info.rho;
8502 affine.sy=geometry_info.sigma;
8503 if ((flags & SigmaValue) == 0)
8504 affine.sy=affine.sx;
8505 break;
8506 }
8507 case 14:
8508 {
8509 /*
8510 Rotate.
8511 */
8512 if (angle == 0.0)
8513 break;
8514 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8515 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8516 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8517 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8518 break;
8519 }
8520 case 15:
8521 {
8522 /*
8523 SkewX.
8524 */
8525 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8526 break;
8527 }
8528 case 16:
8529 {
8530 /*
8531 SkewY.
8532 */
8533 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8534 break;
8535 }
8536 }
8537 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8538 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8539 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8540 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8541 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8542 current.tx;
8543 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8544 current.ty;
8545 }
8546 if (attribute_flag[9] == 0)
8547 argument_list[9].real_reference=0.0;
8548 if (attribute_flag[10] == 0)
8549 argument_list[10].real_reference=0.0;
8550 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8551 {
8552 char
cristy151b66d2015-04-15 10:50:31 +00008553 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008554
cristy151b66d2015-04-15 10:50:31 +00008555 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008556 (double) argument_list[9].real_reference+draw_info->affine.tx,
8557 (double) argument_list[10].real_reference+draw_info->affine.ty);
8558 (void) CloneString(&draw_info->geometry,geometry);
8559 }
8560 if (attribute_flag[17] != 0)
8561 draw_info->stroke_width=argument_list[17].real_reference;
8562 if (attribute_flag[18] != 0)
8563 {
8564 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8565 MagickTrue : MagickFalse;
8566 draw_info->stroke_antialias=draw_info->text_antialias;
8567 }
8568 if (attribute_flag[19] != 0)
8569 (void) CloneString(&draw_info->family,
8570 argument_list[19].string_reference);
8571 if (attribute_flag[20] != 0)
8572 draw_info->style=(StyleType) argument_list[20].integer_reference;
8573 if (attribute_flag[21] != 0)
8574 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8575 if (attribute_flag[22] != 0)
8576 draw_info->weight=argument_list[22].integer_reference;
8577 if (attribute_flag[23] != 0)
8578 draw_info->align=(AlignType) argument_list[23].integer_reference;
8579 if (attribute_flag[24] != 0)
8580 (void) CloneString(&draw_info->encoding,
8581 argument_list[24].string_reference);
8582 if (attribute_flag[25] != 0)
8583 draw_info->fill_pattern=CloneImage(
8584 argument_list[25].image_reference,0,0,MagickTrue,exception);
8585 if (attribute_flag[26] != 0)
8586 draw_info->fill_pattern=CloneImage(
8587 argument_list[26].image_reference,0,0,MagickTrue,exception);
8588 if (attribute_flag[27] != 0)
8589 draw_info->stroke_pattern=CloneImage(
8590 argument_list[27].image_reference,0,0,MagickTrue,exception);
8591 if (attribute_flag[29] != 0)
8592 draw_info->kerning=argument_list[29].real_reference;
8593 if (attribute_flag[30] != 0)
8594 draw_info->interline_spacing=argument_list[30].real_reference;
8595 if (attribute_flag[31] != 0)
8596 draw_info->interword_spacing=argument_list[31].real_reference;
8597 if (attribute_flag[32] != 0)
8598 draw_info->direction=(DirectionType)
8599 argument_list[32].integer_reference;
8600 (void) AnnotateImage(image,draw_info,exception);
8601 draw_info=DestroyDrawInfo(draw_info);
8602 break;
8603 }
8604 case 34: /* ColorFloodfill */
8605 {
8606 DrawInfo
8607 *draw_info;
8608
8609 MagickBooleanType
8610 invert;
8611
8612 PixelInfo
8613 target;
8614
8615 draw_info=CloneDrawInfo(info ? info->image_info :
8616 (ImageInfo *) NULL,(DrawInfo *) NULL);
8617 if (attribute_flag[0] != 0)
8618 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8619 &geometry,exception);
8620 if (attribute_flag[1] != 0)
8621 geometry.x=argument_list[1].integer_reference;
8622 if (attribute_flag[2] != 0)
8623 geometry.y=argument_list[2].integer_reference;
8624 if (attribute_flag[3] != 0)
8625 (void) QueryColorCompliance(argument_list[3].string_reference,
8626 AllCompliance,&draw_info->fill,exception);
8627 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8628 geometry.x,geometry.y,&target,exception);
8629 invert=MagickFalse;
8630 if (attribute_flag[4] != 0)
8631 {
8632 QueryColorCompliance(argument_list[4].string_reference,
8633 AllCompliance,&target,exception);
8634 invert=MagickTrue;
8635 }
8636 if (attribute_flag[5] != 0)
8637 image->fuzz=StringToDoubleInterval(
8638 argument_list[5].string_reference,(double) QuantumRange+1.0);
8639 if (attribute_flag[6] != 0)
8640 invert=(MagickBooleanType) argument_list[6].integer_reference;
8641 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8642 geometry.y,invert,exception);
8643 draw_info=DestroyDrawInfo(draw_info);
8644 break;
8645 }
8646 case 35: /* Composite */
8647 {
8648 char
cristy151b66d2015-04-15 10:50:31 +00008649 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008650
8651 Image
8652 *composite_image,
8653 *rotate_image;
8654
8655 MagickBooleanType
8656 clip_to_self;
8657
8658 compose=OverCompositeOp;
8659 if (attribute_flag[0] != 0)
8660 composite_image=argument_list[0].image_reference;
8661 else
8662 {
8663 ThrowPerlException(exception,OptionError,
8664 "CompositeImageRequired",PackageName);
8665 goto PerlException;
8666 }
8667 /*
8668 Parameter Handling used for BOTH normal and tiled composition.
8669 */
8670 if (attribute_flag[1] != 0) /* compose */
8671 compose=(CompositeOperator) argument_list[1].integer_reference;
8672 if (attribute_flag[6] != 0) /* opacity */
8673 {
8674 if (compose != DissolveCompositeOp)
8675 (void) SetImageAlpha(composite_image,(Quantum)
8676 StringToDoubleInterval(argument_list[6].string_reference,
8677 (double) QuantumRange+1.0),exception);
8678 else
8679 {
8680 CacheView
8681 *composite_view;
8682
8683 double
8684 opacity;
8685
8686 MagickBooleanType
8687 sync;
8688
8689 register ssize_t
8690 x;
8691
8692 register Quantum
8693 *q;
8694
8695 ssize_t
8696 y;
8697
8698 /*
8699 Handle dissolve composite operator (patch by
8700 Kevin A. McGrail).
8701 */
8702 (void) CloneString(&image->geometry,
8703 argument_list[6].string_reference);
8704 opacity=(Quantum) StringToDoubleInterval(
8705 argument_list[6].string_reference,(double) QuantumRange+
8706 1.0);
cristy17f11b02014-12-20 19:37:04 +00008707 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008708 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8709 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8710 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8711 {
8712 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8713 composite_image->columns,1,exception);
8714 for (x=0; x < (ssize_t) composite_image->columns; x++)
8715 {
8716 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8717 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8718 q);
8719 q+=GetPixelChannels(composite_image);
8720 }
8721 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8722 if (sync == MagickFalse)
8723 break;
8724 }
8725 composite_view=DestroyCacheView(composite_view);
8726 }
8727 }
8728 if (attribute_flag[9] != 0) /* "color=>" */
8729 QueryColorCompliance(argument_list[9].string_reference,
8730 AllCompliance,&composite_image->background_color,exception);
8731 if (attribute_flag[12] != 0) /* "interpolate=>" */
8732 image->interpolate=(PixelInterpolateMethod)
8733 argument_list[12].integer_reference;
8734 if (attribute_flag[13] != 0) /* "args=>" */
8735 (void) SetImageArtifact(composite_image,"compose:args",
8736 argument_list[13].string_reference);
8737 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8738 (void) SetImageArtifact(composite_image,"compose:args",
8739 argument_list[14].string_reference);
Cristy72aed842018-07-08 18:25:50 -04008740 clip_to_self=MagickTrue;
8741 switch (compose)
8742 {
8743 case ClearCompositeOp:
8744 case SrcCompositeOp:
8745 case InCompositeOp:
8746 case SrcInCompositeOp:
8747 case OutCompositeOp:
8748 case SrcOutCompositeOp:
8749 case DstInCompositeOp:
8750 case DstAtopCompositeOp:
Cristy901f5212018-07-08 18:43:34 -04008751 case CopyAlphaCompositeOp:
Cristy72aed842018-07-08 18:25:50 -04008752 case ChangeMaskCompositeOp:
8753 case DissolveCompositeOp:
8754 case BlendCompositeOp:
8755 {
Cristy901f5212018-07-08 18:43:34 -04008756 clip_to_self=MagickFalse;
Cristy72aed842018-07-08 18:25:50 -04008757 break;
8758 }
8759 default:
8760 break;
8761 }
cristy4a3ce0a2013-08-03 20:06:59 +00008762 if (attribute_flag[15] != 0)
8763 clip_to_self=(MagickBooleanType)
8764 argument_list[15].integer_reference;
8765 /*
8766 Tiling Composition (with orthogonal rotate).
8767 */
8768 rotate_image=(Image *) NULL;
8769 if (attribute_flag[8] != 0) /* "rotate=>" */
8770 {
8771 /*
8772 Rotate image.
8773 */
8774 rotate_image=RotateImage(composite_image,
8775 argument_list[8].real_reference,exception);
8776 if (rotate_image == (Image *) NULL)
8777 break;
8778 }
8779 if ((attribute_flag[7] != 0) &&
8780 (argument_list[7].integer_reference != 0)) /* tile */
8781 {
8782 ssize_t
8783 x,
8784 y;
8785
8786 /*
8787 Tile the composite image.
8788 */
cristy4a3ce0a2013-08-03 20:06:59 +00008789 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8790 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8791 {
8792 if (attribute_flag[8] != 0) /* rotate */
8793 (void) CompositeImage(image,rotate_image,compose,
Cristyde6c67d2018-07-08 19:14:08 -04008794 MagickTrue,x,y,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008795 else
8796 (void) CompositeImage(image,composite_image,compose,
Cristyde6c67d2018-07-08 19:14:08 -04008797 MagickTrue,x,y,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008798 }
8799 if (attribute_flag[8] != 0) /* rotate */
8800 rotate_image=DestroyImage(rotate_image);
8801 break;
8802 }
8803 /*
8804 Parameter Handling used used ONLY for normal composition.
8805 */
8806 if (attribute_flag[5] != 0) /* gravity */
8807 image->gravity=(GravityType) argument_list[5].integer_reference;
8808 if (attribute_flag[2] != 0) /* geometry offset */
8809 {
8810 SetGeometry(image,&geometry);
8811 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8812 &geometry);
8813 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8814 &geometry);
8815 }
8816 if (attribute_flag[3] != 0) /* x offset */
8817 geometry.x=argument_list[3].integer_reference;
8818 if (attribute_flag[4] != 0) /* y offset */
8819 geometry.y=argument_list[4].integer_reference;
8820 if (attribute_flag[10] != 0) /* mask */
8821 {
8822 if ((image->compose == DisplaceCompositeOp) ||
8823 (image->compose == DistortCompositeOp))
8824 {
8825 /*
8826 Merge Y displacement into X displacement image.
8827 */
8828 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8829 exception);
8830 (void) CompositeImage(composite_image,
8831 argument_list[10].image_reference,CopyGreenCompositeOp,
Cristy74e39292018-07-08 13:13:20 -04008832 clip_to_self,0,0,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008833 }
8834 else
8835 {
8836 Image
8837 *mask_image;
8838
8839 /*
8840 Set a blending mask for the composition.
8841 */
8842 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8843 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008844 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008845 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008846 mask_image=DestroyImage(mask_image);
8847 }
8848 }
8849 if (attribute_flag[11] != 0) /* channel */
8850 channel=(ChannelType) argument_list[11].integer_reference;
8851 /*
8852 Composite two images (normal composition).
8853 */
cristy151b66d2015-04-15 10:50:31 +00008854 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008855 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8856 (double) composite_image->rows,(double) geometry.x,(double)
8857 geometry.y);
8858 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8859 exception);
8860 channel_mask=SetImageChannelMask(image,channel);
8861 if (attribute_flag[8] == 0) /* no rotate */
8862 CompositeImage(image,composite_image,compose,clip_to_self,
8863 geometry.x,geometry.y,exception);
8864 else
8865 {
8866 /*
8867 Position adjust rotated image then composite.
8868 */
8869 geometry.x-=(ssize_t) (rotate_image->columns-
8870 composite_image->columns)/2;
8871 geometry.y-=(ssize_t) (rotate_image->rows-
8872 composite_image->rows)/2;
8873 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8874 geometry.y,exception);
8875 rotate_image=DestroyImage(rotate_image);
8876 }
8877 if (attribute_flag[10] != 0) /* mask */
8878 {
8879 if ((image->compose == DisplaceCompositeOp) ||
8880 (image->compose == DistortCompositeOp))
8881 composite_image=DestroyImage(composite_image);
8882 else
cristy1f7ffb72015-07-29 11:07:03 +00008883 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008884 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008885 }
8886 (void) SetImageChannelMask(image,channel_mask);
8887 break;
8888 }
8889 case 36: /* Contrast */
8890 {
8891 if (attribute_flag[0] == 0)
8892 argument_list[0].integer_reference=0;
8893 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8894 MagickTrue : MagickFalse,exception);
8895 break;
8896 }
8897 case 37: /* CycleColormap */
8898 {
8899 if (attribute_flag[0] == 0)
8900 argument_list[0].integer_reference=6;
8901 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8902 exception);
8903 break;
8904 }
8905 case 38: /* Draw */
8906 {
8907 DrawInfo
8908 *draw_info;
8909
8910 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8911 (DrawInfo *) NULL);
8912 (void) CloneString(&draw_info->primitive,"point");
8913 if (attribute_flag[0] != 0)
8914 {
8915 if (argument_list[0].integer_reference < 0)
8916 (void) CloneString(&draw_info->primitive,
8917 argument_list[0].string_reference);
8918 else
8919 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8920 MagickPrimitiveOptions,argument_list[0].integer_reference));
8921 }
8922 if (attribute_flag[1] != 0)
8923 {
8924 if (LocaleCompare(draw_info->primitive,"path") == 0)
8925 {
8926 (void) ConcatenateString(&draw_info->primitive," '");
8927 ConcatenateString(&draw_info->primitive,
8928 argument_list[1].string_reference);
8929 (void) ConcatenateString(&draw_info->primitive,"'");
8930 }
8931 else
8932 {
8933 (void) ConcatenateString(&draw_info->primitive," ");
8934 ConcatenateString(&draw_info->primitive,
8935 argument_list[1].string_reference);
8936 }
8937 }
8938 if (attribute_flag[2] != 0)
8939 {
8940 (void) ConcatenateString(&draw_info->primitive," ");
8941 (void) ConcatenateString(&draw_info->primitive,
8942 CommandOptionToMnemonic(MagickMethodOptions,
8943 argument_list[2].integer_reference));
8944 }
8945 if (attribute_flag[3] != 0)
8946 {
8947 (void) QueryColorCompliance(argument_list[3].string_reference,
8948 AllCompliance,&draw_info->stroke,exception);
8949 if (argument_list[3].image_reference != (Image *) NULL)
8950 draw_info->stroke_pattern=CloneImage(
8951 argument_list[3].image_reference,0,0,MagickTrue,exception);
8952 }
8953 if (attribute_flag[4] != 0)
8954 {
8955 (void) QueryColorCompliance(argument_list[4].string_reference,
8956 AllCompliance,&draw_info->fill,exception);
8957 if (argument_list[4].image_reference != (Image *) NULL)
8958 draw_info->fill_pattern=CloneImage(
8959 argument_list[4].image_reference,0,0,MagickTrue,exception);
8960 }
8961 if (attribute_flag[5] != 0)
8962 draw_info->stroke_width=argument_list[5].real_reference;
8963 if (attribute_flag[6] != 0)
8964 (void) CloneString(&draw_info->font,
8965 argument_list[6].string_reference);
8966 if (attribute_flag[7] != 0)
8967 (void) QueryColorCompliance(argument_list[7].string_reference,
8968 AllCompliance,&draw_info->border_color,exception);
8969 if (attribute_flag[8] != 0)
8970 draw_info->affine.tx=argument_list[8].real_reference;
8971 if (attribute_flag[9] != 0)
8972 draw_info->affine.ty=argument_list[9].real_reference;
8973 if (attribute_flag[20] != 0)
8974 {
8975 AV
8976 *av;
8977
8978 av=(AV *) argument_list[20].array_reference;
8979 if ((av_len(av) != 3) && (av_len(av) != 5))
8980 {
8981 ThrowPerlException(exception,OptionError,
8982 "affine matrix must have 4 or 6 elements",PackageName);
8983 goto PerlException;
8984 }
8985 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8986 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8987 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8988 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8989 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8990 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8991 {
8992 ThrowPerlException(exception,OptionError,
8993 "affine matrix is singular",PackageName);
8994 goto PerlException;
8995 }
8996 if (av_len(av) == 5)
8997 {
8998 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8999 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9000 }
9001 }
9002 for (j=10; j < 15; j++)
9003 {
9004 if (attribute_flag[j] == 0)
9005 continue;
9006 value=argument_list[j].string_reference;
9007 angle=argument_list[j].real_reference;
9008 current=draw_info->affine;
9009 GetAffineMatrix(&affine);
9010 switch (j)
9011 {
9012 case 10:
9013 {
9014 /*
9015 Translate.
9016 */
9017 flags=ParseGeometry(value,&geometry_info);
9018 affine.tx=geometry_info.xi;
9019 affine.ty=geometry_info.psi;
9020 if ((flags & PsiValue) == 0)
9021 affine.ty=affine.tx;
9022 break;
9023 }
9024 case 11:
9025 {
9026 /*
9027 Scale.
9028 */
9029 flags=ParseGeometry(value,&geometry_info);
9030 affine.sx=geometry_info.rho;
9031 affine.sy=geometry_info.sigma;
9032 if ((flags & SigmaValue) == 0)
9033 affine.sy=affine.sx;
9034 break;
9035 }
9036 case 12:
9037 {
9038 /*
9039 Rotate.
9040 */
9041 if (angle == 0.0)
9042 break;
9043 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9044 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9045 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9046 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9047 break;
9048 }
9049 case 13:
9050 {
9051 /*
9052 SkewX.
9053 */
9054 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9055 break;
9056 }
9057 case 14:
9058 {
9059 /*
9060 SkewY.
9061 */
9062 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9063 break;
9064 }
9065 }
9066 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9067 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9068 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9069 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9070 draw_info->affine.tx=
9071 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9072 draw_info->affine.ty=
9073 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9074 }
9075 if (attribute_flag[15] != 0)
9076 draw_info->fill_pattern=CloneImage(
9077 argument_list[15].image_reference,0,0,MagickTrue,exception);
9078 if (attribute_flag[16] != 0)
9079 draw_info->pointsize=argument_list[16].real_reference;
9080 if (attribute_flag[17] != 0)
9081 {
9082 draw_info->stroke_antialias=argument_list[17].integer_reference != 0
9083 ? MagickTrue : MagickFalse;
9084 draw_info->text_antialias=draw_info->stroke_antialias;
9085 }
9086 if (attribute_flag[18] != 0)
9087 (void) CloneString(&draw_info->density,
9088 argument_list[18].string_reference);
9089 if (attribute_flag[19] != 0)
9090 draw_info->stroke_width=argument_list[19].real_reference;
9091 if (attribute_flag[21] != 0)
9092 draw_info->dash_offset=argument_list[21].real_reference;
9093 if (attribute_flag[22] != 0)
9094 {
9095 AV
9096 *av;
9097
9098 av=(AV *) argument_list[22].array_reference;
9099 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9100 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9101 if (draw_info->dash_pattern != (double *) NULL)
9102 {
9103 for (i=0; i <= av_len(av); i++)
9104 draw_info->dash_pattern[i]=(double)
9105 SvNV(*(av_fetch(av,i,0)));
9106 draw_info->dash_pattern[i]=0.0;
9107 }
9108 }
9109 if (attribute_flag[23] != 0)
9110 image->interpolate=(PixelInterpolateMethod)
9111 argument_list[23].integer_reference;
9112 if ((attribute_flag[24] != 0) &&
9113 (draw_info->fill_pattern != (Image *) NULL))
9114 flags=ParsePageGeometry(draw_info->fill_pattern,
9115 argument_list[24].string_reference,
9116 &draw_info->fill_pattern->tile_offset,exception);
9117 if (attribute_flag[25] != 0)
9118 {
9119 (void) ConcatenateString(&draw_info->primitive," '");
9120 (void) ConcatenateString(&draw_info->primitive,
9121 argument_list[25].string_reference);
9122 (void) ConcatenateString(&draw_info->primitive,"'");
9123 }
9124 if (attribute_flag[26] != 0)
9125 draw_info->fill_pattern=CloneImage(
9126 argument_list[26].image_reference,0,0,MagickTrue,exception);
9127 if (attribute_flag[27] != 0)
9128 draw_info->stroke_pattern=CloneImage(
9129 argument_list[27].image_reference,0,0,MagickTrue,exception);
9130 if (attribute_flag[28] != 0)
9131 (void) CloneString(&draw_info->primitive,
9132 argument_list[28].string_reference);
9133 if (attribute_flag[29] != 0)
9134 draw_info->kerning=argument_list[29].real_reference;
9135 if (attribute_flag[30] != 0)
9136 draw_info->interline_spacing=argument_list[30].real_reference;
9137 if (attribute_flag[31] != 0)
9138 draw_info->interword_spacing=argument_list[31].real_reference;
9139 if (attribute_flag[32] != 0)
9140 draw_info->direction=(DirectionType)
9141 argument_list[32].integer_reference;
9142 DrawImage(image,draw_info,exception);
9143 draw_info=DestroyDrawInfo(draw_info);
9144 break;
9145 }
9146 case 39: /* Equalize */
9147 {
9148 if (attribute_flag[0] != 0)
9149 channel=(ChannelType) argument_list[0].integer_reference;
9150 channel_mask=SetImageChannelMask(image,channel);
9151 EqualizeImage(image,exception);
9152 (void) SetImageChannelMask(image,channel_mask);
9153 break;
9154 }
9155 case 40: /* Gamma */
9156 {
9157 if (attribute_flag[1] != 0)
9158 channel=(ChannelType) argument_list[1].integer_reference;
9159 if (attribute_flag[2] == 0)
9160 argument_list[2].real_reference=1.0;
9161 if (attribute_flag[3] == 0)
9162 argument_list[3].real_reference=1.0;
9163 if (attribute_flag[4] == 0)
9164 argument_list[4].real_reference=1.0;
9165 if (attribute_flag[0] == 0)
9166 {
cristy151b66d2015-04-15 10:50:31 +00009167 (void) FormatLocaleString(message,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -05009168 "%.20g,%.20g,%.20g",(double) argument_list[2].real_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009169 (double) argument_list[3].real_reference,
9170 (double) argument_list[4].real_reference);
9171 argument_list[0].string_reference=message;
9172 }
9173 (void) GammaImage(image,StringToDouble(
9174 argument_list[0].string_reference,(char **) NULL),exception);
9175 break;
9176 }
9177 case 41: /* Map */
9178 {
9179 QuantizeInfo
9180 *quantize_info;
9181
9182 if (attribute_flag[0] == 0)
9183 {
9184 ThrowPerlException(exception,OptionError,"MapImageRequired",
9185 PackageName);
9186 goto PerlException;
9187 }
9188 quantize_info=AcquireQuantizeInfo(info->image_info);
9189 if (attribute_flag[1] != 0)
9190 quantize_info->dither_method=(DitherMethod)
9191 argument_list[1].integer_reference;
9192 (void) RemapImages(quantize_info,image,
9193 argument_list[0].image_reference,exception);
9194 quantize_info=DestroyQuantizeInfo(quantize_info);
9195 break;
9196 }
9197 case 42: /* MatteFloodfill */
9198 {
9199 DrawInfo
9200 *draw_info;
9201
9202 MagickBooleanType
9203 invert;
9204
9205 PixelInfo
9206 target;
9207
9208 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9209 (DrawInfo *) NULL);
9210 if (attribute_flag[0] != 0)
9211 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9212 &geometry,exception);
9213 if (attribute_flag[1] != 0)
9214 geometry.x=argument_list[1].integer_reference;
9215 if (attribute_flag[2] != 0)
9216 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009217 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009218 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9219 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9220 geometry.x,geometry.y,&target,exception);
9221 if (attribute_flag[4] != 0)
9222 QueryColorCompliance(argument_list[4].string_reference,
9223 AllCompliance,&target,exception);
9224 if (attribute_flag[3] != 0)
9225 target.alpha=StringToDoubleInterval(
9226 argument_list[3].string_reference,(double) (double) QuantumRange+
9227 1.0);
9228 if (attribute_flag[5] != 0)
9229 image->fuzz=StringToDoubleInterval(
9230 argument_list[5].string_reference,(double) QuantumRange+1.0);
9231 invert=MagickFalse;
9232 if (attribute_flag[6] != 0)
9233 invert=(MagickBooleanType) argument_list[6].integer_reference;
9234 channel_mask=SetImageChannelMask(image,AlphaChannel);
9235 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9236 geometry.y,invert,exception);
9237 (void) SetImageChannelMask(image,channel_mask);
9238 draw_info=DestroyDrawInfo(draw_info);
9239 break;
9240 }
9241 case 43: /* Modulate */
9242 {
9243 char
cristy151b66d2015-04-15 10:50:31 +00009244 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009245
9246 geometry_info.rho=100.0;
9247 geometry_info.sigma=100.0;
9248 geometry_info.xi=100.0;
9249 if (attribute_flag[0] != 0)
9250 (void)ParseGeometry(argument_list[0].string_reference,
9251 &geometry_info);
9252 if (attribute_flag[1] != 0)
9253 geometry_info.xi=argument_list[1].real_reference;
9254 if (attribute_flag[2] != 0)
9255 geometry_info.sigma=argument_list[2].real_reference;
9256 if (attribute_flag[3] != 0)
9257 {
9258 geometry_info.sigma=argument_list[3].real_reference;
9259 SetImageArtifact(image,"modulate:colorspace","HWB");
9260 }
9261 if (attribute_flag[4] != 0)
9262 {
9263 geometry_info.rho=argument_list[4].real_reference;
9264 SetImageArtifact(image,"modulate:colorspace","HSB");
9265 }
9266 if (attribute_flag[5] != 0)
9267 {
9268 geometry_info.sigma=argument_list[5].real_reference;
9269 SetImageArtifact(image,"modulate:colorspace","HSL");
9270 }
9271 if (attribute_flag[6] != 0)
9272 {
9273 geometry_info.rho=argument_list[6].real_reference;
9274 SetImageArtifact(image,"modulate:colorspace","HWB");
9275 }
Cristy935a4052017-03-31 17:45:37 -04009276 (void) FormatLocaleString(modulate,MagickPathExtent,"%.20g,%.20g,%.20g",
9277 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy4a3ce0a2013-08-03 20:06:59 +00009278 (void) ModulateImage(image,modulate,exception);
9279 break;
9280 }
9281 case 44: /* Negate */
9282 {
9283 if (attribute_flag[0] == 0)
9284 argument_list[0].integer_reference=0;
9285 if (attribute_flag[1] != 0)
9286 channel=(ChannelType) argument_list[1].integer_reference;
9287 channel_mask=SetImageChannelMask(image,channel);
9288 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9289 MagickTrue : MagickFalse,exception);
9290 (void) SetImageChannelMask(image,channel_mask);
9291 break;
9292 }
9293 case 45: /* Normalize */
9294 {
9295 if (attribute_flag[0] != 0)
9296 channel=(ChannelType) argument_list[0].integer_reference;
9297 channel_mask=SetImageChannelMask(image,channel);
9298 NormalizeImage(image,exception);
9299 (void) SetImageChannelMask(image,channel_mask);
9300 break;
9301 }
9302 case 46: /* NumberColors */
9303 break;
9304 case 47: /* Opaque */
9305 {
9306 MagickBooleanType
9307 invert;
9308
9309 PixelInfo
9310 fill_color,
9311 target;
9312
9313 (void) QueryColorCompliance("none",AllCompliance,&target,
9314 exception);
9315 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9316 exception);
9317 if (attribute_flag[0] != 0)
9318 (void) QueryColorCompliance(argument_list[0].string_reference,
9319 AllCompliance,&target,exception);
9320 if (attribute_flag[1] != 0)
9321 (void) QueryColorCompliance(argument_list[1].string_reference,
9322 AllCompliance,&fill_color,exception);
9323 if (attribute_flag[2] != 0)
9324 image->fuzz=StringToDoubleInterval(
9325 argument_list[2].string_reference,(double) QuantumRange+1.0);
9326 if (attribute_flag[3] != 0)
9327 channel=(ChannelType) argument_list[3].integer_reference;
9328 invert=MagickFalse;
9329 if (attribute_flag[4] != 0)
9330 invert=(MagickBooleanType) argument_list[4].integer_reference;
9331 channel_mask=SetImageChannelMask(image,channel);
9332 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9333 (void) SetImageChannelMask(image,channel_mask);
9334 break;
9335 }
9336 case 48: /* Quantize */
9337 {
9338 QuantizeInfo
9339 *quantize_info;
9340
9341 quantize_info=AcquireQuantizeInfo(info->image_info);
9342 if (attribute_flag[0] != 0)
9343 quantize_info->number_colors=(size_t)
9344 argument_list[0].integer_reference;
9345 if (attribute_flag[1] != 0)
9346 quantize_info->tree_depth=(size_t)
9347 argument_list[1].integer_reference;
9348 if (attribute_flag[2] != 0)
9349 quantize_info->colorspace=(ColorspaceType)
9350 argument_list[2].integer_reference;
9351 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009352 quantize_info->dither_method=(DitherMethod)
9353 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009354 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009355 quantize_info->measure_error=
9356 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009357 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009358 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009359 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009360 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009361 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009362 argument_list[7].integer_reference;
9363 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009364 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009365 else
cristyf7563392014-03-25 13:54:04 +00009366 if ((image->storage_class == DirectClass) ||
9367 (image->colors > quantize_info->number_colors) ||
9368 (quantize_info->colorspace == GRAYColorspace))
9369 (void) QuantizeImage(quantize_info,image,exception);
9370 else
9371 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009372 quantize_info=DestroyQuantizeInfo(quantize_info);
9373 break;
9374 }
9375 case 49: /* Raise */
9376 {
9377 if (attribute_flag[0] != 0)
9378 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9379 &geometry,exception);
9380 if (attribute_flag[1] != 0)
9381 geometry.width=argument_list[1].integer_reference;
9382 if (attribute_flag[2] != 0)
9383 geometry.height=argument_list[2].integer_reference;
9384 if (attribute_flag[3] == 0)
9385 argument_list[3].integer_reference=1;
9386 (void) RaiseImage(image,&geometry,
9387 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9388 exception);
9389 break;
9390 }
9391 case 50: /* Segment */
9392 {
9393 ColorspaceType
9394 colorspace;
9395
9396 double
9397 cluster_threshold,
9398 smoothing_threshold;
9399
9400 MagickBooleanType
9401 verbose;
9402
9403 cluster_threshold=1.0;
9404 smoothing_threshold=1.5;
9405 colorspace=sRGBColorspace;
9406 verbose=MagickFalse;
9407 if (attribute_flag[0] != 0)
9408 {
9409 flags=ParseGeometry(argument_list[0].string_reference,
9410 &geometry_info);
9411 cluster_threshold=geometry_info.rho;
9412 if (flags & SigmaValue)
9413 smoothing_threshold=geometry_info.sigma;
9414 }
9415 if (attribute_flag[1] != 0)
9416 cluster_threshold=argument_list[1].real_reference;
9417 if (attribute_flag[2] != 0)
9418 smoothing_threshold=argument_list[2].real_reference;
9419 if (attribute_flag[3] != 0)
9420 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9421 if (attribute_flag[4] != 0)
9422 verbose=argument_list[4].integer_reference != 0 ?
9423 MagickTrue : MagickFalse;
9424 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9425 smoothing_threshold,exception);
9426 break;
9427 }
9428 case 51: /* Signature */
9429 {
9430 (void) SignatureImage(image,exception);
9431 break;
9432 }
9433 case 52: /* Solarize */
9434 {
9435 geometry_info.rho=QuantumRange/2.0;
9436 if (attribute_flag[0] != 0)
9437 flags=ParseGeometry(argument_list[0].string_reference,
9438 &geometry_info);
9439 if (attribute_flag[1] != 0)
9440 geometry_info.rho=StringToDoubleInterval(
9441 argument_list[1].string_reference,(double) QuantumRange+1.0);
9442 (void) SolarizeImage(image,geometry_info.rho,exception);
9443 break;
9444 }
9445 case 53: /* Sync */
9446 {
9447 (void) SyncImage(image,exception);
9448 break;
9449 }
9450 case 54: /* Texture */
9451 {
9452 if (attribute_flag[0] == 0)
9453 break;
9454 TextureImage(image,argument_list[0].image_reference,exception);
9455 break;
9456 }
9457 case 55: /* Evalute */
9458 {
9459 MagickEvaluateOperator
9460 op;
9461
9462 op=SetEvaluateOperator;
9463 if (attribute_flag[0] == MagickFalse)
9464 argument_list[0].real_reference=0.0;
9465 if (attribute_flag[1] != MagickFalse)
9466 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9467 if (attribute_flag[2] != MagickFalse)
9468 channel=(ChannelType) argument_list[2].integer_reference;
9469 channel_mask=SetImageChannelMask(image,channel);
9470 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9471 exception);
9472 (void) SetImageChannelMask(image,channel_mask);
9473 break;
9474 }
9475 case 56: /* Transparent */
9476 {
9477 double
9478 opacity;
9479
9480 MagickBooleanType
9481 invert;
9482
9483 PixelInfo
9484 target;
9485
9486 (void) QueryColorCompliance("none",AllCompliance,&target,
9487 exception);
9488 if (attribute_flag[0] != 0)
9489 (void) QueryColorCompliance(argument_list[0].string_reference,
9490 AllCompliance,&target,exception);
9491 opacity=TransparentAlpha;
9492 if (attribute_flag[1] != 0)
9493 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9494 (double) QuantumRange+1.0);
9495 if (attribute_flag[2] != 0)
9496 image->fuzz=StringToDoubleInterval(
9497 argument_list[2].string_reference,(double) QuantumRange+1.0);
9498 if (attribute_flag[3] == 0)
9499 argument_list[3].integer_reference=0;
9500 invert=MagickFalse;
9501 if (attribute_flag[3] != 0)
9502 invert=(MagickBooleanType) argument_list[3].integer_reference;
9503 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9504 invert,exception);
9505 break;
9506 }
9507 case 57: /* Threshold */
9508 {
9509 double
9510 threshold;
9511
9512 if (attribute_flag[0] == 0)
9513 argument_list[0].string_reference="50%";
9514 if (attribute_flag[1] != 0)
9515 channel=(ChannelType) argument_list[1].integer_reference;
9516 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9517 (double) QuantumRange+1.0);
9518 channel_mask=SetImageChannelMask(image,channel);
9519 (void) BilevelImage(image,threshold,exception);
9520 (void) SetImageChannelMask(image,channel_mask);
9521 break;
9522 }
9523 case 58: /* Charcoal */
9524 {
9525 if (attribute_flag[0] != 0)
9526 {
9527 flags=ParseGeometry(argument_list[0].string_reference,
9528 &geometry_info);
9529 if ((flags & SigmaValue) == 0)
9530 geometry_info.sigma=1.0;
9531 }
9532 if (attribute_flag[1] != 0)
9533 geometry_info.rho=argument_list[1].real_reference;
9534 if (attribute_flag[2] != 0)
9535 geometry_info.sigma=argument_list[2].real_reference;
9536 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9537 exception);
9538 break;
9539 }
9540 case 59: /* Trim */
9541 {
9542 if (attribute_flag[0] != 0)
9543 image->fuzz=StringToDoubleInterval(
9544 argument_list[0].string_reference,(double) QuantumRange+1.0);
9545 image=TrimImage(image,exception);
9546 break;
9547 }
9548 case 60: /* Wave */
9549 {
9550 PixelInterpolateMethod
9551 method;
9552
9553 if (attribute_flag[0] != 0)
9554 {
9555 flags=ParseGeometry(argument_list[0].string_reference,
9556 &geometry_info);
9557 if ((flags & SigmaValue) == 0)
9558 geometry_info.sigma=1.0;
9559 }
9560 if (attribute_flag[1] != 0)
9561 geometry_info.rho=argument_list[1].real_reference;
9562 if (attribute_flag[2] != 0)
9563 geometry_info.sigma=argument_list[2].real_reference;
9564 method=UndefinedInterpolatePixel;
9565 if (attribute_flag[3] != 0)
9566 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9567 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9568 method,exception);
9569 break;
9570 }
9571 case 61: /* Separate */
9572 {
9573 if (attribute_flag[0] != 0)
9574 channel=(ChannelType) argument_list[0].integer_reference;
9575 image=SeparateImage(image,channel,exception);
9576 break;
9577 }
9578 case 63: /* Stereo */
9579 {
9580 if (attribute_flag[0] == 0)
9581 {
9582 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9583 PackageName);
9584 goto PerlException;
9585 }
9586 if (attribute_flag[1] != 0)
9587 geometry.x=argument_list[1].integer_reference;
9588 if (attribute_flag[2] != 0)
9589 geometry.y=argument_list[2].integer_reference;
9590 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9591 geometry.x,geometry.y,exception);
9592 break;
9593 }
9594 case 64: /* Stegano */
9595 {
9596 if (attribute_flag[0] == 0)
9597 {
9598 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9599 PackageName);
9600 goto PerlException;
9601 }
9602 if (attribute_flag[1] == 0)
9603 argument_list[1].integer_reference=0;
9604 image->offset=argument_list[1].integer_reference;
9605 image=SteganoImage(image,argument_list[0].image_reference,exception);
9606 break;
9607 }
9608 case 65: /* Deconstruct */
9609 {
9610 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9611 break;
9612 }
9613 case 66: /* GaussianBlur */
9614 {
9615 if (attribute_flag[0] != 0)
9616 {
9617 flags=ParseGeometry(argument_list[0].string_reference,
9618 &geometry_info);
9619 if ((flags & SigmaValue) == 0)
9620 geometry_info.sigma=1.0;
9621 }
9622 if (attribute_flag[1] != 0)
9623 geometry_info.rho=argument_list[1].real_reference;
9624 if (attribute_flag[2] != 0)
9625 geometry_info.sigma=argument_list[2].real_reference;
9626 if (attribute_flag[3] != 0)
9627 channel=(ChannelType) argument_list[3].integer_reference;
9628 channel_mask=SetImageChannelMask(image,channel);
9629 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9630 exception);
9631 if (image != (Image *) NULL)
9632 (void) SetImageChannelMask(image,channel_mask);
9633 break;
9634 }
9635 case 67: /* Convolve */
9636 {
9637 KernelInfo
9638 *kernel;
9639
9640 kernel=(KernelInfo *) NULL;
9641 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9642 break;
9643 if (attribute_flag[0] != 0)
9644 {
9645 AV
9646 *av;
9647
9648 size_t
9649 order;
9650
cristy2c57b742014-10-31 00:40:34 +00009651 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009652 if (kernel == (KernelInfo *) NULL)
9653 break;
9654 av=(AV *) argument_list[0].array_reference;
9655 order=(size_t) sqrt(av_len(av)+1);
9656 kernel->width=order;
9657 kernel->height=order;
9658 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9659 order*sizeof(*kernel->values));
9660 if (kernel->values == (MagickRealType *) NULL)
9661 {
9662 kernel=DestroyKernelInfo(kernel);
9663 ThrowPerlException(exception,ResourceLimitFatalError,
9664 "MemoryAllocationFailed",PackageName);
9665 goto PerlException;
9666 }
9667 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9668 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9669 for ( ; j < (ssize_t) (order*order); j++)
9670 kernel->values[j]=0.0;
9671 }
9672 if (attribute_flag[1] != 0)
9673 channel=(ChannelType) argument_list[1].integer_reference;
9674 if (attribute_flag[2] != 0)
Cristyc4ff6bd2017-07-05 21:00:11 -04009675 SetImageArtifact(image,"convolve:bias",
cristy4a3ce0a2013-08-03 20:06:59 +00009676 argument_list[2].string_reference);
9677 if (attribute_flag[3] != 0)
9678 {
cristy2c57b742014-10-31 00:40:34 +00009679 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9680 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009681 if (kernel == (KernelInfo *) NULL)
9682 break;
9683 }
9684 channel_mask=SetImageChannelMask(image,channel);
9685 image=ConvolveImage(image,kernel,exception);
9686 if (image != (Image *) NULL)
9687 (void) SetImageChannelMask(image,channel_mask);
9688 kernel=DestroyKernelInfo(kernel);
9689 break;
9690 }
9691 case 68: /* Profile */
9692 {
9693 const char
9694 *name;
9695
9696 Image
9697 *profile_image;
9698
9699 ImageInfo
9700 *profile_info;
9701
9702 StringInfo
9703 *profile;
9704
9705 name="*";
9706 if (attribute_flag[0] != 0)
9707 name=argument_list[0].string_reference;
9708 if (attribute_flag[2] != 0)
9709 image->rendering_intent=(RenderingIntent)
9710 argument_list[2].integer_reference;
9711 if (attribute_flag[3] != 0)
9712 image->black_point_compensation=
9713 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9714 if (attribute_flag[1] != 0)
9715 {
9716 if (argument_list[1].length == 0)
9717 {
9718 /*
9719 Remove a profile from the image.
9720 */
9721 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9722 exception);
9723 break;
9724 }
9725 /*
9726 Associate user supplied profile with the image.
9727 */
9728 profile=AcquireStringInfo(argument_list[1].length);
9729 SetStringInfoDatum(profile,(const unsigned char *)
9730 argument_list[1].string_reference);
9731 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9732 (size_t) GetStringInfoLength(profile),exception);
9733 profile=DestroyStringInfo(profile);
9734 break;
9735 }
9736 /*
9737 Associate a profile with the image.
9738 */
9739 profile_info=CloneImageInfo(info ? info->image_info :
9740 (ImageInfo *) NULL);
9741 profile_image=ReadImages(profile_info,name,exception);
9742 if (profile_image == (Image *) NULL)
9743 break;
9744 ResetImageProfileIterator(profile_image);
9745 name=GetNextImageProfile(profile_image);
9746 while (name != (const char *) NULL)
9747 {
9748 const StringInfo
9749 *profile;
9750
9751 profile=GetImageProfile(profile_image,name);
9752 if (profile != (const StringInfo *) NULL)
9753 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9754 (size_t) GetStringInfoLength(profile),exception);
9755 name=GetNextImageProfile(profile_image);
9756 }
9757 profile_image=DestroyImage(profile_image);
9758 profile_info=DestroyImageInfo(profile_info);
9759 break;
9760 }
9761 case 69: /* UnsharpMask */
9762 {
9763 if (attribute_flag[0] != 0)
9764 {
9765 flags=ParseGeometry(argument_list[0].string_reference,
9766 &geometry_info);
9767 if ((flags & SigmaValue) == 0)
9768 geometry_info.sigma=1.0;
9769 if ((flags & XiValue) == 0)
9770 geometry_info.xi=1.0;
9771 if ((flags & PsiValue) == 0)
9772 geometry_info.psi=0.5;
9773 }
9774 if (attribute_flag[1] != 0)
9775 geometry_info.rho=argument_list[1].real_reference;
9776 if (attribute_flag[2] != 0)
9777 geometry_info.sigma=argument_list[2].real_reference;
9778 if (attribute_flag[3] != 0)
9779 geometry_info.xi=argument_list[3].real_reference;
9780 if (attribute_flag[4] != 0)
9781 geometry_info.psi=argument_list[4].real_reference;
9782 if (attribute_flag[5] != 0)
9783 channel=(ChannelType) argument_list[5].integer_reference;
9784 channel_mask=SetImageChannelMask(image,channel);
9785 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9786 geometry_info.xi,geometry_info.psi,exception);
9787 if (image != (Image *) NULL)
9788 (void) SetImageChannelMask(image,channel_mask);
9789 break;
9790 }
9791 case 70: /* MotionBlur */
9792 {
9793 if (attribute_flag[0] != 0)
9794 {
9795 flags=ParseGeometry(argument_list[0].string_reference,
9796 &geometry_info);
9797 if ((flags & SigmaValue) == 0)
9798 geometry_info.sigma=1.0;
9799 if ((flags & XiValue) == 0)
9800 geometry_info.xi=1.0;
9801 }
9802 if (attribute_flag[1] != 0)
9803 geometry_info.rho=argument_list[1].real_reference;
9804 if (attribute_flag[2] != 0)
9805 geometry_info.sigma=argument_list[2].real_reference;
9806 if (attribute_flag[3] != 0)
9807 geometry_info.xi=argument_list[3].real_reference;
9808 if (attribute_flag[4] != 0)
9809 channel=(ChannelType) argument_list[4].integer_reference;
9810 channel_mask=SetImageChannelMask(image,channel);
9811 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9812 geometry_info.xi,exception);
9813 if (image != (Image *) NULL)
9814 (void) SetImageChannelMask(image,channel_mask);
9815 break;
9816 }
9817 case 71: /* OrderedDither */
9818 {
9819 if (attribute_flag[0] == 0)
9820 argument_list[0].string_reference="o8x8";
9821 if (attribute_flag[1] != 0)
9822 channel=(ChannelType) argument_list[1].integer_reference;
9823 channel_mask=SetImageChannelMask(image,channel);
Cristy6b93c072016-02-04 07:45:48 -05009824 (void) OrderedDitherImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009825 exception);
9826 (void) SetImageChannelMask(image,channel_mask);
9827 break;
9828 }
9829 case 72: /* Shave */
9830 {
9831 if (attribute_flag[0] != 0)
9832 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9833 &geometry,exception);
9834 if (attribute_flag[1] != 0)
9835 geometry.width=argument_list[1].integer_reference;
9836 if (attribute_flag[2] != 0)
9837 geometry.height=argument_list[2].integer_reference;
9838 image=ShaveImage(image,&geometry,exception);
9839 break;
9840 }
9841 case 73: /* Level */
9842 {
9843 double
9844 black_point,
9845 gamma,
9846 white_point;
9847
9848 black_point=0.0;
9849 white_point=(double) image->columns*image->rows;
9850 gamma=1.0;
9851 if (attribute_flag[0] != 0)
9852 {
9853 flags=ParseGeometry(argument_list[0].string_reference,
9854 &geometry_info);
9855 black_point=geometry_info.rho;
9856 if ((flags & SigmaValue) != 0)
9857 white_point=geometry_info.sigma;
9858 if ((flags & XiValue) != 0)
9859 gamma=geometry_info.xi;
9860 if ((flags & PercentValue) != 0)
9861 {
9862 black_point*=(double) (QuantumRange/100.0);
9863 white_point*=(double) (QuantumRange/100.0);
9864 }
9865 if ((flags & SigmaValue) == 0)
9866 white_point=(double) QuantumRange-black_point;
9867 }
9868 if (attribute_flag[1] != 0)
9869 black_point=argument_list[1].real_reference;
9870 if (attribute_flag[2] != 0)
9871 white_point=argument_list[2].real_reference;
9872 if (attribute_flag[3] != 0)
9873 gamma=argument_list[3].real_reference;
9874 if (attribute_flag[4] != 0)
9875 channel=(ChannelType) argument_list[4].integer_reference;
9876 if (attribute_flag[5] != 0)
9877 {
9878 argument_list[0].real_reference=argument_list[5].real_reference;
9879 attribute_flag[0]=attribute_flag[5];
9880 }
9881 channel_mask=SetImageChannelMask(image,channel);
9882 (void) LevelImage(image,black_point,white_point,gamma,exception);
9883 (void) SetImageChannelMask(image,channel_mask);
9884 break;
9885 }
9886 case 74: /* Clip */
9887 {
9888 if (attribute_flag[0] == 0)
9889 argument_list[0].string_reference="#1";
9890 if (attribute_flag[1] == 0)
9891 argument_list[1].integer_reference=MagickTrue;
9892 (void) ClipImagePath(image,argument_list[0].string_reference,
9893 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9894 exception);
9895 break;
9896 }
9897 case 75: /* AffineTransform */
9898 {
9899 DrawInfo
9900 *draw_info;
9901
9902 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9903 (DrawInfo *) NULL);
9904 if (attribute_flag[0] != 0)
9905 {
9906 AV
9907 *av;
9908
9909 av=(AV *) argument_list[0].array_reference;
9910 if ((av_len(av) != 3) && (av_len(av) != 5))
9911 {
9912 ThrowPerlException(exception,OptionError,
9913 "affine matrix must have 4 or 6 elements",PackageName);
9914 goto PerlException;
9915 }
9916 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9917 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9918 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9919 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9920 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9921 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9922 {
9923 ThrowPerlException(exception,OptionError,
9924 "affine matrix is singular",PackageName);
9925 goto PerlException;
9926 }
9927 if (av_len(av) == 5)
9928 {
9929 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9930 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9931 }
9932 }
9933 for (j=1; j < 6; j++)
9934 {
9935 if (attribute_flag[j] == 0)
9936 continue;
9937 value=argument_list[j].string_reference;
9938 angle=argument_list[j].real_reference;
9939 current=draw_info->affine;
9940 GetAffineMatrix(&affine);
9941 switch (j)
9942 {
9943 case 1:
9944 {
9945 /*
9946 Translate.
9947 */
9948 flags=ParseGeometry(value,&geometry_info);
9949 affine.tx=geometry_info.xi;
9950 affine.ty=geometry_info.psi;
9951 if ((flags & PsiValue) == 0)
9952 affine.ty=affine.tx;
9953 break;
9954 }
9955 case 2:
9956 {
9957 /*
9958 Scale.
9959 */
9960 flags=ParseGeometry(value,&geometry_info);
9961 affine.sx=geometry_info.rho;
9962 affine.sy=geometry_info.sigma;
9963 if ((flags & SigmaValue) == 0)
9964 affine.sy=affine.sx;
9965 break;
9966 }
9967 case 3:
9968 {
9969 /*
9970 Rotate.
9971 */
9972 if (angle == 0.0)
9973 break;
9974 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9975 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9976 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9977 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9978 break;
9979 }
9980 case 4:
9981 {
9982 /*
9983 SkewX.
9984 */
9985 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9986 break;
9987 }
9988 case 5:
9989 {
9990 /*
9991 SkewY.
9992 */
9993 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9994 break;
9995 }
9996 }
9997 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9998 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9999 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
10000 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
10001 draw_info->affine.tx=
10002 current.sx*affine.tx+current.ry*affine.ty+current.tx;
10003 draw_info->affine.ty=
10004 current.rx*affine.tx+current.sy*affine.ty+current.ty;
10005 }
10006 if (attribute_flag[6] != 0)
10007 image->interpolate=(PixelInterpolateMethod)
10008 argument_list[6].integer_reference;
10009 if (attribute_flag[7] != 0)
10010 QueryColorCompliance(argument_list[7].string_reference,
10011 AllCompliance,&image->background_color,exception);
10012 image=AffineTransformImage(image,&draw_info->affine,exception);
10013 draw_info=DestroyDrawInfo(draw_info);
10014 break;
10015 }
10016 case 76: /* Difference */
10017 {
10018 if (attribute_flag[0] == 0)
10019 {
10020 ThrowPerlException(exception,OptionError,
10021 "ReferenceImageRequired",PackageName);
10022 goto PerlException;
10023 }
10024 if (attribute_flag[1] != 0)
10025 image->fuzz=StringToDoubleInterval(
10026 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -050010027 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +000010028 exception);
10029 break;
10030 }
10031 case 77: /* AdaptiveThreshold */
10032 {
10033 if (attribute_flag[0] != 0)
10034 {
10035 flags=ParseGeometry(argument_list[0].string_reference,
10036 &geometry_info);
10037 if ((flags & PercentValue) != 0)
10038 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10039 }
10040 if (attribute_flag[1] != 0)
10041 geometry_info.rho=argument_list[1].integer_reference;
10042 if (attribute_flag[2] != 0)
10043 geometry_info.sigma=argument_list[2].integer_reference;
10044 if (attribute_flag[3] != 0)
10045 geometry_info.xi=argument_list[3].integer_reference;;
10046 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
10047 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
10048 break;
10049 }
10050 case 78: /* Resample */
10051 {
10052 size_t
10053 height,
10054 width;
10055
10056 if (attribute_flag[0] != 0)
10057 {
10058 flags=ParseGeometry(argument_list[0].string_reference,
10059 &geometry_info);
10060 if ((flags & SigmaValue) == 0)
10061 geometry_info.sigma=geometry_info.rho;
10062 }
10063 if (attribute_flag[1] != 0)
10064 geometry_info.rho=argument_list[1].real_reference;
10065 if (attribute_flag[2] != 0)
10066 geometry_info.sigma=argument_list[2].real_reference;
10067 if (attribute_flag[3] == 0)
10068 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10069 if (attribute_flag[4] == 0)
10070 SetImageArtifact(image,"filter:support",
10071 argument_list[4].string_reference);
10072 width=(size_t) (geometry_info.rho*image->columns/
10073 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10074 height=(size_t) (geometry_info.sigma*image->rows/
10075 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
Cristy8645e042016-02-03 16:35:29 -050010076 image=ResizeImage(image,width,height,(FilterType)
cristy4a3ce0a2013-08-03 20:06:59 +000010077 argument_list[3].integer_reference,exception);
10078 if (image != (Image *) NULL)
10079 {
10080 image->resolution.x=geometry_info.rho;
10081 image->resolution.y=geometry_info.sigma;
10082 }
10083 break;
10084 }
10085 case 79: /* Describe */
10086 {
10087 if (attribute_flag[0] == 0)
10088 argument_list[0].file_reference=(FILE *) NULL;
10089 if (attribute_flag[1] != 0)
10090 (void) SetImageArtifact(image,"identify:features",
10091 argument_list[1].string_reference);
10092 (void) IdentifyImage(image,argument_list[0].file_reference,
10093 MagickTrue,exception);
10094 break;
10095 }
10096 case 80: /* BlackThreshold */
10097 {
10098 if (attribute_flag[0] == 0)
10099 argument_list[0].string_reference="50%";
10100 if (attribute_flag[2] != 0)
10101 channel=(ChannelType) argument_list[2].integer_reference;
10102 channel_mask=SetImageChannelMask(image,channel);
10103 BlackThresholdImage(image,argument_list[0].string_reference,
10104 exception);
10105 (void) SetImageChannelMask(image,channel_mask);
10106 break;
10107 }
10108 case 81: /* WhiteThreshold */
10109 {
10110 if (attribute_flag[0] == 0)
10111 argument_list[0].string_reference="50%";
10112 if (attribute_flag[2] != 0)
10113 channel=(ChannelType) argument_list[2].integer_reference;
10114 channel_mask=SetImageChannelMask(image,channel);
10115 WhiteThresholdImage(image,argument_list[0].string_reference,
10116 exception);
10117 (void) SetImageChannelMask(image,channel_mask);
10118 break;
10119 }
cristy60c73c02014-03-25 12:09:58 +000010120 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010121 {
10122 if (attribute_flag[0] != 0)
10123 {
10124 flags=ParseGeometry(argument_list[0].string_reference,
10125 &geometry_info);
10126 }
10127 if (attribute_flag[1] != 0)
10128 geometry_info.rho=argument_list[1].real_reference;
10129 if (attribute_flag[2] != 0)
10130 channel=(ChannelType) argument_list[2].integer_reference;
10131 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010132 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010133 if (image != (Image *) NULL)
10134 (void) SetImageChannelMask(image,channel_mask);
10135 break;
10136 }
10137 case 83: /* Thumbnail */
10138 {
10139 if (attribute_flag[0] != 0)
10140 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10141 &geometry,exception);
10142 if (attribute_flag[1] != 0)
10143 geometry.width=argument_list[1].integer_reference;
10144 if (attribute_flag[2] != 0)
10145 geometry.height=argument_list[2].integer_reference;
10146 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10147 break;
10148 }
10149 case 84: /* Strip */
10150 {
10151 (void) StripImage(image,exception);
10152 break;
10153 }
10154 case 85: /* Tint */
10155 {
10156 PixelInfo
10157 tint;
10158
10159 GetPixelInfo(image,&tint);
10160 if (attribute_flag[0] != 0)
10161 (void) QueryColorCompliance(argument_list[0].string_reference,
10162 AllCompliance,&tint,exception);
10163 if (attribute_flag[1] == 0)
10164 argument_list[1].string_reference="100";
10165 image=TintImage(image,argument_list[1].string_reference,&tint,
10166 exception);
10167 break;
10168 }
10169 case 86: /* Channel */
10170 {
10171 if (attribute_flag[0] != 0)
10172 channel=(ChannelType) argument_list[0].integer_reference;
10173 image=SeparateImage(image,channel,exception);
10174 break;
10175 }
10176 case 87: /* Splice */
10177 {
cristy260bd762014-08-15 12:46:34 +000010178 if (attribute_flag[7] != 0)
10179 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010180 if (attribute_flag[0] != 0)
10181 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10182 &geometry,exception);
10183 if (attribute_flag[1] != 0)
10184 geometry.width=argument_list[1].integer_reference;
10185 if (attribute_flag[2] != 0)
10186 geometry.height=argument_list[2].integer_reference;
10187 if (attribute_flag[3] != 0)
10188 geometry.x=argument_list[3].integer_reference;
10189 if (attribute_flag[4] != 0)
10190 geometry.y=argument_list[4].integer_reference;
10191 if (attribute_flag[5] != 0)
10192 image->fuzz=StringToDoubleInterval(
10193 argument_list[5].string_reference,(double) QuantumRange+1.0);
10194 if (attribute_flag[6] != 0)
10195 (void) QueryColorCompliance(argument_list[6].string_reference,
10196 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010197 image=SpliceImage(image,&geometry,exception);
10198 break;
10199 }
10200 case 88: /* Posterize */
10201 {
10202 if (attribute_flag[0] == 0)
10203 argument_list[0].integer_reference=3;
10204 if (attribute_flag[1] == 0)
10205 argument_list[1].integer_reference=0;
10206 (void) PosterizeImage(image,argument_list[0].integer_reference,
10207 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10208 NoDitherMethod,exception);
10209 break;
10210 }
10211 case 89: /* Shadow */
10212 {
10213 if (attribute_flag[0] != 0)
10214 {
10215 flags=ParseGeometry(argument_list[0].string_reference,
10216 &geometry_info);
10217 if ((flags & SigmaValue) == 0)
10218 geometry_info.sigma=1.0;
10219 if ((flags & XiValue) == 0)
10220 geometry_info.xi=4.0;
10221 if ((flags & PsiValue) == 0)
10222 geometry_info.psi=4.0;
10223 }
10224 if (attribute_flag[1] != 0)
10225 geometry_info.rho=argument_list[1].real_reference;
10226 if (attribute_flag[2] != 0)
10227 geometry_info.sigma=argument_list[2].real_reference;
10228 if (attribute_flag[3] != 0)
10229 geometry_info.xi=argument_list[3].integer_reference;
10230 if (attribute_flag[4] != 0)
10231 geometry_info.psi=argument_list[4].integer_reference;
10232 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10233 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10234 ceil(geometry_info.psi-0.5),exception);
10235 break;
10236 }
10237 case 90: /* Identify */
10238 {
10239 if (attribute_flag[0] == 0)
10240 argument_list[0].file_reference=(FILE *) NULL;
10241 if (attribute_flag[1] != 0)
10242 (void) SetImageArtifact(image,"identify:features",
10243 argument_list[1].string_reference);
10244 if ((attribute_flag[2] != 0) &&
10245 (argument_list[2].integer_reference != 0))
10246 (void) SetImageArtifact(image,"identify:unique","true");
10247 (void) IdentifyImage(image,argument_list[0].file_reference,
10248 MagickTrue,exception);
10249 break;
10250 }
10251 case 91: /* SepiaTone */
10252 {
10253 if (attribute_flag[0] == 0)
10254 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10255 image=SepiaToneImage(image,argument_list[0].real_reference,
10256 exception);
10257 break;
10258 }
10259 case 92: /* SigmoidalContrast */
10260 {
10261 MagickBooleanType
10262 sharpen;
10263
10264 if (attribute_flag[0] != 0)
10265 {
10266 flags=ParseGeometry(argument_list[0].string_reference,
10267 &geometry_info);
10268 if ((flags & SigmaValue) == 0)
10269 geometry_info.sigma=QuantumRange/2.0;
10270 if ((flags & PercentValue) != 0)
10271 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10272 }
10273 if (attribute_flag[1] != 0)
10274 geometry_info.rho=argument_list[1].real_reference;
10275 if (attribute_flag[2] != 0)
10276 geometry_info.sigma=argument_list[2].real_reference;
10277 if (attribute_flag[3] != 0)
10278 channel=(ChannelType) argument_list[3].integer_reference;
10279 sharpen=MagickTrue;
10280 if (attribute_flag[4] != 0)
10281 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10282 MagickFalse;
10283 channel_mask=SetImageChannelMask(image,channel);
10284 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10285 geometry_info.sigma,exception);
10286 (void) SetImageChannelMask(image,channel_mask);
10287 break;
10288 }
10289 case 93: /* Extent */
10290 {
10291 if (attribute_flag[7] != 0)
10292 image->gravity=(GravityType) argument_list[7].integer_reference;
10293 if (attribute_flag[0] != 0)
10294 {
10295 int
10296 flags;
10297
10298 flags=ParseGravityGeometry(image,
10299 argument_list[0].string_reference,&geometry,exception);
10300 (void) flags;
10301 if (geometry.width == 0)
10302 geometry.width=image->columns;
10303 if (geometry.height == 0)
10304 geometry.height=image->rows;
10305 }
10306 if (attribute_flag[1] != 0)
10307 geometry.width=argument_list[1].integer_reference;
10308 if (attribute_flag[2] != 0)
10309 geometry.height=argument_list[2].integer_reference;
10310 if (attribute_flag[3] != 0)
10311 geometry.x=argument_list[3].integer_reference;
10312 if (attribute_flag[4] != 0)
10313 geometry.y=argument_list[4].integer_reference;
10314 if (attribute_flag[5] != 0)
10315 image->fuzz=StringToDoubleInterval(
10316 argument_list[5].string_reference,(double) QuantumRange+1.0);
10317 if (attribute_flag[6] != 0)
10318 (void) QueryColorCompliance(argument_list[6].string_reference,
10319 AllCompliance,&image->background_color,exception);
10320 image=ExtentImage(image,&geometry,exception);
10321 break;
10322 }
10323 case 94: /* Vignette */
10324 {
10325 if (attribute_flag[0] != 0)
10326 {
10327 flags=ParseGeometry(argument_list[0].string_reference,
10328 &geometry_info);
10329 if ((flags & SigmaValue) == 0)
10330 geometry_info.sigma=1.0;
10331 if ((flags & XiValue) == 0)
10332 geometry_info.xi=0.1*image->columns;
10333 if ((flags & PsiValue) == 0)
10334 geometry_info.psi=0.1*image->rows;
10335 }
10336 if (attribute_flag[1] != 0)
10337 geometry_info.rho=argument_list[1].real_reference;
10338 if (attribute_flag[2] != 0)
10339 geometry_info.sigma=argument_list[2].real_reference;
10340 if (attribute_flag[3] != 0)
10341 geometry_info.xi=argument_list[3].integer_reference;
10342 if (attribute_flag[4] != 0)
10343 geometry_info.psi=argument_list[4].integer_reference;
10344 if (attribute_flag[5] != 0)
10345 (void) QueryColorCompliance(argument_list[5].string_reference,
10346 AllCompliance,&image->background_color,exception);
10347 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10348 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10349 ceil(geometry_info.psi-0.5),exception);
10350 break;
10351 }
10352 case 95: /* ContrastStretch */
10353 {
10354 double
10355 black_point,
10356 white_point;
10357
10358 black_point=0.0;
10359 white_point=(double) image->columns*image->rows;
10360 if (attribute_flag[0] != 0)
10361 {
10362 flags=ParseGeometry(argument_list[0].string_reference,
10363 &geometry_info);
10364 black_point=geometry_info.rho;
10365 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10366 black_point;
10367 if ((flags & PercentValue) != 0)
10368 {
10369 black_point*=(double) image->columns*image->rows/100.0;
10370 white_point*=(double) image->columns*image->rows/100.0;
10371 }
10372 white_point=(double) image->columns*image->rows-
10373 white_point;
10374 }
10375 if (attribute_flag[1] != 0)
10376 black_point=argument_list[1].real_reference;
10377 if (attribute_flag[2] != 0)
10378 white_point=argument_list[2].real_reference;
10379 if (attribute_flag[4] != 0)
10380 channel=(ChannelType) argument_list[4].integer_reference;
10381 channel_mask=SetImageChannelMask(image,channel);
10382 (void) ContrastStretchImage(image,black_point,white_point,exception);
10383 (void) SetImageChannelMask(image,channel_mask);
10384 break;
10385 }
10386 case 96: /* Sans0 */
10387 {
10388 break;
10389 }
10390 case 97: /* Sans1 */
10391 {
10392 break;
10393 }
10394 case 98: /* AdaptiveSharpen */
10395 {
10396 if (attribute_flag[0] != 0)
10397 {
10398 flags=ParseGeometry(argument_list[0].string_reference,
10399 &geometry_info);
10400 if ((flags & SigmaValue) == 0)
10401 geometry_info.sigma=1.0;
10402 if ((flags & XiValue) == 0)
10403 geometry_info.xi=0.0;
10404 }
10405 if (attribute_flag[1] != 0)
10406 geometry_info.rho=argument_list[1].real_reference;
10407 if (attribute_flag[2] != 0)
10408 geometry_info.sigma=argument_list[2].real_reference;
10409 if (attribute_flag[3] != 0)
10410 geometry_info.xi=argument_list[3].real_reference;
10411 if (attribute_flag[4] != 0)
10412 channel=(ChannelType) argument_list[4].integer_reference;
10413 channel_mask=SetImageChannelMask(image,channel);
10414 image=AdaptiveSharpenImage(image,geometry_info.rho,
10415 geometry_info.sigma,exception);
10416 if (image != (Image *) NULL)
10417 (void) SetImageChannelMask(image,channel_mask);
10418 break;
10419 }
10420 case 99: /* Transpose */
10421 {
10422 image=TransposeImage(image,exception);
10423 break;
10424 }
10425 case 100: /* Tranverse */
10426 {
10427 image=TransverseImage(image,exception);
10428 break;
10429 }
10430 case 101: /* AutoOrient */
10431 {
10432 image=AutoOrientImage(image,image->orientation,exception);
10433 break;
10434 }
10435 case 102: /* AdaptiveBlur */
10436 {
10437 if (attribute_flag[0] != 0)
10438 {
10439 flags=ParseGeometry(argument_list[0].string_reference,
10440 &geometry_info);
10441 if ((flags & SigmaValue) == 0)
10442 geometry_info.sigma=1.0;
10443 if ((flags & XiValue) == 0)
10444 geometry_info.xi=0.0;
10445 }
10446 if (attribute_flag[1] != 0)
10447 geometry_info.rho=argument_list[1].real_reference;
10448 if (attribute_flag[2] != 0)
10449 geometry_info.sigma=argument_list[2].real_reference;
10450 if (attribute_flag[3] != 0)
10451 channel=(ChannelType) argument_list[3].integer_reference;
10452 channel_mask=SetImageChannelMask(image,channel);
10453 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10454 exception);
10455 if (image != (Image *) NULL)
10456 (void) SetImageChannelMask(image,channel_mask);
10457 break;
10458 }
10459 case 103: /* Sketch */
10460 {
10461 if (attribute_flag[0] != 0)
10462 {
10463 flags=ParseGeometry(argument_list[0].string_reference,
10464 &geometry_info);
10465 if ((flags & SigmaValue) == 0)
10466 geometry_info.sigma=1.0;
10467 if ((flags & XiValue) == 0)
10468 geometry_info.xi=1.0;
10469 }
10470 if (attribute_flag[1] != 0)
10471 geometry_info.rho=argument_list[1].real_reference;
10472 if (attribute_flag[2] != 0)
10473 geometry_info.sigma=argument_list[2].real_reference;
10474 if (attribute_flag[3] != 0)
10475 geometry_info.xi=argument_list[3].real_reference;
10476 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10477 geometry_info.xi,exception);
10478 break;
10479 }
10480 case 104: /* UniqueColors */
10481 {
10482 image=UniqueImageColors(image,exception);
10483 break;
10484 }
10485 case 105: /* AdaptiveResize */
10486 {
10487 if (attribute_flag[0] != 0)
10488 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10489 &geometry,exception);
10490 if (attribute_flag[1] != 0)
10491 geometry.width=argument_list[1].integer_reference;
10492 if (attribute_flag[2] != 0)
10493 geometry.height=argument_list[2].integer_reference;
10494 if (attribute_flag[3] != 0)
Cristy8645e042016-02-03 16:35:29 -050010495 image->filter=(FilterType) argument_list[4].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010496 if (attribute_flag[4] != 0)
10497 SetImageArtifact(image,"filter:support",
10498 argument_list[4].string_reference);
10499 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10500 exception);
10501 break;
10502 }
10503 case 106: /* ClipMask */
10504 {
10505 Image
10506 *mask_image;
10507
10508 if (attribute_flag[0] == 0)
10509 {
10510 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10511 PackageName);
10512 goto PerlException;
10513 }
10514 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10515 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010516 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010517 mask_image=DestroyImage(mask_image);
10518 break;
10519 }
10520 case 107: /* LinearStretch */
10521 {
10522 double
10523 black_point,
10524 white_point;
10525
10526 black_point=0.0;
10527 white_point=(double) image->columns*image->rows;
10528 if (attribute_flag[0] != 0)
10529 {
10530 flags=ParseGeometry(argument_list[0].string_reference,
10531 &geometry_info);
10532 if ((flags & SigmaValue) != 0)
10533 white_point=geometry_info.sigma;
10534 if ((flags & PercentValue) != 0)
10535 {
10536 black_point*=(double) image->columns*image->rows/100.0;
10537 white_point*=(double) image->columns*image->rows/100.0;
10538 }
10539 if ((flags & SigmaValue) == 0)
10540 white_point=(double) image->columns*image->rows-black_point;
10541 }
10542 if (attribute_flag[1] != 0)
10543 black_point=argument_list[1].real_reference;
10544 if (attribute_flag[2] != 0)
10545 white_point=argument_list[2].real_reference;
10546 (void) LinearStretchImage(image,black_point,white_point,exception);
10547 break;
10548 }
10549 case 108: /* ColorMatrix */
10550 {
10551 AV
10552 *av;
10553
10554 double
10555 *color_matrix;
10556
10557 KernelInfo
10558 *kernel_info;
10559
10560 size_t
10561 order;
10562
10563 if (attribute_flag[0] == 0)
10564 break;
10565 av=(AV *) argument_list[0].array_reference;
10566 order=(size_t) sqrt(av_len(av)+1);
10567 color_matrix=(double *) AcquireQuantumMemory(order,order*
10568 sizeof(*color_matrix));
10569 if (color_matrix == (double *) NULL)
10570 {
10571 ThrowPerlException(exception,ResourceLimitFatalError,
10572 "MemoryAllocationFailed",PackageName);
10573 goto PerlException;
10574 }
10575 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10576 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10577 for ( ; j < (ssize_t) (order*order); j++)
10578 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010579 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010580 if (kernel_info == (KernelInfo *) NULL)
10581 break;
10582 kernel_info->width=order;
10583 kernel_info->height=order;
10584 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10585 order*sizeof(*kernel_info->values));
10586 if (kernel_info->values != (MagickRealType *) NULL)
10587 {
10588 for (i=0; i < (ssize_t) (order*order); i++)
10589 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10590 image=ColorMatrixImage(image,kernel_info,exception);
10591 }
10592 kernel_info=DestroyKernelInfo(kernel_info);
10593 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10594 break;
10595 }
10596 case 109: /* Mask */
10597 {
10598 Image
10599 *mask_image;
10600
10601 if (attribute_flag[0] == 0)
10602 {
10603 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10604 PackageName);
10605 goto PerlException;
10606 }
10607 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10608 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010609 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010610 mask_image=DestroyImage(mask_image);
10611 break;
10612 }
10613 case 110: /* Polaroid */
10614 {
10615 char
10616 *caption;
10617
10618 DrawInfo
10619 *draw_info;
10620
10621 double
10622 angle;
10623
10624 PixelInterpolateMethod
10625 method;
10626
10627 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10628 (DrawInfo *) NULL);
10629 caption=(char *) NULL;
10630 if (attribute_flag[0] != 0)
10631 caption=InterpretImageProperties(info ? info->image_info :
10632 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10633 exception);
10634 angle=0.0;
10635 if (attribute_flag[1] != 0)
10636 angle=argument_list[1].real_reference;
10637 if (attribute_flag[2] != 0)
10638 (void) CloneString(&draw_info->font,
10639 argument_list[2].string_reference);
10640 if (attribute_flag[3] != 0)
10641 (void) QueryColorCompliance(argument_list[3].string_reference,
10642 AllCompliance,&draw_info->stroke,exception);
10643 if (attribute_flag[4] != 0)
10644 (void) QueryColorCompliance(argument_list[4].string_reference,
10645 AllCompliance,&draw_info->fill,exception);
10646 if (attribute_flag[5] != 0)
10647 draw_info->stroke_width=argument_list[5].real_reference;
10648 if (attribute_flag[6] != 0)
10649 draw_info->pointsize=argument_list[6].real_reference;
10650 if (attribute_flag[7] != 0)
10651 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10652 if (attribute_flag[8] != 0)
10653 (void) QueryColorCompliance(argument_list[8].string_reference,
10654 AllCompliance,&image->background_color,exception);
10655 method=UndefinedInterpolatePixel;
10656 if (attribute_flag[9] != 0)
10657 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10658 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10659 draw_info=DestroyDrawInfo(draw_info);
10660 if (caption != (char *) NULL)
10661 caption=DestroyString(caption);
10662 break;
10663 }
10664 case 111: /* FloodfillPaint */
10665 {
10666 DrawInfo
10667 *draw_info;
10668
10669 MagickBooleanType
10670 invert;
10671
10672 PixelInfo
10673 target;
10674
10675 draw_info=CloneDrawInfo(info ? info->image_info :
10676 (ImageInfo *) NULL,(DrawInfo *) NULL);
10677 if (attribute_flag[0] != 0)
10678 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10679 &geometry,exception);
10680 if (attribute_flag[1] != 0)
10681 geometry.x=argument_list[1].integer_reference;
10682 if (attribute_flag[2] != 0)
10683 geometry.y=argument_list[2].integer_reference;
10684 if (attribute_flag[3] != 0)
10685 (void) QueryColorCompliance(argument_list[3].string_reference,
10686 AllCompliance,&draw_info->fill,exception);
10687 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10688 geometry.x,geometry.y,&target,exception);
10689 if (attribute_flag[4] != 0)
10690 QueryColorCompliance(argument_list[4].string_reference,
10691 AllCompliance,&target,exception);
10692 if (attribute_flag[5] != 0)
10693 image->fuzz=StringToDoubleInterval(
10694 argument_list[5].string_reference,(double) QuantumRange+1.0);
10695 if (attribute_flag[6] != 0)
10696 channel=(ChannelType) argument_list[6].integer_reference;
10697 invert=MagickFalse;
10698 if (attribute_flag[7] != 0)
10699 invert=(MagickBooleanType) argument_list[7].integer_reference;
10700 channel_mask=SetImageChannelMask(image,channel);
10701 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10702 geometry.y,invert,exception);
10703 (void) SetImageChannelMask(image,channel_mask);
10704 draw_info=DestroyDrawInfo(draw_info);
10705 break;
10706 }
10707 case 112: /* Distort */
10708 {
10709 AV
10710 *av;
10711
10712 double
10713 *coordinates;
10714
Cristy8645e042016-02-03 16:35:29 -050010715 DistortMethod
cristy4a3ce0a2013-08-03 20:06:59 +000010716 method;
10717
10718 size_t
10719 number_coordinates;
10720
10721 VirtualPixelMethod
10722 virtual_pixel;
10723
10724 if (attribute_flag[0] == 0)
10725 break;
10726 method=UndefinedDistortion;
10727 if (attribute_flag[1] != 0)
Cristy8645e042016-02-03 16:35:29 -050010728 method=(DistortMethod) argument_list[1].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010729 av=(AV *) argument_list[0].array_reference;
10730 number_coordinates=(size_t) av_len(av)+1;
10731 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10732 sizeof(*coordinates));
10733 if (coordinates == (double *) NULL)
10734 {
10735 ThrowPerlException(exception,ResourceLimitFatalError,
10736 "MemoryAllocationFailed",PackageName);
10737 goto PerlException;
10738 }
10739 for (j=0; j < (ssize_t) number_coordinates; j++)
10740 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10741 virtual_pixel=UndefinedVirtualPixelMethod;
10742 if (attribute_flag[2] != 0)
10743 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10744 argument_list[2].integer_reference,exception);
10745 image=DistortImage(image,method,number_coordinates,coordinates,
10746 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10747 exception);
10748 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10749 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10750 exception);
10751 coordinates=(double *) RelinquishMagickMemory(coordinates);
10752 break;
10753 }
10754 case 113: /* Clut */
10755 {
10756 PixelInterpolateMethod
10757 method;
10758
10759 if (attribute_flag[0] == 0)
10760 {
10761 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10762 PackageName);
10763 goto PerlException;
10764 }
10765 method=UndefinedInterpolatePixel;
10766 if (attribute_flag[1] != 0)
10767 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10768 if (attribute_flag[2] != 0)
10769 channel=(ChannelType) argument_list[2].integer_reference;
10770 channel_mask=SetImageChannelMask(image,channel);
10771 (void) ClutImage(image,argument_list[0].image_reference,method,
10772 exception);
10773 (void) SetImageChannelMask(image,channel_mask);
10774 break;
10775 }
10776 case 114: /* LiquidRescale */
10777 {
10778 if (attribute_flag[0] != 0)
10779 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10780 &geometry,exception);
10781 if (attribute_flag[1] != 0)
10782 geometry.width=argument_list[1].integer_reference;
10783 if (attribute_flag[2] != 0)
10784 geometry.height=argument_list[2].integer_reference;
10785 if (attribute_flag[3] == 0)
10786 argument_list[3].real_reference=1.0;
10787 if (attribute_flag[4] == 0)
10788 argument_list[4].real_reference=0.0;
10789 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10790 argument_list[3].real_reference,argument_list[4].real_reference,
10791 exception);
10792 break;
10793 }
10794 case 115: /* EncipherImage */
10795 {
10796 (void) EncipherImage(image,argument_list[0].string_reference,
10797 exception);
10798 break;
10799 }
10800 case 116: /* DecipherImage */
10801 {
10802 (void) DecipherImage(image,argument_list[0].string_reference,
10803 exception);
10804 break;
10805 }
10806 case 117: /* Deskew */
10807 {
10808 geometry_info.rho=QuantumRange/2.0;
10809 if (attribute_flag[0] != 0)
10810 flags=ParseGeometry(argument_list[0].string_reference,
10811 &geometry_info);
10812 if (attribute_flag[1] != 0)
10813 geometry_info.rho=StringToDoubleInterval(
10814 argument_list[1].string_reference,(double) QuantumRange+1.0);
10815 image=DeskewImage(image,geometry_info.rho,exception);
10816 break;
10817 }
10818 case 118: /* Remap */
10819 {
10820 QuantizeInfo
10821 *quantize_info;
10822
10823 if (attribute_flag[0] == 0)
10824 {
10825 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10826 PackageName);
10827 goto PerlException;
10828 }
10829 quantize_info=AcquireQuantizeInfo(info->image_info);
10830 if (attribute_flag[1] != 0)
10831 quantize_info->dither_method=(DitherMethod)
10832 argument_list[1].integer_reference;
10833 (void) RemapImages(quantize_info,image,
10834 argument_list[0].image_reference,exception);
10835 quantize_info=DestroyQuantizeInfo(quantize_info);
10836 break;
10837 }
10838 case 119: /* SparseColor */
10839 {
10840 AV
10841 *av;
10842
10843 double
10844 *coordinates;
10845
10846 SparseColorMethod
10847 method;
10848
10849 size_t
10850 number_coordinates;
10851
10852 VirtualPixelMethod
10853 virtual_pixel;
10854
10855 if (attribute_flag[0] == 0)
10856 break;
10857 method=UndefinedColorInterpolate;
10858 if (attribute_flag[1] != 0)
10859 method=(SparseColorMethod) argument_list[1].integer_reference;
10860 av=(AV *) argument_list[0].array_reference;
10861 number_coordinates=(size_t) av_len(av)+1;
10862 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10863 sizeof(*coordinates));
10864 if (coordinates == (double *) NULL)
10865 {
10866 ThrowPerlException(exception,ResourceLimitFatalError,
10867 "MemoryAllocationFailed",PackageName);
10868 goto PerlException;
10869 }
10870 for (j=0; j < (ssize_t) number_coordinates; j++)
10871 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10872 virtual_pixel=UndefinedVirtualPixelMethod;
10873 if (attribute_flag[2] != 0)
10874 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10875 argument_list[2].integer_reference,exception);
10876 if (attribute_flag[3] != 0)
10877 channel=(ChannelType) argument_list[3].integer_reference;
10878 channel_mask=SetImageChannelMask(image,channel);
10879 image=SparseColorImage(image,method,number_coordinates,coordinates,
10880 exception);
10881 if (image != (Image *) NULL)
10882 (void) SetImageChannelMask(image,channel_mask);
10883 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10884 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10885 exception);
10886 coordinates=(double *) RelinquishMagickMemory(coordinates);
10887 break;
10888 }
10889 case 120: /* Function */
10890 {
10891 AV
10892 *av;
10893
10894 double
10895 *parameters;
10896
10897 MagickFunction
10898 function;
10899
10900 size_t
10901 number_parameters;
10902
10903 VirtualPixelMethod
10904 virtual_pixel;
10905
10906 if (attribute_flag[0] == 0)
10907 break;
10908 function=UndefinedFunction;
10909 if (attribute_flag[1] != 0)
10910 function=(MagickFunction) argument_list[1].integer_reference;
10911 av=(AV *) argument_list[0].array_reference;
10912 number_parameters=(size_t) av_len(av)+1;
10913 parameters=(double *) AcquireQuantumMemory(number_parameters,
10914 sizeof(*parameters));
10915 if (parameters == (double *) NULL)
10916 {
10917 ThrowPerlException(exception,ResourceLimitFatalError,
10918 "MemoryAllocationFailed",PackageName);
10919 goto PerlException;
10920 }
10921 for (j=0; j < (ssize_t) number_parameters; j++)
10922 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10923 virtual_pixel=UndefinedVirtualPixelMethod;
10924 if (attribute_flag[2] != 0)
10925 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10926 argument_list[2].integer_reference,exception);
10927 (void) FunctionImage(image,function,number_parameters,parameters,
10928 exception);
10929 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10930 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10931 exception);
10932 parameters=(double *) RelinquishMagickMemory(parameters);
10933 break;
10934 }
10935 case 121: /* SelectiveBlur */
10936 {
10937 if (attribute_flag[0] != 0)
10938 {
10939 flags=ParseGeometry(argument_list[0].string_reference,
10940 &geometry_info);
10941 if ((flags & SigmaValue) == 0)
10942 geometry_info.sigma=1.0;
10943 if ((flags & PercentValue) != 0)
10944 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10945 }
10946 if (attribute_flag[1] != 0)
10947 geometry_info.rho=argument_list[1].real_reference;
10948 if (attribute_flag[2] != 0)
10949 geometry_info.sigma=argument_list[2].real_reference;
10950 if (attribute_flag[3] != 0)
10951 geometry_info.xi=argument_list[3].integer_reference;;
10952 if (attribute_flag[5] != 0)
10953 channel=(ChannelType) argument_list[5].integer_reference;
10954 channel_mask=SetImageChannelMask(image,channel);
10955 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10956 geometry_info.xi,exception);
10957 if (image != (Image *) NULL)
10958 (void) SetImageChannelMask(image,channel_mask);
10959 break;
10960 }
10961 case 122: /* HaldClut */
10962 {
10963 if (attribute_flag[0] == 0)
10964 {
10965 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10966 PackageName);
10967 goto PerlException;
10968 }
10969 if (attribute_flag[1] != 0)
10970 channel=(ChannelType) argument_list[1].integer_reference;
10971 channel_mask=SetImageChannelMask(image,channel);
10972 (void) HaldClutImage(image,argument_list[0].image_reference,
10973 exception);
10974 (void) SetImageChannelMask(image,channel_mask);
10975 break;
10976 }
10977 case 123: /* BlueShift */
10978 {
10979 if (attribute_flag[0] != 0)
10980 (void) ParseGeometry(argument_list[0].string_reference,
10981 &geometry_info);
10982 image=BlueShiftImage(image,geometry_info.rho,exception);
10983 break;
10984 }
10985 case 124: /* ForwardFourierTransformImage */
10986 {
10987 image=ForwardFourierTransformImage(image,
10988 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10989 exception);
10990 break;
10991 }
10992 case 125: /* InverseFourierTransformImage */
10993 {
10994 image=InverseFourierTransformImage(image,image->next,
10995 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10996 exception);
10997 break;
10998 }
10999 case 126: /* ColorDecisionList */
11000 {
11001 if (attribute_flag[0] == 0)
11002 argument_list[0].string_reference=(char *) NULL;
11003 (void) ColorDecisionListImage(image,
11004 argument_list[0].string_reference,exception);
11005 break;
11006 }
11007 case 127: /* AutoGamma */
11008 {
11009 if (attribute_flag[0] != 0)
11010 channel=(ChannelType) argument_list[0].integer_reference;
11011 channel_mask=SetImageChannelMask(image,channel);
11012 (void) AutoGammaImage(image,exception);
11013 (void) SetImageChannelMask(image,channel_mask);
11014 break;
11015 }
11016 case 128: /* AutoLevel */
11017 {
11018 if (attribute_flag[0] != 0)
11019 channel=(ChannelType) argument_list[0].integer_reference;
11020 channel_mask=SetImageChannelMask(image,channel);
11021 (void) AutoLevelImage(image,exception);
11022 (void) SetImageChannelMask(image,channel_mask);
11023 break;
11024 }
11025 case 129: /* LevelColors */
11026 {
11027 PixelInfo
11028 black_point,
11029 white_point;
11030
11031 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
11032 exception);
11033 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
11034 exception);
11035 if (attribute_flag[1] != 0)
11036 (void) QueryColorCompliance(
11037 argument_list[1].string_reference,AllCompliance,&black_point,
11038 exception);
11039 if (attribute_flag[2] != 0)
11040 (void) QueryColorCompliance(
11041 argument_list[2].string_reference,AllCompliance,&white_point,
11042 exception);
11043 if (attribute_flag[3] != 0)
11044 channel=(ChannelType) argument_list[3].integer_reference;
11045 channel_mask=SetImageChannelMask(image,channel);
11046 (void) LevelImageColors(image,&black_point,&white_point,
11047 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11048 exception);
11049 (void) SetImageChannelMask(image,channel_mask);
11050 break;
11051 }
11052 case 130: /* Clamp */
11053 {
11054 if (attribute_flag[0] != 0)
11055 channel=(ChannelType) argument_list[0].integer_reference;
11056 channel_mask=SetImageChannelMask(image,channel);
11057 (void) ClampImage(image,exception);
11058 (void) SetImageChannelMask(image,channel_mask);
11059 break;
11060 }
11061 case 131: /* BrightnessContrast */
11062 {
11063 double
11064 brightness,
11065 contrast;
11066
11067 brightness=0.0;
11068 contrast=0.0;
11069 if (attribute_flag[0] != 0)
11070 {
11071 flags=ParseGeometry(argument_list[0].string_reference,
11072 &geometry_info);
11073 brightness=geometry_info.rho;
11074 if ((flags & SigmaValue) == 0)
11075 contrast=geometry_info.sigma;
11076 }
11077 if (attribute_flag[1] != 0)
11078 brightness=argument_list[1].real_reference;
11079 if (attribute_flag[2] != 0)
11080 contrast=argument_list[2].real_reference;
11081 if (attribute_flag[4] != 0)
11082 channel=(ChannelType) argument_list[4].integer_reference;
11083 channel_mask=SetImageChannelMask(image,channel);
11084 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11085 (void) SetImageChannelMask(image,channel_mask);
11086 break;
11087 }
11088 case 132: /* Morphology */
11089 {
11090 KernelInfo
11091 *kernel;
11092
11093 MorphologyMethod
11094 method;
11095
11096 ssize_t
11097 iterations;
11098
11099 if (attribute_flag[0] == 0)
11100 break;
cristy2c57b742014-10-31 00:40:34 +000011101 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011102 if (kernel == (KernelInfo *) NULL)
11103 break;
11104 if (attribute_flag[1] != 0)
11105 channel=(ChannelType) argument_list[1].integer_reference;
11106 method=UndefinedMorphology;
11107 if (attribute_flag[2] != 0)
11108 method=argument_list[2].integer_reference;
11109 iterations=1;
11110 if (attribute_flag[3] != 0)
11111 iterations=argument_list[3].integer_reference;
11112 channel_mask=SetImageChannelMask(image,channel);
11113 image=MorphologyImage(image,method,iterations,kernel,exception);
11114 if (image != (Image *) NULL)
11115 (void) SetImageChannelMask(image,channel_mask);
11116 kernel=DestroyKernelInfo(kernel);
11117 break;
11118 }
11119 case 133: /* Mode */
11120 {
11121 if (attribute_flag[0] != 0)
11122 {
11123 flags=ParseGeometry(argument_list[0].string_reference,
11124 &geometry_info);
11125 if ((flags & SigmaValue) == 0)
11126 geometry_info.sigma=1.0;
11127 }
11128 if (attribute_flag[1] != 0)
11129 geometry_info.rho=argument_list[1].real_reference;
11130 if (attribute_flag[2] != 0)
11131 geometry_info.sigma=argument_list[2].real_reference;
11132 if (attribute_flag[3] != 0)
11133 channel=(ChannelType) argument_list[3].integer_reference;
11134 channel_mask=SetImageChannelMask(image,channel);
11135 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11136 (size_t) geometry_info.sigma,exception);
11137 if (image != (Image *) NULL)
11138 (void) SetImageChannelMask(image,channel_mask);
11139 break;
11140 }
11141 case 134: /* Statistic */
11142 {
11143 StatisticType
11144 statistic;
11145
11146 statistic=UndefinedStatistic;
11147 if (attribute_flag[0] != 0)
11148 {
11149 flags=ParseGeometry(argument_list[0].string_reference,
11150 &geometry_info);
11151 if ((flags & SigmaValue) == 0)
11152 geometry_info.sigma=1.0;
11153 }
11154 if (attribute_flag[1] != 0)
11155 geometry_info.rho=argument_list[1].real_reference;
11156 if (attribute_flag[2] != 0)
11157 geometry_info.sigma=argument_list[2].real_reference;
11158 if (attribute_flag[3] != 0)
11159 channel=(ChannelType) argument_list[3].integer_reference;
11160 if (attribute_flag[4] != 0)
11161 statistic=(StatisticType) argument_list[4].integer_reference;
11162 channel_mask=SetImageChannelMask(image,channel);
11163 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11164 (size_t) geometry_info.sigma,exception);
11165 if (image != (Image *) NULL)
11166 (void) SetImageChannelMask(image,channel_mask);
11167 break;
11168 }
11169 case 135: /* Perceptible */
11170 {
11171 double
11172 epsilon;
11173
11174 epsilon=MagickEpsilon;
11175 if (attribute_flag[0] != 0)
11176 epsilon=argument_list[0].real_reference;
11177 if (attribute_flag[1] != 0)
11178 channel=(ChannelType) argument_list[1].integer_reference;
11179 channel_mask=SetImageChannelMask(image,channel);
11180 (void) PerceptibleImage(image,epsilon,exception);
11181 (void) SetImageChannelMask(image,channel_mask);
11182 break;
11183 }
11184 case 136: /* Poly */
11185 {
11186 AV
11187 *av;
11188
11189 double
11190 *terms;
11191
11192 size_t
11193 number_terms;
11194
11195 if (attribute_flag[0] == 0)
11196 break;
11197 if (attribute_flag[1] != 0)
11198 channel=(ChannelType) argument_list[1].integer_reference;
11199 av=(AV *) argument_list[0].array_reference;
11200 number_terms=(size_t) av_len(av);
11201 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11202 if (terms == (double *) NULL)
11203 {
11204 ThrowPerlException(exception,ResourceLimitFatalError,
11205 "MemoryAllocationFailed",PackageName);
11206 goto PerlException;
11207 }
11208 for (j=0; j < av_len(av); j++)
11209 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11210 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11211 terms=(double *) RelinquishMagickMemory(terms);
11212 break;
11213 }
11214 case 137: /* Grayscale */
11215 {
11216 PixelIntensityMethod
11217 method;
11218
11219 method=UndefinedPixelIntensityMethod;
11220 if (attribute_flag[0] != 0)
11221 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11222 (void) GrayscaleImage(image,method,exception);
11223 break;
11224 }
cristy4ceadb82014-03-29 15:30:43 +000011225 case 138: /* Canny */
11226 {
11227 if (attribute_flag[0] != 0)
11228 {
11229 flags=ParseGeometry(argument_list[0].string_reference,
11230 &geometry_info);
11231 if ((flags & SigmaValue) == 0)
11232 geometry_info.sigma=1.0;
11233 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011234 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011235 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011236 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011237 if ((flags & PercentValue) != 0)
11238 {
11239 geometry_info.xi/=100.0;
11240 geometry_info.psi/=100.0;
11241 }
cristy4ceadb82014-03-29 15:30:43 +000011242 }
11243 if (attribute_flag[1] != 0)
11244 geometry_info.rho=argument_list[1].real_reference;
11245 if (attribute_flag[2] != 0)
11246 geometry_info.sigma=argument_list[2].real_reference;
11247 if (attribute_flag[3] != 0)
11248 geometry_info.xi=argument_list[3].real_reference;
11249 if (attribute_flag[4] != 0)
11250 geometry_info.psi=argument_list[4].real_reference;
11251 if (attribute_flag[5] != 0)
11252 channel=(ChannelType) argument_list[5].integer_reference;
11253 channel_mask=SetImageChannelMask(image,channel);
11254 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11255 geometry_info.xi,geometry_info.psi,exception);
11256 if (image != (Image *) NULL)
11257 (void) SetImageChannelMask(image,channel_mask);
11258 break;
11259 }
cristy2fc10e52014-04-26 14:13:53 +000011260 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011261 {
11262 if (attribute_flag[0] != 0)
11263 {
11264 flags=ParseGeometry(argument_list[0].string_reference,
11265 &geometry_info);
11266 if ((flags & SigmaValue) == 0)
11267 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011268 if ((flags & XiValue) == 0)
11269 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011270 }
11271 if (attribute_flag[1] != 0)
11272 geometry_info.rho=(double) argument_list[1].integer_reference;
11273 if (attribute_flag[2] != 0)
11274 geometry_info.sigma=(double) argument_list[2].integer_reference;
11275 if (attribute_flag[3] != 0)
11276 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011277 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11278 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11279 break;
11280 }
11281 case 140: /* MeanShift */
11282 {
11283 if (attribute_flag[0] != 0)
11284 {
11285 flags=ParseGeometry(argument_list[0].string_reference,
11286 &geometry_info);
11287 if ((flags & SigmaValue) == 0)
11288 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011289 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011290 geometry_info.xi=0.10*QuantumRange;
11291 if ((flags & PercentValue) != 0)
11292 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011293 }
11294 if (attribute_flag[1] != 0)
11295 geometry_info.rho=(double) argument_list[1].integer_reference;
11296 if (attribute_flag[2] != 0)
11297 geometry_info.sigma=(double) argument_list[2].integer_reference;
11298 if (attribute_flag[3] != 0)
11299 geometry_info.xi=(double) argument_list[3].integer_reference;
11300 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011301 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011302 break;
11303 }
cristy3b207f82014-09-27 14:21:20 +000011304 case 141: /* Kuwahara */
11305 {
11306 if (attribute_flag[0] != 0)
11307 {
11308 flags=ParseGeometry(argument_list[0].string_reference,
11309 &geometry_info);
11310 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011311 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011312 }
11313 if (attribute_flag[1] != 0)
11314 geometry_info.rho=argument_list[1].real_reference;
11315 if (attribute_flag[2] != 0)
11316 geometry_info.sigma=argument_list[2].real_reference;
11317 if (attribute_flag[3] != 0)
11318 channel=(ChannelType) argument_list[3].integer_reference;
11319 channel_mask=SetImageChannelMask(image,channel);
11320 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11321 exception);
11322 if (image != (Image *) NULL)
11323 (void) SetImageChannelMask(image,channel_mask);
11324 break;
11325 }
Cristy0f5df812017-07-04 18:30:05 -040011326 case 142: /* ConnectedComponents */
cristy6e0b3bc2014-10-19 17:51:42 +000011327 {
11328 size_t
11329 connectivity;
11330
11331 connectivity=4;
11332 if (attribute_flag[0] != 0)
11333 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011334 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011335 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011336 break;
11337 }
cristy0b94b392015-06-22 18:56:37 +000011338 case 143: /* Copy */
11339 {
11340 Image
11341 *source_image;
11342
11343 OffsetInfo
11344 offset;
11345
cristy2ffdb092015-06-25 14:31:20 +000011346 RectangleInfo
11347 offset_geometry;
11348
cristyf3a724a2015-06-25 13:02:53 +000011349 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011350 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011351 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011352 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011353 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011354 flags=ParseGravityGeometry(source_image,
11355 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011356 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011357 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011358 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011359 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011360 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011361 geometry.x=argument_list[4].integer_reference;
11362 if (attribute_flag[5] != 0)
11363 geometry.y=argument_list[5].integer_reference;
11364 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011365 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011366 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011367 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011368 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11369 &offset_geometry,exception);
11370 offset.x=offset_geometry.x;
11371 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011372 if (attribute_flag[8] != 0)
11373 offset.x=argument_list[8].integer_reference;
11374 if (attribute_flag[9] != 0)
11375 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011376 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11377 exception);
cristy0b94b392015-06-22 18:56:37 +000011378 break;
11379 }
Cristy5488c982016-02-13 14:07:50 -050011380 case 144: /* Color */
11381 {
11382 PixelInfo
11383 color;
11384
Cristyf20e3562016-02-14 09:08:15 -050011385 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011386 if (attribute_flag[0] != 0)
Cristyf20e3562016-02-14 09:08:15 -050011387 (void) QueryColorCompliance(argument_list[0].string_reference,
11388 AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011389 (void) SetImageColor(image,&color,exception);
11390 break;
11391 }
Cristy2d830ed2016-02-21 10:54:16 -050011392 case 145: /* WaveletDenoise */
11393 {
Cristyc1759412016-02-27 12:17:58 -050011394 if (attribute_flag[0] != 0)
Cristyee21f7f2016-02-27 15:56:49 -050011395 {
11396 flags=ParseGeometry(argument_list[0].string_reference,
11397 &geometry_info);
11398 if ((flags & PercentValue) != 0)
Cristy23446632016-02-29 09:36:34 -050011399 {
11400 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11401 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
11402 }
Cristyee21f7f2016-02-27 15:56:49 -050011403 if ((flags & SigmaValue) == 0)
11404 geometry_info.sigma=0.0;
11405 }
Cristyc1759412016-02-27 12:17:58 -050011406 if (attribute_flag[1] != 0)
11407 geometry_info.rho=argument_list[1].real_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011408 if (attribute_flag[2] != 0)
Cristyc1759412016-02-27 12:17:58 -050011409 geometry_info.sigma=argument_list[2].real_reference;
11410 if (attribute_flag[3] != 0)
11411 channel=(ChannelType) argument_list[3].integer_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011412 channel_mask=SetImageChannelMask(image,channel);
Cristyc1759412016-02-27 12:17:58 -050011413 image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11414 exception);
Cristy2d830ed2016-02-21 10:54:16 -050011415 if (image != (Image *) NULL)
11416 (void) SetImageChannelMask(image,channel_mask);
11417 break;
11418 }
Cristy99a57162016-12-05 11:47:57 -050011419 case 146: /* Colorspace */
11420 {
11421 ColorspaceType
11422 colorspace;
11423
11424 colorspace=sRGBColorspace;
11425 if (attribute_flag[0] != 0)
11426 colorspace=(ColorspaceType) argument_list[0].integer_reference;
11427 (void) TransformImageColorspace(image,colorspace,exception);
11428 break;
11429 }
Cristy53353872017-07-02 12:24:24 -040011430 case 147: /* AutoThreshold */
11431 {
11432 AutoThresholdMethod
11433 method;
11434
11435 method=UndefinedThresholdMethod;
11436 if (attribute_flag[0] != 0)
Cristyb63e7752017-07-02 13:22:01 -040011437 method=(AutoThresholdMethod) argument_list[0].integer_reference;
Cristy53353872017-07-02 12:24:24 -040011438 (void) AutoThresholdImage(image,method,exception);
11439 break;
11440 }
cristy4a3ce0a2013-08-03 20:06:59 +000011441 }
11442 if (next != (Image *) NULL)
11443 (void) CatchImageException(next);
Cristy7e567962018-02-03 12:42:20 -050011444 if ((region_info.width*region_info.height) != 0)
11445 (void) SetImageRegionMask(image,WritePixelMask,
11446 (const RectangleInfo *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011447 if (image != (Image *) NULL)
11448 {
11449 number_images++;
11450 if (next && (next != image))
11451 {
11452 image->next=next->next;
11453 if (image->next != (Image *) NULL)
11454 image->next->previous=image;
11455 DeleteImageFromRegistry(*pv,next);
11456 }
11457 sv_setiv(*pv,PTR2IV(image));
11458 next=image;
11459 }
11460 if (*pv)
11461 pv++;
11462 }
11463
11464 PerlException:
11465 if (reference_vector)
11466 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11467 InheritPerlException(exception,perl_exception);
11468 exception=DestroyExceptionInfo(exception);
11469 sv_setiv(perl_exception,(IV) number_images);
11470 SvPOK_on(perl_exception);
11471 ST(0)=sv_2mortal(perl_exception);
11472 XSRETURN(1);
11473 }
11474
11475#
11476###############################################################################
11477# #
11478# #
11479# #
11480# M o n t a g e #
11481# #
11482# #
11483# #
11484###############################################################################
11485#
11486#
11487void
11488Montage(ref,...)
11489 Image::Magick ref=NO_INIT
11490 ALIAS:
11491 MontageImage = 1
11492 montage = 2
11493 montageimage = 3
11494 PPCODE:
11495 {
11496 AV
11497 *av;
11498
11499 char
11500 *attribute;
11501
11502 ExceptionInfo
11503 *exception;
11504
11505 HV
11506 *hv;
11507
11508 Image
11509 *image,
11510 *next;
11511
11512 PixelInfo
11513 transparent_color;
11514
11515 MontageInfo
11516 *montage_info;
11517
11518 register ssize_t
11519 i;
11520
11521 ssize_t
11522 sp;
11523
11524 struct PackageInfo
11525 *info;
11526
11527 SV
11528 *av_reference,
11529 *perl_exception,
11530 *reference,
11531 *rv,
11532 *sv;
11533
11534 PERL_UNUSED_VAR(ref);
11535 PERL_UNUSED_VAR(ix);
11536 exception=AcquireExceptionInfo();
11537 perl_exception=newSVpv("",0);
11538 sv=NULL;
11539 attribute=NULL;
11540 if (sv_isobject(ST(0)) == 0)
11541 {
11542 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11543 PackageName);
11544 goto PerlException;
11545 }
11546 reference=SvRV(ST(0));
11547 hv=SvSTASH(reference);
11548 av=newAV();
11549 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11550 SvREFCNT_dec(av);
11551 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11552 if (image == (Image *) NULL)
11553 {
11554 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11555 PackageName);
11556 goto PerlException;
11557 }
11558 /*
11559 Get options.
11560 */
11561 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11562 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11563 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11564 exception);
11565 for (i=2; i < items; i+=2)
11566 {
11567 attribute=(char *) SvPV(ST(i-1),na);
11568 switch (*attribute)
11569 {
11570 case 'B':
11571 case 'b':
11572 {
11573 if (LocaleCompare(attribute,"background") == 0)
11574 {
11575 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11576 &montage_info->background_color,exception);
11577 for (next=image; next; next=next->next)
11578 next->background_color=montage_info->background_color;
11579 break;
11580 }
11581 if (LocaleCompare(attribute,"border") == 0)
11582 {
11583 montage_info->border_width=SvIV(ST(i));
11584 break;
11585 }
11586 if (LocaleCompare(attribute,"bordercolor") == 0)
11587 {
11588 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11589 &montage_info->border_color,exception);
11590 for (next=image; next; next=next->next)
11591 next->border_color=montage_info->border_color;
11592 break;
11593 }
11594 if (LocaleCompare(attribute,"borderwidth") == 0)
11595 {
11596 montage_info->border_width=SvIV(ST(i));
11597 break;
11598 }
11599 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11600 attribute);
11601 break;
11602 }
11603 case 'C':
11604 case 'c':
11605 {
11606 if (LocaleCompare(attribute,"compose") == 0)
11607 {
11608 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11609 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11610 if (sp < 0)
11611 {
11612 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11613 SvPV(ST(i),na));
11614 break;
11615 }
11616 for (next=image; next; next=next->next)
11617 next->compose=(CompositeOperator) sp;
11618 break;
11619 }
11620 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11621 attribute);
11622 break;
11623 }
11624 case 'F':
11625 case 'f':
11626 {
11627 if (LocaleCompare(attribute,"fill") == 0)
11628 {
11629 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11630 &montage_info->fill,exception);
11631 break;
11632 }
11633 if (LocaleCompare(attribute,"font") == 0)
11634 {
11635 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11636 break;
11637 }
11638 if (LocaleCompare(attribute,"frame") == 0)
11639 {
11640 char
11641 *p;
11642
11643 p=SvPV(ST(i),na);
11644 if (IsGeometry(p) == MagickFalse)
11645 {
11646 ThrowPerlException(exception,OptionError,"MissingGeometry",
11647 p);
11648 break;
11649 }
11650 (void) CloneString(&montage_info->frame,p);
11651 if (*p == '\0')
11652 montage_info->frame=(char *) NULL;
11653 break;
11654 }
11655 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11656 attribute);
11657 break;
11658 }
11659 case 'G':
11660 case 'g':
11661 {
11662 if (LocaleCompare(attribute,"geometry") == 0)
11663 {
11664 char
11665 *p;
11666
11667 p=SvPV(ST(i),na);
11668 if (IsGeometry(p) == MagickFalse)
11669 {
11670 ThrowPerlException(exception,OptionError,"MissingGeometry",
11671 p);
11672 break;
11673 }
11674 (void) CloneString(&montage_info->geometry,p);
11675 if (*p == '\0')
11676 montage_info->geometry=(char *) NULL;
11677 break;
11678 }
11679 if (LocaleCompare(attribute,"gravity") == 0)
11680 {
11681 ssize_t
11682 in;
11683
11684 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11685 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11686 if (in < 0)
11687 {
11688 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11689 SvPV(ST(i),na));
11690 return;
11691 }
11692 montage_info->gravity=(GravityType) in;
11693 for (next=image; next; next=next->next)
11694 next->gravity=(GravityType) in;
11695 break;
11696 }
11697 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11698 attribute);
11699 break;
11700 }
11701 case 'L':
11702 case 'l':
11703 {
11704 if (LocaleCompare(attribute,"label") == 0)
11705 {
11706 for (next=image; next; next=next->next)
Cristy935a4052017-03-31 17:45:37 -040011707 (void) SetImageProperty(next,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +000011708 info ? info->image_info : (ImageInfo *) NULL,next,
Cristy935a4052017-03-31 17:45:37 -040011709 SvPV(ST(i),na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011710 break;
11711 }
11712 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11713 attribute);
11714 break;
11715 }
11716 case 'M':
11717 case 'm':
11718 {
11719 if (LocaleCompare(attribute,"mattecolor") == 0)
11720 {
11721 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
Cristy8645e042016-02-03 16:35:29 -050011722 &montage_info->alpha_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011723 for (next=image; next; next=next->next)
Cristy8645e042016-02-03 16:35:29 -050011724 next->alpha_color=montage_info->alpha_color;
cristy4a3ce0a2013-08-03 20:06:59 +000011725 break;
11726 }
11727 if (LocaleCompare(attribute,"mode") == 0)
11728 {
11729 ssize_t
11730 in;
11731
11732 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11733 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11734 switch (in)
11735 {
11736 default:
11737 {
11738 ThrowPerlException(exception,OptionError,
11739 "UnrecognizedModeType",SvPV(ST(i),na));
11740 break;
11741 }
11742 case FrameMode:
11743 {
11744 (void) CloneString(&montage_info->frame,"15x15+3+3");
11745 montage_info->shadow=MagickTrue;
11746 break;
11747 }
11748 case UnframeMode:
11749 {
11750 montage_info->frame=(char *) NULL;
11751 montage_info->shadow=MagickFalse;
11752 montage_info->border_width=0;
11753 break;
11754 }
11755 case ConcatenateMode:
11756 {
11757 montage_info->frame=(char *) NULL;
11758 montage_info->shadow=MagickFalse;
11759 (void) CloneString(&montage_info->geometry,"+0+0");
11760 montage_info->border_width=0;
11761 }
11762 }
11763 break;
11764 }
11765 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11766 attribute);
11767 break;
11768 }
11769 case 'P':
11770 case 'p':
11771 {
11772 if (LocaleCompare(attribute,"pointsize") == 0)
11773 {
11774 montage_info->pointsize=SvIV(ST(i));
11775 break;
11776 }
11777 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11778 attribute);
11779 break;
11780 }
11781 case 'S':
11782 case 's':
11783 {
11784 if (LocaleCompare(attribute,"shadow") == 0)
11785 {
11786 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11787 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11788 if (sp < 0)
11789 {
11790 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11791 SvPV(ST(i),na));
11792 break;
11793 }
11794 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11795 break;
11796 }
11797 if (LocaleCompare(attribute,"stroke") == 0)
11798 {
11799 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11800 &montage_info->stroke,exception);
11801 break;
11802 }
11803 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11804 attribute);
11805 break;
11806 }
11807 case 'T':
11808 case 't':
11809 {
11810 if (LocaleCompare(attribute,"texture") == 0)
11811 {
11812 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11813 break;
11814 }
11815 if (LocaleCompare(attribute,"tile") == 0)
11816 {
11817 char *p=SvPV(ST(i),na);
11818 if (IsGeometry(p) == MagickFalse)
11819 {
11820 ThrowPerlException(exception,OptionError,"MissingGeometry",
11821 p);
11822 break;
11823 }
11824 (void) CloneString(&montage_info->tile,p);
11825 if (*p == '\0')
11826 montage_info->tile=(char *) NULL;
11827 break;
11828 }
11829 if (LocaleCompare(attribute,"title") == 0)
11830 {
11831 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11832 break;
11833 }
11834 if (LocaleCompare(attribute,"transparent") == 0)
11835 {
11836 PixelInfo
11837 transparent_color;
11838
11839 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11840 &transparent_color,exception);
11841 for (next=image; next; next=next->next)
11842 (void) TransparentPaintImage(next,&transparent_color,
11843 TransparentAlpha,MagickFalse,exception);
11844 break;
11845 }
11846 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11847 attribute);
11848 break;
11849 }
11850 default:
11851 {
11852 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11853 attribute);
11854 break;
11855 }
11856 }
11857 }
11858 image=MontageImageList(info->image_info,montage_info,image,exception);
11859 montage_info=DestroyMontageInfo(montage_info);
11860 if (image == (Image *) NULL)
11861 goto PerlException;
11862 if (transparent_color.alpha != TransparentAlpha)
11863 for (next=image; next; next=next->next)
11864 (void) TransparentPaintImage(next,&transparent_color,
11865 TransparentAlpha,MagickFalse,exception);
11866 for ( ; image; image=image->next)
11867 {
11868 AddImageToRegistry(sv,image);
11869 rv=newRV(sv);
11870 av_push(av,sv_bless(rv,hv));
11871 SvREFCNT_dec(sv);
11872 }
11873 exception=DestroyExceptionInfo(exception);
11874 ST(0)=av_reference;
11875 SvREFCNT_dec(perl_exception);
11876 XSRETURN(1);
11877
11878 PerlException:
11879 InheritPerlException(exception,perl_exception);
11880 exception=DestroyExceptionInfo(exception);
11881 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11882 SvPOK_on(perl_exception);
11883 ST(0)=sv_2mortal(perl_exception);
11884 XSRETURN(1);
11885 }
11886
11887#
11888###############################################################################
11889# #
11890# #
11891# #
11892# M o r p h #
11893# #
11894# #
11895# #
11896###############################################################################
11897#
11898#
11899void
11900Morph(ref,...)
11901 Image::Magick ref=NO_INIT
11902 ALIAS:
11903 MorphImage = 1
11904 morph = 2
11905 morphimage = 3
11906 PPCODE:
11907 {
11908 AV
11909 *av;
11910
11911 char
11912 *attribute;
11913
11914 ExceptionInfo
11915 *exception;
11916
11917 HV
11918 *hv;
11919
11920 Image
11921 *image;
11922
11923 register ssize_t
11924 i;
11925
11926 ssize_t
11927 number_frames;
11928
11929 struct PackageInfo
11930 *info;
11931
11932 SV
11933 *av_reference,
11934 *perl_exception,
11935 *reference,
11936 *rv,
11937 *sv;
11938
11939 PERL_UNUSED_VAR(ref);
11940 PERL_UNUSED_VAR(ix);
11941 exception=AcquireExceptionInfo();
11942 perl_exception=newSVpv("",0);
11943 sv=NULL;
11944 av=NULL;
11945 attribute=NULL;
11946 if (sv_isobject(ST(0)) == 0)
11947 {
11948 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11949 PackageName);
11950 goto PerlException;
11951 }
11952 reference=SvRV(ST(0));
11953 hv=SvSTASH(reference);
11954 av=newAV();
11955 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11956 SvREFCNT_dec(av);
11957 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11958 if (image == (Image *) NULL)
11959 {
11960 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11961 PackageName);
11962 goto PerlException;
11963 }
11964 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11965 /*
11966 Get attribute.
11967 */
11968 number_frames=30;
11969 for (i=2; i < items; i+=2)
11970 {
11971 attribute=(char *) SvPV(ST(i-1),na);
11972 switch (*attribute)
11973 {
11974 case 'F':
11975 case 'f':
11976 {
11977 if (LocaleCompare(attribute,"frames") == 0)
11978 {
11979 number_frames=SvIV(ST(i));
11980 break;
11981 }
11982 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11983 attribute);
11984 break;
11985 }
11986 default:
11987 {
11988 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11989 attribute);
11990 break;
11991 }
11992 }
11993 }
11994 image=MorphImages(image,number_frames,exception);
11995 if (image == (Image *) NULL)
11996 goto PerlException;
11997 for ( ; image; image=image->next)
11998 {
11999 AddImageToRegistry(sv,image);
12000 rv=newRV(sv);
12001 av_push(av,sv_bless(rv,hv));
12002 SvREFCNT_dec(sv);
12003 }
12004 exception=DestroyExceptionInfo(exception);
12005 ST(0)=av_reference;
12006 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12007 XSRETURN(1);
12008
12009 PerlException:
12010 InheritPerlException(exception,perl_exception);
12011 exception=DestroyExceptionInfo(exception);
12012 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12013 SvPOK_on(perl_exception);
12014 ST(0)=sv_2mortal(perl_exception);
12015 XSRETURN(1);
12016 }
12017
12018#
12019###############################################################################
12020# #
12021# #
12022# #
12023# M o s a i c #
12024# #
12025# #
12026# #
12027###############################################################################
12028#
12029#
12030void
12031Mosaic(ref)
12032 Image::Magick ref=NO_INIT
12033 ALIAS:
12034 MosaicImage = 1
12035 mosaic = 2
12036 mosaicimage = 3
12037 PPCODE:
12038 {
12039 AV
12040 *av;
12041
12042 ExceptionInfo
12043 *exception;
12044
12045 HV
12046 *hv;
12047
12048 Image
12049 *image;
12050
12051 struct PackageInfo
12052 *info;
12053
12054 SV
12055 *perl_exception,
12056 *reference,
12057 *rv,
12058 *sv;
12059
12060 PERL_UNUSED_VAR(ref);
12061 PERL_UNUSED_VAR(ix);
12062 exception=AcquireExceptionInfo();
12063 perl_exception=newSVpv("",0);
12064 sv=NULL;
12065 if (sv_isobject(ST(0)) == 0)
12066 {
12067 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12068 PackageName);
12069 goto PerlException;
12070 }
12071 reference=SvRV(ST(0));
12072 hv=SvSTASH(reference);
12073 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12074 if (image == (Image *) NULL)
12075 {
12076 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12077 PackageName);
12078 goto PerlException;
12079 }
12080 image=MergeImageLayers(image,MosaicLayer,exception);
12081 /*
12082 Create blessed Perl array for the returned image.
12083 */
12084 av=newAV();
12085 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12086 SvREFCNT_dec(av);
12087 AddImageToRegistry(sv,image);
12088 rv=newRV(sv);
12089 av_push(av,sv_bless(rv,hv));
12090 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000012091 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000012092 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012093 SetImageInfo(info->image_info,0,exception);
12094 exception=DestroyExceptionInfo(exception);
12095 SvREFCNT_dec(perl_exception);
12096 XSRETURN(1);
12097
12098 PerlException:
12099 InheritPerlException(exception,perl_exception);
12100 exception=DestroyExceptionInfo(exception);
12101 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12102 SvPOK_on(perl_exception); /* return messages in string context */
12103 ST(0)=sv_2mortal(perl_exception);
12104 XSRETURN(1);
12105 }
12106
12107#
12108###############################################################################
12109# #
12110# #
12111# #
12112# P i n g #
12113# #
12114# #
12115# #
12116###############################################################################
12117#
12118#
12119void
12120Ping(ref,...)
12121 Image::Magick ref=NO_INIT
12122 ALIAS:
12123 PingImage = 1
12124 ping = 2
12125 pingimage = 3
12126 PPCODE:
12127 {
12128 AV
12129 *av;
12130
12131 char
12132 **keep,
12133 **list;
12134
12135 ExceptionInfo
12136 *exception;
12137
12138 Image
12139 *image,
12140 *next;
12141
12142 int
12143 n;
12144
12145 MagickBooleanType
12146 status;
12147
12148 register char
12149 **p;
12150
12151 register ssize_t
12152 i;
12153
12154 ssize_t
12155 ac;
12156
12157 STRLEN
12158 *length;
12159
12160 struct PackageInfo
12161 *info,
12162 *package_info;
12163
12164 SV
12165 *perl_exception,
12166 *reference;
12167
12168 size_t
12169 count;
12170
12171 PERL_UNUSED_VAR(ref);
12172 PERL_UNUSED_VAR(ix);
12173 exception=AcquireExceptionInfo();
12174 perl_exception=newSVpv("",0);
12175 package_info=(struct PackageInfo *) NULL;
12176 ac=(items < 2) ? 1 : items-1;
12177 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12178 keep=list;
12179 length=(STRLEN *) NULL;
12180 if (list == (char **) NULL)
12181 {
12182 ThrowPerlException(exception,ResourceLimitError,
12183 "MemoryAllocationFailed",PackageName);
12184 goto PerlException;
12185 }
12186 keep=list;
12187 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12188 if (length == (STRLEN *) NULL)
12189 {
12190 ThrowPerlException(exception,ResourceLimitError,
12191 "MemoryAllocationFailed",PackageName);
12192 goto PerlException;
12193 }
12194 if (sv_isobject(ST(0)) == 0)
12195 {
12196 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12197 PackageName);
12198 goto PerlException;
12199 }
12200 reference=SvRV(ST(0));
12201 if (SvTYPE(reference) != SVt_PVAV)
12202 {
12203 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12204 PackageName);
12205 goto PerlException;
12206 }
12207 av=(AV *) reference;
12208 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12209 exception);
12210 package_info=ClonePackageInfo(info,exception);
12211 n=1;
12212 if (items <= 1)
12213 *list=(char *) (*package_info->image_info->filename ?
12214 package_info->image_info->filename : "XC:black");
12215 else
12216 for (n=0, i=0; i < ac; i++)
12217 {
12218 list[n]=(char *) SvPV(ST(i+1),length[n]);
12219 if ((items >= 3) && strEQcase(list[n],"blob"))
12220 {
12221 void
12222 *blob;
12223
12224 i++;
12225 blob=(void *) (SvPV(ST(i+1),length[n]));
12226 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12227 }
12228 if ((items >= 3) && strEQcase(list[n],"filename"))
12229 continue;
12230 if ((items >= 3) && strEQcase(list[n],"file"))
12231 {
12232 FILE
12233 *file;
12234
12235 PerlIO
12236 *io_info;
12237
12238 i++;
12239 io_info=IoIFP(sv_2io(ST(i+1)));
12240 if (io_info == (PerlIO *) NULL)
12241 {
12242 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12243 PackageName);
12244 continue;
12245 }
12246 file=PerlIO_findFILE(io_info);
12247 if (file == (FILE *) NULL)
12248 {
12249 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12250 PackageName);
12251 continue;
12252 }
12253 SetImageInfoFile(package_info->image_info,file);
12254 }
12255 if ((items >= 3) && strEQcase(list[n],"magick"))
12256 continue;
12257 n++;
12258 }
12259 list[n]=(char *) NULL;
12260 keep=list;
12261 status=ExpandFilenames(&n,&list);
12262 if (status == MagickFalse)
12263 {
12264 ThrowPerlException(exception,ResourceLimitError,
12265 "MemoryAllocationFailed",PackageName);
12266 goto PerlException;
12267 }
12268 count=0;
12269 for (i=0; i < n; i++)
12270 {
12271 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012272 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012273 image=PingImage(package_info->image_info,exception);
12274 if (image == (Image *) NULL)
12275 break;
12276 if ((package_info->image_info->file != (FILE *) NULL) ||
12277 (package_info->image_info->blob != (void *) NULL))
12278 DisassociateImageStream(image);
12279 count+=GetImageListLength(image);
12280 EXTEND(sp,4*count);
12281 for (next=image; next; next=next->next)
12282 {
12283 PUSHs(sv_2mortal(newSViv(next->columns)));
12284 PUSHs(sv_2mortal(newSViv(next->rows)));
12285 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12286 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12287 }
12288 image=DestroyImageList(image);
12289 }
12290 /*
12291 Free resources.
12292 */
12293 for (i=0; i < n; i++)
12294 if (list[i] != (char *) NULL)
12295 for (p=keep; list[i] != *p++; )
12296 if (*p == NULL)
12297 {
12298 list[i]=(char *) RelinquishMagickMemory(list[i]);
12299 break;
12300 }
12301
12302 PerlException:
12303 if (package_info != (struct PackageInfo *) NULL)
12304 DestroyPackageInfo(package_info);
12305 if (list && (list != keep))
12306 list=(char **) RelinquishMagickMemory(list);
12307 if (keep)
12308 keep=(char **) RelinquishMagickMemory(keep);
12309 if (length)
12310 length=(STRLEN *) RelinquishMagickMemory(length);
12311 InheritPerlException(exception,perl_exception);
12312 exception=DestroyExceptionInfo(exception);
12313 SvREFCNT_dec(perl_exception); /* throw away all errors */
12314 }
12315
12316#
12317###############################################################################
12318# #
12319# #
12320# #
12321# P r e v i e w #
12322# #
12323# #
12324# #
12325###############################################################################
12326#
12327#
12328void
12329Preview(ref,...)
12330 Image::Magick ref=NO_INIT
12331 ALIAS:
12332 PreviewImage = 1
12333 preview = 2
12334 previewimage = 3
12335 PPCODE:
12336 {
12337 AV
12338 *av;
12339
12340 ExceptionInfo
12341 *exception;
12342
12343 HV
12344 *hv;
12345
12346 Image
12347 *image,
12348 *preview_image;
12349
12350 PreviewType
12351 preview_type;
12352
12353 struct PackageInfo
12354 *info;
12355
12356 SV
12357 *av_reference,
12358 *perl_exception,
12359 *reference,
12360 *rv,
12361 *sv;
12362
12363 PERL_UNUSED_VAR(ref);
12364 PERL_UNUSED_VAR(ix);
12365 exception=AcquireExceptionInfo();
12366 perl_exception=newSVpv("",0);
12367 sv=NULL;
12368 av=NULL;
12369 if (sv_isobject(ST(0)) == 0)
12370 {
12371 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12372 PackageName);
12373 goto PerlException;
12374 }
12375 reference=SvRV(ST(0));
12376 hv=SvSTASH(reference);
12377 av=newAV();
12378 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12379 SvREFCNT_dec(av);
12380 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12381 if (image == (Image *) NULL)
12382 {
12383 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12384 PackageName);
12385 goto PerlException;
12386 }
12387 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12388 preview_type=GammaPreview;
12389 if (items > 1)
12390 preview_type=(PreviewType)
12391 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12392 for ( ; image; image=image->next)
12393 {
12394 preview_image=PreviewImage(image,preview_type,exception);
12395 if (preview_image == (Image *) NULL)
12396 goto PerlException;
12397 AddImageToRegistry(sv,preview_image);
12398 rv=newRV(sv);
12399 av_push(av,sv_bless(rv,hv));
12400 SvREFCNT_dec(sv);
12401 }
12402 exception=DestroyExceptionInfo(exception);
12403 ST(0)=av_reference;
12404 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12405 XSRETURN(1);
12406
12407 PerlException:
12408 InheritPerlException(exception,perl_exception);
12409 exception=DestroyExceptionInfo(exception);
12410 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12411 SvPOK_on(perl_exception);
12412 ST(0)=sv_2mortal(perl_exception);
12413 XSRETURN(1);
12414 }
12415
12416#
12417###############################################################################
12418# #
12419# #
12420# #
12421# Q u e r y C o l o r #
12422# #
12423# #
12424# #
12425###############################################################################
12426#
12427#
12428void
12429QueryColor(ref,...)
12430 Image::Magick ref=NO_INIT
12431 ALIAS:
12432 querycolor = 1
12433 PPCODE:
12434 {
12435 char
12436 *name;
12437
12438 ExceptionInfo
12439 *exception;
12440
12441 PixelInfo
12442 color;
12443
12444 register ssize_t
12445 i;
12446
12447 SV
12448 *perl_exception;
12449
12450 PERL_UNUSED_VAR(ref);
12451 PERL_UNUSED_VAR(ix);
12452 exception=AcquireExceptionInfo();
12453 perl_exception=newSVpv("",0);
12454 if (items == 1)
12455 {
12456 const ColorInfo
12457 **colorlist;
12458
12459 size_t
12460 colors;
12461
12462 colorlist=GetColorInfoList("*",&colors,exception);
12463 EXTEND(sp,colors);
12464 for (i=0; i < (ssize_t) colors; i++)
12465 {
12466 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12467 }
12468 colorlist=(const ColorInfo **)
12469 RelinquishMagickMemory((ColorInfo **) colorlist);
12470 goto PerlException;
12471 }
12472 EXTEND(sp,5*items);
12473 for (i=1; i < items; i++)
12474 {
12475 name=(char *) SvPV(ST(i),na);
12476 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12477 {
12478 PUSHs(&sv_undef);
12479 continue;
12480 }
12481 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12482 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12483 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12484 if (color.colorspace == CMYKColorspace)
12485 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012486 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012487 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12488 }
12489
12490 PerlException:
12491 InheritPerlException(exception,perl_exception);
12492 exception=DestroyExceptionInfo(exception);
12493 SvREFCNT_dec(perl_exception);
12494 }
12495
12496#
12497###############################################################################
12498# #
12499# #
12500# #
12501# Q u e r y C o l o r N a m e #
12502# #
12503# #
12504# #
12505###############################################################################
12506#
12507#
12508void
12509QueryColorname(ref,...)
12510 Image::Magick ref=NO_INIT
12511 ALIAS:
12512 querycolorname = 1
12513 PPCODE:
12514 {
12515 AV
12516 *av;
12517
12518 char
cristy151b66d2015-04-15 10:50:31 +000012519 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012520
12521 ExceptionInfo
12522 *exception;
12523
12524 Image
12525 *image;
12526
12527 PixelInfo
12528 target_color;
12529
12530 register ssize_t
12531 i;
12532
12533 struct PackageInfo
12534 *info;
12535
12536 SV
12537 *perl_exception,
12538 *reference; /* reference is the SV* of ref=SvIV(reference) */
12539
12540 PERL_UNUSED_VAR(ref);
12541 PERL_UNUSED_VAR(ix);
12542 exception=AcquireExceptionInfo();
12543 perl_exception=newSVpv("",0);
12544 reference=SvRV(ST(0));
12545 av=(AV *) reference;
12546 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12547 exception);
12548 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12549 if (image == (Image *) NULL)
12550 {
12551 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12552 PackageName);
12553 goto PerlException;
12554 }
12555 EXTEND(sp,items);
12556 for (i=1; i < items; i++)
12557 {
12558 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12559 exception);
12560 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12561 exception);
12562 PUSHs(sv_2mortal(newSVpv(message,0)));
12563 }
12564
12565 PerlException:
12566 InheritPerlException(exception,perl_exception);
12567 exception=DestroyExceptionInfo(exception);
12568 SvREFCNT_dec(perl_exception);
12569 }
12570
12571#
12572###############################################################################
12573# #
12574# #
12575# #
12576# Q u e r y F o n t #
12577# #
12578# #
12579# #
12580###############################################################################
12581#
12582#
12583void
12584QueryFont(ref,...)
12585 Image::Magick ref=NO_INIT
12586 ALIAS:
12587 queryfont = 1
12588 PPCODE:
12589 {
12590 char
12591 *name,
cristy151b66d2015-04-15 10:50:31 +000012592 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012593
12594 ExceptionInfo
12595 *exception;
12596
12597 register ssize_t
12598 i;
12599
12600 SV
12601 *perl_exception;
12602
12603 volatile const TypeInfo
12604 *type_info;
12605
12606 PERL_UNUSED_VAR(ref);
12607 PERL_UNUSED_VAR(ix);
12608 exception=AcquireExceptionInfo();
12609 perl_exception=newSVpv("",0);
12610 if (items == 1)
12611 {
12612 const TypeInfo
12613 **typelist;
12614
12615 size_t
12616 types;
12617
12618 typelist=GetTypeInfoList("*",&types,exception);
12619 EXTEND(sp,types);
12620 for (i=0; i < (ssize_t) types; i++)
12621 {
12622 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12623 }
12624 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12625 typelist);
12626 goto PerlException;
12627 }
12628 EXTEND(sp,10*items);
12629 for (i=1; i < items; i++)
12630 {
12631 name=(char *) SvPV(ST(i),na);
12632 type_info=GetTypeInfo(name,exception);
12633 if (type_info == (TypeInfo *) NULL)
12634 {
12635 PUSHs(&sv_undef);
12636 continue;
12637 }
12638 if (type_info->name == (char *) NULL)
12639 PUSHs(&sv_undef);
12640 else
12641 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12642 if (type_info->description == (char *) NULL)
12643 PUSHs(&sv_undef);
12644 else
12645 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12646 if (type_info->family == (char *) NULL)
12647 PUSHs(&sv_undef);
12648 else
12649 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12650 if (type_info->style == UndefinedStyle)
12651 PUSHs(&sv_undef);
12652 else
12653 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12654 type_info->style),0)));
12655 if (type_info->stretch == UndefinedStretch)
12656 PUSHs(&sv_undef);
12657 else
12658 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12659 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012660 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012661 type_info->weight);
12662 PUSHs(sv_2mortal(newSVpv(message,0)));
12663 if (type_info->encoding == (char *) NULL)
12664 PUSHs(&sv_undef);
12665 else
12666 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12667 if (type_info->foundry == (char *) NULL)
12668 PUSHs(&sv_undef);
12669 else
12670 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12671 if (type_info->format == (char *) NULL)
12672 PUSHs(&sv_undef);
12673 else
12674 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12675 if (type_info->metrics == (char *) NULL)
12676 PUSHs(&sv_undef);
12677 else
12678 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12679 if (type_info->glyphs == (char *) NULL)
12680 PUSHs(&sv_undef);
12681 else
12682 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12683 }
12684
12685 PerlException:
12686 InheritPerlException(exception,perl_exception);
12687 exception=DestroyExceptionInfo(exception);
12688 SvREFCNT_dec(perl_exception);
12689 }
12690
12691#
12692###############################################################################
12693# #
12694# #
12695# #
12696# Q u e r y F o n t M e t r i c s #
12697# #
12698# #
12699# #
12700###############################################################################
12701#
12702#
12703void
12704QueryFontMetrics(ref,...)
12705 Image::Magick ref=NO_INIT
12706 ALIAS:
12707 queryfontmetrics = 1
12708 PPCODE:
12709 {
12710 AffineMatrix
12711 affine,
12712 current;
12713
12714 AV
12715 *av;
12716
12717 char
12718 *attribute;
12719
12720 double
12721 x,
12722 y;
12723
12724 DrawInfo
12725 *draw_info;
12726
12727 ExceptionInfo
12728 *exception;
12729
12730 GeometryInfo
12731 geometry_info;
12732
12733 Image
12734 *image;
12735
12736 MagickBooleanType
12737 status;
12738
12739 MagickStatusType
12740 flags;
12741
12742 register ssize_t
12743 i;
12744
12745 ssize_t
12746 type;
12747
12748 struct PackageInfo
12749 *info,
12750 *package_info;
12751
12752 SV
12753 *perl_exception,
12754 *reference; /* reference is the SV* of ref=SvIV(reference) */
12755
12756 TypeMetric
12757 metrics;
12758
12759 PERL_UNUSED_VAR(ref);
12760 PERL_UNUSED_VAR(ix);
12761 exception=AcquireExceptionInfo();
12762 package_info=(struct PackageInfo *) NULL;
12763 perl_exception=newSVpv("",0);
12764 reference=SvRV(ST(0));
12765 av=(AV *) reference;
12766 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12767 exception);
12768 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12769 if (image == (Image *) NULL)
12770 {
12771 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12772 PackageName);
12773 goto PerlException;
12774 }
12775 package_info=ClonePackageInfo(info,exception);
12776 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12777 CloneString(&draw_info->text,"");
12778 current=draw_info->affine;
12779 GetAffineMatrix(&affine);
12780 x=0.0;
12781 y=0.0;
12782 EXTEND(sp,7*items);
12783 for (i=2; i < items; i+=2)
12784 {
12785 attribute=(char *) SvPV(ST(i-1),na);
12786 switch (*attribute)
12787 {
12788 case 'A':
12789 case 'a':
12790 {
12791 if (LocaleCompare(attribute,"antialias") == 0)
12792 {
12793 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12794 SvPV(ST(i),na));
12795 if (type < 0)
12796 {
12797 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12798 SvPV(ST(i),na));
12799 break;
12800 }
12801 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12802 break;
12803 }
12804 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12805 attribute);
12806 break;
12807 }
12808 case 'd':
12809 case 'D':
12810 {
12811 if (LocaleCompare(attribute,"density") == 0)
12812 {
12813 CloneString(&draw_info->density,SvPV(ST(i),na));
12814 break;
12815 }
12816 if (LocaleCompare(attribute,"direction") == 0)
12817 {
12818 draw_info->direction=(DirectionType) ParseCommandOption(
12819 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12820 break;
12821 }
12822 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12823 attribute);
12824 break;
12825 }
12826 case 'e':
12827 case 'E':
12828 {
12829 if (LocaleCompare(attribute,"encoding") == 0)
12830 {
12831 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12832 break;
12833 }
12834 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12835 attribute);
12836 break;
12837 }
12838 case 'f':
12839 case 'F':
12840 {
12841 if (LocaleCompare(attribute,"family") == 0)
12842 {
12843 CloneString(&draw_info->family,SvPV(ST(i),na));
12844 break;
12845 }
12846 if (LocaleCompare(attribute,"fill") == 0)
12847 {
12848 if (info)
12849 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12850 &draw_info->fill,exception);
12851 break;
12852 }
12853 if (LocaleCompare(attribute,"font") == 0)
12854 {
12855 CloneString(&draw_info->font,SvPV(ST(i),na));
12856 break;
12857 }
12858 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12859 attribute);
12860 break;
12861 }
12862 case 'g':
12863 case 'G':
12864 {
12865 if (LocaleCompare(attribute,"geometry") == 0)
12866 {
12867 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12868 break;
12869 }
12870 if (LocaleCompare(attribute,"gravity") == 0)
12871 {
12872 draw_info->gravity=(GravityType) ParseCommandOption(
12873 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12874 break;
12875 }
12876 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12877 attribute);
12878 break;
12879 }
12880 case 'i':
12881 case 'I':
12882 {
12883 if (LocaleCompare(attribute,"interline-spacing") == 0)
12884 {
12885 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12886 draw_info->interline_spacing=geometry_info.rho;
12887 break;
12888 }
12889 if (LocaleCompare(attribute,"interword-spacing") == 0)
12890 {
12891 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12892 draw_info->interword_spacing=geometry_info.rho;
12893 break;
12894 }
12895 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12896 attribute);
12897 break;
12898 }
12899 case 'k':
12900 case 'K':
12901 {
12902 if (LocaleCompare(attribute,"kerning") == 0)
12903 {
12904 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12905 draw_info->kerning=geometry_info.rho;
12906 break;
12907 }
12908 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12909 attribute);
12910 break;
12911 }
12912 case 'p':
12913 case 'P':
12914 {
12915 if (LocaleCompare(attribute,"pointsize") == 0)
12916 {
12917 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12918 draw_info->pointsize=geometry_info.rho;
12919 break;
12920 }
12921 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12922 attribute);
12923 break;
12924 }
12925 case 'r':
12926 case 'R':
12927 {
12928 if (LocaleCompare(attribute,"rotate") == 0)
12929 {
12930 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12931 affine.rx=geometry_info.rho;
12932 affine.ry=geometry_info.sigma;
12933 if ((flags & SigmaValue) == 0)
12934 affine.ry=affine.rx;
12935 break;
12936 }
12937 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12938 attribute);
12939 break;
12940 }
12941 case 's':
12942 case 'S':
12943 {
12944 if (LocaleCompare(attribute,"scale") == 0)
12945 {
12946 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12947 affine.sx=geometry_info.rho;
12948 affine.sy=geometry_info.sigma;
12949 if ((flags & SigmaValue) == 0)
12950 affine.sy=affine.sx;
12951 break;
12952 }
12953 if (LocaleCompare(attribute,"skew") == 0)
12954 {
12955 double
12956 x_angle,
12957 y_angle;
12958
12959 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12960 x_angle=geometry_info.rho;
12961 y_angle=geometry_info.sigma;
12962 if ((flags & SigmaValue) == 0)
12963 y_angle=x_angle;
12964 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12965 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12966 break;
12967 }
12968 if (LocaleCompare(attribute,"stroke") == 0)
12969 {
12970 if (info)
12971 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12972 &draw_info->stroke,exception);
12973 break;
12974 }
12975 if (LocaleCompare(attribute,"style") == 0)
12976 {
12977 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12978 SvPV(ST(i),na));
12979 if (type < 0)
12980 {
12981 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12982 SvPV(ST(i),na));
12983 break;
12984 }
12985 draw_info->style=(StyleType) type;
12986 break;
12987 }
12988 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12989 attribute);
12990 break;
12991 }
12992 case 't':
12993 case 'T':
12994 {
12995 if (LocaleCompare(attribute,"text") == 0)
12996 {
12997 CloneString(&draw_info->text,SvPV(ST(i),na));
12998 break;
12999 }
13000 if (LocaleCompare(attribute,"translate") == 0)
13001 {
13002 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13003 affine.tx=geometry_info.rho;
13004 affine.ty=geometry_info.sigma;
13005 if ((flags & SigmaValue) == 0)
13006 affine.ty=affine.tx;
13007 break;
13008 }
13009 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13010 attribute);
13011 break;
13012 }
13013 case 'w':
13014 case 'W':
13015 {
13016 if (LocaleCompare(attribute,"weight") == 0)
13017 {
13018 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13019 draw_info->weight=(size_t) geometry_info.rho;
13020 break;
13021 }
13022 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13023 attribute);
13024 break;
13025 }
13026 case 'x':
13027 case 'X':
13028 {
13029 if (LocaleCompare(attribute,"x") == 0)
13030 {
13031 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13032 x=geometry_info.rho;
13033 break;
13034 }
13035 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13036 attribute);
13037 break;
13038 }
13039 case 'y':
13040 case 'Y':
13041 {
13042 if (LocaleCompare(attribute,"y") == 0)
13043 {
13044 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13045 y=geometry_info.rho;
13046 break;
13047 }
13048 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13049 attribute);
13050 break;
13051 }
13052 default:
13053 {
13054 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13055 attribute);
13056 break;
13057 }
13058 }
13059 }
13060 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13061 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13062 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13063 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13064 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13065 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13066 if (draw_info->geometry == (char *) NULL)
13067 {
13068 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013069 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013070 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013071 }
13072 status=GetTypeMetrics(image,draw_info,&metrics,exception);
13073 (void) CatchImageException(image);
13074 if (status == MagickFalse)
13075 PUSHs(&sv_undef);
13076 else
13077 {
13078 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13079 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13080 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13081 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13082 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13083 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13084 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13085 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13086 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13087 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13088 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13089 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13090 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13091 }
13092 draw_info=DestroyDrawInfo(draw_info);
13093
13094 PerlException:
13095 if (package_info != (struct PackageInfo *) NULL)
13096 DestroyPackageInfo(package_info);
13097 InheritPerlException(exception,perl_exception);
13098 exception=DestroyExceptionInfo(exception);
13099 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13100 }
13101
13102#
13103###############################################################################
13104# #
13105# #
13106# #
13107# 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 #
13108# #
13109# #
13110# #
13111###############################################################################
13112#
13113#
13114void
13115QueryMultilineFontMetrics(ref,...)
13116 Image::Magick ref=NO_INIT
13117 ALIAS:
13118 querymultilinefontmetrics = 1
13119 PPCODE:
13120 {
13121 AffineMatrix
13122 affine,
13123 current;
13124
13125 AV
13126 *av;
13127
13128 char
13129 *attribute;
13130
13131 double
13132 x,
13133 y;
13134
13135 DrawInfo
13136 *draw_info;
13137
13138 ExceptionInfo
13139 *exception;
13140
13141 GeometryInfo
13142 geometry_info;
13143
13144 Image
13145 *image;
13146
13147 MagickBooleanType
13148 status;
13149
13150 MagickStatusType
13151 flags;
13152
13153 register ssize_t
13154 i;
13155
13156 ssize_t
13157 type;
13158
13159 struct PackageInfo
13160 *info,
13161 *package_info;
13162
13163 SV
13164 *perl_exception,
13165 *reference; /* reference is the SV* of ref=SvIV(reference) */
13166
13167 TypeMetric
13168 metrics;
13169
13170 PERL_UNUSED_VAR(ref);
13171 PERL_UNUSED_VAR(ix);
13172 exception=AcquireExceptionInfo();
13173 package_info=(struct PackageInfo *) NULL;
13174 perl_exception=newSVpv("",0);
13175 reference=SvRV(ST(0));
13176 av=(AV *) reference;
13177 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13178 exception);
13179 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13180 if (image == (Image *) NULL)
13181 {
13182 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13183 PackageName);
13184 goto PerlException;
13185 }
13186 package_info=ClonePackageInfo(info,exception);
13187 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13188 CloneString(&draw_info->text,"");
13189 current=draw_info->affine;
13190 GetAffineMatrix(&affine);
13191 x=0.0;
13192 y=0.0;
13193 EXTEND(sp,7*items);
13194 for (i=2; i < items; i+=2)
13195 {
13196 attribute=(char *) SvPV(ST(i-1),na);
13197 switch (*attribute)
13198 {
13199 case 'A':
13200 case 'a':
13201 {
13202 if (LocaleCompare(attribute,"antialias") == 0)
13203 {
13204 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13205 SvPV(ST(i),na));
13206 if (type < 0)
13207 {
13208 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13209 SvPV(ST(i),na));
13210 break;
13211 }
13212 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13213 break;
13214 }
13215 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13216 attribute);
13217 break;
13218 }
13219 case 'd':
13220 case 'D':
13221 {
13222 if (LocaleCompare(attribute,"density") == 0)
13223 {
13224 CloneString(&draw_info->density,SvPV(ST(i),na));
13225 break;
13226 }
13227 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13228 attribute);
13229 break;
13230 }
13231 case 'e':
13232 case 'E':
13233 {
13234 if (LocaleCompare(attribute,"encoding") == 0)
13235 {
13236 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13237 break;
13238 }
13239 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13240 attribute);
13241 break;
13242 }
13243 case 'f':
13244 case 'F':
13245 {
13246 if (LocaleCompare(attribute,"family") == 0)
13247 {
13248 CloneString(&draw_info->family,SvPV(ST(i),na));
13249 break;
13250 }
13251 if (LocaleCompare(attribute,"fill") == 0)
13252 {
13253 if (info)
13254 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13255 &draw_info->fill,exception);
13256 break;
13257 }
13258 if (LocaleCompare(attribute,"font") == 0)
13259 {
13260 CloneString(&draw_info->font,SvPV(ST(i),na));
13261 break;
13262 }
13263 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13264 attribute);
13265 break;
13266 }
13267 case 'g':
13268 case 'G':
13269 {
13270 if (LocaleCompare(attribute,"geometry") == 0)
13271 {
13272 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13273 break;
13274 }
13275 if (LocaleCompare(attribute,"gravity") == 0)
13276 {
13277 draw_info->gravity=(GravityType) ParseCommandOption(
13278 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13279 break;
13280 }
13281 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13282 attribute);
13283 break;
13284 }
13285 case 'p':
13286 case 'P':
13287 {
13288 if (LocaleCompare(attribute,"pointsize") == 0)
13289 {
13290 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13291 draw_info->pointsize=geometry_info.rho;
13292 break;
13293 }
13294 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13295 attribute);
13296 break;
13297 }
13298 case 'r':
13299 case 'R':
13300 {
13301 if (LocaleCompare(attribute,"rotate") == 0)
13302 {
13303 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13304 affine.rx=geometry_info.rho;
13305 affine.ry=geometry_info.sigma;
13306 if ((flags & SigmaValue) == 0)
13307 affine.ry=affine.rx;
13308 break;
13309 }
13310 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13311 attribute);
13312 break;
13313 }
13314 case 's':
13315 case 'S':
13316 {
13317 if (LocaleCompare(attribute,"scale") == 0)
13318 {
13319 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13320 affine.sx=geometry_info.rho;
13321 affine.sy=geometry_info.sigma;
13322 if ((flags & SigmaValue) == 0)
13323 affine.sy=affine.sx;
13324 break;
13325 }
13326 if (LocaleCompare(attribute,"skew") == 0)
13327 {
13328 double
13329 x_angle,
13330 y_angle;
13331
13332 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13333 x_angle=geometry_info.rho;
13334 y_angle=geometry_info.sigma;
13335 if ((flags & SigmaValue) == 0)
13336 y_angle=x_angle;
13337 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13338 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13339 break;
13340 }
13341 if (LocaleCompare(attribute,"stroke") == 0)
13342 {
13343 if (info)
13344 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13345 &draw_info->stroke,exception);
13346 break;
13347 }
13348 if (LocaleCompare(attribute,"style") == 0)
13349 {
13350 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13351 SvPV(ST(i),na));
13352 if (type < 0)
13353 {
13354 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13355 SvPV(ST(i),na));
13356 break;
13357 }
13358 draw_info->style=(StyleType) type;
13359 break;
13360 }
13361 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13362 attribute);
13363 break;
13364 }
13365 case 't':
13366 case 'T':
13367 {
13368 if (LocaleCompare(attribute,"text") == 0)
13369 {
13370 CloneString(&draw_info->text,SvPV(ST(i),na));
13371 break;
13372 }
13373 if (LocaleCompare(attribute,"translate") == 0)
13374 {
13375 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13376 affine.tx=geometry_info.rho;
13377 affine.ty=geometry_info.sigma;
13378 if ((flags & SigmaValue) == 0)
13379 affine.ty=affine.tx;
13380 break;
13381 }
13382 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13383 attribute);
13384 break;
13385 }
13386 case 'w':
13387 case 'W':
13388 {
13389 if (LocaleCompare(attribute,"weight") == 0)
13390 {
13391 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13392 draw_info->weight=(size_t) geometry_info.rho;
13393 break;
13394 }
13395 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13396 attribute);
13397 break;
13398 }
13399 case 'x':
13400 case 'X':
13401 {
13402 if (LocaleCompare(attribute,"x") == 0)
13403 {
13404 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13405 x=geometry_info.rho;
13406 break;
13407 }
13408 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13409 attribute);
13410 break;
13411 }
13412 case 'y':
13413 case 'Y':
13414 {
13415 if (LocaleCompare(attribute,"y") == 0)
13416 {
13417 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13418 y=geometry_info.rho;
13419 break;
13420 }
13421 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13422 attribute);
13423 break;
13424 }
13425 default:
13426 {
13427 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13428 attribute);
13429 break;
13430 }
13431 }
13432 }
13433 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13434 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13435 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13436 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13437 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13438 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13439 if (draw_info->geometry == (char *) NULL)
13440 {
13441 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013442 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013443 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013444 }
13445 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13446 (void) CatchException(exception);
13447 if (status == MagickFalse)
13448 PUSHs(&sv_undef);
13449 else
13450 {
13451 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13452 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13453 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13454 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13455 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13456 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13457 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13458 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13459 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13460 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13461 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13462 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13463 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13464 }
13465 draw_info=DestroyDrawInfo(draw_info);
13466
13467 PerlException:
13468 if (package_info != (struct PackageInfo *) NULL)
13469 DestroyPackageInfo(package_info);
13470 InheritPerlException(exception,perl_exception);
13471 exception=DestroyExceptionInfo(exception);
13472 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13473 }
13474
13475#
13476###############################################################################
13477# #
13478# #
13479# #
13480# Q u e r y F o r m a t #
13481# #
13482# #
13483# #
13484###############################################################################
13485#
13486#
13487void
13488QueryFormat(ref,...)
13489 Image::Magick ref=NO_INIT
13490 ALIAS:
13491 queryformat = 1
13492 PPCODE:
13493 {
13494 char
13495 *name;
13496
13497 ExceptionInfo
13498 *exception;
13499
13500 register ssize_t
13501 i;
13502
13503 SV
13504 *perl_exception;
13505
13506 volatile const MagickInfo
13507 *magick_info;
13508
13509 PERL_UNUSED_VAR(ref);
13510 PERL_UNUSED_VAR(ix);
13511 exception=AcquireExceptionInfo();
13512 perl_exception=newSVpv("",0);
13513 if (items == 1)
13514 {
13515 char
cristy151b66d2015-04-15 10:50:31 +000013516 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013517
13518 const MagickInfo
13519 **format_list;
13520
13521 size_t
13522 types;
13523
13524 format_list=GetMagickInfoList("*",&types,exception);
13525 EXTEND(sp,types);
13526 for (i=0; i < (ssize_t) types; i++)
13527 {
cristy151b66d2015-04-15 10:50:31 +000013528 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013529 LocaleLower(format);
13530 PUSHs(sv_2mortal(newSVpv(format,0)));
13531 }
13532 format_list=(const MagickInfo **)
13533 RelinquishMagickMemory((MagickInfo *) format_list);
13534 goto PerlException;
13535 }
13536 EXTEND(sp,8*items);
13537 for (i=1; i < items; i++)
13538 {
13539 name=(char *) SvPV(ST(i),na);
13540 magick_info=GetMagickInfo(name,exception);
13541 if (magick_info == (const MagickInfo *) NULL)
13542 {
13543 PUSHs(&sv_undef);
13544 continue;
13545 }
cristy4a3ce0a2013-08-03 20:06:59 +000013546 if (magick_info->description == (char *) NULL)
13547 PUSHs(&sv_undef);
13548 else
13549 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13550 if (magick_info->module == (char *) NULL)
13551 PUSHs(&sv_undef);
13552 else
13553 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13554 }
13555
13556 PerlException:
13557 InheritPerlException(exception,perl_exception);
13558 exception=DestroyExceptionInfo(exception);
13559 SvREFCNT_dec(perl_exception);
13560 }
13561
13562#
13563###############################################################################
13564# #
13565# #
13566# #
13567# Q u e r y O p t i o n #
13568# #
13569# #
13570# #
13571###############################################################################
13572#
13573#
13574void
13575QueryOption(ref,...)
13576 Image::Magick ref=NO_INIT
13577 ALIAS:
13578 queryoption = 1
13579 PPCODE:
13580 {
13581 char
13582 **options;
13583
13584 ExceptionInfo
13585 *exception;
13586
13587 register ssize_t
13588 i;
13589
13590 ssize_t
13591 j,
13592 option;
13593
13594 SV
13595 *perl_exception;
13596
13597 PERL_UNUSED_VAR(ref);
13598 PERL_UNUSED_VAR(ix);
13599 exception=AcquireExceptionInfo();
13600 perl_exception=newSVpv("",0);
13601 EXTEND(sp,8*items);
13602 for (i=1; i < items; i++)
13603 {
13604 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13605 SvPV(ST(i),na));
13606 options=GetCommandOptions((CommandOption) option);
13607 if (options == (char **) NULL)
13608 PUSHs(&sv_undef);
13609 else
13610 {
13611 for (j=0; options[j] != (char *) NULL; j++)
13612 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13613 options=DestroyStringList(options);
13614 }
13615 }
13616
13617 InheritPerlException(exception,perl_exception);
13618 exception=DestroyExceptionInfo(exception);
13619 SvREFCNT_dec(perl_exception);
13620 }
13621
13622#
13623###############################################################################
13624# #
13625# #
13626# #
13627# R e a d #
13628# #
13629# #
13630# #
13631###############################################################################
13632#
13633#
13634void
13635Read(ref,...)
13636 Image::Magick ref=NO_INIT
13637 ALIAS:
13638 ReadImage = 1
13639 read = 2
13640 readimage = 3
13641 PPCODE:
13642 {
13643 AV
13644 *av;
13645
13646 char
13647 **keep,
13648 **list;
13649
13650 ExceptionInfo
13651 *exception;
13652
13653 HV
13654 *hv;
13655
13656 Image
13657 *image;
13658
13659 int
13660 n;
13661
13662 MagickBooleanType
13663 status;
13664
13665 register char
13666 **p;
13667
13668 register ssize_t
13669 i;
13670
13671 ssize_t
13672 ac,
13673 number_images;
13674
13675 STRLEN
13676 *length;
13677
13678 struct PackageInfo
13679 *info,
13680 *package_info;
13681
13682 SV
13683 *perl_exception, /* Perl variable for storing messages */
13684 *reference,
13685 *rv,
13686 *sv;
13687
13688 PERL_UNUSED_VAR(ref);
13689 PERL_UNUSED_VAR(ix);
13690 exception=AcquireExceptionInfo();
13691 perl_exception=newSVpv("",0);
13692 sv=NULL;
13693 package_info=(struct PackageInfo *) NULL;
13694 number_images=0;
13695 ac=(items < 2) ? 1 : items-1;
13696 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13697 keep=list;
13698 length=(STRLEN *) NULL;
13699 if (list == (char **) NULL)
13700 {
13701 ThrowPerlException(exception,ResourceLimitError,
13702 "MemoryAllocationFailed",PackageName);
13703 goto PerlException;
13704 }
13705 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13706 if (length == (STRLEN *) NULL)
13707 {
13708 ThrowPerlException(exception,ResourceLimitError,
13709 "MemoryAllocationFailed",PackageName);
13710 goto PerlException;
13711 }
13712 if (sv_isobject(ST(0)) == 0)
13713 {
13714 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13715 PackageName);
13716 goto PerlException;
13717 }
13718 reference=SvRV(ST(0));
13719 hv=SvSTASH(reference);
13720 if (SvTYPE(reference) != SVt_PVAV)
13721 {
13722 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13723 PackageName);
13724 goto PerlException;
13725 }
13726 av=(AV *) reference;
13727 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13728 exception);
13729 package_info=ClonePackageInfo(info,exception);
13730 n=1;
13731 if (items <= 1)
13732 *list=(char *) (*package_info->image_info->filename ?
13733 package_info->image_info->filename : "XC:black");
13734 else
13735 for (n=0, i=0; i < ac; i++)
13736 {
13737 list[n]=(char *) SvPV(ST(i+1),length[n]);
13738 if ((items >= 3) && strEQcase(list[n],"blob"))
13739 {
13740 void
13741 *blob;
13742
13743 i++;
13744 blob=(void *) (SvPV(ST(i+1),length[n]));
13745 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13746 }
13747 if ((items >= 3) && strEQcase(list[n],"filename"))
13748 continue;
13749 if ((items >= 3) && strEQcase(list[n],"file"))
13750 {
13751 FILE
13752 *file;
13753
13754 PerlIO
13755 *io_info;
13756
13757 i++;
13758 io_info=IoIFP(sv_2io(ST(i+1)));
13759 if (io_info == (PerlIO *) NULL)
13760 {
13761 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13762 PackageName);
13763 continue;
13764 }
13765 file=PerlIO_findFILE(io_info);
13766 if (file == (FILE *) NULL)
13767 {
13768 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13769 PackageName);
13770 continue;
13771 }
13772 SetImageInfoFile(package_info->image_info,file);
13773 }
13774 if ((items >= 3) && strEQcase(list[n],"magick"))
13775 continue;
13776 n++;
13777 }
13778 list[n]=(char *) NULL;
13779 keep=list;
13780 status=ExpandFilenames(&n,&list);
13781 if (status == MagickFalse)
13782 {
13783 ThrowPerlException(exception,ResourceLimitError,
13784 "MemoryAllocationFailed",PackageName);
13785 goto PerlException;
13786 }
13787 number_images=0;
13788 for (i=0; i < n; i++)
13789 {
13790 if ((package_info->image_info->file == (FILE *) NULL) &&
13791 (package_info->image_info->blob == (void *) NULL))
13792 image=ReadImages(package_info->image_info,list[i],exception);
13793 else
13794 {
13795 image=ReadImages(package_info->image_info,
13796 package_info->image_info->filename,exception);
13797 if (image != (Image *) NULL)
13798 DisassociateImageStream(image);
13799 }
13800 if (image == (Image *) NULL)
13801 break;
13802 for ( ; image; image=image->next)
13803 {
13804 AddImageToRegistry(sv,image);
13805 rv=newRV(sv);
13806 av_push(av,sv_bless(rv,hv));
13807 SvREFCNT_dec(sv);
13808 number_images++;
13809 }
13810 }
13811 /*
13812 Free resources.
13813 */
13814 for (i=0; i < n; i++)
13815 if (list[i] != (char *) NULL)
13816 for (p=keep; list[i] != *p++; )
13817 if (*p == (char *) NULL)
13818 {
13819 list[i]=(char *) RelinquishMagickMemory(list[i]);
13820 break;
13821 }
13822
13823 PerlException:
13824 if (package_info != (struct PackageInfo *) NULL)
13825 DestroyPackageInfo(package_info);
13826 if (list && (list != keep))
13827 list=(char **) RelinquishMagickMemory(list);
13828 if (keep)
13829 keep=(char **) RelinquishMagickMemory(keep);
13830 if (length)
13831 length=(STRLEN *) RelinquishMagickMemory(length);
13832 InheritPerlException(exception,perl_exception);
13833 exception=DestroyExceptionInfo(exception);
13834 sv_setiv(perl_exception,(IV) number_images);
13835 SvPOK_on(perl_exception);
13836 ST(0)=sv_2mortal(perl_exception);
13837 XSRETURN(1);
13838 }
13839
13840#
13841###############################################################################
13842# #
13843# #
13844# #
13845# R e m o t e #
13846# #
13847# #
13848# #
13849###############################################################################
13850#
13851#
13852void
13853Remote(ref,...)
13854 Image::Magick ref=NO_INIT
13855 ALIAS:
13856 RemoteCommand = 1
13857 remote = 2
13858 remoteCommand = 3
13859 PPCODE:
13860 {
13861 AV
13862 *av;
13863
13864 ExceptionInfo
13865 *exception;
13866
13867 register ssize_t
13868 i;
13869
13870 SV
13871 *perl_exception,
13872 *reference;
13873
13874 struct PackageInfo
13875 *info;
13876
13877 PERL_UNUSED_VAR(ref);
13878 PERL_UNUSED_VAR(ix);
13879 exception=AcquireExceptionInfo();
13880 perl_exception=newSVpv("",0);
13881 reference=SvRV(ST(0));
13882 av=(AV *) reference;
13883 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13884 exception);
13885 for (i=1; i < items; i++)
13886 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13887 SvPV(ST(i),na),exception);
13888 InheritPerlException(exception,perl_exception);
13889 exception=DestroyExceptionInfo(exception);
13890 SvREFCNT_dec(perl_exception); /* throw away all errors */
13891 }
13892
13893#
13894###############################################################################
13895# #
13896# #
13897# #
13898# S e t #
13899# #
13900# #
13901# #
13902###############################################################################
13903#
13904#
13905void
13906Set(ref,...)
13907 Image::Magick ref=NO_INIT
13908 ALIAS:
13909 SetAttributes = 1
13910 SetAttribute = 2
13911 set = 3
13912 setattributes = 4
13913 setattribute = 5
13914 PPCODE:
13915 {
13916 ExceptionInfo
13917 *exception;
13918
13919 Image
13920 *image;
13921
13922 register ssize_t
13923 i;
13924
13925 struct PackageInfo
13926 *info;
13927
13928 SV
13929 *perl_exception,
13930 *reference; /* reference is the SV* of ref=SvIV(reference) */
13931
13932 PERL_UNUSED_VAR(ref);
13933 PERL_UNUSED_VAR(ix);
13934 exception=AcquireExceptionInfo();
13935 perl_exception=newSVpv("",0);
13936 if (sv_isobject(ST(0)) == 0)
13937 {
13938 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13939 PackageName);
13940 goto PerlException;
13941 }
13942 reference=SvRV(ST(0));
13943 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13944 if (items == 2)
13945 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13946 else
13947 for (i=2; i < items; i+=2)
13948 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13949
13950 PerlException:
13951 InheritPerlException(exception,perl_exception);
13952 exception=DestroyExceptionInfo(exception);
13953 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13954 SvPOK_on(perl_exception);
13955 ST(0)=sv_2mortal(perl_exception);
13956 XSRETURN(1);
13957 }
13958
13959#
13960###############################################################################
13961# #
13962# #
13963# #
13964# S e t P i x e l #
13965# #
13966# #
13967# #
13968###############################################################################
13969#
13970#
13971void
13972SetPixel(ref,...)
13973 Image::Magick ref=NO_INIT
13974 ALIAS:
13975 setpixel = 1
13976 setPixel = 2
13977 PPCODE:
13978 {
13979 AV
13980 *av;
13981
13982 char
13983 *attribute;
13984
13985 ChannelType
13986 channel,
13987 channel_mask;
13988
13989 ExceptionInfo
13990 *exception;
13991
13992 Image
13993 *image;
13994
13995 MagickBooleanType
13996 normalize;
13997
13998 RectangleInfo
13999 region;
14000
14001 register ssize_t
14002 i;
14003
14004 register Quantum
14005 *q;
14006
14007 ssize_t
14008 option;
14009
14010 struct PackageInfo
14011 *info;
14012
14013 SV
14014 *perl_exception,
14015 *reference; /* reference is the SV* of ref=SvIV(reference) */
14016
14017 PERL_UNUSED_VAR(ref);
14018 PERL_UNUSED_VAR(ix);
14019 exception=AcquireExceptionInfo();
14020 perl_exception=newSVpv("",0);
14021 reference=SvRV(ST(0));
14022 av=(AV *) reference;
14023 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14024 exception);
14025 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14026 if (image == (Image *) NULL)
14027 {
14028 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14029 PackageName);
14030 goto PerlException;
14031 }
14032 av=(AV *) NULL;
14033 normalize=MagickTrue;
14034 region.x=0;
14035 region.y=0;
14036 region.width=image->columns;
14037 region.height=1;
14038 if (items == 1)
14039 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
14040 channel=DefaultChannels;
14041 for (i=2; i < items; i+=2)
14042 {
14043 attribute=(char *) SvPV(ST(i-1),na);
14044 switch (*attribute)
14045 {
14046 case 'C':
14047 case 'c':
14048 {
14049 if (LocaleCompare(attribute,"channel") == 0)
14050 {
14051 ssize_t
14052 option;
14053
14054 option=ParseChannelOption(SvPV(ST(i),na));
14055 if (option < 0)
14056 {
14057 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14058 SvPV(ST(i),na));
14059 return;
14060 }
14061 channel=(ChannelType) option;
14062 break;
14063 }
14064 if (LocaleCompare(attribute,"color") == 0)
14065 {
14066 if (SvTYPE(ST(i)) != SVt_RV)
14067 {
14068 char
cristy151b66d2015-04-15 10:50:31 +000014069 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014070
cristy151b66d2015-04-15 10:50:31 +000014071 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000014072 "invalid %.60s value",attribute);
14073 ThrowPerlException(exception,OptionError,message,
14074 SvPV(ST(i),na));
14075 }
14076 av=(AV *) SvRV(ST(i));
14077 break;
14078 }
14079 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14080 attribute);
14081 break;
14082 }
14083 case 'g':
14084 case 'G':
14085 {
14086 if (LocaleCompare(attribute,"geometry") == 0)
14087 {
14088 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14089 break;
14090 }
14091 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14092 attribute);
14093 break;
14094 }
14095 case 'N':
14096 case 'n':
14097 {
14098 if (LocaleCompare(attribute,"normalize") == 0)
14099 {
14100 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14101 SvPV(ST(i),na));
14102 if (option < 0)
14103 {
14104 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14105 SvPV(ST(i),na));
14106 break;
14107 }
14108 normalize=option != 0 ? MagickTrue : MagickFalse;
14109 break;
14110 }
14111 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14112 attribute);
14113 break;
14114 }
14115 case 'x':
14116 case 'X':
14117 {
14118 if (LocaleCompare(attribute,"x") == 0)
14119 {
14120 region.x=SvIV(ST(i));
14121 break;
14122 }
14123 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14124 attribute);
14125 break;
14126 }
14127 case 'y':
14128 case 'Y':
14129 {
14130 if (LocaleCompare(attribute,"y") == 0)
14131 {
14132 region.y=SvIV(ST(i));
14133 break;
14134 }
14135 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14136 attribute);
14137 break;
14138 }
14139 default:
14140 {
14141 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14142 attribute);
14143 break;
14144 }
14145 }
14146 }
14147 (void) SetImageStorageClass(image,DirectClass,exception);
14148 channel_mask=SetImageChannelMask(image,channel);
14149 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14150 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14151 (SvTYPE(av) != SVt_PVAV))
14152 PUSHs(&sv_undef);
14153 else
14154 {
14155 double
14156 scale;
14157
14158 register ssize_t
14159 i;
14160
14161 i=0;
14162 scale=1.0;
14163 if (normalize != MagickFalse)
14164 scale=QuantumRange;
14165 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14166 (i <= av_len(av)))
14167 {
14168 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14169 av_fetch(av,i,0)))),q);
14170 i++;
14171 }
14172 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14173 (i <= av_len(av)))
14174 {
14175 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14176 av_fetch(av,i,0)))),q);
14177 i++;
14178 }
14179 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14180 (i <= av_len(av)))
14181 {
14182 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14183 av_fetch(av,i,0)))),q);
14184 i++;
14185 }
14186 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14187 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14188 {
14189 SetPixelBlack(image,ClampToQuantum(scale*
14190 SvNV(*(av_fetch(av,i,0)))),q);
14191 i++;
14192 }
14193 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14194 (i <= av_len(av)))
14195 {
14196 SetPixelAlpha(image,ClampToQuantum(scale*
14197 SvNV(*(av_fetch(av,i,0)))),q);
14198 i++;
14199 }
14200 (void) SyncAuthenticPixels(image,exception);
14201 }
14202 (void) SetImageChannelMask(image,channel_mask);
14203
14204 PerlException:
14205 InheritPerlException(exception,perl_exception);
14206 exception=DestroyExceptionInfo(exception);
14207 SvREFCNT_dec(perl_exception);
14208 }
14209
14210#
14211###############################################################################
14212# #
14213# #
14214# #
Cristybba545b2018-07-04 15:00:12 -040014215# S e t P i x e l s #
14216# #
14217# #
14218# #
14219###############################################################################
14220#
14221#
14222void
14223SetPixels(ref,...)
14224 Image::Magick ref=NO_INIT
14225 ALIAS:
14226 setpixels = 1
14227 setPixels = 2
14228 PPCODE:
14229 {
14230 AV
14231 *av;
14232
14233 char
14234 *attribute;
14235
14236 ChannelType
14237 channel,
14238 channel_mask;
14239
14240 ExceptionInfo
14241 *exception;
14242
14243 Image
14244 *image;
14245
14246 RectangleInfo
14247 region;
14248
14249 register ssize_t
14250 i;
14251
14252 register Quantum
14253 *q;
14254
14255 struct PackageInfo
14256 *info;
14257
14258 SV
14259 *perl_exception,
14260 *reference; /* reference is the SV* of ref=SvIV(reference) */
14261
14262 PERL_UNUSED_VAR(ref);
14263 PERL_UNUSED_VAR(ix);
14264 exception=AcquireExceptionInfo();
14265 perl_exception=newSVpv("",0);
14266 reference=SvRV(ST(0));
14267 av=(AV *) reference;
14268 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14269 exception);
14270 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14271 if (image == (Image *) NULL)
14272 {
14273 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14274 PackageName);
14275 goto PerlException;
14276 }
14277 av=(AV *) NULL;
14278 region.x=0;
14279 region.y=0;
14280 region.width=image->columns;
14281 region.height=1;
14282 if (items == 1)
14283 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
14284 channel=DefaultChannels;
14285 for (i=2; i < items; i+=2)
14286 {
14287 attribute=(char *) SvPV(ST(i-1),na);
14288 switch (*attribute)
14289 {
14290 case 'C':
14291 case 'c':
14292 {
14293 if (LocaleCompare(attribute,"channel") == 0)
14294 {
14295 ssize_t
14296 option;
14297
14298 option=ParseChannelOption(SvPV(ST(i),na));
14299 if (option < 0)
14300 {
14301 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14302 SvPV(ST(i),na));
14303 return;
14304 }
14305 channel=(ChannelType) option;
14306 break;
14307 }
14308 if (LocaleCompare(attribute,"color") == 0)
14309 {
14310 if (SvTYPE(ST(i)) != SVt_RV)
14311 {
14312 char
14313 message[MagickPathExtent];
14314
14315 (void) FormatLocaleString(message,MagickPathExtent,
14316 "invalid %.60s value",attribute);
14317 ThrowPerlException(exception,OptionError,message,
14318 SvPV(ST(i),na));
14319 }
14320 av=(AV *) SvRV(ST(i));
14321 break;
14322 }
14323 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14324 attribute);
14325 break;
14326 }
14327 case 'g':
14328 case 'G':
14329 {
14330 if (LocaleCompare(attribute,"geometry") == 0)
14331 {
14332 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14333 break;
14334 }
14335 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14336 attribute);
14337 break;
14338 }
14339 case 'h':
14340 case 'H':
14341 {
14342 if (LocaleCompare(attribute,"height") == 0)
14343 {
14344 region.height=SvIV(ST(i));
14345 break;
14346 }
14347 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14348 attribute);
14349 break;
14350 }
14351 case 'w':
14352 case 'W':
14353 {
14354 if (LocaleCompare(attribute,"width") == 0)
14355 {
14356 region.width=SvIV(ST(i));
14357 break;
14358 }
14359 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14360 attribute);
14361 break;
14362 }
14363 case 'x':
14364 case 'X':
14365 {
14366 if (LocaleCompare(attribute,"x") == 0)
14367 {
14368 region.x=SvIV(ST(i));
14369 break;
14370 }
14371 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14372 attribute);
14373 break;
14374 }
14375 case 'y':
14376 case 'Y':
14377 {
14378 if (LocaleCompare(attribute,"y") == 0)
14379 {
14380 region.y=SvIV(ST(i));
14381 break;
14382 }
14383 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14384 attribute);
14385 break;
14386 }
14387 default:
14388 {
14389 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14390 attribute);
14391 break;
14392 }
14393 }
14394 }
14395 (void) SetImageStorageClass(image,DirectClass,exception);
14396 channel_mask=SetImageChannelMask(image,channel);
14397 q=GetAuthenticPixels(image,region.x,region.y,region.width,region.height,
14398 exception);
14399 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14400 (SvTYPE(av) != SVt_PVAV))
14401 PUSHs(&sv_undef);
14402 else
14403 {
14404 double
14405 scale;
14406
14407 register ssize_t
14408 i,
14409 n,
14410 number_pixels;
14411
14412 i=0;
14413 n=0;
14414 scale=(double) QuantumRange;
14415 number_pixels=region.width*region.height;
14416 while ((n < number_pixels) && (i < av_len(av)))
14417 {
14418 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14419 (i <= av_len(av)))
14420 {
14421 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14422 av_fetch(av,i,0)))),q);
14423 i++;
14424 }
14425 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14426 (i <= av_len(av)))
14427 {
14428 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14429 av_fetch(av,i,0)))),q);
14430 i++;
14431 }
14432 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14433 (i <= av_len(av)))
14434 {
14435 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14436 av_fetch(av,i,0)))),q);
14437 i++;
14438 }
14439 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14440 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14441 {
14442 SetPixelBlack(image,ClampToQuantum(scale*
14443 SvNV(*(av_fetch(av,i,0)))),q);
14444 i++;
14445 }
14446 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14447 (i <= av_len(av)))
14448 {
14449 SetPixelAlpha(image,ClampToQuantum(scale*
14450 SvNV(*(av_fetch(av,i,0)))),q);
14451 i++;
14452 }
14453 n++;
14454 q+=image->number_channels;
14455 }
14456 (void) SyncAuthenticPixels(image,exception);
14457 }
14458 (void) SetImageChannelMask(image,channel_mask);
14459
14460 PerlException:
14461 InheritPerlException(exception,perl_exception);
14462 exception=DestroyExceptionInfo(exception);
14463 SvREFCNT_dec(perl_exception);
14464 }
14465
14466#
14467###############################################################################
14468# #
14469# #
14470# #
cristy4a3ce0a2013-08-03 20:06:59 +000014471# S m u s h #
14472# #
14473# #
14474# #
14475###############################################################################
14476#
14477#
14478void
14479Smush(ref,...)
14480 Image::Magick ref=NO_INIT
14481 ALIAS:
14482 SmushImage = 1
14483 smush = 2
14484 smushimage = 3
14485 PPCODE:
14486 {
14487 AV
14488 *av;
14489
14490 char
14491 *attribute;
14492
14493 ExceptionInfo
14494 *exception;
14495
14496 HV
14497 *hv;
14498
14499 Image
14500 *image;
14501
14502 register ssize_t
14503 i;
14504
14505 ssize_t
14506 offset,
14507 stack;
14508
14509 struct PackageInfo
14510 *info;
14511
14512 SV
14513 *av_reference,
14514 *perl_exception,
14515 *reference,
14516 *rv,
14517 *sv;
14518
14519 PERL_UNUSED_VAR(ref);
14520 PERL_UNUSED_VAR(ix);
14521 exception=AcquireExceptionInfo();
14522 perl_exception=newSVpv("",0);
14523 sv=NULL;
14524 attribute=NULL;
14525 av=NULL;
14526 if (sv_isobject(ST(0)) == 0)
14527 {
14528 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14529 PackageName);
14530 goto PerlException;
14531 }
14532 reference=SvRV(ST(0));
14533 hv=SvSTASH(reference);
14534 av=newAV();
14535 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14536 SvREFCNT_dec(av);
14537 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14538 if (image == (Image *) NULL)
14539 {
14540 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14541 PackageName);
14542 goto PerlException;
14543 }
14544 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14545 /*
14546 Get options.
14547 */
14548 offset=0;
14549 stack=MagickTrue;
14550 for (i=2; i < items; i+=2)
14551 {
14552 attribute=(char *) SvPV(ST(i-1),na);
14553 switch (*attribute)
14554 {
14555 case 'O':
14556 case 'o':
14557 {
14558 if (LocaleCompare(attribute,"offset") == 0)
14559 {
14560 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14561 break;
14562 }
14563 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14564 attribute);
14565 break;
14566 }
14567 case 'S':
14568 case 's':
14569 {
14570 if (LocaleCompare(attribute,"stack") == 0)
14571 {
14572 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14573 SvPV(ST(i),na));
14574 if (stack < 0)
14575 {
14576 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14577 SvPV(ST(i),na));
14578 return;
14579 }
14580 break;
14581 }
14582 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14583 attribute);
14584 break;
14585 }
14586 default:
14587 {
14588 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14589 attribute);
14590 break;
14591 }
14592 }
14593 }
14594 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14595 exception);
14596 if (image == (Image *) NULL)
14597 goto PerlException;
14598 for ( ; image; image=image->next)
14599 {
14600 AddImageToRegistry(sv,image);
14601 rv=newRV(sv);
14602 av_push(av,sv_bless(rv,hv));
14603 SvREFCNT_dec(sv);
14604 }
14605 exception=DestroyExceptionInfo(exception);
14606 ST(0)=av_reference;
14607 SvREFCNT_dec(perl_exception);
14608 XSRETURN(1);
14609
14610 PerlException:
14611 InheritPerlException(exception,perl_exception);
14612 exception=DestroyExceptionInfo(exception);
14613 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14614 SvPOK_on(perl_exception);
14615 ST(0)=sv_2mortal(perl_exception);
14616 XSRETURN(1);
14617 }
14618
14619#
14620###############################################################################
14621# #
14622# #
14623# #
14624# S t a t i s t i c s #
14625# #
14626# #
14627# #
14628###############################################################################
14629#
14630#
14631void
14632Statistics(ref,...)
14633 Image::Magick ref=NO_INIT
14634 ALIAS:
14635 StatisticsImage = 1
14636 statistics = 2
14637 statisticsimage = 3
14638 PPCODE:
14639 {
14640#define ChannelStatistics(channel) \
14641{ \
cristy151b66d2015-04-15 10:50:31 +000014642 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014643 (double) channel_statistics[channel].depth); \
14644 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014645 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014646 channel_statistics[channel].minima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014647 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014648 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014649 channel_statistics[channel].maxima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014650 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014651 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014652 channel_statistics[channel].mean/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014653 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014654 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014655 channel_statistics[channel].standard_deviation/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014656 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014657 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014658 channel_statistics[channel].kurtosis); \
14659 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014660 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014661 channel_statistics[channel].skewness); \
14662 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014663 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy275bdd92014-11-08 23:45:03 +000014664 channel_statistics[channel].entropy); \
14665 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014666}
14667
14668 AV
14669 *av;
14670
14671 char
cristy151b66d2015-04-15 10:50:31 +000014672 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014673
14674 ChannelStatistics
14675 *channel_statistics;
14676
cristy4a3ce0a2013-08-03 20:06:59 +000014677 ExceptionInfo
14678 *exception;
14679
14680 Image
14681 *image;
14682
14683 ssize_t
14684 count;
14685
14686 struct PackageInfo
14687 *info;
14688
14689 SV
14690 *perl_exception,
14691 *reference;
14692
14693 PERL_UNUSED_VAR(ref);
14694 PERL_UNUSED_VAR(ix);
14695 exception=AcquireExceptionInfo();
14696 perl_exception=newSVpv("",0);
14697 av=NULL;
14698 if (sv_isobject(ST(0)) == 0)
14699 {
14700 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14701 PackageName);
14702 goto PerlException;
14703 }
14704 reference=SvRV(ST(0));
14705 av=newAV();
14706 SvREFCNT_dec(av);
14707 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14708 if (image == (Image *) NULL)
14709 {
14710 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14711 PackageName);
14712 goto PerlException;
14713 }
cristy4a3ce0a2013-08-03 20:06:59 +000014714 count=0;
14715 for ( ; image; image=image->next)
14716 {
Cristyb1710fe2017-02-11 13:51:48 -050014717 register size_t
14718 i;
14719
cristy4a3ce0a2013-08-03 20:06:59 +000014720 channel_statistics=GetImageStatistics(image,exception);
14721 if (channel_statistics == (ChannelStatistics *) NULL)
14722 continue;
14723 count++;
Cristyb1710fe2017-02-11 13:51:48 -050014724 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
14725 {
14726 PixelChannel channel=GetPixelChannelChannel(image,i);
14727 PixelTrait traits=GetPixelChannelTraits(image,channel);
Cristy5a854dc2017-02-11 15:43:46 -050014728 if (traits == UndefinedPixelTrait)
Cristyb1710fe2017-02-11 13:51:48 -050014729 continue;
Cristy5a854dc2017-02-11 15:43:46 -050014730 EXTEND(sp,8*(i+1)*count);
Cristyb1710fe2017-02-11 13:51:48 -050014731 ChannelStatistics(channel);
14732 }
Cristy25813902017-02-11 15:47:52 -050014733 EXTEND(sp,8*(i+1)*count);
14734 ChannelStatistics(CompositePixelChannel);
cristy4a3ce0a2013-08-03 20:06:59 +000014735 channel_statistics=(ChannelStatistics *)
14736 RelinquishMagickMemory(channel_statistics);
14737 }
14738
14739 PerlException:
14740 InheritPerlException(exception,perl_exception);
14741 exception=DestroyExceptionInfo(exception);
14742 SvREFCNT_dec(perl_exception);
14743 }
14744
14745#
14746###############################################################################
14747# #
14748# #
14749# #
14750# S y n c A u t h e n t i c P i x e l s #
14751# #
14752# #
14753# #
14754###############################################################################
14755#
14756#
14757void
14758SyncAuthenticPixels(ref,...)
14759 Image::Magick ref = NO_INIT
14760 ALIAS:
14761 Syncauthenticpixels = 1
14762 SyncImagePixels = 2
14763 syncimagepixels = 3
14764 CODE:
14765 {
14766 ExceptionInfo
14767 *exception;
14768
14769 Image
14770 *image;
14771
14772 MagickBooleanType
14773 status;
14774
14775 struct PackageInfo
14776 *info;
14777
14778 SV
14779 *perl_exception,
14780 *reference;
14781
14782 PERL_UNUSED_VAR(ref);
14783 PERL_UNUSED_VAR(ix);
14784 exception=AcquireExceptionInfo();
14785 perl_exception=newSVpv("",0);
14786 if (sv_isobject(ST(0)) == 0)
14787 {
14788 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14789 PackageName);
14790 goto PerlException;
14791 }
14792
14793 reference=SvRV(ST(0));
14794 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14795 if (image == (Image *) NULL)
14796 {
14797 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14798 PackageName);
14799 goto PerlException;
14800 }
14801
14802 status=SyncAuthenticPixels(image,exception);
14803 if (status != MagickFalse)
14804 return;
14805
14806 PerlException:
14807 InheritPerlException(exception,perl_exception);
14808 exception=DestroyExceptionInfo(exception);
14809 SvREFCNT_dec(perl_exception); /* throw away all errors */
14810 }
14811
14812#
14813###############################################################################
14814# #
14815# #
14816# #
cristy4a3ce0a2013-08-03 20:06:59 +000014817# W r i t e #
14818# #
14819# #
14820# #
14821###############################################################################
14822#
14823#
14824void
14825Write(ref,...)
14826 Image::Magick ref=NO_INIT
14827 ALIAS:
14828 WriteImage = 1
14829 write = 2
14830 writeimage = 3
14831 PPCODE:
14832 {
14833 char
cristy151b66d2015-04-15 10:50:31 +000014834 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014835
14836 ExceptionInfo
14837 *exception;
14838
14839 Image
14840 *image,
14841 *next;
14842
14843 register ssize_t
14844 i;
14845
14846 ssize_t
14847 number_images,
14848 scene;
14849
14850 struct PackageInfo
14851 *info,
14852 *package_info;
14853
14854 SV
14855 *perl_exception,
14856 *reference;
14857
14858 PERL_UNUSED_VAR(ref);
14859 PERL_UNUSED_VAR(ix);
14860 exception=AcquireExceptionInfo();
14861 perl_exception=newSVpv("",0);
14862 number_images=0;
14863 package_info=(struct PackageInfo *) NULL;
14864 if (sv_isobject(ST(0)) == 0)
14865 {
14866 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14867 PackageName);
14868 goto PerlException;
14869 }
14870 reference=SvRV(ST(0));
14871 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14872 if (image == (Image *) NULL)
14873 {
14874 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14875 PackageName);
14876 goto PerlException;
14877 }
Cristyb4ee45c2017-09-27 17:58:55 -040014878 scene=0;
14879 for (next=image; next; next=next->next)
14880 next->scene=scene++;
cristy4a3ce0a2013-08-03 20:06:59 +000014881 package_info=ClonePackageInfo(info,exception);
14882 if (items == 2)
14883 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14884 else
14885 if (items > 2)
14886 for (i=2; i < items; i+=2)
14887 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14888 exception);
14889 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014890 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014891 for (next=image; next; next=next->next)
cristy151b66d2015-04-15 10:50:31 +000014892 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy68bd79a2015-02-25 12:23:36 +000014893 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014894 SetImageInfo(package_info->image_info,(unsigned int)
14895 GetImageListLength(image),exception);
14896 for (next=image; next; next=next->next)
14897 {
14898 (void) WriteImage(package_info->image_info,next,exception);
14899 number_images++;
14900 if (package_info->image_info->adjoin)
14901 break;
14902 }
14903
14904 PerlException:
14905 if (package_info != (struct PackageInfo *) NULL)
14906 DestroyPackageInfo(package_info);
14907 InheritPerlException(exception,perl_exception);
14908 exception=DestroyExceptionInfo(exception);
14909 sv_setiv(perl_exception,(IV) number_images);
14910 SvPOK_on(perl_exception);
14911 ST(0)=sv_2mortal(perl_exception);
14912 XSRETURN(1);
14913 }