blob: edc0c3dc53560218a3e19db6454011b4e0c61ffc [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% %
Cristyf6ff9ea2016-12-05 09:53:35 -050026% Copyright 1999-2017 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{
145 ArrayReference = (~0),
146 RealReference = (~0)-1,
147 FileReference = (~0)-2,
148 ImageReference = (~0)-3,
149 IntegerReference = (~0)-4,
150 StringReference = (~0)-5
151} MagickReference;
152
153typedef struct _Arguments
154{
155 const char
156 *method;
157
158 ssize_t
159 type;
160} Arguments;
161
162struct ArgumentList
163{
164 ssize_t
165 integer_reference;
166
167 double
168 real_reference;
169
170 const char
171 *string_reference;
172
173 Image
174 *image_reference;
175
176 SV
177 *array_reference;
178
179 FILE
180 *file_reference;
181
182 size_t
183 length;
184};
185
186struct PackageInfo
187{
188 ImageInfo
189 *image_info;
190};
191
192typedef void
193 *Image__Magick; /* data type for the Image::Magick package */
194
195/*
196 Static declarations.
197*/
198static struct
199 Methods
200 {
201 const char
202 *name;
203
204 Arguments
205 arguments[MaxArguments];
206 } Methods[] =
207 {
208 { "Comment", { {"comment", StringReference} } },
209 { "Label", { {"label", StringReference} } },
210 { "AddNoise", { {"noise", MagickNoiseOptions}, {"attenuate", RealReference},
211 {"channel", MagickChannelOptions} } },
212 { "Colorize", { {"fill", StringReference}, {"blend", StringReference} } },
213 { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
214 {"height", IntegerReference}, {"fill", StringReference},
215 {"bordercolor", StringReference}, {"color", StringReference},
216 {"compose", MagickComposeOptions} } },
217 { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
218 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
219 { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
220 {"height", IntegerReference}, {"x", IntegerReference},
cristy260bd762014-08-15 12:46:34 +0000221 {"y", IntegerReference}, {"gravity", MagickGravityOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000222 { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
223 {"height", IntegerReference}, {"x", IntegerReference},
224 {"y", IntegerReference}, {"fuzz", StringReference},
225 {"gravity", MagickGravityOptions} } },
226 { "Despeckle", },
227 { "Edge", { {"radius", RealReference} } },
228 { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
229 {"sigma", RealReference} } },
230 { "Enhance", },
231 { "Flip", },
232 { "Flop", },
233 { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
234 {"height", IntegerReference}, {"inner", IntegerReference},
235 {"outer", IntegerReference}, {"fill", StringReference},
236 {"color", StringReference}, {"compose", MagickComposeOptions} } },
237 { "Implode", { {"amount", RealReference},
238 {"interpolate", MagickInterpolateOptions} } },
239 { "Magnify", },
240 { "MedianFilter", { {"geometry", StringReference},
241 {"width", IntegerReference}, {"height", IntegerReference},
242 {"channel", MagickChannelOptions} } },
243 { "Minify", },
244 { "OilPaint", { {"radius", RealReference}, {"sigma", RealReference} } },
245 { "ReduceNoise", { {"geometry", StringReference},
246 {"width", IntegerReference},{"height", IntegerReference},
247 {"channel", MagickChannelOptions} } },
248 { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
249 {"y", IntegerReference} } },
cristy83a28a02013-08-03 20:25:48 +0000250 { "Rotate", { {"degrees", RealReference},
cristy4a3ce0a2013-08-03 20:06:59 +0000251 {"background", StringReference} } },
252 { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
253 {"height", IntegerReference} } },
254 { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
255 {"height", IntegerReference} } },
256 { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
257 {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
258 { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
259 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
260 { "Shear", { {"geometry", StringReference}, {"x", RealReference},
261 {"y", RealReference}, { "fill", StringReference},
262 {"color", StringReference} } },
Cristye3319c12015-08-24 07:11:48 -0400263 { "Spread", { {"radius", RealReference},
Cristy3ca633e2016-02-13 12:49:01 -0500264 {"interpolate", MagickInterpolateOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000265 { "Swirl", { {"degrees", RealReference},
266 {"interpolate", MagickInterpolateOptions} } },
267 { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
268 {"height", IntegerReference}, {"filter", MagickFilterOptions},
269 {"support", StringReference } } },
270 { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
271 {"height", IntegerReference}, {"filter", MagickFilterOptions},
272 {"support", RealReference } } },
273 { "Annotate", { {"text", StringReference}, {"font", StringReference},
274 {"pointsize", RealReference}, {"density", StringReference},
275 {"undercolor", StringReference}, {"stroke", StringReference},
276 {"fill", StringReference}, {"geometry", StringReference},
277 {"sans", StringReference}, {"x", RealReference},
278 {"y", RealReference}, {"gravity", MagickGravityOptions},
279 {"translate", StringReference}, {"scale", StringReference},
280 {"rotate", RealReference}, {"skewX", RealReference},
281 {"skewY", RealReference}, {"strokewidth", RealReference},
282 {"antialias", MagickBooleanOptions}, {"family", StringReference},
283 {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
284 {"weight", IntegerReference}, {"align", MagickAlignOptions},
285 {"encoding", StringReference}, {"affine", ArrayReference},
286 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
287 {"tile", ImageReference}, {"kerning", RealReference},
288 {"interline-spacing", RealReference},
289 {"interword-spacing", RealReference},
290 {"direction", MagickDirectionOptions} } },
291 { "ColorFloodfill", { {"geometry", StringReference},
292 {"x", IntegerReference}, {"y", IntegerReference},
293 {"fill", StringReference}, {"bordercolor", StringReference},
294 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
295 { "Composite", { {"image", ImageReference},
296 {"compose", MagickComposeOptions}, {"geometry", StringReference},
297 {"x", IntegerReference}, {"y", IntegerReference},
298 {"gravity", MagickGravityOptions}, {"opacity", StringReference},
299 {"tile", MagickBooleanOptions}, {"rotate", RealReference},
300 {"color", StringReference}, {"mask", ImageReference},
301 {"channel", MagickChannelOptions},
302 {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
303 {"blend", StringReference}, {"crop-to-self", MagickBooleanOptions} } },
304 { "Contrast", { {"sharpen", MagickBooleanOptions} } },
305 { "CycleColormap", { {"display", IntegerReference} } },
306 { "Draw", { {"primitive", MagickPrimitiveOptions},
307 {"points", StringReference}, {"method", MagickMethodOptions},
308 {"stroke", StringReference}, {"fill", StringReference},
309 {"strokewidth", RealReference}, {"font", StringReference},
310 {"bordercolor", StringReference}, {"x", RealReference},
311 {"y", RealReference}, {"translate", StringReference},
312 {"scale", StringReference}, {"rotate", RealReference},
313 {"skewX", RealReference}, {"skewY", RealReference},
314 {"tile", ImageReference}, {"pointsize", RealReference},
315 {"antialias", MagickBooleanOptions}, {"density", StringReference},
316 {"linewidth", RealReference}, {"affine", ArrayReference},
317 {"stroke-dashoffset", RealReference},
318 {"stroke-dasharray", ArrayReference},
319 {"interpolate", MagickInterpolateOptions},
320 {"origin", StringReference}, {"text", StringReference},
321 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
322 {"vector-graphics", StringReference}, {"kerning", RealReference},
323 {"interline-spacing", RealReference},
324 {"interword-spacing", RealReference},
325 {"direction", MagickDirectionOptions} } },
326 { "Equalize", { {"channel", MagickChannelOptions} } },
327 { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
328 {"red", RealReference}, {"green", RealReference},
329 {"blue", RealReference} } },
330 { "Map", { {"image", ImageReference},
331 {"dither-method", MagickDitherOptions} } },
332 { "MatteFloodfill", { {"geometry", StringReference},
333 {"x", IntegerReference}, {"y", IntegerReference},
334 {"opacity", StringReference}, {"bordercolor", StringReference},
335 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
336 { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
337 {"saturation", RealReference}, {"whiteness", RealReference},
338 {"brightness", RealReference}, {"lightness", RealReference},
339 {"blackness", RealReference} } },
340 { "Negate", { {"gray", MagickBooleanOptions},
341 {"channel", MagickChannelOptions} } },
342 { "Normalize", { {"channel", MagickChannelOptions} } },
343 { "NumberColors", },
344 { "Opaque", { {"color", StringReference}, {"fill", StringReference},
345 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
346 {"invert", MagickBooleanOptions} } },
347 { "Quantize", { {"colors", IntegerReference},
348 {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
349 {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
350 {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
351 {"dither-method", MagickDitherOptions} } },
352 { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
353 {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
354 { "Segment", { {"geometry", StringReference},
355 {"cluster-threshold", RealReference},
356 {"smoothing-threshold", RealReference},
357 {"colorspace", MagickColorspaceOptions},
358 {"verbose", MagickBooleanOptions} } },
359 { "Signature", },
360 { "Solarize", { {"geometry", StringReference},
361 {"threshold", StringReference} } },
362 { "Sync", },
363 { "Texture", { {"texture", ImageReference} } },
364 { "Evaluate", { {"value", RealReference},
365 {"operator", MagickEvaluateOptions},
366 {"channel", MagickChannelOptions} } },
367 { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
368 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
369 { "Threshold", { {"threshold", StringReference},
370 {"channel", MagickChannelOptions} } },
371 { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
372 {"sigma", RealReference} } },
373 { "Trim", { {"fuzz", StringReference} } },
374 { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
375 {"wavelength", RealReference},
376 {"interpolate", MagickInterpolateOptions} } },
377 { "Separate", { {"channel", MagickChannelOptions} } },
378 { "Condense", },
379 { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
380 {"y", IntegerReference} } },
381 { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
382 { "Deconstruct", },
383 { "GaussianBlur", { {"geometry", StringReference},
384 {"radius", RealReference}, {"sigma", RealReference},
385 {"channel", MagickChannelOptions} } },
386 { "Convolve", { {"coefficients", ArrayReference},
387 {"channel", MagickChannelOptions}, {"bias", StringReference},
388 {"kernel", StringReference} } },
389 { "Profile", { {"name", StringReference}, {"profile", StringReference},
390 { "rendering-intent", MagickIntentOptions},
391 { "black-point-compensation", MagickBooleanOptions} } },
392 { "UnsharpMask", { {"geometry", StringReference},
393 {"radius", RealReference}, {"sigma", RealReference},
394 {"gain", RealReference}, {"threshold", RealReference},
395 {"channel", MagickChannelOptions} } },
396 { "MotionBlur", { {"geometry", StringReference},
397 {"radius", RealReference}, {"sigma", RealReference},
398 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
399 { "OrderedDither", { {"threshold", StringReference},
400 {"channel", MagickChannelOptions} } },
401 { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
402 {"height", IntegerReference} } },
403 { "Level", { {"levels", StringReference}, {"black-point", RealReference},
404 {"white-point", RealReference}, {"gamma", RealReference},
405 {"channel", MagickChannelOptions}, {"level", StringReference} } },
406 { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
407 { "AffineTransform", { {"affine", ArrayReference},
408 {"translate", StringReference}, {"scale", StringReference},
409 {"rotate", RealReference}, {"skewX", RealReference},
410 {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
411 {"background", StringReference} } },
412 { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
413 { "AdaptiveThreshold", { {"geometry", StringReference},
414 {"width", IntegerReference}, {"height", IntegerReference} } },
415 { "Resample", { {"density", StringReference}, {"x", RealReference},
416 {"y", RealReference}, {"filter", MagickFilterOptions},
417 {"support", RealReference } } },
418 { "Describe", { {"file", FileReference} } },
419 { "BlackThreshold", { {"threshold", StringReference},
420 {"channel", MagickChannelOptions} } },
421 { "WhiteThreshold", { {"threshold", StringReference},
422 {"channel", MagickChannelOptions} } },
cristy60c73c02014-03-25 12:09:58 +0000423 { "RotationalBlur", { {"geometry", StringReference},
424 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000425 { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
426 {"height", IntegerReference} } },
427 { "Strip", },
428 { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
429 { "Channel", { {"channel", MagickChannelOptions} } },
430 { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
431 {"height", IntegerReference}, {"x", IntegerReference},
432 {"y", IntegerReference}, {"fuzz", StringReference},
433 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
434 { "Posterize", { {"levels", IntegerReference},
435 {"dither", MagickBooleanOptions} } },
436 { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
437 {"sigma", RealReference}, {"x", IntegerReference},
438 {"y", IntegerReference} } },
439 { "Identify", { {"file", FileReference}, {"features", StringReference},
440 {"unique", MagickBooleanOptions} } },
441 { "SepiaTone", { {"threshold", RealReference} } },
442 { "SigmoidalContrast", { {"geometry", StringReference},
443 {"contrast", RealReference}, {"mid-point", RealReference},
444 {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
445 { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
446 {"height", IntegerReference}, {"x", IntegerReference},
447 {"y", IntegerReference}, {"fuzz", StringReference},
448 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
449 { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
450 {"sigma", RealReference}, {"x", IntegerReference},
451 {"y", IntegerReference}, {"background", StringReference} } },
452 { "ContrastStretch", { {"levels", StringReference},
453 {"black-point", RealReference},{"white-point", RealReference},
454 {"channel", MagickChannelOptions} } },
455 { "Sans0", },
456 { "Sans1", },
457 { "AdaptiveSharpen", { {"geometry", StringReference},
458 {"radius", RealReference}, {"sigma", RealReference},
459 {"bias", RealReference}, {"channel", MagickChannelOptions} } },
460 { "Transpose", },
461 { "Transverse", },
462 { "AutoOrient", },
463 { "AdaptiveBlur", { {"geometry", StringReference},
464 {"radius", RealReference}, {"sigma", RealReference},
465 {"channel", MagickChannelOptions} } },
466 { "Sketch", { {"geometry", StringReference},
467 {"radius", RealReference}, {"sigma", RealReference},
468 {"angle", RealReference} } },
469 { "UniqueColors", },
470 { "AdaptiveResize", { {"geometry", StringReference},
471 {"width", IntegerReference}, {"height", IntegerReference},
472 {"filter", MagickFilterOptions}, {"support", StringReference },
473 {"blur", RealReference } } },
474 { "ClipMask", { {"mask", ImageReference} } },
475 { "LinearStretch", { {"levels", StringReference},
476 {"black-point", RealReference},{"white-point", RealReference} } },
477 { "ColorMatrix", { {"matrix", ArrayReference} } },
478 { "Mask", { {"mask", ImageReference} } },
479 { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
480 {"font", StringReference}, {"stroke", StringReference},
481 {"fill", StringReference}, {"strokewidth", RealReference},
482 {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
483 {"background", StringReference},
484 {"interpolate", MagickInterpolateOptions} } },
485 { "FloodfillPaint", { {"geometry", StringReference},
486 {"x", IntegerReference}, {"y", IntegerReference},
487 {"fill", StringReference}, {"bordercolor", StringReference},
488 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
489 {"invert", MagickBooleanOptions} } },
490 { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
491 {"virtual-pixel", MagickVirtualPixelOptions},
492 {"best-fit", MagickBooleanOptions} } },
493 { "Clut", { {"image", ImageReference},
494 {"interpolate", MagickInterpolateOptions},
495 {"channel", MagickChannelOptions} } },
496 { "LiquidRescale", { {"geometry", StringReference},
497 {"width", IntegerReference}, {"height", IntegerReference},
498 {"delta-x", RealReference}, {"rigidity", RealReference } } },
499 { "Encipher", { {"passphrase", StringReference} } },
500 { "Decipher", { {"passphrase", StringReference} } },
501 { "Deskew", { {"geometry", StringReference},
502 {"threshold", StringReference} } },
503 { "Remap", { {"image", ImageReference},
504 {"dither-method", MagickDitherOptions} } },
505 { "SparseColor", { {"points", ArrayReference},
506 {"method", MagickSparseColorOptions},
507 {"virtual-pixel", MagickVirtualPixelOptions},
508 {"channel", MagickChannelOptions} } },
509 { "Function", { {"parameters", ArrayReference},
510 {"function", MagickFunctionOptions},
511 {"virtual-pixel", MagickVirtualPixelOptions} } },
512 { "SelectiveBlur", { {"geometry", StringReference},
513 {"radius", RealReference}, {"sigma", RealReference},
514 {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
515 { "HaldClut", { {"image", ImageReference},
516 {"channel", MagickChannelOptions} } },
517 { "BlueShift", { {"factor", StringReference} } },
518 { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
519 { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
520 { "ColorDecisionList", {
521 {"color-correction-collection", StringReference} } },
522 { "AutoGamma", { {"channel", MagickChannelOptions} } },
523 { "AutoLevel", { {"channel", MagickChannelOptions} } },
524 { "LevelColors", { {"invert", MagickBooleanOptions},
525 {"black-point", StringReference}, {"white-point", StringReference},
526 {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
527 { "Clamp", { {"channel", MagickChannelOptions} } },
528 { "BrightnessContrast", { {"levels", StringReference},
529 {"brightness", RealReference},{"contrast", RealReference},
530 {"channel", MagickChannelOptions} } },
531 { "Morphology", { {"kernel", StringReference},
532 {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
533 {"iterations", IntegerReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000534 { "Mode", { {"geometry", StringReference},
535 {"width", IntegerReference},{"height", IntegerReference},
536 {"channel", MagickChannelOptions} } },
537 { "Statistic", { {"geometry", StringReference},
538 {"width", IntegerReference},{"height", IntegerReference},
539 {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
540 { "Perceptible", { {"epsilon", RealReference},
541 {"channel", MagickChannelOptions} } },
542 { "Poly", { {"terms", ArrayReference},
543 {"channel", MagickChannelOptions} } },
544 { "Grayscale", { {"method", MagickNoiseOptions} } },
cristy4ceadb82014-03-29 15:30:43 +0000545 { "CannyEdge", { {"geometry", StringReference},
546 {"radius", RealReference}, {"sigma", RealReference},
cristycfe7bf02014-04-04 15:31:52 +0000547 {"lower-percent", RealReference}, {"upper-percent", RealReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000548 { "HoughLine", { {"geometry", StringReference},
cristy4e215022014-04-19 18:02:35 +0000549 {"width", IntegerReference}, {"height", IntegerReference},
550 {"threshold", IntegerReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000551 { "MeanShift", { {"geometry", StringReference},
552 {"width", IntegerReference}, {"height", IntegerReference},
cristy1309fc32014-04-26 18:48:37 +0000553 {"distance", RealReference} } },
cristy3b207f82014-09-27 14:21:20 +0000554 { "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
555 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
Cristy2ca0e9a2016-01-01 08:36:14 -0500556 { "ConnectedComponents", { {"connectivity", IntegerReference} } },
cristyf3a724a2015-06-25 13:02:53 +0000557 { "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
558 {"width", IntegerReference}, {"height", IntegerReference},
559 {"x", IntegerReference}, {"y", IntegerReference},
560 {"gravity", MagickGravityOptions}, {"offset", StringReference},
561 {"dx", IntegerReference}, {"dy", IntegerReference} } },
Cristy5488c982016-02-13 14:07:50 -0500562 { "Color", { {"color", StringReference} } },
Cristyc1759412016-02-27 12:17:58 -0500563 { "WaveletDenoise", { {"geometry", StringReference},
564 {"threshold", RealReference}, {"softness", RealReference},
Cristy2d830ed2016-02-21 10:54:16 -0500565 {"channel", MagickChannelOptions} } },
Cristy99a57162016-12-05 11:47:57 -0500566 { "Colorspace", { {"colorspace", MagickColorspaceOptions} } },
Cristy53353872017-07-02 12:24:24 -0400567 { "AutoThreshold", { {"method", MagickAutoThresholdOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000568 };
569
570static SplayTreeInfo
571 *magick_registry = (SplayTreeInfo *) NULL;
572
573/*
574 Forward declarations.
575*/
576static Image
577 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
578
579static ssize_t
580 strEQcase(const char *,const char *);
581
582/*
583%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
584% %
585% %
586% %
587% C l o n e P a c k a g e I n f o %
588% %
589% %
590% %
591%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
592%
593% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
594% a new one.
595%
596% The format of the ClonePackageInfo routine is:
597%
598% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
599% exception)
600%
601% A description of each parameter follows:
602%
603% o info: a structure of type info.
604%
605% o exception: Return any errors or warnings in this structure.
606%
607*/
608static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
609 ExceptionInfo *exception)
610{
611 struct PackageInfo
612 *clone_info;
613
614 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
615 if (clone_info == (struct PackageInfo *) NULL)
616 {
617 ThrowPerlException(exception,ResourceLimitError,
618 "UnableToClonePackageInfo",PackageName);
619 return((struct PackageInfo *) NULL);
620 }
621 if (info == (struct PackageInfo *) NULL)
622 {
623 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
624 return(clone_info);
625 }
626 *clone_info=(*info);
627 clone_info->image_info=CloneImageInfo(info->image_info);
628 return(clone_info);
629}
630
631/*
632%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
633% %
634% %
635% %
636% c o n s t a n t %
637% %
638% %
639% %
640%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
641%
642% constant() returns a double value for the specified name.
643%
644% The format of the constant routine is:
645%
646% double constant(char *name,ssize_t sans)
647%
648% A description of each parameter follows:
649%
650% o value: Method constant returns a double value for the specified name.
651%
652% o name: The name of the constant.
653%
654% o sans: This integer value is not used.
655%
656*/
657static double constant(char *name,ssize_t sans)
658{
659 (void) sans;
660 errno=0;
661 switch (*name)
662 {
663 case 'B':
664 {
665 if (strEQ(name,"BlobError"))
666 return(BlobError);
667 if (strEQ(name,"BlobWarning"))
668 return(BlobWarning);
669 break;
670 }
671 case 'C':
672 {
673 if (strEQ(name,"CacheError"))
674 return(CacheError);
675 if (strEQ(name,"CacheWarning"))
676 return(CacheWarning);
677 if (strEQ(name,"CoderError"))
678 return(CoderError);
679 if (strEQ(name,"CoderWarning"))
680 return(CoderWarning);
681 if (strEQ(name,"ConfigureError"))
682 return(ConfigureError);
683 if (strEQ(name,"ConfigureWarning"))
684 return(ConfigureWarning);
685 if (strEQ(name,"CorruptImageError"))
686 return(CorruptImageError);
687 if (strEQ(name,"CorruptImageWarning"))
688 return(CorruptImageWarning);
689 break;
690 }
691 case 'D':
692 {
693 if (strEQ(name,"DelegateError"))
694 return(DelegateError);
695 if (strEQ(name,"DelegateWarning"))
696 return(DelegateWarning);
697 if (strEQ(name,"DrawError"))
698 return(DrawError);
699 if (strEQ(name,"DrawWarning"))
700 return(DrawWarning);
701 break;
702 }
703 case 'E':
704 {
705 if (strEQ(name,"ErrorException"))
706 return(ErrorException);
707 if (strEQ(name,"ExceptionError"))
708 return(CoderError);
709 if (strEQ(name,"ExceptionWarning"))
710 return(CoderWarning);
711 break;
712 }
713 case 'F':
714 {
715 if (strEQ(name,"FatalErrorException"))
716 return(FatalErrorException);
717 if (strEQ(name,"FileOpenError"))
718 return(FileOpenError);
719 if (strEQ(name,"FileOpenWarning"))
720 return(FileOpenWarning);
721 break;
722 }
723 case 'I':
724 {
725 if (strEQ(name,"ImageError"))
726 return(ImageError);
727 if (strEQ(name,"ImageWarning"))
728 return(ImageWarning);
729 break;
730 }
731 case 'M':
732 {
733 if (strEQ(name,"MaxRGB"))
734 return(QuantumRange);
735 if (strEQ(name,"MissingDelegateError"))
736 return(MissingDelegateError);
737 if (strEQ(name,"MissingDelegateWarning"))
738 return(MissingDelegateWarning);
739 if (strEQ(name,"ModuleError"))
740 return(ModuleError);
741 if (strEQ(name,"ModuleWarning"))
742 return(ModuleWarning);
743 break;
744 }
745 case 'O':
746 {
747 if (strEQ(name,"Opaque"))
748 return(OpaqueAlpha);
749 if (strEQ(name,"OptionError"))
750 return(OptionError);
751 if (strEQ(name,"OptionWarning"))
752 return(OptionWarning);
753 break;
754 }
755 case 'Q':
756 {
757 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
758 return(MAGICKCORE_QUANTUM_DEPTH);
759 if (strEQ(name,"QuantumDepth"))
760 return(MAGICKCORE_QUANTUM_DEPTH);
761 if (strEQ(name,"QuantumRange"))
762 return(QuantumRange);
763 break;
764 }
765 case 'R':
766 {
767 if (strEQ(name,"ResourceLimitError"))
768 return(ResourceLimitError);
769 if (strEQ(name,"ResourceLimitWarning"))
770 return(ResourceLimitWarning);
771 if (strEQ(name,"RegistryError"))
772 return(RegistryError);
773 if (strEQ(name,"RegistryWarning"))
774 return(RegistryWarning);
775 break;
776 }
777 case 'S':
778 {
779 if (strEQ(name,"StreamError"))
780 return(StreamError);
781 if (strEQ(name,"StreamWarning"))
782 return(StreamWarning);
783 if (strEQ(name,"Success"))
784 return(0);
785 break;
786 }
787 case 'T':
788 {
789 if (strEQ(name,"Transparent"))
790 return(TransparentAlpha);
791 if (strEQ(name,"TypeError"))
792 return(TypeError);
793 if (strEQ(name,"TypeWarning"))
794 return(TypeWarning);
795 break;
796 }
797 case 'W':
798 {
799 if (strEQ(name,"WarningException"))
800 return(WarningException);
801 break;
802 }
803 case 'X':
804 {
805 if (strEQ(name,"XServerError"))
806 return(XServerError);
807 if (strEQ(name,"XServerWarning"))
808 return(XServerWarning);
809 break;
810 }
811 }
812 errno=EINVAL;
813 return(0);
814}
815
816/*
817%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
818% %
819% %
820% %
821% D e s t r o y P a c k a g e I n f o %
822% %
823% %
824% %
825%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
826%
827% Method DestroyPackageInfo frees a previously created info structure.
828%
829% The format of the DestroyPackageInfo routine is:
830%
831% DestroyPackageInfo(struct PackageInfo *info)
832%
833% A description of each parameter follows:
834%
835% o info: a structure of type info.
836%
837*/
838static void DestroyPackageInfo(struct PackageInfo *info)
839{
840 info->image_info=DestroyImageInfo(info->image_info);
841 info=(struct PackageInfo *) RelinquishMagickMemory(info);
842}
843
844/*
845%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
846% %
847% %
848% %
849% G e t L i s t %
850% %
851% %
852% %
853%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
854%
855% Method GetList is recursively called by SetupList to traverse the
856% Image__Magick reference. If building an reference_vector (see SetupList),
857% *current is the current position in *reference_vector and *last is the final
858% entry in *reference_vector.
859%
860% The format of the GetList routine is:
861%
862% GetList(info)
863%
864% A description of each parameter follows:
865%
866% o info: a structure of type info.
867%
868*/
869static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
870 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
871{
872 Image
873 *image;
874
875 if (reference == (SV *) NULL)
876 return(NULL);
877 switch (SvTYPE(reference))
878 {
879 case SVt_PVAV:
880 {
881 AV
882 *av;
883
884 Image
885 *head,
886 *previous;
887
888 register ssize_t
889 i;
890
891 ssize_t
892 n;
893
894 /*
895 Array of images.
896 */
897 previous=(Image *) NULL;
898 head=(Image *) NULL;
899 av=(AV *) reference;
900 n=av_len(av);
901 for (i=0; i <= n; i++)
902 {
903 SV
904 **rv;
905
906 rv=av_fetch(av,i,0);
907 if (rv && *rv && sv_isobject(*rv))
908 {
909 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
910 exception);
911 if (image == (Image *) NULL)
912 continue;
913 if (image == previous)
914 {
915 image=CloneImage(image,0,0,MagickTrue,exception);
916 if (image == (Image *) NULL)
917 return(NULL);
918 }
919 image->previous=previous;
920 *(previous ? &previous->next : &head)=image;
921 for (previous=image; previous->next; previous=previous->next) ;
922 }
923 }
924 return(head);
925 }
926 case SVt_PVMG:
927 {
928 /*
929 Blessed scalar, one image.
930 */
931 image=INT2PTR(Image *,SvIV(reference));
932 if (image == (Image *) NULL)
933 return(NULL);
934 image->previous=(Image *) NULL;
935 image->next=(Image *) NULL;
936 if (reference_vector)
937 {
938 if (*current == *last)
939 {
940 *last+=256;
941 if (*reference_vector == (SV **) NULL)
942 *reference_vector=(SV **) AcquireQuantumMemory(*last,
943 sizeof(*reference_vector));
944 else
945 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
946 *last,sizeof(*reference_vector));
947 }
948 if (*reference_vector == (SV **) NULL)
949 {
950 ThrowPerlException(exception,ResourceLimitError,
951 "MemoryAllocationFailed",PackageName);
952 return((Image *) NULL);
953 }
954 (*reference_vector)[*current]=reference;
955 (*reference_vector)[++(*current)]=NULL;
956 }
957 return(image);
958 }
959 default:
960 break;
961 }
962 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
963 (double) SvTYPE(reference));
964 return((Image *) NULL);
965}
966
967/*
968%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
969% %
970% %
971% %
972% G e t P a c k a g e I n f o %
973% %
974% %
975% %
976%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
977%
978% Method GetPackageInfo looks up or creates an info structure for the given
979% Image__Magick reference. If it does create a new one, the information in
980% package_info is used to initialize it.
981%
982% The format of the GetPackageInfo routine is:
983%
984% struct PackageInfo *GetPackageInfo(void *reference,
985% struct PackageInfo *package_info,ExceptionInfo *exception)
986%
987% A description of each parameter follows:
988%
989% o info: a structure of type info.
990%
991% o exception: Return any errors or warnings in this structure.
992%
993*/
994static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
995 struct PackageInfo *package_info,ExceptionInfo *exception)
996{
997 char
cristy151b66d2015-04-15 10:50:31 +0000998 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +0000999
1000 struct PackageInfo
1001 *clone_info;
1002
1003 SV
1004 *sv;
1005
cristy151b66d2015-04-15 10:50:31 +00001006 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00001007 PackageName,XS_VERSION,reference);
1008 sv=perl_get_sv(message,(TRUE | 0x02));
1009 if (sv == (SV *) NULL)
1010 {
1011 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1012 message);
1013 return(package_info);
1014 }
1015 if (SvREFCNT(sv) == 0)
1016 (void) SvREFCNT_inc(sv);
1017 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1018 return(clone_info);
1019 clone_info=ClonePackageInfo(package_info,exception);
1020 sv_setiv(sv,PTR2IV(clone_info));
1021 return(clone_info);
1022}
1023
1024/*
1025%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1026% %
1027% %
1028% %
1029% S e t A t t r i b u t e %
1030% %
1031% %
1032% %
1033%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1034%
1035% SetAttribute() sets the attribute to the value in sval. This can change
1036% either or both of image or info.
1037%
1038% The format of the SetAttribute routine is:
1039%
1040% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1041% SV *sval,ExceptionInfo *exception)
1042%
1043% A description of each parameter follows:
1044%
1045% o list: a list of strings.
1046%
1047% o string: a character string.
1048%
1049*/
1050
1051static double SiPrefixToDoubleInterval(const char *string,const double interval)
1052{
1053 char
1054 *q;
1055
1056 double
1057 value;
1058
1059 value=InterpretSiPrefixValue(string,&q);
1060 if (*q == '%')
1061 value*=interval/100.0;
1062 return(value);
1063}
1064
1065static inline double StringToDouble(const char *string,char **sentinal)
1066{
1067 return(InterpretLocaleValue(string,sentinal));
1068}
1069
1070static double StringToDoubleInterval(const char *string,const double interval)
1071{
1072 char
1073 *q;
1074
1075 double
1076 value;
1077
1078 value=InterpretLocaleValue(string,&q);
1079 if (*q == '%')
1080 value*=interval/100.0;
1081 return(value);
1082}
1083
1084static inline ssize_t StringToLong(const char *value)
1085{
1086 return(strtol(value,(char **) NULL,10));
1087}
1088
1089static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1090 const char *attribute,SV *sval,ExceptionInfo *exception)
1091{
1092 GeometryInfo
1093 geometry_info;
1094
1095 long
1096 x,
1097 y;
1098
1099 PixelInfo
1100 pixel;
1101
1102 MagickStatusType
1103 flags;
1104
1105 PixelInfo
1106 *color,
1107 target_color;
1108
1109 ssize_t
1110 sp;
1111
1112 switch (*attribute)
1113 {
1114 case 'A':
1115 case 'a':
1116 {
1117 if (LocaleCompare(attribute,"adjoin") == 0)
1118 {
1119 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1120 SvPV(sval,na)) : SvIV(sval);
1121 if (sp < 0)
1122 {
1123 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1124 SvPV(sval,na));
1125 break;
1126 }
1127 if (info)
1128 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1129 break;
1130 }
1131 if (LocaleCompare(attribute,"alpha") == 0)
1132 {
1133 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1134 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1135 if (sp < 0)
1136 {
1137 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1138 SvPV(sval,na));
1139 break;
1140 }
1141 for ( ; image; image=image->next)
1142 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1143 exception);
1144 break;
1145 }
1146 if (LocaleCompare(attribute,"antialias") == 0)
1147 {
1148 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1149 SvPV(sval,na)) : SvIV(sval);
1150 if (sp < 0)
1151 {
1152 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1153 SvPV(sval,na));
1154 break;
1155 }
1156 if (info)
1157 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1158 break;
1159 }
1160 if (LocaleCompare(attribute,"area-limit") == 0)
1161 {
1162 MagickSizeType
1163 limit;
1164
1165 limit=MagickResourceInfinity;
1166 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1167 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1168 100.0);
1169 (void) SetMagickResourceLimit(AreaResource,limit);
1170 break;
1171 }
1172 if (LocaleCompare(attribute,"attenuate") == 0)
1173 {
1174 if (info)
1175 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1176 break;
1177 }
1178 if (LocaleCompare(attribute,"authenticate") == 0)
1179 {
1180 if (info)
1181 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1182 break;
1183 }
1184 if (info)
1185 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1186 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001187 {
1188 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstra337c9bc2017-04-03 16:04:21 +02001189 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001190 }
cristy4a3ce0a2013-08-03 20:06:59 +00001191 break;
1192 }
1193 case 'B':
1194 case 'b':
1195 {
1196 if (LocaleCompare(attribute,"background") == 0)
1197 {
1198 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1199 exception);
1200 if (info)
1201 info->image_info->background_color=target_color;
1202 for ( ; image; image=image->next)
1203 image->background_color=target_color;
1204 break;
1205 }
1206 if (LocaleCompare(attribute,"blue-primary") == 0)
1207 {
1208 for ( ; image; image=image->next)
1209 {
1210 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1211 image->chromaticity.blue_primary.x=geometry_info.rho;
1212 image->chromaticity.blue_primary.y=geometry_info.sigma;
1213 if ((flags & SigmaValue) == 0)
1214 image->chromaticity.blue_primary.y=
1215 image->chromaticity.blue_primary.x;
1216 }
1217 break;
1218 }
1219 if (LocaleCompare(attribute,"bordercolor") == 0)
1220 {
1221 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1222 exception);
1223 if (info)
1224 info->image_info->border_color=target_color;
1225 for ( ; image; image=image->next)
1226 image->border_color=target_color;
1227 break;
1228 }
1229 if (info)
1230 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1231 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001232 {
1233 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001234 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001235 }
cristy4a3ce0a2013-08-03 20:06:59 +00001236 break;
1237 }
1238 case 'C':
1239 case 'c':
1240 {
1241 if (LocaleCompare(attribute,"cache-threshold") == 0)
1242 {
1243 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1244 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1245 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1246 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1247 break;
1248 }
1249 if (LocaleCompare(attribute,"clip-mask") == 0)
1250 {
1251 Image
1252 *clip_mask;
1253
1254 clip_mask=(Image *) NULL;
1255 if (SvPOK(sval))
1256 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1257 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001258 SetImageMask(image,ReadPixelMask,clip_mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001259 break;
1260 }
1261 if (LocaleNCompare(attribute,"colormap",8) == 0)
1262 {
1263 for ( ; image; image=image->next)
1264 {
1265 int
1266 items;
1267
1268 long
1269 i;
1270
1271 if (image->storage_class == DirectClass)
1272 continue;
1273 i=0;
1274 items=sscanf(attribute,"%*[^[][%ld",&i);
1275 (void) items;
1276 if (i > (ssize_t) image->colors)
1277 i%=image->colors;
1278 if ((strchr(SvPV(sval,na),',') == 0) ||
1279 (strchr(SvPV(sval,na),')') != 0))
1280 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1281 image->colormap+i,exception);
1282 else
1283 {
1284 color=image->colormap+i;
1285 pixel.red=color->red;
1286 pixel.green=color->green;
1287 pixel.blue=color->blue;
1288 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1289 pixel.red=geometry_info.rho;
1290 pixel.green=geometry_info.sigma;
1291 pixel.blue=geometry_info.xi;
1292 color->red=ClampToQuantum(pixel.red);
1293 color->green=ClampToQuantum(pixel.green);
1294 color->blue=ClampToQuantum(pixel.blue);
1295 }
1296 }
1297 break;
1298 }
1299 if (LocaleCompare(attribute,"colorspace") == 0)
1300 {
1301 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1302 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1303 if (sp < 0)
1304 {
1305 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1306 SvPV(sval,na));
1307 break;
1308 }
1309 for ( ; image; image=image->next)
Cristy59262d92016-12-05 15:21:50 -05001310 (void) SetImageColorspace(image,(ColorspaceType) sp,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001311 break;
1312 }
1313 if (LocaleCompare(attribute,"comment") == 0)
1314 {
1315 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001316 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001317 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001318 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001319 break;
1320 }
1321 if (LocaleCompare(attribute,"compression") == 0)
1322 {
1323 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1324 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1325 if (sp < 0)
1326 {
1327 ThrowPerlException(exception,OptionError,
1328 "UnrecognizedImageCompression",SvPV(sval,na));
1329 break;
1330 }
1331 if (info)
1332 info->image_info->compression=(CompressionType) sp;
1333 for ( ; image; image=image->next)
1334 image->compression=(CompressionType) sp;
1335 break;
1336 }
1337 if (info)
1338 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1339 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001340 {
1341 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001342 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001343 }
cristy4a3ce0a2013-08-03 20:06:59 +00001344 break;
1345 }
1346 case 'D':
1347 case 'd':
1348 {
1349 if (LocaleCompare(attribute,"debug") == 0)
1350 {
1351 SetLogEventMask(SvPV(sval,na));
1352 break;
1353 }
1354 if (LocaleCompare(attribute,"delay") == 0)
1355 {
1356 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1357 for ( ; image; image=image->next)
1358 {
1359 image->delay=(size_t) floor(geometry_info.rho+0.5);
1360 if ((flags & SigmaValue) != 0)
1361 image->ticks_per_second=(ssize_t)
1362 floor(geometry_info.sigma+0.5);
1363 }
1364 break;
1365 }
1366 if (LocaleCompare(attribute,"disk-limit") == 0)
1367 {
1368 MagickSizeType
1369 limit;
1370
1371 limit=MagickResourceInfinity;
1372 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1373 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1374 100.0);
1375 (void) SetMagickResourceLimit(DiskResource,limit);
1376 break;
1377 }
1378 if (LocaleCompare(attribute,"density") == 0)
1379 {
1380 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1381 {
1382 ThrowPerlException(exception,OptionError,"MissingGeometry",
1383 SvPV(sval,na));
1384 break;
1385 }
1386 if (info)
1387 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1388 for ( ; image; image=image->next)
1389 {
1390 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1391 image->resolution.x=geometry_info.rho;
1392 image->resolution.y=geometry_info.sigma;
1393 if ((flags & SigmaValue) == 0)
1394 image->resolution.y=image->resolution.x;
1395 }
1396 break;
1397 }
1398 if (LocaleCompare(attribute,"depth") == 0)
1399 {
1400 if (info)
1401 info->image_info->depth=SvIV(sval);
1402 for ( ; image; image=image->next)
1403 (void) SetImageDepth(image,SvIV(sval),exception);
1404 break;
1405 }
1406 if (LocaleCompare(attribute,"dispose") == 0)
1407 {
1408 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1409 SvPV(sval,na)) : SvIV(sval);
1410 if (sp < 0)
1411 {
1412 ThrowPerlException(exception,OptionError,
1413 "UnrecognizedDisposeMethod",SvPV(sval,na));
1414 break;
1415 }
1416 for ( ; image; image=image->next)
1417 image->dispose=(DisposeType) sp;
1418 break;
1419 }
1420 if (LocaleCompare(attribute,"dither") == 0)
1421 {
1422 if (info)
1423 {
1424 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1425 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1426 if (sp < 0)
1427 {
1428 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1429 SvPV(sval,na));
1430 break;
1431 }
1432 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1433 }
1434 break;
1435 }
1436 if (LocaleCompare(attribute,"display") == 0)
1437 {
1438 display:
1439 if (info)
1440 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1441 break;
1442 }
1443 if (info)
1444 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1445 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001446 {
1447 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001448 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001449 }
cristy4a3ce0a2013-08-03 20:06:59 +00001450 break;
1451 }
1452 case 'E':
1453 case 'e':
1454 {
1455 if (LocaleCompare(attribute,"endian") == 0)
1456 {
1457 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1458 SvPV(sval,na)) : SvIV(sval);
1459 if (sp < 0)
1460 {
1461 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1462 SvPV(sval,na));
1463 break;
1464 }
1465 if (info)
1466 info->image_info->endian=(EndianType) sp;
1467 for ( ; image; image=image->next)
1468 image->endian=(EndianType) sp;
1469 break;
1470 }
1471 if (LocaleCompare(attribute,"extract") == 0)
1472 {
1473 /*
1474 Set image extract geometry.
1475 */
1476 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1477 break;
1478 }
1479 if (info)
1480 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1481 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001482 {
1483 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001484 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001485 }
cristy4a3ce0a2013-08-03 20:06:59 +00001486 break;
1487 }
1488 case 'F':
1489 case 'f':
1490 {
1491 if (LocaleCompare(attribute,"filename") == 0)
1492 {
1493 if (info)
1494 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001495 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001496 for ( ; image; image=image->next)
1497 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001498 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001499 break;
1500 }
1501 if (LocaleCompare(attribute,"file") == 0)
1502 {
1503 FILE
1504 *file;
1505
1506 PerlIO
1507 *io_info;
1508
1509 if (info == (struct PackageInfo *) NULL)
1510 break;
1511 io_info=IoIFP(sv_2io(sval));
1512 if (io_info == (PerlIO *) NULL)
1513 {
1514 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1515 PackageName);
1516 break;
1517 }
1518 file=PerlIO_findFILE(io_info);
1519 if (file == (FILE *) NULL)
1520 {
1521 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1522 PackageName);
1523 break;
1524 }
1525 SetImageInfoFile(info->image_info,file);
1526 break;
1527 }
1528 if (LocaleCompare(attribute,"fill") == 0)
1529 {
1530 if (info)
1531 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1532 break;
1533 }
1534 if (LocaleCompare(attribute,"font") == 0)
1535 {
1536 if (info)
1537 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1538 break;
1539 }
1540 if (LocaleCompare(attribute,"foreground") == 0)
1541 break;
1542 if (LocaleCompare(attribute,"fuzz") == 0)
1543 {
1544 if (info)
1545 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1546 QuantumRange+1.0);
1547 for ( ; image; image=image->next)
1548 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1549 QuantumRange+1.0);
1550 break;
1551 }
1552 if (info)
1553 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1554 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001555 {
1556 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001557 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001558 }
cristy4a3ce0a2013-08-03 20:06:59 +00001559 break;
1560 }
1561 case 'G':
1562 case 'g':
1563 {
1564 if (LocaleCompare(attribute,"gamma") == 0)
1565 {
1566 for ( ; image; image=image->next)
1567 image->gamma=SvNV(sval);
1568 break;
1569 }
1570 if (LocaleCompare(attribute,"gravity") == 0)
1571 {
1572 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1573 SvPV(sval,na)) : SvIV(sval);
1574 if (sp < 0)
1575 {
1576 ThrowPerlException(exception,OptionError,
1577 "UnrecognizedGravityType",SvPV(sval,na));
1578 break;
1579 }
1580 if (info)
1581 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1582 for ( ; image; image=image->next)
1583 image->gravity=(GravityType) sp;
1584 break;
1585 }
1586 if (LocaleCompare(attribute,"green-primary") == 0)
1587 {
1588 for ( ; image; image=image->next)
1589 {
1590 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1591 image->chromaticity.green_primary.x=geometry_info.rho;
1592 image->chromaticity.green_primary.y=geometry_info.sigma;
1593 if ((flags & SigmaValue) == 0)
1594 image->chromaticity.green_primary.y=
1595 image->chromaticity.green_primary.x;
1596 }
1597 break;
1598 }
1599 if (info)
1600 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1601 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001602 {
1603 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001604 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001605 }
cristy4a3ce0a2013-08-03 20:06:59 +00001606 break;
1607 }
1608 case 'I':
1609 case 'i':
1610 {
1611 if (LocaleNCompare(attribute,"index",5) == 0)
1612 {
1613 int
1614 items;
1615
1616 long
1617 index;
1618
1619 register Quantum
1620 *q;
1621
1622 CacheView
1623 *image_view;
1624
1625 for ( ; image; image=image->next)
1626 {
1627 if (image->storage_class != PseudoClass)
1628 continue;
1629 x=0;
1630 y=0;
1631 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1632 (void) items;
1633 image_view=AcquireAuthenticCacheView(image,exception);
1634 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1635 if (q != (Quantum *) NULL)
1636 {
1637 items=sscanf(SvPV(sval,na),"%ld",&index);
1638 if ((index >= 0) && (index < (ssize_t) image->colors))
1639 SetPixelIndex(image,index,q);
1640 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1641 }
1642 image_view=DestroyCacheView(image_view);
1643 }
1644 break;
1645 }
1646 if (LocaleCompare(attribute,"iterations") == 0)
1647 {
1648 iterations:
1649 for ( ; image; image=image->next)
1650 image->iterations=SvIV(sval);
1651 break;
1652 }
1653 if (LocaleCompare(attribute,"interlace") == 0)
1654 {
1655 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1656 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1657 if (sp < 0)
1658 {
1659 ThrowPerlException(exception,OptionError,
1660 "UnrecognizedInterlaceType",SvPV(sval,na));
1661 break;
1662 }
1663 if (info)
1664 info->image_info->interlace=(InterlaceType) sp;
1665 for ( ; image; image=image->next)
1666 image->interlace=(InterlaceType) sp;
1667 break;
1668 }
1669 if (info)
1670 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1671 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001672 {
1673 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001674 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001675 }
cristy4a3ce0a2013-08-03 20:06:59 +00001676 break;
1677 }
1678 case 'L':
1679 case 'l':
1680 {
1681 if (LocaleCompare(attribute,"label") == 0)
1682 {
1683 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001684 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001685 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001686 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001687 break;
1688 }
1689 if (LocaleCompare(attribute,"loop") == 0)
1690 goto iterations;
1691 if (info)
1692 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1693 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001694 {
1695 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001696 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001697 }
cristy4a3ce0a2013-08-03 20:06:59 +00001698 break;
1699 }
1700 case 'M':
1701 case 'm':
1702 {
1703 if (LocaleCompare(attribute,"magick") == 0)
1704 {
1705 if (info)
Cristyb5b1f5d2017-03-31 16:42:35 -04001706 (void) FormatLocaleString(info->image_info->filename,
1707 MagickPathExtent,"%s:",SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001708 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001709 (void) CopyMagickString(image->magick,SvPV(sval,na),
1710 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001711 break;
1712 }
1713 if (LocaleCompare(attribute,"map-limit") == 0)
1714 {
1715 MagickSizeType
1716 limit;
1717
1718 limit=MagickResourceInfinity;
1719 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1720 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1721 100.0);
1722 (void) SetMagickResourceLimit(MapResource,limit);
1723 break;
1724 }
1725 if (LocaleCompare(attribute,"mask") == 0)
1726 {
1727 Image
1728 *mask;
1729
1730 mask=(Image *) NULL;
1731 if (SvPOK(sval))
1732 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1733 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001734 SetImageMask(image,ReadPixelMask,mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001735 break;
1736 }
1737 if (LocaleCompare(attribute,"mattecolor") == 0)
1738 {
1739 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1740 exception);
1741 if (info)
Cristy8645e042016-02-03 16:35:29 -05001742 info->image_info->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001743 for ( ; image; image=image->next)
Cristy8645e042016-02-03 16:35:29 -05001744 image->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001745 break;
1746 }
1747 if (LocaleCompare(attribute,"matte") == 0)
1748 {
1749 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1750 SvPV(sval,na)) : SvIV(sval);
1751 if (sp < 0)
1752 {
1753 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1754 SvPV(sval,na));
1755 break;
1756 }
1757 for ( ; image; image=image->next)
1758 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1759 break;
1760 }
1761 if (LocaleCompare(attribute,"memory-limit") == 0)
1762 {
1763 MagickSizeType
1764 limit;
1765
1766 limit=MagickResourceInfinity;
1767 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1768 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1769 100.0);
1770 (void) SetMagickResourceLimit(MemoryResource,limit);
1771 break;
1772 }
1773 if (LocaleCompare(attribute,"monochrome") == 0)
1774 {
1775 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1776 SvPV(sval,na)) : SvIV(sval);
1777 if (sp < 0)
1778 {
1779 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1780 SvPV(sval,na));
1781 break;
1782 }
1783 if (info)
1784 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1785 for ( ; image; image=image->next)
1786 (void) SetImageType(image,BilevelType,exception);
1787 break;
1788 }
1789 if (info)
1790 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1791 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001792 {
1793 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001794 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001795 }
cristy4a3ce0a2013-08-03 20:06:59 +00001796 break;
1797 }
1798 case 'O':
1799 case 'o':
1800 {
1801 if (LocaleCompare(attribute,"option") == 0)
1802 {
1803 if (info)
1804 DefineImageOption(info->image_info,SvPV(sval,na));
1805 break;
1806 }
1807 if (LocaleCompare(attribute,"orientation") == 0)
1808 {
1809 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1810 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1811 if (sp < 0)
1812 {
1813 ThrowPerlException(exception,OptionError,
1814 "UnrecognizedOrientationType",SvPV(sval,na));
1815 break;
1816 }
1817 if (info)
1818 info->image_info->orientation=(OrientationType) sp;
1819 for ( ; image; image=image->next)
1820 image->orientation=(OrientationType) sp;
1821 break;
1822 }
1823 if (info)
1824 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1825 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001826 {
1827 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001828 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001829 }
cristy4a3ce0a2013-08-03 20:06:59 +00001830 break;
1831 }
1832 case 'P':
1833 case 'p':
1834 {
1835 if (LocaleCompare(attribute,"page") == 0)
1836 {
1837 char
1838 *geometry;
1839
1840 geometry=GetPageGeometry(SvPV(sval,na));
1841 if (info)
1842 (void) CloneString(&info->image_info->page,geometry);
1843 for ( ; image; image=image->next)
1844 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1845 geometry=(char *) RelinquishMagickMemory(geometry);
1846 break;
1847 }
1848 if (LocaleNCompare(attribute,"pixel",5) == 0)
1849 {
1850 int
1851 items;
1852
1853 PixelInfo
1854 pixel;
1855
1856 register Quantum
1857 *q;
1858
1859 CacheView
1860 *image_view;
1861
1862 for ( ; image; image=image->next)
1863 {
1864 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1865 break;
1866 x=0;
1867 y=0;
1868 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1869 (void) items;
1870 image_view=AcquireVirtualCacheView(image,exception);
1871 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1872 if (q != (Quantum *) NULL)
1873 {
1874 if ((strchr(SvPV(sval,na),',') == 0) ||
1875 (strchr(SvPV(sval,na),')') != 0))
1876 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1877 &pixel,exception);
1878 else
1879 {
1880 GetPixelInfo(image,&pixel);
1881 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1882 pixel.red=geometry_info.rho;
1883 if ((flags & SigmaValue) != 0)
1884 pixel.green=geometry_info.sigma;
1885 if ((flags & XiValue) != 0)
1886 pixel.blue=geometry_info.xi;
1887 if ((flags & PsiValue) != 0)
1888 pixel.alpha=geometry_info.psi;
1889 if ((flags & ChiValue) != 0)
1890 pixel.black=geometry_info.chi;
1891 }
1892 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1893 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1894 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1895 if (image->colorspace == CMYKColorspace)
1896 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1897 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1898 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1899 }
1900 image_view=DestroyCacheView(image_view);
1901 }
1902 break;
1903 }
1904 if (LocaleCompare(attribute,"pointsize") == 0)
1905 {
1906 if (info)
1907 {
1908 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1909 info->image_info->pointsize=geometry_info.rho;
1910 }
1911 break;
1912 }
cristy4a3ce0a2013-08-03 20:06:59 +00001913 if (info)
1914 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1915 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001916 {
1917 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001918 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001919 }
cristy4a3ce0a2013-08-03 20:06:59 +00001920 break;
1921 }
1922 case 'Q':
1923 case 'q':
1924 {
1925 if (LocaleCompare(attribute,"quality") == 0)
1926 {
1927 if (info)
1928 info->image_info->quality=SvIV(sval);
1929 for ( ; image; image=image->next)
1930 image->quality=SvIV(sval);
1931 break;
1932 }
1933 if (info)
1934 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1935 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001936 {
1937 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001938 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001939 }
cristy4a3ce0a2013-08-03 20:06:59 +00001940 break;
1941 }
1942 case 'R':
1943 case 'r':
1944 {
cristyc0fe4752015-07-27 18:02:39 +00001945 if (LocaleCompare(attribute,"read-mask") == 0)
1946 {
1947 Image
1948 *mask;
1949
1950 mask=(Image *) NULL;
1951 if (SvPOK(sval))
1952 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1953 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001954 SetImageMask(image,ReadPixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00001955 break;
1956 }
cristy4a3ce0a2013-08-03 20:06:59 +00001957 if (LocaleCompare(attribute,"red-primary") == 0)
1958 {
1959 for ( ; image; image=image->next)
1960 {
1961 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1962 image->chromaticity.red_primary.x=geometry_info.rho;
1963 image->chromaticity.red_primary.y=geometry_info.sigma;
1964 if ((flags & SigmaValue) == 0)
1965 image->chromaticity.red_primary.y=
1966 image->chromaticity.red_primary.x;
1967 }
1968 break;
1969 }
1970 if (LocaleCompare(attribute,"render") == 0)
1971 {
1972 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1973 SvPV(sval,na)) : SvIV(sval);
1974 if (sp < 0)
1975 {
1976 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1977 SvPV(sval,na));
1978 break;
1979 }
1980 for ( ; image; image=image->next)
1981 image->rendering_intent=(RenderingIntent) sp;
1982 break;
1983 }
1984 if (LocaleCompare(attribute,"repage") == 0)
1985 {
1986 RectangleInfo
1987 geometry;
1988
1989 for ( ; image; image=image->next)
1990 {
1991 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1992 if ((flags & WidthValue) != 0)
1993 {
1994 if ((flags & HeightValue) == 0)
1995 geometry.height=geometry.width;
1996 image->page.width=geometry.width;
1997 image->page.height=geometry.height;
1998 }
1999 if ((flags & AspectValue) != 0)
2000 {
2001 if ((flags & XValue) != 0)
2002 image->page.x+=geometry.x;
2003 if ((flags & YValue) != 0)
2004 image->page.y+=geometry.y;
2005 }
2006 else
2007 {
2008 if ((flags & XValue) != 0)
2009 {
2010 image->page.x=geometry.x;
2011 if (((flags & WidthValue) != 0) && (geometry.x > 0))
2012 image->page.width=image->columns+geometry.x;
2013 }
2014 if ((flags & YValue) != 0)
2015 {
2016 image->page.y=geometry.y;
2017 if (((flags & HeightValue) != 0) && (geometry.y > 0))
2018 image->page.height=image->rows+geometry.y;
2019 }
2020 }
2021 }
2022 break;
2023 }
2024 if (info)
2025 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2026 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002027 {
2028 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002029 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002030 }
cristy4a3ce0a2013-08-03 20:06:59 +00002031 break;
2032 }
2033 case 'S':
2034 case 's':
2035 {
2036 if (LocaleCompare(attribute,"sampling-factor") == 0)
2037 {
2038 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2039 {
2040 ThrowPerlException(exception,OptionError,"MissingGeometry",
2041 SvPV(sval,na));
2042 break;
2043 }
2044 if (info)
2045 (void) CloneString(&info->image_info->sampling_factor,
2046 SvPV(sval,na));
2047 break;
2048 }
2049 if (LocaleCompare(attribute,"scene") == 0)
2050 {
2051 for ( ; image; image=image->next)
2052 image->scene=SvIV(sval);
2053 break;
2054 }
2055 if (LocaleCompare(attribute,"server") == 0)
2056 goto display;
2057 if (LocaleCompare(attribute,"size") == 0)
2058 {
2059 if (info)
2060 {
2061 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2062 {
2063 ThrowPerlException(exception,OptionError,"MissingGeometry",
2064 SvPV(sval,na));
2065 break;
2066 }
2067 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2068 }
2069 break;
2070 }
2071 if (LocaleCompare(attribute,"stroke") == 0)
2072 {
2073 if (info)
2074 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2075 break;
2076 }
2077 if (info)
2078 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2079 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002080 {
2081 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002082 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002083 }
cristy4a3ce0a2013-08-03 20:06:59 +00002084 break;
2085 }
2086 case 'T':
2087 case 't':
2088 {
2089 if (LocaleCompare(attribute,"texture") == 0)
2090 {
2091 if (info)
2092 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2093 break;
2094 }
2095 if (LocaleCompare(attribute,"thread-limit") == 0)
2096 {
2097 MagickSizeType
2098 limit;
2099
2100 limit=MagickResourceInfinity;
2101 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2102 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2103 100.0);
2104 (void) SetMagickResourceLimit(ThreadResource,limit);
2105 break;
2106 }
2107 if (LocaleCompare(attribute,"tile-offset") == 0)
2108 {
2109 char
2110 *geometry;
2111
2112 geometry=GetPageGeometry(SvPV(sval,na));
2113 if (info)
2114 (void) CloneString(&info->image_info->page,geometry);
2115 for ( ; image; image=image->next)
2116 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2117 exception);
2118 geometry=(char *) RelinquishMagickMemory(geometry);
2119 break;
2120 }
2121 if (LocaleCompare(attribute,"time-limit") == 0)
2122 {
2123 MagickSizeType
2124 limit;
2125
2126 limit=MagickResourceInfinity;
2127 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2128 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2129 100.0);
2130 (void) SetMagickResourceLimit(TimeResource,limit);
2131 break;
2132 }
2133 if (LocaleCompare(attribute,"transparent-color") == 0)
2134 {
2135 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2136 exception);
2137 if (info)
2138 info->image_info->transparent_color=target_color;
2139 for ( ; image; image=image->next)
2140 image->transparent_color=target_color;
2141 break;
2142 }
2143 if (LocaleCompare(attribute,"type") == 0)
2144 {
2145 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2146 SvPV(sval,na)) : SvIV(sval);
2147 if (sp < 0)
2148 {
2149 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2150 SvPV(sval,na));
2151 break;
2152 }
2153 if (info)
2154 info->image_info->type=(ImageType) sp;
2155 for ( ; image; image=image->next)
2156 SetImageType(image,(ImageType) sp,exception);
2157 break;
2158 }
2159 if (info)
2160 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2161 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002162 {
2163 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002164 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002165 }
cristy4a3ce0a2013-08-03 20:06:59 +00002166 break;
2167 }
2168 case 'U':
2169 case 'u':
2170 {
2171 if (LocaleCompare(attribute,"units") == 0)
2172 {
2173 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2174 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2175 if (sp < 0)
2176 {
2177 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2178 SvPV(sval,na));
2179 break;
2180 }
2181 if (info)
2182 info->image_info->units=(ResolutionType) sp;
2183 for ( ; image; image=image->next)
2184 {
2185 ResolutionType
2186 units;
2187
2188 units=(ResolutionType) sp;
2189 if (image->units != units)
2190 switch (image->units)
2191 {
2192 case UndefinedResolution:
2193 case PixelsPerInchResolution:
2194 {
2195 if (units == PixelsPerCentimeterResolution)
2196 {
2197 image->resolution.x*=2.54;
2198 image->resolution.y*=2.54;
2199 }
2200 break;
2201 }
2202 case PixelsPerCentimeterResolution:
2203 {
2204 if (units == PixelsPerInchResolution)
2205 {
2206 image->resolution.x/=2.54;
2207 image->resolution.y/=2.54;
2208 }
2209 break;
2210 }
2211 }
2212 image->units=units;
2213 }
2214 break;
2215 }
2216 if (info)
2217 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2218 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002219 {
2220 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002221 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002222 }
cristy4a3ce0a2013-08-03 20:06:59 +00002223 break;
2224 }
2225 case 'V':
2226 case 'v':
2227 {
2228 if (LocaleCompare(attribute,"verbose") == 0)
2229 {
2230 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2231 SvPV(sval,na)) : SvIV(sval);
2232 if (sp < 0)
2233 {
2234 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2235 SvPV(sval,na));
2236 break;
2237 }
2238 if (info)
2239 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2240 break;
2241 }
cristy4a3ce0a2013-08-03 20:06:59 +00002242 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2243 {
2244 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2245 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2246 if (sp < 0)
2247 {
2248 ThrowPerlException(exception,OptionError,
2249 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2250 break;
2251 }
2252 for ( ; image; image=image->next)
2253 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2254 break;
2255 }
2256 if (info)
2257 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2258 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002259 {
2260 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002261 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002262 }
cristy4a3ce0a2013-08-03 20:06:59 +00002263 break;
2264 }
2265 case 'W':
2266 case 'w':
2267 {
2268 if (LocaleCompare(attribute,"white-point") == 0)
2269 {
2270 for ( ; image; image=image->next)
2271 {
2272 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2273 image->chromaticity.white_point.x=geometry_info.rho;
2274 image->chromaticity.white_point.y=geometry_info.sigma;
2275 if ((flags & SigmaValue) == 0)
2276 image->chromaticity.white_point.y=
2277 image->chromaticity.white_point.x;
2278 }
2279 break;
2280 }
cristyc0fe4752015-07-27 18:02:39 +00002281 if (LocaleCompare(attribute,"write-mask") == 0)
2282 {
2283 Image
2284 *mask;
2285
2286 mask=(Image *) NULL;
2287 if (SvPOK(sval))
2288 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2289 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002290 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002291 break;
2292 }
cristy4a3ce0a2013-08-03 20:06:59 +00002293 if (info)
2294 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2295 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002296 {
2297 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002298 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002299 }
cristy4a3ce0a2013-08-03 20:06:59 +00002300 break;
2301 }
2302 default:
2303 {
2304 if (info)
2305 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2306 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002307 {
2308 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002309 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002310 }
cristy4a3ce0a2013-08-03 20:06:59 +00002311 break;
2312 }
2313 }
2314}
2315
2316/*
2317%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2318% %
2319% %
2320% %
2321% S e t u p L i s t %
2322% %
2323% %
2324% %
2325%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2326%
2327% Method SetupList returns the list of all the images linked by their
2328% image->next and image->previous link lists for use with ImageMagick. If
2329% info is non-NULL, an info structure is returned in *info. If
2330% reference_vector is non-NULL,an array of SV* are returned in
2331% *reference_vector. Reference_vector is used when the images are going to be
2332% replaced with new Image*'s.
2333%
2334% The format of the SetupList routine is:
2335%
2336% Image *SetupList(SV *reference,struct PackageInfo **info,
2337% SV ***reference_vector,ExceptionInfo *exception)
2338%
2339% A description of each parameter follows:
2340%
2341% o list: a list of strings.
2342%
2343% o string: a character string.
2344%
2345% o exception: Return any errors or warnings in this structure.
2346%
2347*/
2348static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2349 SV ***reference_vector,ExceptionInfo *exception)
2350{
2351 Image
2352 *image;
2353
2354 ssize_t
2355 current,
2356 last;
2357
2358 if (reference_vector)
2359 *reference_vector=NULL;
2360 if (info)
2361 *info=NULL;
2362 current=0;
2363 last=0;
2364 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2365 if (info && (SvTYPE(reference) == SVt_PVAV))
2366 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2367 exception);
2368 return(image);
2369}
2370
2371/*
2372%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2373% %
2374% %
2375% %
2376% s t r E Q c a s e %
2377% %
2378% %
2379% %
2380%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2381%
2382% strEQcase() compares two strings and returns 0 if they are the
2383% same or if the second string runs out first. The comparison is case
2384% insensitive.
2385%
2386% The format of the strEQcase routine is:
2387%
2388% ssize_t strEQcase(const char *p,const char *q)
2389%
2390% A description of each parameter follows:
2391%
2392% o p: a character string.
2393%
2394% o q: a character string.
2395%
2396%
2397*/
2398static ssize_t strEQcase(const char *p,const char *q)
2399{
2400 char
2401 c;
2402
2403 register ssize_t
2404 i;
2405
2406 for (i=0 ; (c=(*q)) != 0; i++)
2407 {
2408 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2409 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2410 return(0);
2411 p++;
2412 q++;
2413 }
2414 return(((*q == 0) && (*p == 0)) ? i : 0);
2415}
2416
2417/*
2418%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2419% %
2420% %
2421% %
2422% I m a g e : : M a g i c k %
2423% %
2424% %
2425% %
2426%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2427%
2428%
2429*/
2430MODULE = Image::Magick PACKAGE = Image::Magick
2431
2432PROTOTYPES: ENABLE
2433
2434BOOT:
2435 MagickCoreGenesis("PerlMagick",MagickFalse);
2436 SetWarningHandler(NULL);
2437 SetErrorHandler(NULL);
2438 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2439 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2440
2441void
2442UNLOAD()
2443 PPCODE:
2444 {
2445 if (magick_registry != (SplayTreeInfo *) NULL)
2446 magick_registry=DestroySplayTree(magick_registry);
2447 MagickCoreTerminus();
2448 }
2449
2450double
2451constant(name,argument)
2452 char *name
2453 ssize_t argument
2454
2455#
2456###############################################################################
2457# #
2458# #
2459# #
2460# A n i m a t e #
2461# #
2462# #
2463# #
2464###############################################################################
2465#
2466#
2467void
2468Animate(ref,...)
2469 Image::Magick ref=NO_INIT
2470 ALIAS:
2471 AnimateImage = 1
2472 animate = 2
2473 animateimage = 3
2474 PPCODE:
2475 {
2476 ExceptionInfo
2477 *exception;
2478
2479 Image
2480 *image;
2481
2482 register ssize_t
2483 i;
2484
2485 struct PackageInfo
2486 *info,
2487 *package_info;
2488
2489 SV
2490 *perl_exception,
2491 *reference;
2492
2493 PERL_UNUSED_VAR(ref);
2494 PERL_UNUSED_VAR(ix);
2495 exception=AcquireExceptionInfo();
2496 perl_exception=newSVpv("",0);
2497 package_info=(struct PackageInfo *) NULL;
2498 if (sv_isobject(ST(0)) == 0)
2499 {
2500 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2501 PackageName);
2502 goto PerlException;
2503 }
2504 reference=SvRV(ST(0));
2505 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2506 if (image == (Image *) NULL)
2507 {
2508 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2509 PackageName);
2510 goto PerlException;
2511 }
2512 package_info=ClonePackageInfo(info,exception);
2513 if (items == 2)
2514 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2515 else
2516 if (items > 2)
2517 for (i=2; i < items; i+=2)
2518 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2519 exception);
2520 (void) AnimateImages(package_info->image_info,image,exception);
2521 (void) CatchImageException(image);
2522
2523 PerlException:
2524 if (package_info != (struct PackageInfo *) NULL)
2525 DestroyPackageInfo(package_info);
2526 InheritPerlException(exception,perl_exception);
2527 exception=DestroyExceptionInfo(exception);
2528 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2529 SvPOK_on(perl_exception);
2530 ST(0)=sv_2mortal(perl_exception);
2531 XSRETURN(1);
2532 }
2533
2534#
2535###############################################################################
2536# #
2537# #
2538# #
2539# A p p e n d #
2540# #
2541# #
2542# #
2543###############################################################################
2544#
2545#
2546void
2547Append(ref,...)
2548 Image::Magick ref=NO_INIT
2549 ALIAS:
2550 AppendImage = 1
2551 append = 2
2552 appendimage = 3
2553 PPCODE:
2554 {
2555 AV
2556 *av;
2557
2558 char
2559 *attribute;
2560
2561 ExceptionInfo
2562 *exception;
2563
2564 HV
2565 *hv;
2566
2567 Image
2568 *image;
2569
2570 register ssize_t
2571 i;
2572
2573 ssize_t
2574 stack;
2575
2576 struct PackageInfo
2577 *info;
2578
2579 SV
2580 *av_reference,
2581 *perl_exception,
2582 *reference,
2583 *rv,
2584 *sv;
2585
2586 PERL_UNUSED_VAR(ref);
2587 PERL_UNUSED_VAR(ix);
2588 exception=AcquireExceptionInfo();
2589 perl_exception=newSVpv("",0);
2590 sv=NULL;
2591 attribute=NULL;
2592 av=NULL;
2593 if (sv_isobject(ST(0)) == 0)
2594 {
2595 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2596 PackageName);
2597 goto PerlException;
2598 }
2599 reference=SvRV(ST(0));
2600 hv=SvSTASH(reference);
2601 av=newAV();
2602 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2603 SvREFCNT_dec(av);
2604 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2605 if (image == (Image *) NULL)
2606 {
2607 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2608 PackageName);
2609 goto PerlException;
2610 }
2611 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2612 /*
2613 Get options.
2614 */
2615 stack=MagickTrue;
2616 for (i=2; i < items; i+=2)
2617 {
2618 attribute=(char *) SvPV(ST(i-1),na);
2619 switch (*attribute)
2620 {
2621 case 'S':
2622 case 's':
2623 {
2624 if (LocaleCompare(attribute,"stack") == 0)
2625 {
2626 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2627 SvPV(ST(i),na));
2628 if (stack < 0)
2629 {
2630 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2631 SvPV(ST(i),na));
2632 return;
2633 }
2634 break;
2635 }
2636 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2637 attribute);
2638 break;
2639 }
2640 default:
2641 {
2642 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2643 attribute);
2644 break;
2645 }
2646 }
2647 }
2648 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2649 if (image == (Image *) NULL)
2650 goto PerlException;
2651 for ( ; image; image=image->next)
2652 {
2653 AddImageToRegistry(sv,image);
2654 rv=newRV(sv);
2655 av_push(av,sv_bless(rv,hv));
2656 SvREFCNT_dec(sv);
2657 }
2658 exception=DestroyExceptionInfo(exception);
2659 ST(0)=av_reference;
2660 SvREFCNT_dec(perl_exception);
2661 XSRETURN(1);
2662
2663 PerlException:
2664 InheritPerlException(exception,perl_exception);
2665 exception=DestroyExceptionInfo(exception);
2666 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2667 SvPOK_on(perl_exception);
2668 ST(0)=sv_2mortal(perl_exception);
2669 XSRETURN(1);
2670 }
2671
2672#
2673###############################################################################
2674# #
2675# #
2676# #
2677# A v e r a g e #
2678# #
2679# #
2680# #
2681###############################################################################
2682#
2683#
2684void
2685Average(ref)
2686 Image::Magick ref=NO_INIT
2687 ALIAS:
2688 AverageImage = 1
2689 average = 2
2690 averageimage = 3
2691 PPCODE:
2692 {
2693 AV
2694 *av;
2695
2696 char
2697 *p;
2698
2699 ExceptionInfo
2700 *exception;
2701
2702 HV
2703 *hv;
2704
2705 Image
2706 *image;
2707
2708 struct PackageInfo
2709 *info;
2710
2711 SV
2712 *perl_exception,
2713 *reference,
2714 *rv,
2715 *sv;
2716
2717 PERL_UNUSED_VAR(ref);
2718 PERL_UNUSED_VAR(ix);
2719 exception=AcquireExceptionInfo();
2720 perl_exception=newSVpv("",0);
2721 sv=NULL;
2722 if (sv_isobject(ST(0)) == 0)
2723 {
2724 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2725 PackageName);
2726 goto PerlException;
2727 }
2728 reference=SvRV(ST(0));
2729 hv=SvSTASH(reference);
2730 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2731 if (image == (Image *) NULL)
2732 {
2733 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2734 PackageName);
2735 goto PerlException;
2736 }
2737 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2738 if (image == (Image *) NULL)
2739 goto PerlException;
2740 /*
2741 Create blessed Perl array for the returned image.
2742 */
2743 av=newAV();
2744 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2745 SvREFCNT_dec(av);
2746 AddImageToRegistry(sv,image);
2747 rv=newRV(sv);
2748 av_push(av,sv_bless(rv,hv));
2749 SvREFCNT_dec(sv);
2750 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002751 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2752 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002753 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2754 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002755 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002756 SetImageInfo(info->image_info,0,exception);
2757 exception=DestroyExceptionInfo(exception);
2758 SvREFCNT_dec(perl_exception);
2759 XSRETURN(1);
2760
2761 PerlException:
2762 InheritPerlException(exception,perl_exception);
2763 exception=DestroyExceptionInfo(exception);
2764 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2765 SvPOK_on(perl_exception);
2766 ST(0)=sv_2mortal(perl_exception);
2767 XSRETURN(1);
2768 }
2769
2770#
2771###############################################################################
2772# #
2773# #
2774# #
2775# B l o b T o I m a g e #
2776# #
2777# #
2778# #
2779###############################################################################
2780#
2781#
2782void
2783BlobToImage(ref,...)
2784 Image::Magick ref=NO_INIT
2785 ALIAS:
2786 BlobToImage = 1
2787 blobtoimage = 2
2788 blobto = 3
2789 PPCODE:
2790 {
2791 AV
2792 *av;
2793
2794 char
2795 **keep,
2796 **list;
2797
2798 ExceptionInfo
2799 *exception;
2800
2801 HV
2802 *hv;
2803
2804 Image
2805 *image;
2806
2807 register char
2808 **p;
2809
2810 register ssize_t
2811 i;
2812
2813 ssize_t
2814 ac,
2815 n,
2816 number_images;
2817
2818 STRLEN
2819 *length;
2820
2821 struct PackageInfo
2822 *info;
2823
2824 SV
2825 *perl_exception,
2826 *reference,
2827 *rv,
2828 *sv;
2829
2830 PERL_UNUSED_VAR(ref);
2831 PERL_UNUSED_VAR(ix);
2832 exception=AcquireExceptionInfo();
2833 perl_exception=newSVpv("",0);
2834 sv=NULL;
2835 number_images=0;
2836 ac=(items < 2) ? 1 : items-1;
2837 length=(STRLEN *) NULL;
2838 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2839 if (list == (char **) NULL)
2840 {
2841 ThrowPerlException(exception,ResourceLimitError,
2842 "MemoryAllocationFailed",PackageName);
2843 goto PerlException;
2844 }
2845 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2846 if (length == (STRLEN *) NULL)
2847 {
2848 ThrowPerlException(exception,ResourceLimitError,
2849 "MemoryAllocationFailed",PackageName);
2850 goto PerlException;
2851 }
2852 if (sv_isobject(ST(0)) == 0)
2853 {
2854 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2855 PackageName);
2856 goto PerlException;
2857 }
2858 reference=SvRV(ST(0));
2859 hv=SvSTASH(reference);
2860 if (SvTYPE(reference) != SVt_PVAV)
2861 {
2862 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2863 PackageName);
2864 goto PerlException;
2865 }
2866 av=(AV *) reference;
2867 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2868 exception);
2869 n=1;
2870 if (items <= 1)
2871 {
2872 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2873 goto PerlException;
2874 }
2875 for (n=0, i=0; i < ac; i++)
2876 {
2877 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2878 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2879 {
2880 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2881 continue;
2882 }
2883 n++;
2884 }
2885 list[n]=(char *) NULL;
2886 keep=list;
2887 for (i=number_images=0; i < n; i++)
2888 {
2889 image=BlobToImage(info->image_info,list[i],length[i],exception);
2890 if (image == (Image *) NULL)
2891 break;
2892 for ( ; image; image=image->next)
2893 {
2894 AddImageToRegistry(sv,image);
2895 rv=newRV(sv);
2896 av_push(av,sv_bless(rv,hv));
2897 SvREFCNT_dec(sv);
2898 number_images++;
2899 }
2900 }
2901 /*
2902 Free resources.
2903 */
2904 for (i=0; i < n; i++)
2905 if (list[i] != (char *) NULL)
2906 for (p=keep; list[i] != *p++; )
2907 if (*p == (char *) NULL)
2908 {
2909 list[i]=(char *) RelinquishMagickMemory(list[i]);
2910 break;
2911 }
2912
2913 PerlException:
2914 if (list)
2915 list=(char **) RelinquishMagickMemory(list);
2916 if (length)
2917 length=(STRLEN *) RelinquishMagickMemory(length);
2918 InheritPerlException(exception,perl_exception);
2919 exception=DestroyExceptionInfo(exception);
2920 sv_setiv(perl_exception,(IV) number_images);
2921 SvPOK_on(perl_exception);
2922 ST(0)=sv_2mortal(perl_exception);
2923 XSRETURN(1);
2924 }
2925
2926#
2927###############################################################################
2928# #
2929# #
2930# #
2931# C h a n n e l F x #
2932# #
2933# #
2934# #
2935###############################################################################
2936#
2937#
2938void
2939ChannelFx(ref,...)
2940 Image::Magick ref=NO_INIT
2941 ALIAS:
2942 ChannelFxImage = 1
2943 channelfx = 2
2944 channelfximage = 3
2945 PPCODE:
2946 {
2947 AV
2948 *av;
2949
2950 char
2951 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002952 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002953
2954 ChannelType
2955 channel,
2956 channel_mask;
2957
2958 ExceptionInfo
2959 *exception;
2960
2961 HV
2962 *hv;
2963
2964 Image
2965 *image;
2966
2967 register ssize_t
2968 i;
2969
2970 struct PackageInfo
2971 *info;
2972
2973 SV
2974 *av_reference,
2975 *perl_exception,
2976 *reference,
2977 *rv,
2978 *sv;
2979
2980 PERL_UNUSED_VAR(ref);
2981 PERL_UNUSED_VAR(ix);
2982 exception=AcquireExceptionInfo();
2983 perl_exception=newSVpv("",0);
2984 sv=NULL;
2985 attribute=NULL;
2986 av=NULL;
2987 if (sv_isobject(ST(0)) == 0)
2988 {
2989 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2990 PackageName);
2991 goto PerlException;
2992 }
2993 reference=SvRV(ST(0));
2994 hv=SvSTASH(reference);
2995 av=newAV();
2996 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2997 SvREFCNT_dec(av);
2998 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2999 if (image == (Image *) NULL)
3000 {
3001 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3002 PackageName);
3003 goto PerlException;
3004 }
3005 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3006 /*
3007 Get options.
3008 */
3009 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00003010 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003011 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00003012 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003013 else
3014 for (i=2; i < items; i+=2)
3015 {
3016 attribute=(char *) SvPV(ST(i-1),na);
3017 switch (*attribute)
3018 {
3019 case 'C':
3020 case 'c':
3021 {
3022 if (LocaleCompare(attribute,"channel") == 0)
3023 {
3024 ssize_t
3025 option;
3026
3027 option=ParseChannelOption(SvPV(ST(i),na));
3028 if (option < 0)
3029 {
3030 ThrowPerlException(exception,OptionError,
3031 "UnrecognizedType",SvPV(ST(i),na));
3032 return;
3033 }
3034 channel=(ChannelType) option;
3035 break;
3036 }
3037 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3038 attribute);
3039 break;
3040 }
3041 case 'E':
3042 case 'e':
3043 {
3044 if (LocaleCompare(attribute,"expression") == 0)
3045 {
3046 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00003047 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003048 break;
3049 }
3050 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3051 attribute);
3052 break;
3053 }
3054 default:
3055 {
3056 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3057 attribute);
3058 break;
3059 }
3060 }
3061 }
3062 channel_mask=SetImageChannelMask(image,channel);
3063 image=ChannelFxImage(image,expression,exception);
3064 if (image != (Image *) NULL)
3065 (void) SetImageChannelMask(image,channel_mask);
3066 if (image == (Image *) NULL)
3067 goto PerlException;
3068 for ( ; image; image=image->next)
3069 {
3070 AddImageToRegistry(sv,image);
3071 rv=newRV(sv);
3072 av_push(av,sv_bless(rv,hv));
3073 SvREFCNT_dec(sv);
3074 }
3075 exception=DestroyExceptionInfo(exception);
3076 ST(0)=av_reference;
3077 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3078 XSRETURN(1);
3079
3080 PerlException:
3081 InheritPerlException(exception,perl_exception);
3082 exception=DestroyExceptionInfo(exception);
3083 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3084 SvPOK_on(perl_exception);
3085 ST(0)=sv_2mortal(perl_exception);
3086 XSRETURN(1);
3087 }
3088
3089#
3090###############################################################################
3091# #
3092# #
3093# #
3094# C l o n e #
3095# #
3096# #
3097# #
3098###############################################################################
3099#
3100#
3101void
3102Clone(ref)
3103 Image::Magick ref=NO_INIT
3104 ALIAS:
3105 CopyImage = 1
3106 copy = 2
3107 copyimage = 3
3108 CloneImage = 4
3109 clone = 5
3110 cloneimage = 6
3111 Clone = 7
3112 PPCODE:
3113 {
3114 AV
3115 *av;
3116
3117 ExceptionInfo
3118 *exception;
3119
3120 HV
3121 *hv;
3122
3123 Image
3124 *clone,
3125 *image;
3126
3127 struct PackageInfo
3128 *info;
3129
3130 SV
3131 *perl_exception,
3132 *reference,
3133 *rv,
3134 *sv;
3135
3136 PERL_UNUSED_VAR(ref);
3137 PERL_UNUSED_VAR(ix);
3138 exception=AcquireExceptionInfo();
3139 perl_exception=newSVpv("",0);
3140 sv=NULL;
3141 if (sv_isobject(ST(0)) == 0)
3142 {
3143 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3144 PackageName);
3145 goto PerlException;
3146 }
3147 reference=SvRV(ST(0));
3148 hv=SvSTASH(reference);
3149 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3150 if (image == (Image *) NULL)
3151 {
3152 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3153 PackageName);
3154 goto PerlException;
3155 }
3156 /*
3157 Create blessed Perl array for the returned image.
3158 */
3159 av=newAV();
3160 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3161 SvREFCNT_dec(av);
3162 for ( ; image; image=image->next)
3163 {
3164 clone=CloneImage(image,0,0,MagickTrue,exception);
3165 if (clone == (Image *) NULL)
3166 break;
3167 AddImageToRegistry(sv,clone);
3168 rv=newRV(sv);
3169 av_push(av,sv_bless(rv,hv));
3170 SvREFCNT_dec(sv);
3171 }
3172 exception=DestroyExceptionInfo(exception);
3173 SvREFCNT_dec(perl_exception);
3174 XSRETURN(1);
3175
3176 PerlException:
3177 InheritPerlException(exception,perl_exception);
3178 exception=DestroyExceptionInfo(exception);
3179 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3180 SvPOK_on(perl_exception);
3181 ST(0)=sv_2mortal(perl_exception);
3182 XSRETURN(1);
3183 }
3184
3185#
3186###############################################################################
3187# #
3188# #
3189# #
3190# C L O N E #
3191# #
3192# #
3193# #
3194###############################################################################
3195#
3196#
3197void
3198CLONE(ref,...)
3199 SV *ref;
3200 CODE:
3201 {
3202 PERL_UNUSED_VAR(ref);
3203 if (magick_registry != (SplayTreeInfo *) NULL)
3204 {
3205 register Image
3206 *p;
3207
3208 ResetSplayTreeIterator(magick_registry);
3209 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3210 while (p != (Image *) NULL)
3211 {
3212 ReferenceImage(p);
3213 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3214 }
3215 }
3216 }
3217
3218#
3219###############################################################################
3220# #
3221# #
3222# #
3223# C o a l e s c e #
3224# #
3225# #
3226# #
3227###############################################################################
3228#
3229#
3230void
3231Coalesce(ref)
3232 Image::Magick ref=NO_INIT
3233 ALIAS:
3234 CoalesceImage = 1
3235 coalesce = 2
3236 coalesceimage = 3
3237 PPCODE:
3238 {
3239 AV
3240 *av;
3241
3242 ExceptionInfo
3243 *exception;
3244
3245 HV
3246 *hv;
3247
3248 Image
3249 *image;
3250
3251 struct PackageInfo
3252 *info;
3253
3254 SV
3255 *av_reference,
3256 *perl_exception,
3257 *reference,
3258 *rv,
3259 *sv;
3260
3261 PERL_UNUSED_VAR(ref);
3262 PERL_UNUSED_VAR(ix);
3263 exception=AcquireExceptionInfo();
3264 perl_exception=newSVpv("",0);
3265 sv=NULL;
3266 if (sv_isobject(ST(0)) == 0)
3267 {
3268 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3269 PackageName);
3270 goto PerlException;
3271 }
3272 reference=SvRV(ST(0));
3273 hv=SvSTASH(reference);
3274 av=newAV();
3275 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3276 SvREFCNT_dec(av);
3277 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3278 if (image == (Image *) NULL)
3279 {
3280 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3281 PackageName);
3282 goto PerlException;
3283 }
3284 image=CoalesceImages(image,exception);
3285 if (image == (Image *) NULL)
3286 goto PerlException;
3287 for ( ; image; image=image->next)
3288 {
3289 AddImageToRegistry(sv,image);
3290 rv=newRV(sv);
3291 av_push(av,sv_bless(rv,hv));
3292 SvREFCNT_dec(sv);
3293 }
3294 exception=DestroyExceptionInfo(exception);
3295 ST(0)=av_reference;
3296 SvREFCNT_dec(perl_exception);
3297 XSRETURN(1);
3298
3299 PerlException:
3300 InheritPerlException(exception,perl_exception);
3301 exception=DestroyExceptionInfo(exception);
3302 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3303 SvPOK_on(perl_exception);
3304 ST(0)=sv_2mortal(perl_exception);
3305 XSRETURN(1);
3306 }
3307
3308#
3309###############################################################################
3310# #
3311# #
3312# #
3313# C o m p a r e #
3314# #
3315# #
3316# #
3317###############################################################################
3318#
3319#
3320void
3321Compare(ref,...)
3322 Image::Magick ref=NO_INIT
3323 ALIAS:
3324 CompareImages = 1
3325 compare = 2
3326 compareimage = 3
3327 PPCODE:
3328 {
3329 AV
3330 *av;
3331
3332 char
3333 *attribute;
3334
3335 double
3336 distortion;
3337
3338 ExceptionInfo
3339 *exception;
3340
3341 HV
3342 *hv;
3343
3344 Image
3345 *difference_image,
3346 *image,
3347 *reconstruct_image;
3348
3349 MetricType
3350 metric;
3351
3352 register ssize_t
3353 i;
3354
3355 ssize_t
3356 option;
3357
3358 struct PackageInfo
3359 *info;
3360
3361 SV
3362 *av_reference,
3363 *perl_exception,
3364 *reference,
3365 *rv,
3366 *sv;
3367
3368 PERL_UNUSED_VAR(ref);
3369 PERL_UNUSED_VAR(ix);
3370 exception=AcquireExceptionInfo();
3371 perl_exception=newSVpv("",0);
3372 sv=NULL;
3373 av=NULL;
3374 attribute=NULL;
3375 if (sv_isobject(ST(0)) == 0)
3376 {
3377 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3378 PackageName);
3379 goto PerlException;
3380 }
3381 reference=SvRV(ST(0));
3382 hv=SvSTASH(reference);
3383 av=newAV();
3384 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3385 SvREFCNT_dec(av);
3386 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3387 if (image == (Image *) NULL)
3388 {
3389 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3390 PackageName);
3391 goto PerlException;
3392 }
3393 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3394 /*
3395 Get attribute.
3396 */
3397 reconstruct_image=image;
3398 metric=RootMeanSquaredErrorMetric;
3399 for (i=2; i < items; i+=2)
3400 {
3401 attribute=(char *) SvPV(ST(i-1),na);
3402 switch (*attribute)
3403 {
3404 case 'C':
3405 case 'c':
3406 {
3407 if (LocaleCompare(attribute,"channel") == 0)
3408 {
3409 ssize_t
3410 option;
3411
3412 option=ParseChannelOption(SvPV(ST(i),na));
3413 if (option < 0)
3414 {
3415 ThrowPerlException(exception,OptionError,
3416 "UnrecognizedType",SvPV(ST(i),na));
3417 return;
3418 }
cristybcd59342015-06-07 14:07:19 +00003419 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003420 break;
3421 }
3422 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3423 attribute);
3424 break;
3425 }
3426 case 'F':
3427 case 'f':
3428 {
3429 if (LocaleCompare(attribute,"fuzz") == 0)
3430 {
3431 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3432 break;
3433 }
3434 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3435 attribute);
3436 break;
3437 }
3438 case 'I':
3439 case 'i':
3440 {
3441 if (LocaleCompare(attribute,"image") == 0)
3442 {
3443 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3444 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3445 break;
3446 }
3447 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3448 attribute);
3449 break;
3450 }
3451 case 'M':
3452 case 'm':
3453 {
3454 if (LocaleCompare(attribute,"metric") == 0)
3455 {
3456 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3457 SvPV(ST(i),na));
3458 if (option < 0)
3459 {
3460 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3461 SvPV(ST(i),na));
3462 break;
3463 }
3464 metric=(MetricType) option;
3465 break;
3466 }
3467 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3468 attribute);
3469 break;
3470 }
3471 default:
3472 {
3473 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3474 attribute);
3475 break;
3476 }
3477 }
3478 }
3479 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3480 exception);
3481 if (difference_image != (Image *) NULL)
3482 {
3483 difference_image->error.mean_error_per_pixel=distortion;
3484 AddImageToRegistry(sv,difference_image);
3485 rv=newRV(sv);
3486 av_push(av,sv_bless(rv,hv));
3487 SvREFCNT_dec(sv);
3488 }
3489 exception=DestroyExceptionInfo(exception);
3490 ST(0)=av_reference;
3491 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3492 XSRETURN(1);
3493
3494 PerlException:
3495 InheritPerlException(exception,perl_exception);
3496 exception=DestroyExceptionInfo(exception);
3497 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3498 SvPOK_on(perl_exception);
3499 ST(0)=sv_2mortal(perl_exception);
3500 XSRETURN(1);
3501 }
3502
3503#
3504###############################################################################
3505# #
3506# #
3507# #
cristy15655332013-10-06 00:27:33 +00003508# C o m p l e x I m a g e s #
3509# #
3510# #
3511# #
3512###############################################################################
3513#
3514#
3515void
3516ComplexImages(ref)
3517 Image::Magick ref=NO_INIT
3518 ALIAS:
3519 ComplexImages = 1
3520 compleximages = 2
3521 PPCODE:
3522 {
3523 AV
3524 *av;
3525
3526 char
3527 *attribute,
3528 *p;
3529
cristyfa21e9e2013-10-07 10:37:38 +00003530 ComplexOperator
3531 op;
3532
cristy15655332013-10-06 00:27:33 +00003533 ExceptionInfo
3534 *exception;
3535
3536 HV
3537 *hv;
3538
3539 Image
3540 *image;
3541
cristy15655332013-10-06 00:27:33 +00003542 register ssize_t
3543 i;
3544
3545 struct PackageInfo
3546 *info;
3547
3548 SV
3549 *perl_exception,
3550 *reference,
3551 *rv,
3552 *sv;
3553
3554 PERL_UNUSED_VAR(ref);
3555 PERL_UNUSED_VAR(ix);
3556 exception=AcquireExceptionInfo();
3557 perl_exception=newSVpv("",0);
3558 sv=NULL;
3559 if (sv_isobject(ST(0)) == 0)
3560 {
3561 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3562 PackageName);
3563 goto PerlException;
3564 }
3565 reference=SvRV(ST(0));
3566 hv=SvSTASH(reference);
3567 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3568 if (image == (Image *) NULL)
3569 {
3570 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3571 PackageName);
3572 goto PerlException;
3573 }
cristyfd168722013-10-07 15:59:31 +00003574 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003575 if (items == 2)
3576 {
3577 ssize_t
3578 in;
3579
3580 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3581 SvPV(ST(1),na));
3582 if (in < 0)
3583 {
3584 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3585 SvPV(ST(1),na));
3586 return;
3587 }
cristyfa21e9e2013-10-07 10:37:38 +00003588 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003589 }
3590 else
3591 for (i=2; i < items; i+=2)
3592 {
3593 attribute=(char *) SvPV(ST(i-1),na);
3594 switch (*attribute)
3595 {
3596 case 'O':
3597 case 'o':
3598 {
3599 if (LocaleCompare(attribute,"operator") == 0)
3600 {
3601 ssize_t
3602 in;
3603
3604 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3605 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3606 if (in < 0)
3607 {
3608 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3609 SvPV(ST(i),na));
3610 return;
3611 }
cristyfa21e9e2013-10-07 10:37:38 +00003612 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003613 break;
3614 }
3615 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3616 attribute);
3617 break;
3618 }
3619 default:
3620 {
3621 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3622 attribute);
3623 break;
3624 }
3625 }
3626 }
3627 image=ComplexImages(image,op,exception);
3628 if (image == (Image *) NULL)
3629 goto PerlException;
3630 /*
3631 Create blessed Perl array for the returned image.
3632 */
3633 av=newAV();
3634 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3635 SvREFCNT_dec(av);
3636 AddImageToRegistry(sv,image);
3637 rv=newRV(sv);
3638 av_push(av,sv_bless(rv,hv));
3639 SvREFCNT_dec(sv);
3640 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003641 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3642 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003643 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3644 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003645 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003646 SetImageInfo(info->image_info,0,exception);
3647 exception=DestroyExceptionInfo(exception);
3648 SvREFCNT_dec(perl_exception);
3649 XSRETURN(1);
3650
3651 PerlException:
3652 InheritPerlException(exception,perl_exception);
3653 exception=DestroyExceptionInfo(exception);
3654 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3655 SvPOK_on(perl_exception);
3656 ST(0)=sv_2mortal(perl_exception);
3657 XSRETURN(1);
3658 }
3659
3660#
3661###############################################################################
3662# #
3663# #
3664# #
cristy4a3ce0a2013-08-03 20:06:59 +00003665# C o m p a r e L a y e r s #
3666# #
3667# #
3668# #
3669###############################################################################
3670#
3671#
3672void
3673CompareLayers(ref)
3674 Image::Magick ref=NO_INIT
3675 ALIAS:
3676 CompareImagesLayers = 1
3677 comparelayers = 2
3678 compareimagelayers = 3
3679 PPCODE:
3680 {
3681 AV
3682 *av;
3683
3684 char
3685 *attribute;
3686
3687 ExceptionInfo
3688 *exception;
3689
3690 HV
3691 *hv;
3692
3693 Image
3694 *image;
3695
3696 LayerMethod
3697 method;
3698
3699 register ssize_t
3700 i;
3701
3702 ssize_t
3703 option;
3704
3705 struct PackageInfo
3706 *info;
3707
3708 SV
3709 *av_reference,
3710 *perl_exception,
3711 *reference,
3712 *rv,
3713 *sv;
3714
3715 PERL_UNUSED_VAR(ref);
3716 PERL_UNUSED_VAR(ix);
3717 exception=AcquireExceptionInfo();
3718 perl_exception=newSVpv("",0);
3719 sv=NULL;
3720 if (sv_isobject(ST(0)) == 0)
3721 {
3722 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3723 PackageName);
3724 goto PerlException;
3725 }
3726 reference=SvRV(ST(0));
3727 hv=SvSTASH(reference);
3728 av=newAV();
3729 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3730 SvREFCNT_dec(av);
3731 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3732 if (image == (Image *) NULL)
3733 {
3734 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3735 PackageName);
3736 goto PerlException;
3737 }
3738 method=CompareAnyLayer;
3739 for (i=2; i < items; i+=2)
3740 {
3741 attribute=(char *) SvPV(ST(i-1),na);
3742 switch (*attribute)
3743 {
3744 case 'M':
3745 case 'm':
3746 {
3747 if (LocaleCompare(attribute,"method") == 0)
3748 {
3749 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3750 SvPV(ST(i),na));
3751 if (option < 0)
3752 {
3753 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3754 SvPV(ST(i),na));
3755 break;
3756 }
3757 method=(LayerMethod) option;
3758 break;
3759 }
3760 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3761 attribute);
3762 break;
3763 }
3764 default:
3765 {
3766 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3767 attribute);
3768 break;
3769 }
3770 }
3771 }
3772 image=CompareImagesLayers(image,method,exception);
3773 if (image == (Image *) NULL)
3774 goto PerlException;
3775 for ( ; image; image=image->next)
3776 {
3777 AddImageToRegistry(sv,image);
3778 rv=newRV(sv);
3779 av_push(av,sv_bless(rv,hv));
3780 SvREFCNT_dec(sv);
3781 }
3782 exception=DestroyExceptionInfo(exception);
3783 ST(0)=av_reference;
3784 SvREFCNT_dec(perl_exception);
3785 XSRETURN(1);
3786
3787 PerlException:
3788 InheritPerlException(exception,perl_exception);
3789 exception=DestroyExceptionInfo(exception);
3790 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3791 SvPOK_on(perl_exception);
3792 ST(0)=sv_2mortal(perl_exception);
3793 XSRETURN(1);
3794 }
3795
3796#
3797###############################################################################
3798# #
3799# #
3800# #
3801# D e s t r o y #
3802# #
3803# #
3804# #
3805###############################################################################
3806#
3807#
3808void
3809DESTROY(ref)
3810 Image::Magick ref=NO_INIT
3811 PPCODE:
3812 {
3813 SV
3814 *reference;
3815
3816 PERL_UNUSED_VAR(ref);
3817 if (sv_isobject(ST(0)) == 0)
3818 croak("ReferenceIsNotMyType");
3819 reference=SvRV(ST(0));
3820 switch (SvTYPE(reference))
3821 {
3822 case SVt_PVAV:
3823 {
3824 char
cristy151b66d2015-04-15 10:50:31 +00003825 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003826
3827 const SV
3828 *key;
3829
3830 HV
3831 *hv;
3832
3833 GV
3834 **gvp;
3835
3836 struct PackageInfo
3837 *info;
3838
3839 SV
3840 *sv;
3841
3842 /*
3843 Array (AV *) reference
3844 */
cristy151b66d2015-04-15 10:50:31 +00003845 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003846 XS_VERSION,reference);
3847 hv=gv_stashpv(PackageName, FALSE);
3848 if (!hv)
3849 break;
3850 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3851 if (!gvp)
3852 break;
3853 sv=GvSV(*gvp);
3854 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3855 {
3856 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3857 DestroyPackageInfo(info);
3858 }
3859 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3860 (void) key;
3861 break;
3862 }
3863 case SVt_PVMG:
3864 {
3865 Image
3866 *image;
3867
3868 /*
3869 Blessed scalar = (Image *) SvIV(reference)
3870 */
3871 image=INT2PTR(Image *,SvIV(reference));
3872 if (image != (Image *) NULL)
3873 DeleteImageFromRegistry(reference,image);
3874 break;
3875 }
3876 default:
3877 break;
3878 }
3879 }
3880
3881#
3882###############################################################################
3883# #
3884# #
3885# #
3886# D i s p l a y #
3887# #
3888# #
3889# #
3890###############################################################################
3891#
3892#
3893void
3894Display(ref,...)
3895 Image::Magick ref=NO_INIT
3896 ALIAS:
3897 DisplayImage = 1
3898 display = 2
3899 displayimage = 3
3900 PPCODE:
3901 {
3902 ExceptionInfo
3903 *exception;
3904
3905 Image
3906 *image;
3907
3908 register ssize_t
3909 i;
3910
3911 struct PackageInfo
3912 *info,
3913 *package_info;
3914
3915 SV
3916 *perl_exception,
3917 *reference;
3918
3919 PERL_UNUSED_VAR(ref);
3920 PERL_UNUSED_VAR(ix);
3921 exception=AcquireExceptionInfo();
3922 perl_exception=newSVpv("",0);
3923 package_info=(struct PackageInfo *) NULL;
3924 if (sv_isobject(ST(0)) == 0)
3925 {
3926 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3927 PackageName);
3928 goto PerlException;
3929 }
3930 reference=SvRV(ST(0));
3931 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3932 if (image == (Image *) NULL)
3933 {
3934 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3935 PackageName);
3936 goto PerlException;
3937 }
3938 package_info=ClonePackageInfo(info,exception);
3939 if (items == 2)
3940 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3941 else
3942 if (items > 2)
3943 for (i=2; i < items; i+=2)
3944 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3945 exception);
3946 (void) DisplayImages(package_info->image_info,image,exception);
3947 (void) CatchImageException(image);
3948
3949 PerlException:
3950 if (package_info != (struct PackageInfo *) NULL)
3951 DestroyPackageInfo(package_info);
3952 InheritPerlException(exception,perl_exception);
3953 exception=DestroyExceptionInfo(exception);
3954 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3955 SvPOK_on(perl_exception);
3956 ST(0)=sv_2mortal(perl_exception);
3957 XSRETURN(1);
3958 }
3959
3960#
3961###############################################################################
3962# #
3963# #
3964# #
3965# E v a l u a t e I m a g e s #
3966# #
3967# #
3968# #
3969###############################################################################
3970#
3971#
3972void
3973EvaluateImages(ref)
3974 Image::Magick ref=NO_INIT
3975 ALIAS:
3976 EvaluateImages = 1
3977 evaluateimages = 2
3978 PPCODE:
3979 {
3980 AV
3981 *av;
3982
3983 char
3984 *attribute,
3985 *p;
3986
3987 ExceptionInfo
3988 *exception;
3989
3990 HV
3991 *hv;
3992
3993 Image
3994 *image;
3995
3996 MagickEvaluateOperator
3997 op;
3998
3999 register ssize_t
4000 i;
4001
4002 struct PackageInfo
4003 *info;
4004
4005 SV
4006 *perl_exception,
4007 *reference,
4008 *rv,
4009 *sv;
4010
4011 PERL_UNUSED_VAR(ref);
4012 PERL_UNUSED_VAR(ix);
4013 exception=AcquireExceptionInfo();
4014 perl_exception=newSVpv("",0);
4015 sv=NULL;
4016 if (sv_isobject(ST(0)) == 0)
4017 {
4018 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4019 PackageName);
4020 goto PerlException;
4021 }
4022 reference=SvRV(ST(0));
4023 hv=SvSTASH(reference);
4024 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4025 if (image == (Image *) NULL)
4026 {
4027 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4028 PackageName);
4029 goto PerlException;
4030 }
4031 op=MeanEvaluateOperator;
4032 if (items == 2)
4033 {
4034 ssize_t
4035 in;
4036
4037 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
4038 SvPV(ST(1),na));
4039 if (in < 0)
4040 {
4041 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4042 SvPV(ST(1),na));
4043 return;
4044 }
4045 op=(MagickEvaluateOperator) in;
4046 }
4047 else
4048 for (i=2; i < items; i+=2)
4049 {
4050 attribute=(char *) SvPV(ST(i-1),na);
4051 switch (*attribute)
4052 {
4053 case 'O':
4054 case 'o':
4055 {
4056 if (LocaleCompare(attribute,"operator") == 0)
4057 {
4058 ssize_t
4059 in;
4060
4061 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4062 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4063 if (in < 0)
4064 {
4065 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4066 SvPV(ST(i),na));
4067 return;
4068 }
4069 op=(MagickEvaluateOperator) in;
4070 break;
4071 }
4072 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4073 attribute);
4074 break;
4075 }
4076 default:
4077 {
4078 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4079 attribute);
4080 break;
4081 }
4082 }
4083 }
4084 image=EvaluateImages(image,op,exception);
4085 if (image == (Image *) NULL)
4086 goto PerlException;
4087 /*
4088 Create blessed Perl array for the returned image.
4089 */
4090 av=newAV();
4091 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4092 SvREFCNT_dec(av);
4093 AddImageToRegistry(sv,image);
4094 rv=newRV(sv);
4095 av_push(av,sv_bless(rv,hv));
4096 SvREFCNT_dec(sv);
4097 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004098 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4099 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004100 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4101 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004102 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004103 SetImageInfo(info->image_info,0,exception);
4104 exception=DestroyExceptionInfo(exception);
4105 SvREFCNT_dec(perl_exception);
4106 XSRETURN(1);
4107
4108 PerlException:
4109 InheritPerlException(exception,perl_exception);
4110 exception=DestroyExceptionInfo(exception);
4111 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4112 SvPOK_on(perl_exception);
4113 ST(0)=sv_2mortal(perl_exception);
4114 XSRETURN(1);
4115 }
4116
4117#
4118###############################################################################
4119# #
4120# #
4121# #
4122# F e a t u r e s #
4123# #
4124# #
4125# #
4126###############################################################################
4127#
4128#
4129void
4130Features(ref,...)
4131 Image::Magick ref=NO_INIT
4132 ALIAS:
4133 FeaturesImage = 1
4134 features = 2
4135 featuresimage = 3
4136 PPCODE:
4137 {
4138#define ChannelFeatures(channel,direction) \
4139{ \
Cristyb1710fe2017-02-11 13:51:48 -05004140 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004141 channel_features[channel].angular_second_moment[direction]); \
4142 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004143 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004144 channel_features[channel].contrast[direction]); \
4145 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004146 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004147 channel_features[channel].contrast[direction]); \
4148 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004149 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004150 channel_features[channel].variance_sum_of_squares[direction]); \
4151 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004152 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004153 channel_features[channel].inverse_difference_moment[direction]); \
4154 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004155 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004156 channel_features[channel].sum_average[direction]); \
4157 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004158 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004159 channel_features[channel].sum_variance[direction]); \
4160 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004161 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004162 channel_features[channel].sum_entropy[direction]); \
4163 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004164 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004165 channel_features[channel].entropy[direction]); \
4166 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004167 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004168 channel_features[channel].difference_variance[direction]); \
4169 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004170 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004171 channel_features[channel].difference_entropy[direction]); \
4172 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004173 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004174 channel_features[channel].measure_of_correlation_1[direction]); \
4175 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004176 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004177 channel_features[channel].measure_of_correlation_2[direction]); \
4178 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004179 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004180 channel_features[channel].maximum_correlation_coefficient[direction]); \
4181 PUSHs(sv_2mortal(newSVpv(message,0))); \
4182}
4183
4184 AV
4185 *av;
4186
4187 char
4188 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004189 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004190
4191 ChannelFeatures
4192 *channel_features;
4193
4194 double
4195 distance;
4196
4197 ExceptionInfo
4198 *exception;
4199
4200 Image
4201 *image;
4202
4203 register ssize_t
4204 i;
4205
4206 ssize_t
4207 count;
4208
4209 struct PackageInfo
4210 *info;
4211
4212 SV
4213 *perl_exception,
4214 *reference;
4215
4216 PERL_UNUSED_VAR(ref);
4217 PERL_UNUSED_VAR(ix);
4218 exception=AcquireExceptionInfo();
4219 perl_exception=newSVpv("",0);
4220 av=NULL;
4221 if (sv_isobject(ST(0)) == 0)
4222 {
4223 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4224 PackageName);
4225 goto PerlException;
4226 }
4227 reference=SvRV(ST(0));
4228 av=newAV();
4229 SvREFCNT_dec(av);
4230 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4231 if (image == (Image *) NULL)
4232 {
4233 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4234 PackageName);
4235 goto PerlException;
4236 }
cristy7dbd9262014-07-02 17:53:42 +00004237 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004238 for (i=2; i < items; i+=2)
4239 {
4240 attribute=(char *) SvPV(ST(i-1),na);
4241 switch (*attribute)
4242 {
4243 case 'D':
4244 case 'd':
4245 {
4246 if (LocaleCompare(attribute,"distance") == 0)
4247 {
4248 distance=StringToLong((char *) SvPV(ST(1),na));
4249 break;
4250 }
4251 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4252 attribute);
4253 break;
4254 }
4255 default:
4256 {
4257 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4258 attribute);
4259 break;
4260 }
4261 }
4262 }
4263 count=0;
4264 for ( ; image; image=image->next)
4265 {
Cristy5a854dc2017-02-11 15:43:46 -05004266 register ssize_t
4267 j;
4268
cristy4a3ce0a2013-08-03 20:06:59 +00004269 channel_features=GetImageFeatures(image,distance,exception);
4270 if (channel_features == (ChannelFeatures *) NULL)
4271 continue;
4272 count++;
Cristy5a854dc2017-02-11 15:43:46 -05004273 for (j=0; j < 4; j++)
cristy4a3ce0a2013-08-03 20:06:59 +00004274 {
Cristy5a854dc2017-02-11 15:43:46 -05004275 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
4276 {
4277 PixelChannel channel=GetPixelChannelChannel(image,i);
4278 PixelTrait traits=GetPixelChannelTraits(image,channel);
4279 if (traits == UndefinedPixelTrait)
4280 continue;
4281 EXTEND(sp,14*(i+1)*count);
4282 ChannelFeatures(channel,j);
4283 }
cristy4a3ce0a2013-08-03 20:06:59 +00004284 }
4285 channel_features=(ChannelFeatures *)
4286 RelinquishMagickMemory(channel_features);
4287 }
4288
4289 PerlException:
4290 InheritPerlException(exception,perl_exception);
4291 exception=DestroyExceptionInfo(exception);
4292 SvREFCNT_dec(perl_exception);
4293 }
4294
4295#
4296###############################################################################
4297# #
4298# #
4299# #
4300# F l a t t e n #
4301# #
4302# #
4303# #
4304###############################################################################
4305#
4306#
4307void
4308Flatten(ref)
4309 Image::Magick ref=NO_INIT
4310 ALIAS:
4311 FlattenImage = 1
4312 flatten = 2
4313 flattenimage = 3
4314 PPCODE:
4315 {
4316 AV
4317 *av;
4318
4319 char
4320 *attribute,
4321 *p;
4322
4323 ExceptionInfo
4324 *exception;
4325
4326 HV
4327 *hv;
4328
4329 Image
4330 *image;
4331
4332 PixelInfo
4333 background_color;
4334
4335 register ssize_t
4336 i;
4337
4338 struct PackageInfo
4339 *info;
4340
4341 SV
4342 *perl_exception,
4343 *reference,
4344 *rv,
4345 *sv;
4346
4347 PERL_UNUSED_VAR(ref);
4348 PERL_UNUSED_VAR(ix);
4349 exception=AcquireExceptionInfo();
4350 perl_exception=newSVpv("",0);
4351 sv=NULL;
4352 if (sv_isobject(ST(0)) == 0)
4353 {
4354 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4355 PackageName);
4356 goto PerlException;
4357 }
4358 reference=SvRV(ST(0));
4359 hv=SvSTASH(reference);
4360 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4361 if (image == (Image *) NULL)
4362 {
4363 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4364 PackageName);
4365 goto PerlException;
4366 }
4367 background_color=image->background_color;
4368 if (items == 2)
4369 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4370 &background_color,exception);
4371 else
4372 for (i=2; i < items; i+=2)
4373 {
4374 attribute=(char *) SvPV(ST(i-1),na);
4375 switch (*attribute)
4376 {
4377 case 'B':
4378 case 'b':
4379 {
4380 if (LocaleCompare(attribute,"background") == 0)
4381 {
4382 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4383 AllCompliance,&background_color,exception);
4384 break;
4385 }
4386 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4387 attribute);
4388 break;
4389 }
4390 default:
4391 {
4392 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4393 attribute);
4394 break;
4395 }
4396 }
4397 }
4398 image->background_color=background_color;
4399 image=MergeImageLayers(image,FlattenLayer,exception);
4400 if (image == (Image *) NULL)
4401 goto PerlException;
4402 /*
4403 Create blessed Perl array for the returned image.
4404 */
4405 av=newAV();
4406 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4407 SvREFCNT_dec(av);
4408 AddImageToRegistry(sv,image);
4409 rv=newRV(sv);
4410 av_push(av,sv_bless(rv,hv));
4411 SvREFCNT_dec(sv);
4412 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004413 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4414 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004415 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4416 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004417 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004418 SetImageInfo(info->image_info,0,exception);
4419 exception=DestroyExceptionInfo(exception);
4420 SvREFCNT_dec(perl_exception);
4421 XSRETURN(1);
4422
4423 PerlException:
4424 InheritPerlException(exception,perl_exception);
4425 exception=DestroyExceptionInfo(exception);
4426 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4427 SvPOK_on(perl_exception); /* return messages in string context */
4428 ST(0)=sv_2mortal(perl_exception);
4429 XSRETURN(1);
4430 }
4431
4432#
4433###############################################################################
4434# #
4435# #
4436# #
4437# F x #
4438# #
4439# #
4440# #
4441###############################################################################
4442#
4443#
4444void
4445Fx(ref,...)
4446 Image::Magick ref=NO_INIT
4447 ALIAS:
4448 FxImage = 1
4449 fx = 2
4450 fximage = 3
4451 PPCODE:
4452 {
4453 AV
4454 *av;
4455
4456 char
4457 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004458 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004459
4460 ChannelType
4461 channel,
4462 channel_mask;
4463
4464 ExceptionInfo
4465 *exception;
4466
4467 HV
4468 *hv;
4469
4470 Image
4471 *image;
4472
4473 register ssize_t
4474 i;
4475
4476 struct PackageInfo
4477 *info;
4478
4479 SV
4480 *av_reference,
4481 *perl_exception,
4482 *reference,
4483 *rv,
4484 *sv;
4485
4486 PERL_UNUSED_VAR(ref);
4487 PERL_UNUSED_VAR(ix);
4488 exception=AcquireExceptionInfo();
4489 perl_exception=newSVpv("",0);
4490 sv=NULL;
4491 attribute=NULL;
4492 av=NULL;
4493 if (sv_isobject(ST(0)) == 0)
4494 {
4495 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4496 PackageName);
4497 goto PerlException;
4498 }
4499 reference=SvRV(ST(0));
4500 hv=SvSTASH(reference);
4501 av=newAV();
4502 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4503 SvREFCNT_dec(av);
4504 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4505 if (image == (Image *) NULL)
4506 {
4507 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4508 PackageName);
4509 goto PerlException;
4510 }
4511 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4512 /*
4513 Get options.
4514 */
4515 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004516 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004517 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004518 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004519 else
4520 for (i=2; i < items; i+=2)
4521 {
4522 attribute=(char *) SvPV(ST(i-1),na);
4523 switch (*attribute)
4524 {
4525 case 'C':
4526 case 'c':
4527 {
4528 if (LocaleCompare(attribute,"channel") == 0)
4529 {
4530 ssize_t
4531 option;
4532
4533 option=ParseChannelOption(SvPV(ST(i),na));
4534 if (option < 0)
4535 {
4536 ThrowPerlException(exception,OptionError,
4537 "UnrecognizedType",SvPV(ST(i),na));
4538 return;
4539 }
4540 channel=(ChannelType) option;
4541 break;
4542 }
4543 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4544 attribute);
4545 break;
4546 }
4547 case 'E':
4548 case 'e':
4549 {
4550 if (LocaleCompare(attribute,"expression") == 0)
4551 {
4552 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004553 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004554 break;
4555 }
4556 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4557 attribute);
4558 break;
4559 }
4560 default:
4561 {
4562 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4563 attribute);
4564 break;
4565 }
4566 }
4567 }
4568 channel_mask=SetImageChannelMask(image,channel);
4569 image=FxImage(image,expression,exception);
4570 if (image != (Image *) NULL)
4571 (void) SetImageChannelMask(image,channel_mask);
4572 if (image == (Image *) NULL)
4573 goto PerlException;
4574 for ( ; image; image=image->next)
4575 {
4576 AddImageToRegistry(sv,image);
4577 rv=newRV(sv);
4578 av_push(av,sv_bless(rv,hv));
4579 SvREFCNT_dec(sv);
4580 }
4581 exception=DestroyExceptionInfo(exception);
4582 ST(0)=av_reference;
4583 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4584 XSRETURN(1);
4585
4586 PerlException:
4587 InheritPerlException(exception,perl_exception);
4588 exception=DestroyExceptionInfo(exception);
4589 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4590 SvPOK_on(perl_exception);
4591 ST(0)=sv_2mortal(perl_exception);
4592 XSRETURN(1);
4593 }
4594
4595#
4596###############################################################################
4597# #
4598# #
4599# #
4600# G e t #
4601# #
4602# #
4603# #
4604###############################################################################
4605#
4606#
4607void
4608Get(ref,...)
4609 Image::Magick ref=NO_INIT
4610 ALIAS:
4611 GetAttributes = 1
4612 GetAttribute = 2
4613 get = 3
4614 getattributes = 4
4615 getattribute = 5
4616 PPCODE:
4617 {
4618 char
4619 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004620 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004621
4622 const char
4623 *value;
4624
4625 ExceptionInfo
4626 *exception;
4627
4628 Image
4629 *image;
4630
4631 long
4632 j;
4633
4634 register ssize_t
4635 i;
4636
4637 struct PackageInfo
4638 *info;
4639
4640 SV
4641 *perl_exception,
4642 *reference,
4643 *s;
4644
4645 PERL_UNUSED_VAR(ref);
4646 PERL_UNUSED_VAR(ix);
4647 exception=AcquireExceptionInfo();
4648 perl_exception=newSVpv("",0);
4649 if (sv_isobject(ST(0)) == 0)
4650 {
4651 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4652 PackageName);
4653 XSRETURN_EMPTY;
4654 }
4655 reference=SvRV(ST(0));
4656 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4657 if (image == (Image *) NULL && !info)
4658 XSRETURN_EMPTY;
4659 EXTEND(sp,items);
4660 for (i=1; i < items; i++)
4661 {
4662 attribute=(char *) SvPV(ST(i),na);
4663 s=NULL;
4664 switch (*attribute)
4665 {
4666 case 'A':
4667 case 'a':
4668 {
4669 if (LocaleCompare(attribute,"adjoin") == 0)
4670 {
4671 if (info)
4672 s=newSViv((ssize_t) info->image_info->adjoin);
4673 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4674 continue;
4675 }
4676 if (LocaleCompare(attribute,"antialias") == 0)
4677 {
4678 if (info)
4679 s=newSViv((ssize_t) info->image_info->antialias);
4680 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4681 continue;
4682 }
4683 if (LocaleCompare(attribute,"area") == 0)
4684 {
4685 s=newSViv(GetMagickResource(AreaResource));
4686 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4687 continue;
4688 }
4689 if (LocaleCompare(attribute,"attenuate") == 0)
4690 {
4691 const char
4692 *value;
4693
4694 value=GetImageProperty(image,attribute,exception);
4695 if (value != (const char *) NULL)
4696 s=newSVpv(value,0);
4697 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4698 continue;
4699 }
4700 if (LocaleCompare(attribute,"authenticate") == 0)
4701 {
4702 if (info)
4703 {
4704 const char
4705 *option;
4706
4707 option=GetImageOption(info->image_info,attribute);
4708 if (option != (const char *) NULL)
4709 s=newSVpv(option,0);
4710 }
4711 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4712 continue;
4713 }
4714 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4715 attribute);
4716 break;
4717 }
4718 case 'B':
4719 case 'b':
4720 {
4721 if (LocaleCompare(attribute,"background") == 0)
4722 {
4723 if (image == (Image *) NULL)
4724 break;
cristy151b66d2015-04-15 10:50:31 +00004725 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004726 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4727 (double) image->background_color.green,
4728 (double) image->background_color.blue,
4729 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004730 s=newSVpv(color,0);
4731 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4732 continue;
4733 }
4734 if (LocaleCompare(attribute,"base-columns") == 0)
4735 {
4736 if (image != (Image *) NULL)
4737 s=newSViv((ssize_t) image->magick_columns);
4738 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4739 continue;
4740 }
4741 if (LocaleCompare(attribute,"base-filename") == 0)
4742 {
4743 if (image != (Image *) NULL)
4744 s=newSVpv(image->magick_filename,0);
4745 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4746 continue;
4747 }
4748 if (LocaleCompare(attribute,"base-height") == 0)
4749 {
4750 if (image != (Image *) NULL)
4751 s=newSViv((ssize_t) image->magick_rows);
4752 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4753 continue;
4754 }
4755 if (LocaleCompare(attribute,"base-rows") == 0)
4756 {
4757 if (image != (Image *) NULL)
4758 s=newSViv((ssize_t) image->magick_rows);
4759 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4760 continue;
4761 }
4762 if (LocaleCompare(attribute,"base-width") == 0)
4763 {
4764 if (image != (Image *) NULL)
4765 s=newSViv((ssize_t) image->magick_columns);
4766 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4767 continue;
4768 }
4769 if (LocaleCompare(attribute,"blue-primary") == 0)
4770 {
4771 if (image == (Image *) NULL)
4772 break;
Cristyb1710fe2017-02-11 13:51:48 -05004773 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004774 image->chromaticity.blue_primary.x,
4775 image->chromaticity.blue_primary.y);
4776 s=newSVpv(color,0);
4777 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4778 continue;
4779 }
4780 if (LocaleCompare(attribute,"bordercolor") == 0)
4781 {
4782 if (image == (Image *) NULL)
4783 break;
cristy151b66d2015-04-15 10:50:31 +00004784 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004785 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4786 (double) image->border_color.green,
4787 (double) image->border_color.blue,
4788 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004789 s=newSVpv(color,0);
4790 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4791 continue;
4792 }
4793 if (LocaleCompare(attribute,"bounding-box") == 0)
4794 {
4795 char
cristy151b66d2015-04-15 10:50:31 +00004796 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004797
4798 RectangleInfo
4799 page;
4800
4801 if (image == (Image *) NULL)
4802 break;
4803 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004804 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004805 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4806 page.height,(double) page.x,(double) page.y);
4807 s=newSVpv(geometry,0);
4808 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4809 continue;
4810 }
4811 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4812 attribute);
4813 break;
4814 }
4815 case 'C':
4816 case 'c':
4817 {
4818 if (LocaleCompare(attribute,"class") == 0)
4819 {
4820 if (image == (Image *) NULL)
4821 break;
4822 s=newSViv(image->storage_class);
4823 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4824 image->storage_class));
4825 SvIOK_on(s);
4826 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4827 continue;
4828 }
4829 if (LocaleCompare(attribute,"clip-mask") == 0)
4830 {
4831 if (image != (Image *) NULL)
4832 {
4833 Image
4834 *mask_image;
4835
4836 SV
4837 *sv;
4838
4839 sv=NULL;
4840 if (image->read_mask == MagickFalse)
4841 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004842 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004843 if (mask_image != (Image *) NULL)
4844 {
4845 AddImageToRegistry(sv,mask_image);
4846 s=sv_bless(newRV(sv),SvSTASH(reference));
4847 }
4848 }
4849 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4850 continue;
4851 }
4852 if (LocaleCompare(attribute,"clip-path") == 0)
4853 {
4854 if (image != (Image *) NULL)
4855 {
4856 Image
4857 *mask_image;
4858
4859 SV
4860 *sv;
4861
4862 sv=NULL;
4863 if (image->read_mask != MagickFalse)
4864 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004865 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004866 if (mask_image != (Image *) NULL)
4867 {
4868 AddImageToRegistry(sv,mask_image);
4869 s=sv_bless(newRV(sv),SvSTASH(reference));
4870 }
4871 }
4872 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4873 continue;
4874 }
4875 if (LocaleCompare(attribute,"compression") == 0)
4876 {
4877 j=info ? info->image_info->compression : image ?
4878 image->compression : UndefinedCompression;
4879 if (info)
4880 if (info->image_info->compression == UndefinedCompression)
4881 j=image->compression;
4882 s=newSViv(j);
4883 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4884 j));
4885 SvIOK_on(s);
4886 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4887 continue;
4888 }
4889 if (LocaleCompare(attribute,"colorspace") == 0)
4890 {
4891 j=image ? image->colorspace : RGBColorspace;
4892 s=newSViv(j);
4893 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4894 j));
4895 SvIOK_on(s);
4896 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4897 continue;
4898 }
4899 if (LocaleCompare(attribute,"colors") == 0)
4900 {
4901 if (image != (Image *) NULL)
4902 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4903 exception));
4904 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4905 continue;
4906 }
4907 if (LocaleNCompare(attribute,"colormap",8) == 0)
4908 {
4909 int
4910 items;
4911
4912 if (image == (Image *) NULL || !image->colormap)
4913 break;
4914 j=0;
4915 items=sscanf(attribute,"%*[^[][%ld",&j);
4916 (void) items;
4917 if (j > (ssize_t) image->colors)
4918 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004919 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004920 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4921 (double) image->colormap[j].green,
4922 (double) image->colormap[j].blue,
4923 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004924 s=newSVpv(color,0);
4925 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4926 continue;
4927 }
4928 if (LocaleCompare(attribute,"columns") == 0)
4929 {
4930 if (image != (Image *) NULL)
4931 s=newSViv((ssize_t) image->columns);
4932 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4933 continue;
4934 }
4935 if (LocaleCompare(attribute,"comment") == 0)
4936 {
4937 const char
4938 *value;
4939
Cristy935a4052017-03-31 17:45:37 -04004940 value=GetImageProperty(image,attribute,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004941 if (value != (const char *) NULL)
4942 s=newSVpv(value,0);
4943 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4944 continue;
4945 }
4946 if (LocaleCompare(attribute,"copyright") == 0)
4947 {
4948 s=newSVpv(GetMagickCopyright(),0);
4949 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4950 continue;
4951 }
4952 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4953 attribute);
4954 break;
4955 }
4956 case 'D':
4957 case 'd':
4958 {
4959 if (LocaleCompare(attribute,"density") == 0)
4960 {
4961 char
cristy151b66d2015-04-15 10:50:31 +00004962 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004963
4964 if (image == (Image *) NULL)
4965 break;
Cristyb1710fe2017-02-11 13:51:48 -05004966 (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004967 image->resolution.x,image->resolution.y);
4968 s=newSVpv(geometry,0);
4969 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4970 continue;
4971 }
4972 if (LocaleCompare(attribute,"delay") == 0)
4973 {
4974 if (image != (Image *) NULL)
4975 s=newSViv((ssize_t) image->delay);
4976 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4977 continue;
4978 }
4979 if (LocaleCompare(attribute,"depth") == 0)
4980 {
4981 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4982 if (image != (Image *) NULL)
4983 s=newSViv((ssize_t) GetImageDepth(image,exception));
4984 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4985 continue;
4986 }
4987 if (LocaleCompare(attribute,"directory") == 0)
4988 {
4989 if (image && image->directory)
4990 s=newSVpv(image->directory,0);
4991 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4992 continue;
4993 }
4994 if (LocaleCompare(attribute,"dispose") == 0)
4995 {
4996 if (image == (Image *) NULL)
4997 break;
4998
4999 s=newSViv(image->dispose);
5000 (void) sv_setpv(s,
5001 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
5002 SvIOK_on(s);
5003 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5004 continue;
5005 }
5006 if (LocaleCompare(attribute,"disk") == 0)
5007 {
5008 s=newSViv(GetMagickResource(DiskResource));
5009 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5010 continue;
5011 }
5012 if (LocaleCompare(attribute,"dither") == 0)
5013 {
5014 if (info)
5015 s=newSViv((ssize_t) info->image_info->dither);
5016 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5017 continue;
5018 }
5019 if (LocaleCompare(attribute,"display") == 0) /* same as server */
5020 {
5021 if (info && info->image_info->server_name)
5022 s=newSVpv(info->image_info->server_name,0);
5023 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5024 continue;
5025 }
5026 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5027 attribute);
5028 break;
5029 }
5030 case 'E':
5031 case 'e':
5032 {
5033 if (LocaleCompare(attribute,"elapsed-time") == 0)
5034 {
5035 if (image != (Image *) NULL)
5036 s=newSVnv(GetElapsedTime(&image->timer));
5037 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5038 continue;
5039 }
5040 if (LocaleCompare(attribute,"endian") == 0)
5041 {
5042 j=info ? info->image_info->endian : image ? image->endian :
5043 UndefinedEndian;
5044 s=newSViv(j);
5045 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
5046 SvIOK_on(s);
5047 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5048 continue;
5049 }
5050 if (LocaleCompare(attribute,"error") == 0)
5051 {
5052 if (image != (Image *) NULL)
5053 s=newSVnv(image->error.mean_error_per_pixel);
5054 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5055 continue;
5056 }
5057 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5058 attribute);
5059 break;
5060 }
5061 case 'F':
5062 case 'f':
5063 {
5064 if (LocaleCompare(attribute,"filesize") == 0)
5065 {
5066 if (image != (Image *) NULL)
5067 s=newSViv((ssize_t) GetBlobSize(image));
5068 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5069 continue;
5070 }
5071 if (LocaleCompare(attribute,"filename") == 0)
5072 {
Cristy2273d6a2017-07-14 19:19:55 -04005073 if (info && *info->image_info->filename)
cristy4a3ce0a2013-08-03 20:06:59 +00005074 s=newSVpv(info->image_info->filename,0);
5075 if (image != (Image *) NULL)
5076 s=newSVpv(image->filename,0);
5077 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5078 continue;
5079 }
5080 if (LocaleCompare(attribute,"filter") == 0)
5081 {
5082 s=image ? newSViv(image->filter) : newSViv(0);
5083 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5084 image->filter));
5085 SvIOK_on(s);
5086 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5087 continue;
5088 }
5089 if (LocaleCompare(attribute,"font") == 0)
5090 {
5091 if (info && info->image_info->font)
5092 s=newSVpv(info->image_info->font,0);
5093 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5094 continue;
5095 }
5096 if (LocaleCompare(attribute,"foreground") == 0)
5097 continue;
5098 if (LocaleCompare(attribute,"format") == 0)
5099 {
5100 const MagickInfo
5101 *magick_info;
5102
5103 magick_info=(const MagickInfo *) NULL;
5104 if (info && (*info->image_info->magick != '\0'))
5105 magick_info=GetMagickInfo(info->image_info->magick,exception);
5106 if (image != (Image *) NULL)
5107 magick_info=GetMagickInfo(image->magick,exception);
5108 if ((magick_info != (const MagickInfo *) NULL) &&
5109 (*magick_info->description != '\0'))
5110 s=newSVpv((char *) magick_info->description,0);
5111 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5112 continue;
5113 }
5114 if (LocaleCompare(attribute,"fuzz") == 0)
5115 {
5116 if (info)
5117 s=newSVnv(info->image_info->fuzz);
5118 if (image != (Image *) NULL)
5119 s=newSVnv(image->fuzz);
5120 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5121 continue;
5122 }
5123 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5124 attribute);
5125 break;
5126 }
5127 case 'G':
5128 case 'g':
5129 {
5130 if (LocaleCompare(attribute,"gamma") == 0)
5131 {
5132 if (image != (Image *) NULL)
5133 s=newSVnv(image->gamma);
5134 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5135 continue;
5136 }
5137 if (LocaleCompare(attribute,"geometry") == 0)
5138 {
5139 if (image && image->geometry)
5140 s=newSVpv(image->geometry,0);
5141 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5142 continue;
5143 }
5144 if (LocaleCompare(attribute,"gravity") == 0)
5145 {
5146 s=image ? newSViv(image->gravity) : newSViv(0);
5147 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5148 image->gravity));
5149 SvIOK_on(s);
5150 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5151 continue;
5152 }
5153 if (LocaleCompare(attribute,"green-primary") == 0)
5154 {
5155 if (image == (Image *) NULL)
5156 break;
Cristyb1710fe2017-02-11 13:51:48 -05005157 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005158 image->chromaticity.green_primary.x,
5159 image->chromaticity.green_primary.y);
5160 s=newSVpv(color,0);
5161 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5162 continue;
5163 }
5164 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5165 attribute);
5166 break;
5167 }
5168 case 'H':
5169 case 'h':
5170 {
5171 if (LocaleCompare(attribute,"height") == 0)
5172 {
5173 if (image != (Image *) NULL)
5174 s=newSViv((ssize_t) image->rows);
5175 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5176 continue;
5177 }
5178 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5179 attribute);
5180 break;
5181 }
5182 case 'I':
5183 case 'i':
5184 {
5185 if (LocaleCompare(attribute,"icc") == 0)
5186 {
5187 if (image != (Image *) NULL)
5188 {
5189 const StringInfo
5190 *profile;
5191
5192 profile=GetImageProfile(image,"icc");
5193 if (profile != (StringInfo *) NULL)
5194 s=newSVpv((const char *) GetStringInfoDatum(profile),
5195 GetStringInfoLength(profile));
5196 }
5197 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5198 continue;
5199 }
5200 if (LocaleCompare(attribute,"icm") == 0)
5201 {
5202 if (image != (Image *) NULL)
5203 {
5204 const StringInfo
5205 *profile;
5206
5207 profile=GetImageProfile(image,"icm");
5208 if (profile != (const StringInfo *) NULL)
5209 s=newSVpv((const char *) GetStringInfoDatum(profile),
5210 GetStringInfoLength(profile));
5211 }
5212 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5213 continue;
5214 }
5215 if (LocaleCompare(attribute,"id") == 0)
5216 {
5217 if (image != (Image *) NULL)
5218 {
5219 char
cristy151b66d2015-04-15 10:50:31 +00005220 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005221
5222 MagickBooleanType
5223 status;
5224
5225 static ssize_t
5226 id = 0;
5227
cristy151b66d2015-04-15 10:50:31 +00005228 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005229 id);
5230 status=SetImageRegistry(ImageRegistryType,key,image,
5231 exception);
5232 (void) status;
5233 s=newSViv(id++);
5234 }
5235 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5236 continue;
5237 }
5238 if (LocaleNCompare(attribute,"index",5) == 0)
5239 {
5240 char
cristy151b66d2015-04-15 10:50:31 +00005241 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005242
5243 int
5244 items;
5245
5246 long
5247 x,
5248 y;
5249
5250 register const Quantum
5251 *p;
5252
5253 CacheView
5254 *image_view;
5255
5256 if (image == (Image *) NULL)
5257 break;
5258 if (image->storage_class != PseudoClass)
5259 break;
5260 x=0;
5261 y=0;
5262 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5263 (void) items;
5264 image_view=AcquireVirtualCacheView(image,exception);
5265 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5266 if (p != (const Quantum *) NULL)
5267 {
cristy151b66d2015-04-15 10:50:31 +00005268 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005269 GetPixelIndex(image,p));
5270 s=newSVpv(name,0);
5271 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5272 }
5273 image_view=DestroyCacheView(image_view);
5274 continue;
5275 }
5276 if (LocaleCompare(attribute,"iptc") == 0)
5277 {
5278 if (image != (Image *) NULL)
5279 {
5280 const StringInfo
5281 *profile;
5282
5283 profile=GetImageProfile(image,"iptc");
5284 if (profile != (const StringInfo *) NULL)
5285 s=newSVpv((const char *) GetStringInfoDatum(profile),
5286 GetStringInfoLength(profile));
5287 }
5288 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5289 continue;
5290 }
5291 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5292 {
5293 if (image != (Image *) NULL)
5294 s=newSViv((ssize_t) image->iterations);
5295 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5296 continue;
5297 }
5298 if (LocaleCompare(attribute,"interlace") == 0)
5299 {
5300 j=info ? info->image_info->interlace : image ? image->interlace :
5301 UndefinedInterlace;
5302 s=newSViv(j);
5303 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5304 j));
5305 SvIOK_on(s);
5306 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5307 continue;
5308 }
5309 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5310 attribute);
5311 break;
5312 }
5313 case 'L':
5314 case 'l':
5315 {
5316 if (LocaleCompare(attribute,"label") == 0)
5317 {
5318 const char
5319 *value;
5320
5321 if (image == (Image *) NULL)
5322 break;
Cristy935a4052017-03-31 17:45:37 -04005323 value=GetImageProperty(image,"Label",exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005324 if (value != (const char *) NULL)
5325 s=newSVpv(value,0);
5326 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5327 continue;
5328 }
5329 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5330 {
5331 if (image != (Image *) NULL)
5332 s=newSViv((ssize_t) image->iterations);
5333 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5334 continue;
5335 }
5336 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5337 attribute);
5338 break;
5339 }
5340 case 'M':
5341 case 'm':
5342 {
5343 if (LocaleCompare(attribute,"magick") == 0)
5344 {
5345 if (info && *info->image_info->magick)
5346 s=newSVpv(info->image_info->magick,0);
5347 if (image != (Image *) NULL)
5348 s=newSVpv(image->magick,0);
5349 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5350 continue;
5351 }
5352 if (LocaleCompare(attribute,"map") == 0)
5353 {
5354 s=newSViv(GetMagickResource(MapResource));
5355 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5356 continue;
5357 }
5358 if (LocaleCompare(attribute,"maximum-error") == 0)
5359 {
5360 if (image != (Image *) NULL)
5361 s=newSVnv(image->error.normalized_maximum_error);
5362 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5363 continue;
5364 }
5365 if (LocaleCompare(attribute,"memory") == 0)
5366 {
5367 s=newSViv(GetMagickResource(MemoryResource));
5368 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5369 continue;
5370 }
5371 if (LocaleCompare(attribute,"mean-error") == 0)
5372 {
5373 if (image != (Image *) NULL)
5374 s=newSVnv(image->error.normalized_mean_error);
5375 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5376 continue;
5377 }
5378 if (LocaleCompare(attribute,"mime") == 0)
5379 {
5380 if (info && *info->image_info->magick)
5381 s=newSVpv(MagickToMime(info->image_info->magick),0);
5382 if (image != (Image *) NULL)
5383 s=newSVpv(MagickToMime(image->magick),0);
5384 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5385 continue;
5386 }
5387 if (LocaleCompare(attribute,"mattecolor") == 0)
5388 {
5389 if (image == (Image *) NULL)
5390 break;
cristy151b66d2015-04-15 10:50:31 +00005391 (void) FormatLocaleString(color,MagickPathExtent,
Cristy8645e042016-02-03 16:35:29 -05005392 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5393 (double) image->alpha_color.green,
5394 (double) image->alpha_color.blue,
5395 (double) image->alpha_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005396 s=newSVpv(color,0);
5397 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5398 continue;
5399 }
5400 if (LocaleCompare(attribute,"matte") == 0)
5401 {
5402 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005403 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005404 1 : 0);
5405 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5406 continue;
5407 }
5408 if (LocaleCompare(attribute,"mime") == 0)
5409 {
5410 const char
5411 *magick;
5412
5413 magick=NULL;
5414 if (info && *info->image_info->magick)
5415 magick=info->image_info->magick;
5416 if (image != (Image *) NULL)
5417 magick=image->magick;
5418 if (magick)
5419 {
5420 char
5421 *mime;
5422
5423 mime=MagickToMime(magick);
5424 s=newSVpv(mime,0);
5425 mime=(char *) RelinquishMagickMemory(mime);
5426 }
5427 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5428 continue;
5429 }
5430 if (LocaleCompare(attribute,"monochrome") == 0)
5431 {
5432 if (image == (Image *) NULL)
5433 continue;
5434 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005435 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005436 s=newSViv(j);
5437 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5438 continue;
5439 }
5440 if (LocaleCompare(attribute,"montage") == 0)
5441 {
5442 if (image && image->montage)
5443 s=newSVpv(image->montage,0);
5444 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5445 continue;
5446 }
5447 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5448 attribute);
5449 break;
5450 }
5451 case 'O':
5452 case 'o':
5453 {
5454 if (LocaleCompare(attribute,"orientation") == 0)
5455 {
5456 j=info ? info->image_info->orientation : image ?
5457 image->orientation : UndefinedOrientation;
5458 s=newSViv(j);
5459 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5460 j));
5461 SvIOK_on(s);
5462 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5463 continue;
5464 }
5465 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5466 attribute);
5467 break;
5468 }
5469 case 'P':
5470 case 'p':
5471 {
5472 if (LocaleCompare(attribute,"page") == 0)
5473 {
5474 if (info && info->image_info->page)
5475 s=newSVpv(info->image_info->page,0);
5476 if (image != (Image *) NULL)
5477 {
5478 char
cristy151b66d2015-04-15 10:50:31 +00005479 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005480
cristy151b66d2015-04-15 10:50:31 +00005481 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005482 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5483 (double) image->page.height,(double) image->page.x,(double)
5484 image->page.y);
5485 s=newSVpv(geometry,0);
5486 }
5487 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5488 continue;
5489 }
5490 if (LocaleCompare(attribute,"page.x") == 0)
5491 {
5492 if (image != (Image *) NULL)
5493 s=newSViv((ssize_t) image->page.x);
5494 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5495 continue;
5496 }
5497 if (LocaleCompare(attribute,"page.y") == 0)
5498 {
5499 if (image != (Image *) NULL)
5500 s=newSViv((ssize_t) image->page.y);
5501 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5502 continue;
5503 }
5504 if (LocaleNCompare(attribute,"pixel",5) == 0)
5505 {
5506 char
cristy151b66d2015-04-15 10:50:31 +00005507 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005508
5509 int
5510 items;
5511
5512 long
5513 x,
5514 y;
5515
5516 register const Quantum
5517 *p;
5518
5519 if (image == (Image *) NULL)
5520 break;
5521 x=0;
5522 y=0;
5523 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5524 (void) items;
5525 p=GetVirtualPixels(image,x,y,1,1,exception);
5526 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005527 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005528 QuantumFormat "," QuantumFormat "," QuantumFormat,
5529 GetPixelRed(image,p),GetPixelGreen(image,p),
5530 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5531 else
cristy151b66d2015-04-15 10:50:31 +00005532 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005533 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5534 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5535 GetPixelBlue(image,p),GetPixelBlack(image,p),
5536 GetPixelAlpha(image,p));
5537 s=newSVpv(tuple,0);
5538 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5539 continue;
5540 }
5541 if (LocaleCompare(attribute,"pointsize") == 0)
5542 {
5543 if (info)
5544 s=newSViv((ssize_t) info->image_info->pointsize);
5545 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5546 continue;
5547 }
cristy4a3ce0a2013-08-03 20:06:59 +00005548 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5549 attribute);
5550 break;
5551 }
5552 case 'Q':
5553 case 'q':
5554 {
5555 if (LocaleCompare(attribute,"quality") == 0)
5556 {
5557 if (info)
5558 s=newSViv((ssize_t) info->image_info->quality);
5559 if (image != (Image *) NULL)
5560 s=newSViv((ssize_t) image->quality);
5561 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5562 continue;
5563 }
5564 if (LocaleCompare(attribute,"quantum") == 0)
5565 {
5566 if (info)
5567 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5568 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5569 continue;
5570 }
5571 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5572 attribute);
5573 break;
5574 }
5575 case 'R':
5576 case 'r':
5577 {
5578 if (LocaleCompare(attribute,"rendering-intent") == 0)
5579 {
5580 s=newSViv(image->rendering_intent);
5581 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5582 image->rendering_intent));
5583 SvIOK_on(s);
5584 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5585 continue;
5586 }
5587 if (LocaleCompare(attribute,"red-primary") == 0)
5588 {
5589 if (image == (Image *) NULL)
5590 break;
Cristyb1710fe2017-02-11 13:51:48 -05005591 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005592 image->chromaticity.red_primary.x,
5593 image->chromaticity.red_primary.y);
5594 s=newSVpv(color,0);
5595 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5596 continue;
5597 }
5598 if (LocaleCompare(attribute,"rows") == 0)
5599 {
5600 if (image != (Image *) NULL)
5601 s=newSViv((ssize_t) image->rows);
5602 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5603 continue;
5604 }
5605 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5606 attribute);
5607 break;
5608 }
5609 case 'S':
5610 case 's':
5611 {
5612 if (LocaleCompare(attribute,"sampling-factor") == 0)
5613 {
5614 if (info && info->image_info->sampling_factor)
5615 s=newSVpv(info->image_info->sampling_factor,0);
5616 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5617 continue;
5618 }
5619 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5620 {
5621 if (info && info->image_info->server_name)
5622 s=newSVpv(info->image_info->server_name,0);
5623 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5624 continue;
5625 }
5626 if (LocaleCompare(attribute,"size") == 0)
5627 {
5628 if (info && info->image_info->size)
5629 s=newSVpv(info->image_info->size,0);
5630 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5631 continue;
5632 }
5633 if (LocaleCompare(attribute,"scene") == 0)
5634 {
5635 if (image != (Image *) NULL)
5636 s=newSViv((ssize_t) image->scene);
5637 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5638 continue;
5639 }
5640 if (LocaleCompare(attribute,"scenes") == 0)
5641 {
5642 if (image != (Image *) NULL)
5643 s=newSViv((ssize_t) info->image_info->number_scenes);
5644 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5645 continue;
5646 }
5647 if (LocaleCompare(attribute,"signature") == 0)
5648 {
5649 const char
5650 *value;
5651
5652 if (image == (Image *) NULL)
5653 break;
5654 (void) SignatureImage(image,exception);
5655 value=GetImageProperty(image,"Signature",exception);
5656 if (value != (const char *) NULL)
5657 s=newSVpv(value,0);
5658 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5659 continue;
5660 }
5661 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5662 attribute);
5663 break;
5664 }
5665 case 'T':
5666 case 't':
5667 {
5668 if (LocaleCompare(attribute,"taint") == 0)
5669 {
5670 if (image != (Image *) NULL)
5671 s=newSViv((ssize_t) IsTaintImage(image));
5672 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5673 continue;
5674 }
5675 if (LocaleCompare(attribute,"texture") == 0)
5676 {
5677 if (info && info->image_info->texture)
5678 s=newSVpv(info->image_info->texture,0);
5679 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5680 continue;
5681 }
5682 if (LocaleCompare(attribute,"total-ink-density") == 0)
5683 {
5684 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5685 if (image != (Image *) NULL)
5686 s=newSVnv(GetImageTotalInkDensity(image,exception));
5687 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5688 continue;
5689 }
5690 if (LocaleCompare(attribute,"transparent-color") == 0)
5691 {
5692 if (image == (Image *) NULL)
5693 break;
cristy151b66d2015-04-15 10:50:31 +00005694 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005695 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5696 (double) image->transparent_color.green,
5697 (double) image->transparent_color.blue,
5698 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005699 s=newSVpv(color,0);
5700 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5701 continue;
5702 }
5703 if (LocaleCompare(attribute,"type") == 0)
5704 {
5705 if (image == (Image *) NULL)
5706 break;
cristya26f54c2015-07-29 12:26:12 +00005707 j=(ssize_t) GetImageType(image);
cristy4a3ce0a2013-08-03 20:06:59 +00005708 s=newSViv(j);
5709 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5710 SvIOK_on(s);
5711 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5712 continue;
5713 }
5714 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5715 attribute);
5716 break;
5717 }
5718 case 'U':
5719 case 'u':
5720 {
5721 if (LocaleCompare(attribute,"units") == 0)
5722 {
5723 j=info ? info->image_info->units : image ? image->units :
5724 UndefinedResolution;
5725 if (info && (info->image_info->units == UndefinedResolution))
5726 if (image)
5727 j=image->units;
5728 if (j == UndefinedResolution)
5729 s=newSVpv("undefined units",0);
5730 else
5731 if (j == PixelsPerInchResolution)
5732 s=newSVpv("pixels / inch",0);
5733 else
5734 s=newSVpv("pixels / centimeter",0);
5735 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5736 continue;
5737 }
5738 if (LocaleCompare(attribute,"user-time") == 0)
5739 {
5740 if (image != (Image *) NULL)
5741 s=newSVnv(GetUserTime(&image->timer));
5742 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5743 continue;
5744 }
5745 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5746 attribute);
5747 break;
5748 }
5749 case 'V':
5750 case 'v':
5751 {
5752 if (LocaleCompare(attribute,"verbose") == 0)
5753 {
5754 if (info)
5755 s=newSViv((ssize_t) info->image_info->verbose);
5756 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5757 continue;
5758 }
5759 if (LocaleCompare(attribute,"version") == 0)
5760 {
5761 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5762 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5763 continue;
5764 }
cristy4a3ce0a2013-08-03 20:06:59 +00005765 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5766 {
5767 if (image == (Image *) NULL)
5768 break;
5769 j=(ssize_t) GetImageVirtualPixelMethod(image);
5770 s=newSViv(j);
5771 (void) sv_setpv(s,CommandOptionToMnemonic(
5772 MagickVirtualPixelOptions,j));
5773 SvIOK_on(s);
5774 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5775 continue;
5776 }
5777 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5778 attribute);
5779 break;
5780 }
5781 case 'W':
5782 case 'w':
5783 {
5784 if (LocaleCompare(attribute,"white-point") == 0)
5785 {
5786 if (image == (Image *) NULL)
5787 break;
Cristyb1710fe2017-02-11 13:51:48 -05005788 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005789 image->chromaticity.white_point.x,
5790 image->chromaticity.white_point.y);
5791 s=newSVpv(color,0);
5792 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5793 continue;
5794 }
5795 if (LocaleCompare(attribute,"width") == 0)
5796 {
5797 if (image != (Image *) NULL)
5798 s=newSViv((ssize_t) image->columns);
5799 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5800 continue;
5801 }
5802 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5803 attribute);
5804 break;
5805 }
5806 case 'X':
5807 case 'x':
5808 {
Cristyc1f9f9f2016-01-05 08:19:28 -05005809 if (LocaleCompare(attribute,"xmp") == 0)
5810 {
5811 if (image != (Image *) NULL)
5812 {
5813 const StringInfo
5814 *profile;
5815
5816 profile=GetImageProfile(image,"xmp");
5817 if (profile != (StringInfo *) NULL)
5818 s=newSVpv((const char *) GetStringInfoDatum(profile),
5819 GetStringInfoLength(profile));
5820 }
5821 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5822 continue;
5823 }
cristy4a3ce0a2013-08-03 20:06:59 +00005824 if (LocaleCompare(attribute,"x-resolution") == 0)
5825 {
5826 if (image != (Image *) NULL)
5827 s=newSVnv(image->resolution.x);
5828 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5829 continue;
5830 }
5831 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5832 attribute);
5833 break;
5834 }
5835 case 'Y':
5836 case 'y':
5837 {
5838 if (LocaleCompare(attribute,"y-resolution") == 0)
5839 {
5840 if (image != (Image *) NULL)
5841 s=newSVnv(image->resolution.y);
5842 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5843 continue;
5844 }
5845 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5846 attribute);
5847 break;
5848 }
5849 default:
5850 break;
5851 }
5852 if (image == (Image *) NULL)
5853 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5854 attribute)
5855 else
5856 {
5857 value=GetImageProperty(image,attribute,exception);
5858 if (value != (const char *) NULL)
5859 {
5860 s=newSVpv(value,0);
5861 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5862 }
5863 else
5864 if (*attribute != '%')
5865 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5866 attribute)
5867 else
5868 {
5869 char
5870 *meta;
5871
5872 meta=InterpretImageProperties(info ? info->image_info :
5873 (ImageInfo *) NULL,image,attribute,exception);
5874 s=newSVpv(meta,0);
5875 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5876 meta=(char *) RelinquishMagickMemory(meta);
5877 }
5878 }
5879 }
5880 exception=DestroyExceptionInfo(exception);
5881 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5882 }
5883
5884#
5885###############################################################################
5886# #
5887# #
5888# #
5889# G e t A u t h e n t i c P i x e l s #
5890# #
5891# #
5892# #
5893###############################################################################
5894#
5895#
5896void *
5897GetAuthenticPixels(ref,...)
5898 Image::Magick ref = NO_INIT
5899 ALIAS:
5900 getauthenticpixels = 1
5901 GetImagePixels = 2
5902 getimagepixels = 3
5903 CODE:
5904 {
5905 char
5906 *attribute;
5907
5908 ExceptionInfo
5909 *exception;
5910
5911 Image
5912 *image;
5913
5914 RectangleInfo
5915 region;
5916
5917 ssize_t
5918 i;
5919
5920 struct PackageInfo
5921 *info;
5922
5923 SV
5924 *perl_exception,
5925 *reference;
5926
5927 void
5928 *blob = NULL;
5929
5930 PERL_UNUSED_VAR(ref);
5931 PERL_UNUSED_VAR(ix);
5932 exception=AcquireExceptionInfo();
5933 perl_exception=newSVpv("",0);
5934 if (sv_isobject(ST(0)) == 0)
5935 {
5936 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5937 PackageName);
5938 goto PerlException;
5939 }
5940 reference=SvRV(ST(0));
5941
5942 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5943 if (image == (Image *) NULL)
5944 {
5945 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5946 PackageName);
5947 goto PerlException;
5948 }
5949
5950 region.x=0;
5951 region.y=0;
5952 region.width=image->columns;
5953 region.height=1;
5954 if (items == 1)
5955 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5956 for (i=2; i < items; i+=2)
5957 {
5958 attribute=(char *) SvPV(ST(i-1),na);
5959 switch (*attribute)
5960 {
5961 case 'g':
5962 case 'G':
5963 {
5964 if (LocaleCompare(attribute,"geometry") == 0)
5965 {
5966 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5967 break;
5968 }
5969 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5970 attribute);
5971 break;
5972 }
5973 case 'H':
5974 case 'h':
5975 {
5976 if (LocaleCompare(attribute,"height") == 0)
5977 {
5978 region.height=SvIV(ST(i));
5979 continue;
5980 }
5981 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5982 attribute);
5983 break;
5984 }
5985 case 'X':
5986 case 'x':
5987 {
5988 if (LocaleCompare(attribute,"x") == 0)
5989 {
5990 region.x=SvIV(ST(i));
5991 continue;
5992 }
5993 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5994 attribute);
5995 break;
5996 }
5997 case 'Y':
5998 case 'y':
5999 {
6000 if (LocaleCompare(attribute,"y") == 0)
6001 {
6002 region.y=SvIV(ST(i));
6003 continue;
6004 }
6005 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6006 attribute);
6007 break;
6008 }
6009 case 'W':
6010 case 'w':
6011 {
6012 if (LocaleCompare(attribute,"width") == 0)
6013 {
6014 region.width=SvIV(ST(i));
6015 continue;
6016 }
6017 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6018 attribute);
6019 break;
6020 }
6021 }
6022 }
6023 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
6024 region.height,exception);
6025 if (blob != (void *) NULL)
6026 goto PerlEnd;
6027
6028 PerlException:
6029 InheritPerlException(exception,perl_exception);
6030 exception=DestroyExceptionInfo(exception);
6031 SvREFCNT_dec(perl_exception); /* throw away all errors */
6032
6033 PerlEnd:
6034 RETVAL = blob;
6035 }
6036 OUTPUT:
6037 RETVAL
6038
6039#
6040###############################################################################
6041# #
6042# #
6043# #
6044# G e t V i r t u a l P i x e l s #
6045# #
6046# #
6047# #
6048###############################################################################
6049#
6050#
6051void *
6052GetVirtualPixels(ref,...)
6053 Image::Magick ref = NO_INIT
6054 ALIAS:
6055 getvirtualpixels = 1
6056 AcquireImagePixels = 2
6057 acquireimagepixels = 3
6058 CODE:
6059 {
6060 char
6061 *attribute;
6062
6063 const void
6064 *blob = NULL;
6065
6066 ExceptionInfo
6067 *exception;
6068
6069 Image
6070 *image;
6071
6072 RectangleInfo
6073 region;
6074
6075 ssize_t
6076 i;
6077
6078 struct PackageInfo
6079 *info;
6080
6081 SV
6082 *perl_exception,
6083 *reference;
6084
6085 PERL_UNUSED_VAR(ref);
6086 PERL_UNUSED_VAR(ix);
6087 exception=AcquireExceptionInfo();
6088 perl_exception=newSVpv("",0);
6089 if (sv_isobject(ST(0)) == 0)
6090 {
6091 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6092 PackageName);
6093 goto PerlException;
6094 }
6095 reference=SvRV(ST(0));
6096
6097 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6098 if (image == (Image *) NULL)
6099 {
6100 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6101 PackageName);
6102 goto PerlException;
6103 }
6104
6105 region.x=0;
6106 region.y=0;
6107 region.width=image->columns;
6108 region.height=1;
6109 if (items == 1)
6110 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6111 for (i=2; i < items; i+=2)
6112 {
6113 attribute=(char *) SvPV(ST(i-1),na);
6114 switch (*attribute)
6115 {
6116 case 'g':
6117 case 'G':
6118 {
6119 if (LocaleCompare(attribute,"geometry") == 0)
6120 {
6121 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6122 break;
6123 }
6124 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6125 attribute);
6126 break;
6127 }
6128 case 'H':
6129 case 'h':
6130 {
6131 if (LocaleCompare(attribute,"height") == 0)
6132 {
6133 region.height=SvIV(ST(i));
6134 continue;
6135 }
6136 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6137 attribute);
6138 break;
6139 }
6140 case 'X':
6141 case 'x':
6142 {
6143 if (LocaleCompare(attribute,"x") == 0)
6144 {
6145 region.x=SvIV(ST(i));
6146 continue;
6147 }
6148 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6149 attribute);
6150 break;
6151 }
6152 case 'Y':
6153 case 'y':
6154 {
6155 if (LocaleCompare(attribute,"y") == 0)
6156 {
6157 region.y=SvIV(ST(i));
6158 continue;
6159 }
6160 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6161 attribute);
6162 break;
6163 }
6164 case 'W':
6165 case 'w':
6166 {
6167 if (LocaleCompare(attribute,"width") == 0)
6168 {
6169 region.width=SvIV(ST(i));
6170 continue;
6171 }
6172 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6173 attribute);
6174 break;
6175 }
6176 }
6177 }
6178 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6179 region.height,exception);
6180 if (blob != (void *) NULL)
6181 goto PerlEnd;
6182
6183 PerlException:
6184 InheritPerlException(exception,perl_exception);
6185 exception=DestroyExceptionInfo(exception);
6186 SvREFCNT_dec(perl_exception); /* throw away all errors */
6187
6188 PerlEnd:
6189 RETVAL = (void *) blob;
6190 }
6191 OUTPUT:
6192 RETVAL
6193
6194#
6195###############################################################################
6196# #
6197# #
6198# #
6199# G e t A u t h e n t i c M e t a c o n t e n t #
6200# #
6201# #
6202# #
6203###############################################################################
6204#
6205#
6206void *
6207GetAuthenticMetacontent(ref,...)
6208 Image::Magick ref = NO_INIT
6209 ALIAS:
6210 getauthenticmetacontent = 1
6211 GetMetacontent = 2
6212 getmetacontent = 3
6213 CODE:
6214 {
6215 ExceptionInfo
6216 *exception;
6217
6218 Image
6219 *image;
6220
6221 struct PackageInfo
6222 *info;
6223
6224 SV
6225 *perl_exception,
6226 *reference;
6227
6228 void
6229 *blob = NULL;
6230
6231 PERL_UNUSED_VAR(ref);
6232 PERL_UNUSED_VAR(ix);
6233 exception=AcquireExceptionInfo();
6234 perl_exception=newSVpv("",0);
6235 if (sv_isobject(ST(0)) == 0)
6236 {
6237 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6238 PackageName);
6239 goto PerlException;
6240 }
6241 reference=SvRV(ST(0));
6242
6243 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6244 if (image == (Image *) NULL)
6245 {
6246 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6247 PackageName);
6248 goto PerlException;
6249 }
6250
6251 blob=(void *) GetAuthenticMetacontent(image);
6252 if (blob != (void *) NULL)
6253 goto PerlEnd;
6254
6255 PerlException:
6256 InheritPerlException(exception,perl_exception);
6257 exception=DestroyExceptionInfo(exception);
6258 SvREFCNT_dec(perl_exception); /* throw away all errors */
6259
6260 PerlEnd:
6261 RETVAL = blob;
6262 }
6263 OUTPUT:
6264 RETVAL
6265
6266#
6267###############################################################################
6268# #
6269# #
6270# #
6271# G e t V i r t u a l M e t a c o n t e n t #
6272# #
6273# #
6274# #
6275###############################################################################
6276#
6277#
6278void *
6279GetVirtualMetacontent(ref,...)
6280 Image::Magick ref = NO_INIT
6281 ALIAS:
6282 getvirtualmetacontent = 1
6283 CODE:
6284 {
6285 ExceptionInfo
6286 *exception;
6287
6288 Image
6289 *image;
6290
6291 struct PackageInfo
6292 *info;
6293
6294 SV
6295 *perl_exception,
6296 *reference;
6297
6298 void
6299 *blob = NULL;
6300
6301 PERL_UNUSED_VAR(ref);
6302 PERL_UNUSED_VAR(ix);
6303 exception=AcquireExceptionInfo();
6304 perl_exception=newSVpv("",0);
6305 if (sv_isobject(ST(0)) == 0)
6306 {
6307 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6308 PackageName);
6309 goto PerlException;
6310 }
6311 reference=SvRV(ST(0));
6312
6313 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6314 if (image == (Image *) NULL)
6315 {
6316 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6317 PackageName);
6318 goto PerlException;
6319 }
6320
6321 blob=(void *) GetVirtualMetacontent(image);
6322 if (blob != (void *) NULL)
6323 goto PerlEnd;
6324
6325 PerlException:
6326 InheritPerlException(exception,perl_exception);
6327 exception=DestroyExceptionInfo(exception);
6328 SvREFCNT_dec(perl_exception); /* throw away all errors */
6329
6330 PerlEnd:
6331 RETVAL = blob;
6332 }
6333 OUTPUT:
6334 RETVAL
6335
6336#
6337###############################################################################
6338# #
6339# #
6340# #
6341# H i s t o g r a m #
6342# #
6343# #
6344# #
6345###############################################################################
6346#
6347#
6348void
6349Histogram(ref,...)
6350 Image::Magick ref=NO_INIT
6351 ALIAS:
6352 HistogramImage = 1
6353 histogram = 2
6354 histogramimage = 3
6355 PPCODE:
6356 {
6357 AV
6358 *av;
6359
6360 char
cristy151b66d2015-04-15 10:50:31 +00006361 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006362
6363 PixelInfo
6364 *histogram;
6365
6366 ExceptionInfo
6367 *exception;
6368
6369 Image
6370 *image;
6371
6372 register ssize_t
6373 i;
6374
6375 ssize_t
6376 count;
6377
6378 struct PackageInfo
6379 *info;
6380
6381 SV
6382 *perl_exception,
6383 *reference;
6384
6385 size_t
6386 number_colors;
6387
6388 PERL_UNUSED_VAR(ref);
6389 PERL_UNUSED_VAR(ix);
6390 exception=AcquireExceptionInfo();
6391 perl_exception=newSVpv("",0);
6392 av=NULL;
6393 if (sv_isobject(ST(0)) == 0)
6394 {
6395 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6396 PackageName);
6397 goto PerlException;
6398 }
6399 reference=SvRV(ST(0));
6400 av=newAV();
6401 SvREFCNT_dec(av);
6402 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6403 if (image == (Image *) NULL)
6404 {
6405 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6406 PackageName);
6407 goto PerlException;
6408 }
cristy4a3ce0a2013-08-03 20:06:59 +00006409 count=0;
6410 for ( ; image; image=image->next)
6411 {
6412 histogram=GetImageHistogram(image,&number_colors,exception);
6413 if (histogram == (PixelInfo *) NULL)
6414 continue;
6415 count+=(ssize_t) number_colors;
6416 EXTEND(sp,6*count);
6417 for (i=0; i < (ssize_t) number_colors; i++)
6418 {
cristy151b66d2015-04-15 10:50:31 +00006419 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006420 histogram[i].red);
6421 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006422 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006423 histogram[i].green);
6424 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006425 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006426 histogram[i].blue);
6427 PUSHs(sv_2mortal(newSVpv(message,0)));
6428 if (image->colorspace == CMYKColorspace)
6429 {
cristy151b66d2015-04-15 10:50:31 +00006430 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006431 histogram[i].black);
6432 PUSHs(sv_2mortal(newSVpv(message,0)));
6433 }
cristy151b66d2015-04-15 10:50:31 +00006434 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006435 histogram[i].alpha);
6436 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006437 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006438 histogram[i].count);
6439 PUSHs(sv_2mortal(newSVpv(message,0)));
6440 }
6441 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6442 }
6443
6444 PerlException:
6445 InheritPerlException(exception,perl_exception);
6446 exception=DestroyExceptionInfo(exception);
6447 SvREFCNT_dec(perl_exception);
6448 }
6449
6450#
6451###############################################################################
6452# #
6453# #
6454# #
6455# G e t P i x e l #
6456# #
6457# #
6458# #
6459###############################################################################
6460#
6461#
6462void
6463GetPixel(ref,...)
6464 Image::Magick ref=NO_INIT
6465 ALIAS:
6466 getpixel = 1
6467 getPixel = 2
6468 PPCODE:
6469 {
6470 AV
6471 *av;
6472
6473 char
6474 *attribute;
6475
6476 ExceptionInfo
6477 *exception;
6478
6479 Image
6480 *image;
6481
6482 MagickBooleanType
6483 normalize;
6484
6485 RectangleInfo
6486 region;
6487
6488 register const Quantum
6489 *p;
6490
6491 register ssize_t
6492 i;
6493
6494 ssize_t
6495 option;
6496
6497 struct PackageInfo
6498 *info;
6499
6500 SV
6501 *perl_exception,
6502 *reference; /* reference is the SV* of ref=SvIV(reference) */
6503
6504 PERL_UNUSED_VAR(ref);
6505 PERL_UNUSED_VAR(ix);
6506 exception=AcquireExceptionInfo();
6507 perl_exception=newSVpv("",0);
6508 reference=SvRV(ST(0));
6509 av=(AV *) reference;
6510 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6511 exception);
6512 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6513 if (image == (Image *) NULL)
6514 {
6515 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6516 PackageName);
6517 goto PerlException;
6518 }
6519 normalize=MagickTrue;
6520 region.x=0;
6521 region.y=0;
6522 region.width=image->columns;
6523 region.height=1;
6524 if (items == 1)
6525 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6526 for (i=2; i < items; i+=2)
6527 {
6528 attribute=(char *) SvPV(ST(i-1),na);
6529 switch (*attribute)
6530 {
6531 case 'C':
6532 case 'c':
6533 {
6534 if (LocaleCompare(attribute,"channel") == 0)
6535 {
6536 ssize_t
6537 option;
6538
6539 option=ParseChannelOption(SvPV(ST(i),na));
6540 if (option < 0)
6541 {
6542 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6543 SvPV(ST(i),na));
6544 return;
6545 }
cristybcd59342015-06-07 14:07:19 +00006546 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00006547 break;
6548 }
6549 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6550 attribute);
6551 break;
6552 }
6553 case 'g':
6554 case 'G':
6555 {
6556 if (LocaleCompare(attribute,"geometry") == 0)
6557 {
6558 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6559 break;
6560 }
6561 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6562 attribute);
6563 break;
6564 }
6565 case 'N':
6566 case 'n':
6567 {
6568 if (LocaleCompare(attribute,"normalize") == 0)
6569 {
6570 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6571 SvPV(ST(i),na));
6572 if (option < 0)
6573 {
6574 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6575 SvPV(ST(i),na));
6576 break;
6577 }
6578 normalize=option != 0 ? MagickTrue : MagickFalse;
6579 break;
6580 }
6581 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6582 attribute);
6583 break;
6584 }
6585 case 'x':
6586 case 'X':
6587 {
6588 if (LocaleCompare(attribute,"x") == 0)
6589 {
6590 region.x=SvIV(ST(i));
6591 break;
6592 }
6593 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6594 attribute);
6595 break;
6596 }
6597 case 'y':
6598 case 'Y':
6599 {
6600 if (LocaleCompare(attribute,"y") == 0)
6601 {
6602 region.y=SvIV(ST(i));
6603 break;
6604 }
6605 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6606 attribute);
6607 break;
6608 }
6609 default:
6610 {
6611 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6612 attribute);
6613 break;
6614 }
6615 }
6616 }
6617 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6618 if (p == (const Quantum *) NULL)
6619 PUSHs(&sv_undef);
6620 else
6621 {
6622 double
6623 scale;
6624
6625 scale=1.0;
6626 if (normalize != MagickFalse)
6627 scale=1.0/QuantumRange;
6628 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6629 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6630 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6631 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6632 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6633 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6634 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6635 (image->colorspace == CMYKColorspace))
6636 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6637 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6638 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6639 }
6640
6641 PerlException:
6642 InheritPerlException(exception,perl_exception);
6643 exception=DestroyExceptionInfo(exception);
6644 SvREFCNT_dec(perl_exception);
6645 }
6646
6647#
6648###############################################################################
6649# #
6650# #
6651# #
6652# G e t P i x e l s #
6653# #
6654# #
6655# #
6656###############################################################################
6657#
6658#
6659void
6660GetPixels(ref,...)
6661 Image::Magick ref=NO_INIT
6662 ALIAS:
6663 getpixels = 1
6664 getPixels = 2
6665 PPCODE:
6666 {
6667 AV
6668 *av;
6669
6670 char
6671 *attribute;
6672
6673 const char
6674 *map;
6675
6676 ExceptionInfo
6677 *exception;
6678
6679 Image
6680 *image;
6681
6682 MagickBooleanType
6683 normalize,
6684 status;
6685
6686 RectangleInfo
6687 region;
6688
6689 register ssize_t
6690 i;
6691
6692 ssize_t
6693 option;
6694
6695 struct PackageInfo
6696 *info;
6697
6698 SV
6699 *perl_exception,
6700 *reference; /* reference is the SV* of ref=SvIV(reference) */
6701
6702 PERL_UNUSED_VAR(ref);
6703 PERL_UNUSED_VAR(ix);
6704 exception=AcquireExceptionInfo();
6705 perl_exception=newSVpv("",0);
6706 reference=SvRV(ST(0));
6707 av=(AV *) reference;
6708 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6709 exception);
6710 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6711 if (image == (Image *) NULL)
6712 {
6713 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6714 PackageName);
6715 goto PerlException;
6716 }
6717 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006718 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006719 map="RGBA";
6720 if (image->colorspace == CMYKColorspace)
6721 {
6722 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006723 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006724 map="CMYKA";
6725 }
6726 normalize=MagickFalse;
6727 region.x=0;
6728 region.y=0;
6729 region.width=image->columns;
6730 region.height=1;
6731 if (items == 1)
6732 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6733 for (i=2; i < items; i+=2)
6734 {
6735 attribute=(char *) SvPV(ST(i-1),na);
6736 switch (*attribute)
6737 {
6738 case 'g':
6739 case 'G':
6740 {
6741 if (LocaleCompare(attribute,"geometry") == 0)
6742 {
6743 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6744 break;
6745 }
6746 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6747 attribute);
6748 break;
6749 }
6750 case 'H':
6751 case 'h':
6752 {
6753 if (LocaleCompare(attribute,"height") == 0)
6754 {
6755 region.height=SvIV(ST(i));
6756 break;
6757 }
6758 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6759 attribute);
6760 break;
6761 }
6762 case 'M':
6763 case 'm':
6764 {
6765 if (LocaleCompare(attribute,"map") == 0)
6766 {
6767 map=SvPV(ST(i),na);
6768 break;
6769 }
6770 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6771 attribute);
6772 break;
6773 }
6774 case 'N':
6775 case 'n':
6776 {
6777 if (LocaleCompare(attribute,"normalize") == 0)
6778 {
6779 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6780 SvPV(ST(i),na));
6781 if (option < 0)
6782 {
6783 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6784 SvPV(ST(i),na));
6785 break;
6786 }
6787 normalize=option != 0 ? MagickTrue : MagickFalse;
6788 break;
6789 }
6790 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6791 attribute);
6792 break;
6793 }
6794 case 'W':
6795 case 'w':
6796 {
6797 if (LocaleCompare(attribute,"width") == 0)
6798 {
6799 region.width=SvIV(ST(i));
6800 break;
6801 }
6802 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6803 attribute);
6804 break;
6805 }
6806 case 'x':
6807 case 'X':
6808 {
6809 if (LocaleCompare(attribute,"x") == 0)
6810 {
6811 region.x=SvIV(ST(i));
6812 break;
6813 }
6814 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6815 attribute);
6816 break;
6817 }
6818 case 'y':
6819 case 'Y':
6820 {
6821 if (LocaleCompare(attribute,"y") == 0)
6822 {
6823 region.y=SvIV(ST(i));
6824 break;
6825 }
6826 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6827 attribute);
6828 break;
6829 }
6830 default:
6831 {
6832 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6833 attribute);
6834 break;
6835 }
6836 }
6837 }
6838 if (normalize != MagickFalse)
6839 {
6840 float
6841 *pixels;
6842
6843 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6844 region.height*sizeof(*pixels));
6845 if (pixels == (float *) NULL)
6846 {
6847 ThrowPerlException(exception,ResourceLimitError,
6848 "MemoryAllocationFailed",PackageName);
6849 goto PerlException;
6850 }
6851 status=ExportImagePixels(image,region.x,region.y,region.width,
6852 region.height,map,FloatPixel,pixels,exception);
6853 if (status == MagickFalse)
6854 PUSHs(&sv_undef);
6855 else
6856 {
6857 EXTEND(sp,strlen(map)*region.width*region.height);
6858 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6859 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6860 }
6861 pixels=(float *) RelinquishMagickMemory(pixels);
6862 }
6863 else
6864 {
6865 Quantum
6866 *pixels;
6867
6868 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6869 region.height*sizeof(*pixels));
6870 if (pixels == (Quantum *) NULL)
6871 {
6872 ThrowPerlException(exception,ResourceLimitError,
6873 "MemoryAllocationFailed",PackageName);
6874 goto PerlException;
6875 }
6876 status=ExportImagePixels(image,region.x,region.y,region.width,
6877 region.height,map,QuantumPixel,pixels,exception);
6878 if (status == MagickFalse)
6879 PUSHs(&sv_undef);
6880 else
6881 {
6882 EXTEND(sp,strlen(map)*region.width*region.height);
6883 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6884 PUSHs(sv_2mortal(newSViv(pixels[i])));
6885 }
6886 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6887 }
6888
6889 PerlException:
6890 InheritPerlException(exception,perl_exception);
6891 exception=DestroyExceptionInfo(exception);
6892 SvREFCNT_dec(perl_exception);
6893 }
6894
6895#
6896###############################################################################
6897# #
6898# #
6899# #
6900# I m a g e T o B l o b #
6901# #
6902# #
6903# #
6904###############################################################################
6905#
6906#
6907void
6908ImageToBlob(ref,...)
6909 Image::Magick ref=NO_INIT
6910 ALIAS:
6911 ImageToBlob = 1
6912 imagetoblob = 2
6913 toblob = 3
6914 blob = 4
6915 PPCODE:
6916 {
6917 char
cristy151b66d2015-04-15 10:50:31 +00006918 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006919
6920 ExceptionInfo
6921 *exception;
6922
6923 Image
6924 *image,
6925 *next;
6926
6927 register ssize_t
6928 i;
6929
6930 struct PackageInfo
6931 *info,
6932 *package_info;
6933
6934 size_t
6935 length;
6936
6937 ssize_t
6938 scene;
6939
6940 SV
6941 *perl_exception,
6942 *reference;
6943
6944 void
6945 *blob;
6946
6947 PERL_UNUSED_VAR(ref);
6948 PERL_UNUSED_VAR(ix);
6949 exception=AcquireExceptionInfo();
6950 perl_exception=newSVpv("",0);
6951 package_info=(struct PackageInfo *) NULL;
6952 if (sv_isobject(ST(0)) == 0)
6953 {
6954 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6955 PackageName);
6956 goto PerlException;
6957 }
6958 reference=SvRV(ST(0));
6959 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6960 if (image == (Image *) NULL)
6961 {
6962 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6963 PackageName);
6964 goto PerlException;
6965 }
6966 package_info=ClonePackageInfo(info,exception);
6967 for (i=2; i < items; i+=2)
6968 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6969 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006970 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006971 scene=0;
6972 for (next=image; next; next=next->next)
6973 {
cristy151b66d2015-04-15 10:50:31 +00006974 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006975 next->scene=scene++;
6976 }
6977 SetImageInfo(package_info->image_info,(unsigned int)
6978 GetImageListLength(image),exception);
6979 EXTEND(sp,(ssize_t) GetImageListLength(image));
6980 for ( ; image; image=image->next)
6981 {
6982 length=0;
6983 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6984 if (blob != (char *) NULL)
6985 {
6986 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6987 blob=(unsigned char *) RelinquishMagickMemory(blob);
6988 }
6989 if (package_info->image_info->adjoin)
6990 break;
6991 }
6992
6993 PerlException:
6994 if (package_info != (struct PackageInfo *) NULL)
6995 DestroyPackageInfo(package_info);
6996 InheritPerlException(exception,perl_exception);
6997 exception=DestroyExceptionInfo(exception);
6998 SvREFCNT_dec(perl_exception); /* throw away all errors */
6999 }
7000
7001#
7002###############################################################################
7003# #
7004# #
7005# #
7006# L a y e r s #
7007# #
7008# #
7009# #
7010###############################################################################
7011#
7012#
7013void
7014Layers(ref,...)
7015 Image::Magick ref=NO_INIT
7016 ALIAS:
7017 Layers = 1
7018 layers = 2
7019 OptimizeImageLayers = 3
7020 optimizelayers = 4
7021 optimizeimagelayers = 5
7022 PPCODE:
7023 {
7024 AV
7025 *av;
7026
7027 char
7028 *attribute;
7029
7030 CompositeOperator
7031 compose;
7032
7033 ExceptionInfo
7034 *exception;
7035
7036 HV
7037 *hv;
7038
7039 Image
7040 *image,
7041 *layers;
7042
7043 LayerMethod
7044 method;
7045
7046 register ssize_t
7047 i;
7048
7049 ssize_t
7050 option,
7051 sp;
7052
7053 struct PackageInfo
7054 *info;
7055
7056 SV
7057 *av_reference,
7058 *perl_exception,
7059 *reference,
7060 *rv,
7061 *sv;
7062
7063 PERL_UNUSED_VAR(ref);
7064 PERL_UNUSED_VAR(ix);
7065 exception=AcquireExceptionInfo();
7066 perl_exception=newSVpv("",0);
7067 sv=NULL;
7068 if (sv_isobject(ST(0)) == 0)
7069 {
7070 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7071 PackageName);
7072 goto PerlException;
7073 }
7074 reference=SvRV(ST(0));
7075 hv=SvSTASH(reference);
7076 av=newAV();
7077 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7078 SvREFCNT_dec(av);
7079 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7080 if (image == (Image *) NULL)
7081 {
7082 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7083 PackageName);
7084 goto PerlException;
7085 }
7086 compose=image->compose;
7087 method=OptimizeLayer;
7088 for (i=2; i < items; i+=2)
7089 {
7090 attribute=(char *) SvPV(ST(i-1),na);
7091 switch (*attribute)
7092 {
7093 case 'C':
7094 case 'c':
7095 {
7096 if (LocaleCompare(attribute,"compose") == 0)
7097 {
7098 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7099 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7100 if (sp < 0)
7101 {
7102 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7103 SvPV(ST(i),na));
7104 break;
7105 }
7106 compose=(CompositeOperator) sp;
7107 break;
7108 }
7109 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7110 attribute);
7111 break;
7112 }
7113 case 'M':
7114 case 'm':
7115 {
7116 if (LocaleCompare(attribute,"method") == 0)
7117 {
7118 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7119 SvPV(ST(i),na));
7120 if (option < 0)
7121 {
7122 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7123 SvPV(ST(i),na));
7124 break;
7125 }
7126 method=(LayerMethod) option;
7127 break;
7128 }
7129 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7130 attribute);
7131 break;
7132 }
7133 default:
7134 {
7135 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7136 attribute);
7137 break;
7138 }
7139 }
7140 }
7141 layers=(Image *) NULL;
7142 switch (method)
7143 {
7144 case CompareAnyLayer:
7145 case CompareClearLayer:
7146 case CompareOverlayLayer:
7147 default:
7148 {
7149 layers=CompareImagesLayers(image,method,exception);
7150 break;
7151 }
7152 case MergeLayer:
7153 case FlattenLayer:
7154 case MosaicLayer:
7155 {
7156 layers=MergeImageLayers(image,method,exception);
7157 break;
7158 }
7159 case DisposeLayer:
7160 {
7161 layers=DisposeImages(image,exception);
7162 break;
7163 }
7164 case OptimizeImageLayer:
7165 {
7166 layers=OptimizeImageLayers(image,exception);
7167 break;
7168 }
7169 case OptimizePlusLayer:
7170 {
7171 layers=OptimizePlusImageLayers(image,exception);
7172 break;
7173 }
7174 case OptimizeTransLayer:
7175 {
7176 OptimizeImageTransparency(image,exception);
7177 break;
7178 }
7179 case RemoveDupsLayer:
7180 {
7181 RemoveDuplicateLayers(&image,exception);
7182 break;
7183 }
7184 case RemoveZeroLayer:
7185 {
7186 RemoveZeroDelayLayers(&image,exception);
7187 break;
7188 }
7189 case OptimizeLayer:
7190 {
7191 QuantizeInfo
7192 *quantize_info;
7193
7194 /*
7195 General Purpose, GIF Animation Optimizer.
7196 */
7197 layers=CoalesceImages(image,exception);
7198 if (layers == (Image *) NULL)
7199 break;
7200 image=layers;
7201 layers=OptimizeImageLayers(image,exception);
7202 if (layers == (Image *) NULL)
7203 break;
7204 image=DestroyImageList(image);
7205 image=layers;
7206 layers=(Image *) NULL;
7207 OptimizeImageTransparency(image,exception);
7208 quantize_info=AcquireQuantizeInfo(info->image_info);
7209 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7210 quantize_info=DestroyQuantizeInfo(quantize_info);
7211 break;
7212 }
7213 case CompositeLayer:
7214 {
7215 Image
7216 *source;
7217
7218 RectangleInfo
7219 geometry;
7220
7221 /*
7222 Split image sequence at the first 'NULL:' image.
7223 */
7224 source=image;
7225 while (source != (Image *) NULL)
7226 {
7227 source=GetNextImageInList(source);
7228 if ((source != (Image *) NULL) &&
7229 (LocaleCompare(source->magick,"NULL") == 0))
7230 break;
7231 }
7232 if (source != (Image *) NULL)
7233 {
7234 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7235 (GetNextImageInList(source) == (Image *) NULL))
7236 source=(Image *) NULL;
7237 else
7238 {
7239 /*
7240 Separate the two lists, junk the null: image.
7241 */
7242 source=SplitImageList(source->previous);
7243 DeleteImageFromList(&source);
7244 }
7245 }
7246 if (source == (Image *) NULL)
7247 {
7248 (void) ThrowMagickException(exception,GetMagickModule(),
7249 OptionError,"MissingNullSeparator","layers Composite");
7250 break;
7251 }
7252 /*
7253 Adjust offset with gravity and virtual canvas.
7254 */
7255 SetGeometry(image,&geometry);
7256 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7257 geometry.width=source->page.width != 0 ? source->page.width :
7258 source->columns;
7259 geometry.height=source->page.height != 0 ? source->page.height :
7260 source->rows;
7261 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7262 image->columns,image->page.height != 0 ? image->page.height :
7263 image->rows,image->gravity,&geometry);
7264 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7265 source=DestroyImageList(source);
7266 break;
7267 }
7268 }
7269 if (layers != (Image *) NULL)
7270 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007271 else
7272 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007273 if (image == (Image *) NULL)
7274 goto PerlException;
7275 for ( ; image; image=image->next)
7276 {
7277 AddImageToRegistry(sv,image);
7278 rv=newRV(sv);
7279 av_push(av,sv_bless(rv,hv));
7280 SvREFCNT_dec(sv);
7281 }
7282 exception=DestroyExceptionInfo(exception);
7283 ST(0)=av_reference;
7284 SvREFCNT_dec(perl_exception);
7285 XSRETURN(1);
7286
7287 PerlException:
7288 InheritPerlException(exception,perl_exception);
7289 exception=DestroyExceptionInfo(exception);
7290 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7291 SvPOK_on(perl_exception);
7292 ST(0)=sv_2mortal(perl_exception);
7293 XSRETURN(1);
7294 }
7295
7296#
7297###############################################################################
7298# #
7299# #
7300# #
7301# M a g i c k T o M i m e #
7302# #
7303# #
7304# #
7305###############################################################################
7306#
7307#
7308SV *
7309MagickToMime(ref,name)
7310 Image::Magick ref=NO_INIT
7311 char *name
7312 ALIAS:
7313 magicktomime = 1
7314 CODE:
7315 {
7316 char
7317 *mime;
7318
7319 PERL_UNUSED_VAR(ref);
7320 PERL_UNUSED_VAR(ix);
7321 mime=MagickToMime(name);
7322 RETVAL=newSVpv(mime,0);
7323 mime=(char *) RelinquishMagickMemory(mime);
7324 }
7325 OUTPUT:
7326 RETVAL
7327
7328#
7329###############################################################################
7330# #
7331# #
7332# #
7333# M o g r i f y #
7334# #
7335# #
7336# #
7337###############################################################################
7338#
7339#
7340void
7341Mogrify(ref,...)
7342 Image::Magick ref=NO_INIT
7343 ALIAS:
7344 Comment = 1
7345 CommentImage = 2
7346 Label = 3
7347 LabelImage = 4
7348 AddNoise = 5
7349 AddNoiseImage = 6
7350 Colorize = 7
7351 ColorizeImage = 8
7352 Border = 9
7353 BorderImage = 10
7354 Blur = 11
7355 BlurImage = 12
7356 Chop = 13
7357 ChopImage = 14
7358 Crop = 15
7359 CropImage = 16
7360 Despeckle = 17
7361 DespeckleImage = 18
7362 Edge = 19
7363 EdgeImage = 20
7364 Emboss = 21
7365 EmbossImage = 22
7366 Enhance = 23
7367 EnhanceImage = 24
7368 Flip = 25
7369 FlipImage = 26
7370 Flop = 27
7371 FlopImage = 28
7372 Frame = 29
7373 FrameImage = 30
7374 Implode = 31
7375 ImplodeImage = 32
7376 Magnify = 33
7377 MagnifyImage = 34
7378 MedianFilter = 35
7379 MedianConvolveImage = 36
7380 Minify = 37
7381 MinifyImage = 38
7382 OilPaint = 39
7383 OilPaintImage = 40
7384 ReduceNoise = 41
7385 ReduceNoiseImage = 42
7386 Roll = 43
7387 RollImage = 44
7388 Rotate = 45
7389 RotateImage = 46
7390 Sample = 47
7391 SampleImage = 48
7392 Scale = 49
7393 ScaleImage = 50
7394 Shade = 51
7395 ShadeImage = 52
7396 Sharpen = 53
7397 SharpenImage = 54
7398 Shear = 55
7399 ShearImage = 56
7400 Spread = 57
7401 SpreadImage = 58
7402 Swirl = 59
7403 SwirlImage = 60
7404 Resize = 61
7405 ResizeImage = 62
7406 Zoom = 63
7407 ZoomImage = 64
7408 Annotate = 65
7409 AnnotateImage = 66
7410 ColorFloodfill = 67
7411 ColorFloodfillImage= 68
7412 Composite = 69
7413 CompositeImage = 70
7414 Contrast = 71
7415 ContrastImage = 72
7416 CycleColormap = 73
7417 CycleColormapImage = 74
7418 Draw = 75
7419 DrawImage = 76
7420 Equalize = 77
7421 EqualizeImage = 78
7422 Gamma = 79
7423 GammaImage = 80
7424 Map = 81
7425 MapImage = 82
7426 MatteFloodfill = 83
7427 MatteFloodfillImage= 84
7428 Modulate = 85
7429 ModulateImage = 86
7430 Negate = 87
7431 NegateImage = 88
7432 Normalize = 89
7433 NormalizeImage = 90
7434 NumberColors = 91
7435 NumberColorsImage = 92
7436 Opaque = 93
7437 OpaqueImage = 94
7438 Quantize = 95
7439 QuantizeImage = 96
7440 Raise = 97
7441 RaiseImage = 98
7442 Segment = 99
7443 SegmentImage = 100
7444 Signature = 101
7445 SignatureImage = 102
7446 Solarize = 103
7447 SolarizeImage = 104
7448 Sync = 105
7449 SyncImage = 106
7450 Texture = 107
7451 TextureImage = 108
7452 Evaluate = 109
7453 EvaluateImage = 110
7454 Transparent = 111
7455 TransparentImage = 112
7456 Threshold = 113
7457 ThresholdImage = 114
7458 Charcoal = 115
7459 CharcoalImage = 116
7460 Trim = 117
7461 TrimImage = 118
7462 Wave = 119
7463 WaveImage = 120
7464 Separate = 121
7465 SeparateImage = 122
7466 Stereo = 125
7467 StereoImage = 126
7468 Stegano = 127
7469 SteganoImage = 128
7470 Deconstruct = 129
7471 DeconstructImage = 130
7472 GaussianBlur = 131
7473 GaussianBlurImage = 132
7474 Convolve = 133
7475 ConvolveImage = 134
7476 Profile = 135
7477 ProfileImage = 136
7478 UnsharpMask = 137
7479 UnsharpMaskImage = 138
7480 MotionBlur = 139
7481 MotionBlurImage = 140
7482 OrderedDither = 141
7483 OrderedDitherImage = 142
7484 Shave = 143
7485 ShaveImage = 144
7486 Level = 145
7487 LevelImage = 146
7488 Clip = 147
7489 ClipImage = 148
7490 AffineTransform = 149
7491 AffineTransformImage = 150
7492 Difference = 151
7493 DifferenceImage = 152
7494 AdaptiveThreshold = 153
7495 AdaptiveThresholdImage = 154
7496 Resample = 155
7497 ResampleImage = 156
7498 Describe = 157
7499 DescribeImage = 158
7500 BlackThreshold = 159
7501 BlackThresholdImage= 160
7502 WhiteThreshold = 161
7503 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007504 RotationalBlur = 163
7505 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007506 Thumbnail = 165
7507 ThumbnailImage = 166
7508 Strip = 167
7509 StripImage = 168
7510 Tint = 169
7511 TintImage = 170
7512 Channel = 171
7513 ChannelImage = 172
7514 Splice = 173
7515 SpliceImage = 174
7516 Posterize = 175
7517 PosterizeImage = 176
7518 Shadow = 177
7519 ShadowImage = 178
7520 Identify = 179
7521 IdentifyImage = 180
7522 SepiaTone = 181
7523 SepiaToneImage = 182
7524 SigmoidalContrast = 183
7525 SigmoidalContrastImage = 184
7526 Extent = 185
7527 ExtentImage = 186
7528 Vignette = 187
7529 VignetteImage = 188
7530 ContrastStretch = 189
7531 ContrastStretchImage = 190
7532 Sans0 = 191
7533 Sans0Image = 192
7534 Sans1 = 193
7535 Sans1Image = 194
7536 AdaptiveSharpen = 195
7537 AdaptiveSharpenImage = 196
7538 Transpose = 197
7539 TransposeImage = 198
7540 Transverse = 199
7541 TransverseImage = 200
7542 AutoOrient = 201
7543 AutoOrientImage = 202
7544 AdaptiveBlur = 203
7545 AdaptiveBlurImage = 204
7546 Sketch = 205
7547 SketchImage = 206
7548 UniqueColors = 207
7549 UniqueColorsImage = 208
7550 AdaptiveResize = 209
7551 AdaptiveResizeImage= 210
7552 ClipMask = 211
7553 ClipMaskImage = 212
7554 LinearStretch = 213
7555 LinearStretchImage = 214
7556 ColorMatrix = 215
7557 ColorMatrixImage = 216
7558 Mask = 217
7559 MaskImage = 218
7560 Polaroid = 219
7561 PolaroidImage = 220
7562 FloodfillPaint = 221
7563 FloodfillPaintImage= 222
7564 Distort = 223
7565 DistortImage = 224
7566 Clut = 225
7567 ClutImage = 226
7568 LiquidRescale = 227
7569 LiquidRescaleImage = 228
7570 Encipher = 229
7571 EncipherImage = 230
7572 Decipher = 231
7573 DecipherImage = 232
7574 Deskew = 233
7575 DeskewImage = 234
7576 Remap = 235
7577 RemapImage = 236
7578 SparseColor = 237
7579 SparseColorImage = 238
7580 Function = 239
7581 FunctionImage = 240
7582 SelectiveBlur = 241
7583 SelectiveBlurImage = 242
7584 HaldClut = 243
7585 HaldClutImage = 244
7586 BlueShift = 245
7587 BlueShiftImage = 246
7588 ForwardFourierTransform = 247
7589 ForwardFourierTransformImage = 248
7590 InverseFourierTransform = 249
7591 InverseFourierTransformImage = 250
7592 ColorDecisionList = 251
7593 ColorDecisionListImage = 252
7594 AutoGamma = 253
7595 AutoGammaImage = 254
7596 AutoLevel = 255
7597 AutoLevelImage = 256
7598 LevelColors = 257
7599 LevelImageColors = 258
7600 Clamp = 259
7601 ClampImage = 260
7602 BrightnessContrast = 261
7603 BrightnessContrastImage = 262
7604 Morphology = 263
7605 MorphologyImage = 264
Cristy3ca633e2016-02-13 12:49:01 -05007606 Mode = 265
7607 ModeImage = 266
7608 Statistic = 267
7609 StatisticImage = 268
7610 Perceptible = 269
7611 PerceptibleImage = 270
7612 Poly = 271
7613 PolyImage = 272
7614 Grayscale = 273
7615 GrayscaleImage = 274
7616 CannyEdge = 275
7617 CannyEdgeImage = 276
7618 HoughLine = 277
7619 HoughLineImage = 278
7620 MeanShift = 279
7621 MeanShiftImage = 280
7622 Kuwahara = 281
7623 KuwaharaImage = 282
Cristy0f5df812017-07-04 18:30:05 -04007624 ConnectedComponents = 283
7625 ConnectedComponentsImage = 284
Cristy3ca633e2016-02-13 12:49:01 -05007626 CopyPixels = 285
7627 CopyImagePixels = 286
Cristy5488c982016-02-13 14:07:50 -05007628 Color = 287
7629 ColorImage = 288
Cristy2d830ed2016-02-21 10:54:16 -05007630 WaveletDenoise = 289
7631 WaveletDenoiseImage= 290
Cristy99a57162016-12-05 11:47:57 -05007632 Colorspace = 291
7633 ColorspaceImage = 292
Cristy53353872017-07-02 12:24:24 -04007634 AutoThreshold = 293
7635 AutoThresholdImage = 294
cristy4a3ce0a2013-08-03 20:06:59 +00007636 MogrifyRegion = 666
7637 PPCODE:
7638 {
7639 AffineMatrix
7640 affine,
7641 current;
7642
7643 char
7644 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007645 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007646
7647 ChannelType
7648 channel,
7649 channel_mask;
7650
7651 CompositeOperator
7652 compose;
7653
7654 const char
7655 *attribute,
7656 *value;
7657
7658 double
7659 angle;
7660
7661 ExceptionInfo
7662 *exception;
7663
7664 GeometryInfo
7665 geometry_info;
7666
7667 Image
7668 *image,
7669 *next,
7670 *region_image;
7671
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;
7713 region_image=NULL;
7714 number_images=0;
7715 base=2;
7716 if (sv_isobject(ST(0)) == 0)
7717 {
7718 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7719 PackageName);
7720 goto PerlException;
7721 }
7722 reference=SvRV(ST(0));
7723 region_info.width=0;
7724 region_info.height=0;
7725 region_info.x=0;
7726 region_info.y=0;
7727 region_image=(Image *) NULL;
7728 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7729 if (ix && (ix != 666))
7730 {
7731 /*
7732 Called as Method(...)
7733 */
7734 ix=(ix+1)/2;
7735 rp=(&Methods[ix-1]);
7736 attribute=rp->name;
7737 }
7738 else
7739 {
7740 /*
7741 Called as Mogrify("Method",...)
7742 */
7743 attribute=(char *) SvPV(ST(1),na);
7744 if (ix)
7745 {
7746 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7747 attribute=(char *) SvPV(ST(2),na);
7748 base++;
7749 }
7750 for (rp=Methods; ; rp++)
7751 {
7752 if (rp >= EndOf(Methods))
7753 {
7754 ThrowPerlException(exception,OptionError,
7755 "UnrecognizedPerlMagickMethod",attribute);
7756 goto PerlException;
7757 }
7758 if (strEQcase(attribute,rp->name))
7759 break;
7760 }
7761 ix=rp-Methods+1;
7762 base++;
7763 }
7764 if (image == (Image *) NULL)
7765 {
7766 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7767 goto PerlException;
7768 }
7769 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7770 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7771 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7772 {
7773 Arguments
7774 *pp,
7775 *qq;
7776
7777 ssize_t
7778 ssize_test;
7779
7780 struct ArgumentList
7781 *al;
7782
7783 SV
7784 *sv;
7785
7786 sv=NULL;
7787 ssize_test=0;
7788 pp=(Arguments *) NULL;
7789 qq=rp->arguments;
7790 if (i == items)
7791 {
7792 pp=rp->arguments,
7793 sv=ST(i-1);
7794 }
7795 else
7796 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7797 {
7798 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7799 break;
7800 if (strEQcase(attribute,qq->method) > ssize_test)
7801 {
7802 pp=qq;
7803 ssize_test=strEQcase(attribute,qq->method);
7804 }
7805 }
7806 if (pp == (Arguments *) NULL)
7807 {
7808 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7809 attribute);
7810 goto continue_outer_loop;
7811 }
7812 al=(&argument_list[pp-rp->arguments]);
7813 switch (pp->type)
7814 {
7815 case ArrayReference:
7816 {
7817 if (SvTYPE(sv) != SVt_RV)
7818 {
cristy151b66d2015-04-15 10:50:31 +00007819 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007820 "invalid %.60s value",pp->method);
7821 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7822 goto continue_outer_loop;
7823 }
7824 al->array_reference=SvRV(sv);
7825 break;
7826 }
7827 case RealReference:
7828 {
7829 al->real_reference=SvNV(sv);
7830 break;
7831 }
7832 case FileReference:
7833 {
7834 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7835 break;
7836 }
7837 case ImageReference:
7838 {
7839 if (!sv_isobject(sv) ||
7840 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7841 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7842 {
7843 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7844 PackageName);
7845 goto PerlException;
7846 }
7847 break;
7848 }
7849 case IntegerReference:
7850 {
7851 al->integer_reference=SvIV(sv);
7852 break;
7853 }
7854 case StringReference:
7855 {
7856 al->string_reference=(char *) SvPV(sv,al->length);
7857 if (sv_isobject(sv))
7858 al->image_reference=SetupList(aTHX_ SvRV(sv),
7859 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7860 break;
7861 }
7862 default:
7863 {
7864 /*
7865 Is a string; look up name.
7866 */
7867 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7868 {
7869 al->string_reference=(char *) SvPV(sv,al->length);
7870 al->integer_reference=(-1);
7871 break;
7872 }
7873 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7874 MagickFalse,SvPV(sv,na));
7875 if (pp->type == MagickChannelOptions)
7876 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7877 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7878 {
cristy151b66d2015-04-15 10:50:31 +00007879 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007880 "invalid %.60s value",pp->method);
7881 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7882 goto continue_outer_loop;
7883 }
7884 break;
7885 }
7886 }
7887 attribute_flag[pp-rp->arguments]++;
7888 continue_outer_loop: ;
7889 }
7890 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7891 pv=reference_vector;
7892 SetGeometryInfo(&geometry_info);
7893 channel=DefaultChannels;
7894 for (next=image; next; next=next->next)
7895 {
7896 image=next;
7897 SetGeometry(image,&geometry);
7898 if ((region_info.width*region_info.height) != 0)
7899 {
7900 region_image=image;
7901 image=CropImage(image,&region_info,exception);
7902 }
7903 switch (ix)
7904 {
7905 default:
7906 {
cristy151b66d2015-04-15 10:50:31 +00007907 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007908 ThrowPerlException(exception,OptionError,
7909 "UnrecognizedPerlMagickMethod",message);
7910 goto PerlException;
7911 }
7912 case 1: /* Comment */
7913 {
7914 if (attribute_flag[0] == 0)
7915 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007916 (void) SetImageProperty(image,"comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007917 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007918 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007919 break;
7920 }
7921 case 2: /* Label */
7922 {
7923 if (attribute_flag[0] == 0)
7924 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007925 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007926 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007927 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007928 break;
7929 }
7930 case 3: /* AddNoise */
7931 {
7932 double
7933 attenuate;
7934
7935 if (attribute_flag[0] == 0)
7936 argument_list[0].integer_reference=UniformNoise;
7937 attenuate=1.0;
7938 if (attribute_flag[1] != 0)
7939 attenuate=argument_list[1].real_reference;
7940 if (attribute_flag[2] != 0)
7941 channel=(ChannelType) argument_list[2].integer_reference;
7942 channel_mask=SetImageChannelMask(image,channel);
7943 image=AddNoiseImage(image,(NoiseType)
7944 argument_list[0].integer_reference,attenuate,exception);
7945 if (image != (Image *) NULL)
7946 (void) SetImageChannelMask(image,channel_mask);
7947 break;
7948 }
7949 case 4: /* Colorize */
7950 {
7951 PixelInfo
7952 target;
7953
7954 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7955 0,0,&target,exception);
7956 if (attribute_flag[0] != 0)
7957 (void) QueryColorCompliance(argument_list[0].string_reference,
7958 AllCompliance,&target,exception);
7959 if (attribute_flag[1] == 0)
7960 argument_list[1].string_reference="100%";
7961 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7962 exception);
7963 break;
7964 }
7965 case 5: /* Border */
7966 {
7967 CompositeOperator
7968 compose;
7969
7970 geometry.width=0;
7971 geometry.height=0;
7972 if (attribute_flag[0] != 0)
7973 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7974 &geometry,exception);
7975 if (attribute_flag[1] != 0)
7976 geometry.width=argument_list[1].integer_reference;
7977 if (attribute_flag[2] != 0)
7978 geometry.height=argument_list[2].integer_reference;
7979 if (attribute_flag[3] != 0)
7980 QueryColorCompliance(argument_list[3].string_reference,
7981 AllCompliance,&image->border_color,exception);
7982 if (attribute_flag[4] != 0)
7983 QueryColorCompliance(argument_list[4].string_reference,
7984 AllCompliance,&image->border_color,exception);
7985 if (attribute_flag[5] != 0)
7986 QueryColorCompliance(argument_list[5].string_reference,
7987 AllCompliance,&image->border_color,exception);
7988 compose=image->compose;
7989 if (attribute_flag[6] != 0)
7990 compose=(CompositeOperator) argument_list[6].integer_reference;
7991 image=BorderImage(image,&geometry,compose,exception);
7992 break;
7993 }
7994 case 6: /* Blur */
7995 {
7996 if (attribute_flag[0] != 0)
7997 {
7998 flags=ParseGeometry(argument_list[0].string_reference,
7999 &geometry_info);
8000 if ((flags & SigmaValue) == 0)
8001 geometry_info.sigma=1.0;
8002 }
8003 if (attribute_flag[1] != 0)
8004 geometry_info.rho=argument_list[1].real_reference;
8005 if (attribute_flag[2] != 0)
8006 geometry_info.sigma=argument_list[2].real_reference;
8007 if (attribute_flag[3] != 0)
8008 channel=(ChannelType) argument_list[3].integer_reference;
8009 channel_mask=SetImageChannelMask(image,channel);
8010 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
8011 exception);
8012 if (image != (Image *) NULL)
8013 (void) SetImageChannelMask(image,channel_mask);
8014 break;
8015 }
8016 case 7: /* Chop */
8017 {
cristy260bd762014-08-15 12:46:34 +00008018 if (attribute_flag[5] != 0)
8019 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00008020 if (attribute_flag[0] != 0)
8021 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8022 &geometry,exception);
8023 if (attribute_flag[1] != 0)
8024 geometry.width=argument_list[1].integer_reference;
8025 if (attribute_flag[2] != 0)
8026 geometry.height=argument_list[2].integer_reference;
8027 if (attribute_flag[3] != 0)
8028 geometry.x=argument_list[3].integer_reference;
8029 if (attribute_flag[4] != 0)
8030 geometry.y=argument_list[4].integer_reference;
8031 image=ChopImage(image,&geometry,exception);
8032 break;
8033 }
8034 case 8: /* Crop */
8035 {
8036 if (attribute_flag[6] != 0)
8037 image->gravity=(GravityType) argument_list[6].integer_reference;
8038 if (attribute_flag[0] != 0)
8039 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8040 &geometry,exception);
8041 if (attribute_flag[1] != 0)
8042 geometry.width=argument_list[1].integer_reference;
8043 if (attribute_flag[2] != 0)
8044 geometry.height=argument_list[2].integer_reference;
8045 if (attribute_flag[3] != 0)
8046 geometry.x=argument_list[3].integer_reference;
8047 if (attribute_flag[4] != 0)
8048 geometry.y=argument_list[4].integer_reference;
8049 if (attribute_flag[5] != 0)
8050 image->fuzz=StringToDoubleInterval(
8051 argument_list[5].string_reference,(double) QuantumRange+1.0);
8052 image=CropImage(image,&geometry,exception);
8053 break;
8054 }
8055 case 9: /* Despeckle */
8056 {
8057 image=DespeckleImage(image,exception);
8058 break;
8059 }
8060 case 10: /* Edge */
8061 {
8062 if (attribute_flag[0] != 0)
8063 geometry_info.rho=argument_list[0].real_reference;
8064 image=EdgeImage(image,geometry_info.rho,exception);
8065 break;
8066 }
8067 case 11: /* Emboss */
8068 {
8069 if (attribute_flag[0] != 0)
8070 {
8071 flags=ParseGeometry(argument_list[0].string_reference,
8072 &geometry_info);
8073 if ((flags & SigmaValue) == 0)
8074 geometry_info.sigma=1.0;
8075 }
8076 if (attribute_flag[1] != 0)
8077 geometry_info.rho=argument_list[1].real_reference;
8078 if (attribute_flag[2] != 0)
8079 geometry_info.sigma=argument_list[2].real_reference;
8080 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8081 exception);
8082 break;
8083 }
8084 case 12: /* Enhance */
8085 {
8086 image=EnhanceImage(image,exception);
8087 break;
8088 }
8089 case 13: /* Flip */
8090 {
8091 image=FlipImage(image,exception);
8092 break;
8093 }
8094 case 14: /* Flop */
8095 {
8096 image=FlopImage(image,exception);
8097 break;
8098 }
8099 case 15: /* Frame */
8100 {
8101 CompositeOperator
8102 compose;
8103
8104 FrameInfo
8105 frame_info;
8106
8107 if (attribute_flag[0] != 0)
8108 {
8109 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8110 &geometry,exception);
8111 frame_info.width=geometry.width;
8112 frame_info.height=geometry.height;
8113 frame_info.outer_bevel=geometry.x;
8114 frame_info.inner_bevel=geometry.y;
8115 }
8116 if (attribute_flag[1] != 0)
8117 frame_info.width=argument_list[1].integer_reference;
8118 if (attribute_flag[2] != 0)
8119 frame_info.height=argument_list[2].integer_reference;
8120 if (attribute_flag[3] != 0)
8121 frame_info.inner_bevel=argument_list[3].integer_reference;
8122 if (attribute_flag[4] != 0)
8123 frame_info.outer_bevel=argument_list[4].integer_reference;
8124 if (attribute_flag[5] != 0)
8125 QueryColorCompliance(argument_list[5].string_reference,
8126 AllCompliance,&fill_color,exception);
8127 if (attribute_flag[6] != 0)
8128 QueryColorCompliance(argument_list[6].string_reference,
8129 AllCompliance,&fill_color,exception);
8130 frame_info.x=(ssize_t) frame_info.width;
8131 frame_info.y=(ssize_t) frame_info.height;
8132 frame_info.width=image->columns+2*frame_info.x;
8133 frame_info.height=image->rows+2*frame_info.y;
8134 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
Cristy8645e042016-02-03 16:35:29 -05008135 image->alpha_color=fill_color;
cristy4a3ce0a2013-08-03 20:06:59 +00008136 compose=image->compose;
8137 if (attribute_flag[7] != 0)
8138 compose=(CompositeOperator) argument_list[7].integer_reference;
8139 image=FrameImage(image,&frame_info,compose,exception);
8140 break;
8141 }
8142 case 16: /* Implode */
8143 {
8144 PixelInterpolateMethod
8145 method;
8146
8147 if (attribute_flag[0] == 0)
8148 argument_list[0].real_reference=0.5;
8149 method=UndefinedInterpolatePixel;
8150 if (attribute_flag[1] != 0)
8151 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8152 image=ImplodeImage(image,argument_list[0].real_reference,
8153 method,exception);
8154 break;
8155 }
8156 case 17: /* Magnify */
8157 {
8158 image=MagnifyImage(image,exception);
8159 break;
8160 }
8161 case 18: /* MedianFilter */
8162 {
8163 if (attribute_flag[0] != 0)
8164 {
8165 flags=ParseGeometry(argument_list[0].string_reference,
8166 &geometry_info);
8167 if ((flags & SigmaValue) == 0)
8168 geometry_info.sigma=geometry_info.rho;
8169 }
8170 if (attribute_flag[1] != 0)
8171 geometry_info.rho=argument_list[1].real_reference;
8172 if (attribute_flag[2] != 0)
8173 geometry_info.sigma=argument_list[2].real_reference;
8174 if (attribute_flag[3] != 0)
8175 channel=(ChannelType) argument_list[3].integer_reference;
8176 channel_mask=SetImageChannelMask(image,channel);
8177 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8178 (size_t) geometry_info.sigma,exception);
8179 if (image != (Image *) NULL)
8180 (void) SetImageChannelMask(image,channel_mask);
8181 break;
8182 }
8183 case 19: /* Minify */
8184 {
8185 image=MinifyImage(image,exception);
8186 break;
8187 }
8188 case 20: /* OilPaint */
8189 {
8190 if (attribute_flag[0] == 0)
8191 argument_list[0].real_reference=0.0;
8192 if (attribute_flag[1] == 0)
8193 argument_list[1].real_reference=1.0;
8194 image=OilPaintImage(image,argument_list[0].real_reference,
8195 argument_list[1].real_reference,exception);
8196 break;
8197 }
8198 case 21: /* ReduceNoise */
8199 {
8200 if (attribute_flag[0] != 0)
8201 {
8202 flags=ParseGeometry(argument_list[0].string_reference,
8203 &geometry_info);
8204 if ((flags & SigmaValue) == 0)
8205 geometry_info.sigma=1.0;
8206 }
8207 if (attribute_flag[1] != 0)
8208 geometry_info.rho=argument_list[1].real_reference;
8209 if (attribute_flag[2] != 0)
8210 geometry_info.sigma=argument_list[2].real_reference;
8211 if (attribute_flag[3] != 0)
8212 channel=(ChannelType) argument_list[3].integer_reference;
8213 channel_mask=SetImageChannelMask(image,channel);
8214 image=StatisticImage(image,NonpeakStatistic,(size_t)
8215 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8216 if (image != (Image *) NULL)
8217 (void) SetImageChannelMask(image,channel_mask);
8218 break;
8219 }
8220 case 22: /* Roll */
8221 {
8222 if (attribute_flag[0] != 0)
Cristyf94b0842017-07-14 07:05:02 -04008223 {
8224 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8225 &geometry,exception);
8226 if ((flags & PercentValue) != 0)
8227 {
8228 geometry.x*=(double) image->columns/100.0;
8229 geometry.y*=(double) image->rows/100.0;
8230 }
8231 }
cristy4a3ce0a2013-08-03 20:06:59 +00008232 if (attribute_flag[1] != 0)
8233 geometry.x=argument_list[1].integer_reference;
8234 if (attribute_flag[2] != 0)
8235 geometry.y=argument_list[2].integer_reference;
8236 image=RollImage(image,geometry.x,geometry.y,exception);
8237 break;
8238 }
8239 case 23: /* Rotate */
8240 {
8241 if (attribute_flag[0] == 0)
8242 argument_list[0].real_reference=90.0;
8243 if (attribute_flag[1] != 0)
8244 {
8245 QueryColorCompliance(argument_list[1].string_reference,
8246 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008247 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8248 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008249 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8250 }
8251 image=RotateImage(image,argument_list[0].real_reference,exception);
8252 break;
8253 }
8254 case 24: /* Sample */
8255 {
8256 if (attribute_flag[0] != 0)
8257 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8258 &geometry,exception);
8259 if (attribute_flag[1] != 0)
8260 geometry.width=argument_list[1].integer_reference;
8261 if (attribute_flag[2] != 0)
8262 geometry.height=argument_list[2].integer_reference;
8263 image=SampleImage(image,geometry.width,geometry.height,exception);
8264 break;
8265 }
8266 case 25: /* Scale */
8267 {
8268 if (attribute_flag[0] != 0)
8269 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8270 &geometry,exception);
8271 if (attribute_flag[1] != 0)
8272 geometry.width=argument_list[1].integer_reference;
8273 if (attribute_flag[2] != 0)
8274 geometry.height=argument_list[2].integer_reference;
8275 image=ScaleImage(image,geometry.width,geometry.height,exception);
8276 break;
8277 }
8278 case 26: /* Shade */
8279 {
8280 if (attribute_flag[0] != 0)
8281 {
8282 flags=ParseGeometry(argument_list[0].string_reference,
8283 &geometry_info);
8284 if ((flags & SigmaValue) == 0)
8285 geometry_info.sigma=0.0;
8286 }
8287 if (attribute_flag[1] != 0)
8288 geometry_info.rho=argument_list[1].real_reference;
8289 if (attribute_flag[2] != 0)
8290 geometry_info.sigma=argument_list[2].real_reference;
8291 image=ShadeImage(image,
8292 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8293 geometry_info.rho,geometry_info.sigma,exception);
8294 break;
8295 }
8296 case 27: /* Sharpen */
8297 {
8298 if (attribute_flag[0] != 0)
8299 {
8300 flags=ParseGeometry(argument_list[0].string_reference,
8301 &geometry_info);
8302 if ((flags & SigmaValue) == 0)
8303 geometry_info.sigma=1.0;
8304 }
8305 if (attribute_flag[1] != 0)
8306 geometry_info.rho=argument_list[1].real_reference;
8307 if (attribute_flag[2] != 0)
8308 geometry_info.sigma=argument_list[2].real_reference;
8309 if (attribute_flag[3] != 0)
8310 channel=(ChannelType) argument_list[3].integer_reference;
8311 channel_mask=SetImageChannelMask(image,channel);
8312 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8313 exception);
8314 if (image != (Image *) NULL)
8315 (void) SetImageChannelMask(image,channel_mask);
8316 break;
8317 }
8318 case 28: /* Shear */
8319 {
8320 if (attribute_flag[0] != 0)
8321 {
8322 flags=ParseGeometry(argument_list[0].string_reference,
8323 &geometry_info);
8324 if ((flags & SigmaValue) == 0)
8325 geometry_info.sigma=geometry_info.rho;
8326 }
8327 if (attribute_flag[1] != 0)
8328 geometry_info.rho=argument_list[1].real_reference;
8329 if (attribute_flag[2] != 0)
8330 geometry_info.sigma=argument_list[2].real_reference;
8331 if (attribute_flag[3] != 0)
8332 QueryColorCompliance(argument_list[3].string_reference,
8333 AllCompliance,&image->background_color,exception);
8334 if (attribute_flag[4] != 0)
8335 QueryColorCompliance(argument_list[4].string_reference,
8336 AllCompliance,&image->background_color,exception);
8337 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8338 exception);
8339 break;
8340 }
8341 case 29: /* Spread */
8342 {
Cristye3319c12015-08-24 07:11:48 -04008343 PixelInterpolateMethod
8344 method;
8345
cristy4a3ce0a2013-08-03 20:06:59 +00008346 if (attribute_flag[0] == 0)
8347 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008348 method=UndefinedInterpolatePixel;
8349 if (attribute_flag[1] != 0)
8350 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8351 image=SpreadImage(image,method,argument_list[0].real_reference,
8352 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008353 break;
8354 }
8355 case 30: /* Swirl */
8356 {
8357 PixelInterpolateMethod
8358 method;
8359
8360 if (attribute_flag[0] == 0)
8361 argument_list[0].real_reference=50.0;
8362 method=UndefinedInterpolatePixel;
8363 if (attribute_flag[1] != 0)
8364 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8365 image=SwirlImage(image,argument_list[0].real_reference,
8366 method,exception);
8367 break;
8368 }
8369 case 31: /* Resize */
8370 case 32: /* Zoom */
8371 {
8372 if (attribute_flag[0] != 0)
8373 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8374 &geometry,exception);
8375 if (attribute_flag[1] != 0)
8376 geometry.width=argument_list[1].integer_reference;
8377 if (attribute_flag[2] != 0)
8378 geometry.height=argument_list[2].integer_reference;
8379 if (attribute_flag[3] == 0)
8380 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8381 if (attribute_flag[4] != 0)
8382 SetImageArtifact(image,"filter:support",
8383 argument_list[4].string_reference);
8384 image=ResizeImage(image,geometry.width,geometry.height,
Cristy8645e042016-02-03 16:35:29 -05008385 (FilterType) argument_list[3].integer_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00008386 exception);
8387 break;
8388 }
8389 case 33: /* Annotate */
8390 {
8391 DrawInfo
8392 *draw_info;
8393
8394 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8395 (DrawInfo *) NULL);
8396 if (attribute_flag[0] != 0)
8397 {
8398 char
8399 *text;
8400
8401 text=InterpretImageProperties(info ? info->image_info :
8402 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8403 exception);
8404 (void) CloneString(&draw_info->text,text);
8405 text=DestroyString(text);
8406 }
8407 if (attribute_flag[1] != 0)
8408 (void) CloneString(&draw_info->font,
8409 argument_list[1].string_reference);
8410 if (attribute_flag[2] != 0)
8411 draw_info->pointsize=argument_list[2].real_reference;
8412 if (attribute_flag[3] != 0)
8413 (void) CloneString(&draw_info->density,
8414 argument_list[3].string_reference);
8415 if (attribute_flag[4] != 0)
8416 (void) QueryColorCompliance(argument_list[4].string_reference,
8417 AllCompliance,&draw_info->undercolor,exception);
8418 if (attribute_flag[5] != 0)
8419 {
8420 (void) QueryColorCompliance(argument_list[5].string_reference,
8421 AllCompliance,&draw_info->stroke,exception);
8422 if (argument_list[5].image_reference != (Image *) NULL)
8423 draw_info->stroke_pattern=CloneImage(
8424 argument_list[5].image_reference,0,0,MagickTrue,exception);
8425 }
8426 if (attribute_flag[6] != 0)
8427 {
8428 (void) QueryColorCompliance(argument_list[6].string_reference,
8429 AllCompliance,&draw_info->fill,exception);
8430 if (argument_list[6].image_reference != (Image *) NULL)
8431 draw_info->fill_pattern=CloneImage(
8432 argument_list[6].image_reference,0,0,MagickTrue,exception);
8433 }
8434 if (attribute_flag[7] != 0)
8435 {
8436 (void) CloneString(&draw_info->geometry,
8437 argument_list[7].string_reference);
8438 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8439 &geometry,exception);
8440 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8441 geometry_info.sigma=geometry_info.xi;
8442 }
8443 if (attribute_flag[8] != 0)
8444 (void) QueryColorCompliance(argument_list[8].string_reference,
8445 AllCompliance,&draw_info->fill,exception);
8446 if (attribute_flag[11] != 0)
8447 draw_info->gravity=(GravityType)
8448 argument_list[11].integer_reference;
8449 if (attribute_flag[25] != 0)
8450 {
8451 AV
8452 *av;
8453
8454 av=(AV *) argument_list[25].array_reference;
8455 if ((av_len(av) != 3) && (av_len(av) != 5))
8456 {
8457 ThrowPerlException(exception,OptionError,
8458 "affine matrix must have 4 or 6 elements",PackageName);
8459 goto PerlException;
8460 }
8461 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8462 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8463 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8464 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8465 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8466 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8467 {
8468 ThrowPerlException(exception,OptionError,
8469 "affine matrix is singular",PackageName);
8470 goto PerlException;
8471 }
8472 if (av_len(av) == 5)
8473 {
8474 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8475 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8476 }
8477 }
8478 for (j=12; j < 17; j++)
8479 {
8480 if (attribute_flag[j] == 0)
8481 continue;
8482 value=argument_list[j].string_reference;
8483 angle=argument_list[j].real_reference;
8484 current=draw_info->affine;
8485 GetAffineMatrix(&affine);
8486 switch (j)
8487 {
8488 case 12:
8489 {
8490 /*
8491 Translate.
8492 */
8493 flags=ParseGeometry(value,&geometry_info);
8494 affine.tx=geometry_info.xi;
8495 affine.ty=geometry_info.psi;
8496 if ((flags & PsiValue) == 0)
8497 affine.ty=affine.tx;
8498 break;
8499 }
8500 case 13:
8501 {
8502 /*
8503 Scale.
8504 */
8505 flags=ParseGeometry(value,&geometry_info);
8506 affine.sx=geometry_info.rho;
8507 affine.sy=geometry_info.sigma;
8508 if ((flags & SigmaValue) == 0)
8509 affine.sy=affine.sx;
8510 break;
8511 }
8512 case 14:
8513 {
8514 /*
8515 Rotate.
8516 */
8517 if (angle == 0.0)
8518 break;
8519 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8520 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8521 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8522 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8523 break;
8524 }
8525 case 15:
8526 {
8527 /*
8528 SkewX.
8529 */
8530 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8531 break;
8532 }
8533 case 16:
8534 {
8535 /*
8536 SkewY.
8537 */
8538 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8539 break;
8540 }
8541 }
8542 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8543 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8544 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8545 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8546 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8547 current.tx;
8548 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8549 current.ty;
8550 }
8551 if (attribute_flag[9] == 0)
8552 argument_list[9].real_reference=0.0;
8553 if (attribute_flag[10] == 0)
8554 argument_list[10].real_reference=0.0;
8555 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8556 {
8557 char
cristy151b66d2015-04-15 10:50:31 +00008558 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008559
cristy151b66d2015-04-15 10:50:31 +00008560 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008561 (double) argument_list[9].real_reference+draw_info->affine.tx,
8562 (double) argument_list[10].real_reference+draw_info->affine.ty);
8563 (void) CloneString(&draw_info->geometry,geometry);
8564 }
8565 if (attribute_flag[17] != 0)
8566 draw_info->stroke_width=argument_list[17].real_reference;
8567 if (attribute_flag[18] != 0)
8568 {
8569 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8570 MagickTrue : MagickFalse;
8571 draw_info->stroke_antialias=draw_info->text_antialias;
8572 }
8573 if (attribute_flag[19] != 0)
8574 (void) CloneString(&draw_info->family,
8575 argument_list[19].string_reference);
8576 if (attribute_flag[20] != 0)
8577 draw_info->style=(StyleType) argument_list[20].integer_reference;
8578 if (attribute_flag[21] != 0)
8579 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8580 if (attribute_flag[22] != 0)
8581 draw_info->weight=argument_list[22].integer_reference;
8582 if (attribute_flag[23] != 0)
8583 draw_info->align=(AlignType) argument_list[23].integer_reference;
8584 if (attribute_flag[24] != 0)
8585 (void) CloneString(&draw_info->encoding,
8586 argument_list[24].string_reference);
8587 if (attribute_flag[25] != 0)
8588 draw_info->fill_pattern=CloneImage(
8589 argument_list[25].image_reference,0,0,MagickTrue,exception);
8590 if (attribute_flag[26] != 0)
8591 draw_info->fill_pattern=CloneImage(
8592 argument_list[26].image_reference,0,0,MagickTrue,exception);
8593 if (attribute_flag[27] != 0)
8594 draw_info->stroke_pattern=CloneImage(
8595 argument_list[27].image_reference,0,0,MagickTrue,exception);
8596 if (attribute_flag[29] != 0)
8597 draw_info->kerning=argument_list[29].real_reference;
8598 if (attribute_flag[30] != 0)
8599 draw_info->interline_spacing=argument_list[30].real_reference;
8600 if (attribute_flag[31] != 0)
8601 draw_info->interword_spacing=argument_list[31].real_reference;
8602 if (attribute_flag[32] != 0)
8603 draw_info->direction=(DirectionType)
8604 argument_list[32].integer_reference;
8605 (void) AnnotateImage(image,draw_info,exception);
8606 draw_info=DestroyDrawInfo(draw_info);
8607 break;
8608 }
8609 case 34: /* ColorFloodfill */
8610 {
8611 DrawInfo
8612 *draw_info;
8613
8614 MagickBooleanType
8615 invert;
8616
8617 PixelInfo
8618 target;
8619
8620 draw_info=CloneDrawInfo(info ? info->image_info :
8621 (ImageInfo *) NULL,(DrawInfo *) NULL);
8622 if (attribute_flag[0] != 0)
8623 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8624 &geometry,exception);
8625 if (attribute_flag[1] != 0)
8626 geometry.x=argument_list[1].integer_reference;
8627 if (attribute_flag[2] != 0)
8628 geometry.y=argument_list[2].integer_reference;
8629 if (attribute_flag[3] != 0)
8630 (void) QueryColorCompliance(argument_list[3].string_reference,
8631 AllCompliance,&draw_info->fill,exception);
8632 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8633 geometry.x,geometry.y,&target,exception);
8634 invert=MagickFalse;
8635 if (attribute_flag[4] != 0)
8636 {
8637 QueryColorCompliance(argument_list[4].string_reference,
8638 AllCompliance,&target,exception);
8639 invert=MagickTrue;
8640 }
8641 if (attribute_flag[5] != 0)
8642 image->fuzz=StringToDoubleInterval(
8643 argument_list[5].string_reference,(double) QuantumRange+1.0);
8644 if (attribute_flag[6] != 0)
8645 invert=(MagickBooleanType) argument_list[6].integer_reference;
8646 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8647 geometry.y,invert,exception);
8648 draw_info=DestroyDrawInfo(draw_info);
8649 break;
8650 }
8651 case 35: /* Composite */
8652 {
8653 char
cristy151b66d2015-04-15 10:50:31 +00008654 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008655
8656 Image
8657 *composite_image,
8658 *rotate_image;
8659
8660 MagickBooleanType
8661 clip_to_self;
8662
8663 compose=OverCompositeOp;
8664 if (attribute_flag[0] != 0)
8665 composite_image=argument_list[0].image_reference;
8666 else
8667 {
8668 ThrowPerlException(exception,OptionError,
8669 "CompositeImageRequired",PackageName);
8670 goto PerlException;
8671 }
8672 /*
8673 Parameter Handling used for BOTH normal and tiled composition.
8674 */
8675 if (attribute_flag[1] != 0) /* compose */
8676 compose=(CompositeOperator) argument_list[1].integer_reference;
8677 if (attribute_flag[6] != 0) /* opacity */
8678 {
8679 if (compose != DissolveCompositeOp)
8680 (void) SetImageAlpha(composite_image,(Quantum)
8681 StringToDoubleInterval(argument_list[6].string_reference,
8682 (double) QuantumRange+1.0),exception);
8683 else
8684 {
8685 CacheView
8686 *composite_view;
8687
8688 double
8689 opacity;
8690
8691 MagickBooleanType
8692 sync;
8693
8694 register ssize_t
8695 x;
8696
8697 register Quantum
8698 *q;
8699
8700 ssize_t
8701 y;
8702
8703 /*
8704 Handle dissolve composite operator (patch by
8705 Kevin A. McGrail).
8706 */
8707 (void) CloneString(&image->geometry,
8708 argument_list[6].string_reference);
8709 opacity=(Quantum) StringToDoubleInterval(
8710 argument_list[6].string_reference,(double) QuantumRange+
8711 1.0);
cristy17f11b02014-12-20 19:37:04 +00008712 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008713 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8714 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8715 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8716 {
8717 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8718 composite_image->columns,1,exception);
8719 for (x=0; x < (ssize_t) composite_image->columns; x++)
8720 {
8721 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8722 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8723 q);
8724 q+=GetPixelChannels(composite_image);
8725 }
8726 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8727 if (sync == MagickFalse)
8728 break;
8729 }
8730 composite_view=DestroyCacheView(composite_view);
8731 }
8732 }
8733 if (attribute_flag[9] != 0) /* "color=>" */
8734 QueryColorCompliance(argument_list[9].string_reference,
8735 AllCompliance,&composite_image->background_color,exception);
8736 if (attribute_flag[12] != 0) /* "interpolate=>" */
8737 image->interpolate=(PixelInterpolateMethod)
8738 argument_list[12].integer_reference;
8739 if (attribute_flag[13] != 0) /* "args=>" */
8740 (void) SetImageArtifact(composite_image,"compose:args",
8741 argument_list[13].string_reference);
8742 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8743 (void) SetImageArtifact(composite_image,"compose:args",
8744 argument_list[14].string_reference);
8745 clip_to_self=MagickTrue;
8746 if (attribute_flag[15] != 0)
8747 clip_to_self=(MagickBooleanType)
8748 argument_list[15].integer_reference;
8749 /*
8750 Tiling Composition (with orthogonal rotate).
8751 */
8752 rotate_image=(Image *) NULL;
8753 if (attribute_flag[8] != 0) /* "rotate=>" */
8754 {
8755 /*
8756 Rotate image.
8757 */
8758 rotate_image=RotateImage(composite_image,
8759 argument_list[8].real_reference,exception);
8760 if (rotate_image == (Image *) NULL)
8761 break;
8762 }
8763 if ((attribute_flag[7] != 0) &&
8764 (argument_list[7].integer_reference != 0)) /* tile */
8765 {
8766 ssize_t
8767 x,
8768 y;
8769
8770 /*
8771 Tile the composite image.
8772 */
8773 if (attribute_flag[8] != 0) /* "tile=>" */
8774 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8775 "false");
8776 else
8777 (void) SetImageArtifact(composite_image,
8778 "compose:outside-overlay","false");
8779 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8780 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8781 {
8782 if (attribute_flag[8] != 0) /* rotate */
8783 (void) CompositeImage(image,rotate_image,compose,
8784 MagickTrue,x,y,exception);
8785 else
8786 (void) CompositeImage(image,composite_image,compose,
8787 MagickTrue,x,y,exception);
8788 }
8789 if (attribute_flag[8] != 0) /* rotate */
8790 rotate_image=DestroyImage(rotate_image);
8791 break;
8792 }
8793 /*
8794 Parameter Handling used used ONLY for normal composition.
8795 */
8796 if (attribute_flag[5] != 0) /* gravity */
8797 image->gravity=(GravityType) argument_list[5].integer_reference;
8798 if (attribute_flag[2] != 0) /* geometry offset */
8799 {
8800 SetGeometry(image,&geometry);
8801 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8802 &geometry);
8803 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8804 &geometry);
8805 }
8806 if (attribute_flag[3] != 0) /* x offset */
8807 geometry.x=argument_list[3].integer_reference;
8808 if (attribute_flag[4] != 0) /* y offset */
8809 geometry.y=argument_list[4].integer_reference;
8810 if (attribute_flag[10] != 0) /* mask */
8811 {
8812 if ((image->compose == DisplaceCompositeOp) ||
8813 (image->compose == DistortCompositeOp))
8814 {
8815 /*
8816 Merge Y displacement into X displacement image.
8817 */
8818 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8819 exception);
8820 (void) CompositeImage(composite_image,
8821 argument_list[10].image_reference,CopyGreenCompositeOp,
8822 MagickTrue,0,0,exception);
8823 }
8824 else
8825 {
8826 Image
8827 *mask_image;
8828
8829 /*
8830 Set a blending mask for the composition.
8831 */
8832 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8833 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008834 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008835 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008836 mask_image=DestroyImage(mask_image);
8837 }
8838 }
8839 if (attribute_flag[11] != 0) /* channel */
8840 channel=(ChannelType) argument_list[11].integer_reference;
8841 /*
8842 Composite two images (normal composition).
8843 */
cristy151b66d2015-04-15 10:50:31 +00008844 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008845 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8846 (double) composite_image->rows,(double) geometry.x,(double)
8847 geometry.y);
8848 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8849 exception);
8850 channel_mask=SetImageChannelMask(image,channel);
8851 if (attribute_flag[8] == 0) /* no rotate */
8852 CompositeImage(image,composite_image,compose,clip_to_self,
8853 geometry.x,geometry.y,exception);
8854 else
8855 {
8856 /*
8857 Position adjust rotated image then composite.
8858 */
8859 geometry.x-=(ssize_t) (rotate_image->columns-
8860 composite_image->columns)/2;
8861 geometry.y-=(ssize_t) (rotate_image->rows-
8862 composite_image->rows)/2;
8863 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8864 geometry.y,exception);
8865 rotate_image=DestroyImage(rotate_image);
8866 }
8867 if (attribute_flag[10] != 0) /* mask */
8868 {
8869 if ((image->compose == DisplaceCompositeOp) ||
8870 (image->compose == DistortCompositeOp))
8871 composite_image=DestroyImage(composite_image);
8872 else
cristy1f7ffb72015-07-29 11:07:03 +00008873 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008874 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008875 }
8876 (void) SetImageChannelMask(image,channel_mask);
8877 break;
8878 }
8879 case 36: /* Contrast */
8880 {
8881 if (attribute_flag[0] == 0)
8882 argument_list[0].integer_reference=0;
8883 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8884 MagickTrue : MagickFalse,exception);
8885 break;
8886 }
8887 case 37: /* CycleColormap */
8888 {
8889 if (attribute_flag[0] == 0)
8890 argument_list[0].integer_reference=6;
8891 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8892 exception);
8893 break;
8894 }
8895 case 38: /* Draw */
8896 {
8897 DrawInfo
8898 *draw_info;
8899
8900 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8901 (DrawInfo *) NULL);
8902 (void) CloneString(&draw_info->primitive,"point");
8903 if (attribute_flag[0] != 0)
8904 {
8905 if (argument_list[0].integer_reference < 0)
8906 (void) CloneString(&draw_info->primitive,
8907 argument_list[0].string_reference);
8908 else
8909 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8910 MagickPrimitiveOptions,argument_list[0].integer_reference));
8911 }
8912 if (attribute_flag[1] != 0)
8913 {
8914 if (LocaleCompare(draw_info->primitive,"path") == 0)
8915 {
8916 (void) ConcatenateString(&draw_info->primitive," '");
8917 ConcatenateString(&draw_info->primitive,
8918 argument_list[1].string_reference);
8919 (void) ConcatenateString(&draw_info->primitive,"'");
8920 }
8921 else
8922 {
8923 (void) ConcatenateString(&draw_info->primitive," ");
8924 ConcatenateString(&draw_info->primitive,
8925 argument_list[1].string_reference);
8926 }
8927 }
8928 if (attribute_flag[2] != 0)
8929 {
8930 (void) ConcatenateString(&draw_info->primitive," ");
8931 (void) ConcatenateString(&draw_info->primitive,
8932 CommandOptionToMnemonic(MagickMethodOptions,
8933 argument_list[2].integer_reference));
8934 }
8935 if (attribute_flag[3] != 0)
8936 {
8937 (void) QueryColorCompliance(argument_list[3].string_reference,
8938 AllCompliance,&draw_info->stroke,exception);
8939 if (argument_list[3].image_reference != (Image *) NULL)
8940 draw_info->stroke_pattern=CloneImage(
8941 argument_list[3].image_reference,0,0,MagickTrue,exception);
8942 }
8943 if (attribute_flag[4] != 0)
8944 {
8945 (void) QueryColorCompliance(argument_list[4].string_reference,
8946 AllCompliance,&draw_info->fill,exception);
8947 if (argument_list[4].image_reference != (Image *) NULL)
8948 draw_info->fill_pattern=CloneImage(
8949 argument_list[4].image_reference,0,0,MagickTrue,exception);
8950 }
8951 if (attribute_flag[5] != 0)
8952 draw_info->stroke_width=argument_list[5].real_reference;
8953 if (attribute_flag[6] != 0)
8954 (void) CloneString(&draw_info->font,
8955 argument_list[6].string_reference);
8956 if (attribute_flag[7] != 0)
8957 (void) QueryColorCompliance(argument_list[7].string_reference,
8958 AllCompliance,&draw_info->border_color,exception);
8959 if (attribute_flag[8] != 0)
8960 draw_info->affine.tx=argument_list[8].real_reference;
8961 if (attribute_flag[9] != 0)
8962 draw_info->affine.ty=argument_list[9].real_reference;
8963 if (attribute_flag[20] != 0)
8964 {
8965 AV
8966 *av;
8967
8968 av=(AV *) argument_list[20].array_reference;
8969 if ((av_len(av) != 3) && (av_len(av) != 5))
8970 {
8971 ThrowPerlException(exception,OptionError,
8972 "affine matrix must have 4 or 6 elements",PackageName);
8973 goto PerlException;
8974 }
8975 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8976 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8977 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8978 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8979 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8980 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8981 {
8982 ThrowPerlException(exception,OptionError,
8983 "affine matrix is singular",PackageName);
8984 goto PerlException;
8985 }
8986 if (av_len(av) == 5)
8987 {
8988 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8989 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8990 }
8991 }
8992 for (j=10; j < 15; j++)
8993 {
8994 if (attribute_flag[j] == 0)
8995 continue;
8996 value=argument_list[j].string_reference;
8997 angle=argument_list[j].real_reference;
8998 current=draw_info->affine;
8999 GetAffineMatrix(&affine);
9000 switch (j)
9001 {
9002 case 10:
9003 {
9004 /*
9005 Translate.
9006 */
9007 flags=ParseGeometry(value,&geometry_info);
9008 affine.tx=geometry_info.xi;
9009 affine.ty=geometry_info.psi;
9010 if ((flags & PsiValue) == 0)
9011 affine.ty=affine.tx;
9012 break;
9013 }
9014 case 11:
9015 {
9016 /*
9017 Scale.
9018 */
9019 flags=ParseGeometry(value,&geometry_info);
9020 affine.sx=geometry_info.rho;
9021 affine.sy=geometry_info.sigma;
9022 if ((flags & SigmaValue) == 0)
9023 affine.sy=affine.sx;
9024 break;
9025 }
9026 case 12:
9027 {
9028 /*
9029 Rotate.
9030 */
9031 if (angle == 0.0)
9032 break;
9033 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9034 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9035 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9036 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9037 break;
9038 }
9039 case 13:
9040 {
9041 /*
9042 SkewX.
9043 */
9044 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9045 break;
9046 }
9047 case 14:
9048 {
9049 /*
9050 SkewY.
9051 */
9052 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9053 break;
9054 }
9055 }
9056 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9057 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9058 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9059 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9060 draw_info->affine.tx=
9061 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9062 draw_info->affine.ty=
9063 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9064 }
9065 if (attribute_flag[15] != 0)
9066 draw_info->fill_pattern=CloneImage(
9067 argument_list[15].image_reference,0,0,MagickTrue,exception);
9068 if (attribute_flag[16] != 0)
9069 draw_info->pointsize=argument_list[16].real_reference;
9070 if (attribute_flag[17] != 0)
9071 {
9072 draw_info->stroke_antialias=argument_list[17].integer_reference != 0
9073 ? MagickTrue : MagickFalse;
9074 draw_info->text_antialias=draw_info->stroke_antialias;
9075 }
9076 if (attribute_flag[18] != 0)
9077 (void) CloneString(&draw_info->density,
9078 argument_list[18].string_reference);
9079 if (attribute_flag[19] != 0)
9080 draw_info->stroke_width=argument_list[19].real_reference;
9081 if (attribute_flag[21] != 0)
9082 draw_info->dash_offset=argument_list[21].real_reference;
9083 if (attribute_flag[22] != 0)
9084 {
9085 AV
9086 *av;
9087
9088 av=(AV *) argument_list[22].array_reference;
9089 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9090 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9091 if (draw_info->dash_pattern != (double *) NULL)
9092 {
9093 for (i=0; i <= av_len(av); i++)
9094 draw_info->dash_pattern[i]=(double)
9095 SvNV(*(av_fetch(av,i,0)));
9096 draw_info->dash_pattern[i]=0.0;
9097 }
9098 }
9099 if (attribute_flag[23] != 0)
9100 image->interpolate=(PixelInterpolateMethod)
9101 argument_list[23].integer_reference;
9102 if ((attribute_flag[24] != 0) &&
9103 (draw_info->fill_pattern != (Image *) NULL))
9104 flags=ParsePageGeometry(draw_info->fill_pattern,
9105 argument_list[24].string_reference,
9106 &draw_info->fill_pattern->tile_offset,exception);
9107 if (attribute_flag[25] != 0)
9108 {
9109 (void) ConcatenateString(&draw_info->primitive," '");
9110 (void) ConcatenateString(&draw_info->primitive,
9111 argument_list[25].string_reference);
9112 (void) ConcatenateString(&draw_info->primitive,"'");
9113 }
9114 if (attribute_flag[26] != 0)
9115 draw_info->fill_pattern=CloneImage(
9116 argument_list[26].image_reference,0,0,MagickTrue,exception);
9117 if (attribute_flag[27] != 0)
9118 draw_info->stroke_pattern=CloneImage(
9119 argument_list[27].image_reference,0,0,MagickTrue,exception);
9120 if (attribute_flag[28] != 0)
9121 (void) CloneString(&draw_info->primitive,
9122 argument_list[28].string_reference);
9123 if (attribute_flag[29] != 0)
9124 draw_info->kerning=argument_list[29].real_reference;
9125 if (attribute_flag[30] != 0)
9126 draw_info->interline_spacing=argument_list[30].real_reference;
9127 if (attribute_flag[31] != 0)
9128 draw_info->interword_spacing=argument_list[31].real_reference;
9129 if (attribute_flag[32] != 0)
9130 draw_info->direction=(DirectionType)
9131 argument_list[32].integer_reference;
9132 DrawImage(image,draw_info,exception);
9133 draw_info=DestroyDrawInfo(draw_info);
9134 break;
9135 }
9136 case 39: /* Equalize */
9137 {
9138 if (attribute_flag[0] != 0)
9139 channel=(ChannelType) argument_list[0].integer_reference;
9140 channel_mask=SetImageChannelMask(image,channel);
9141 EqualizeImage(image,exception);
9142 (void) SetImageChannelMask(image,channel_mask);
9143 break;
9144 }
9145 case 40: /* Gamma */
9146 {
9147 if (attribute_flag[1] != 0)
9148 channel=(ChannelType) argument_list[1].integer_reference;
9149 if (attribute_flag[2] == 0)
9150 argument_list[2].real_reference=1.0;
9151 if (attribute_flag[3] == 0)
9152 argument_list[3].real_reference=1.0;
9153 if (attribute_flag[4] == 0)
9154 argument_list[4].real_reference=1.0;
9155 if (attribute_flag[0] == 0)
9156 {
cristy151b66d2015-04-15 10:50:31 +00009157 (void) FormatLocaleString(message,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -05009158 "%.20g,%.20g,%.20g",(double) argument_list[2].real_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009159 (double) argument_list[3].real_reference,
9160 (double) argument_list[4].real_reference);
9161 argument_list[0].string_reference=message;
9162 }
9163 (void) GammaImage(image,StringToDouble(
9164 argument_list[0].string_reference,(char **) NULL),exception);
9165 break;
9166 }
9167 case 41: /* Map */
9168 {
9169 QuantizeInfo
9170 *quantize_info;
9171
9172 if (attribute_flag[0] == 0)
9173 {
9174 ThrowPerlException(exception,OptionError,"MapImageRequired",
9175 PackageName);
9176 goto PerlException;
9177 }
9178 quantize_info=AcquireQuantizeInfo(info->image_info);
9179 if (attribute_flag[1] != 0)
9180 quantize_info->dither_method=(DitherMethod)
9181 argument_list[1].integer_reference;
9182 (void) RemapImages(quantize_info,image,
9183 argument_list[0].image_reference,exception);
9184 quantize_info=DestroyQuantizeInfo(quantize_info);
9185 break;
9186 }
9187 case 42: /* MatteFloodfill */
9188 {
9189 DrawInfo
9190 *draw_info;
9191
9192 MagickBooleanType
9193 invert;
9194
9195 PixelInfo
9196 target;
9197
9198 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9199 (DrawInfo *) NULL);
9200 if (attribute_flag[0] != 0)
9201 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9202 &geometry,exception);
9203 if (attribute_flag[1] != 0)
9204 geometry.x=argument_list[1].integer_reference;
9205 if (attribute_flag[2] != 0)
9206 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009207 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009208 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9209 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9210 geometry.x,geometry.y,&target,exception);
9211 if (attribute_flag[4] != 0)
9212 QueryColorCompliance(argument_list[4].string_reference,
9213 AllCompliance,&target,exception);
9214 if (attribute_flag[3] != 0)
9215 target.alpha=StringToDoubleInterval(
9216 argument_list[3].string_reference,(double) (double) QuantumRange+
9217 1.0);
9218 if (attribute_flag[5] != 0)
9219 image->fuzz=StringToDoubleInterval(
9220 argument_list[5].string_reference,(double) QuantumRange+1.0);
9221 invert=MagickFalse;
9222 if (attribute_flag[6] != 0)
9223 invert=(MagickBooleanType) argument_list[6].integer_reference;
9224 channel_mask=SetImageChannelMask(image,AlphaChannel);
9225 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9226 geometry.y,invert,exception);
9227 (void) SetImageChannelMask(image,channel_mask);
9228 draw_info=DestroyDrawInfo(draw_info);
9229 break;
9230 }
9231 case 43: /* Modulate */
9232 {
9233 char
cristy151b66d2015-04-15 10:50:31 +00009234 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009235
9236 geometry_info.rho=100.0;
9237 geometry_info.sigma=100.0;
9238 geometry_info.xi=100.0;
9239 if (attribute_flag[0] != 0)
9240 (void)ParseGeometry(argument_list[0].string_reference,
9241 &geometry_info);
9242 if (attribute_flag[1] != 0)
9243 geometry_info.xi=argument_list[1].real_reference;
9244 if (attribute_flag[2] != 0)
9245 geometry_info.sigma=argument_list[2].real_reference;
9246 if (attribute_flag[3] != 0)
9247 {
9248 geometry_info.sigma=argument_list[3].real_reference;
9249 SetImageArtifact(image,"modulate:colorspace","HWB");
9250 }
9251 if (attribute_flag[4] != 0)
9252 {
9253 geometry_info.rho=argument_list[4].real_reference;
9254 SetImageArtifact(image,"modulate:colorspace","HSB");
9255 }
9256 if (attribute_flag[5] != 0)
9257 {
9258 geometry_info.sigma=argument_list[5].real_reference;
9259 SetImageArtifact(image,"modulate:colorspace","HSL");
9260 }
9261 if (attribute_flag[6] != 0)
9262 {
9263 geometry_info.rho=argument_list[6].real_reference;
9264 SetImageArtifact(image,"modulate:colorspace","HWB");
9265 }
Cristy935a4052017-03-31 17:45:37 -04009266 (void) FormatLocaleString(modulate,MagickPathExtent,"%.20g,%.20g,%.20g",
9267 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy4a3ce0a2013-08-03 20:06:59 +00009268 (void) ModulateImage(image,modulate,exception);
9269 break;
9270 }
9271 case 44: /* Negate */
9272 {
9273 if (attribute_flag[0] == 0)
9274 argument_list[0].integer_reference=0;
9275 if (attribute_flag[1] != 0)
9276 channel=(ChannelType) argument_list[1].integer_reference;
9277 channel_mask=SetImageChannelMask(image,channel);
9278 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9279 MagickTrue : MagickFalse,exception);
9280 (void) SetImageChannelMask(image,channel_mask);
9281 break;
9282 }
9283 case 45: /* Normalize */
9284 {
9285 if (attribute_flag[0] != 0)
9286 channel=(ChannelType) argument_list[0].integer_reference;
9287 channel_mask=SetImageChannelMask(image,channel);
9288 NormalizeImage(image,exception);
9289 (void) SetImageChannelMask(image,channel_mask);
9290 break;
9291 }
9292 case 46: /* NumberColors */
9293 break;
9294 case 47: /* Opaque */
9295 {
9296 MagickBooleanType
9297 invert;
9298
9299 PixelInfo
9300 fill_color,
9301 target;
9302
9303 (void) QueryColorCompliance("none",AllCompliance,&target,
9304 exception);
9305 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9306 exception);
9307 if (attribute_flag[0] != 0)
9308 (void) QueryColorCompliance(argument_list[0].string_reference,
9309 AllCompliance,&target,exception);
9310 if (attribute_flag[1] != 0)
9311 (void) QueryColorCompliance(argument_list[1].string_reference,
9312 AllCompliance,&fill_color,exception);
9313 if (attribute_flag[2] != 0)
9314 image->fuzz=StringToDoubleInterval(
9315 argument_list[2].string_reference,(double) QuantumRange+1.0);
9316 if (attribute_flag[3] != 0)
9317 channel=(ChannelType) argument_list[3].integer_reference;
9318 invert=MagickFalse;
9319 if (attribute_flag[4] != 0)
9320 invert=(MagickBooleanType) argument_list[4].integer_reference;
9321 channel_mask=SetImageChannelMask(image,channel);
9322 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9323 (void) SetImageChannelMask(image,channel_mask);
9324 break;
9325 }
9326 case 48: /* Quantize */
9327 {
9328 QuantizeInfo
9329 *quantize_info;
9330
9331 quantize_info=AcquireQuantizeInfo(info->image_info);
9332 if (attribute_flag[0] != 0)
9333 quantize_info->number_colors=(size_t)
9334 argument_list[0].integer_reference;
9335 if (attribute_flag[1] != 0)
9336 quantize_info->tree_depth=(size_t)
9337 argument_list[1].integer_reference;
9338 if (attribute_flag[2] != 0)
9339 quantize_info->colorspace=(ColorspaceType)
9340 argument_list[2].integer_reference;
9341 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009342 quantize_info->dither_method=(DitherMethod)
9343 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009344 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009345 quantize_info->measure_error=
9346 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009347 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009348 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009349 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009350 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009351 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009352 argument_list[7].integer_reference;
9353 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009354 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009355 else
cristyf7563392014-03-25 13:54:04 +00009356 if ((image->storage_class == DirectClass) ||
9357 (image->colors > quantize_info->number_colors) ||
9358 (quantize_info->colorspace == GRAYColorspace))
9359 (void) QuantizeImage(quantize_info,image,exception);
9360 else
9361 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009362 quantize_info=DestroyQuantizeInfo(quantize_info);
9363 break;
9364 }
9365 case 49: /* Raise */
9366 {
9367 if (attribute_flag[0] != 0)
9368 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9369 &geometry,exception);
9370 if (attribute_flag[1] != 0)
9371 geometry.width=argument_list[1].integer_reference;
9372 if (attribute_flag[2] != 0)
9373 geometry.height=argument_list[2].integer_reference;
9374 if (attribute_flag[3] == 0)
9375 argument_list[3].integer_reference=1;
9376 (void) RaiseImage(image,&geometry,
9377 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9378 exception);
9379 break;
9380 }
9381 case 50: /* Segment */
9382 {
9383 ColorspaceType
9384 colorspace;
9385
9386 double
9387 cluster_threshold,
9388 smoothing_threshold;
9389
9390 MagickBooleanType
9391 verbose;
9392
9393 cluster_threshold=1.0;
9394 smoothing_threshold=1.5;
9395 colorspace=sRGBColorspace;
9396 verbose=MagickFalse;
9397 if (attribute_flag[0] != 0)
9398 {
9399 flags=ParseGeometry(argument_list[0].string_reference,
9400 &geometry_info);
9401 cluster_threshold=geometry_info.rho;
9402 if (flags & SigmaValue)
9403 smoothing_threshold=geometry_info.sigma;
9404 }
9405 if (attribute_flag[1] != 0)
9406 cluster_threshold=argument_list[1].real_reference;
9407 if (attribute_flag[2] != 0)
9408 smoothing_threshold=argument_list[2].real_reference;
9409 if (attribute_flag[3] != 0)
9410 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9411 if (attribute_flag[4] != 0)
9412 verbose=argument_list[4].integer_reference != 0 ?
9413 MagickTrue : MagickFalse;
9414 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9415 smoothing_threshold,exception);
9416 break;
9417 }
9418 case 51: /* Signature */
9419 {
9420 (void) SignatureImage(image,exception);
9421 break;
9422 }
9423 case 52: /* Solarize */
9424 {
9425 geometry_info.rho=QuantumRange/2.0;
9426 if (attribute_flag[0] != 0)
9427 flags=ParseGeometry(argument_list[0].string_reference,
9428 &geometry_info);
9429 if (attribute_flag[1] != 0)
9430 geometry_info.rho=StringToDoubleInterval(
9431 argument_list[1].string_reference,(double) QuantumRange+1.0);
9432 (void) SolarizeImage(image,geometry_info.rho,exception);
9433 break;
9434 }
9435 case 53: /* Sync */
9436 {
9437 (void) SyncImage(image,exception);
9438 break;
9439 }
9440 case 54: /* Texture */
9441 {
9442 if (attribute_flag[0] == 0)
9443 break;
9444 TextureImage(image,argument_list[0].image_reference,exception);
9445 break;
9446 }
9447 case 55: /* Evalute */
9448 {
9449 MagickEvaluateOperator
9450 op;
9451
9452 op=SetEvaluateOperator;
9453 if (attribute_flag[0] == MagickFalse)
9454 argument_list[0].real_reference=0.0;
9455 if (attribute_flag[1] != MagickFalse)
9456 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9457 if (attribute_flag[2] != MagickFalse)
9458 channel=(ChannelType) argument_list[2].integer_reference;
9459 channel_mask=SetImageChannelMask(image,channel);
9460 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9461 exception);
9462 (void) SetImageChannelMask(image,channel_mask);
9463 break;
9464 }
9465 case 56: /* Transparent */
9466 {
9467 double
9468 opacity;
9469
9470 MagickBooleanType
9471 invert;
9472
9473 PixelInfo
9474 target;
9475
9476 (void) QueryColorCompliance("none",AllCompliance,&target,
9477 exception);
9478 if (attribute_flag[0] != 0)
9479 (void) QueryColorCompliance(argument_list[0].string_reference,
9480 AllCompliance,&target,exception);
9481 opacity=TransparentAlpha;
9482 if (attribute_flag[1] != 0)
9483 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9484 (double) QuantumRange+1.0);
9485 if (attribute_flag[2] != 0)
9486 image->fuzz=StringToDoubleInterval(
9487 argument_list[2].string_reference,(double) QuantumRange+1.0);
9488 if (attribute_flag[3] == 0)
9489 argument_list[3].integer_reference=0;
9490 invert=MagickFalse;
9491 if (attribute_flag[3] != 0)
9492 invert=(MagickBooleanType) argument_list[3].integer_reference;
9493 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9494 invert,exception);
9495 break;
9496 }
9497 case 57: /* Threshold */
9498 {
9499 double
9500 threshold;
9501
9502 if (attribute_flag[0] == 0)
9503 argument_list[0].string_reference="50%";
9504 if (attribute_flag[1] != 0)
9505 channel=(ChannelType) argument_list[1].integer_reference;
9506 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9507 (double) QuantumRange+1.0);
9508 channel_mask=SetImageChannelMask(image,channel);
9509 (void) BilevelImage(image,threshold,exception);
9510 (void) SetImageChannelMask(image,channel_mask);
9511 break;
9512 }
9513 case 58: /* Charcoal */
9514 {
9515 if (attribute_flag[0] != 0)
9516 {
9517 flags=ParseGeometry(argument_list[0].string_reference,
9518 &geometry_info);
9519 if ((flags & SigmaValue) == 0)
9520 geometry_info.sigma=1.0;
9521 }
9522 if (attribute_flag[1] != 0)
9523 geometry_info.rho=argument_list[1].real_reference;
9524 if (attribute_flag[2] != 0)
9525 geometry_info.sigma=argument_list[2].real_reference;
9526 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9527 exception);
9528 break;
9529 }
9530 case 59: /* Trim */
9531 {
9532 if (attribute_flag[0] != 0)
9533 image->fuzz=StringToDoubleInterval(
9534 argument_list[0].string_reference,(double) QuantumRange+1.0);
9535 image=TrimImage(image,exception);
9536 break;
9537 }
9538 case 60: /* Wave */
9539 {
9540 PixelInterpolateMethod
9541 method;
9542
9543 if (attribute_flag[0] != 0)
9544 {
9545 flags=ParseGeometry(argument_list[0].string_reference,
9546 &geometry_info);
9547 if ((flags & SigmaValue) == 0)
9548 geometry_info.sigma=1.0;
9549 }
9550 if (attribute_flag[1] != 0)
9551 geometry_info.rho=argument_list[1].real_reference;
9552 if (attribute_flag[2] != 0)
9553 geometry_info.sigma=argument_list[2].real_reference;
9554 method=UndefinedInterpolatePixel;
9555 if (attribute_flag[3] != 0)
9556 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9557 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9558 method,exception);
9559 break;
9560 }
9561 case 61: /* Separate */
9562 {
9563 if (attribute_flag[0] != 0)
9564 channel=(ChannelType) argument_list[0].integer_reference;
9565 image=SeparateImage(image,channel,exception);
9566 break;
9567 }
9568 case 63: /* Stereo */
9569 {
9570 if (attribute_flag[0] == 0)
9571 {
9572 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9573 PackageName);
9574 goto PerlException;
9575 }
9576 if (attribute_flag[1] != 0)
9577 geometry.x=argument_list[1].integer_reference;
9578 if (attribute_flag[2] != 0)
9579 geometry.y=argument_list[2].integer_reference;
9580 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9581 geometry.x,geometry.y,exception);
9582 break;
9583 }
9584 case 64: /* Stegano */
9585 {
9586 if (attribute_flag[0] == 0)
9587 {
9588 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9589 PackageName);
9590 goto PerlException;
9591 }
9592 if (attribute_flag[1] == 0)
9593 argument_list[1].integer_reference=0;
9594 image->offset=argument_list[1].integer_reference;
9595 image=SteganoImage(image,argument_list[0].image_reference,exception);
9596 break;
9597 }
9598 case 65: /* Deconstruct */
9599 {
9600 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9601 break;
9602 }
9603 case 66: /* GaussianBlur */
9604 {
9605 if (attribute_flag[0] != 0)
9606 {
9607 flags=ParseGeometry(argument_list[0].string_reference,
9608 &geometry_info);
9609 if ((flags & SigmaValue) == 0)
9610 geometry_info.sigma=1.0;
9611 }
9612 if (attribute_flag[1] != 0)
9613 geometry_info.rho=argument_list[1].real_reference;
9614 if (attribute_flag[2] != 0)
9615 geometry_info.sigma=argument_list[2].real_reference;
9616 if (attribute_flag[3] != 0)
9617 channel=(ChannelType) argument_list[3].integer_reference;
9618 channel_mask=SetImageChannelMask(image,channel);
9619 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9620 exception);
9621 if (image != (Image *) NULL)
9622 (void) SetImageChannelMask(image,channel_mask);
9623 break;
9624 }
9625 case 67: /* Convolve */
9626 {
9627 KernelInfo
9628 *kernel;
9629
9630 kernel=(KernelInfo *) NULL;
9631 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9632 break;
9633 if (attribute_flag[0] != 0)
9634 {
9635 AV
9636 *av;
9637
9638 size_t
9639 order;
9640
cristy2c57b742014-10-31 00:40:34 +00009641 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009642 if (kernel == (KernelInfo *) NULL)
9643 break;
9644 av=(AV *) argument_list[0].array_reference;
9645 order=(size_t) sqrt(av_len(av)+1);
9646 kernel->width=order;
9647 kernel->height=order;
9648 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9649 order*sizeof(*kernel->values));
9650 if (kernel->values == (MagickRealType *) NULL)
9651 {
9652 kernel=DestroyKernelInfo(kernel);
9653 ThrowPerlException(exception,ResourceLimitFatalError,
9654 "MemoryAllocationFailed",PackageName);
9655 goto PerlException;
9656 }
9657 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9658 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9659 for ( ; j < (ssize_t) (order*order); j++)
9660 kernel->values[j]=0.0;
9661 }
9662 if (attribute_flag[1] != 0)
9663 channel=(ChannelType) argument_list[1].integer_reference;
9664 if (attribute_flag[2] != 0)
Cristyc4ff6bd2017-07-05 21:00:11 -04009665 SetImageArtifact(image,"convolve:bias",
cristy4a3ce0a2013-08-03 20:06:59 +00009666 argument_list[2].string_reference);
9667 if (attribute_flag[3] != 0)
9668 {
cristy2c57b742014-10-31 00:40:34 +00009669 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9670 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009671 if (kernel == (KernelInfo *) NULL)
9672 break;
9673 }
9674 channel_mask=SetImageChannelMask(image,channel);
9675 image=ConvolveImage(image,kernel,exception);
9676 if (image != (Image *) NULL)
9677 (void) SetImageChannelMask(image,channel_mask);
9678 kernel=DestroyKernelInfo(kernel);
9679 break;
9680 }
9681 case 68: /* Profile */
9682 {
9683 const char
9684 *name;
9685
9686 Image
9687 *profile_image;
9688
9689 ImageInfo
9690 *profile_info;
9691
9692 StringInfo
9693 *profile;
9694
9695 name="*";
9696 if (attribute_flag[0] != 0)
9697 name=argument_list[0].string_reference;
9698 if (attribute_flag[2] != 0)
9699 image->rendering_intent=(RenderingIntent)
9700 argument_list[2].integer_reference;
9701 if (attribute_flag[3] != 0)
9702 image->black_point_compensation=
9703 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9704 if (attribute_flag[1] != 0)
9705 {
9706 if (argument_list[1].length == 0)
9707 {
9708 /*
9709 Remove a profile from the image.
9710 */
9711 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9712 exception);
9713 break;
9714 }
9715 /*
9716 Associate user supplied profile with the image.
9717 */
9718 profile=AcquireStringInfo(argument_list[1].length);
9719 SetStringInfoDatum(profile,(const unsigned char *)
9720 argument_list[1].string_reference);
9721 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9722 (size_t) GetStringInfoLength(profile),exception);
9723 profile=DestroyStringInfo(profile);
9724 break;
9725 }
9726 /*
9727 Associate a profile with the image.
9728 */
9729 profile_info=CloneImageInfo(info ? info->image_info :
9730 (ImageInfo *) NULL);
9731 profile_image=ReadImages(profile_info,name,exception);
9732 if (profile_image == (Image *) NULL)
9733 break;
9734 ResetImageProfileIterator(profile_image);
9735 name=GetNextImageProfile(profile_image);
9736 while (name != (const char *) NULL)
9737 {
9738 const StringInfo
9739 *profile;
9740
9741 profile=GetImageProfile(profile_image,name);
9742 if (profile != (const StringInfo *) NULL)
9743 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9744 (size_t) GetStringInfoLength(profile),exception);
9745 name=GetNextImageProfile(profile_image);
9746 }
9747 profile_image=DestroyImage(profile_image);
9748 profile_info=DestroyImageInfo(profile_info);
9749 break;
9750 }
9751 case 69: /* UnsharpMask */
9752 {
9753 if (attribute_flag[0] != 0)
9754 {
9755 flags=ParseGeometry(argument_list[0].string_reference,
9756 &geometry_info);
9757 if ((flags & SigmaValue) == 0)
9758 geometry_info.sigma=1.0;
9759 if ((flags & XiValue) == 0)
9760 geometry_info.xi=1.0;
9761 if ((flags & PsiValue) == 0)
9762 geometry_info.psi=0.5;
9763 }
9764 if (attribute_flag[1] != 0)
9765 geometry_info.rho=argument_list[1].real_reference;
9766 if (attribute_flag[2] != 0)
9767 geometry_info.sigma=argument_list[2].real_reference;
9768 if (attribute_flag[3] != 0)
9769 geometry_info.xi=argument_list[3].real_reference;
9770 if (attribute_flag[4] != 0)
9771 geometry_info.psi=argument_list[4].real_reference;
9772 if (attribute_flag[5] != 0)
9773 channel=(ChannelType) argument_list[5].integer_reference;
9774 channel_mask=SetImageChannelMask(image,channel);
9775 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9776 geometry_info.xi,geometry_info.psi,exception);
9777 if (image != (Image *) NULL)
9778 (void) SetImageChannelMask(image,channel_mask);
9779 break;
9780 }
9781 case 70: /* MotionBlur */
9782 {
9783 if (attribute_flag[0] != 0)
9784 {
9785 flags=ParseGeometry(argument_list[0].string_reference,
9786 &geometry_info);
9787 if ((flags & SigmaValue) == 0)
9788 geometry_info.sigma=1.0;
9789 if ((flags & XiValue) == 0)
9790 geometry_info.xi=1.0;
9791 }
9792 if (attribute_flag[1] != 0)
9793 geometry_info.rho=argument_list[1].real_reference;
9794 if (attribute_flag[2] != 0)
9795 geometry_info.sigma=argument_list[2].real_reference;
9796 if (attribute_flag[3] != 0)
9797 geometry_info.xi=argument_list[3].real_reference;
9798 if (attribute_flag[4] != 0)
9799 channel=(ChannelType) argument_list[4].integer_reference;
9800 channel_mask=SetImageChannelMask(image,channel);
9801 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9802 geometry_info.xi,exception);
9803 if (image != (Image *) NULL)
9804 (void) SetImageChannelMask(image,channel_mask);
9805 break;
9806 }
9807 case 71: /* OrderedDither */
9808 {
9809 if (attribute_flag[0] == 0)
9810 argument_list[0].string_reference="o8x8";
9811 if (attribute_flag[1] != 0)
9812 channel=(ChannelType) argument_list[1].integer_reference;
9813 channel_mask=SetImageChannelMask(image,channel);
Cristy6b93c072016-02-04 07:45:48 -05009814 (void) OrderedDitherImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009815 exception);
9816 (void) SetImageChannelMask(image,channel_mask);
9817 break;
9818 }
9819 case 72: /* Shave */
9820 {
9821 if (attribute_flag[0] != 0)
9822 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9823 &geometry,exception);
9824 if (attribute_flag[1] != 0)
9825 geometry.width=argument_list[1].integer_reference;
9826 if (attribute_flag[2] != 0)
9827 geometry.height=argument_list[2].integer_reference;
9828 image=ShaveImage(image,&geometry,exception);
9829 break;
9830 }
9831 case 73: /* Level */
9832 {
9833 double
9834 black_point,
9835 gamma,
9836 white_point;
9837
9838 black_point=0.0;
9839 white_point=(double) image->columns*image->rows;
9840 gamma=1.0;
9841 if (attribute_flag[0] != 0)
9842 {
9843 flags=ParseGeometry(argument_list[0].string_reference,
9844 &geometry_info);
9845 black_point=geometry_info.rho;
9846 if ((flags & SigmaValue) != 0)
9847 white_point=geometry_info.sigma;
9848 if ((flags & XiValue) != 0)
9849 gamma=geometry_info.xi;
9850 if ((flags & PercentValue) != 0)
9851 {
9852 black_point*=(double) (QuantumRange/100.0);
9853 white_point*=(double) (QuantumRange/100.0);
9854 }
9855 if ((flags & SigmaValue) == 0)
9856 white_point=(double) QuantumRange-black_point;
9857 }
9858 if (attribute_flag[1] != 0)
9859 black_point=argument_list[1].real_reference;
9860 if (attribute_flag[2] != 0)
9861 white_point=argument_list[2].real_reference;
9862 if (attribute_flag[3] != 0)
9863 gamma=argument_list[3].real_reference;
9864 if (attribute_flag[4] != 0)
9865 channel=(ChannelType) argument_list[4].integer_reference;
9866 if (attribute_flag[5] != 0)
9867 {
9868 argument_list[0].real_reference=argument_list[5].real_reference;
9869 attribute_flag[0]=attribute_flag[5];
9870 }
9871 channel_mask=SetImageChannelMask(image,channel);
9872 (void) LevelImage(image,black_point,white_point,gamma,exception);
9873 (void) SetImageChannelMask(image,channel_mask);
9874 break;
9875 }
9876 case 74: /* Clip */
9877 {
9878 if (attribute_flag[0] == 0)
9879 argument_list[0].string_reference="#1";
9880 if (attribute_flag[1] == 0)
9881 argument_list[1].integer_reference=MagickTrue;
9882 (void) ClipImagePath(image,argument_list[0].string_reference,
9883 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9884 exception);
9885 break;
9886 }
9887 case 75: /* AffineTransform */
9888 {
9889 DrawInfo
9890 *draw_info;
9891
9892 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9893 (DrawInfo *) NULL);
9894 if (attribute_flag[0] != 0)
9895 {
9896 AV
9897 *av;
9898
9899 av=(AV *) argument_list[0].array_reference;
9900 if ((av_len(av) != 3) && (av_len(av) != 5))
9901 {
9902 ThrowPerlException(exception,OptionError,
9903 "affine matrix must have 4 or 6 elements",PackageName);
9904 goto PerlException;
9905 }
9906 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9907 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9908 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9909 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9910 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9911 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9912 {
9913 ThrowPerlException(exception,OptionError,
9914 "affine matrix is singular",PackageName);
9915 goto PerlException;
9916 }
9917 if (av_len(av) == 5)
9918 {
9919 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9920 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9921 }
9922 }
9923 for (j=1; j < 6; j++)
9924 {
9925 if (attribute_flag[j] == 0)
9926 continue;
9927 value=argument_list[j].string_reference;
9928 angle=argument_list[j].real_reference;
9929 current=draw_info->affine;
9930 GetAffineMatrix(&affine);
9931 switch (j)
9932 {
9933 case 1:
9934 {
9935 /*
9936 Translate.
9937 */
9938 flags=ParseGeometry(value,&geometry_info);
9939 affine.tx=geometry_info.xi;
9940 affine.ty=geometry_info.psi;
9941 if ((flags & PsiValue) == 0)
9942 affine.ty=affine.tx;
9943 break;
9944 }
9945 case 2:
9946 {
9947 /*
9948 Scale.
9949 */
9950 flags=ParseGeometry(value,&geometry_info);
9951 affine.sx=geometry_info.rho;
9952 affine.sy=geometry_info.sigma;
9953 if ((flags & SigmaValue) == 0)
9954 affine.sy=affine.sx;
9955 break;
9956 }
9957 case 3:
9958 {
9959 /*
9960 Rotate.
9961 */
9962 if (angle == 0.0)
9963 break;
9964 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9965 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9966 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9967 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9968 break;
9969 }
9970 case 4:
9971 {
9972 /*
9973 SkewX.
9974 */
9975 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9976 break;
9977 }
9978 case 5:
9979 {
9980 /*
9981 SkewY.
9982 */
9983 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9984 break;
9985 }
9986 }
9987 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9988 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9989 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9990 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9991 draw_info->affine.tx=
9992 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9993 draw_info->affine.ty=
9994 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9995 }
9996 if (attribute_flag[6] != 0)
9997 image->interpolate=(PixelInterpolateMethod)
9998 argument_list[6].integer_reference;
9999 if (attribute_flag[7] != 0)
10000 QueryColorCompliance(argument_list[7].string_reference,
10001 AllCompliance,&image->background_color,exception);
10002 image=AffineTransformImage(image,&draw_info->affine,exception);
10003 draw_info=DestroyDrawInfo(draw_info);
10004 break;
10005 }
10006 case 76: /* Difference */
10007 {
10008 if (attribute_flag[0] == 0)
10009 {
10010 ThrowPerlException(exception,OptionError,
10011 "ReferenceImageRequired",PackageName);
10012 goto PerlException;
10013 }
10014 if (attribute_flag[1] != 0)
10015 image->fuzz=StringToDoubleInterval(
10016 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -050010017 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +000010018 exception);
10019 break;
10020 }
10021 case 77: /* AdaptiveThreshold */
10022 {
10023 if (attribute_flag[0] != 0)
10024 {
10025 flags=ParseGeometry(argument_list[0].string_reference,
10026 &geometry_info);
10027 if ((flags & PercentValue) != 0)
10028 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10029 }
10030 if (attribute_flag[1] != 0)
10031 geometry_info.rho=argument_list[1].integer_reference;
10032 if (attribute_flag[2] != 0)
10033 geometry_info.sigma=argument_list[2].integer_reference;
10034 if (attribute_flag[3] != 0)
10035 geometry_info.xi=argument_list[3].integer_reference;;
10036 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
10037 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
10038 break;
10039 }
10040 case 78: /* Resample */
10041 {
10042 size_t
10043 height,
10044 width;
10045
10046 if (attribute_flag[0] != 0)
10047 {
10048 flags=ParseGeometry(argument_list[0].string_reference,
10049 &geometry_info);
10050 if ((flags & SigmaValue) == 0)
10051 geometry_info.sigma=geometry_info.rho;
10052 }
10053 if (attribute_flag[1] != 0)
10054 geometry_info.rho=argument_list[1].real_reference;
10055 if (attribute_flag[2] != 0)
10056 geometry_info.sigma=argument_list[2].real_reference;
10057 if (attribute_flag[3] == 0)
10058 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10059 if (attribute_flag[4] == 0)
10060 SetImageArtifact(image,"filter:support",
10061 argument_list[4].string_reference);
10062 width=(size_t) (geometry_info.rho*image->columns/
10063 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10064 height=(size_t) (geometry_info.sigma*image->rows/
10065 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
Cristy8645e042016-02-03 16:35:29 -050010066 image=ResizeImage(image,width,height,(FilterType)
cristy4a3ce0a2013-08-03 20:06:59 +000010067 argument_list[3].integer_reference,exception);
10068 if (image != (Image *) NULL)
10069 {
10070 image->resolution.x=geometry_info.rho;
10071 image->resolution.y=geometry_info.sigma;
10072 }
10073 break;
10074 }
10075 case 79: /* Describe */
10076 {
10077 if (attribute_flag[0] == 0)
10078 argument_list[0].file_reference=(FILE *) NULL;
10079 if (attribute_flag[1] != 0)
10080 (void) SetImageArtifact(image,"identify:features",
10081 argument_list[1].string_reference);
10082 (void) IdentifyImage(image,argument_list[0].file_reference,
10083 MagickTrue,exception);
10084 break;
10085 }
10086 case 80: /* BlackThreshold */
10087 {
10088 if (attribute_flag[0] == 0)
10089 argument_list[0].string_reference="50%";
10090 if (attribute_flag[2] != 0)
10091 channel=(ChannelType) argument_list[2].integer_reference;
10092 channel_mask=SetImageChannelMask(image,channel);
10093 BlackThresholdImage(image,argument_list[0].string_reference,
10094 exception);
10095 (void) SetImageChannelMask(image,channel_mask);
10096 break;
10097 }
10098 case 81: /* WhiteThreshold */
10099 {
10100 if (attribute_flag[0] == 0)
10101 argument_list[0].string_reference="50%";
10102 if (attribute_flag[2] != 0)
10103 channel=(ChannelType) argument_list[2].integer_reference;
10104 channel_mask=SetImageChannelMask(image,channel);
10105 WhiteThresholdImage(image,argument_list[0].string_reference,
10106 exception);
10107 (void) SetImageChannelMask(image,channel_mask);
10108 break;
10109 }
cristy60c73c02014-03-25 12:09:58 +000010110 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010111 {
10112 if (attribute_flag[0] != 0)
10113 {
10114 flags=ParseGeometry(argument_list[0].string_reference,
10115 &geometry_info);
10116 }
10117 if (attribute_flag[1] != 0)
10118 geometry_info.rho=argument_list[1].real_reference;
10119 if (attribute_flag[2] != 0)
10120 channel=(ChannelType) argument_list[2].integer_reference;
10121 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010122 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010123 if (image != (Image *) NULL)
10124 (void) SetImageChannelMask(image,channel_mask);
10125 break;
10126 }
10127 case 83: /* Thumbnail */
10128 {
10129 if (attribute_flag[0] != 0)
10130 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10131 &geometry,exception);
10132 if (attribute_flag[1] != 0)
10133 geometry.width=argument_list[1].integer_reference;
10134 if (attribute_flag[2] != 0)
10135 geometry.height=argument_list[2].integer_reference;
10136 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10137 break;
10138 }
10139 case 84: /* Strip */
10140 {
10141 (void) StripImage(image,exception);
10142 break;
10143 }
10144 case 85: /* Tint */
10145 {
10146 PixelInfo
10147 tint;
10148
10149 GetPixelInfo(image,&tint);
10150 if (attribute_flag[0] != 0)
10151 (void) QueryColorCompliance(argument_list[0].string_reference,
10152 AllCompliance,&tint,exception);
10153 if (attribute_flag[1] == 0)
10154 argument_list[1].string_reference="100";
10155 image=TintImage(image,argument_list[1].string_reference,&tint,
10156 exception);
10157 break;
10158 }
10159 case 86: /* Channel */
10160 {
10161 if (attribute_flag[0] != 0)
10162 channel=(ChannelType) argument_list[0].integer_reference;
10163 image=SeparateImage(image,channel,exception);
10164 break;
10165 }
10166 case 87: /* Splice */
10167 {
cristy260bd762014-08-15 12:46:34 +000010168 if (attribute_flag[7] != 0)
10169 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010170 if (attribute_flag[0] != 0)
10171 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10172 &geometry,exception);
10173 if (attribute_flag[1] != 0)
10174 geometry.width=argument_list[1].integer_reference;
10175 if (attribute_flag[2] != 0)
10176 geometry.height=argument_list[2].integer_reference;
10177 if (attribute_flag[3] != 0)
10178 geometry.x=argument_list[3].integer_reference;
10179 if (attribute_flag[4] != 0)
10180 geometry.y=argument_list[4].integer_reference;
10181 if (attribute_flag[5] != 0)
10182 image->fuzz=StringToDoubleInterval(
10183 argument_list[5].string_reference,(double) QuantumRange+1.0);
10184 if (attribute_flag[6] != 0)
10185 (void) QueryColorCompliance(argument_list[6].string_reference,
10186 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010187 image=SpliceImage(image,&geometry,exception);
10188 break;
10189 }
10190 case 88: /* Posterize */
10191 {
10192 if (attribute_flag[0] == 0)
10193 argument_list[0].integer_reference=3;
10194 if (attribute_flag[1] == 0)
10195 argument_list[1].integer_reference=0;
10196 (void) PosterizeImage(image,argument_list[0].integer_reference,
10197 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10198 NoDitherMethod,exception);
10199 break;
10200 }
10201 case 89: /* Shadow */
10202 {
10203 if (attribute_flag[0] != 0)
10204 {
10205 flags=ParseGeometry(argument_list[0].string_reference,
10206 &geometry_info);
10207 if ((flags & SigmaValue) == 0)
10208 geometry_info.sigma=1.0;
10209 if ((flags & XiValue) == 0)
10210 geometry_info.xi=4.0;
10211 if ((flags & PsiValue) == 0)
10212 geometry_info.psi=4.0;
10213 }
10214 if (attribute_flag[1] != 0)
10215 geometry_info.rho=argument_list[1].real_reference;
10216 if (attribute_flag[2] != 0)
10217 geometry_info.sigma=argument_list[2].real_reference;
10218 if (attribute_flag[3] != 0)
10219 geometry_info.xi=argument_list[3].integer_reference;
10220 if (attribute_flag[4] != 0)
10221 geometry_info.psi=argument_list[4].integer_reference;
10222 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10223 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10224 ceil(geometry_info.psi-0.5),exception);
10225 break;
10226 }
10227 case 90: /* Identify */
10228 {
10229 if (attribute_flag[0] == 0)
10230 argument_list[0].file_reference=(FILE *) NULL;
10231 if (attribute_flag[1] != 0)
10232 (void) SetImageArtifact(image,"identify:features",
10233 argument_list[1].string_reference);
10234 if ((attribute_flag[2] != 0) &&
10235 (argument_list[2].integer_reference != 0))
10236 (void) SetImageArtifact(image,"identify:unique","true");
10237 (void) IdentifyImage(image,argument_list[0].file_reference,
10238 MagickTrue,exception);
10239 break;
10240 }
10241 case 91: /* SepiaTone */
10242 {
10243 if (attribute_flag[0] == 0)
10244 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10245 image=SepiaToneImage(image,argument_list[0].real_reference,
10246 exception);
10247 break;
10248 }
10249 case 92: /* SigmoidalContrast */
10250 {
10251 MagickBooleanType
10252 sharpen;
10253
10254 if (attribute_flag[0] != 0)
10255 {
10256 flags=ParseGeometry(argument_list[0].string_reference,
10257 &geometry_info);
10258 if ((flags & SigmaValue) == 0)
10259 geometry_info.sigma=QuantumRange/2.0;
10260 if ((flags & PercentValue) != 0)
10261 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10262 }
10263 if (attribute_flag[1] != 0)
10264 geometry_info.rho=argument_list[1].real_reference;
10265 if (attribute_flag[2] != 0)
10266 geometry_info.sigma=argument_list[2].real_reference;
10267 if (attribute_flag[3] != 0)
10268 channel=(ChannelType) argument_list[3].integer_reference;
10269 sharpen=MagickTrue;
10270 if (attribute_flag[4] != 0)
10271 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10272 MagickFalse;
10273 channel_mask=SetImageChannelMask(image,channel);
10274 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10275 geometry_info.sigma,exception);
10276 (void) SetImageChannelMask(image,channel_mask);
10277 break;
10278 }
10279 case 93: /* Extent */
10280 {
10281 if (attribute_flag[7] != 0)
10282 image->gravity=(GravityType) argument_list[7].integer_reference;
10283 if (attribute_flag[0] != 0)
10284 {
10285 int
10286 flags;
10287
10288 flags=ParseGravityGeometry(image,
10289 argument_list[0].string_reference,&geometry,exception);
10290 (void) flags;
10291 if (geometry.width == 0)
10292 geometry.width=image->columns;
10293 if (geometry.height == 0)
10294 geometry.height=image->rows;
10295 }
10296 if (attribute_flag[1] != 0)
10297 geometry.width=argument_list[1].integer_reference;
10298 if (attribute_flag[2] != 0)
10299 geometry.height=argument_list[2].integer_reference;
10300 if (attribute_flag[3] != 0)
10301 geometry.x=argument_list[3].integer_reference;
10302 if (attribute_flag[4] != 0)
10303 geometry.y=argument_list[4].integer_reference;
10304 if (attribute_flag[5] != 0)
10305 image->fuzz=StringToDoubleInterval(
10306 argument_list[5].string_reference,(double) QuantumRange+1.0);
10307 if (attribute_flag[6] != 0)
10308 (void) QueryColorCompliance(argument_list[6].string_reference,
10309 AllCompliance,&image->background_color,exception);
10310 image=ExtentImage(image,&geometry,exception);
10311 break;
10312 }
10313 case 94: /* Vignette */
10314 {
10315 if (attribute_flag[0] != 0)
10316 {
10317 flags=ParseGeometry(argument_list[0].string_reference,
10318 &geometry_info);
10319 if ((flags & SigmaValue) == 0)
10320 geometry_info.sigma=1.0;
10321 if ((flags & XiValue) == 0)
10322 geometry_info.xi=0.1*image->columns;
10323 if ((flags & PsiValue) == 0)
10324 geometry_info.psi=0.1*image->rows;
10325 }
10326 if (attribute_flag[1] != 0)
10327 geometry_info.rho=argument_list[1].real_reference;
10328 if (attribute_flag[2] != 0)
10329 geometry_info.sigma=argument_list[2].real_reference;
10330 if (attribute_flag[3] != 0)
10331 geometry_info.xi=argument_list[3].integer_reference;
10332 if (attribute_flag[4] != 0)
10333 geometry_info.psi=argument_list[4].integer_reference;
10334 if (attribute_flag[5] != 0)
10335 (void) QueryColorCompliance(argument_list[5].string_reference,
10336 AllCompliance,&image->background_color,exception);
10337 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10338 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10339 ceil(geometry_info.psi-0.5),exception);
10340 break;
10341 }
10342 case 95: /* ContrastStretch */
10343 {
10344 double
10345 black_point,
10346 white_point;
10347
10348 black_point=0.0;
10349 white_point=(double) image->columns*image->rows;
10350 if (attribute_flag[0] != 0)
10351 {
10352 flags=ParseGeometry(argument_list[0].string_reference,
10353 &geometry_info);
10354 black_point=geometry_info.rho;
10355 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10356 black_point;
10357 if ((flags & PercentValue) != 0)
10358 {
10359 black_point*=(double) image->columns*image->rows/100.0;
10360 white_point*=(double) image->columns*image->rows/100.0;
10361 }
10362 white_point=(double) image->columns*image->rows-
10363 white_point;
10364 }
10365 if (attribute_flag[1] != 0)
10366 black_point=argument_list[1].real_reference;
10367 if (attribute_flag[2] != 0)
10368 white_point=argument_list[2].real_reference;
10369 if (attribute_flag[4] != 0)
10370 channel=(ChannelType) argument_list[4].integer_reference;
10371 channel_mask=SetImageChannelMask(image,channel);
10372 (void) ContrastStretchImage(image,black_point,white_point,exception);
10373 (void) SetImageChannelMask(image,channel_mask);
10374 break;
10375 }
10376 case 96: /* Sans0 */
10377 {
10378 break;
10379 }
10380 case 97: /* Sans1 */
10381 {
10382 break;
10383 }
10384 case 98: /* AdaptiveSharpen */
10385 {
10386 if (attribute_flag[0] != 0)
10387 {
10388 flags=ParseGeometry(argument_list[0].string_reference,
10389 &geometry_info);
10390 if ((flags & SigmaValue) == 0)
10391 geometry_info.sigma=1.0;
10392 if ((flags & XiValue) == 0)
10393 geometry_info.xi=0.0;
10394 }
10395 if (attribute_flag[1] != 0)
10396 geometry_info.rho=argument_list[1].real_reference;
10397 if (attribute_flag[2] != 0)
10398 geometry_info.sigma=argument_list[2].real_reference;
10399 if (attribute_flag[3] != 0)
10400 geometry_info.xi=argument_list[3].real_reference;
10401 if (attribute_flag[4] != 0)
10402 channel=(ChannelType) argument_list[4].integer_reference;
10403 channel_mask=SetImageChannelMask(image,channel);
10404 image=AdaptiveSharpenImage(image,geometry_info.rho,
10405 geometry_info.sigma,exception);
10406 if (image != (Image *) NULL)
10407 (void) SetImageChannelMask(image,channel_mask);
10408 break;
10409 }
10410 case 99: /* Transpose */
10411 {
10412 image=TransposeImage(image,exception);
10413 break;
10414 }
10415 case 100: /* Tranverse */
10416 {
10417 image=TransverseImage(image,exception);
10418 break;
10419 }
10420 case 101: /* AutoOrient */
10421 {
10422 image=AutoOrientImage(image,image->orientation,exception);
10423 break;
10424 }
10425 case 102: /* AdaptiveBlur */
10426 {
10427 if (attribute_flag[0] != 0)
10428 {
10429 flags=ParseGeometry(argument_list[0].string_reference,
10430 &geometry_info);
10431 if ((flags & SigmaValue) == 0)
10432 geometry_info.sigma=1.0;
10433 if ((flags & XiValue) == 0)
10434 geometry_info.xi=0.0;
10435 }
10436 if (attribute_flag[1] != 0)
10437 geometry_info.rho=argument_list[1].real_reference;
10438 if (attribute_flag[2] != 0)
10439 geometry_info.sigma=argument_list[2].real_reference;
10440 if (attribute_flag[3] != 0)
10441 channel=(ChannelType) argument_list[3].integer_reference;
10442 channel_mask=SetImageChannelMask(image,channel);
10443 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10444 exception);
10445 if (image != (Image *) NULL)
10446 (void) SetImageChannelMask(image,channel_mask);
10447 break;
10448 }
10449 case 103: /* Sketch */
10450 {
10451 if (attribute_flag[0] != 0)
10452 {
10453 flags=ParseGeometry(argument_list[0].string_reference,
10454 &geometry_info);
10455 if ((flags & SigmaValue) == 0)
10456 geometry_info.sigma=1.0;
10457 if ((flags & XiValue) == 0)
10458 geometry_info.xi=1.0;
10459 }
10460 if (attribute_flag[1] != 0)
10461 geometry_info.rho=argument_list[1].real_reference;
10462 if (attribute_flag[2] != 0)
10463 geometry_info.sigma=argument_list[2].real_reference;
10464 if (attribute_flag[3] != 0)
10465 geometry_info.xi=argument_list[3].real_reference;
10466 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10467 geometry_info.xi,exception);
10468 break;
10469 }
10470 case 104: /* UniqueColors */
10471 {
10472 image=UniqueImageColors(image,exception);
10473 break;
10474 }
10475 case 105: /* AdaptiveResize */
10476 {
10477 if (attribute_flag[0] != 0)
10478 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10479 &geometry,exception);
10480 if (attribute_flag[1] != 0)
10481 geometry.width=argument_list[1].integer_reference;
10482 if (attribute_flag[2] != 0)
10483 geometry.height=argument_list[2].integer_reference;
10484 if (attribute_flag[3] != 0)
Cristy8645e042016-02-03 16:35:29 -050010485 image->filter=(FilterType) argument_list[4].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010486 if (attribute_flag[4] != 0)
10487 SetImageArtifact(image,"filter:support",
10488 argument_list[4].string_reference);
10489 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10490 exception);
10491 break;
10492 }
10493 case 106: /* ClipMask */
10494 {
10495 Image
10496 *mask_image;
10497
10498 if (attribute_flag[0] == 0)
10499 {
10500 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10501 PackageName);
10502 goto PerlException;
10503 }
10504 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10505 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010506 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010507 mask_image=DestroyImage(mask_image);
10508 break;
10509 }
10510 case 107: /* LinearStretch */
10511 {
10512 double
10513 black_point,
10514 white_point;
10515
10516 black_point=0.0;
10517 white_point=(double) image->columns*image->rows;
10518 if (attribute_flag[0] != 0)
10519 {
10520 flags=ParseGeometry(argument_list[0].string_reference,
10521 &geometry_info);
10522 if ((flags & SigmaValue) != 0)
10523 white_point=geometry_info.sigma;
10524 if ((flags & PercentValue) != 0)
10525 {
10526 black_point*=(double) image->columns*image->rows/100.0;
10527 white_point*=(double) image->columns*image->rows/100.0;
10528 }
10529 if ((flags & SigmaValue) == 0)
10530 white_point=(double) image->columns*image->rows-black_point;
10531 }
10532 if (attribute_flag[1] != 0)
10533 black_point=argument_list[1].real_reference;
10534 if (attribute_flag[2] != 0)
10535 white_point=argument_list[2].real_reference;
10536 (void) LinearStretchImage(image,black_point,white_point,exception);
10537 break;
10538 }
10539 case 108: /* ColorMatrix */
10540 {
10541 AV
10542 *av;
10543
10544 double
10545 *color_matrix;
10546
10547 KernelInfo
10548 *kernel_info;
10549
10550 size_t
10551 order;
10552
10553 if (attribute_flag[0] == 0)
10554 break;
10555 av=(AV *) argument_list[0].array_reference;
10556 order=(size_t) sqrt(av_len(av)+1);
10557 color_matrix=(double *) AcquireQuantumMemory(order,order*
10558 sizeof(*color_matrix));
10559 if (color_matrix == (double *) NULL)
10560 {
10561 ThrowPerlException(exception,ResourceLimitFatalError,
10562 "MemoryAllocationFailed",PackageName);
10563 goto PerlException;
10564 }
10565 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10566 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10567 for ( ; j < (ssize_t) (order*order); j++)
10568 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010569 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010570 if (kernel_info == (KernelInfo *) NULL)
10571 break;
10572 kernel_info->width=order;
10573 kernel_info->height=order;
10574 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10575 order*sizeof(*kernel_info->values));
10576 if (kernel_info->values != (MagickRealType *) NULL)
10577 {
10578 for (i=0; i < (ssize_t) (order*order); i++)
10579 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10580 image=ColorMatrixImage(image,kernel_info,exception);
10581 }
10582 kernel_info=DestroyKernelInfo(kernel_info);
10583 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10584 break;
10585 }
10586 case 109: /* Mask */
10587 {
10588 Image
10589 *mask_image;
10590
10591 if (attribute_flag[0] == 0)
10592 {
10593 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10594 PackageName);
10595 goto PerlException;
10596 }
10597 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10598 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010599 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010600 mask_image=DestroyImage(mask_image);
10601 break;
10602 }
10603 case 110: /* Polaroid */
10604 {
10605 char
10606 *caption;
10607
10608 DrawInfo
10609 *draw_info;
10610
10611 double
10612 angle;
10613
10614 PixelInterpolateMethod
10615 method;
10616
10617 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10618 (DrawInfo *) NULL);
10619 caption=(char *) NULL;
10620 if (attribute_flag[0] != 0)
10621 caption=InterpretImageProperties(info ? info->image_info :
10622 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10623 exception);
10624 angle=0.0;
10625 if (attribute_flag[1] != 0)
10626 angle=argument_list[1].real_reference;
10627 if (attribute_flag[2] != 0)
10628 (void) CloneString(&draw_info->font,
10629 argument_list[2].string_reference);
10630 if (attribute_flag[3] != 0)
10631 (void) QueryColorCompliance(argument_list[3].string_reference,
10632 AllCompliance,&draw_info->stroke,exception);
10633 if (attribute_flag[4] != 0)
10634 (void) QueryColorCompliance(argument_list[4].string_reference,
10635 AllCompliance,&draw_info->fill,exception);
10636 if (attribute_flag[5] != 0)
10637 draw_info->stroke_width=argument_list[5].real_reference;
10638 if (attribute_flag[6] != 0)
10639 draw_info->pointsize=argument_list[6].real_reference;
10640 if (attribute_flag[7] != 0)
10641 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10642 if (attribute_flag[8] != 0)
10643 (void) QueryColorCompliance(argument_list[8].string_reference,
10644 AllCompliance,&image->background_color,exception);
10645 method=UndefinedInterpolatePixel;
10646 if (attribute_flag[9] != 0)
10647 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10648 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10649 draw_info=DestroyDrawInfo(draw_info);
10650 if (caption != (char *) NULL)
10651 caption=DestroyString(caption);
10652 break;
10653 }
10654 case 111: /* FloodfillPaint */
10655 {
10656 DrawInfo
10657 *draw_info;
10658
10659 MagickBooleanType
10660 invert;
10661
10662 PixelInfo
10663 target;
10664
10665 draw_info=CloneDrawInfo(info ? info->image_info :
10666 (ImageInfo *) NULL,(DrawInfo *) NULL);
10667 if (attribute_flag[0] != 0)
10668 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10669 &geometry,exception);
10670 if (attribute_flag[1] != 0)
10671 geometry.x=argument_list[1].integer_reference;
10672 if (attribute_flag[2] != 0)
10673 geometry.y=argument_list[2].integer_reference;
10674 if (attribute_flag[3] != 0)
10675 (void) QueryColorCompliance(argument_list[3].string_reference,
10676 AllCompliance,&draw_info->fill,exception);
10677 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10678 geometry.x,geometry.y,&target,exception);
10679 if (attribute_flag[4] != 0)
10680 QueryColorCompliance(argument_list[4].string_reference,
10681 AllCompliance,&target,exception);
10682 if (attribute_flag[5] != 0)
10683 image->fuzz=StringToDoubleInterval(
10684 argument_list[5].string_reference,(double) QuantumRange+1.0);
10685 if (attribute_flag[6] != 0)
10686 channel=(ChannelType) argument_list[6].integer_reference;
10687 invert=MagickFalse;
10688 if (attribute_flag[7] != 0)
10689 invert=(MagickBooleanType) argument_list[7].integer_reference;
10690 channel_mask=SetImageChannelMask(image,channel);
10691 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10692 geometry.y,invert,exception);
10693 (void) SetImageChannelMask(image,channel_mask);
10694 draw_info=DestroyDrawInfo(draw_info);
10695 break;
10696 }
10697 case 112: /* Distort */
10698 {
10699 AV
10700 *av;
10701
10702 double
10703 *coordinates;
10704
Cristy8645e042016-02-03 16:35:29 -050010705 DistortMethod
cristy4a3ce0a2013-08-03 20:06:59 +000010706 method;
10707
10708 size_t
10709 number_coordinates;
10710
10711 VirtualPixelMethod
10712 virtual_pixel;
10713
10714 if (attribute_flag[0] == 0)
10715 break;
10716 method=UndefinedDistortion;
10717 if (attribute_flag[1] != 0)
Cristy8645e042016-02-03 16:35:29 -050010718 method=(DistortMethod) argument_list[1].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010719 av=(AV *) argument_list[0].array_reference;
10720 number_coordinates=(size_t) av_len(av)+1;
10721 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10722 sizeof(*coordinates));
10723 if (coordinates == (double *) NULL)
10724 {
10725 ThrowPerlException(exception,ResourceLimitFatalError,
10726 "MemoryAllocationFailed",PackageName);
10727 goto PerlException;
10728 }
10729 for (j=0; j < (ssize_t) number_coordinates; j++)
10730 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10731 virtual_pixel=UndefinedVirtualPixelMethod;
10732 if (attribute_flag[2] != 0)
10733 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10734 argument_list[2].integer_reference,exception);
10735 image=DistortImage(image,method,number_coordinates,coordinates,
10736 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10737 exception);
10738 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10739 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10740 exception);
10741 coordinates=(double *) RelinquishMagickMemory(coordinates);
10742 break;
10743 }
10744 case 113: /* Clut */
10745 {
10746 PixelInterpolateMethod
10747 method;
10748
10749 if (attribute_flag[0] == 0)
10750 {
10751 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10752 PackageName);
10753 goto PerlException;
10754 }
10755 method=UndefinedInterpolatePixel;
10756 if (attribute_flag[1] != 0)
10757 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10758 if (attribute_flag[2] != 0)
10759 channel=(ChannelType) argument_list[2].integer_reference;
10760 channel_mask=SetImageChannelMask(image,channel);
10761 (void) ClutImage(image,argument_list[0].image_reference,method,
10762 exception);
10763 (void) SetImageChannelMask(image,channel_mask);
10764 break;
10765 }
10766 case 114: /* LiquidRescale */
10767 {
10768 if (attribute_flag[0] != 0)
10769 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10770 &geometry,exception);
10771 if (attribute_flag[1] != 0)
10772 geometry.width=argument_list[1].integer_reference;
10773 if (attribute_flag[2] != 0)
10774 geometry.height=argument_list[2].integer_reference;
10775 if (attribute_flag[3] == 0)
10776 argument_list[3].real_reference=1.0;
10777 if (attribute_flag[4] == 0)
10778 argument_list[4].real_reference=0.0;
10779 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10780 argument_list[3].real_reference,argument_list[4].real_reference,
10781 exception);
10782 break;
10783 }
10784 case 115: /* EncipherImage */
10785 {
10786 (void) EncipherImage(image,argument_list[0].string_reference,
10787 exception);
10788 break;
10789 }
10790 case 116: /* DecipherImage */
10791 {
10792 (void) DecipherImage(image,argument_list[0].string_reference,
10793 exception);
10794 break;
10795 }
10796 case 117: /* Deskew */
10797 {
10798 geometry_info.rho=QuantumRange/2.0;
10799 if (attribute_flag[0] != 0)
10800 flags=ParseGeometry(argument_list[0].string_reference,
10801 &geometry_info);
10802 if (attribute_flag[1] != 0)
10803 geometry_info.rho=StringToDoubleInterval(
10804 argument_list[1].string_reference,(double) QuantumRange+1.0);
10805 image=DeskewImage(image,geometry_info.rho,exception);
10806 break;
10807 }
10808 case 118: /* Remap */
10809 {
10810 QuantizeInfo
10811 *quantize_info;
10812
10813 if (attribute_flag[0] == 0)
10814 {
10815 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10816 PackageName);
10817 goto PerlException;
10818 }
10819 quantize_info=AcquireQuantizeInfo(info->image_info);
10820 if (attribute_flag[1] != 0)
10821 quantize_info->dither_method=(DitherMethod)
10822 argument_list[1].integer_reference;
10823 (void) RemapImages(quantize_info,image,
10824 argument_list[0].image_reference,exception);
10825 quantize_info=DestroyQuantizeInfo(quantize_info);
10826 break;
10827 }
10828 case 119: /* SparseColor */
10829 {
10830 AV
10831 *av;
10832
10833 double
10834 *coordinates;
10835
10836 SparseColorMethod
10837 method;
10838
10839 size_t
10840 number_coordinates;
10841
10842 VirtualPixelMethod
10843 virtual_pixel;
10844
10845 if (attribute_flag[0] == 0)
10846 break;
10847 method=UndefinedColorInterpolate;
10848 if (attribute_flag[1] != 0)
10849 method=(SparseColorMethod) argument_list[1].integer_reference;
10850 av=(AV *) argument_list[0].array_reference;
10851 number_coordinates=(size_t) av_len(av)+1;
10852 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10853 sizeof(*coordinates));
10854 if (coordinates == (double *) NULL)
10855 {
10856 ThrowPerlException(exception,ResourceLimitFatalError,
10857 "MemoryAllocationFailed",PackageName);
10858 goto PerlException;
10859 }
10860 for (j=0; j < (ssize_t) number_coordinates; j++)
10861 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10862 virtual_pixel=UndefinedVirtualPixelMethod;
10863 if (attribute_flag[2] != 0)
10864 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10865 argument_list[2].integer_reference,exception);
10866 if (attribute_flag[3] != 0)
10867 channel=(ChannelType) argument_list[3].integer_reference;
10868 channel_mask=SetImageChannelMask(image,channel);
10869 image=SparseColorImage(image,method,number_coordinates,coordinates,
10870 exception);
10871 if (image != (Image *) NULL)
10872 (void) SetImageChannelMask(image,channel_mask);
10873 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10874 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10875 exception);
10876 coordinates=(double *) RelinquishMagickMemory(coordinates);
10877 break;
10878 }
10879 case 120: /* Function */
10880 {
10881 AV
10882 *av;
10883
10884 double
10885 *parameters;
10886
10887 MagickFunction
10888 function;
10889
10890 size_t
10891 number_parameters;
10892
10893 VirtualPixelMethod
10894 virtual_pixel;
10895
10896 if (attribute_flag[0] == 0)
10897 break;
10898 function=UndefinedFunction;
10899 if (attribute_flag[1] != 0)
10900 function=(MagickFunction) argument_list[1].integer_reference;
10901 av=(AV *) argument_list[0].array_reference;
10902 number_parameters=(size_t) av_len(av)+1;
10903 parameters=(double *) AcquireQuantumMemory(number_parameters,
10904 sizeof(*parameters));
10905 if (parameters == (double *) NULL)
10906 {
10907 ThrowPerlException(exception,ResourceLimitFatalError,
10908 "MemoryAllocationFailed",PackageName);
10909 goto PerlException;
10910 }
10911 for (j=0; j < (ssize_t) number_parameters; j++)
10912 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10913 virtual_pixel=UndefinedVirtualPixelMethod;
10914 if (attribute_flag[2] != 0)
10915 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10916 argument_list[2].integer_reference,exception);
10917 (void) FunctionImage(image,function,number_parameters,parameters,
10918 exception);
10919 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10920 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10921 exception);
10922 parameters=(double *) RelinquishMagickMemory(parameters);
10923 break;
10924 }
10925 case 121: /* SelectiveBlur */
10926 {
10927 if (attribute_flag[0] != 0)
10928 {
10929 flags=ParseGeometry(argument_list[0].string_reference,
10930 &geometry_info);
10931 if ((flags & SigmaValue) == 0)
10932 geometry_info.sigma=1.0;
10933 if ((flags & PercentValue) != 0)
10934 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10935 }
10936 if (attribute_flag[1] != 0)
10937 geometry_info.rho=argument_list[1].real_reference;
10938 if (attribute_flag[2] != 0)
10939 geometry_info.sigma=argument_list[2].real_reference;
10940 if (attribute_flag[3] != 0)
10941 geometry_info.xi=argument_list[3].integer_reference;;
10942 if (attribute_flag[5] != 0)
10943 channel=(ChannelType) argument_list[5].integer_reference;
10944 channel_mask=SetImageChannelMask(image,channel);
10945 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10946 geometry_info.xi,exception);
10947 if (image != (Image *) NULL)
10948 (void) SetImageChannelMask(image,channel_mask);
10949 break;
10950 }
10951 case 122: /* HaldClut */
10952 {
10953 if (attribute_flag[0] == 0)
10954 {
10955 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10956 PackageName);
10957 goto PerlException;
10958 }
10959 if (attribute_flag[1] != 0)
10960 channel=(ChannelType) argument_list[1].integer_reference;
10961 channel_mask=SetImageChannelMask(image,channel);
10962 (void) HaldClutImage(image,argument_list[0].image_reference,
10963 exception);
10964 (void) SetImageChannelMask(image,channel_mask);
10965 break;
10966 }
10967 case 123: /* BlueShift */
10968 {
10969 if (attribute_flag[0] != 0)
10970 (void) ParseGeometry(argument_list[0].string_reference,
10971 &geometry_info);
10972 image=BlueShiftImage(image,geometry_info.rho,exception);
10973 break;
10974 }
10975 case 124: /* ForwardFourierTransformImage */
10976 {
10977 image=ForwardFourierTransformImage(image,
10978 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10979 exception);
10980 break;
10981 }
10982 case 125: /* InverseFourierTransformImage */
10983 {
10984 image=InverseFourierTransformImage(image,image->next,
10985 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10986 exception);
10987 break;
10988 }
10989 case 126: /* ColorDecisionList */
10990 {
10991 if (attribute_flag[0] == 0)
10992 argument_list[0].string_reference=(char *) NULL;
10993 (void) ColorDecisionListImage(image,
10994 argument_list[0].string_reference,exception);
10995 break;
10996 }
10997 case 127: /* AutoGamma */
10998 {
10999 if (attribute_flag[0] != 0)
11000 channel=(ChannelType) argument_list[0].integer_reference;
11001 channel_mask=SetImageChannelMask(image,channel);
11002 (void) AutoGammaImage(image,exception);
11003 (void) SetImageChannelMask(image,channel_mask);
11004 break;
11005 }
11006 case 128: /* AutoLevel */
11007 {
11008 if (attribute_flag[0] != 0)
11009 channel=(ChannelType) argument_list[0].integer_reference;
11010 channel_mask=SetImageChannelMask(image,channel);
11011 (void) AutoLevelImage(image,exception);
11012 (void) SetImageChannelMask(image,channel_mask);
11013 break;
11014 }
11015 case 129: /* LevelColors */
11016 {
11017 PixelInfo
11018 black_point,
11019 white_point;
11020
11021 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
11022 exception);
11023 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
11024 exception);
11025 if (attribute_flag[1] != 0)
11026 (void) QueryColorCompliance(
11027 argument_list[1].string_reference,AllCompliance,&black_point,
11028 exception);
11029 if (attribute_flag[2] != 0)
11030 (void) QueryColorCompliance(
11031 argument_list[2].string_reference,AllCompliance,&white_point,
11032 exception);
11033 if (attribute_flag[3] != 0)
11034 channel=(ChannelType) argument_list[3].integer_reference;
11035 channel_mask=SetImageChannelMask(image,channel);
11036 (void) LevelImageColors(image,&black_point,&white_point,
11037 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11038 exception);
11039 (void) SetImageChannelMask(image,channel_mask);
11040 break;
11041 }
11042 case 130: /* Clamp */
11043 {
11044 if (attribute_flag[0] != 0)
11045 channel=(ChannelType) argument_list[0].integer_reference;
11046 channel_mask=SetImageChannelMask(image,channel);
11047 (void) ClampImage(image,exception);
11048 (void) SetImageChannelMask(image,channel_mask);
11049 break;
11050 }
11051 case 131: /* BrightnessContrast */
11052 {
11053 double
11054 brightness,
11055 contrast;
11056
11057 brightness=0.0;
11058 contrast=0.0;
11059 if (attribute_flag[0] != 0)
11060 {
11061 flags=ParseGeometry(argument_list[0].string_reference,
11062 &geometry_info);
11063 brightness=geometry_info.rho;
11064 if ((flags & SigmaValue) == 0)
11065 contrast=geometry_info.sigma;
11066 }
11067 if (attribute_flag[1] != 0)
11068 brightness=argument_list[1].real_reference;
11069 if (attribute_flag[2] != 0)
11070 contrast=argument_list[2].real_reference;
11071 if (attribute_flag[4] != 0)
11072 channel=(ChannelType) argument_list[4].integer_reference;
11073 channel_mask=SetImageChannelMask(image,channel);
11074 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11075 (void) SetImageChannelMask(image,channel_mask);
11076 break;
11077 }
11078 case 132: /* Morphology */
11079 {
11080 KernelInfo
11081 *kernel;
11082
11083 MorphologyMethod
11084 method;
11085
11086 ssize_t
11087 iterations;
11088
11089 if (attribute_flag[0] == 0)
11090 break;
cristy2c57b742014-10-31 00:40:34 +000011091 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011092 if (kernel == (KernelInfo *) NULL)
11093 break;
11094 if (attribute_flag[1] != 0)
11095 channel=(ChannelType) argument_list[1].integer_reference;
11096 method=UndefinedMorphology;
11097 if (attribute_flag[2] != 0)
11098 method=argument_list[2].integer_reference;
11099 iterations=1;
11100 if (attribute_flag[3] != 0)
11101 iterations=argument_list[3].integer_reference;
11102 channel_mask=SetImageChannelMask(image,channel);
11103 image=MorphologyImage(image,method,iterations,kernel,exception);
11104 if (image != (Image *) NULL)
11105 (void) SetImageChannelMask(image,channel_mask);
11106 kernel=DestroyKernelInfo(kernel);
11107 break;
11108 }
11109 case 133: /* Mode */
11110 {
11111 if (attribute_flag[0] != 0)
11112 {
11113 flags=ParseGeometry(argument_list[0].string_reference,
11114 &geometry_info);
11115 if ((flags & SigmaValue) == 0)
11116 geometry_info.sigma=1.0;
11117 }
11118 if (attribute_flag[1] != 0)
11119 geometry_info.rho=argument_list[1].real_reference;
11120 if (attribute_flag[2] != 0)
11121 geometry_info.sigma=argument_list[2].real_reference;
11122 if (attribute_flag[3] != 0)
11123 channel=(ChannelType) argument_list[3].integer_reference;
11124 channel_mask=SetImageChannelMask(image,channel);
11125 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11126 (size_t) geometry_info.sigma,exception);
11127 if (image != (Image *) NULL)
11128 (void) SetImageChannelMask(image,channel_mask);
11129 break;
11130 }
11131 case 134: /* Statistic */
11132 {
11133 StatisticType
11134 statistic;
11135
11136 statistic=UndefinedStatistic;
11137 if (attribute_flag[0] != 0)
11138 {
11139 flags=ParseGeometry(argument_list[0].string_reference,
11140 &geometry_info);
11141 if ((flags & SigmaValue) == 0)
11142 geometry_info.sigma=1.0;
11143 }
11144 if (attribute_flag[1] != 0)
11145 geometry_info.rho=argument_list[1].real_reference;
11146 if (attribute_flag[2] != 0)
11147 geometry_info.sigma=argument_list[2].real_reference;
11148 if (attribute_flag[3] != 0)
11149 channel=(ChannelType) argument_list[3].integer_reference;
11150 if (attribute_flag[4] != 0)
11151 statistic=(StatisticType) argument_list[4].integer_reference;
11152 channel_mask=SetImageChannelMask(image,channel);
11153 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11154 (size_t) geometry_info.sigma,exception);
11155 if (image != (Image *) NULL)
11156 (void) SetImageChannelMask(image,channel_mask);
11157 break;
11158 }
11159 case 135: /* Perceptible */
11160 {
11161 double
11162 epsilon;
11163
11164 epsilon=MagickEpsilon;
11165 if (attribute_flag[0] != 0)
11166 epsilon=argument_list[0].real_reference;
11167 if (attribute_flag[1] != 0)
11168 channel=(ChannelType) argument_list[1].integer_reference;
11169 channel_mask=SetImageChannelMask(image,channel);
11170 (void) PerceptibleImage(image,epsilon,exception);
11171 (void) SetImageChannelMask(image,channel_mask);
11172 break;
11173 }
11174 case 136: /* Poly */
11175 {
11176 AV
11177 *av;
11178
11179 double
11180 *terms;
11181
11182 size_t
11183 number_terms;
11184
11185 if (attribute_flag[0] == 0)
11186 break;
11187 if (attribute_flag[1] != 0)
11188 channel=(ChannelType) argument_list[1].integer_reference;
11189 av=(AV *) argument_list[0].array_reference;
11190 number_terms=(size_t) av_len(av);
11191 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11192 if (terms == (double *) NULL)
11193 {
11194 ThrowPerlException(exception,ResourceLimitFatalError,
11195 "MemoryAllocationFailed",PackageName);
11196 goto PerlException;
11197 }
11198 for (j=0; j < av_len(av); j++)
11199 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11200 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11201 terms=(double *) RelinquishMagickMemory(terms);
11202 break;
11203 }
11204 case 137: /* Grayscale */
11205 {
11206 PixelIntensityMethod
11207 method;
11208
11209 method=UndefinedPixelIntensityMethod;
11210 if (attribute_flag[0] != 0)
11211 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11212 (void) GrayscaleImage(image,method,exception);
11213 break;
11214 }
cristy4ceadb82014-03-29 15:30:43 +000011215 case 138: /* Canny */
11216 {
11217 if (attribute_flag[0] != 0)
11218 {
11219 flags=ParseGeometry(argument_list[0].string_reference,
11220 &geometry_info);
11221 if ((flags & SigmaValue) == 0)
11222 geometry_info.sigma=1.0;
11223 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011224 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011225 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011226 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011227 if ((flags & PercentValue) != 0)
11228 {
11229 geometry_info.xi/=100.0;
11230 geometry_info.psi/=100.0;
11231 }
cristy4ceadb82014-03-29 15:30:43 +000011232 }
11233 if (attribute_flag[1] != 0)
11234 geometry_info.rho=argument_list[1].real_reference;
11235 if (attribute_flag[2] != 0)
11236 geometry_info.sigma=argument_list[2].real_reference;
11237 if (attribute_flag[3] != 0)
11238 geometry_info.xi=argument_list[3].real_reference;
11239 if (attribute_flag[4] != 0)
11240 geometry_info.psi=argument_list[4].real_reference;
11241 if (attribute_flag[5] != 0)
11242 channel=(ChannelType) argument_list[5].integer_reference;
11243 channel_mask=SetImageChannelMask(image,channel);
11244 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11245 geometry_info.xi,geometry_info.psi,exception);
11246 if (image != (Image *) NULL)
11247 (void) SetImageChannelMask(image,channel_mask);
11248 break;
11249 }
cristy2fc10e52014-04-26 14:13:53 +000011250 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011251 {
11252 if (attribute_flag[0] != 0)
11253 {
11254 flags=ParseGeometry(argument_list[0].string_reference,
11255 &geometry_info);
11256 if ((flags & SigmaValue) == 0)
11257 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011258 if ((flags & XiValue) == 0)
11259 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011260 }
11261 if (attribute_flag[1] != 0)
11262 geometry_info.rho=(double) argument_list[1].integer_reference;
11263 if (attribute_flag[2] != 0)
11264 geometry_info.sigma=(double) argument_list[2].integer_reference;
11265 if (attribute_flag[3] != 0)
11266 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011267 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11268 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11269 break;
11270 }
11271 case 140: /* MeanShift */
11272 {
11273 if (attribute_flag[0] != 0)
11274 {
11275 flags=ParseGeometry(argument_list[0].string_reference,
11276 &geometry_info);
11277 if ((flags & SigmaValue) == 0)
11278 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011279 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011280 geometry_info.xi=0.10*QuantumRange;
11281 if ((flags & PercentValue) != 0)
11282 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011283 }
11284 if (attribute_flag[1] != 0)
11285 geometry_info.rho=(double) argument_list[1].integer_reference;
11286 if (attribute_flag[2] != 0)
11287 geometry_info.sigma=(double) argument_list[2].integer_reference;
11288 if (attribute_flag[3] != 0)
11289 geometry_info.xi=(double) argument_list[3].integer_reference;
11290 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011291 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011292 break;
11293 }
cristy3b207f82014-09-27 14:21:20 +000011294 case 141: /* Kuwahara */
11295 {
11296 if (attribute_flag[0] != 0)
11297 {
11298 flags=ParseGeometry(argument_list[0].string_reference,
11299 &geometry_info);
11300 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011301 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011302 }
11303 if (attribute_flag[1] != 0)
11304 geometry_info.rho=argument_list[1].real_reference;
11305 if (attribute_flag[2] != 0)
11306 geometry_info.sigma=argument_list[2].real_reference;
11307 if (attribute_flag[3] != 0)
11308 channel=(ChannelType) argument_list[3].integer_reference;
11309 channel_mask=SetImageChannelMask(image,channel);
11310 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11311 exception);
11312 if (image != (Image *) NULL)
11313 (void) SetImageChannelMask(image,channel_mask);
11314 break;
11315 }
Cristy0f5df812017-07-04 18:30:05 -040011316 case 142: /* ConnectedComponents */
cristy6e0b3bc2014-10-19 17:51:42 +000011317 {
11318 size_t
11319 connectivity;
11320
11321 connectivity=4;
11322 if (attribute_flag[0] != 0)
11323 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011324 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011325 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011326 break;
11327 }
cristy0b94b392015-06-22 18:56:37 +000011328 case 143: /* Copy */
11329 {
11330 Image
11331 *source_image;
11332
11333 OffsetInfo
11334 offset;
11335
cristy2ffdb092015-06-25 14:31:20 +000011336 RectangleInfo
11337 offset_geometry;
11338
cristyf3a724a2015-06-25 13:02:53 +000011339 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011340 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011341 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011342 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011343 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011344 flags=ParseGravityGeometry(source_image,
11345 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011346 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011347 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011348 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011349 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011350 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011351 geometry.x=argument_list[4].integer_reference;
11352 if (attribute_flag[5] != 0)
11353 geometry.y=argument_list[5].integer_reference;
11354 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011355 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011356 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011357 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011358 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11359 &offset_geometry,exception);
11360 offset.x=offset_geometry.x;
11361 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011362 if (attribute_flag[8] != 0)
11363 offset.x=argument_list[8].integer_reference;
11364 if (attribute_flag[9] != 0)
11365 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011366 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11367 exception);
cristy0b94b392015-06-22 18:56:37 +000011368 break;
11369 }
Cristy5488c982016-02-13 14:07:50 -050011370 case 144: /* Color */
11371 {
11372 PixelInfo
11373 color;
11374
Cristyf20e3562016-02-14 09:08:15 -050011375 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011376 if (attribute_flag[0] != 0)
Cristyf20e3562016-02-14 09:08:15 -050011377 (void) QueryColorCompliance(argument_list[0].string_reference,
11378 AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011379 (void) SetImageColor(image,&color,exception);
11380 break;
11381 }
Cristy2d830ed2016-02-21 10:54:16 -050011382 case 145: /* WaveletDenoise */
11383 {
Cristyc1759412016-02-27 12:17:58 -050011384 if (attribute_flag[0] != 0)
Cristyee21f7f2016-02-27 15:56:49 -050011385 {
11386 flags=ParseGeometry(argument_list[0].string_reference,
11387 &geometry_info);
11388 if ((flags & PercentValue) != 0)
Cristy23446632016-02-29 09:36:34 -050011389 {
11390 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11391 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
11392 }
Cristyee21f7f2016-02-27 15:56:49 -050011393 if ((flags & SigmaValue) == 0)
11394 geometry_info.sigma=0.0;
11395 }
Cristyc1759412016-02-27 12:17:58 -050011396 if (attribute_flag[1] != 0)
11397 geometry_info.rho=argument_list[1].real_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011398 if (attribute_flag[2] != 0)
Cristyc1759412016-02-27 12:17:58 -050011399 geometry_info.sigma=argument_list[2].real_reference;
11400 if (attribute_flag[3] != 0)
11401 channel=(ChannelType) argument_list[3].integer_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011402 channel_mask=SetImageChannelMask(image,channel);
Cristyc1759412016-02-27 12:17:58 -050011403 image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11404 exception);
Cristy2d830ed2016-02-21 10:54:16 -050011405 if (image != (Image *) NULL)
11406 (void) SetImageChannelMask(image,channel_mask);
11407 break;
11408 }
Cristy99a57162016-12-05 11:47:57 -050011409 case 146: /* Colorspace */
11410 {
11411 ColorspaceType
11412 colorspace;
11413
11414 colorspace=sRGBColorspace;
11415 if (attribute_flag[0] != 0)
11416 colorspace=(ColorspaceType) argument_list[0].integer_reference;
11417 (void) TransformImageColorspace(image,colorspace,exception);
11418 break;
11419 }
Cristy53353872017-07-02 12:24:24 -040011420 case 147: /* AutoThreshold */
11421 {
11422 AutoThresholdMethod
11423 method;
11424
11425 method=UndefinedThresholdMethod;
11426 if (attribute_flag[0] != 0)
Cristyb63e7752017-07-02 13:22:01 -040011427 method=(AutoThresholdMethod) argument_list[0].integer_reference;
Cristy53353872017-07-02 12:24:24 -040011428 (void) AutoThresholdImage(image,method,exception);
11429 break;
11430 }
cristy4a3ce0a2013-08-03 20:06:59 +000011431 }
11432 if (next != (Image *) NULL)
11433 (void) CatchImageException(next);
11434 if (region_image != (Image *) NULL)
11435 {
11436 /*
11437 Composite region.
cristy83a28a02013-08-03 20:25:48 +000011438 */
cristy4a3ce0a2013-08-03 20:06:59 +000011439 status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11440 region_info.x,region_info.y,exception);
11441 (void) status;
11442 (void) CatchImageException(region_image);
11443 image=DestroyImage(image);
11444 image=region_image;
11445 }
11446 if (image != (Image *) NULL)
11447 {
11448 number_images++;
11449 if (next && (next != image))
11450 {
11451 image->next=next->next;
11452 if (image->next != (Image *) NULL)
11453 image->next->previous=image;
11454 DeleteImageFromRegistry(*pv,next);
11455 }
11456 sv_setiv(*pv,PTR2IV(image));
11457 next=image;
11458 }
11459 if (*pv)
11460 pv++;
11461 }
11462
11463 PerlException:
11464 if (reference_vector)
11465 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11466 InheritPerlException(exception,perl_exception);
11467 exception=DestroyExceptionInfo(exception);
11468 sv_setiv(perl_exception,(IV) number_images);
11469 SvPOK_on(perl_exception);
11470 ST(0)=sv_2mortal(perl_exception);
11471 XSRETURN(1);
11472 }
11473
11474#
11475###############################################################################
11476# #
11477# #
11478# #
11479# M o n t a g e #
11480# #
11481# #
11482# #
11483###############################################################################
11484#
11485#
11486void
11487Montage(ref,...)
11488 Image::Magick ref=NO_INIT
11489 ALIAS:
11490 MontageImage = 1
11491 montage = 2
11492 montageimage = 3
11493 PPCODE:
11494 {
11495 AV
11496 *av;
11497
11498 char
11499 *attribute;
11500
11501 ExceptionInfo
11502 *exception;
11503
11504 HV
11505 *hv;
11506
11507 Image
11508 *image,
11509 *next;
11510
11511 PixelInfo
11512 transparent_color;
11513
11514 MontageInfo
11515 *montage_info;
11516
11517 register ssize_t
11518 i;
11519
11520 ssize_t
11521 sp;
11522
11523 struct PackageInfo
11524 *info;
11525
11526 SV
11527 *av_reference,
11528 *perl_exception,
11529 *reference,
11530 *rv,
11531 *sv;
11532
11533 PERL_UNUSED_VAR(ref);
11534 PERL_UNUSED_VAR(ix);
11535 exception=AcquireExceptionInfo();
11536 perl_exception=newSVpv("",0);
11537 sv=NULL;
11538 attribute=NULL;
11539 if (sv_isobject(ST(0)) == 0)
11540 {
11541 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11542 PackageName);
11543 goto PerlException;
11544 }
11545 reference=SvRV(ST(0));
11546 hv=SvSTASH(reference);
11547 av=newAV();
11548 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11549 SvREFCNT_dec(av);
11550 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11551 if (image == (Image *) NULL)
11552 {
11553 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11554 PackageName);
11555 goto PerlException;
11556 }
11557 /*
11558 Get options.
11559 */
11560 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11561 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11562 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11563 exception);
11564 for (i=2; i < items; i+=2)
11565 {
11566 attribute=(char *) SvPV(ST(i-1),na);
11567 switch (*attribute)
11568 {
11569 case 'B':
11570 case 'b':
11571 {
11572 if (LocaleCompare(attribute,"background") == 0)
11573 {
11574 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11575 &montage_info->background_color,exception);
11576 for (next=image; next; next=next->next)
11577 next->background_color=montage_info->background_color;
11578 break;
11579 }
11580 if (LocaleCompare(attribute,"border") == 0)
11581 {
11582 montage_info->border_width=SvIV(ST(i));
11583 break;
11584 }
11585 if (LocaleCompare(attribute,"bordercolor") == 0)
11586 {
11587 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11588 &montage_info->border_color,exception);
11589 for (next=image; next; next=next->next)
11590 next->border_color=montage_info->border_color;
11591 break;
11592 }
11593 if (LocaleCompare(attribute,"borderwidth") == 0)
11594 {
11595 montage_info->border_width=SvIV(ST(i));
11596 break;
11597 }
11598 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11599 attribute);
11600 break;
11601 }
11602 case 'C':
11603 case 'c':
11604 {
11605 if (LocaleCompare(attribute,"compose") == 0)
11606 {
11607 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11608 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11609 if (sp < 0)
11610 {
11611 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11612 SvPV(ST(i),na));
11613 break;
11614 }
11615 for (next=image; next; next=next->next)
11616 next->compose=(CompositeOperator) sp;
11617 break;
11618 }
11619 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11620 attribute);
11621 break;
11622 }
11623 case 'F':
11624 case 'f':
11625 {
11626 if (LocaleCompare(attribute,"fill") == 0)
11627 {
11628 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11629 &montage_info->fill,exception);
11630 break;
11631 }
11632 if (LocaleCompare(attribute,"font") == 0)
11633 {
11634 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11635 break;
11636 }
11637 if (LocaleCompare(attribute,"frame") == 0)
11638 {
11639 char
11640 *p;
11641
11642 p=SvPV(ST(i),na);
11643 if (IsGeometry(p) == MagickFalse)
11644 {
11645 ThrowPerlException(exception,OptionError,"MissingGeometry",
11646 p);
11647 break;
11648 }
11649 (void) CloneString(&montage_info->frame,p);
11650 if (*p == '\0')
11651 montage_info->frame=(char *) NULL;
11652 break;
11653 }
11654 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11655 attribute);
11656 break;
11657 }
11658 case 'G':
11659 case 'g':
11660 {
11661 if (LocaleCompare(attribute,"geometry") == 0)
11662 {
11663 char
11664 *p;
11665
11666 p=SvPV(ST(i),na);
11667 if (IsGeometry(p) == MagickFalse)
11668 {
11669 ThrowPerlException(exception,OptionError,"MissingGeometry",
11670 p);
11671 break;
11672 }
11673 (void) CloneString(&montage_info->geometry,p);
11674 if (*p == '\0')
11675 montage_info->geometry=(char *) NULL;
11676 break;
11677 }
11678 if (LocaleCompare(attribute,"gravity") == 0)
11679 {
11680 ssize_t
11681 in;
11682
11683 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11684 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11685 if (in < 0)
11686 {
11687 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11688 SvPV(ST(i),na));
11689 return;
11690 }
11691 montage_info->gravity=(GravityType) in;
11692 for (next=image; next; next=next->next)
11693 next->gravity=(GravityType) in;
11694 break;
11695 }
11696 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11697 attribute);
11698 break;
11699 }
11700 case 'L':
11701 case 'l':
11702 {
11703 if (LocaleCompare(attribute,"label") == 0)
11704 {
11705 for (next=image; next; next=next->next)
Cristy935a4052017-03-31 17:45:37 -040011706 (void) SetImageProperty(next,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +000011707 info ? info->image_info : (ImageInfo *) NULL,next,
Cristy935a4052017-03-31 17:45:37 -040011708 SvPV(ST(i),na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011709 break;
11710 }
11711 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11712 attribute);
11713 break;
11714 }
11715 case 'M':
11716 case 'm':
11717 {
11718 if (LocaleCompare(attribute,"mattecolor") == 0)
11719 {
11720 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
Cristy8645e042016-02-03 16:35:29 -050011721 &montage_info->alpha_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011722 for (next=image; next; next=next->next)
Cristy8645e042016-02-03 16:35:29 -050011723 next->alpha_color=montage_info->alpha_color;
cristy4a3ce0a2013-08-03 20:06:59 +000011724 break;
11725 }
11726 if (LocaleCompare(attribute,"mode") == 0)
11727 {
11728 ssize_t
11729 in;
11730
11731 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11732 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11733 switch (in)
11734 {
11735 default:
11736 {
11737 ThrowPerlException(exception,OptionError,
11738 "UnrecognizedModeType",SvPV(ST(i),na));
11739 break;
11740 }
11741 case FrameMode:
11742 {
11743 (void) CloneString(&montage_info->frame,"15x15+3+3");
11744 montage_info->shadow=MagickTrue;
11745 break;
11746 }
11747 case UnframeMode:
11748 {
11749 montage_info->frame=(char *) NULL;
11750 montage_info->shadow=MagickFalse;
11751 montage_info->border_width=0;
11752 break;
11753 }
11754 case ConcatenateMode:
11755 {
11756 montage_info->frame=(char *) NULL;
11757 montage_info->shadow=MagickFalse;
11758 (void) CloneString(&montage_info->geometry,"+0+0");
11759 montage_info->border_width=0;
11760 }
11761 }
11762 break;
11763 }
11764 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11765 attribute);
11766 break;
11767 }
11768 case 'P':
11769 case 'p':
11770 {
11771 if (LocaleCompare(attribute,"pointsize") == 0)
11772 {
11773 montage_info->pointsize=SvIV(ST(i));
11774 break;
11775 }
11776 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11777 attribute);
11778 break;
11779 }
11780 case 'S':
11781 case 's':
11782 {
11783 if (LocaleCompare(attribute,"shadow") == 0)
11784 {
11785 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11786 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11787 if (sp < 0)
11788 {
11789 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11790 SvPV(ST(i),na));
11791 break;
11792 }
11793 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11794 break;
11795 }
11796 if (LocaleCompare(attribute,"stroke") == 0)
11797 {
11798 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11799 &montage_info->stroke,exception);
11800 break;
11801 }
11802 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11803 attribute);
11804 break;
11805 }
11806 case 'T':
11807 case 't':
11808 {
11809 if (LocaleCompare(attribute,"texture") == 0)
11810 {
11811 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11812 break;
11813 }
11814 if (LocaleCompare(attribute,"tile") == 0)
11815 {
11816 char *p=SvPV(ST(i),na);
11817 if (IsGeometry(p) == MagickFalse)
11818 {
11819 ThrowPerlException(exception,OptionError,"MissingGeometry",
11820 p);
11821 break;
11822 }
11823 (void) CloneString(&montage_info->tile,p);
11824 if (*p == '\0')
11825 montage_info->tile=(char *) NULL;
11826 break;
11827 }
11828 if (LocaleCompare(attribute,"title") == 0)
11829 {
11830 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11831 break;
11832 }
11833 if (LocaleCompare(attribute,"transparent") == 0)
11834 {
11835 PixelInfo
11836 transparent_color;
11837
11838 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11839 &transparent_color,exception);
11840 for (next=image; next; next=next->next)
11841 (void) TransparentPaintImage(next,&transparent_color,
11842 TransparentAlpha,MagickFalse,exception);
11843 break;
11844 }
11845 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11846 attribute);
11847 break;
11848 }
11849 default:
11850 {
11851 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11852 attribute);
11853 break;
11854 }
11855 }
11856 }
11857 image=MontageImageList(info->image_info,montage_info,image,exception);
11858 montage_info=DestroyMontageInfo(montage_info);
11859 if (image == (Image *) NULL)
11860 goto PerlException;
11861 if (transparent_color.alpha != TransparentAlpha)
11862 for (next=image; next; next=next->next)
11863 (void) TransparentPaintImage(next,&transparent_color,
11864 TransparentAlpha,MagickFalse,exception);
11865 for ( ; image; image=image->next)
11866 {
11867 AddImageToRegistry(sv,image);
11868 rv=newRV(sv);
11869 av_push(av,sv_bless(rv,hv));
11870 SvREFCNT_dec(sv);
11871 }
11872 exception=DestroyExceptionInfo(exception);
11873 ST(0)=av_reference;
11874 SvREFCNT_dec(perl_exception);
11875 XSRETURN(1);
11876
11877 PerlException:
11878 InheritPerlException(exception,perl_exception);
11879 exception=DestroyExceptionInfo(exception);
11880 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11881 SvPOK_on(perl_exception);
11882 ST(0)=sv_2mortal(perl_exception);
11883 XSRETURN(1);
11884 }
11885
11886#
11887###############################################################################
11888# #
11889# #
11890# #
11891# M o r p h #
11892# #
11893# #
11894# #
11895###############################################################################
11896#
11897#
11898void
11899Morph(ref,...)
11900 Image::Magick ref=NO_INIT
11901 ALIAS:
11902 MorphImage = 1
11903 morph = 2
11904 morphimage = 3
11905 PPCODE:
11906 {
11907 AV
11908 *av;
11909
11910 char
11911 *attribute;
11912
11913 ExceptionInfo
11914 *exception;
11915
11916 HV
11917 *hv;
11918
11919 Image
11920 *image;
11921
11922 register ssize_t
11923 i;
11924
11925 ssize_t
11926 number_frames;
11927
11928 struct PackageInfo
11929 *info;
11930
11931 SV
11932 *av_reference,
11933 *perl_exception,
11934 *reference,
11935 *rv,
11936 *sv;
11937
11938 PERL_UNUSED_VAR(ref);
11939 PERL_UNUSED_VAR(ix);
11940 exception=AcquireExceptionInfo();
11941 perl_exception=newSVpv("",0);
11942 sv=NULL;
11943 av=NULL;
11944 attribute=NULL;
11945 if (sv_isobject(ST(0)) == 0)
11946 {
11947 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11948 PackageName);
11949 goto PerlException;
11950 }
11951 reference=SvRV(ST(0));
11952 hv=SvSTASH(reference);
11953 av=newAV();
11954 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11955 SvREFCNT_dec(av);
11956 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11957 if (image == (Image *) NULL)
11958 {
11959 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11960 PackageName);
11961 goto PerlException;
11962 }
11963 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11964 /*
11965 Get attribute.
11966 */
11967 number_frames=30;
11968 for (i=2; i < items; i+=2)
11969 {
11970 attribute=(char *) SvPV(ST(i-1),na);
11971 switch (*attribute)
11972 {
11973 case 'F':
11974 case 'f':
11975 {
11976 if (LocaleCompare(attribute,"frames") == 0)
11977 {
11978 number_frames=SvIV(ST(i));
11979 break;
11980 }
11981 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11982 attribute);
11983 break;
11984 }
11985 default:
11986 {
11987 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11988 attribute);
11989 break;
11990 }
11991 }
11992 }
11993 image=MorphImages(image,number_frames,exception);
11994 if (image == (Image *) NULL)
11995 goto PerlException;
11996 for ( ; image; image=image->next)
11997 {
11998 AddImageToRegistry(sv,image);
11999 rv=newRV(sv);
12000 av_push(av,sv_bless(rv,hv));
12001 SvREFCNT_dec(sv);
12002 }
12003 exception=DestroyExceptionInfo(exception);
12004 ST(0)=av_reference;
12005 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12006 XSRETURN(1);
12007
12008 PerlException:
12009 InheritPerlException(exception,perl_exception);
12010 exception=DestroyExceptionInfo(exception);
12011 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12012 SvPOK_on(perl_exception);
12013 ST(0)=sv_2mortal(perl_exception);
12014 XSRETURN(1);
12015 }
12016
12017#
12018###############################################################################
12019# #
12020# #
12021# #
12022# M o s a i c #
12023# #
12024# #
12025# #
12026###############################################################################
12027#
12028#
12029void
12030Mosaic(ref)
12031 Image::Magick ref=NO_INIT
12032 ALIAS:
12033 MosaicImage = 1
12034 mosaic = 2
12035 mosaicimage = 3
12036 PPCODE:
12037 {
12038 AV
12039 *av;
12040
12041 ExceptionInfo
12042 *exception;
12043
12044 HV
12045 *hv;
12046
12047 Image
12048 *image;
12049
12050 struct PackageInfo
12051 *info;
12052
12053 SV
12054 *perl_exception,
12055 *reference,
12056 *rv,
12057 *sv;
12058
12059 PERL_UNUSED_VAR(ref);
12060 PERL_UNUSED_VAR(ix);
12061 exception=AcquireExceptionInfo();
12062 perl_exception=newSVpv("",0);
12063 sv=NULL;
12064 if (sv_isobject(ST(0)) == 0)
12065 {
12066 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12067 PackageName);
12068 goto PerlException;
12069 }
12070 reference=SvRV(ST(0));
12071 hv=SvSTASH(reference);
12072 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12073 if (image == (Image *) NULL)
12074 {
12075 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12076 PackageName);
12077 goto PerlException;
12078 }
12079 image=MergeImageLayers(image,MosaicLayer,exception);
12080 /*
12081 Create blessed Perl array for the returned image.
12082 */
12083 av=newAV();
12084 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12085 SvREFCNT_dec(av);
12086 AddImageToRegistry(sv,image);
12087 rv=newRV(sv);
12088 av_push(av,sv_bless(rv,hv));
12089 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000012090 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000012091 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012092 SetImageInfo(info->image_info,0,exception);
12093 exception=DestroyExceptionInfo(exception);
12094 SvREFCNT_dec(perl_exception);
12095 XSRETURN(1);
12096
12097 PerlException:
12098 InheritPerlException(exception,perl_exception);
12099 exception=DestroyExceptionInfo(exception);
12100 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12101 SvPOK_on(perl_exception); /* return messages in string context */
12102 ST(0)=sv_2mortal(perl_exception);
12103 XSRETURN(1);
12104 }
12105
12106#
12107###############################################################################
12108# #
12109# #
12110# #
12111# P i n g #
12112# #
12113# #
12114# #
12115###############################################################################
12116#
12117#
12118void
12119Ping(ref,...)
12120 Image::Magick ref=NO_INIT
12121 ALIAS:
12122 PingImage = 1
12123 ping = 2
12124 pingimage = 3
12125 PPCODE:
12126 {
12127 AV
12128 *av;
12129
12130 char
12131 **keep,
12132 **list;
12133
12134 ExceptionInfo
12135 *exception;
12136
12137 Image
12138 *image,
12139 *next;
12140
12141 int
12142 n;
12143
12144 MagickBooleanType
12145 status;
12146
12147 register char
12148 **p;
12149
12150 register ssize_t
12151 i;
12152
12153 ssize_t
12154 ac;
12155
12156 STRLEN
12157 *length;
12158
12159 struct PackageInfo
12160 *info,
12161 *package_info;
12162
12163 SV
12164 *perl_exception,
12165 *reference;
12166
12167 size_t
12168 count;
12169
12170 PERL_UNUSED_VAR(ref);
12171 PERL_UNUSED_VAR(ix);
12172 exception=AcquireExceptionInfo();
12173 perl_exception=newSVpv("",0);
12174 package_info=(struct PackageInfo *) NULL;
12175 ac=(items < 2) ? 1 : items-1;
12176 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12177 keep=list;
12178 length=(STRLEN *) NULL;
12179 if (list == (char **) NULL)
12180 {
12181 ThrowPerlException(exception,ResourceLimitError,
12182 "MemoryAllocationFailed",PackageName);
12183 goto PerlException;
12184 }
12185 keep=list;
12186 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12187 if (length == (STRLEN *) NULL)
12188 {
12189 ThrowPerlException(exception,ResourceLimitError,
12190 "MemoryAllocationFailed",PackageName);
12191 goto PerlException;
12192 }
12193 if (sv_isobject(ST(0)) == 0)
12194 {
12195 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12196 PackageName);
12197 goto PerlException;
12198 }
12199 reference=SvRV(ST(0));
12200 if (SvTYPE(reference) != SVt_PVAV)
12201 {
12202 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12203 PackageName);
12204 goto PerlException;
12205 }
12206 av=(AV *) reference;
12207 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12208 exception);
12209 package_info=ClonePackageInfo(info,exception);
12210 n=1;
12211 if (items <= 1)
12212 *list=(char *) (*package_info->image_info->filename ?
12213 package_info->image_info->filename : "XC:black");
12214 else
12215 for (n=0, i=0; i < ac; i++)
12216 {
12217 list[n]=(char *) SvPV(ST(i+1),length[n]);
12218 if ((items >= 3) && strEQcase(list[n],"blob"))
12219 {
12220 void
12221 *blob;
12222
12223 i++;
12224 blob=(void *) (SvPV(ST(i+1),length[n]));
12225 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12226 }
12227 if ((items >= 3) && strEQcase(list[n],"filename"))
12228 continue;
12229 if ((items >= 3) && strEQcase(list[n],"file"))
12230 {
12231 FILE
12232 *file;
12233
12234 PerlIO
12235 *io_info;
12236
12237 i++;
12238 io_info=IoIFP(sv_2io(ST(i+1)));
12239 if (io_info == (PerlIO *) NULL)
12240 {
12241 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12242 PackageName);
12243 continue;
12244 }
12245 file=PerlIO_findFILE(io_info);
12246 if (file == (FILE *) NULL)
12247 {
12248 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12249 PackageName);
12250 continue;
12251 }
12252 SetImageInfoFile(package_info->image_info,file);
12253 }
12254 if ((items >= 3) && strEQcase(list[n],"magick"))
12255 continue;
12256 n++;
12257 }
12258 list[n]=(char *) NULL;
12259 keep=list;
12260 status=ExpandFilenames(&n,&list);
12261 if (status == MagickFalse)
12262 {
12263 ThrowPerlException(exception,ResourceLimitError,
12264 "MemoryAllocationFailed",PackageName);
12265 goto PerlException;
12266 }
12267 count=0;
12268 for (i=0; i < n; i++)
12269 {
12270 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012271 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012272 image=PingImage(package_info->image_info,exception);
12273 if (image == (Image *) NULL)
12274 break;
12275 if ((package_info->image_info->file != (FILE *) NULL) ||
12276 (package_info->image_info->blob != (void *) NULL))
12277 DisassociateImageStream(image);
12278 count+=GetImageListLength(image);
12279 EXTEND(sp,4*count);
12280 for (next=image; next; next=next->next)
12281 {
12282 PUSHs(sv_2mortal(newSViv(next->columns)));
12283 PUSHs(sv_2mortal(newSViv(next->rows)));
12284 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12285 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12286 }
12287 image=DestroyImageList(image);
12288 }
12289 /*
12290 Free resources.
12291 */
12292 for (i=0; i < n; i++)
12293 if (list[i] != (char *) NULL)
12294 for (p=keep; list[i] != *p++; )
12295 if (*p == NULL)
12296 {
12297 list[i]=(char *) RelinquishMagickMemory(list[i]);
12298 break;
12299 }
12300
12301 PerlException:
12302 if (package_info != (struct PackageInfo *) NULL)
12303 DestroyPackageInfo(package_info);
12304 if (list && (list != keep))
12305 list=(char **) RelinquishMagickMemory(list);
12306 if (keep)
12307 keep=(char **) RelinquishMagickMemory(keep);
12308 if (length)
12309 length=(STRLEN *) RelinquishMagickMemory(length);
12310 InheritPerlException(exception,perl_exception);
12311 exception=DestroyExceptionInfo(exception);
12312 SvREFCNT_dec(perl_exception); /* throw away all errors */
12313 }
12314
12315#
12316###############################################################################
12317# #
12318# #
12319# #
12320# P r e v i e w #
12321# #
12322# #
12323# #
12324###############################################################################
12325#
12326#
12327void
12328Preview(ref,...)
12329 Image::Magick ref=NO_INIT
12330 ALIAS:
12331 PreviewImage = 1
12332 preview = 2
12333 previewimage = 3
12334 PPCODE:
12335 {
12336 AV
12337 *av;
12338
12339 ExceptionInfo
12340 *exception;
12341
12342 HV
12343 *hv;
12344
12345 Image
12346 *image,
12347 *preview_image;
12348
12349 PreviewType
12350 preview_type;
12351
12352 struct PackageInfo
12353 *info;
12354
12355 SV
12356 *av_reference,
12357 *perl_exception,
12358 *reference,
12359 *rv,
12360 *sv;
12361
12362 PERL_UNUSED_VAR(ref);
12363 PERL_UNUSED_VAR(ix);
12364 exception=AcquireExceptionInfo();
12365 perl_exception=newSVpv("",0);
12366 sv=NULL;
12367 av=NULL;
12368 if (sv_isobject(ST(0)) == 0)
12369 {
12370 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12371 PackageName);
12372 goto PerlException;
12373 }
12374 reference=SvRV(ST(0));
12375 hv=SvSTASH(reference);
12376 av=newAV();
12377 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12378 SvREFCNT_dec(av);
12379 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12380 if (image == (Image *) NULL)
12381 {
12382 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12383 PackageName);
12384 goto PerlException;
12385 }
12386 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12387 preview_type=GammaPreview;
12388 if (items > 1)
12389 preview_type=(PreviewType)
12390 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12391 for ( ; image; image=image->next)
12392 {
12393 preview_image=PreviewImage(image,preview_type,exception);
12394 if (preview_image == (Image *) NULL)
12395 goto PerlException;
12396 AddImageToRegistry(sv,preview_image);
12397 rv=newRV(sv);
12398 av_push(av,sv_bless(rv,hv));
12399 SvREFCNT_dec(sv);
12400 }
12401 exception=DestroyExceptionInfo(exception);
12402 ST(0)=av_reference;
12403 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12404 XSRETURN(1);
12405
12406 PerlException:
12407 InheritPerlException(exception,perl_exception);
12408 exception=DestroyExceptionInfo(exception);
12409 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12410 SvPOK_on(perl_exception);
12411 ST(0)=sv_2mortal(perl_exception);
12412 XSRETURN(1);
12413 }
12414
12415#
12416###############################################################################
12417# #
12418# #
12419# #
12420# Q u e r y C o l o r #
12421# #
12422# #
12423# #
12424###############################################################################
12425#
12426#
12427void
12428QueryColor(ref,...)
12429 Image::Magick ref=NO_INIT
12430 ALIAS:
12431 querycolor = 1
12432 PPCODE:
12433 {
12434 char
12435 *name;
12436
12437 ExceptionInfo
12438 *exception;
12439
12440 PixelInfo
12441 color;
12442
12443 register ssize_t
12444 i;
12445
12446 SV
12447 *perl_exception;
12448
12449 PERL_UNUSED_VAR(ref);
12450 PERL_UNUSED_VAR(ix);
12451 exception=AcquireExceptionInfo();
12452 perl_exception=newSVpv("",0);
12453 if (items == 1)
12454 {
12455 const ColorInfo
12456 **colorlist;
12457
12458 size_t
12459 colors;
12460
12461 colorlist=GetColorInfoList("*",&colors,exception);
12462 EXTEND(sp,colors);
12463 for (i=0; i < (ssize_t) colors; i++)
12464 {
12465 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12466 }
12467 colorlist=(const ColorInfo **)
12468 RelinquishMagickMemory((ColorInfo **) colorlist);
12469 goto PerlException;
12470 }
12471 EXTEND(sp,5*items);
12472 for (i=1; i < items; i++)
12473 {
12474 name=(char *) SvPV(ST(i),na);
12475 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12476 {
12477 PUSHs(&sv_undef);
12478 continue;
12479 }
12480 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12481 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12482 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12483 if (color.colorspace == CMYKColorspace)
12484 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012485 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012486 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12487 }
12488
12489 PerlException:
12490 InheritPerlException(exception,perl_exception);
12491 exception=DestroyExceptionInfo(exception);
12492 SvREFCNT_dec(perl_exception);
12493 }
12494
12495#
12496###############################################################################
12497# #
12498# #
12499# #
12500# Q u e r y C o l o r N a m e #
12501# #
12502# #
12503# #
12504###############################################################################
12505#
12506#
12507void
12508QueryColorname(ref,...)
12509 Image::Magick ref=NO_INIT
12510 ALIAS:
12511 querycolorname = 1
12512 PPCODE:
12513 {
12514 AV
12515 *av;
12516
12517 char
cristy151b66d2015-04-15 10:50:31 +000012518 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012519
12520 ExceptionInfo
12521 *exception;
12522
12523 Image
12524 *image;
12525
12526 PixelInfo
12527 target_color;
12528
12529 register ssize_t
12530 i;
12531
12532 struct PackageInfo
12533 *info;
12534
12535 SV
12536 *perl_exception,
12537 *reference; /* reference is the SV* of ref=SvIV(reference) */
12538
12539 PERL_UNUSED_VAR(ref);
12540 PERL_UNUSED_VAR(ix);
12541 exception=AcquireExceptionInfo();
12542 perl_exception=newSVpv("",0);
12543 reference=SvRV(ST(0));
12544 av=(AV *) reference;
12545 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12546 exception);
12547 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12548 if (image == (Image *) NULL)
12549 {
12550 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12551 PackageName);
12552 goto PerlException;
12553 }
12554 EXTEND(sp,items);
12555 for (i=1; i < items; i++)
12556 {
12557 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12558 exception);
12559 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12560 exception);
12561 PUSHs(sv_2mortal(newSVpv(message,0)));
12562 }
12563
12564 PerlException:
12565 InheritPerlException(exception,perl_exception);
12566 exception=DestroyExceptionInfo(exception);
12567 SvREFCNT_dec(perl_exception);
12568 }
12569
12570#
12571###############################################################################
12572# #
12573# #
12574# #
12575# Q u e r y F o n t #
12576# #
12577# #
12578# #
12579###############################################################################
12580#
12581#
12582void
12583QueryFont(ref,...)
12584 Image::Magick ref=NO_INIT
12585 ALIAS:
12586 queryfont = 1
12587 PPCODE:
12588 {
12589 char
12590 *name,
cristy151b66d2015-04-15 10:50:31 +000012591 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012592
12593 ExceptionInfo
12594 *exception;
12595
12596 register ssize_t
12597 i;
12598
12599 SV
12600 *perl_exception;
12601
12602 volatile const TypeInfo
12603 *type_info;
12604
12605 PERL_UNUSED_VAR(ref);
12606 PERL_UNUSED_VAR(ix);
12607 exception=AcquireExceptionInfo();
12608 perl_exception=newSVpv("",0);
12609 if (items == 1)
12610 {
12611 const TypeInfo
12612 **typelist;
12613
12614 size_t
12615 types;
12616
12617 typelist=GetTypeInfoList("*",&types,exception);
12618 EXTEND(sp,types);
12619 for (i=0; i < (ssize_t) types; i++)
12620 {
12621 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12622 }
12623 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12624 typelist);
12625 goto PerlException;
12626 }
12627 EXTEND(sp,10*items);
12628 for (i=1; i < items; i++)
12629 {
12630 name=(char *) SvPV(ST(i),na);
12631 type_info=GetTypeInfo(name,exception);
12632 if (type_info == (TypeInfo *) NULL)
12633 {
12634 PUSHs(&sv_undef);
12635 continue;
12636 }
12637 if (type_info->name == (char *) NULL)
12638 PUSHs(&sv_undef);
12639 else
12640 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12641 if (type_info->description == (char *) NULL)
12642 PUSHs(&sv_undef);
12643 else
12644 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12645 if (type_info->family == (char *) NULL)
12646 PUSHs(&sv_undef);
12647 else
12648 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12649 if (type_info->style == UndefinedStyle)
12650 PUSHs(&sv_undef);
12651 else
12652 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12653 type_info->style),0)));
12654 if (type_info->stretch == UndefinedStretch)
12655 PUSHs(&sv_undef);
12656 else
12657 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12658 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012659 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012660 type_info->weight);
12661 PUSHs(sv_2mortal(newSVpv(message,0)));
12662 if (type_info->encoding == (char *) NULL)
12663 PUSHs(&sv_undef);
12664 else
12665 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12666 if (type_info->foundry == (char *) NULL)
12667 PUSHs(&sv_undef);
12668 else
12669 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12670 if (type_info->format == (char *) NULL)
12671 PUSHs(&sv_undef);
12672 else
12673 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12674 if (type_info->metrics == (char *) NULL)
12675 PUSHs(&sv_undef);
12676 else
12677 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12678 if (type_info->glyphs == (char *) NULL)
12679 PUSHs(&sv_undef);
12680 else
12681 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12682 }
12683
12684 PerlException:
12685 InheritPerlException(exception,perl_exception);
12686 exception=DestroyExceptionInfo(exception);
12687 SvREFCNT_dec(perl_exception);
12688 }
12689
12690#
12691###############################################################################
12692# #
12693# #
12694# #
12695# Q u e r y F o n t M e t r i c s #
12696# #
12697# #
12698# #
12699###############################################################################
12700#
12701#
12702void
12703QueryFontMetrics(ref,...)
12704 Image::Magick ref=NO_INIT
12705 ALIAS:
12706 queryfontmetrics = 1
12707 PPCODE:
12708 {
12709 AffineMatrix
12710 affine,
12711 current;
12712
12713 AV
12714 *av;
12715
12716 char
12717 *attribute;
12718
12719 double
12720 x,
12721 y;
12722
12723 DrawInfo
12724 *draw_info;
12725
12726 ExceptionInfo
12727 *exception;
12728
12729 GeometryInfo
12730 geometry_info;
12731
12732 Image
12733 *image;
12734
12735 MagickBooleanType
12736 status;
12737
12738 MagickStatusType
12739 flags;
12740
12741 register ssize_t
12742 i;
12743
12744 ssize_t
12745 type;
12746
12747 struct PackageInfo
12748 *info,
12749 *package_info;
12750
12751 SV
12752 *perl_exception,
12753 *reference; /* reference is the SV* of ref=SvIV(reference) */
12754
12755 TypeMetric
12756 metrics;
12757
12758 PERL_UNUSED_VAR(ref);
12759 PERL_UNUSED_VAR(ix);
12760 exception=AcquireExceptionInfo();
12761 package_info=(struct PackageInfo *) NULL;
12762 perl_exception=newSVpv("",0);
12763 reference=SvRV(ST(0));
12764 av=(AV *) reference;
12765 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12766 exception);
12767 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12768 if (image == (Image *) NULL)
12769 {
12770 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12771 PackageName);
12772 goto PerlException;
12773 }
12774 package_info=ClonePackageInfo(info,exception);
12775 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12776 CloneString(&draw_info->text,"");
12777 current=draw_info->affine;
12778 GetAffineMatrix(&affine);
12779 x=0.0;
12780 y=0.0;
12781 EXTEND(sp,7*items);
12782 for (i=2; i < items; i+=2)
12783 {
12784 attribute=(char *) SvPV(ST(i-1),na);
12785 switch (*attribute)
12786 {
12787 case 'A':
12788 case 'a':
12789 {
12790 if (LocaleCompare(attribute,"antialias") == 0)
12791 {
12792 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12793 SvPV(ST(i),na));
12794 if (type < 0)
12795 {
12796 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12797 SvPV(ST(i),na));
12798 break;
12799 }
12800 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12801 break;
12802 }
12803 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12804 attribute);
12805 break;
12806 }
12807 case 'd':
12808 case 'D':
12809 {
12810 if (LocaleCompare(attribute,"density") == 0)
12811 {
12812 CloneString(&draw_info->density,SvPV(ST(i),na));
12813 break;
12814 }
12815 if (LocaleCompare(attribute,"direction") == 0)
12816 {
12817 draw_info->direction=(DirectionType) ParseCommandOption(
12818 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12819 break;
12820 }
12821 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12822 attribute);
12823 break;
12824 }
12825 case 'e':
12826 case 'E':
12827 {
12828 if (LocaleCompare(attribute,"encoding") == 0)
12829 {
12830 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12831 break;
12832 }
12833 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12834 attribute);
12835 break;
12836 }
12837 case 'f':
12838 case 'F':
12839 {
12840 if (LocaleCompare(attribute,"family") == 0)
12841 {
12842 CloneString(&draw_info->family,SvPV(ST(i),na));
12843 break;
12844 }
12845 if (LocaleCompare(attribute,"fill") == 0)
12846 {
12847 if (info)
12848 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12849 &draw_info->fill,exception);
12850 break;
12851 }
12852 if (LocaleCompare(attribute,"font") == 0)
12853 {
12854 CloneString(&draw_info->font,SvPV(ST(i),na));
12855 break;
12856 }
12857 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12858 attribute);
12859 break;
12860 }
12861 case 'g':
12862 case 'G':
12863 {
12864 if (LocaleCompare(attribute,"geometry") == 0)
12865 {
12866 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12867 break;
12868 }
12869 if (LocaleCompare(attribute,"gravity") == 0)
12870 {
12871 draw_info->gravity=(GravityType) ParseCommandOption(
12872 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12873 break;
12874 }
12875 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12876 attribute);
12877 break;
12878 }
12879 case 'i':
12880 case 'I':
12881 {
12882 if (LocaleCompare(attribute,"interline-spacing") == 0)
12883 {
12884 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12885 draw_info->interline_spacing=geometry_info.rho;
12886 break;
12887 }
12888 if (LocaleCompare(attribute,"interword-spacing") == 0)
12889 {
12890 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12891 draw_info->interword_spacing=geometry_info.rho;
12892 break;
12893 }
12894 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12895 attribute);
12896 break;
12897 }
12898 case 'k':
12899 case 'K':
12900 {
12901 if (LocaleCompare(attribute,"kerning") == 0)
12902 {
12903 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12904 draw_info->kerning=geometry_info.rho;
12905 break;
12906 }
12907 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12908 attribute);
12909 break;
12910 }
12911 case 'p':
12912 case 'P':
12913 {
12914 if (LocaleCompare(attribute,"pointsize") == 0)
12915 {
12916 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12917 draw_info->pointsize=geometry_info.rho;
12918 break;
12919 }
12920 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12921 attribute);
12922 break;
12923 }
12924 case 'r':
12925 case 'R':
12926 {
12927 if (LocaleCompare(attribute,"rotate") == 0)
12928 {
12929 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12930 affine.rx=geometry_info.rho;
12931 affine.ry=geometry_info.sigma;
12932 if ((flags & SigmaValue) == 0)
12933 affine.ry=affine.rx;
12934 break;
12935 }
12936 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12937 attribute);
12938 break;
12939 }
12940 case 's':
12941 case 'S':
12942 {
12943 if (LocaleCompare(attribute,"scale") == 0)
12944 {
12945 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12946 affine.sx=geometry_info.rho;
12947 affine.sy=geometry_info.sigma;
12948 if ((flags & SigmaValue) == 0)
12949 affine.sy=affine.sx;
12950 break;
12951 }
12952 if (LocaleCompare(attribute,"skew") == 0)
12953 {
12954 double
12955 x_angle,
12956 y_angle;
12957
12958 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12959 x_angle=geometry_info.rho;
12960 y_angle=geometry_info.sigma;
12961 if ((flags & SigmaValue) == 0)
12962 y_angle=x_angle;
12963 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12964 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12965 break;
12966 }
12967 if (LocaleCompare(attribute,"stroke") == 0)
12968 {
12969 if (info)
12970 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12971 &draw_info->stroke,exception);
12972 break;
12973 }
12974 if (LocaleCompare(attribute,"style") == 0)
12975 {
12976 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12977 SvPV(ST(i),na));
12978 if (type < 0)
12979 {
12980 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12981 SvPV(ST(i),na));
12982 break;
12983 }
12984 draw_info->style=(StyleType) type;
12985 break;
12986 }
12987 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12988 attribute);
12989 break;
12990 }
12991 case 't':
12992 case 'T':
12993 {
12994 if (LocaleCompare(attribute,"text") == 0)
12995 {
12996 CloneString(&draw_info->text,SvPV(ST(i),na));
12997 break;
12998 }
12999 if (LocaleCompare(attribute,"translate") == 0)
13000 {
13001 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13002 affine.tx=geometry_info.rho;
13003 affine.ty=geometry_info.sigma;
13004 if ((flags & SigmaValue) == 0)
13005 affine.ty=affine.tx;
13006 break;
13007 }
13008 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13009 attribute);
13010 break;
13011 }
13012 case 'w':
13013 case 'W':
13014 {
13015 if (LocaleCompare(attribute,"weight") == 0)
13016 {
13017 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13018 draw_info->weight=(size_t) geometry_info.rho;
13019 break;
13020 }
13021 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13022 attribute);
13023 break;
13024 }
13025 case 'x':
13026 case 'X':
13027 {
13028 if (LocaleCompare(attribute,"x") == 0)
13029 {
13030 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13031 x=geometry_info.rho;
13032 break;
13033 }
13034 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13035 attribute);
13036 break;
13037 }
13038 case 'y':
13039 case 'Y':
13040 {
13041 if (LocaleCompare(attribute,"y") == 0)
13042 {
13043 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13044 y=geometry_info.rho;
13045 break;
13046 }
13047 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13048 attribute);
13049 break;
13050 }
13051 default:
13052 {
13053 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13054 attribute);
13055 break;
13056 }
13057 }
13058 }
13059 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13060 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13061 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13062 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13063 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13064 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13065 if (draw_info->geometry == (char *) NULL)
13066 {
13067 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013068 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013069 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013070 }
13071 status=GetTypeMetrics(image,draw_info,&metrics,exception);
13072 (void) CatchImageException(image);
13073 if (status == MagickFalse)
13074 PUSHs(&sv_undef);
13075 else
13076 {
13077 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13078 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13079 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13080 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13081 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13082 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13083 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13084 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13085 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13086 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13087 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13088 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13089 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13090 }
13091 draw_info=DestroyDrawInfo(draw_info);
13092
13093 PerlException:
13094 if (package_info != (struct PackageInfo *) NULL)
13095 DestroyPackageInfo(package_info);
13096 InheritPerlException(exception,perl_exception);
13097 exception=DestroyExceptionInfo(exception);
13098 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13099 }
13100
13101#
13102###############################################################################
13103# #
13104# #
13105# #
13106# 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 #
13107# #
13108# #
13109# #
13110###############################################################################
13111#
13112#
13113void
13114QueryMultilineFontMetrics(ref,...)
13115 Image::Magick ref=NO_INIT
13116 ALIAS:
13117 querymultilinefontmetrics = 1
13118 PPCODE:
13119 {
13120 AffineMatrix
13121 affine,
13122 current;
13123
13124 AV
13125 *av;
13126
13127 char
13128 *attribute;
13129
13130 double
13131 x,
13132 y;
13133
13134 DrawInfo
13135 *draw_info;
13136
13137 ExceptionInfo
13138 *exception;
13139
13140 GeometryInfo
13141 geometry_info;
13142
13143 Image
13144 *image;
13145
13146 MagickBooleanType
13147 status;
13148
13149 MagickStatusType
13150 flags;
13151
13152 register ssize_t
13153 i;
13154
13155 ssize_t
13156 type;
13157
13158 struct PackageInfo
13159 *info,
13160 *package_info;
13161
13162 SV
13163 *perl_exception,
13164 *reference; /* reference is the SV* of ref=SvIV(reference) */
13165
13166 TypeMetric
13167 metrics;
13168
13169 PERL_UNUSED_VAR(ref);
13170 PERL_UNUSED_VAR(ix);
13171 exception=AcquireExceptionInfo();
13172 package_info=(struct PackageInfo *) NULL;
13173 perl_exception=newSVpv("",0);
13174 reference=SvRV(ST(0));
13175 av=(AV *) reference;
13176 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13177 exception);
13178 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13179 if (image == (Image *) NULL)
13180 {
13181 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13182 PackageName);
13183 goto PerlException;
13184 }
13185 package_info=ClonePackageInfo(info,exception);
13186 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13187 CloneString(&draw_info->text,"");
13188 current=draw_info->affine;
13189 GetAffineMatrix(&affine);
13190 x=0.0;
13191 y=0.0;
13192 EXTEND(sp,7*items);
13193 for (i=2; i < items; i+=2)
13194 {
13195 attribute=(char *) SvPV(ST(i-1),na);
13196 switch (*attribute)
13197 {
13198 case 'A':
13199 case 'a':
13200 {
13201 if (LocaleCompare(attribute,"antialias") == 0)
13202 {
13203 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13204 SvPV(ST(i),na));
13205 if (type < 0)
13206 {
13207 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13208 SvPV(ST(i),na));
13209 break;
13210 }
13211 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13212 break;
13213 }
13214 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13215 attribute);
13216 break;
13217 }
13218 case 'd':
13219 case 'D':
13220 {
13221 if (LocaleCompare(attribute,"density") == 0)
13222 {
13223 CloneString(&draw_info->density,SvPV(ST(i),na));
13224 break;
13225 }
13226 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13227 attribute);
13228 break;
13229 }
13230 case 'e':
13231 case 'E':
13232 {
13233 if (LocaleCompare(attribute,"encoding") == 0)
13234 {
13235 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13236 break;
13237 }
13238 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13239 attribute);
13240 break;
13241 }
13242 case 'f':
13243 case 'F':
13244 {
13245 if (LocaleCompare(attribute,"family") == 0)
13246 {
13247 CloneString(&draw_info->family,SvPV(ST(i),na));
13248 break;
13249 }
13250 if (LocaleCompare(attribute,"fill") == 0)
13251 {
13252 if (info)
13253 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13254 &draw_info->fill,exception);
13255 break;
13256 }
13257 if (LocaleCompare(attribute,"font") == 0)
13258 {
13259 CloneString(&draw_info->font,SvPV(ST(i),na));
13260 break;
13261 }
13262 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13263 attribute);
13264 break;
13265 }
13266 case 'g':
13267 case 'G':
13268 {
13269 if (LocaleCompare(attribute,"geometry") == 0)
13270 {
13271 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13272 break;
13273 }
13274 if (LocaleCompare(attribute,"gravity") == 0)
13275 {
13276 draw_info->gravity=(GravityType) ParseCommandOption(
13277 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13278 break;
13279 }
13280 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13281 attribute);
13282 break;
13283 }
13284 case 'p':
13285 case 'P':
13286 {
13287 if (LocaleCompare(attribute,"pointsize") == 0)
13288 {
13289 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13290 draw_info->pointsize=geometry_info.rho;
13291 break;
13292 }
13293 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13294 attribute);
13295 break;
13296 }
13297 case 'r':
13298 case 'R':
13299 {
13300 if (LocaleCompare(attribute,"rotate") == 0)
13301 {
13302 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13303 affine.rx=geometry_info.rho;
13304 affine.ry=geometry_info.sigma;
13305 if ((flags & SigmaValue) == 0)
13306 affine.ry=affine.rx;
13307 break;
13308 }
13309 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13310 attribute);
13311 break;
13312 }
13313 case 's':
13314 case 'S':
13315 {
13316 if (LocaleCompare(attribute,"scale") == 0)
13317 {
13318 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13319 affine.sx=geometry_info.rho;
13320 affine.sy=geometry_info.sigma;
13321 if ((flags & SigmaValue) == 0)
13322 affine.sy=affine.sx;
13323 break;
13324 }
13325 if (LocaleCompare(attribute,"skew") == 0)
13326 {
13327 double
13328 x_angle,
13329 y_angle;
13330
13331 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13332 x_angle=geometry_info.rho;
13333 y_angle=geometry_info.sigma;
13334 if ((flags & SigmaValue) == 0)
13335 y_angle=x_angle;
13336 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13337 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13338 break;
13339 }
13340 if (LocaleCompare(attribute,"stroke") == 0)
13341 {
13342 if (info)
13343 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13344 &draw_info->stroke,exception);
13345 break;
13346 }
13347 if (LocaleCompare(attribute,"style") == 0)
13348 {
13349 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13350 SvPV(ST(i),na));
13351 if (type < 0)
13352 {
13353 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13354 SvPV(ST(i),na));
13355 break;
13356 }
13357 draw_info->style=(StyleType) type;
13358 break;
13359 }
13360 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13361 attribute);
13362 break;
13363 }
13364 case 't':
13365 case 'T':
13366 {
13367 if (LocaleCompare(attribute,"text") == 0)
13368 {
13369 CloneString(&draw_info->text,SvPV(ST(i),na));
13370 break;
13371 }
13372 if (LocaleCompare(attribute,"translate") == 0)
13373 {
13374 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13375 affine.tx=geometry_info.rho;
13376 affine.ty=geometry_info.sigma;
13377 if ((flags & SigmaValue) == 0)
13378 affine.ty=affine.tx;
13379 break;
13380 }
13381 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13382 attribute);
13383 break;
13384 }
13385 case 'w':
13386 case 'W':
13387 {
13388 if (LocaleCompare(attribute,"weight") == 0)
13389 {
13390 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13391 draw_info->weight=(size_t) geometry_info.rho;
13392 break;
13393 }
13394 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13395 attribute);
13396 break;
13397 }
13398 case 'x':
13399 case 'X':
13400 {
13401 if (LocaleCompare(attribute,"x") == 0)
13402 {
13403 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13404 x=geometry_info.rho;
13405 break;
13406 }
13407 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13408 attribute);
13409 break;
13410 }
13411 case 'y':
13412 case 'Y':
13413 {
13414 if (LocaleCompare(attribute,"y") == 0)
13415 {
13416 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13417 y=geometry_info.rho;
13418 break;
13419 }
13420 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13421 attribute);
13422 break;
13423 }
13424 default:
13425 {
13426 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13427 attribute);
13428 break;
13429 }
13430 }
13431 }
13432 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13433 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13434 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13435 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13436 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13437 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13438 if (draw_info->geometry == (char *) NULL)
13439 {
13440 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013441 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013442 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013443 }
13444 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13445 (void) CatchException(exception);
13446 if (status == MagickFalse)
13447 PUSHs(&sv_undef);
13448 else
13449 {
13450 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13451 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13452 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13453 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13454 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13455 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13456 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13457 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13458 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13459 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13460 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13461 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13462 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13463 }
13464 draw_info=DestroyDrawInfo(draw_info);
13465
13466 PerlException:
13467 if (package_info != (struct PackageInfo *) NULL)
13468 DestroyPackageInfo(package_info);
13469 InheritPerlException(exception,perl_exception);
13470 exception=DestroyExceptionInfo(exception);
13471 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13472 }
13473
13474#
13475###############################################################################
13476# #
13477# #
13478# #
13479# Q u e r y F o r m a t #
13480# #
13481# #
13482# #
13483###############################################################################
13484#
13485#
13486void
13487QueryFormat(ref,...)
13488 Image::Magick ref=NO_INIT
13489 ALIAS:
13490 queryformat = 1
13491 PPCODE:
13492 {
13493 char
13494 *name;
13495
13496 ExceptionInfo
13497 *exception;
13498
13499 register ssize_t
13500 i;
13501
13502 SV
13503 *perl_exception;
13504
13505 volatile const MagickInfo
13506 *magick_info;
13507
13508 PERL_UNUSED_VAR(ref);
13509 PERL_UNUSED_VAR(ix);
13510 exception=AcquireExceptionInfo();
13511 perl_exception=newSVpv("",0);
13512 if (items == 1)
13513 {
13514 char
cristy151b66d2015-04-15 10:50:31 +000013515 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013516
13517 const MagickInfo
13518 **format_list;
13519
13520 size_t
13521 types;
13522
13523 format_list=GetMagickInfoList("*",&types,exception);
13524 EXTEND(sp,types);
13525 for (i=0; i < (ssize_t) types; i++)
13526 {
cristy151b66d2015-04-15 10:50:31 +000013527 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013528 LocaleLower(format);
13529 PUSHs(sv_2mortal(newSVpv(format,0)));
13530 }
13531 format_list=(const MagickInfo **)
13532 RelinquishMagickMemory((MagickInfo *) format_list);
13533 goto PerlException;
13534 }
13535 EXTEND(sp,8*items);
13536 for (i=1; i < items; i++)
13537 {
13538 name=(char *) SvPV(ST(i),na);
13539 magick_info=GetMagickInfo(name,exception);
13540 if (magick_info == (const MagickInfo *) NULL)
13541 {
13542 PUSHs(&sv_undef);
13543 continue;
13544 }
cristy4a3ce0a2013-08-03 20:06:59 +000013545 if (magick_info->description == (char *) NULL)
13546 PUSHs(&sv_undef);
13547 else
13548 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13549 if (magick_info->module == (char *) NULL)
13550 PUSHs(&sv_undef);
13551 else
13552 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13553 }
13554
13555 PerlException:
13556 InheritPerlException(exception,perl_exception);
13557 exception=DestroyExceptionInfo(exception);
13558 SvREFCNT_dec(perl_exception);
13559 }
13560
13561#
13562###############################################################################
13563# #
13564# #
13565# #
13566# Q u e r y O p t i o n #
13567# #
13568# #
13569# #
13570###############################################################################
13571#
13572#
13573void
13574QueryOption(ref,...)
13575 Image::Magick ref=NO_INIT
13576 ALIAS:
13577 queryoption = 1
13578 PPCODE:
13579 {
13580 char
13581 **options;
13582
13583 ExceptionInfo
13584 *exception;
13585
13586 register ssize_t
13587 i;
13588
13589 ssize_t
13590 j,
13591 option;
13592
13593 SV
13594 *perl_exception;
13595
13596 PERL_UNUSED_VAR(ref);
13597 PERL_UNUSED_VAR(ix);
13598 exception=AcquireExceptionInfo();
13599 perl_exception=newSVpv("",0);
13600 EXTEND(sp,8*items);
13601 for (i=1; i < items; i++)
13602 {
13603 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13604 SvPV(ST(i),na));
13605 options=GetCommandOptions((CommandOption) option);
13606 if (options == (char **) NULL)
13607 PUSHs(&sv_undef);
13608 else
13609 {
13610 for (j=0; options[j] != (char *) NULL; j++)
13611 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13612 options=DestroyStringList(options);
13613 }
13614 }
13615
13616 InheritPerlException(exception,perl_exception);
13617 exception=DestroyExceptionInfo(exception);
13618 SvREFCNT_dec(perl_exception);
13619 }
13620
13621#
13622###############################################################################
13623# #
13624# #
13625# #
13626# R e a d #
13627# #
13628# #
13629# #
13630###############################################################################
13631#
13632#
13633void
13634Read(ref,...)
13635 Image::Magick ref=NO_INIT
13636 ALIAS:
13637 ReadImage = 1
13638 read = 2
13639 readimage = 3
13640 PPCODE:
13641 {
13642 AV
13643 *av;
13644
13645 char
13646 **keep,
13647 **list;
13648
13649 ExceptionInfo
13650 *exception;
13651
13652 HV
13653 *hv;
13654
13655 Image
13656 *image;
13657
13658 int
13659 n;
13660
13661 MagickBooleanType
13662 status;
13663
13664 register char
13665 **p;
13666
13667 register ssize_t
13668 i;
13669
13670 ssize_t
13671 ac,
13672 number_images;
13673
13674 STRLEN
13675 *length;
13676
13677 struct PackageInfo
13678 *info,
13679 *package_info;
13680
13681 SV
13682 *perl_exception, /* Perl variable for storing messages */
13683 *reference,
13684 *rv,
13685 *sv;
13686
13687 PERL_UNUSED_VAR(ref);
13688 PERL_UNUSED_VAR(ix);
13689 exception=AcquireExceptionInfo();
13690 perl_exception=newSVpv("",0);
13691 sv=NULL;
13692 package_info=(struct PackageInfo *) NULL;
13693 number_images=0;
13694 ac=(items < 2) ? 1 : items-1;
13695 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13696 keep=list;
13697 length=(STRLEN *) NULL;
13698 if (list == (char **) NULL)
13699 {
13700 ThrowPerlException(exception,ResourceLimitError,
13701 "MemoryAllocationFailed",PackageName);
13702 goto PerlException;
13703 }
13704 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13705 if (length == (STRLEN *) NULL)
13706 {
13707 ThrowPerlException(exception,ResourceLimitError,
13708 "MemoryAllocationFailed",PackageName);
13709 goto PerlException;
13710 }
13711 if (sv_isobject(ST(0)) == 0)
13712 {
13713 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13714 PackageName);
13715 goto PerlException;
13716 }
13717 reference=SvRV(ST(0));
13718 hv=SvSTASH(reference);
13719 if (SvTYPE(reference) != SVt_PVAV)
13720 {
13721 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13722 PackageName);
13723 goto PerlException;
13724 }
13725 av=(AV *) reference;
13726 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13727 exception);
13728 package_info=ClonePackageInfo(info,exception);
13729 n=1;
13730 if (items <= 1)
13731 *list=(char *) (*package_info->image_info->filename ?
13732 package_info->image_info->filename : "XC:black");
13733 else
13734 for (n=0, i=0; i < ac; i++)
13735 {
13736 list[n]=(char *) SvPV(ST(i+1),length[n]);
13737 if ((items >= 3) && strEQcase(list[n],"blob"))
13738 {
13739 void
13740 *blob;
13741
13742 i++;
13743 blob=(void *) (SvPV(ST(i+1),length[n]));
13744 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13745 }
13746 if ((items >= 3) && strEQcase(list[n],"filename"))
13747 continue;
13748 if ((items >= 3) && strEQcase(list[n],"file"))
13749 {
13750 FILE
13751 *file;
13752
13753 PerlIO
13754 *io_info;
13755
13756 i++;
13757 io_info=IoIFP(sv_2io(ST(i+1)));
13758 if (io_info == (PerlIO *) NULL)
13759 {
13760 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13761 PackageName);
13762 continue;
13763 }
13764 file=PerlIO_findFILE(io_info);
13765 if (file == (FILE *) NULL)
13766 {
13767 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13768 PackageName);
13769 continue;
13770 }
13771 SetImageInfoFile(package_info->image_info,file);
13772 }
13773 if ((items >= 3) && strEQcase(list[n],"magick"))
13774 continue;
13775 n++;
13776 }
13777 list[n]=(char *) NULL;
13778 keep=list;
13779 status=ExpandFilenames(&n,&list);
13780 if (status == MagickFalse)
13781 {
13782 ThrowPerlException(exception,ResourceLimitError,
13783 "MemoryAllocationFailed",PackageName);
13784 goto PerlException;
13785 }
13786 number_images=0;
13787 for (i=0; i < n; i++)
13788 {
13789 if ((package_info->image_info->file == (FILE *) NULL) &&
13790 (package_info->image_info->blob == (void *) NULL))
13791 image=ReadImages(package_info->image_info,list[i],exception);
13792 else
13793 {
13794 image=ReadImages(package_info->image_info,
13795 package_info->image_info->filename,exception);
13796 if (image != (Image *) NULL)
13797 DisassociateImageStream(image);
13798 }
13799 if (image == (Image *) NULL)
13800 break;
13801 for ( ; image; image=image->next)
13802 {
13803 AddImageToRegistry(sv,image);
13804 rv=newRV(sv);
13805 av_push(av,sv_bless(rv,hv));
13806 SvREFCNT_dec(sv);
13807 number_images++;
13808 }
13809 }
13810 /*
13811 Free resources.
13812 */
13813 for (i=0; i < n; i++)
13814 if (list[i] != (char *) NULL)
13815 for (p=keep; list[i] != *p++; )
13816 if (*p == (char *) NULL)
13817 {
13818 list[i]=(char *) RelinquishMagickMemory(list[i]);
13819 break;
13820 }
13821
13822 PerlException:
13823 if (package_info != (struct PackageInfo *) NULL)
13824 DestroyPackageInfo(package_info);
13825 if (list && (list != keep))
13826 list=(char **) RelinquishMagickMemory(list);
13827 if (keep)
13828 keep=(char **) RelinquishMagickMemory(keep);
13829 if (length)
13830 length=(STRLEN *) RelinquishMagickMemory(length);
13831 InheritPerlException(exception,perl_exception);
13832 exception=DestroyExceptionInfo(exception);
13833 sv_setiv(perl_exception,(IV) number_images);
13834 SvPOK_on(perl_exception);
13835 ST(0)=sv_2mortal(perl_exception);
13836 XSRETURN(1);
13837 }
13838
13839#
13840###############################################################################
13841# #
13842# #
13843# #
13844# R e m o t e #
13845# #
13846# #
13847# #
13848###############################################################################
13849#
13850#
13851void
13852Remote(ref,...)
13853 Image::Magick ref=NO_INIT
13854 ALIAS:
13855 RemoteCommand = 1
13856 remote = 2
13857 remoteCommand = 3
13858 PPCODE:
13859 {
13860 AV
13861 *av;
13862
13863 ExceptionInfo
13864 *exception;
13865
13866 register ssize_t
13867 i;
13868
13869 SV
13870 *perl_exception,
13871 *reference;
13872
13873 struct PackageInfo
13874 *info;
13875
13876 PERL_UNUSED_VAR(ref);
13877 PERL_UNUSED_VAR(ix);
13878 exception=AcquireExceptionInfo();
13879 perl_exception=newSVpv("",0);
13880 reference=SvRV(ST(0));
13881 av=(AV *) reference;
13882 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13883 exception);
13884 for (i=1; i < items; i++)
13885 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13886 SvPV(ST(i),na),exception);
13887 InheritPerlException(exception,perl_exception);
13888 exception=DestroyExceptionInfo(exception);
13889 SvREFCNT_dec(perl_exception); /* throw away all errors */
13890 }
13891
13892#
13893###############################################################################
13894# #
13895# #
13896# #
13897# S e t #
13898# #
13899# #
13900# #
13901###############################################################################
13902#
13903#
13904void
13905Set(ref,...)
13906 Image::Magick ref=NO_INIT
13907 ALIAS:
13908 SetAttributes = 1
13909 SetAttribute = 2
13910 set = 3
13911 setattributes = 4
13912 setattribute = 5
13913 PPCODE:
13914 {
13915 ExceptionInfo
13916 *exception;
13917
13918 Image
13919 *image;
13920
13921 register ssize_t
13922 i;
13923
13924 struct PackageInfo
13925 *info;
13926
13927 SV
13928 *perl_exception,
13929 *reference; /* reference is the SV* of ref=SvIV(reference) */
13930
13931 PERL_UNUSED_VAR(ref);
13932 PERL_UNUSED_VAR(ix);
13933 exception=AcquireExceptionInfo();
13934 perl_exception=newSVpv("",0);
13935 if (sv_isobject(ST(0)) == 0)
13936 {
13937 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13938 PackageName);
13939 goto PerlException;
13940 }
13941 reference=SvRV(ST(0));
13942 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13943 if (items == 2)
13944 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13945 else
13946 for (i=2; i < items; i+=2)
13947 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13948
13949 PerlException:
13950 InheritPerlException(exception,perl_exception);
13951 exception=DestroyExceptionInfo(exception);
13952 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13953 SvPOK_on(perl_exception);
13954 ST(0)=sv_2mortal(perl_exception);
13955 XSRETURN(1);
13956 }
13957
13958#
13959###############################################################################
13960# #
13961# #
13962# #
13963# S e t P i x e l #
13964# #
13965# #
13966# #
13967###############################################################################
13968#
13969#
13970void
13971SetPixel(ref,...)
13972 Image::Magick ref=NO_INIT
13973 ALIAS:
13974 setpixel = 1
13975 setPixel = 2
13976 PPCODE:
13977 {
13978 AV
13979 *av;
13980
13981 char
13982 *attribute;
13983
13984 ChannelType
13985 channel,
13986 channel_mask;
13987
13988 ExceptionInfo
13989 *exception;
13990
13991 Image
13992 *image;
13993
13994 MagickBooleanType
13995 normalize;
13996
13997 RectangleInfo
13998 region;
13999
14000 register ssize_t
14001 i;
14002
14003 register Quantum
14004 *q;
14005
14006 ssize_t
14007 option;
14008
14009 struct PackageInfo
14010 *info;
14011
14012 SV
14013 *perl_exception,
14014 *reference; /* reference is the SV* of ref=SvIV(reference) */
14015
14016 PERL_UNUSED_VAR(ref);
14017 PERL_UNUSED_VAR(ix);
14018 exception=AcquireExceptionInfo();
14019 perl_exception=newSVpv("",0);
14020 reference=SvRV(ST(0));
14021 av=(AV *) reference;
14022 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14023 exception);
14024 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14025 if (image == (Image *) NULL)
14026 {
14027 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14028 PackageName);
14029 goto PerlException;
14030 }
14031 av=(AV *) NULL;
14032 normalize=MagickTrue;
14033 region.x=0;
14034 region.y=0;
14035 region.width=image->columns;
14036 region.height=1;
14037 if (items == 1)
14038 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
14039 channel=DefaultChannels;
14040 for (i=2; i < items; i+=2)
14041 {
14042 attribute=(char *) SvPV(ST(i-1),na);
14043 switch (*attribute)
14044 {
14045 case 'C':
14046 case 'c':
14047 {
14048 if (LocaleCompare(attribute,"channel") == 0)
14049 {
14050 ssize_t
14051 option;
14052
14053 option=ParseChannelOption(SvPV(ST(i),na));
14054 if (option < 0)
14055 {
14056 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14057 SvPV(ST(i),na));
14058 return;
14059 }
14060 channel=(ChannelType) option;
14061 break;
14062 }
14063 if (LocaleCompare(attribute,"color") == 0)
14064 {
14065 if (SvTYPE(ST(i)) != SVt_RV)
14066 {
14067 char
cristy151b66d2015-04-15 10:50:31 +000014068 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014069
cristy151b66d2015-04-15 10:50:31 +000014070 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000014071 "invalid %.60s value",attribute);
14072 ThrowPerlException(exception,OptionError,message,
14073 SvPV(ST(i),na));
14074 }
14075 av=(AV *) SvRV(ST(i));
14076 break;
14077 }
14078 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14079 attribute);
14080 break;
14081 }
14082 case 'g':
14083 case 'G':
14084 {
14085 if (LocaleCompare(attribute,"geometry") == 0)
14086 {
14087 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14088 break;
14089 }
14090 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14091 attribute);
14092 break;
14093 }
14094 case 'N':
14095 case 'n':
14096 {
14097 if (LocaleCompare(attribute,"normalize") == 0)
14098 {
14099 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14100 SvPV(ST(i),na));
14101 if (option < 0)
14102 {
14103 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14104 SvPV(ST(i),na));
14105 break;
14106 }
14107 normalize=option != 0 ? MagickTrue : MagickFalse;
14108 break;
14109 }
14110 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14111 attribute);
14112 break;
14113 }
14114 case 'x':
14115 case 'X':
14116 {
14117 if (LocaleCompare(attribute,"x") == 0)
14118 {
14119 region.x=SvIV(ST(i));
14120 break;
14121 }
14122 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14123 attribute);
14124 break;
14125 }
14126 case 'y':
14127 case 'Y':
14128 {
14129 if (LocaleCompare(attribute,"y") == 0)
14130 {
14131 region.y=SvIV(ST(i));
14132 break;
14133 }
14134 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14135 attribute);
14136 break;
14137 }
14138 default:
14139 {
14140 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14141 attribute);
14142 break;
14143 }
14144 }
14145 }
14146 (void) SetImageStorageClass(image,DirectClass,exception);
14147 channel_mask=SetImageChannelMask(image,channel);
14148 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14149 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14150 (SvTYPE(av) != SVt_PVAV))
14151 PUSHs(&sv_undef);
14152 else
14153 {
14154 double
14155 scale;
14156
14157 register ssize_t
14158 i;
14159
14160 i=0;
14161 scale=1.0;
14162 if (normalize != MagickFalse)
14163 scale=QuantumRange;
14164 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14165 (i <= av_len(av)))
14166 {
14167 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14168 av_fetch(av,i,0)))),q);
14169 i++;
14170 }
14171 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14172 (i <= av_len(av)))
14173 {
14174 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14175 av_fetch(av,i,0)))),q);
14176 i++;
14177 }
14178 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14179 (i <= av_len(av)))
14180 {
14181 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14182 av_fetch(av,i,0)))),q);
14183 i++;
14184 }
14185 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14186 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14187 {
14188 SetPixelBlack(image,ClampToQuantum(scale*
14189 SvNV(*(av_fetch(av,i,0)))),q);
14190 i++;
14191 }
14192 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14193 (i <= av_len(av)))
14194 {
14195 SetPixelAlpha(image,ClampToQuantum(scale*
14196 SvNV(*(av_fetch(av,i,0)))),q);
14197 i++;
14198 }
14199 (void) SyncAuthenticPixels(image,exception);
14200 }
14201 (void) SetImageChannelMask(image,channel_mask);
14202
14203 PerlException:
14204 InheritPerlException(exception,perl_exception);
14205 exception=DestroyExceptionInfo(exception);
14206 SvREFCNT_dec(perl_exception);
14207 }
14208
14209#
14210###############################################################################
14211# #
14212# #
14213# #
14214# S m u s h #
14215# #
14216# #
14217# #
14218###############################################################################
14219#
14220#
14221void
14222Smush(ref,...)
14223 Image::Magick ref=NO_INIT
14224 ALIAS:
14225 SmushImage = 1
14226 smush = 2
14227 smushimage = 3
14228 PPCODE:
14229 {
14230 AV
14231 *av;
14232
14233 char
14234 *attribute;
14235
14236 ExceptionInfo
14237 *exception;
14238
14239 HV
14240 *hv;
14241
14242 Image
14243 *image;
14244
14245 register ssize_t
14246 i;
14247
14248 ssize_t
14249 offset,
14250 stack;
14251
14252 struct PackageInfo
14253 *info;
14254
14255 SV
14256 *av_reference,
14257 *perl_exception,
14258 *reference,
14259 *rv,
14260 *sv;
14261
14262 PERL_UNUSED_VAR(ref);
14263 PERL_UNUSED_VAR(ix);
14264 exception=AcquireExceptionInfo();
14265 perl_exception=newSVpv("",0);
14266 sv=NULL;
14267 attribute=NULL;
14268 av=NULL;
14269 if (sv_isobject(ST(0)) == 0)
14270 {
14271 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14272 PackageName);
14273 goto PerlException;
14274 }
14275 reference=SvRV(ST(0));
14276 hv=SvSTASH(reference);
14277 av=newAV();
14278 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14279 SvREFCNT_dec(av);
14280 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14281 if (image == (Image *) NULL)
14282 {
14283 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14284 PackageName);
14285 goto PerlException;
14286 }
14287 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14288 /*
14289 Get options.
14290 */
14291 offset=0;
14292 stack=MagickTrue;
14293 for (i=2; i < items; i+=2)
14294 {
14295 attribute=(char *) SvPV(ST(i-1),na);
14296 switch (*attribute)
14297 {
14298 case 'O':
14299 case 'o':
14300 {
14301 if (LocaleCompare(attribute,"offset") == 0)
14302 {
14303 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14304 break;
14305 }
14306 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14307 attribute);
14308 break;
14309 }
14310 case 'S':
14311 case 's':
14312 {
14313 if (LocaleCompare(attribute,"stack") == 0)
14314 {
14315 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14316 SvPV(ST(i),na));
14317 if (stack < 0)
14318 {
14319 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14320 SvPV(ST(i),na));
14321 return;
14322 }
14323 break;
14324 }
14325 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14326 attribute);
14327 break;
14328 }
14329 default:
14330 {
14331 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14332 attribute);
14333 break;
14334 }
14335 }
14336 }
14337 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14338 exception);
14339 if (image == (Image *) NULL)
14340 goto PerlException;
14341 for ( ; image; image=image->next)
14342 {
14343 AddImageToRegistry(sv,image);
14344 rv=newRV(sv);
14345 av_push(av,sv_bless(rv,hv));
14346 SvREFCNT_dec(sv);
14347 }
14348 exception=DestroyExceptionInfo(exception);
14349 ST(0)=av_reference;
14350 SvREFCNT_dec(perl_exception);
14351 XSRETURN(1);
14352
14353 PerlException:
14354 InheritPerlException(exception,perl_exception);
14355 exception=DestroyExceptionInfo(exception);
14356 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14357 SvPOK_on(perl_exception);
14358 ST(0)=sv_2mortal(perl_exception);
14359 XSRETURN(1);
14360 }
14361
14362#
14363###############################################################################
14364# #
14365# #
14366# #
14367# S t a t i s t i c s #
14368# #
14369# #
14370# #
14371###############################################################################
14372#
14373#
14374void
14375Statistics(ref,...)
14376 Image::Magick ref=NO_INIT
14377 ALIAS:
14378 StatisticsImage = 1
14379 statistics = 2
14380 statisticsimage = 3
14381 PPCODE:
14382 {
14383#define ChannelStatistics(channel) \
14384{ \
cristy151b66d2015-04-15 10:50:31 +000014385 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014386 (double) channel_statistics[channel].depth); \
14387 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014388 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014389 channel_statistics[channel].minima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014390 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014391 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014392 channel_statistics[channel].maxima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014393 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014394 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014395 channel_statistics[channel].mean/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014396 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014397 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014398 channel_statistics[channel].standard_deviation/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014399 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014400 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014401 channel_statistics[channel].kurtosis); \
14402 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014403 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014404 channel_statistics[channel].skewness); \
14405 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014406 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy275bdd92014-11-08 23:45:03 +000014407 channel_statistics[channel].entropy); \
14408 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014409}
14410
14411 AV
14412 *av;
14413
14414 char
cristy151b66d2015-04-15 10:50:31 +000014415 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014416
14417 ChannelStatistics
14418 *channel_statistics;
14419
cristy4a3ce0a2013-08-03 20:06:59 +000014420 ExceptionInfo
14421 *exception;
14422
14423 Image
14424 *image;
14425
14426 ssize_t
14427 count;
14428
14429 struct PackageInfo
14430 *info;
14431
14432 SV
14433 *perl_exception,
14434 *reference;
14435
14436 PERL_UNUSED_VAR(ref);
14437 PERL_UNUSED_VAR(ix);
14438 exception=AcquireExceptionInfo();
14439 perl_exception=newSVpv("",0);
14440 av=NULL;
14441 if (sv_isobject(ST(0)) == 0)
14442 {
14443 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14444 PackageName);
14445 goto PerlException;
14446 }
14447 reference=SvRV(ST(0));
14448 av=newAV();
14449 SvREFCNT_dec(av);
14450 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14451 if (image == (Image *) NULL)
14452 {
14453 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14454 PackageName);
14455 goto PerlException;
14456 }
cristy4a3ce0a2013-08-03 20:06:59 +000014457 count=0;
14458 for ( ; image; image=image->next)
14459 {
Cristyb1710fe2017-02-11 13:51:48 -050014460 register size_t
14461 i;
14462
cristy4a3ce0a2013-08-03 20:06:59 +000014463 channel_statistics=GetImageStatistics(image,exception);
14464 if (channel_statistics == (ChannelStatistics *) NULL)
14465 continue;
14466 count++;
Cristyb1710fe2017-02-11 13:51:48 -050014467 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
14468 {
14469 PixelChannel channel=GetPixelChannelChannel(image,i);
14470 PixelTrait traits=GetPixelChannelTraits(image,channel);
Cristy5a854dc2017-02-11 15:43:46 -050014471 if (traits == UndefinedPixelTrait)
Cristyb1710fe2017-02-11 13:51:48 -050014472 continue;
Cristy5a854dc2017-02-11 15:43:46 -050014473 EXTEND(sp,8*(i+1)*count);
Cristyb1710fe2017-02-11 13:51:48 -050014474 ChannelStatistics(channel);
14475 }
Cristy25813902017-02-11 15:47:52 -050014476 EXTEND(sp,8*(i+1)*count);
14477 ChannelStatistics(CompositePixelChannel);
cristy4a3ce0a2013-08-03 20:06:59 +000014478 channel_statistics=(ChannelStatistics *)
14479 RelinquishMagickMemory(channel_statistics);
14480 }
14481
14482 PerlException:
14483 InheritPerlException(exception,perl_exception);
14484 exception=DestroyExceptionInfo(exception);
14485 SvREFCNT_dec(perl_exception);
14486 }
14487
14488#
14489###############################################################################
14490# #
14491# #
14492# #
14493# S y n c A u t h e n t i c P i x e l s #
14494# #
14495# #
14496# #
14497###############################################################################
14498#
14499#
14500void
14501SyncAuthenticPixels(ref,...)
14502 Image::Magick ref = NO_INIT
14503 ALIAS:
14504 Syncauthenticpixels = 1
14505 SyncImagePixels = 2
14506 syncimagepixels = 3
14507 CODE:
14508 {
14509 ExceptionInfo
14510 *exception;
14511
14512 Image
14513 *image;
14514
14515 MagickBooleanType
14516 status;
14517
14518 struct PackageInfo
14519 *info;
14520
14521 SV
14522 *perl_exception,
14523 *reference;
14524
14525 PERL_UNUSED_VAR(ref);
14526 PERL_UNUSED_VAR(ix);
14527 exception=AcquireExceptionInfo();
14528 perl_exception=newSVpv("",0);
14529 if (sv_isobject(ST(0)) == 0)
14530 {
14531 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14532 PackageName);
14533 goto PerlException;
14534 }
14535
14536 reference=SvRV(ST(0));
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
14545 status=SyncAuthenticPixels(image,exception);
14546 if (status != MagickFalse)
14547 return;
14548
14549 PerlException:
14550 InheritPerlException(exception,perl_exception);
14551 exception=DestroyExceptionInfo(exception);
14552 SvREFCNT_dec(perl_exception); /* throw away all errors */
14553 }
14554
14555#
14556###############################################################################
14557# #
14558# #
14559# #
cristy4a3ce0a2013-08-03 20:06:59 +000014560# W r i t e #
14561# #
14562# #
14563# #
14564###############################################################################
14565#
14566#
14567void
14568Write(ref,...)
14569 Image::Magick ref=NO_INIT
14570 ALIAS:
14571 WriteImage = 1
14572 write = 2
14573 writeimage = 3
14574 PPCODE:
14575 {
14576 char
cristy151b66d2015-04-15 10:50:31 +000014577 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014578
14579 ExceptionInfo
14580 *exception;
14581
14582 Image
14583 *image,
14584 *next;
14585
14586 register ssize_t
14587 i;
14588
14589 ssize_t
14590 number_images,
14591 scene;
14592
14593 struct PackageInfo
14594 *info,
14595 *package_info;
14596
14597 SV
14598 *perl_exception,
14599 *reference;
14600
14601 PERL_UNUSED_VAR(ref);
14602 PERL_UNUSED_VAR(ix);
14603 exception=AcquireExceptionInfo();
14604 perl_exception=newSVpv("",0);
14605 number_images=0;
14606 package_info=(struct PackageInfo *) NULL;
14607 if (sv_isobject(ST(0)) == 0)
14608 {
14609 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14610 PackageName);
14611 goto PerlException;
14612 }
14613 reference=SvRV(ST(0));
14614 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14615 if (image == (Image *) NULL)
14616 {
14617 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14618 PackageName);
14619 goto PerlException;
14620 }
14621 package_info=ClonePackageInfo(info,exception);
14622 if (items == 2)
14623 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14624 else
14625 if (items > 2)
14626 for (i=2; i < items; i+=2)
14627 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14628 exception);
14629 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014630 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014631 scene=0;
14632 for (next=image; next; next=next->next)
14633 {
cristy151b66d2015-04-15 10:50:31 +000014634 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014635 next->scene=scene++;
14636 }
cristy68bd79a2015-02-25 12:23:36 +000014637 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014638 SetImageInfo(package_info->image_info,(unsigned int)
14639 GetImageListLength(image),exception);
14640 for (next=image; next; next=next->next)
14641 {
14642 (void) WriteImage(package_info->image_info,next,exception);
14643 number_images++;
14644 if (package_info->image_info->adjoin)
14645 break;
14646 }
14647
14648 PerlException:
14649 if (package_info != (struct PackageInfo *) NULL)
14650 DestroyPackageInfo(package_info);
14651 InheritPerlException(exception,perl_exception);
14652 exception=DestroyExceptionInfo(exception);
14653 sv_setiv(perl_exception,(IV) number_images);
14654 SvPOK_on(perl_exception);
14655 ST(0)=sv_2mortal(perl_exception);
14656 XSRETURN(1);
14657 }