blob: eb5d643f3a66f2b63b542f6dc19cf60837d32d40 [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} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000567 };
568
569static SplayTreeInfo
570 *magick_registry = (SplayTreeInfo *) NULL;
571
572/*
573 Forward declarations.
574*/
575static Image
576 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
577
578static ssize_t
579 strEQcase(const char *,const char *);
580
581/*
582%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
583% %
584% %
585% %
586% C l o n e P a c k a g e I n f o %
587% %
588% %
589% %
590%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
591%
592% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
593% a new one.
594%
595% The format of the ClonePackageInfo routine is:
596%
597% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
598% exception)
599%
600% A description of each parameter follows:
601%
602% o info: a structure of type info.
603%
604% o exception: Return any errors or warnings in this structure.
605%
606*/
607static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
608 ExceptionInfo *exception)
609{
610 struct PackageInfo
611 *clone_info;
612
613 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
614 if (clone_info == (struct PackageInfo *) NULL)
615 {
616 ThrowPerlException(exception,ResourceLimitError,
617 "UnableToClonePackageInfo",PackageName);
618 return((struct PackageInfo *) NULL);
619 }
620 if (info == (struct PackageInfo *) NULL)
621 {
622 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
623 return(clone_info);
624 }
625 *clone_info=(*info);
626 clone_info->image_info=CloneImageInfo(info->image_info);
627 return(clone_info);
628}
629
630/*
631%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
632% %
633% %
634% %
635% c o n s t a n t %
636% %
637% %
638% %
639%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
640%
641% constant() returns a double value for the specified name.
642%
643% The format of the constant routine is:
644%
645% double constant(char *name,ssize_t sans)
646%
647% A description of each parameter follows:
648%
649% o value: Method constant returns a double value for the specified name.
650%
651% o name: The name of the constant.
652%
653% o sans: This integer value is not used.
654%
655*/
656static double constant(char *name,ssize_t sans)
657{
658 (void) sans;
659 errno=0;
660 switch (*name)
661 {
662 case 'B':
663 {
664 if (strEQ(name,"BlobError"))
665 return(BlobError);
666 if (strEQ(name,"BlobWarning"))
667 return(BlobWarning);
668 break;
669 }
670 case 'C':
671 {
672 if (strEQ(name,"CacheError"))
673 return(CacheError);
674 if (strEQ(name,"CacheWarning"))
675 return(CacheWarning);
676 if (strEQ(name,"CoderError"))
677 return(CoderError);
678 if (strEQ(name,"CoderWarning"))
679 return(CoderWarning);
680 if (strEQ(name,"ConfigureError"))
681 return(ConfigureError);
682 if (strEQ(name,"ConfigureWarning"))
683 return(ConfigureWarning);
684 if (strEQ(name,"CorruptImageError"))
685 return(CorruptImageError);
686 if (strEQ(name,"CorruptImageWarning"))
687 return(CorruptImageWarning);
688 break;
689 }
690 case 'D':
691 {
692 if (strEQ(name,"DelegateError"))
693 return(DelegateError);
694 if (strEQ(name,"DelegateWarning"))
695 return(DelegateWarning);
696 if (strEQ(name,"DrawError"))
697 return(DrawError);
698 if (strEQ(name,"DrawWarning"))
699 return(DrawWarning);
700 break;
701 }
702 case 'E':
703 {
704 if (strEQ(name,"ErrorException"))
705 return(ErrorException);
706 if (strEQ(name,"ExceptionError"))
707 return(CoderError);
708 if (strEQ(name,"ExceptionWarning"))
709 return(CoderWarning);
710 break;
711 }
712 case 'F':
713 {
714 if (strEQ(name,"FatalErrorException"))
715 return(FatalErrorException);
716 if (strEQ(name,"FileOpenError"))
717 return(FileOpenError);
718 if (strEQ(name,"FileOpenWarning"))
719 return(FileOpenWarning);
720 break;
721 }
722 case 'I':
723 {
724 if (strEQ(name,"ImageError"))
725 return(ImageError);
726 if (strEQ(name,"ImageWarning"))
727 return(ImageWarning);
728 break;
729 }
730 case 'M':
731 {
732 if (strEQ(name,"MaxRGB"))
733 return(QuantumRange);
734 if (strEQ(name,"MissingDelegateError"))
735 return(MissingDelegateError);
736 if (strEQ(name,"MissingDelegateWarning"))
737 return(MissingDelegateWarning);
738 if (strEQ(name,"ModuleError"))
739 return(ModuleError);
740 if (strEQ(name,"ModuleWarning"))
741 return(ModuleWarning);
742 break;
743 }
744 case 'O':
745 {
746 if (strEQ(name,"Opaque"))
747 return(OpaqueAlpha);
748 if (strEQ(name,"OptionError"))
749 return(OptionError);
750 if (strEQ(name,"OptionWarning"))
751 return(OptionWarning);
752 break;
753 }
754 case 'Q':
755 {
756 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
757 return(MAGICKCORE_QUANTUM_DEPTH);
758 if (strEQ(name,"QuantumDepth"))
759 return(MAGICKCORE_QUANTUM_DEPTH);
760 if (strEQ(name,"QuantumRange"))
761 return(QuantumRange);
762 break;
763 }
764 case 'R':
765 {
766 if (strEQ(name,"ResourceLimitError"))
767 return(ResourceLimitError);
768 if (strEQ(name,"ResourceLimitWarning"))
769 return(ResourceLimitWarning);
770 if (strEQ(name,"RegistryError"))
771 return(RegistryError);
772 if (strEQ(name,"RegistryWarning"))
773 return(RegistryWarning);
774 break;
775 }
776 case 'S':
777 {
778 if (strEQ(name,"StreamError"))
779 return(StreamError);
780 if (strEQ(name,"StreamWarning"))
781 return(StreamWarning);
782 if (strEQ(name,"Success"))
783 return(0);
784 break;
785 }
786 case 'T':
787 {
788 if (strEQ(name,"Transparent"))
789 return(TransparentAlpha);
790 if (strEQ(name,"TypeError"))
791 return(TypeError);
792 if (strEQ(name,"TypeWarning"))
793 return(TypeWarning);
794 break;
795 }
796 case 'W':
797 {
798 if (strEQ(name,"WarningException"))
799 return(WarningException);
800 break;
801 }
802 case 'X':
803 {
804 if (strEQ(name,"XServerError"))
805 return(XServerError);
806 if (strEQ(name,"XServerWarning"))
807 return(XServerWarning);
808 break;
809 }
810 }
811 errno=EINVAL;
812 return(0);
813}
814
815/*
816%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
817% %
818% %
819% %
820% D e s t r o y P a c k a g e I n f o %
821% %
822% %
823% %
824%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
825%
826% Method DestroyPackageInfo frees a previously created info structure.
827%
828% The format of the DestroyPackageInfo routine is:
829%
830% DestroyPackageInfo(struct PackageInfo *info)
831%
832% A description of each parameter follows:
833%
834% o info: a structure of type info.
835%
836*/
837static void DestroyPackageInfo(struct PackageInfo *info)
838{
839 info->image_info=DestroyImageInfo(info->image_info);
840 info=(struct PackageInfo *) RelinquishMagickMemory(info);
841}
842
843/*
844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
845% %
846% %
847% %
848% G e t L i s t %
849% %
850% %
851% %
852%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
853%
854% Method GetList is recursively called by SetupList to traverse the
855% Image__Magick reference. If building an reference_vector (see SetupList),
856% *current is the current position in *reference_vector and *last is the final
857% entry in *reference_vector.
858%
859% The format of the GetList routine is:
860%
861% GetList(info)
862%
863% A description of each parameter follows:
864%
865% o info: a structure of type info.
866%
867*/
868static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
869 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
870{
871 Image
872 *image;
873
874 if (reference == (SV *) NULL)
875 return(NULL);
876 switch (SvTYPE(reference))
877 {
878 case SVt_PVAV:
879 {
880 AV
881 *av;
882
883 Image
884 *head,
885 *previous;
886
887 register ssize_t
888 i;
889
890 ssize_t
891 n;
892
893 /*
894 Array of images.
895 */
896 previous=(Image *) NULL;
897 head=(Image *) NULL;
898 av=(AV *) reference;
899 n=av_len(av);
900 for (i=0; i <= n; i++)
901 {
902 SV
903 **rv;
904
905 rv=av_fetch(av,i,0);
906 if (rv && *rv && sv_isobject(*rv))
907 {
908 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
909 exception);
910 if (image == (Image *) NULL)
911 continue;
912 if (image == previous)
913 {
914 image=CloneImage(image,0,0,MagickTrue,exception);
915 if (image == (Image *) NULL)
916 return(NULL);
917 }
918 image->previous=previous;
919 *(previous ? &previous->next : &head)=image;
920 for (previous=image; previous->next; previous=previous->next) ;
921 }
922 }
923 return(head);
924 }
925 case SVt_PVMG:
926 {
927 /*
928 Blessed scalar, one image.
929 */
930 image=INT2PTR(Image *,SvIV(reference));
931 if (image == (Image *) NULL)
932 return(NULL);
933 image->previous=(Image *) NULL;
934 image->next=(Image *) NULL;
935 if (reference_vector)
936 {
937 if (*current == *last)
938 {
939 *last+=256;
940 if (*reference_vector == (SV **) NULL)
941 *reference_vector=(SV **) AcquireQuantumMemory(*last,
942 sizeof(*reference_vector));
943 else
944 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
945 *last,sizeof(*reference_vector));
946 }
947 if (*reference_vector == (SV **) NULL)
948 {
949 ThrowPerlException(exception,ResourceLimitError,
950 "MemoryAllocationFailed",PackageName);
951 return((Image *) NULL);
952 }
953 (*reference_vector)[*current]=reference;
954 (*reference_vector)[++(*current)]=NULL;
955 }
956 return(image);
957 }
958 default:
959 break;
960 }
961 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
962 (double) SvTYPE(reference));
963 return((Image *) NULL);
964}
965
966/*
967%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
968% %
969% %
970% %
971% G e t P a c k a g e I n f o %
972% %
973% %
974% %
975%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
976%
977% Method GetPackageInfo looks up or creates an info structure for the given
978% Image__Magick reference. If it does create a new one, the information in
979% package_info is used to initialize it.
980%
981% The format of the GetPackageInfo routine is:
982%
983% struct PackageInfo *GetPackageInfo(void *reference,
984% struct PackageInfo *package_info,ExceptionInfo *exception)
985%
986% A description of each parameter follows:
987%
988% o info: a structure of type info.
989%
990% o exception: Return any errors or warnings in this structure.
991%
992*/
993static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
994 struct PackageInfo *package_info,ExceptionInfo *exception)
995{
996 char
cristy151b66d2015-04-15 10:50:31 +0000997 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +0000998
999 struct PackageInfo
1000 *clone_info;
1001
1002 SV
1003 *sv;
1004
cristy151b66d2015-04-15 10:50:31 +00001005 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00001006 PackageName,XS_VERSION,reference);
1007 sv=perl_get_sv(message,(TRUE | 0x02));
1008 if (sv == (SV *) NULL)
1009 {
1010 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1011 message);
1012 return(package_info);
1013 }
1014 if (SvREFCNT(sv) == 0)
1015 (void) SvREFCNT_inc(sv);
1016 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1017 return(clone_info);
1018 clone_info=ClonePackageInfo(package_info,exception);
1019 sv_setiv(sv,PTR2IV(clone_info));
1020 return(clone_info);
1021}
1022
1023/*
1024%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1025% %
1026% %
1027% %
1028% S e t A t t r i b u t e %
1029% %
1030% %
1031% %
1032%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1033%
1034% SetAttribute() sets the attribute to the value in sval. This can change
1035% either or both of image or info.
1036%
1037% The format of the SetAttribute routine is:
1038%
1039% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1040% SV *sval,ExceptionInfo *exception)
1041%
1042% A description of each parameter follows:
1043%
1044% o list: a list of strings.
1045%
1046% o string: a character string.
1047%
1048*/
1049
1050static double SiPrefixToDoubleInterval(const char *string,const double interval)
1051{
1052 char
1053 *q;
1054
1055 double
1056 value;
1057
1058 value=InterpretSiPrefixValue(string,&q);
1059 if (*q == '%')
1060 value*=interval/100.0;
1061 return(value);
1062}
1063
1064static inline double StringToDouble(const char *string,char **sentinal)
1065{
1066 return(InterpretLocaleValue(string,sentinal));
1067}
1068
1069static double StringToDoubleInterval(const char *string,const double interval)
1070{
1071 char
1072 *q;
1073
1074 double
1075 value;
1076
1077 value=InterpretLocaleValue(string,&q);
1078 if (*q == '%')
1079 value*=interval/100.0;
1080 return(value);
1081}
1082
1083static inline ssize_t StringToLong(const char *value)
1084{
1085 return(strtol(value,(char **) NULL,10));
1086}
1087
1088static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1089 const char *attribute,SV *sval,ExceptionInfo *exception)
1090{
1091 GeometryInfo
1092 geometry_info;
1093
1094 long
1095 x,
1096 y;
1097
1098 PixelInfo
1099 pixel;
1100
1101 MagickStatusType
1102 flags;
1103
1104 PixelInfo
1105 *color,
1106 target_color;
1107
1108 ssize_t
1109 sp;
1110
1111 switch (*attribute)
1112 {
1113 case 'A':
1114 case 'a':
1115 {
1116 if (LocaleCompare(attribute,"adjoin") == 0)
1117 {
1118 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1119 SvPV(sval,na)) : SvIV(sval);
1120 if (sp < 0)
1121 {
1122 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1123 SvPV(sval,na));
1124 break;
1125 }
1126 if (info)
1127 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1128 break;
1129 }
1130 if (LocaleCompare(attribute,"alpha") == 0)
1131 {
1132 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1133 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1134 if (sp < 0)
1135 {
1136 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1137 SvPV(sval,na));
1138 break;
1139 }
1140 for ( ; image; image=image->next)
1141 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1142 exception);
1143 break;
1144 }
1145 if (LocaleCompare(attribute,"antialias") == 0)
1146 {
1147 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1148 SvPV(sval,na)) : SvIV(sval);
1149 if (sp < 0)
1150 {
1151 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1152 SvPV(sval,na));
1153 break;
1154 }
1155 if (info)
1156 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1157 break;
1158 }
1159 if (LocaleCompare(attribute,"area-limit") == 0)
1160 {
1161 MagickSizeType
1162 limit;
1163
1164 limit=MagickResourceInfinity;
1165 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1166 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1167 100.0);
1168 (void) SetMagickResourceLimit(AreaResource,limit);
1169 break;
1170 }
1171 if (LocaleCompare(attribute,"attenuate") == 0)
1172 {
1173 if (info)
1174 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1175 break;
1176 }
1177 if (LocaleCompare(attribute,"authenticate") == 0)
1178 {
1179 if (info)
1180 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1181 break;
1182 }
1183 if (info)
1184 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1185 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001186 {
1187 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstra337c9bc2017-04-03 16:04:21 +02001188 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001189 }
cristy4a3ce0a2013-08-03 20:06:59 +00001190 break;
1191 }
1192 case 'B':
1193 case 'b':
1194 {
1195 if (LocaleCompare(attribute,"background") == 0)
1196 {
1197 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1198 exception);
1199 if (info)
1200 info->image_info->background_color=target_color;
1201 for ( ; image; image=image->next)
1202 image->background_color=target_color;
1203 break;
1204 }
1205 if (LocaleCompare(attribute,"blue-primary") == 0)
1206 {
1207 for ( ; image; image=image->next)
1208 {
1209 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1210 image->chromaticity.blue_primary.x=geometry_info.rho;
1211 image->chromaticity.blue_primary.y=geometry_info.sigma;
1212 if ((flags & SigmaValue) == 0)
1213 image->chromaticity.blue_primary.y=
1214 image->chromaticity.blue_primary.x;
1215 }
1216 break;
1217 }
1218 if (LocaleCompare(attribute,"bordercolor") == 0)
1219 {
1220 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1221 exception);
1222 if (info)
1223 info->image_info->border_color=target_color;
1224 for ( ; image; image=image->next)
1225 image->border_color=target_color;
1226 break;
1227 }
1228 if (info)
1229 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1230 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001231 {
1232 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001233 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001234 }
cristy4a3ce0a2013-08-03 20:06:59 +00001235 break;
1236 }
1237 case 'C':
1238 case 'c':
1239 {
1240 if (LocaleCompare(attribute,"cache-threshold") == 0)
1241 {
1242 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1243 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1244 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1245 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1246 break;
1247 }
1248 if (LocaleCompare(attribute,"clip-mask") == 0)
1249 {
1250 Image
1251 *clip_mask;
1252
1253 clip_mask=(Image *) NULL;
1254 if (SvPOK(sval))
1255 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1256 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001257 SetImageMask(image,ReadPixelMask,clip_mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001258 break;
1259 }
1260 if (LocaleNCompare(attribute,"colormap",8) == 0)
1261 {
1262 for ( ; image; image=image->next)
1263 {
1264 int
1265 items;
1266
1267 long
1268 i;
1269
1270 if (image->storage_class == DirectClass)
1271 continue;
1272 i=0;
1273 items=sscanf(attribute,"%*[^[][%ld",&i);
1274 (void) items;
1275 if (i > (ssize_t) image->colors)
1276 i%=image->colors;
1277 if ((strchr(SvPV(sval,na),',') == 0) ||
1278 (strchr(SvPV(sval,na),')') != 0))
1279 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1280 image->colormap+i,exception);
1281 else
1282 {
1283 color=image->colormap+i;
1284 pixel.red=color->red;
1285 pixel.green=color->green;
1286 pixel.blue=color->blue;
1287 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1288 pixel.red=geometry_info.rho;
1289 pixel.green=geometry_info.sigma;
1290 pixel.blue=geometry_info.xi;
1291 color->red=ClampToQuantum(pixel.red);
1292 color->green=ClampToQuantum(pixel.green);
1293 color->blue=ClampToQuantum(pixel.blue);
1294 }
1295 }
1296 break;
1297 }
1298 if (LocaleCompare(attribute,"colorspace") == 0)
1299 {
1300 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1301 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1302 if (sp < 0)
1303 {
1304 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1305 SvPV(sval,na));
1306 break;
1307 }
1308 for ( ; image; image=image->next)
Cristy59262d92016-12-05 15:21:50 -05001309 (void) SetImageColorspace(image,(ColorspaceType) sp,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001310 break;
1311 }
1312 if (LocaleCompare(attribute,"comment") == 0)
1313 {
1314 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001315 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001316 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001317 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001318 break;
1319 }
1320 if (LocaleCompare(attribute,"compression") == 0)
1321 {
1322 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1323 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1324 if (sp < 0)
1325 {
1326 ThrowPerlException(exception,OptionError,
1327 "UnrecognizedImageCompression",SvPV(sval,na));
1328 break;
1329 }
1330 if (info)
1331 info->image_info->compression=(CompressionType) sp;
1332 for ( ; image; image=image->next)
1333 image->compression=(CompressionType) sp;
1334 break;
1335 }
1336 if (info)
1337 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1338 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001339 {
1340 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001341 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001342 }
cristy4a3ce0a2013-08-03 20:06:59 +00001343 break;
1344 }
1345 case 'D':
1346 case 'd':
1347 {
1348 if (LocaleCompare(attribute,"debug") == 0)
1349 {
1350 SetLogEventMask(SvPV(sval,na));
1351 break;
1352 }
1353 if (LocaleCompare(attribute,"delay") == 0)
1354 {
1355 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1356 for ( ; image; image=image->next)
1357 {
1358 image->delay=(size_t) floor(geometry_info.rho+0.5);
1359 if ((flags & SigmaValue) != 0)
1360 image->ticks_per_second=(ssize_t)
1361 floor(geometry_info.sigma+0.5);
1362 }
1363 break;
1364 }
1365 if (LocaleCompare(attribute,"disk-limit") == 0)
1366 {
1367 MagickSizeType
1368 limit;
1369
1370 limit=MagickResourceInfinity;
1371 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1372 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1373 100.0);
1374 (void) SetMagickResourceLimit(DiskResource,limit);
1375 break;
1376 }
1377 if (LocaleCompare(attribute,"density") == 0)
1378 {
1379 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1380 {
1381 ThrowPerlException(exception,OptionError,"MissingGeometry",
1382 SvPV(sval,na));
1383 break;
1384 }
1385 if (info)
1386 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1387 for ( ; image; image=image->next)
1388 {
1389 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1390 image->resolution.x=geometry_info.rho;
1391 image->resolution.y=geometry_info.sigma;
1392 if ((flags & SigmaValue) == 0)
1393 image->resolution.y=image->resolution.x;
1394 }
1395 break;
1396 }
1397 if (LocaleCompare(attribute,"depth") == 0)
1398 {
1399 if (info)
1400 info->image_info->depth=SvIV(sval);
1401 for ( ; image; image=image->next)
1402 (void) SetImageDepth(image,SvIV(sval),exception);
1403 break;
1404 }
1405 if (LocaleCompare(attribute,"dispose") == 0)
1406 {
1407 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1408 SvPV(sval,na)) : SvIV(sval);
1409 if (sp < 0)
1410 {
1411 ThrowPerlException(exception,OptionError,
1412 "UnrecognizedDisposeMethod",SvPV(sval,na));
1413 break;
1414 }
1415 for ( ; image; image=image->next)
1416 image->dispose=(DisposeType) sp;
1417 break;
1418 }
1419 if (LocaleCompare(attribute,"dither") == 0)
1420 {
1421 if (info)
1422 {
1423 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1424 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1425 if (sp < 0)
1426 {
1427 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1428 SvPV(sval,na));
1429 break;
1430 }
1431 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1432 }
1433 break;
1434 }
1435 if (LocaleCompare(attribute,"display") == 0)
1436 {
1437 display:
1438 if (info)
1439 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1440 break;
1441 }
1442 if (info)
1443 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1444 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001445 {
1446 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001447 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001448 }
cristy4a3ce0a2013-08-03 20:06:59 +00001449 break;
1450 }
1451 case 'E':
1452 case 'e':
1453 {
1454 if (LocaleCompare(attribute,"endian") == 0)
1455 {
1456 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1457 SvPV(sval,na)) : SvIV(sval);
1458 if (sp < 0)
1459 {
1460 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1461 SvPV(sval,na));
1462 break;
1463 }
1464 if (info)
1465 info->image_info->endian=(EndianType) sp;
1466 for ( ; image; image=image->next)
1467 image->endian=(EndianType) sp;
1468 break;
1469 }
1470 if (LocaleCompare(attribute,"extract") == 0)
1471 {
1472 /*
1473 Set image extract geometry.
1474 */
1475 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1476 break;
1477 }
1478 if (info)
1479 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1480 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001481 {
1482 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001483 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001484 }
cristy4a3ce0a2013-08-03 20:06:59 +00001485 break;
1486 }
1487 case 'F':
1488 case 'f':
1489 {
1490 if (LocaleCompare(attribute,"filename") == 0)
1491 {
1492 if (info)
1493 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001494 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001495 for ( ; image; image=image->next)
1496 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001497 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001498 break;
1499 }
1500 if (LocaleCompare(attribute,"file") == 0)
1501 {
1502 FILE
1503 *file;
1504
1505 PerlIO
1506 *io_info;
1507
1508 if (info == (struct PackageInfo *) NULL)
1509 break;
1510 io_info=IoIFP(sv_2io(sval));
1511 if (io_info == (PerlIO *) NULL)
1512 {
1513 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1514 PackageName);
1515 break;
1516 }
1517 file=PerlIO_findFILE(io_info);
1518 if (file == (FILE *) NULL)
1519 {
1520 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1521 PackageName);
1522 break;
1523 }
1524 SetImageInfoFile(info->image_info,file);
1525 break;
1526 }
1527 if (LocaleCompare(attribute,"fill") == 0)
1528 {
1529 if (info)
1530 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1531 break;
1532 }
1533 if (LocaleCompare(attribute,"font") == 0)
1534 {
1535 if (info)
1536 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1537 break;
1538 }
1539 if (LocaleCompare(attribute,"foreground") == 0)
1540 break;
1541 if (LocaleCompare(attribute,"fuzz") == 0)
1542 {
1543 if (info)
1544 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1545 QuantumRange+1.0);
1546 for ( ; image; image=image->next)
1547 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1548 QuantumRange+1.0);
1549 break;
1550 }
1551 if (info)
1552 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1553 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001554 {
1555 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001556 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001557 }
cristy4a3ce0a2013-08-03 20:06:59 +00001558 break;
1559 }
1560 case 'G':
1561 case 'g':
1562 {
1563 if (LocaleCompare(attribute,"gamma") == 0)
1564 {
1565 for ( ; image; image=image->next)
1566 image->gamma=SvNV(sval);
1567 break;
1568 }
1569 if (LocaleCompare(attribute,"gravity") == 0)
1570 {
1571 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1572 SvPV(sval,na)) : SvIV(sval);
1573 if (sp < 0)
1574 {
1575 ThrowPerlException(exception,OptionError,
1576 "UnrecognizedGravityType",SvPV(sval,na));
1577 break;
1578 }
1579 if (info)
1580 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1581 for ( ; image; image=image->next)
1582 image->gravity=(GravityType) sp;
1583 break;
1584 }
1585 if (LocaleCompare(attribute,"green-primary") == 0)
1586 {
1587 for ( ; image; image=image->next)
1588 {
1589 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1590 image->chromaticity.green_primary.x=geometry_info.rho;
1591 image->chromaticity.green_primary.y=geometry_info.sigma;
1592 if ((flags & SigmaValue) == 0)
1593 image->chromaticity.green_primary.y=
1594 image->chromaticity.green_primary.x;
1595 }
1596 break;
1597 }
1598 if (info)
1599 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1600 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001601 {
1602 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001603 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001604 }
cristy4a3ce0a2013-08-03 20:06:59 +00001605 break;
1606 }
1607 case 'I':
1608 case 'i':
1609 {
1610 if (LocaleNCompare(attribute,"index",5) == 0)
1611 {
1612 int
1613 items;
1614
1615 long
1616 index;
1617
1618 register Quantum
1619 *q;
1620
1621 CacheView
1622 *image_view;
1623
1624 for ( ; image; image=image->next)
1625 {
1626 if (image->storage_class != PseudoClass)
1627 continue;
1628 x=0;
1629 y=0;
1630 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1631 (void) items;
1632 image_view=AcquireAuthenticCacheView(image,exception);
1633 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1634 if (q != (Quantum *) NULL)
1635 {
1636 items=sscanf(SvPV(sval,na),"%ld",&index);
1637 if ((index >= 0) && (index < (ssize_t) image->colors))
1638 SetPixelIndex(image,index,q);
1639 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1640 }
1641 image_view=DestroyCacheView(image_view);
1642 }
1643 break;
1644 }
1645 if (LocaleCompare(attribute,"iterations") == 0)
1646 {
1647 iterations:
1648 for ( ; image; image=image->next)
1649 image->iterations=SvIV(sval);
1650 break;
1651 }
1652 if (LocaleCompare(attribute,"interlace") == 0)
1653 {
1654 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1655 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1656 if (sp < 0)
1657 {
1658 ThrowPerlException(exception,OptionError,
1659 "UnrecognizedInterlaceType",SvPV(sval,na));
1660 break;
1661 }
1662 if (info)
1663 info->image_info->interlace=(InterlaceType) sp;
1664 for ( ; image; image=image->next)
1665 image->interlace=(InterlaceType) sp;
1666 break;
1667 }
1668 if (info)
1669 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1670 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001671 {
1672 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001673 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001674 }
cristy4a3ce0a2013-08-03 20:06:59 +00001675 break;
1676 }
1677 case 'L':
1678 case 'l':
1679 {
1680 if (LocaleCompare(attribute,"label") == 0)
1681 {
1682 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001683 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001684 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001685 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001686 break;
1687 }
1688 if (LocaleCompare(attribute,"loop") == 0)
1689 goto iterations;
1690 if (info)
1691 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1692 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001693 {
1694 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001695 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001696 }
cristy4a3ce0a2013-08-03 20:06:59 +00001697 break;
1698 }
1699 case 'M':
1700 case 'm':
1701 {
1702 if (LocaleCompare(attribute,"magick") == 0)
1703 {
1704 if (info)
Cristyb5b1f5d2017-03-31 16:42:35 -04001705 (void) FormatLocaleString(info->image_info->filename,
1706 MagickPathExtent,"%s:",SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001707 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001708 (void) CopyMagickString(image->magick,SvPV(sval,na),
1709 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001710 break;
1711 }
1712 if (LocaleCompare(attribute,"map-limit") == 0)
1713 {
1714 MagickSizeType
1715 limit;
1716
1717 limit=MagickResourceInfinity;
1718 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1719 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1720 100.0);
1721 (void) SetMagickResourceLimit(MapResource,limit);
1722 break;
1723 }
1724 if (LocaleCompare(attribute,"mask") == 0)
1725 {
1726 Image
1727 *mask;
1728
1729 mask=(Image *) NULL;
1730 if (SvPOK(sval))
1731 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1732 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001733 SetImageMask(image,ReadPixelMask,mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001734 break;
1735 }
1736 if (LocaleCompare(attribute,"mattecolor") == 0)
1737 {
1738 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1739 exception);
1740 if (info)
Cristy8645e042016-02-03 16:35:29 -05001741 info->image_info->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001742 for ( ; image; image=image->next)
Cristy8645e042016-02-03 16:35:29 -05001743 image->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001744 break;
1745 }
1746 if (LocaleCompare(attribute,"matte") == 0)
1747 {
1748 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1749 SvPV(sval,na)) : SvIV(sval);
1750 if (sp < 0)
1751 {
1752 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1753 SvPV(sval,na));
1754 break;
1755 }
1756 for ( ; image; image=image->next)
1757 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1758 break;
1759 }
1760 if (LocaleCompare(attribute,"memory-limit") == 0)
1761 {
1762 MagickSizeType
1763 limit;
1764
1765 limit=MagickResourceInfinity;
1766 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1767 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1768 100.0);
1769 (void) SetMagickResourceLimit(MemoryResource,limit);
1770 break;
1771 }
1772 if (LocaleCompare(attribute,"monochrome") == 0)
1773 {
1774 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1775 SvPV(sval,na)) : SvIV(sval);
1776 if (sp < 0)
1777 {
1778 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1779 SvPV(sval,na));
1780 break;
1781 }
1782 if (info)
1783 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1784 for ( ; image; image=image->next)
1785 (void) SetImageType(image,BilevelType,exception);
1786 break;
1787 }
1788 if (info)
1789 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1790 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001791 {
1792 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001793 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001794 }
cristy4a3ce0a2013-08-03 20:06:59 +00001795 break;
1796 }
1797 case 'O':
1798 case 'o':
1799 {
1800 if (LocaleCompare(attribute,"option") == 0)
1801 {
1802 if (info)
1803 DefineImageOption(info->image_info,SvPV(sval,na));
1804 break;
1805 }
1806 if (LocaleCompare(attribute,"orientation") == 0)
1807 {
1808 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1809 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1810 if (sp < 0)
1811 {
1812 ThrowPerlException(exception,OptionError,
1813 "UnrecognizedOrientationType",SvPV(sval,na));
1814 break;
1815 }
1816 if (info)
1817 info->image_info->orientation=(OrientationType) sp;
1818 for ( ; image; image=image->next)
1819 image->orientation=(OrientationType) sp;
1820 break;
1821 }
1822 if (info)
1823 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1824 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001825 {
1826 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001827 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001828 }
cristy4a3ce0a2013-08-03 20:06:59 +00001829 break;
1830 }
1831 case 'P':
1832 case 'p':
1833 {
1834 if (LocaleCompare(attribute,"page") == 0)
1835 {
1836 char
1837 *geometry;
1838
1839 geometry=GetPageGeometry(SvPV(sval,na));
1840 if (info)
1841 (void) CloneString(&info->image_info->page,geometry);
1842 for ( ; image; image=image->next)
1843 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1844 geometry=(char *) RelinquishMagickMemory(geometry);
1845 break;
1846 }
1847 if (LocaleNCompare(attribute,"pixel",5) == 0)
1848 {
1849 int
1850 items;
1851
1852 PixelInfo
1853 pixel;
1854
1855 register Quantum
1856 *q;
1857
1858 CacheView
1859 *image_view;
1860
1861 for ( ; image; image=image->next)
1862 {
1863 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1864 break;
1865 x=0;
1866 y=0;
1867 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1868 (void) items;
1869 image_view=AcquireVirtualCacheView(image,exception);
1870 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1871 if (q != (Quantum *) NULL)
1872 {
1873 if ((strchr(SvPV(sval,na),',') == 0) ||
1874 (strchr(SvPV(sval,na),')') != 0))
1875 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1876 &pixel,exception);
1877 else
1878 {
1879 GetPixelInfo(image,&pixel);
1880 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1881 pixel.red=geometry_info.rho;
1882 if ((flags & SigmaValue) != 0)
1883 pixel.green=geometry_info.sigma;
1884 if ((flags & XiValue) != 0)
1885 pixel.blue=geometry_info.xi;
1886 if ((flags & PsiValue) != 0)
1887 pixel.alpha=geometry_info.psi;
1888 if ((flags & ChiValue) != 0)
1889 pixel.black=geometry_info.chi;
1890 }
1891 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1892 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1893 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1894 if (image->colorspace == CMYKColorspace)
1895 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1896 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1897 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1898 }
1899 image_view=DestroyCacheView(image_view);
1900 }
1901 break;
1902 }
1903 if (LocaleCompare(attribute,"pointsize") == 0)
1904 {
1905 if (info)
1906 {
1907 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1908 info->image_info->pointsize=geometry_info.rho;
1909 }
1910 break;
1911 }
cristy4a3ce0a2013-08-03 20:06:59 +00001912 if (info)
1913 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1914 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001915 {
1916 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001917 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001918 }
cristy4a3ce0a2013-08-03 20:06:59 +00001919 break;
1920 }
1921 case 'Q':
1922 case 'q':
1923 {
1924 if (LocaleCompare(attribute,"quality") == 0)
1925 {
1926 if (info)
1927 info->image_info->quality=SvIV(sval);
1928 for ( ; image; image=image->next)
1929 image->quality=SvIV(sval);
1930 break;
1931 }
1932 if (info)
1933 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1934 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001935 {
1936 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001937 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001938 }
cristy4a3ce0a2013-08-03 20:06:59 +00001939 break;
1940 }
1941 case 'R':
1942 case 'r':
1943 {
cristyc0fe4752015-07-27 18:02:39 +00001944 if (LocaleCompare(attribute,"read-mask") == 0)
1945 {
1946 Image
1947 *mask;
1948
1949 mask=(Image *) NULL;
1950 if (SvPOK(sval))
1951 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1952 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001953 SetImageMask(image,ReadPixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00001954 break;
1955 }
cristy4a3ce0a2013-08-03 20:06:59 +00001956 if (LocaleCompare(attribute,"red-primary") == 0)
1957 {
1958 for ( ; image; image=image->next)
1959 {
1960 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1961 image->chromaticity.red_primary.x=geometry_info.rho;
1962 image->chromaticity.red_primary.y=geometry_info.sigma;
1963 if ((flags & SigmaValue) == 0)
1964 image->chromaticity.red_primary.y=
1965 image->chromaticity.red_primary.x;
1966 }
1967 break;
1968 }
1969 if (LocaleCompare(attribute,"render") == 0)
1970 {
1971 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1972 SvPV(sval,na)) : SvIV(sval);
1973 if (sp < 0)
1974 {
1975 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1976 SvPV(sval,na));
1977 break;
1978 }
1979 for ( ; image; image=image->next)
1980 image->rendering_intent=(RenderingIntent) sp;
1981 break;
1982 }
1983 if (LocaleCompare(attribute,"repage") == 0)
1984 {
1985 RectangleInfo
1986 geometry;
1987
1988 for ( ; image; image=image->next)
1989 {
1990 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1991 if ((flags & WidthValue) != 0)
1992 {
1993 if ((flags & HeightValue) == 0)
1994 geometry.height=geometry.width;
1995 image->page.width=geometry.width;
1996 image->page.height=geometry.height;
1997 }
1998 if ((flags & AspectValue) != 0)
1999 {
2000 if ((flags & XValue) != 0)
2001 image->page.x+=geometry.x;
2002 if ((flags & YValue) != 0)
2003 image->page.y+=geometry.y;
2004 }
2005 else
2006 {
2007 if ((flags & XValue) != 0)
2008 {
2009 image->page.x=geometry.x;
2010 if (((flags & WidthValue) != 0) && (geometry.x > 0))
2011 image->page.width=image->columns+geometry.x;
2012 }
2013 if ((flags & YValue) != 0)
2014 {
2015 image->page.y=geometry.y;
2016 if (((flags & HeightValue) != 0) && (geometry.y > 0))
2017 image->page.height=image->rows+geometry.y;
2018 }
2019 }
2020 }
2021 break;
2022 }
2023 if (info)
2024 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2025 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002026 {
2027 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002028 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002029 }
cristy4a3ce0a2013-08-03 20:06:59 +00002030 break;
2031 }
2032 case 'S':
2033 case 's':
2034 {
2035 if (LocaleCompare(attribute,"sampling-factor") == 0)
2036 {
2037 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2038 {
2039 ThrowPerlException(exception,OptionError,"MissingGeometry",
2040 SvPV(sval,na));
2041 break;
2042 }
2043 if (info)
2044 (void) CloneString(&info->image_info->sampling_factor,
2045 SvPV(sval,na));
2046 break;
2047 }
2048 if (LocaleCompare(attribute,"scene") == 0)
2049 {
2050 for ( ; image; image=image->next)
2051 image->scene=SvIV(sval);
2052 break;
2053 }
2054 if (LocaleCompare(attribute,"server") == 0)
2055 goto display;
2056 if (LocaleCompare(attribute,"size") == 0)
2057 {
2058 if (info)
2059 {
2060 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2061 {
2062 ThrowPerlException(exception,OptionError,"MissingGeometry",
2063 SvPV(sval,na));
2064 break;
2065 }
2066 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2067 }
2068 break;
2069 }
2070 if (LocaleCompare(attribute,"stroke") == 0)
2071 {
2072 if (info)
2073 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2074 break;
2075 }
2076 if (info)
2077 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2078 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002079 {
2080 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002081 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002082 }
cristy4a3ce0a2013-08-03 20:06:59 +00002083 break;
2084 }
2085 case 'T':
2086 case 't':
2087 {
2088 if (LocaleCompare(attribute,"texture") == 0)
2089 {
2090 if (info)
2091 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2092 break;
2093 }
2094 if (LocaleCompare(attribute,"thread-limit") == 0)
2095 {
2096 MagickSizeType
2097 limit;
2098
2099 limit=MagickResourceInfinity;
2100 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2101 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2102 100.0);
2103 (void) SetMagickResourceLimit(ThreadResource,limit);
2104 break;
2105 }
2106 if (LocaleCompare(attribute,"tile-offset") == 0)
2107 {
2108 char
2109 *geometry;
2110
2111 geometry=GetPageGeometry(SvPV(sval,na));
2112 if (info)
2113 (void) CloneString(&info->image_info->page,geometry);
2114 for ( ; image; image=image->next)
2115 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2116 exception);
2117 geometry=(char *) RelinquishMagickMemory(geometry);
2118 break;
2119 }
2120 if (LocaleCompare(attribute,"time-limit") == 0)
2121 {
2122 MagickSizeType
2123 limit;
2124
2125 limit=MagickResourceInfinity;
2126 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2127 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2128 100.0);
2129 (void) SetMagickResourceLimit(TimeResource,limit);
2130 break;
2131 }
2132 if (LocaleCompare(attribute,"transparent-color") == 0)
2133 {
2134 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2135 exception);
2136 if (info)
2137 info->image_info->transparent_color=target_color;
2138 for ( ; image; image=image->next)
2139 image->transparent_color=target_color;
2140 break;
2141 }
2142 if (LocaleCompare(attribute,"type") == 0)
2143 {
2144 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2145 SvPV(sval,na)) : SvIV(sval);
2146 if (sp < 0)
2147 {
2148 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2149 SvPV(sval,na));
2150 break;
2151 }
2152 if (info)
2153 info->image_info->type=(ImageType) sp;
2154 for ( ; image; image=image->next)
2155 SetImageType(image,(ImageType) sp,exception);
2156 break;
2157 }
2158 if (info)
2159 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2160 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002161 {
2162 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002163 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002164 }
cristy4a3ce0a2013-08-03 20:06:59 +00002165 break;
2166 }
2167 case 'U':
2168 case 'u':
2169 {
2170 if (LocaleCompare(attribute,"units") == 0)
2171 {
2172 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2173 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2174 if (sp < 0)
2175 {
2176 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2177 SvPV(sval,na));
2178 break;
2179 }
2180 if (info)
2181 info->image_info->units=(ResolutionType) sp;
2182 for ( ; image; image=image->next)
2183 {
2184 ResolutionType
2185 units;
2186
2187 units=(ResolutionType) sp;
2188 if (image->units != units)
2189 switch (image->units)
2190 {
2191 case UndefinedResolution:
2192 case PixelsPerInchResolution:
2193 {
2194 if (units == PixelsPerCentimeterResolution)
2195 {
2196 image->resolution.x*=2.54;
2197 image->resolution.y*=2.54;
2198 }
2199 break;
2200 }
2201 case PixelsPerCentimeterResolution:
2202 {
2203 if (units == PixelsPerInchResolution)
2204 {
2205 image->resolution.x/=2.54;
2206 image->resolution.y/=2.54;
2207 }
2208 break;
2209 }
2210 }
2211 image->units=units;
2212 }
2213 break;
2214 }
2215 if (info)
2216 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2217 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002218 {
2219 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002220 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002221 }
cristy4a3ce0a2013-08-03 20:06:59 +00002222 break;
2223 }
2224 case 'V':
2225 case 'v':
2226 {
2227 if (LocaleCompare(attribute,"verbose") == 0)
2228 {
2229 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2230 SvPV(sval,na)) : SvIV(sval);
2231 if (sp < 0)
2232 {
2233 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2234 SvPV(sval,na));
2235 break;
2236 }
2237 if (info)
2238 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2239 break;
2240 }
cristy4a3ce0a2013-08-03 20:06:59 +00002241 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2242 {
2243 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2244 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2245 if (sp < 0)
2246 {
2247 ThrowPerlException(exception,OptionError,
2248 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2249 break;
2250 }
2251 for ( ; image; image=image->next)
2252 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2253 break;
2254 }
2255 if (info)
2256 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2257 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002258 {
2259 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002260 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002261 }
cristy4a3ce0a2013-08-03 20:06:59 +00002262 break;
2263 }
2264 case 'W':
2265 case 'w':
2266 {
2267 if (LocaleCompare(attribute,"white-point") == 0)
2268 {
2269 for ( ; image; image=image->next)
2270 {
2271 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2272 image->chromaticity.white_point.x=geometry_info.rho;
2273 image->chromaticity.white_point.y=geometry_info.sigma;
2274 if ((flags & SigmaValue) == 0)
2275 image->chromaticity.white_point.y=
2276 image->chromaticity.white_point.x;
2277 }
2278 break;
2279 }
cristyc0fe4752015-07-27 18:02:39 +00002280 if (LocaleCompare(attribute,"write-mask") == 0)
2281 {
2282 Image
2283 *mask;
2284
2285 mask=(Image *) NULL;
2286 if (SvPOK(sval))
2287 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2288 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002289 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002290 break;
2291 }
cristy4a3ce0a2013-08-03 20:06:59 +00002292 if (info)
2293 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2294 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002295 {
2296 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002297 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002298 }
cristy4a3ce0a2013-08-03 20:06:59 +00002299 break;
2300 }
2301 default:
2302 {
2303 if (info)
2304 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2305 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002306 {
2307 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002308 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002309 }
cristy4a3ce0a2013-08-03 20:06:59 +00002310 break;
2311 }
2312 }
2313}
2314
2315/*
2316%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2317% %
2318% %
2319% %
2320% S e t u p L i s t %
2321% %
2322% %
2323% %
2324%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2325%
2326% Method SetupList returns the list of all the images linked by their
2327% image->next and image->previous link lists for use with ImageMagick. If
2328% info is non-NULL, an info structure is returned in *info. If
2329% reference_vector is non-NULL,an array of SV* are returned in
2330% *reference_vector. Reference_vector is used when the images are going to be
2331% replaced with new Image*'s.
2332%
2333% The format of the SetupList routine is:
2334%
2335% Image *SetupList(SV *reference,struct PackageInfo **info,
2336% SV ***reference_vector,ExceptionInfo *exception)
2337%
2338% A description of each parameter follows:
2339%
2340% o list: a list of strings.
2341%
2342% o string: a character string.
2343%
2344% o exception: Return any errors or warnings in this structure.
2345%
2346*/
2347static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2348 SV ***reference_vector,ExceptionInfo *exception)
2349{
2350 Image
2351 *image;
2352
2353 ssize_t
2354 current,
2355 last;
2356
2357 if (reference_vector)
2358 *reference_vector=NULL;
2359 if (info)
2360 *info=NULL;
2361 current=0;
2362 last=0;
2363 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2364 if (info && (SvTYPE(reference) == SVt_PVAV))
2365 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2366 exception);
2367 return(image);
2368}
2369
2370/*
2371%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2372% %
2373% %
2374% %
2375% s t r E Q c a s e %
2376% %
2377% %
2378% %
2379%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2380%
2381% strEQcase() compares two strings and returns 0 if they are the
2382% same or if the second string runs out first. The comparison is case
2383% insensitive.
2384%
2385% The format of the strEQcase routine is:
2386%
2387% ssize_t strEQcase(const char *p,const char *q)
2388%
2389% A description of each parameter follows:
2390%
2391% o p: a character string.
2392%
2393% o q: a character string.
2394%
2395%
2396*/
2397static ssize_t strEQcase(const char *p,const char *q)
2398{
2399 char
2400 c;
2401
2402 register ssize_t
2403 i;
2404
2405 for (i=0 ; (c=(*q)) != 0; i++)
2406 {
2407 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2408 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2409 return(0);
2410 p++;
2411 q++;
2412 }
2413 return(((*q == 0) && (*p == 0)) ? i : 0);
2414}
2415
2416/*
2417%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2418% %
2419% %
2420% %
2421% I m a g e : : M a g i c k %
2422% %
2423% %
2424% %
2425%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2426%
2427%
2428*/
2429MODULE = Image::Magick PACKAGE = Image::Magick
2430
2431PROTOTYPES: ENABLE
2432
2433BOOT:
2434 MagickCoreGenesis("PerlMagick",MagickFalse);
2435 SetWarningHandler(NULL);
2436 SetErrorHandler(NULL);
2437 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2438 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2439
2440void
2441UNLOAD()
2442 PPCODE:
2443 {
2444 if (magick_registry != (SplayTreeInfo *) NULL)
2445 magick_registry=DestroySplayTree(magick_registry);
2446 MagickCoreTerminus();
2447 }
2448
2449double
2450constant(name,argument)
2451 char *name
2452 ssize_t argument
2453
2454#
2455###############################################################################
2456# #
2457# #
2458# #
2459# A n i m a t e #
2460# #
2461# #
2462# #
2463###############################################################################
2464#
2465#
2466void
2467Animate(ref,...)
2468 Image::Magick ref=NO_INIT
2469 ALIAS:
2470 AnimateImage = 1
2471 animate = 2
2472 animateimage = 3
2473 PPCODE:
2474 {
2475 ExceptionInfo
2476 *exception;
2477
2478 Image
2479 *image;
2480
2481 register ssize_t
2482 i;
2483
2484 struct PackageInfo
2485 *info,
2486 *package_info;
2487
2488 SV
2489 *perl_exception,
2490 *reference;
2491
2492 PERL_UNUSED_VAR(ref);
2493 PERL_UNUSED_VAR(ix);
2494 exception=AcquireExceptionInfo();
2495 perl_exception=newSVpv("",0);
2496 package_info=(struct PackageInfo *) NULL;
2497 if (sv_isobject(ST(0)) == 0)
2498 {
2499 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2500 PackageName);
2501 goto PerlException;
2502 }
2503 reference=SvRV(ST(0));
2504 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2505 if (image == (Image *) NULL)
2506 {
2507 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2508 PackageName);
2509 goto PerlException;
2510 }
2511 package_info=ClonePackageInfo(info,exception);
2512 if (items == 2)
2513 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2514 else
2515 if (items > 2)
2516 for (i=2; i < items; i+=2)
2517 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2518 exception);
2519 (void) AnimateImages(package_info->image_info,image,exception);
2520 (void) CatchImageException(image);
2521
2522 PerlException:
2523 if (package_info != (struct PackageInfo *) NULL)
2524 DestroyPackageInfo(package_info);
2525 InheritPerlException(exception,perl_exception);
2526 exception=DestroyExceptionInfo(exception);
2527 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2528 SvPOK_on(perl_exception);
2529 ST(0)=sv_2mortal(perl_exception);
2530 XSRETURN(1);
2531 }
2532
2533#
2534###############################################################################
2535# #
2536# #
2537# #
2538# A p p e n d #
2539# #
2540# #
2541# #
2542###############################################################################
2543#
2544#
2545void
2546Append(ref,...)
2547 Image::Magick ref=NO_INIT
2548 ALIAS:
2549 AppendImage = 1
2550 append = 2
2551 appendimage = 3
2552 PPCODE:
2553 {
2554 AV
2555 *av;
2556
2557 char
2558 *attribute;
2559
2560 ExceptionInfo
2561 *exception;
2562
2563 HV
2564 *hv;
2565
2566 Image
2567 *image;
2568
2569 register ssize_t
2570 i;
2571
2572 ssize_t
2573 stack;
2574
2575 struct PackageInfo
2576 *info;
2577
2578 SV
2579 *av_reference,
2580 *perl_exception,
2581 *reference,
2582 *rv,
2583 *sv;
2584
2585 PERL_UNUSED_VAR(ref);
2586 PERL_UNUSED_VAR(ix);
2587 exception=AcquireExceptionInfo();
2588 perl_exception=newSVpv("",0);
2589 sv=NULL;
2590 attribute=NULL;
2591 av=NULL;
2592 if (sv_isobject(ST(0)) == 0)
2593 {
2594 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2595 PackageName);
2596 goto PerlException;
2597 }
2598 reference=SvRV(ST(0));
2599 hv=SvSTASH(reference);
2600 av=newAV();
2601 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2602 SvREFCNT_dec(av);
2603 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2604 if (image == (Image *) NULL)
2605 {
2606 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2607 PackageName);
2608 goto PerlException;
2609 }
2610 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2611 /*
2612 Get options.
2613 */
2614 stack=MagickTrue;
2615 for (i=2; i < items; i+=2)
2616 {
2617 attribute=(char *) SvPV(ST(i-1),na);
2618 switch (*attribute)
2619 {
2620 case 'S':
2621 case 's':
2622 {
2623 if (LocaleCompare(attribute,"stack") == 0)
2624 {
2625 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2626 SvPV(ST(i),na));
2627 if (stack < 0)
2628 {
2629 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2630 SvPV(ST(i),na));
2631 return;
2632 }
2633 break;
2634 }
2635 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2636 attribute);
2637 break;
2638 }
2639 default:
2640 {
2641 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2642 attribute);
2643 break;
2644 }
2645 }
2646 }
2647 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2648 if (image == (Image *) NULL)
2649 goto PerlException;
2650 for ( ; image; image=image->next)
2651 {
2652 AddImageToRegistry(sv,image);
2653 rv=newRV(sv);
2654 av_push(av,sv_bless(rv,hv));
2655 SvREFCNT_dec(sv);
2656 }
2657 exception=DestroyExceptionInfo(exception);
2658 ST(0)=av_reference;
2659 SvREFCNT_dec(perl_exception);
2660 XSRETURN(1);
2661
2662 PerlException:
2663 InheritPerlException(exception,perl_exception);
2664 exception=DestroyExceptionInfo(exception);
2665 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2666 SvPOK_on(perl_exception);
2667 ST(0)=sv_2mortal(perl_exception);
2668 XSRETURN(1);
2669 }
2670
2671#
2672###############################################################################
2673# #
2674# #
2675# #
2676# A v e r a g e #
2677# #
2678# #
2679# #
2680###############################################################################
2681#
2682#
2683void
2684Average(ref)
2685 Image::Magick ref=NO_INIT
2686 ALIAS:
2687 AverageImage = 1
2688 average = 2
2689 averageimage = 3
2690 PPCODE:
2691 {
2692 AV
2693 *av;
2694
2695 char
2696 *p;
2697
2698 ExceptionInfo
2699 *exception;
2700
2701 HV
2702 *hv;
2703
2704 Image
2705 *image;
2706
2707 struct PackageInfo
2708 *info;
2709
2710 SV
2711 *perl_exception,
2712 *reference,
2713 *rv,
2714 *sv;
2715
2716 PERL_UNUSED_VAR(ref);
2717 PERL_UNUSED_VAR(ix);
2718 exception=AcquireExceptionInfo();
2719 perl_exception=newSVpv("",0);
2720 sv=NULL;
2721 if (sv_isobject(ST(0)) == 0)
2722 {
2723 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2724 PackageName);
2725 goto PerlException;
2726 }
2727 reference=SvRV(ST(0));
2728 hv=SvSTASH(reference);
2729 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2730 if (image == (Image *) NULL)
2731 {
2732 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2733 PackageName);
2734 goto PerlException;
2735 }
2736 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2737 if (image == (Image *) NULL)
2738 goto PerlException;
2739 /*
2740 Create blessed Perl array for the returned image.
2741 */
2742 av=newAV();
2743 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2744 SvREFCNT_dec(av);
2745 AddImageToRegistry(sv,image);
2746 rv=newRV(sv);
2747 av_push(av,sv_bless(rv,hv));
2748 SvREFCNT_dec(sv);
2749 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002750 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2751 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002752 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2753 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002754 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002755 SetImageInfo(info->image_info,0,exception);
2756 exception=DestroyExceptionInfo(exception);
2757 SvREFCNT_dec(perl_exception);
2758 XSRETURN(1);
2759
2760 PerlException:
2761 InheritPerlException(exception,perl_exception);
2762 exception=DestroyExceptionInfo(exception);
2763 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2764 SvPOK_on(perl_exception);
2765 ST(0)=sv_2mortal(perl_exception);
2766 XSRETURN(1);
2767 }
2768
2769#
2770###############################################################################
2771# #
2772# #
2773# #
2774# B l o b T o I m a g e #
2775# #
2776# #
2777# #
2778###############################################################################
2779#
2780#
2781void
2782BlobToImage(ref,...)
2783 Image::Magick ref=NO_INIT
2784 ALIAS:
2785 BlobToImage = 1
2786 blobtoimage = 2
2787 blobto = 3
2788 PPCODE:
2789 {
2790 AV
2791 *av;
2792
2793 char
2794 **keep,
2795 **list;
2796
2797 ExceptionInfo
2798 *exception;
2799
2800 HV
2801 *hv;
2802
2803 Image
2804 *image;
2805
2806 register char
2807 **p;
2808
2809 register ssize_t
2810 i;
2811
2812 ssize_t
2813 ac,
2814 n,
2815 number_images;
2816
2817 STRLEN
2818 *length;
2819
2820 struct PackageInfo
2821 *info;
2822
2823 SV
2824 *perl_exception,
2825 *reference,
2826 *rv,
2827 *sv;
2828
2829 PERL_UNUSED_VAR(ref);
2830 PERL_UNUSED_VAR(ix);
2831 exception=AcquireExceptionInfo();
2832 perl_exception=newSVpv("",0);
2833 sv=NULL;
2834 number_images=0;
2835 ac=(items < 2) ? 1 : items-1;
2836 length=(STRLEN *) NULL;
2837 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2838 if (list == (char **) NULL)
2839 {
2840 ThrowPerlException(exception,ResourceLimitError,
2841 "MemoryAllocationFailed",PackageName);
2842 goto PerlException;
2843 }
2844 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2845 if (length == (STRLEN *) NULL)
2846 {
2847 ThrowPerlException(exception,ResourceLimitError,
2848 "MemoryAllocationFailed",PackageName);
2849 goto PerlException;
2850 }
2851 if (sv_isobject(ST(0)) == 0)
2852 {
2853 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2854 PackageName);
2855 goto PerlException;
2856 }
2857 reference=SvRV(ST(0));
2858 hv=SvSTASH(reference);
2859 if (SvTYPE(reference) != SVt_PVAV)
2860 {
2861 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2862 PackageName);
2863 goto PerlException;
2864 }
2865 av=(AV *) reference;
2866 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2867 exception);
2868 n=1;
2869 if (items <= 1)
2870 {
2871 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2872 goto PerlException;
2873 }
2874 for (n=0, i=0; i < ac; i++)
2875 {
2876 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2877 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2878 {
2879 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2880 continue;
2881 }
2882 n++;
2883 }
2884 list[n]=(char *) NULL;
2885 keep=list;
2886 for (i=number_images=0; i < n; i++)
2887 {
2888 image=BlobToImage(info->image_info,list[i],length[i],exception);
2889 if (image == (Image *) NULL)
2890 break;
2891 for ( ; image; image=image->next)
2892 {
2893 AddImageToRegistry(sv,image);
2894 rv=newRV(sv);
2895 av_push(av,sv_bless(rv,hv));
2896 SvREFCNT_dec(sv);
2897 number_images++;
2898 }
2899 }
2900 /*
2901 Free resources.
2902 */
2903 for (i=0; i < n; i++)
2904 if (list[i] != (char *) NULL)
2905 for (p=keep; list[i] != *p++; )
2906 if (*p == (char *) NULL)
2907 {
2908 list[i]=(char *) RelinquishMagickMemory(list[i]);
2909 break;
2910 }
2911
2912 PerlException:
2913 if (list)
2914 list=(char **) RelinquishMagickMemory(list);
2915 if (length)
2916 length=(STRLEN *) RelinquishMagickMemory(length);
2917 InheritPerlException(exception,perl_exception);
2918 exception=DestroyExceptionInfo(exception);
2919 sv_setiv(perl_exception,(IV) number_images);
2920 SvPOK_on(perl_exception);
2921 ST(0)=sv_2mortal(perl_exception);
2922 XSRETURN(1);
2923 }
2924
2925#
2926###############################################################################
2927# #
2928# #
2929# #
2930# C h a n n e l F x #
2931# #
2932# #
2933# #
2934###############################################################################
2935#
2936#
2937void
2938ChannelFx(ref,...)
2939 Image::Magick ref=NO_INIT
2940 ALIAS:
2941 ChannelFxImage = 1
2942 channelfx = 2
2943 channelfximage = 3
2944 PPCODE:
2945 {
2946 AV
2947 *av;
2948
2949 char
2950 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002951 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002952
2953 ChannelType
2954 channel,
2955 channel_mask;
2956
2957 ExceptionInfo
2958 *exception;
2959
2960 HV
2961 *hv;
2962
2963 Image
2964 *image;
2965
2966 register ssize_t
2967 i;
2968
2969 struct PackageInfo
2970 *info;
2971
2972 SV
2973 *av_reference,
2974 *perl_exception,
2975 *reference,
2976 *rv,
2977 *sv;
2978
2979 PERL_UNUSED_VAR(ref);
2980 PERL_UNUSED_VAR(ix);
2981 exception=AcquireExceptionInfo();
2982 perl_exception=newSVpv("",0);
2983 sv=NULL;
2984 attribute=NULL;
2985 av=NULL;
2986 if (sv_isobject(ST(0)) == 0)
2987 {
2988 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2989 PackageName);
2990 goto PerlException;
2991 }
2992 reference=SvRV(ST(0));
2993 hv=SvSTASH(reference);
2994 av=newAV();
2995 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2996 SvREFCNT_dec(av);
2997 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2998 if (image == (Image *) NULL)
2999 {
3000 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3001 PackageName);
3002 goto PerlException;
3003 }
3004 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3005 /*
3006 Get options.
3007 */
3008 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00003009 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003010 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00003011 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003012 else
3013 for (i=2; i < items; i+=2)
3014 {
3015 attribute=(char *) SvPV(ST(i-1),na);
3016 switch (*attribute)
3017 {
3018 case 'C':
3019 case 'c':
3020 {
3021 if (LocaleCompare(attribute,"channel") == 0)
3022 {
3023 ssize_t
3024 option;
3025
3026 option=ParseChannelOption(SvPV(ST(i),na));
3027 if (option < 0)
3028 {
3029 ThrowPerlException(exception,OptionError,
3030 "UnrecognizedType",SvPV(ST(i),na));
3031 return;
3032 }
3033 channel=(ChannelType) option;
3034 break;
3035 }
3036 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3037 attribute);
3038 break;
3039 }
3040 case 'E':
3041 case 'e':
3042 {
3043 if (LocaleCompare(attribute,"expression") == 0)
3044 {
3045 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00003046 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003047 break;
3048 }
3049 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3050 attribute);
3051 break;
3052 }
3053 default:
3054 {
3055 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3056 attribute);
3057 break;
3058 }
3059 }
3060 }
3061 channel_mask=SetImageChannelMask(image,channel);
3062 image=ChannelFxImage(image,expression,exception);
3063 if (image != (Image *) NULL)
3064 (void) SetImageChannelMask(image,channel_mask);
3065 if (image == (Image *) NULL)
3066 goto PerlException;
3067 for ( ; image; image=image->next)
3068 {
3069 AddImageToRegistry(sv,image);
3070 rv=newRV(sv);
3071 av_push(av,sv_bless(rv,hv));
3072 SvREFCNT_dec(sv);
3073 }
3074 exception=DestroyExceptionInfo(exception);
3075 ST(0)=av_reference;
3076 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3077 XSRETURN(1);
3078
3079 PerlException:
3080 InheritPerlException(exception,perl_exception);
3081 exception=DestroyExceptionInfo(exception);
3082 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3083 SvPOK_on(perl_exception);
3084 ST(0)=sv_2mortal(perl_exception);
3085 XSRETURN(1);
3086 }
3087
3088#
3089###############################################################################
3090# #
3091# #
3092# #
3093# C l o n e #
3094# #
3095# #
3096# #
3097###############################################################################
3098#
3099#
3100void
3101Clone(ref)
3102 Image::Magick ref=NO_INIT
3103 ALIAS:
3104 CopyImage = 1
3105 copy = 2
3106 copyimage = 3
3107 CloneImage = 4
3108 clone = 5
3109 cloneimage = 6
3110 Clone = 7
3111 PPCODE:
3112 {
3113 AV
3114 *av;
3115
3116 ExceptionInfo
3117 *exception;
3118
3119 HV
3120 *hv;
3121
3122 Image
3123 *clone,
3124 *image;
3125
3126 struct PackageInfo
3127 *info;
3128
3129 SV
3130 *perl_exception,
3131 *reference,
3132 *rv,
3133 *sv;
3134
3135 PERL_UNUSED_VAR(ref);
3136 PERL_UNUSED_VAR(ix);
3137 exception=AcquireExceptionInfo();
3138 perl_exception=newSVpv("",0);
3139 sv=NULL;
3140 if (sv_isobject(ST(0)) == 0)
3141 {
3142 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3143 PackageName);
3144 goto PerlException;
3145 }
3146 reference=SvRV(ST(0));
3147 hv=SvSTASH(reference);
3148 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3149 if (image == (Image *) NULL)
3150 {
3151 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3152 PackageName);
3153 goto PerlException;
3154 }
3155 /*
3156 Create blessed Perl array for the returned image.
3157 */
3158 av=newAV();
3159 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3160 SvREFCNT_dec(av);
3161 for ( ; image; image=image->next)
3162 {
3163 clone=CloneImage(image,0,0,MagickTrue,exception);
3164 if (clone == (Image *) NULL)
3165 break;
3166 AddImageToRegistry(sv,clone);
3167 rv=newRV(sv);
3168 av_push(av,sv_bless(rv,hv));
3169 SvREFCNT_dec(sv);
3170 }
3171 exception=DestroyExceptionInfo(exception);
3172 SvREFCNT_dec(perl_exception);
3173 XSRETURN(1);
3174
3175 PerlException:
3176 InheritPerlException(exception,perl_exception);
3177 exception=DestroyExceptionInfo(exception);
3178 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3179 SvPOK_on(perl_exception);
3180 ST(0)=sv_2mortal(perl_exception);
3181 XSRETURN(1);
3182 }
3183
3184#
3185###############################################################################
3186# #
3187# #
3188# #
3189# C L O N E #
3190# #
3191# #
3192# #
3193###############################################################################
3194#
3195#
3196void
3197CLONE(ref,...)
3198 SV *ref;
3199 CODE:
3200 {
3201 PERL_UNUSED_VAR(ref);
3202 if (magick_registry != (SplayTreeInfo *) NULL)
3203 {
3204 register Image
3205 *p;
3206
3207 ResetSplayTreeIterator(magick_registry);
3208 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3209 while (p != (Image *) NULL)
3210 {
3211 ReferenceImage(p);
3212 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3213 }
3214 }
3215 }
3216
3217#
3218###############################################################################
3219# #
3220# #
3221# #
3222# C o a l e s c e #
3223# #
3224# #
3225# #
3226###############################################################################
3227#
3228#
3229void
3230Coalesce(ref)
3231 Image::Magick ref=NO_INIT
3232 ALIAS:
3233 CoalesceImage = 1
3234 coalesce = 2
3235 coalesceimage = 3
3236 PPCODE:
3237 {
3238 AV
3239 *av;
3240
3241 ExceptionInfo
3242 *exception;
3243
3244 HV
3245 *hv;
3246
3247 Image
3248 *image;
3249
3250 struct PackageInfo
3251 *info;
3252
3253 SV
3254 *av_reference,
3255 *perl_exception,
3256 *reference,
3257 *rv,
3258 *sv;
3259
3260 PERL_UNUSED_VAR(ref);
3261 PERL_UNUSED_VAR(ix);
3262 exception=AcquireExceptionInfo();
3263 perl_exception=newSVpv("",0);
3264 sv=NULL;
3265 if (sv_isobject(ST(0)) == 0)
3266 {
3267 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3268 PackageName);
3269 goto PerlException;
3270 }
3271 reference=SvRV(ST(0));
3272 hv=SvSTASH(reference);
3273 av=newAV();
3274 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3275 SvREFCNT_dec(av);
3276 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3277 if (image == (Image *) NULL)
3278 {
3279 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3280 PackageName);
3281 goto PerlException;
3282 }
3283 image=CoalesceImages(image,exception);
3284 if (image == (Image *) NULL)
3285 goto PerlException;
3286 for ( ; image; image=image->next)
3287 {
3288 AddImageToRegistry(sv,image);
3289 rv=newRV(sv);
3290 av_push(av,sv_bless(rv,hv));
3291 SvREFCNT_dec(sv);
3292 }
3293 exception=DestroyExceptionInfo(exception);
3294 ST(0)=av_reference;
3295 SvREFCNT_dec(perl_exception);
3296 XSRETURN(1);
3297
3298 PerlException:
3299 InheritPerlException(exception,perl_exception);
3300 exception=DestroyExceptionInfo(exception);
3301 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3302 SvPOK_on(perl_exception);
3303 ST(0)=sv_2mortal(perl_exception);
3304 XSRETURN(1);
3305 }
3306
3307#
3308###############################################################################
3309# #
3310# #
3311# #
3312# C o m p a r e #
3313# #
3314# #
3315# #
3316###############################################################################
3317#
3318#
3319void
3320Compare(ref,...)
3321 Image::Magick ref=NO_INIT
3322 ALIAS:
3323 CompareImages = 1
3324 compare = 2
3325 compareimage = 3
3326 PPCODE:
3327 {
3328 AV
3329 *av;
3330
3331 char
3332 *attribute;
3333
3334 double
3335 distortion;
3336
3337 ExceptionInfo
3338 *exception;
3339
3340 HV
3341 *hv;
3342
3343 Image
3344 *difference_image,
3345 *image,
3346 *reconstruct_image;
3347
3348 MetricType
3349 metric;
3350
3351 register ssize_t
3352 i;
3353
3354 ssize_t
3355 option;
3356
3357 struct PackageInfo
3358 *info;
3359
3360 SV
3361 *av_reference,
3362 *perl_exception,
3363 *reference,
3364 *rv,
3365 *sv;
3366
3367 PERL_UNUSED_VAR(ref);
3368 PERL_UNUSED_VAR(ix);
3369 exception=AcquireExceptionInfo();
3370 perl_exception=newSVpv("",0);
3371 sv=NULL;
3372 av=NULL;
3373 attribute=NULL;
3374 if (sv_isobject(ST(0)) == 0)
3375 {
3376 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3377 PackageName);
3378 goto PerlException;
3379 }
3380 reference=SvRV(ST(0));
3381 hv=SvSTASH(reference);
3382 av=newAV();
3383 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3384 SvREFCNT_dec(av);
3385 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3386 if (image == (Image *) NULL)
3387 {
3388 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3389 PackageName);
3390 goto PerlException;
3391 }
3392 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3393 /*
3394 Get attribute.
3395 */
3396 reconstruct_image=image;
3397 metric=RootMeanSquaredErrorMetric;
3398 for (i=2; i < items; i+=2)
3399 {
3400 attribute=(char *) SvPV(ST(i-1),na);
3401 switch (*attribute)
3402 {
3403 case 'C':
3404 case 'c':
3405 {
3406 if (LocaleCompare(attribute,"channel") == 0)
3407 {
3408 ssize_t
3409 option;
3410
3411 option=ParseChannelOption(SvPV(ST(i),na));
3412 if (option < 0)
3413 {
3414 ThrowPerlException(exception,OptionError,
3415 "UnrecognizedType",SvPV(ST(i),na));
3416 return;
3417 }
cristybcd59342015-06-07 14:07:19 +00003418 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003419 break;
3420 }
3421 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3422 attribute);
3423 break;
3424 }
3425 case 'F':
3426 case 'f':
3427 {
3428 if (LocaleCompare(attribute,"fuzz") == 0)
3429 {
3430 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3431 break;
3432 }
3433 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3434 attribute);
3435 break;
3436 }
3437 case 'I':
3438 case 'i':
3439 {
3440 if (LocaleCompare(attribute,"image") == 0)
3441 {
3442 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3443 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3444 break;
3445 }
3446 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3447 attribute);
3448 break;
3449 }
3450 case 'M':
3451 case 'm':
3452 {
3453 if (LocaleCompare(attribute,"metric") == 0)
3454 {
3455 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3456 SvPV(ST(i),na));
3457 if (option < 0)
3458 {
3459 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3460 SvPV(ST(i),na));
3461 break;
3462 }
3463 metric=(MetricType) option;
3464 break;
3465 }
3466 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3467 attribute);
3468 break;
3469 }
3470 default:
3471 {
3472 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3473 attribute);
3474 break;
3475 }
3476 }
3477 }
3478 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3479 exception);
3480 if (difference_image != (Image *) NULL)
3481 {
3482 difference_image->error.mean_error_per_pixel=distortion;
3483 AddImageToRegistry(sv,difference_image);
3484 rv=newRV(sv);
3485 av_push(av,sv_bless(rv,hv));
3486 SvREFCNT_dec(sv);
3487 }
3488 exception=DestroyExceptionInfo(exception);
3489 ST(0)=av_reference;
3490 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3491 XSRETURN(1);
3492
3493 PerlException:
3494 InheritPerlException(exception,perl_exception);
3495 exception=DestroyExceptionInfo(exception);
3496 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3497 SvPOK_on(perl_exception);
3498 ST(0)=sv_2mortal(perl_exception);
3499 XSRETURN(1);
3500 }
3501
3502#
3503###############################################################################
3504# #
3505# #
3506# #
cristy15655332013-10-06 00:27:33 +00003507# C o m p l e x I m a g e s #
3508# #
3509# #
3510# #
3511###############################################################################
3512#
3513#
3514void
3515ComplexImages(ref)
3516 Image::Magick ref=NO_INIT
3517 ALIAS:
3518 ComplexImages = 1
3519 compleximages = 2
3520 PPCODE:
3521 {
3522 AV
3523 *av;
3524
3525 char
3526 *attribute,
3527 *p;
3528
cristyfa21e9e2013-10-07 10:37:38 +00003529 ComplexOperator
3530 op;
3531
cristy15655332013-10-06 00:27:33 +00003532 ExceptionInfo
3533 *exception;
3534
3535 HV
3536 *hv;
3537
3538 Image
3539 *image;
3540
cristy15655332013-10-06 00:27:33 +00003541 register ssize_t
3542 i;
3543
3544 struct PackageInfo
3545 *info;
3546
3547 SV
3548 *perl_exception,
3549 *reference,
3550 *rv,
3551 *sv;
3552
3553 PERL_UNUSED_VAR(ref);
3554 PERL_UNUSED_VAR(ix);
3555 exception=AcquireExceptionInfo();
3556 perl_exception=newSVpv("",0);
3557 sv=NULL;
3558 if (sv_isobject(ST(0)) == 0)
3559 {
3560 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3561 PackageName);
3562 goto PerlException;
3563 }
3564 reference=SvRV(ST(0));
3565 hv=SvSTASH(reference);
3566 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3567 if (image == (Image *) NULL)
3568 {
3569 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3570 PackageName);
3571 goto PerlException;
3572 }
cristyfd168722013-10-07 15:59:31 +00003573 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003574 if (items == 2)
3575 {
3576 ssize_t
3577 in;
3578
3579 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3580 SvPV(ST(1),na));
3581 if (in < 0)
3582 {
3583 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3584 SvPV(ST(1),na));
3585 return;
3586 }
cristyfa21e9e2013-10-07 10:37:38 +00003587 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003588 }
3589 else
3590 for (i=2; i < items; i+=2)
3591 {
3592 attribute=(char *) SvPV(ST(i-1),na);
3593 switch (*attribute)
3594 {
3595 case 'O':
3596 case 'o':
3597 {
3598 if (LocaleCompare(attribute,"operator") == 0)
3599 {
3600 ssize_t
3601 in;
3602
3603 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3604 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3605 if (in < 0)
3606 {
3607 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3608 SvPV(ST(i),na));
3609 return;
3610 }
cristyfa21e9e2013-10-07 10:37:38 +00003611 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003612 break;
3613 }
3614 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3615 attribute);
3616 break;
3617 }
3618 default:
3619 {
3620 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3621 attribute);
3622 break;
3623 }
3624 }
3625 }
3626 image=ComplexImages(image,op,exception);
3627 if (image == (Image *) NULL)
3628 goto PerlException;
3629 /*
3630 Create blessed Perl array for the returned image.
3631 */
3632 av=newAV();
3633 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3634 SvREFCNT_dec(av);
3635 AddImageToRegistry(sv,image);
3636 rv=newRV(sv);
3637 av_push(av,sv_bless(rv,hv));
3638 SvREFCNT_dec(sv);
3639 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003640 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3641 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003642 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3643 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003644 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003645 SetImageInfo(info->image_info,0,exception);
3646 exception=DestroyExceptionInfo(exception);
3647 SvREFCNT_dec(perl_exception);
3648 XSRETURN(1);
3649
3650 PerlException:
3651 InheritPerlException(exception,perl_exception);
3652 exception=DestroyExceptionInfo(exception);
3653 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3654 SvPOK_on(perl_exception);
3655 ST(0)=sv_2mortal(perl_exception);
3656 XSRETURN(1);
3657 }
3658
3659#
3660###############################################################################
3661# #
3662# #
3663# #
cristy4a3ce0a2013-08-03 20:06:59 +00003664# C o m p a r e L a y e r s #
3665# #
3666# #
3667# #
3668###############################################################################
3669#
3670#
3671void
3672CompareLayers(ref)
3673 Image::Magick ref=NO_INIT
3674 ALIAS:
3675 CompareImagesLayers = 1
3676 comparelayers = 2
3677 compareimagelayers = 3
3678 PPCODE:
3679 {
3680 AV
3681 *av;
3682
3683 char
3684 *attribute;
3685
3686 ExceptionInfo
3687 *exception;
3688
3689 HV
3690 *hv;
3691
3692 Image
3693 *image;
3694
3695 LayerMethod
3696 method;
3697
3698 register ssize_t
3699 i;
3700
3701 ssize_t
3702 option;
3703
3704 struct PackageInfo
3705 *info;
3706
3707 SV
3708 *av_reference,
3709 *perl_exception,
3710 *reference,
3711 *rv,
3712 *sv;
3713
3714 PERL_UNUSED_VAR(ref);
3715 PERL_UNUSED_VAR(ix);
3716 exception=AcquireExceptionInfo();
3717 perl_exception=newSVpv("",0);
3718 sv=NULL;
3719 if (sv_isobject(ST(0)) == 0)
3720 {
3721 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3722 PackageName);
3723 goto PerlException;
3724 }
3725 reference=SvRV(ST(0));
3726 hv=SvSTASH(reference);
3727 av=newAV();
3728 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3729 SvREFCNT_dec(av);
3730 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3731 if (image == (Image *) NULL)
3732 {
3733 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3734 PackageName);
3735 goto PerlException;
3736 }
3737 method=CompareAnyLayer;
3738 for (i=2; i < items; i+=2)
3739 {
3740 attribute=(char *) SvPV(ST(i-1),na);
3741 switch (*attribute)
3742 {
3743 case 'M':
3744 case 'm':
3745 {
3746 if (LocaleCompare(attribute,"method") == 0)
3747 {
3748 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3749 SvPV(ST(i),na));
3750 if (option < 0)
3751 {
3752 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3753 SvPV(ST(i),na));
3754 break;
3755 }
3756 method=(LayerMethod) option;
3757 break;
3758 }
3759 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3760 attribute);
3761 break;
3762 }
3763 default:
3764 {
3765 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3766 attribute);
3767 break;
3768 }
3769 }
3770 }
3771 image=CompareImagesLayers(image,method,exception);
3772 if (image == (Image *) NULL)
3773 goto PerlException;
3774 for ( ; image; image=image->next)
3775 {
3776 AddImageToRegistry(sv,image);
3777 rv=newRV(sv);
3778 av_push(av,sv_bless(rv,hv));
3779 SvREFCNT_dec(sv);
3780 }
3781 exception=DestroyExceptionInfo(exception);
3782 ST(0)=av_reference;
3783 SvREFCNT_dec(perl_exception);
3784 XSRETURN(1);
3785
3786 PerlException:
3787 InheritPerlException(exception,perl_exception);
3788 exception=DestroyExceptionInfo(exception);
3789 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3790 SvPOK_on(perl_exception);
3791 ST(0)=sv_2mortal(perl_exception);
3792 XSRETURN(1);
3793 }
3794
3795#
3796###############################################################################
3797# #
3798# #
3799# #
3800# D e s t r o y #
3801# #
3802# #
3803# #
3804###############################################################################
3805#
3806#
3807void
3808DESTROY(ref)
3809 Image::Magick ref=NO_INIT
3810 PPCODE:
3811 {
3812 SV
3813 *reference;
3814
3815 PERL_UNUSED_VAR(ref);
3816 if (sv_isobject(ST(0)) == 0)
3817 croak("ReferenceIsNotMyType");
3818 reference=SvRV(ST(0));
3819 switch (SvTYPE(reference))
3820 {
3821 case SVt_PVAV:
3822 {
3823 char
cristy151b66d2015-04-15 10:50:31 +00003824 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003825
3826 const SV
3827 *key;
3828
3829 HV
3830 *hv;
3831
3832 GV
3833 **gvp;
3834
3835 struct PackageInfo
3836 *info;
3837
3838 SV
3839 *sv;
3840
3841 /*
3842 Array (AV *) reference
3843 */
cristy151b66d2015-04-15 10:50:31 +00003844 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003845 XS_VERSION,reference);
3846 hv=gv_stashpv(PackageName, FALSE);
3847 if (!hv)
3848 break;
3849 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3850 if (!gvp)
3851 break;
3852 sv=GvSV(*gvp);
3853 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3854 {
3855 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3856 DestroyPackageInfo(info);
3857 }
3858 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3859 (void) key;
3860 break;
3861 }
3862 case SVt_PVMG:
3863 {
3864 Image
3865 *image;
3866
3867 /*
3868 Blessed scalar = (Image *) SvIV(reference)
3869 */
3870 image=INT2PTR(Image *,SvIV(reference));
3871 if (image != (Image *) NULL)
3872 DeleteImageFromRegistry(reference,image);
3873 break;
3874 }
3875 default:
3876 break;
3877 }
3878 }
3879
3880#
3881###############################################################################
3882# #
3883# #
3884# #
3885# D i s p l a y #
3886# #
3887# #
3888# #
3889###############################################################################
3890#
3891#
3892void
3893Display(ref,...)
3894 Image::Magick ref=NO_INIT
3895 ALIAS:
3896 DisplayImage = 1
3897 display = 2
3898 displayimage = 3
3899 PPCODE:
3900 {
3901 ExceptionInfo
3902 *exception;
3903
3904 Image
3905 *image;
3906
3907 register ssize_t
3908 i;
3909
3910 struct PackageInfo
3911 *info,
3912 *package_info;
3913
3914 SV
3915 *perl_exception,
3916 *reference;
3917
3918 PERL_UNUSED_VAR(ref);
3919 PERL_UNUSED_VAR(ix);
3920 exception=AcquireExceptionInfo();
3921 perl_exception=newSVpv("",0);
3922 package_info=(struct PackageInfo *) NULL;
3923 if (sv_isobject(ST(0)) == 0)
3924 {
3925 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3926 PackageName);
3927 goto PerlException;
3928 }
3929 reference=SvRV(ST(0));
3930 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3931 if (image == (Image *) NULL)
3932 {
3933 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3934 PackageName);
3935 goto PerlException;
3936 }
3937 package_info=ClonePackageInfo(info,exception);
3938 if (items == 2)
3939 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3940 else
3941 if (items > 2)
3942 for (i=2; i < items; i+=2)
3943 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3944 exception);
3945 (void) DisplayImages(package_info->image_info,image,exception);
3946 (void) CatchImageException(image);
3947
3948 PerlException:
3949 if (package_info != (struct PackageInfo *) NULL)
3950 DestroyPackageInfo(package_info);
3951 InheritPerlException(exception,perl_exception);
3952 exception=DestroyExceptionInfo(exception);
3953 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3954 SvPOK_on(perl_exception);
3955 ST(0)=sv_2mortal(perl_exception);
3956 XSRETURN(1);
3957 }
3958
3959#
3960###############################################################################
3961# #
3962# #
3963# #
3964# E v a l u a t e I m a g e s #
3965# #
3966# #
3967# #
3968###############################################################################
3969#
3970#
3971void
3972EvaluateImages(ref)
3973 Image::Magick ref=NO_INIT
3974 ALIAS:
3975 EvaluateImages = 1
3976 evaluateimages = 2
3977 PPCODE:
3978 {
3979 AV
3980 *av;
3981
3982 char
3983 *attribute,
3984 *p;
3985
3986 ExceptionInfo
3987 *exception;
3988
3989 HV
3990 *hv;
3991
3992 Image
3993 *image;
3994
3995 MagickEvaluateOperator
3996 op;
3997
3998 register ssize_t
3999 i;
4000
4001 struct PackageInfo
4002 *info;
4003
4004 SV
4005 *perl_exception,
4006 *reference,
4007 *rv,
4008 *sv;
4009
4010 PERL_UNUSED_VAR(ref);
4011 PERL_UNUSED_VAR(ix);
4012 exception=AcquireExceptionInfo();
4013 perl_exception=newSVpv("",0);
4014 sv=NULL;
4015 if (sv_isobject(ST(0)) == 0)
4016 {
4017 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4018 PackageName);
4019 goto PerlException;
4020 }
4021 reference=SvRV(ST(0));
4022 hv=SvSTASH(reference);
4023 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4024 if (image == (Image *) NULL)
4025 {
4026 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4027 PackageName);
4028 goto PerlException;
4029 }
4030 op=MeanEvaluateOperator;
4031 if (items == 2)
4032 {
4033 ssize_t
4034 in;
4035
4036 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
4037 SvPV(ST(1),na));
4038 if (in < 0)
4039 {
4040 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4041 SvPV(ST(1),na));
4042 return;
4043 }
4044 op=(MagickEvaluateOperator) in;
4045 }
4046 else
4047 for (i=2; i < items; i+=2)
4048 {
4049 attribute=(char *) SvPV(ST(i-1),na);
4050 switch (*attribute)
4051 {
4052 case 'O':
4053 case 'o':
4054 {
4055 if (LocaleCompare(attribute,"operator") == 0)
4056 {
4057 ssize_t
4058 in;
4059
4060 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4061 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4062 if (in < 0)
4063 {
4064 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4065 SvPV(ST(i),na));
4066 return;
4067 }
4068 op=(MagickEvaluateOperator) in;
4069 break;
4070 }
4071 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4072 attribute);
4073 break;
4074 }
4075 default:
4076 {
4077 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4078 attribute);
4079 break;
4080 }
4081 }
4082 }
4083 image=EvaluateImages(image,op,exception);
4084 if (image == (Image *) NULL)
4085 goto PerlException;
4086 /*
4087 Create blessed Perl array for the returned image.
4088 */
4089 av=newAV();
4090 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4091 SvREFCNT_dec(av);
4092 AddImageToRegistry(sv,image);
4093 rv=newRV(sv);
4094 av_push(av,sv_bless(rv,hv));
4095 SvREFCNT_dec(sv);
4096 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004097 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4098 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004099 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4100 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004101 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004102 SetImageInfo(info->image_info,0,exception);
4103 exception=DestroyExceptionInfo(exception);
4104 SvREFCNT_dec(perl_exception);
4105 XSRETURN(1);
4106
4107 PerlException:
4108 InheritPerlException(exception,perl_exception);
4109 exception=DestroyExceptionInfo(exception);
4110 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4111 SvPOK_on(perl_exception);
4112 ST(0)=sv_2mortal(perl_exception);
4113 XSRETURN(1);
4114 }
4115
4116#
4117###############################################################################
4118# #
4119# #
4120# #
4121# F e a t u r e s #
4122# #
4123# #
4124# #
4125###############################################################################
4126#
4127#
4128void
4129Features(ref,...)
4130 Image::Magick ref=NO_INIT
4131 ALIAS:
4132 FeaturesImage = 1
4133 features = 2
4134 featuresimage = 3
4135 PPCODE:
4136 {
4137#define ChannelFeatures(channel,direction) \
4138{ \
Cristyb1710fe2017-02-11 13:51:48 -05004139 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004140 channel_features[channel].angular_second_moment[direction]); \
4141 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004142 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004143 channel_features[channel].contrast[direction]); \
4144 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004145 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004146 channel_features[channel].contrast[direction]); \
4147 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004148 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004149 channel_features[channel].variance_sum_of_squares[direction]); \
4150 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004151 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004152 channel_features[channel].inverse_difference_moment[direction]); \
4153 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004154 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004155 channel_features[channel].sum_average[direction]); \
4156 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004157 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004158 channel_features[channel].sum_variance[direction]); \
4159 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004160 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004161 channel_features[channel].sum_entropy[direction]); \
4162 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004163 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004164 channel_features[channel].entropy[direction]); \
4165 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004166 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004167 channel_features[channel].difference_variance[direction]); \
4168 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004169 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004170 channel_features[channel].difference_entropy[direction]); \
4171 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004172 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004173 channel_features[channel].measure_of_correlation_1[direction]); \
4174 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004175 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004176 channel_features[channel].measure_of_correlation_2[direction]); \
4177 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004178 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004179 channel_features[channel].maximum_correlation_coefficient[direction]); \
4180 PUSHs(sv_2mortal(newSVpv(message,0))); \
4181}
4182
4183 AV
4184 *av;
4185
4186 char
4187 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004188 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004189
4190 ChannelFeatures
4191 *channel_features;
4192
4193 double
4194 distance;
4195
4196 ExceptionInfo
4197 *exception;
4198
4199 Image
4200 *image;
4201
4202 register ssize_t
4203 i;
4204
4205 ssize_t
4206 count;
4207
4208 struct PackageInfo
4209 *info;
4210
4211 SV
4212 *perl_exception,
4213 *reference;
4214
4215 PERL_UNUSED_VAR(ref);
4216 PERL_UNUSED_VAR(ix);
4217 exception=AcquireExceptionInfo();
4218 perl_exception=newSVpv("",0);
4219 av=NULL;
4220 if (sv_isobject(ST(0)) == 0)
4221 {
4222 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4223 PackageName);
4224 goto PerlException;
4225 }
4226 reference=SvRV(ST(0));
4227 av=newAV();
4228 SvREFCNT_dec(av);
4229 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4230 if (image == (Image *) NULL)
4231 {
4232 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4233 PackageName);
4234 goto PerlException;
4235 }
cristy7dbd9262014-07-02 17:53:42 +00004236 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004237 for (i=2; i < items; i+=2)
4238 {
4239 attribute=(char *) SvPV(ST(i-1),na);
4240 switch (*attribute)
4241 {
4242 case 'D':
4243 case 'd':
4244 {
4245 if (LocaleCompare(attribute,"distance") == 0)
4246 {
4247 distance=StringToLong((char *) SvPV(ST(1),na));
4248 break;
4249 }
4250 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4251 attribute);
4252 break;
4253 }
4254 default:
4255 {
4256 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4257 attribute);
4258 break;
4259 }
4260 }
4261 }
4262 count=0;
4263 for ( ; image; image=image->next)
4264 {
Cristy5a854dc2017-02-11 15:43:46 -05004265 register ssize_t
4266 j;
4267
cristy4a3ce0a2013-08-03 20:06:59 +00004268 channel_features=GetImageFeatures(image,distance,exception);
4269 if (channel_features == (ChannelFeatures *) NULL)
4270 continue;
4271 count++;
Cristy5a854dc2017-02-11 15:43:46 -05004272 for (j=0; j < 4; j++)
cristy4a3ce0a2013-08-03 20:06:59 +00004273 {
Cristy5a854dc2017-02-11 15:43:46 -05004274 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
4275 {
4276 PixelChannel channel=GetPixelChannelChannel(image,i);
4277 PixelTrait traits=GetPixelChannelTraits(image,channel);
4278 if (traits == UndefinedPixelTrait)
4279 continue;
4280 EXTEND(sp,14*(i+1)*count);
4281 ChannelFeatures(channel,j);
4282 }
cristy4a3ce0a2013-08-03 20:06:59 +00004283 }
4284 channel_features=(ChannelFeatures *)
4285 RelinquishMagickMemory(channel_features);
4286 }
4287
4288 PerlException:
4289 InheritPerlException(exception,perl_exception);
4290 exception=DestroyExceptionInfo(exception);
4291 SvREFCNT_dec(perl_exception);
4292 }
4293
4294#
4295###############################################################################
4296# #
4297# #
4298# #
4299# F l a t t e n #
4300# #
4301# #
4302# #
4303###############################################################################
4304#
4305#
4306void
4307Flatten(ref)
4308 Image::Magick ref=NO_INIT
4309 ALIAS:
4310 FlattenImage = 1
4311 flatten = 2
4312 flattenimage = 3
4313 PPCODE:
4314 {
4315 AV
4316 *av;
4317
4318 char
4319 *attribute,
4320 *p;
4321
4322 ExceptionInfo
4323 *exception;
4324
4325 HV
4326 *hv;
4327
4328 Image
4329 *image;
4330
4331 PixelInfo
4332 background_color;
4333
4334 register ssize_t
4335 i;
4336
4337 struct PackageInfo
4338 *info;
4339
4340 SV
4341 *perl_exception,
4342 *reference,
4343 *rv,
4344 *sv;
4345
4346 PERL_UNUSED_VAR(ref);
4347 PERL_UNUSED_VAR(ix);
4348 exception=AcquireExceptionInfo();
4349 perl_exception=newSVpv("",0);
4350 sv=NULL;
4351 if (sv_isobject(ST(0)) == 0)
4352 {
4353 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4354 PackageName);
4355 goto PerlException;
4356 }
4357 reference=SvRV(ST(0));
4358 hv=SvSTASH(reference);
4359 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4360 if (image == (Image *) NULL)
4361 {
4362 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4363 PackageName);
4364 goto PerlException;
4365 }
4366 background_color=image->background_color;
4367 if (items == 2)
4368 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4369 &background_color,exception);
4370 else
4371 for (i=2; i < items; i+=2)
4372 {
4373 attribute=(char *) SvPV(ST(i-1),na);
4374 switch (*attribute)
4375 {
4376 case 'B':
4377 case 'b':
4378 {
4379 if (LocaleCompare(attribute,"background") == 0)
4380 {
4381 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4382 AllCompliance,&background_color,exception);
4383 break;
4384 }
4385 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4386 attribute);
4387 break;
4388 }
4389 default:
4390 {
4391 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4392 attribute);
4393 break;
4394 }
4395 }
4396 }
4397 image->background_color=background_color;
4398 image=MergeImageLayers(image,FlattenLayer,exception);
4399 if (image == (Image *) NULL)
4400 goto PerlException;
4401 /*
4402 Create blessed Perl array for the returned image.
4403 */
4404 av=newAV();
4405 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4406 SvREFCNT_dec(av);
4407 AddImageToRegistry(sv,image);
4408 rv=newRV(sv);
4409 av_push(av,sv_bless(rv,hv));
4410 SvREFCNT_dec(sv);
4411 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004412 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4413 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004414 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4415 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004416 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004417 SetImageInfo(info->image_info,0,exception);
4418 exception=DestroyExceptionInfo(exception);
4419 SvREFCNT_dec(perl_exception);
4420 XSRETURN(1);
4421
4422 PerlException:
4423 InheritPerlException(exception,perl_exception);
4424 exception=DestroyExceptionInfo(exception);
4425 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4426 SvPOK_on(perl_exception); /* return messages in string context */
4427 ST(0)=sv_2mortal(perl_exception);
4428 XSRETURN(1);
4429 }
4430
4431#
4432###############################################################################
4433# #
4434# #
4435# #
4436# F x #
4437# #
4438# #
4439# #
4440###############################################################################
4441#
4442#
4443void
4444Fx(ref,...)
4445 Image::Magick ref=NO_INIT
4446 ALIAS:
4447 FxImage = 1
4448 fx = 2
4449 fximage = 3
4450 PPCODE:
4451 {
4452 AV
4453 *av;
4454
4455 char
4456 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004457 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004458
4459 ChannelType
4460 channel,
4461 channel_mask;
4462
4463 ExceptionInfo
4464 *exception;
4465
4466 HV
4467 *hv;
4468
4469 Image
4470 *image;
4471
4472 register ssize_t
4473 i;
4474
4475 struct PackageInfo
4476 *info;
4477
4478 SV
4479 *av_reference,
4480 *perl_exception,
4481 *reference,
4482 *rv,
4483 *sv;
4484
4485 PERL_UNUSED_VAR(ref);
4486 PERL_UNUSED_VAR(ix);
4487 exception=AcquireExceptionInfo();
4488 perl_exception=newSVpv("",0);
4489 sv=NULL;
4490 attribute=NULL;
4491 av=NULL;
4492 if (sv_isobject(ST(0)) == 0)
4493 {
4494 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4495 PackageName);
4496 goto PerlException;
4497 }
4498 reference=SvRV(ST(0));
4499 hv=SvSTASH(reference);
4500 av=newAV();
4501 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4502 SvREFCNT_dec(av);
4503 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4504 if (image == (Image *) NULL)
4505 {
4506 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4507 PackageName);
4508 goto PerlException;
4509 }
4510 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4511 /*
4512 Get options.
4513 */
4514 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004515 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004516 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004517 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004518 else
4519 for (i=2; i < items; i+=2)
4520 {
4521 attribute=(char *) SvPV(ST(i-1),na);
4522 switch (*attribute)
4523 {
4524 case 'C':
4525 case 'c':
4526 {
4527 if (LocaleCompare(attribute,"channel") == 0)
4528 {
4529 ssize_t
4530 option;
4531
4532 option=ParseChannelOption(SvPV(ST(i),na));
4533 if (option < 0)
4534 {
4535 ThrowPerlException(exception,OptionError,
4536 "UnrecognizedType",SvPV(ST(i),na));
4537 return;
4538 }
4539 channel=(ChannelType) option;
4540 break;
4541 }
4542 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4543 attribute);
4544 break;
4545 }
4546 case 'E':
4547 case 'e':
4548 {
4549 if (LocaleCompare(attribute,"expression") == 0)
4550 {
4551 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004552 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004553 break;
4554 }
4555 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4556 attribute);
4557 break;
4558 }
4559 default:
4560 {
4561 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4562 attribute);
4563 break;
4564 }
4565 }
4566 }
4567 channel_mask=SetImageChannelMask(image,channel);
4568 image=FxImage(image,expression,exception);
4569 if (image != (Image *) NULL)
4570 (void) SetImageChannelMask(image,channel_mask);
4571 if (image == (Image *) NULL)
4572 goto PerlException;
4573 for ( ; image; image=image->next)
4574 {
4575 AddImageToRegistry(sv,image);
4576 rv=newRV(sv);
4577 av_push(av,sv_bless(rv,hv));
4578 SvREFCNT_dec(sv);
4579 }
4580 exception=DestroyExceptionInfo(exception);
4581 ST(0)=av_reference;
4582 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4583 XSRETURN(1);
4584
4585 PerlException:
4586 InheritPerlException(exception,perl_exception);
4587 exception=DestroyExceptionInfo(exception);
4588 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4589 SvPOK_on(perl_exception);
4590 ST(0)=sv_2mortal(perl_exception);
4591 XSRETURN(1);
4592 }
4593
4594#
4595###############################################################################
4596# #
4597# #
4598# #
4599# G e t #
4600# #
4601# #
4602# #
4603###############################################################################
4604#
4605#
4606void
4607Get(ref,...)
4608 Image::Magick ref=NO_INIT
4609 ALIAS:
4610 GetAttributes = 1
4611 GetAttribute = 2
4612 get = 3
4613 getattributes = 4
4614 getattribute = 5
4615 PPCODE:
4616 {
4617 char
4618 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004619 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004620
4621 const char
4622 *value;
4623
4624 ExceptionInfo
4625 *exception;
4626
4627 Image
4628 *image;
4629
4630 long
4631 j;
4632
4633 register ssize_t
4634 i;
4635
4636 struct PackageInfo
4637 *info;
4638
4639 SV
4640 *perl_exception,
4641 *reference,
4642 *s;
4643
4644 PERL_UNUSED_VAR(ref);
4645 PERL_UNUSED_VAR(ix);
4646 exception=AcquireExceptionInfo();
4647 perl_exception=newSVpv("",0);
4648 if (sv_isobject(ST(0)) == 0)
4649 {
4650 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4651 PackageName);
4652 XSRETURN_EMPTY;
4653 }
4654 reference=SvRV(ST(0));
4655 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4656 if (image == (Image *) NULL && !info)
4657 XSRETURN_EMPTY;
4658 EXTEND(sp,items);
4659 for (i=1; i < items; i++)
4660 {
4661 attribute=(char *) SvPV(ST(i),na);
4662 s=NULL;
4663 switch (*attribute)
4664 {
4665 case 'A':
4666 case 'a':
4667 {
4668 if (LocaleCompare(attribute,"adjoin") == 0)
4669 {
4670 if (info)
4671 s=newSViv((ssize_t) info->image_info->adjoin);
4672 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4673 continue;
4674 }
4675 if (LocaleCompare(attribute,"antialias") == 0)
4676 {
4677 if (info)
4678 s=newSViv((ssize_t) info->image_info->antialias);
4679 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4680 continue;
4681 }
4682 if (LocaleCompare(attribute,"area") == 0)
4683 {
4684 s=newSViv(GetMagickResource(AreaResource));
4685 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4686 continue;
4687 }
4688 if (LocaleCompare(attribute,"attenuate") == 0)
4689 {
4690 const char
4691 *value;
4692
4693 value=GetImageProperty(image,attribute,exception);
4694 if (value != (const char *) NULL)
4695 s=newSVpv(value,0);
4696 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4697 continue;
4698 }
4699 if (LocaleCompare(attribute,"authenticate") == 0)
4700 {
4701 if (info)
4702 {
4703 const char
4704 *option;
4705
4706 option=GetImageOption(info->image_info,attribute);
4707 if (option != (const char *) NULL)
4708 s=newSVpv(option,0);
4709 }
4710 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4711 continue;
4712 }
4713 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4714 attribute);
4715 break;
4716 }
4717 case 'B':
4718 case 'b':
4719 {
4720 if (LocaleCompare(attribute,"background") == 0)
4721 {
4722 if (image == (Image *) NULL)
4723 break;
cristy151b66d2015-04-15 10:50:31 +00004724 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004725 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4726 (double) image->background_color.green,
4727 (double) image->background_color.blue,
4728 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004729 s=newSVpv(color,0);
4730 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4731 continue;
4732 }
4733 if (LocaleCompare(attribute,"base-columns") == 0)
4734 {
4735 if (image != (Image *) NULL)
4736 s=newSViv((ssize_t) image->magick_columns);
4737 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4738 continue;
4739 }
4740 if (LocaleCompare(attribute,"base-filename") == 0)
4741 {
4742 if (image != (Image *) NULL)
4743 s=newSVpv(image->magick_filename,0);
4744 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4745 continue;
4746 }
4747 if (LocaleCompare(attribute,"base-height") == 0)
4748 {
4749 if (image != (Image *) NULL)
4750 s=newSViv((ssize_t) image->magick_rows);
4751 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4752 continue;
4753 }
4754 if (LocaleCompare(attribute,"base-rows") == 0)
4755 {
4756 if (image != (Image *) NULL)
4757 s=newSViv((ssize_t) image->magick_rows);
4758 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4759 continue;
4760 }
4761 if (LocaleCompare(attribute,"base-width") == 0)
4762 {
4763 if (image != (Image *) NULL)
4764 s=newSViv((ssize_t) image->magick_columns);
4765 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4766 continue;
4767 }
4768 if (LocaleCompare(attribute,"blue-primary") == 0)
4769 {
4770 if (image == (Image *) NULL)
4771 break;
Cristyb1710fe2017-02-11 13:51:48 -05004772 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004773 image->chromaticity.blue_primary.x,
4774 image->chromaticity.blue_primary.y);
4775 s=newSVpv(color,0);
4776 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4777 continue;
4778 }
4779 if (LocaleCompare(attribute,"bordercolor") == 0)
4780 {
4781 if (image == (Image *) NULL)
4782 break;
cristy151b66d2015-04-15 10:50:31 +00004783 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004784 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4785 (double) image->border_color.green,
4786 (double) image->border_color.blue,
4787 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004788 s=newSVpv(color,0);
4789 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4790 continue;
4791 }
4792 if (LocaleCompare(attribute,"bounding-box") == 0)
4793 {
4794 char
cristy151b66d2015-04-15 10:50:31 +00004795 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004796
4797 RectangleInfo
4798 page;
4799
4800 if (image == (Image *) NULL)
4801 break;
4802 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004803 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004804 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4805 page.height,(double) page.x,(double) page.y);
4806 s=newSVpv(geometry,0);
4807 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4808 continue;
4809 }
4810 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4811 attribute);
4812 break;
4813 }
4814 case 'C':
4815 case 'c':
4816 {
4817 if (LocaleCompare(attribute,"class") == 0)
4818 {
4819 if (image == (Image *) NULL)
4820 break;
4821 s=newSViv(image->storage_class);
4822 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4823 image->storage_class));
4824 SvIOK_on(s);
4825 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4826 continue;
4827 }
4828 if (LocaleCompare(attribute,"clip-mask") == 0)
4829 {
4830 if (image != (Image *) NULL)
4831 {
4832 Image
4833 *mask_image;
4834
4835 SV
4836 *sv;
4837
4838 sv=NULL;
4839 if (image->read_mask == MagickFalse)
4840 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004841 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004842 if (mask_image != (Image *) NULL)
4843 {
4844 AddImageToRegistry(sv,mask_image);
4845 s=sv_bless(newRV(sv),SvSTASH(reference));
4846 }
4847 }
4848 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4849 continue;
4850 }
4851 if (LocaleCompare(attribute,"clip-path") == 0)
4852 {
4853 if (image != (Image *) NULL)
4854 {
4855 Image
4856 *mask_image;
4857
4858 SV
4859 *sv;
4860
4861 sv=NULL;
4862 if (image->read_mask != MagickFalse)
4863 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004864 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004865 if (mask_image != (Image *) NULL)
4866 {
4867 AddImageToRegistry(sv,mask_image);
4868 s=sv_bless(newRV(sv),SvSTASH(reference));
4869 }
4870 }
4871 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4872 continue;
4873 }
4874 if (LocaleCompare(attribute,"compression") == 0)
4875 {
4876 j=info ? info->image_info->compression : image ?
4877 image->compression : UndefinedCompression;
4878 if (info)
4879 if (info->image_info->compression == UndefinedCompression)
4880 j=image->compression;
4881 s=newSViv(j);
4882 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4883 j));
4884 SvIOK_on(s);
4885 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4886 continue;
4887 }
4888 if (LocaleCompare(attribute,"colorspace") == 0)
4889 {
4890 j=image ? image->colorspace : RGBColorspace;
4891 s=newSViv(j);
4892 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4893 j));
4894 SvIOK_on(s);
4895 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4896 continue;
4897 }
4898 if (LocaleCompare(attribute,"colors") == 0)
4899 {
4900 if (image != (Image *) NULL)
4901 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4902 exception));
4903 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4904 continue;
4905 }
4906 if (LocaleNCompare(attribute,"colormap",8) == 0)
4907 {
4908 int
4909 items;
4910
4911 if (image == (Image *) NULL || !image->colormap)
4912 break;
4913 j=0;
4914 items=sscanf(attribute,"%*[^[][%ld",&j);
4915 (void) items;
4916 if (j > (ssize_t) image->colors)
4917 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004918 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004919 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4920 (double) image->colormap[j].green,
4921 (double) image->colormap[j].blue,
4922 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004923 s=newSVpv(color,0);
4924 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4925 continue;
4926 }
4927 if (LocaleCompare(attribute,"columns") == 0)
4928 {
4929 if (image != (Image *) NULL)
4930 s=newSViv((ssize_t) image->columns);
4931 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4932 continue;
4933 }
4934 if (LocaleCompare(attribute,"comment") == 0)
4935 {
4936 const char
4937 *value;
4938
Cristy935a4052017-03-31 17:45:37 -04004939 value=GetImageProperty(image,attribute,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004940 if (value != (const char *) NULL)
4941 s=newSVpv(value,0);
4942 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4943 continue;
4944 }
4945 if (LocaleCompare(attribute,"copyright") == 0)
4946 {
4947 s=newSVpv(GetMagickCopyright(),0);
4948 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4949 continue;
4950 }
4951 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4952 attribute);
4953 break;
4954 }
4955 case 'D':
4956 case 'd':
4957 {
4958 if (LocaleCompare(attribute,"density") == 0)
4959 {
4960 char
cristy151b66d2015-04-15 10:50:31 +00004961 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004962
4963 if (image == (Image *) NULL)
4964 break;
Cristyb1710fe2017-02-11 13:51:48 -05004965 (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004966 image->resolution.x,image->resolution.y);
4967 s=newSVpv(geometry,0);
4968 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4969 continue;
4970 }
4971 if (LocaleCompare(attribute,"delay") == 0)
4972 {
4973 if (image != (Image *) NULL)
4974 s=newSViv((ssize_t) image->delay);
4975 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4976 continue;
4977 }
4978 if (LocaleCompare(attribute,"depth") == 0)
4979 {
4980 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4981 if (image != (Image *) NULL)
4982 s=newSViv((ssize_t) GetImageDepth(image,exception));
4983 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4984 continue;
4985 }
4986 if (LocaleCompare(attribute,"directory") == 0)
4987 {
4988 if (image && image->directory)
4989 s=newSVpv(image->directory,0);
4990 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4991 continue;
4992 }
4993 if (LocaleCompare(attribute,"dispose") == 0)
4994 {
4995 if (image == (Image *) NULL)
4996 break;
4997
4998 s=newSViv(image->dispose);
4999 (void) sv_setpv(s,
5000 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
5001 SvIOK_on(s);
5002 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5003 continue;
5004 }
5005 if (LocaleCompare(attribute,"disk") == 0)
5006 {
5007 s=newSViv(GetMagickResource(DiskResource));
5008 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5009 continue;
5010 }
5011 if (LocaleCompare(attribute,"dither") == 0)
5012 {
5013 if (info)
5014 s=newSViv((ssize_t) info->image_info->dither);
5015 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5016 continue;
5017 }
5018 if (LocaleCompare(attribute,"display") == 0) /* same as server */
5019 {
5020 if (info && info->image_info->server_name)
5021 s=newSVpv(info->image_info->server_name,0);
5022 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5023 continue;
5024 }
5025 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5026 attribute);
5027 break;
5028 }
5029 case 'E':
5030 case 'e':
5031 {
5032 if (LocaleCompare(attribute,"elapsed-time") == 0)
5033 {
5034 if (image != (Image *) NULL)
5035 s=newSVnv(GetElapsedTime(&image->timer));
5036 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5037 continue;
5038 }
5039 if (LocaleCompare(attribute,"endian") == 0)
5040 {
5041 j=info ? info->image_info->endian : image ? image->endian :
5042 UndefinedEndian;
5043 s=newSViv(j);
5044 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
5045 SvIOK_on(s);
5046 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5047 continue;
5048 }
5049 if (LocaleCompare(attribute,"error") == 0)
5050 {
5051 if (image != (Image *) NULL)
5052 s=newSVnv(image->error.mean_error_per_pixel);
5053 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5054 continue;
5055 }
5056 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5057 attribute);
5058 break;
5059 }
5060 case 'F':
5061 case 'f':
5062 {
5063 if (LocaleCompare(attribute,"filesize") == 0)
5064 {
5065 if (image != (Image *) NULL)
5066 s=newSViv((ssize_t) GetBlobSize(image));
5067 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5068 continue;
5069 }
5070 if (LocaleCompare(attribute,"filename") == 0)
5071 {
5072 if (info && info->image_info->filename &&
5073 *info->image_info->filename)
5074 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
7624 ConnectedComponent = 283
7625 ConnectedComponentImage = 284
7626 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
cristy4a3ce0a2013-08-03 20:06:59 +00007634 MogrifyRegion = 666
7635 PPCODE:
7636 {
7637 AffineMatrix
7638 affine,
7639 current;
7640
7641 char
7642 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007643 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007644
7645 ChannelType
7646 channel,
7647 channel_mask;
7648
7649 CompositeOperator
7650 compose;
7651
7652 const char
7653 *attribute,
7654 *value;
7655
7656 double
7657 angle;
7658
7659 ExceptionInfo
7660 *exception;
7661
7662 GeometryInfo
7663 geometry_info;
7664
7665 Image
7666 *image,
7667 *next,
7668 *region_image;
7669
7670 MagickBooleanType
7671 status;
7672
7673 MagickStatusType
7674 flags;
7675
7676 PixelInfo
7677 fill_color;
7678
7679 RectangleInfo
7680 geometry,
7681 region_info;
7682
7683 register ssize_t
7684 i;
7685
7686 ssize_t
7687 base,
7688 j,
7689 number_images;
7690
7691 struct Methods
7692 *rp;
7693
7694 struct PackageInfo
7695 *info;
7696
7697 SV
7698 *perl_exception,
7699 **pv,
7700 *reference,
7701 **reference_vector;
7702
7703 struct ArgumentList
7704 argument_list[MaxArguments];
7705
7706 PERL_UNUSED_VAR(ref);
7707 PERL_UNUSED_VAR(ix);
7708 exception=AcquireExceptionInfo();
7709 perl_exception=newSVpv("",0);
7710 reference_vector=NULL;
7711 region_image=NULL;
7712 number_images=0;
7713 base=2;
7714 if (sv_isobject(ST(0)) == 0)
7715 {
7716 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7717 PackageName);
7718 goto PerlException;
7719 }
7720 reference=SvRV(ST(0));
7721 region_info.width=0;
7722 region_info.height=0;
7723 region_info.x=0;
7724 region_info.y=0;
7725 region_image=(Image *) NULL;
7726 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7727 if (ix && (ix != 666))
7728 {
7729 /*
7730 Called as Method(...)
7731 */
7732 ix=(ix+1)/2;
7733 rp=(&Methods[ix-1]);
7734 attribute=rp->name;
7735 }
7736 else
7737 {
7738 /*
7739 Called as Mogrify("Method",...)
7740 */
7741 attribute=(char *) SvPV(ST(1),na);
7742 if (ix)
7743 {
7744 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7745 attribute=(char *) SvPV(ST(2),na);
7746 base++;
7747 }
7748 for (rp=Methods; ; rp++)
7749 {
7750 if (rp >= EndOf(Methods))
7751 {
7752 ThrowPerlException(exception,OptionError,
7753 "UnrecognizedPerlMagickMethod",attribute);
7754 goto PerlException;
7755 }
7756 if (strEQcase(attribute,rp->name))
7757 break;
7758 }
7759 ix=rp-Methods+1;
7760 base++;
7761 }
7762 if (image == (Image *) NULL)
7763 {
7764 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7765 goto PerlException;
7766 }
7767 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7768 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7769 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7770 {
7771 Arguments
7772 *pp,
7773 *qq;
7774
7775 ssize_t
7776 ssize_test;
7777
7778 struct ArgumentList
7779 *al;
7780
7781 SV
7782 *sv;
7783
7784 sv=NULL;
7785 ssize_test=0;
7786 pp=(Arguments *) NULL;
7787 qq=rp->arguments;
7788 if (i == items)
7789 {
7790 pp=rp->arguments,
7791 sv=ST(i-1);
7792 }
7793 else
7794 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7795 {
7796 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7797 break;
7798 if (strEQcase(attribute,qq->method) > ssize_test)
7799 {
7800 pp=qq;
7801 ssize_test=strEQcase(attribute,qq->method);
7802 }
7803 }
7804 if (pp == (Arguments *) NULL)
7805 {
7806 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7807 attribute);
7808 goto continue_outer_loop;
7809 }
7810 al=(&argument_list[pp-rp->arguments]);
7811 switch (pp->type)
7812 {
7813 case ArrayReference:
7814 {
7815 if (SvTYPE(sv) != SVt_RV)
7816 {
cristy151b66d2015-04-15 10:50:31 +00007817 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007818 "invalid %.60s value",pp->method);
7819 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7820 goto continue_outer_loop;
7821 }
7822 al->array_reference=SvRV(sv);
7823 break;
7824 }
7825 case RealReference:
7826 {
7827 al->real_reference=SvNV(sv);
7828 break;
7829 }
7830 case FileReference:
7831 {
7832 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7833 break;
7834 }
7835 case ImageReference:
7836 {
7837 if (!sv_isobject(sv) ||
7838 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7839 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7840 {
7841 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7842 PackageName);
7843 goto PerlException;
7844 }
7845 break;
7846 }
7847 case IntegerReference:
7848 {
7849 al->integer_reference=SvIV(sv);
7850 break;
7851 }
7852 case StringReference:
7853 {
7854 al->string_reference=(char *) SvPV(sv,al->length);
7855 if (sv_isobject(sv))
7856 al->image_reference=SetupList(aTHX_ SvRV(sv),
7857 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7858 break;
7859 }
7860 default:
7861 {
7862 /*
7863 Is a string; look up name.
7864 */
7865 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7866 {
7867 al->string_reference=(char *) SvPV(sv,al->length);
7868 al->integer_reference=(-1);
7869 break;
7870 }
7871 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7872 MagickFalse,SvPV(sv,na));
7873 if (pp->type == MagickChannelOptions)
7874 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7875 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7876 {
cristy151b66d2015-04-15 10:50:31 +00007877 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007878 "invalid %.60s value",pp->method);
7879 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7880 goto continue_outer_loop;
7881 }
7882 break;
7883 }
7884 }
7885 attribute_flag[pp-rp->arguments]++;
7886 continue_outer_loop: ;
7887 }
7888 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7889 pv=reference_vector;
7890 SetGeometryInfo(&geometry_info);
7891 channel=DefaultChannels;
7892 for (next=image; next; next=next->next)
7893 {
7894 image=next;
7895 SetGeometry(image,&geometry);
7896 if ((region_info.width*region_info.height) != 0)
7897 {
7898 region_image=image;
7899 image=CropImage(image,&region_info,exception);
7900 }
7901 switch (ix)
7902 {
7903 default:
7904 {
cristy151b66d2015-04-15 10:50:31 +00007905 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007906 ThrowPerlException(exception,OptionError,
7907 "UnrecognizedPerlMagickMethod",message);
7908 goto PerlException;
7909 }
7910 case 1: /* Comment */
7911 {
7912 if (attribute_flag[0] == 0)
7913 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007914 (void) SetImageProperty(image,"comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007915 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007916 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007917 break;
7918 }
7919 case 2: /* Label */
7920 {
7921 if (attribute_flag[0] == 0)
7922 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007923 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007924 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007925 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007926 break;
7927 }
7928 case 3: /* AddNoise */
7929 {
7930 double
7931 attenuate;
7932
7933 if (attribute_flag[0] == 0)
7934 argument_list[0].integer_reference=UniformNoise;
7935 attenuate=1.0;
7936 if (attribute_flag[1] != 0)
7937 attenuate=argument_list[1].real_reference;
7938 if (attribute_flag[2] != 0)
7939 channel=(ChannelType) argument_list[2].integer_reference;
7940 channel_mask=SetImageChannelMask(image,channel);
7941 image=AddNoiseImage(image,(NoiseType)
7942 argument_list[0].integer_reference,attenuate,exception);
7943 if (image != (Image *) NULL)
7944 (void) SetImageChannelMask(image,channel_mask);
7945 break;
7946 }
7947 case 4: /* Colorize */
7948 {
7949 PixelInfo
7950 target;
7951
7952 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7953 0,0,&target,exception);
7954 if (attribute_flag[0] != 0)
7955 (void) QueryColorCompliance(argument_list[0].string_reference,
7956 AllCompliance,&target,exception);
7957 if (attribute_flag[1] == 0)
7958 argument_list[1].string_reference="100%";
7959 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7960 exception);
7961 break;
7962 }
7963 case 5: /* Border */
7964 {
7965 CompositeOperator
7966 compose;
7967
7968 geometry.width=0;
7969 geometry.height=0;
7970 if (attribute_flag[0] != 0)
7971 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7972 &geometry,exception);
7973 if (attribute_flag[1] != 0)
7974 geometry.width=argument_list[1].integer_reference;
7975 if (attribute_flag[2] != 0)
7976 geometry.height=argument_list[2].integer_reference;
7977 if (attribute_flag[3] != 0)
7978 QueryColorCompliance(argument_list[3].string_reference,
7979 AllCompliance,&image->border_color,exception);
7980 if (attribute_flag[4] != 0)
7981 QueryColorCompliance(argument_list[4].string_reference,
7982 AllCompliance,&image->border_color,exception);
7983 if (attribute_flag[5] != 0)
7984 QueryColorCompliance(argument_list[5].string_reference,
7985 AllCompliance,&image->border_color,exception);
7986 compose=image->compose;
7987 if (attribute_flag[6] != 0)
7988 compose=(CompositeOperator) argument_list[6].integer_reference;
7989 image=BorderImage(image,&geometry,compose,exception);
7990 break;
7991 }
7992 case 6: /* Blur */
7993 {
7994 if (attribute_flag[0] != 0)
7995 {
7996 flags=ParseGeometry(argument_list[0].string_reference,
7997 &geometry_info);
7998 if ((flags & SigmaValue) == 0)
7999 geometry_info.sigma=1.0;
8000 }
8001 if (attribute_flag[1] != 0)
8002 geometry_info.rho=argument_list[1].real_reference;
8003 if (attribute_flag[2] != 0)
8004 geometry_info.sigma=argument_list[2].real_reference;
8005 if (attribute_flag[3] != 0)
8006 channel=(ChannelType) argument_list[3].integer_reference;
8007 channel_mask=SetImageChannelMask(image,channel);
8008 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
8009 exception);
8010 if (image != (Image *) NULL)
8011 (void) SetImageChannelMask(image,channel_mask);
8012 break;
8013 }
8014 case 7: /* Chop */
8015 {
cristy260bd762014-08-15 12:46:34 +00008016 if (attribute_flag[5] != 0)
8017 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00008018 if (attribute_flag[0] != 0)
8019 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8020 &geometry,exception);
8021 if (attribute_flag[1] != 0)
8022 geometry.width=argument_list[1].integer_reference;
8023 if (attribute_flag[2] != 0)
8024 geometry.height=argument_list[2].integer_reference;
8025 if (attribute_flag[3] != 0)
8026 geometry.x=argument_list[3].integer_reference;
8027 if (attribute_flag[4] != 0)
8028 geometry.y=argument_list[4].integer_reference;
8029 image=ChopImage(image,&geometry,exception);
8030 break;
8031 }
8032 case 8: /* Crop */
8033 {
8034 if (attribute_flag[6] != 0)
8035 image->gravity=(GravityType) argument_list[6].integer_reference;
8036 if (attribute_flag[0] != 0)
8037 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8038 &geometry,exception);
8039 if (attribute_flag[1] != 0)
8040 geometry.width=argument_list[1].integer_reference;
8041 if (attribute_flag[2] != 0)
8042 geometry.height=argument_list[2].integer_reference;
8043 if (attribute_flag[3] != 0)
8044 geometry.x=argument_list[3].integer_reference;
8045 if (attribute_flag[4] != 0)
8046 geometry.y=argument_list[4].integer_reference;
8047 if (attribute_flag[5] != 0)
8048 image->fuzz=StringToDoubleInterval(
8049 argument_list[5].string_reference,(double) QuantumRange+1.0);
8050 image=CropImage(image,&geometry,exception);
8051 break;
8052 }
8053 case 9: /* Despeckle */
8054 {
8055 image=DespeckleImage(image,exception);
8056 break;
8057 }
8058 case 10: /* Edge */
8059 {
8060 if (attribute_flag[0] != 0)
8061 geometry_info.rho=argument_list[0].real_reference;
8062 image=EdgeImage(image,geometry_info.rho,exception);
8063 break;
8064 }
8065 case 11: /* Emboss */
8066 {
8067 if (attribute_flag[0] != 0)
8068 {
8069 flags=ParseGeometry(argument_list[0].string_reference,
8070 &geometry_info);
8071 if ((flags & SigmaValue) == 0)
8072 geometry_info.sigma=1.0;
8073 }
8074 if (attribute_flag[1] != 0)
8075 geometry_info.rho=argument_list[1].real_reference;
8076 if (attribute_flag[2] != 0)
8077 geometry_info.sigma=argument_list[2].real_reference;
8078 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8079 exception);
8080 break;
8081 }
8082 case 12: /* Enhance */
8083 {
8084 image=EnhanceImage(image,exception);
8085 break;
8086 }
8087 case 13: /* Flip */
8088 {
8089 image=FlipImage(image,exception);
8090 break;
8091 }
8092 case 14: /* Flop */
8093 {
8094 image=FlopImage(image,exception);
8095 break;
8096 }
8097 case 15: /* Frame */
8098 {
8099 CompositeOperator
8100 compose;
8101
8102 FrameInfo
8103 frame_info;
8104
8105 if (attribute_flag[0] != 0)
8106 {
8107 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8108 &geometry,exception);
8109 frame_info.width=geometry.width;
8110 frame_info.height=geometry.height;
8111 frame_info.outer_bevel=geometry.x;
8112 frame_info.inner_bevel=geometry.y;
8113 }
8114 if (attribute_flag[1] != 0)
8115 frame_info.width=argument_list[1].integer_reference;
8116 if (attribute_flag[2] != 0)
8117 frame_info.height=argument_list[2].integer_reference;
8118 if (attribute_flag[3] != 0)
8119 frame_info.inner_bevel=argument_list[3].integer_reference;
8120 if (attribute_flag[4] != 0)
8121 frame_info.outer_bevel=argument_list[4].integer_reference;
8122 if (attribute_flag[5] != 0)
8123 QueryColorCompliance(argument_list[5].string_reference,
8124 AllCompliance,&fill_color,exception);
8125 if (attribute_flag[6] != 0)
8126 QueryColorCompliance(argument_list[6].string_reference,
8127 AllCompliance,&fill_color,exception);
8128 frame_info.x=(ssize_t) frame_info.width;
8129 frame_info.y=(ssize_t) frame_info.height;
8130 frame_info.width=image->columns+2*frame_info.x;
8131 frame_info.height=image->rows+2*frame_info.y;
8132 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
Cristy8645e042016-02-03 16:35:29 -05008133 image->alpha_color=fill_color;
cristy4a3ce0a2013-08-03 20:06:59 +00008134 compose=image->compose;
8135 if (attribute_flag[7] != 0)
8136 compose=(CompositeOperator) argument_list[7].integer_reference;
8137 image=FrameImage(image,&frame_info,compose,exception);
8138 break;
8139 }
8140 case 16: /* Implode */
8141 {
8142 PixelInterpolateMethod
8143 method;
8144
8145 if (attribute_flag[0] == 0)
8146 argument_list[0].real_reference=0.5;
8147 method=UndefinedInterpolatePixel;
8148 if (attribute_flag[1] != 0)
8149 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8150 image=ImplodeImage(image,argument_list[0].real_reference,
8151 method,exception);
8152 break;
8153 }
8154 case 17: /* Magnify */
8155 {
8156 image=MagnifyImage(image,exception);
8157 break;
8158 }
8159 case 18: /* MedianFilter */
8160 {
8161 if (attribute_flag[0] != 0)
8162 {
8163 flags=ParseGeometry(argument_list[0].string_reference,
8164 &geometry_info);
8165 if ((flags & SigmaValue) == 0)
8166 geometry_info.sigma=geometry_info.rho;
8167 }
8168 if (attribute_flag[1] != 0)
8169 geometry_info.rho=argument_list[1].real_reference;
8170 if (attribute_flag[2] != 0)
8171 geometry_info.sigma=argument_list[2].real_reference;
8172 if (attribute_flag[3] != 0)
8173 channel=(ChannelType) argument_list[3].integer_reference;
8174 channel_mask=SetImageChannelMask(image,channel);
8175 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8176 (size_t) geometry_info.sigma,exception);
8177 if (image != (Image *) NULL)
8178 (void) SetImageChannelMask(image,channel_mask);
8179 break;
8180 }
8181 case 19: /* Minify */
8182 {
8183 image=MinifyImage(image,exception);
8184 break;
8185 }
8186 case 20: /* OilPaint */
8187 {
8188 if (attribute_flag[0] == 0)
8189 argument_list[0].real_reference=0.0;
8190 if (attribute_flag[1] == 0)
8191 argument_list[1].real_reference=1.0;
8192 image=OilPaintImage(image,argument_list[0].real_reference,
8193 argument_list[1].real_reference,exception);
8194 break;
8195 }
8196 case 21: /* ReduceNoise */
8197 {
8198 if (attribute_flag[0] != 0)
8199 {
8200 flags=ParseGeometry(argument_list[0].string_reference,
8201 &geometry_info);
8202 if ((flags & SigmaValue) == 0)
8203 geometry_info.sigma=1.0;
8204 }
8205 if (attribute_flag[1] != 0)
8206 geometry_info.rho=argument_list[1].real_reference;
8207 if (attribute_flag[2] != 0)
8208 geometry_info.sigma=argument_list[2].real_reference;
8209 if (attribute_flag[3] != 0)
8210 channel=(ChannelType) argument_list[3].integer_reference;
8211 channel_mask=SetImageChannelMask(image,channel);
8212 image=StatisticImage(image,NonpeakStatistic,(size_t)
8213 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8214 if (image != (Image *) NULL)
8215 (void) SetImageChannelMask(image,channel_mask);
8216 break;
8217 }
8218 case 22: /* Roll */
8219 {
8220 if (attribute_flag[0] != 0)
8221 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8222 &geometry,exception);
8223 if (attribute_flag[1] != 0)
8224 geometry.x=argument_list[1].integer_reference;
8225 if (attribute_flag[2] != 0)
8226 geometry.y=argument_list[2].integer_reference;
8227 image=RollImage(image,geometry.x,geometry.y,exception);
8228 break;
8229 }
8230 case 23: /* Rotate */
8231 {
8232 if (attribute_flag[0] == 0)
8233 argument_list[0].real_reference=90.0;
8234 if (attribute_flag[1] != 0)
8235 {
8236 QueryColorCompliance(argument_list[1].string_reference,
8237 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008238 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8239 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008240 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8241 }
8242 image=RotateImage(image,argument_list[0].real_reference,exception);
8243 break;
8244 }
8245 case 24: /* Sample */
8246 {
8247 if (attribute_flag[0] != 0)
8248 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8249 &geometry,exception);
8250 if (attribute_flag[1] != 0)
8251 geometry.width=argument_list[1].integer_reference;
8252 if (attribute_flag[2] != 0)
8253 geometry.height=argument_list[2].integer_reference;
8254 image=SampleImage(image,geometry.width,geometry.height,exception);
8255 break;
8256 }
8257 case 25: /* Scale */
8258 {
8259 if (attribute_flag[0] != 0)
8260 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8261 &geometry,exception);
8262 if (attribute_flag[1] != 0)
8263 geometry.width=argument_list[1].integer_reference;
8264 if (attribute_flag[2] != 0)
8265 geometry.height=argument_list[2].integer_reference;
8266 image=ScaleImage(image,geometry.width,geometry.height,exception);
8267 break;
8268 }
8269 case 26: /* Shade */
8270 {
8271 if (attribute_flag[0] != 0)
8272 {
8273 flags=ParseGeometry(argument_list[0].string_reference,
8274 &geometry_info);
8275 if ((flags & SigmaValue) == 0)
8276 geometry_info.sigma=0.0;
8277 }
8278 if (attribute_flag[1] != 0)
8279 geometry_info.rho=argument_list[1].real_reference;
8280 if (attribute_flag[2] != 0)
8281 geometry_info.sigma=argument_list[2].real_reference;
8282 image=ShadeImage(image,
8283 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8284 geometry_info.rho,geometry_info.sigma,exception);
8285 break;
8286 }
8287 case 27: /* Sharpen */
8288 {
8289 if (attribute_flag[0] != 0)
8290 {
8291 flags=ParseGeometry(argument_list[0].string_reference,
8292 &geometry_info);
8293 if ((flags & SigmaValue) == 0)
8294 geometry_info.sigma=1.0;
8295 }
8296 if (attribute_flag[1] != 0)
8297 geometry_info.rho=argument_list[1].real_reference;
8298 if (attribute_flag[2] != 0)
8299 geometry_info.sigma=argument_list[2].real_reference;
8300 if (attribute_flag[3] != 0)
8301 channel=(ChannelType) argument_list[3].integer_reference;
8302 channel_mask=SetImageChannelMask(image,channel);
8303 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8304 exception);
8305 if (image != (Image *) NULL)
8306 (void) SetImageChannelMask(image,channel_mask);
8307 break;
8308 }
8309 case 28: /* Shear */
8310 {
8311 if (attribute_flag[0] != 0)
8312 {
8313 flags=ParseGeometry(argument_list[0].string_reference,
8314 &geometry_info);
8315 if ((flags & SigmaValue) == 0)
8316 geometry_info.sigma=geometry_info.rho;
8317 }
8318 if (attribute_flag[1] != 0)
8319 geometry_info.rho=argument_list[1].real_reference;
8320 if (attribute_flag[2] != 0)
8321 geometry_info.sigma=argument_list[2].real_reference;
8322 if (attribute_flag[3] != 0)
8323 QueryColorCompliance(argument_list[3].string_reference,
8324 AllCompliance,&image->background_color,exception);
8325 if (attribute_flag[4] != 0)
8326 QueryColorCompliance(argument_list[4].string_reference,
8327 AllCompliance,&image->background_color,exception);
8328 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8329 exception);
8330 break;
8331 }
8332 case 29: /* Spread */
8333 {
Cristye3319c12015-08-24 07:11:48 -04008334 PixelInterpolateMethod
8335 method;
8336
cristy4a3ce0a2013-08-03 20:06:59 +00008337 if (attribute_flag[0] == 0)
8338 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008339 method=UndefinedInterpolatePixel;
8340 if (attribute_flag[1] != 0)
8341 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8342 image=SpreadImage(image,method,argument_list[0].real_reference,
8343 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008344 break;
8345 }
8346 case 30: /* Swirl */
8347 {
8348 PixelInterpolateMethod
8349 method;
8350
8351 if (attribute_flag[0] == 0)
8352 argument_list[0].real_reference=50.0;
8353 method=UndefinedInterpolatePixel;
8354 if (attribute_flag[1] != 0)
8355 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8356 image=SwirlImage(image,argument_list[0].real_reference,
8357 method,exception);
8358 break;
8359 }
8360 case 31: /* Resize */
8361 case 32: /* Zoom */
8362 {
8363 if (attribute_flag[0] != 0)
8364 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8365 &geometry,exception);
8366 if (attribute_flag[1] != 0)
8367 geometry.width=argument_list[1].integer_reference;
8368 if (attribute_flag[2] != 0)
8369 geometry.height=argument_list[2].integer_reference;
8370 if (attribute_flag[3] == 0)
8371 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8372 if (attribute_flag[4] != 0)
8373 SetImageArtifact(image,"filter:support",
8374 argument_list[4].string_reference);
8375 image=ResizeImage(image,geometry.width,geometry.height,
Cristy8645e042016-02-03 16:35:29 -05008376 (FilterType) argument_list[3].integer_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00008377 exception);
8378 break;
8379 }
8380 case 33: /* Annotate */
8381 {
8382 DrawInfo
8383 *draw_info;
8384
8385 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8386 (DrawInfo *) NULL);
8387 if (attribute_flag[0] != 0)
8388 {
8389 char
8390 *text;
8391
8392 text=InterpretImageProperties(info ? info->image_info :
8393 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8394 exception);
8395 (void) CloneString(&draw_info->text,text);
8396 text=DestroyString(text);
8397 }
8398 if (attribute_flag[1] != 0)
8399 (void) CloneString(&draw_info->font,
8400 argument_list[1].string_reference);
8401 if (attribute_flag[2] != 0)
8402 draw_info->pointsize=argument_list[2].real_reference;
8403 if (attribute_flag[3] != 0)
8404 (void) CloneString(&draw_info->density,
8405 argument_list[3].string_reference);
8406 if (attribute_flag[4] != 0)
8407 (void) QueryColorCompliance(argument_list[4].string_reference,
8408 AllCompliance,&draw_info->undercolor,exception);
8409 if (attribute_flag[5] != 0)
8410 {
8411 (void) QueryColorCompliance(argument_list[5].string_reference,
8412 AllCompliance,&draw_info->stroke,exception);
8413 if (argument_list[5].image_reference != (Image *) NULL)
8414 draw_info->stroke_pattern=CloneImage(
8415 argument_list[5].image_reference,0,0,MagickTrue,exception);
8416 }
8417 if (attribute_flag[6] != 0)
8418 {
8419 (void) QueryColorCompliance(argument_list[6].string_reference,
8420 AllCompliance,&draw_info->fill,exception);
8421 if (argument_list[6].image_reference != (Image *) NULL)
8422 draw_info->fill_pattern=CloneImage(
8423 argument_list[6].image_reference,0,0,MagickTrue,exception);
8424 }
8425 if (attribute_flag[7] != 0)
8426 {
8427 (void) CloneString(&draw_info->geometry,
8428 argument_list[7].string_reference);
8429 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8430 &geometry,exception);
8431 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8432 geometry_info.sigma=geometry_info.xi;
8433 }
8434 if (attribute_flag[8] != 0)
8435 (void) QueryColorCompliance(argument_list[8].string_reference,
8436 AllCompliance,&draw_info->fill,exception);
8437 if (attribute_flag[11] != 0)
8438 draw_info->gravity=(GravityType)
8439 argument_list[11].integer_reference;
8440 if (attribute_flag[25] != 0)
8441 {
8442 AV
8443 *av;
8444
8445 av=(AV *) argument_list[25].array_reference;
8446 if ((av_len(av) != 3) && (av_len(av) != 5))
8447 {
8448 ThrowPerlException(exception,OptionError,
8449 "affine matrix must have 4 or 6 elements",PackageName);
8450 goto PerlException;
8451 }
8452 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8453 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8454 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8455 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8456 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8457 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8458 {
8459 ThrowPerlException(exception,OptionError,
8460 "affine matrix is singular",PackageName);
8461 goto PerlException;
8462 }
8463 if (av_len(av) == 5)
8464 {
8465 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8466 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8467 }
8468 }
8469 for (j=12; j < 17; j++)
8470 {
8471 if (attribute_flag[j] == 0)
8472 continue;
8473 value=argument_list[j].string_reference;
8474 angle=argument_list[j].real_reference;
8475 current=draw_info->affine;
8476 GetAffineMatrix(&affine);
8477 switch (j)
8478 {
8479 case 12:
8480 {
8481 /*
8482 Translate.
8483 */
8484 flags=ParseGeometry(value,&geometry_info);
8485 affine.tx=geometry_info.xi;
8486 affine.ty=geometry_info.psi;
8487 if ((flags & PsiValue) == 0)
8488 affine.ty=affine.tx;
8489 break;
8490 }
8491 case 13:
8492 {
8493 /*
8494 Scale.
8495 */
8496 flags=ParseGeometry(value,&geometry_info);
8497 affine.sx=geometry_info.rho;
8498 affine.sy=geometry_info.sigma;
8499 if ((flags & SigmaValue) == 0)
8500 affine.sy=affine.sx;
8501 break;
8502 }
8503 case 14:
8504 {
8505 /*
8506 Rotate.
8507 */
8508 if (angle == 0.0)
8509 break;
8510 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8511 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8512 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8513 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8514 break;
8515 }
8516 case 15:
8517 {
8518 /*
8519 SkewX.
8520 */
8521 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8522 break;
8523 }
8524 case 16:
8525 {
8526 /*
8527 SkewY.
8528 */
8529 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8530 break;
8531 }
8532 }
8533 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8534 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8535 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8536 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8537 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8538 current.tx;
8539 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8540 current.ty;
8541 }
8542 if (attribute_flag[9] == 0)
8543 argument_list[9].real_reference=0.0;
8544 if (attribute_flag[10] == 0)
8545 argument_list[10].real_reference=0.0;
8546 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8547 {
8548 char
cristy151b66d2015-04-15 10:50:31 +00008549 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008550
cristy151b66d2015-04-15 10:50:31 +00008551 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008552 (double) argument_list[9].real_reference+draw_info->affine.tx,
8553 (double) argument_list[10].real_reference+draw_info->affine.ty);
8554 (void) CloneString(&draw_info->geometry,geometry);
8555 }
8556 if (attribute_flag[17] != 0)
8557 draw_info->stroke_width=argument_list[17].real_reference;
8558 if (attribute_flag[18] != 0)
8559 {
8560 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8561 MagickTrue : MagickFalse;
8562 draw_info->stroke_antialias=draw_info->text_antialias;
8563 }
8564 if (attribute_flag[19] != 0)
8565 (void) CloneString(&draw_info->family,
8566 argument_list[19].string_reference);
8567 if (attribute_flag[20] != 0)
8568 draw_info->style=(StyleType) argument_list[20].integer_reference;
8569 if (attribute_flag[21] != 0)
8570 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8571 if (attribute_flag[22] != 0)
8572 draw_info->weight=argument_list[22].integer_reference;
8573 if (attribute_flag[23] != 0)
8574 draw_info->align=(AlignType) argument_list[23].integer_reference;
8575 if (attribute_flag[24] != 0)
8576 (void) CloneString(&draw_info->encoding,
8577 argument_list[24].string_reference);
8578 if (attribute_flag[25] != 0)
8579 draw_info->fill_pattern=CloneImage(
8580 argument_list[25].image_reference,0,0,MagickTrue,exception);
8581 if (attribute_flag[26] != 0)
8582 draw_info->fill_pattern=CloneImage(
8583 argument_list[26].image_reference,0,0,MagickTrue,exception);
8584 if (attribute_flag[27] != 0)
8585 draw_info->stroke_pattern=CloneImage(
8586 argument_list[27].image_reference,0,0,MagickTrue,exception);
8587 if (attribute_flag[29] != 0)
8588 draw_info->kerning=argument_list[29].real_reference;
8589 if (attribute_flag[30] != 0)
8590 draw_info->interline_spacing=argument_list[30].real_reference;
8591 if (attribute_flag[31] != 0)
8592 draw_info->interword_spacing=argument_list[31].real_reference;
8593 if (attribute_flag[32] != 0)
8594 draw_info->direction=(DirectionType)
8595 argument_list[32].integer_reference;
8596 (void) AnnotateImage(image,draw_info,exception);
8597 draw_info=DestroyDrawInfo(draw_info);
8598 break;
8599 }
8600 case 34: /* ColorFloodfill */
8601 {
8602 DrawInfo
8603 *draw_info;
8604
8605 MagickBooleanType
8606 invert;
8607
8608 PixelInfo
8609 target;
8610
8611 draw_info=CloneDrawInfo(info ? info->image_info :
8612 (ImageInfo *) NULL,(DrawInfo *) NULL);
8613 if (attribute_flag[0] != 0)
8614 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8615 &geometry,exception);
8616 if (attribute_flag[1] != 0)
8617 geometry.x=argument_list[1].integer_reference;
8618 if (attribute_flag[2] != 0)
8619 geometry.y=argument_list[2].integer_reference;
8620 if (attribute_flag[3] != 0)
8621 (void) QueryColorCompliance(argument_list[3].string_reference,
8622 AllCompliance,&draw_info->fill,exception);
8623 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8624 geometry.x,geometry.y,&target,exception);
8625 invert=MagickFalse;
8626 if (attribute_flag[4] != 0)
8627 {
8628 QueryColorCompliance(argument_list[4].string_reference,
8629 AllCompliance,&target,exception);
8630 invert=MagickTrue;
8631 }
8632 if (attribute_flag[5] != 0)
8633 image->fuzz=StringToDoubleInterval(
8634 argument_list[5].string_reference,(double) QuantumRange+1.0);
8635 if (attribute_flag[6] != 0)
8636 invert=(MagickBooleanType) argument_list[6].integer_reference;
8637 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8638 geometry.y,invert,exception);
8639 draw_info=DestroyDrawInfo(draw_info);
8640 break;
8641 }
8642 case 35: /* Composite */
8643 {
8644 char
cristy151b66d2015-04-15 10:50:31 +00008645 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008646
8647 Image
8648 *composite_image,
8649 *rotate_image;
8650
8651 MagickBooleanType
8652 clip_to_self;
8653
8654 compose=OverCompositeOp;
8655 if (attribute_flag[0] != 0)
8656 composite_image=argument_list[0].image_reference;
8657 else
8658 {
8659 ThrowPerlException(exception,OptionError,
8660 "CompositeImageRequired",PackageName);
8661 goto PerlException;
8662 }
8663 /*
8664 Parameter Handling used for BOTH normal and tiled composition.
8665 */
8666 if (attribute_flag[1] != 0) /* compose */
8667 compose=(CompositeOperator) argument_list[1].integer_reference;
8668 if (attribute_flag[6] != 0) /* opacity */
8669 {
8670 if (compose != DissolveCompositeOp)
8671 (void) SetImageAlpha(composite_image,(Quantum)
8672 StringToDoubleInterval(argument_list[6].string_reference,
8673 (double) QuantumRange+1.0),exception);
8674 else
8675 {
8676 CacheView
8677 *composite_view;
8678
8679 double
8680 opacity;
8681
8682 MagickBooleanType
8683 sync;
8684
8685 register ssize_t
8686 x;
8687
8688 register Quantum
8689 *q;
8690
8691 ssize_t
8692 y;
8693
8694 /*
8695 Handle dissolve composite operator (patch by
8696 Kevin A. McGrail).
8697 */
8698 (void) CloneString(&image->geometry,
8699 argument_list[6].string_reference);
8700 opacity=(Quantum) StringToDoubleInterval(
8701 argument_list[6].string_reference,(double) QuantumRange+
8702 1.0);
cristy17f11b02014-12-20 19:37:04 +00008703 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008704 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8705 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8706 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8707 {
8708 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8709 composite_image->columns,1,exception);
8710 for (x=0; x < (ssize_t) composite_image->columns; x++)
8711 {
8712 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8713 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8714 q);
8715 q+=GetPixelChannels(composite_image);
8716 }
8717 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8718 if (sync == MagickFalse)
8719 break;
8720 }
8721 composite_view=DestroyCacheView(composite_view);
8722 }
8723 }
8724 if (attribute_flag[9] != 0) /* "color=>" */
8725 QueryColorCompliance(argument_list[9].string_reference,
8726 AllCompliance,&composite_image->background_color,exception);
8727 if (attribute_flag[12] != 0) /* "interpolate=>" */
8728 image->interpolate=(PixelInterpolateMethod)
8729 argument_list[12].integer_reference;
8730 if (attribute_flag[13] != 0) /* "args=>" */
8731 (void) SetImageArtifact(composite_image,"compose:args",
8732 argument_list[13].string_reference);
8733 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8734 (void) SetImageArtifact(composite_image,"compose:args",
8735 argument_list[14].string_reference);
8736 clip_to_self=MagickTrue;
8737 if (attribute_flag[15] != 0)
8738 clip_to_self=(MagickBooleanType)
8739 argument_list[15].integer_reference;
8740 /*
8741 Tiling Composition (with orthogonal rotate).
8742 */
8743 rotate_image=(Image *) NULL;
8744 if (attribute_flag[8] != 0) /* "rotate=>" */
8745 {
8746 /*
8747 Rotate image.
8748 */
8749 rotate_image=RotateImage(composite_image,
8750 argument_list[8].real_reference,exception);
8751 if (rotate_image == (Image *) NULL)
8752 break;
8753 }
8754 if ((attribute_flag[7] != 0) &&
8755 (argument_list[7].integer_reference != 0)) /* tile */
8756 {
8757 ssize_t
8758 x,
8759 y;
8760
8761 /*
8762 Tile the composite image.
8763 */
8764 if (attribute_flag[8] != 0) /* "tile=>" */
8765 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8766 "false");
8767 else
8768 (void) SetImageArtifact(composite_image,
8769 "compose:outside-overlay","false");
8770 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8771 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8772 {
8773 if (attribute_flag[8] != 0) /* rotate */
8774 (void) CompositeImage(image,rotate_image,compose,
8775 MagickTrue,x,y,exception);
8776 else
8777 (void) CompositeImage(image,composite_image,compose,
8778 MagickTrue,x,y,exception);
8779 }
8780 if (attribute_flag[8] != 0) /* rotate */
8781 rotate_image=DestroyImage(rotate_image);
8782 break;
8783 }
8784 /*
8785 Parameter Handling used used ONLY for normal composition.
8786 */
8787 if (attribute_flag[5] != 0) /* gravity */
8788 image->gravity=(GravityType) argument_list[5].integer_reference;
8789 if (attribute_flag[2] != 0) /* geometry offset */
8790 {
8791 SetGeometry(image,&geometry);
8792 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8793 &geometry);
8794 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8795 &geometry);
8796 }
8797 if (attribute_flag[3] != 0) /* x offset */
8798 geometry.x=argument_list[3].integer_reference;
8799 if (attribute_flag[4] != 0) /* y offset */
8800 geometry.y=argument_list[4].integer_reference;
8801 if (attribute_flag[10] != 0) /* mask */
8802 {
8803 if ((image->compose == DisplaceCompositeOp) ||
8804 (image->compose == DistortCompositeOp))
8805 {
8806 /*
8807 Merge Y displacement into X displacement image.
8808 */
8809 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8810 exception);
8811 (void) CompositeImage(composite_image,
8812 argument_list[10].image_reference,CopyGreenCompositeOp,
8813 MagickTrue,0,0,exception);
8814 }
8815 else
8816 {
8817 Image
8818 *mask_image;
8819
8820 /*
8821 Set a blending mask for the composition.
8822 */
8823 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8824 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008825 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008826 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008827 mask_image=DestroyImage(mask_image);
8828 }
8829 }
8830 if (attribute_flag[11] != 0) /* channel */
8831 channel=(ChannelType) argument_list[11].integer_reference;
8832 /*
8833 Composite two images (normal composition).
8834 */
cristy151b66d2015-04-15 10:50:31 +00008835 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008836 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8837 (double) composite_image->rows,(double) geometry.x,(double)
8838 geometry.y);
8839 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8840 exception);
8841 channel_mask=SetImageChannelMask(image,channel);
8842 if (attribute_flag[8] == 0) /* no rotate */
8843 CompositeImage(image,composite_image,compose,clip_to_self,
8844 geometry.x,geometry.y,exception);
8845 else
8846 {
8847 /*
8848 Position adjust rotated image then composite.
8849 */
8850 geometry.x-=(ssize_t) (rotate_image->columns-
8851 composite_image->columns)/2;
8852 geometry.y-=(ssize_t) (rotate_image->rows-
8853 composite_image->rows)/2;
8854 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8855 geometry.y,exception);
8856 rotate_image=DestroyImage(rotate_image);
8857 }
8858 if (attribute_flag[10] != 0) /* mask */
8859 {
8860 if ((image->compose == DisplaceCompositeOp) ||
8861 (image->compose == DistortCompositeOp))
8862 composite_image=DestroyImage(composite_image);
8863 else
cristy1f7ffb72015-07-29 11:07:03 +00008864 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008865 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008866 }
8867 (void) SetImageChannelMask(image,channel_mask);
8868 break;
8869 }
8870 case 36: /* Contrast */
8871 {
8872 if (attribute_flag[0] == 0)
8873 argument_list[0].integer_reference=0;
8874 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8875 MagickTrue : MagickFalse,exception);
8876 break;
8877 }
8878 case 37: /* CycleColormap */
8879 {
8880 if (attribute_flag[0] == 0)
8881 argument_list[0].integer_reference=6;
8882 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8883 exception);
8884 break;
8885 }
8886 case 38: /* Draw */
8887 {
8888 DrawInfo
8889 *draw_info;
8890
8891 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8892 (DrawInfo *) NULL);
8893 (void) CloneString(&draw_info->primitive,"point");
8894 if (attribute_flag[0] != 0)
8895 {
8896 if (argument_list[0].integer_reference < 0)
8897 (void) CloneString(&draw_info->primitive,
8898 argument_list[0].string_reference);
8899 else
8900 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8901 MagickPrimitiveOptions,argument_list[0].integer_reference));
8902 }
8903 if (attribute_flag[1] != 0)
8904 {
8905 if (LocaleCompare(draw_info->primitive,"path") == 0)
8906 {
8907 (void) ConcatenateString(&draw_info->primitive," '");
8908 ConcatenateString(&draw_info->primitive,
8909 argument_list[1].string_reference);
8910 (void) ConcatenateString(&draw_info->primitive,"'");
8911 }
8912 else
8913 {
8914 (void) ConcatenateString(&draw_info->primitive," ");
8915 ConcatenateString(&draw_info->primitive,
8916 argument_list[1].string_reference);
8917 }
8918 }
8919 if (attribute_flag[2] != 0)
8920 {
8921 (void) ConcatenateString(&draw_info->primitive," ");
8922 (void) ConcatenateString(&draw_info->primitive,
8923 CommandOptionToMnemonic(MagickMethodOptions,
8924 argument_list[2].integer_reference));
8925 }
8926 if (attribute_flag[3] != 0)
8927 {
8928 (void) QueryColorCompliance(argument_list[3].string_reference,
8929 AllCompliance,&draw_info->stroke,exception);
8930 if (argument_list[3].image_reference != (Image *) NULL)
8931 draw_info->stroke_pattern=CloneImage(
8932 argument_list[3].image_reference,0,0,MagickTrue,exception);
8933 }
8934 if (attribute_flag[4] != 0)
8935 {
8936 (void) QueryColorCompliance(argument_list[4].string_reference,
8937 AllCompliance,&draw_info->fill,exception);
8938 if (argument_list[4].image_reference != (Image *) NULL)
8939 draw_info->fill_pattern=CloneImage(
8940 argument_list[4].image_reference,0,0,MagickTrue,exception);
8941 }
8942 if (attribute_flag[5] != 0)
8943 draw_info->stroke_width=argument_list[5].real_reference;
8944 if (attribute_flag[6] != 0)
8945 (void) CloneString(&draw_info->font,
8946 argument_list[6].string_reference);
8947 if (attribute_flag[7] != 0)
8948 (void) QueryColorCompliance(argument_list[7].string_reference,
8949 AllCompliance,&draw_info->border_color,exception);
8950 if (attribute_flag[8] != 0)
8951 draw_info->affine.tx=argument_list[8].real_reference;
8952 if (attribute_flag[9] != 0)
8953 draw_info->affine.ty=argument_list[9].real_reference;
8954 if (attribute_flag[20] != 0)
8955 {
8956 AV
8957 *av;
8958
8959 av=(AV *) argument_list[20].array_reference;
8960 if ((av_len(av) != 3) && (av_len(av) != 5))
8961 {
8962 ThrowPerlException(exception,OptionError,
8963 "affine matrix must have 4 or 6 elements",PackageName);
8964 goto PerlException;
8965 }
8966 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8967 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8968 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8969 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8970 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8971 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8972 {
8973 ThrowPerlException(exception,OptionError,
8974 "affine matrix is singular",PackageName);
8975 goto PerlException;
8976 }
8977 if (av_len(av) == 5)
8978 {
8979 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8980 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8981 }
8982 }
8983 for (j=10; j < 15; j++)
8984 {
8985 if (attribute_flag[j] == 0)
8986 continue;
8987 value=argument_list[j].string_reference;
8988 angle=argument_list[j].real_reference;
8989 current=draw_info->affine;
8990 GetAffineMatrix(&affine);
8991 switch (j)
8992 {
8993 case 10:
8994 {
8995 /*
8996 Translate.
8997 */
8998 flags=ParseGeometry(value,&geometry_info);
8999 affine.tx=geometry_info.xi;
9000 affine.ty=geometry_info.psi;
9001 if ((flags & PsiValue) == 0)
9002 affine.ty=affine.tx;
9003 break;
9004 }
9005 case 11:
9006 {
9007 /*
9008 Scale.
9009 */
9010 flags=ParseGeometry(value,&geometry_info);
9011 affine.sx=geometry_info.rho;
9012 affine.sy=geometry_info.sigma;
9013 if ((flags & SigmaValue) == 0)
9014 affine.sy=affine.sx;
9015 break;
9016 }
9017 case 12:
9018 {
9019 /*
9020 Rotate.
9021 */
9022 if (angle == 0.0)
9023 break;
9024 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9025 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9026 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9027 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9028 break;
9029 }
9030 case 13:
9031 {
9032 /*
9033 SkewX.
9034 */
9035 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9036 break;
9037 }
9038 case 14:
9039 {
9040 /*
9041 SkewY.
9042 */
9043 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9044 break;
9045 }
9046 }
9047 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9048 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9049 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9050 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9051 draw_info->affine.tx=
9052 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9053 draw_info->affine.ty=
9054 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9055 }
9056 if (attribute_flag[15] != 0)
9057 draw_info->fill_pattern=CloneImage(
9058 argument_list[15].image_reference,0,0,MagickTrue,exception);
9059 if (attribute_flag[16] != 0)
9060 draw_info->pointsize=argument_list[16].real_reference;
9061 if (attribute_flag[17] != 0)
9062 {
9063 draw_info->stroke_antialias=argument_list[17].integer_reference != 0
9064 ? MagickTrue : MagickFalse;
9065 draw_info->text_antialias=draw_info->stroke_antialias;
9066 }
9067 if (attribute_flag[18] != 0)
9068 (void) CloneString(&draw_info->density,
9069 argument_list[18].string_reference);
9070 if (attribute_flag[19] != 0)
9071 draw_info->stroke_width=argument_list[19].real_reference;
9072 if (attribute_flag[21] != 0)
9073 draw_info->dash_offset=argument_list[21].real_reference;
9074 if (attribute_flag[22] != 0)
9075 {
9076 AV
9077 *av;
9078
9079 av=(AV *) argument_list[22].array_reference;
9080 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9081 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9082 if (draw_info->dash_pattern != (double *) NULL)
9083 {
9084 for (i=0; i <= av_len(av); i++)
9085 draw_info->dash_pattern[i]=(double)
9086 SvNV(*(av_fetch(av,i,0)));
9087 draw_info->dash_pattern[i]=0.0;
9088 }
9089 }
9090 if (attribute_flag[23] != 0)
9091 image->interpolate=(PixelInterpolateMethod)
9092 argument_list[23].integer_reference;
9093 if ((attribute_flag[24] != 0) &&
9094 (draw_info->fill_pattern != (Image *) NULL))
9095 flags=ParsePageGeometry(draw_info->fill_pattern,
9096 argument_list[24].string_reference,
9097 &draw_info->fill_pattern->tile_offset,exception);
9098 if (attribute_flag[25] != 0)
9099 {
9100 (void) ConcatenateString(&draw_info->primitive," '");
9101 (void) ConcatenateString(&draw_info->primitive,
9102 argument_list[25].string_reference);
9103 (void) ConcatenateString(&draw_info->primitive,"'");
9104 }
9105 if (attribute_flag[26] != 0)
9106 draw_info->fill_pattern=CloneImage(
9107 argument_list[26].image_reference,0,0,MagickTrue,exception);
9108 if (attribute_flag[27] != 0)
9109 draw_info->stroke_pattern=CloneImage(
9110 argument_list[27].image_reference,0,0,MagickTrue,exception);
9111 if (attribute_flag[28] != 0)
9112 (void) CloneString(&draw_info->primitive,
9113 argument_list[28].string_reference);
9114 if (attribute_flag[29] != 0)
9115 draw_info->kerning=argument_list[29].real_reference;
9116 if (attribute_flag[30] != 0)
9117 draw_info->interline_spacing=argument_list[30].real_reference;
9118 if (attribute_flag[31] != 0)
9119 draw_info->interword_spacing=argument_list[31].real_reference;
9120 if (attribute_flag[32] != 0)
9121 draw_info->direction=(DirectionType)
9122 argument_list[32].integer_reference;
9123 DrawImage(image,draw_info,exception);
9124 draw_info=DestroyDrawInfo(draw_info);
9125 break;
9126 }
9127 case 39: /* Equalize */
9128 {
9129 if (attribute_flag[0] != 0)
9130 channel=(ChannelType) argument_list[0].integer_reference;
9131 channel_mask=SetImageChannelMask(image,channel);
9132 EqualizeImage(image,exception);
9133 (void) SetImageChannelMask(image,channel_mask);
9134 break;
9135 }
9136 case 40: /* Gamma */
9137 {
9138 if (attribute_flag[1] != 0)
9139 channel=(ChannelType) argument_list[1].integer_reference;
9140 if (attribute_flag[2] == 0)
9141 argument_list[2].real_reference=1.0;
9142 if (attribute_flag[3] == 0)
9143 argument_list[3].real_reference=1.0;
9144 if (attribute_flag[4] == 0)
9145 argument_list[4].real_reference=1.0;
9146 if (attribute_flag[0] == 0)
9147 {
cristy151b66d2015-04-15 10:50:31 +00009148 (void) FormatLocaleString(message,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -05009149 "%.20g,%.20g,%.20g",(double) argument_list[2].real_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009150 (double) argument_list[3].real_reference,
9151 (double) argument_list[4].real_reference);
9152 argument_list[0].string_reference=message;
9153 }
9154 (void) GammaImage(image,StringToDouble(
9155 argument_list[0].string_reference,(char **) NULL),exception);
9156 break;
9157 }
9158 case 41: /* Map */
9159 {
9160 QuantizeInfo
9161 *quantize_info;
9162
9163 if (attribute_flag[0] == 0)
9164 {
9165 ThrowPerlException(exception,OptionError,"MapImageRequired",
9166 PackageName);
9167 goto PerlException;
9168 }
9169 quantize_info=AcquireQuantizeInfo(info->image_info);
9170 if (attribute_flag[1] != 0)
9171 quantize_info->dither_method=(DitherMethod)
9172 argument_list[1].integer_reference;
9173 (void) RemapImages(quantize_info,image,
9174 argument_list[0].image_reference,exception);
9175 quantize_info=DestroyQuantizeInfo(quantize_info);
9176 break;
9177 }
9178 case 42: /* MatteFloodfill */
9179 {
9180 DrawInfo
9181 *draw_info;
9182
9183 MagickBooleanType
9184 invert;
9185
9186 PixelInfo
9187 target;
9188
9189 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9190 (DrawInfo *) NULL);
9191 if (attribute_flag[0] != 0)
9192 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9193 &geometry,exception);
9194 if (attribute_flag[1] != 0)
9195 geometry.x=argument_list[1].integer_reference;
9196 if (attribute_flag[2] != 0)
9197 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009198 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009199 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9200 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9201 geometry.x,geometry.y,&target,exception);
9202 if (attribute_flag[4] != 0)
9203 QueryColorCompliance(argument_list[4].string_reference,
9204 AllCompliance,&target,exception);
9205 if (attribute_flag[3] != 0)
9206 target.alpha=StringToDoubleInterval(
9207 argument_list[3].string_reference,(double) (double) QuantumRange+
9208 1.0);
9209 if (attribute_flag[5] != 0)
9210 image->fuzz=StringToDoubleInterval(
9211 argument_list[5].string_reference,(double) QuantumRange+1.0);
9212 invert=MagickFalse;
9213 if (attribute_flag[6] != 0)
9214 invert=(MagickBooleanType) argument_list[6].integer_reference;
9215 channel_mask=SetImageChannelMask(image,AlphaChannel);
9216 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9217 geometry.y,invert,exception);
9218 (void) SetImageChannelMask(image,channel_mask);
9219 draw_info=DestroyDrawInfo(draw_info);
9220 break;
9221 }
9222 case 43: /* Modulate */
9223 {
9224 char
cristy151b66d2015-04-15 10:50:31 +00009225 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009226
9227 geometry_info.rho=100.0;
9228 geometry_info.sigma=100.0;
9229 geometry_info.xi=100.0;
9230 if (attribute_flag[0] != 0)
9231 (void)ParseGeometry(argument_list[0].string_reference,
9232 &geometry_info);
9233 if (attribute_flag[1] != 0)
9234 geometry_info.xi=argument_list[1].real_reference;
9235 if (attribute_flag[2] != 0)
9236 geometry_info.sigma=argument_list[2].real_reference;
9237 if (attribute_flag[3] != 0)
9238 {
9239 geometry_info.sigma=argument_list[3].real_reference;
9240 SetImageArtifact(image,"modulate:colorspace","HWB");
9241 }
9242 if (attribute_flag[4] != 0)
9243 {
9244 geometry_info.rho=argument_list[4].real_reference;
9245 SetImageArtifact(image,"modulate:colorspace","HSB");
9246 }
9247 if (attribute_flag[5] != 0)
9248 {
9249 geometry_info.sigma=argument_list[5].real_reference;
9250 SetImageArtifact(image,"modulate:colorspace","HSL");
9251 }
9252 if (attribute_flag[6] != 0)
9253 {
9254 geometry_info.rho=argument_list[6].real_reference;
9255 SetImageArtifact(image,"modulate:colorspace","HWB");
9256 }
Cristy935a4052017-03-31 17:45:37 -04009257 (void) FormatLocaleString(modulate,MagickPathExtent,"%.20g,%.20g,%.20g",
9258 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy4a3ce0a2013-08-03 20:06:59 +00009259 (void) ModulateImage(image,modulate,exception);
9260 break;
9261 }
9262 case 44: /* Negate */
9263 {
9264 if (attribute_flag[0] == 0)
9265 argument_list[0].integer_reference=0;
9266 if (attribute_flag[1] != 0)
9267 channel=(ChannelType) argument_list[1].integer_reference;
9268 channel_mask=SetImageChannelMask(image,channel);
9269 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9270 MagickTrue : MagickFalse,exception);
9271 (void) SetImageChannelMask(image,channel_mask);
9272 break;
9273 }
9274 case 45: /* Normalize */
9275 {
9276 if (attribute_flag[0] != 0)
9277 channel=(ChannelType) argument_list[0].integer_reference;
9278 channel_mask=SetImageChannelMask(image,channel);
9279 NormalizeImage(image,exception);
9280 (void) SetImageChannelMask(image,channel_mask);
9281 break;
9282 }
9283 case 46: /* NumberColors */
9284 break;
9285 case 47: /* Opaque */
9286 {
9287 MagickBooleanType
9288 invert;
9289
9290 PixelInfo
9291 fill_color,
9292 target;
9293
9294 (void) QueryColorCompliance("none",AllCompliance,&target,
9295 exception);
9296 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9297 exception);
9298 if (attribute_flag[0] != 0)
9299 (void) QueryColorCompliance(argument_list[0].string_reference,
9300 AllCompliance,&target,exception);
9301 if (attribute_flag[1] != 0)
9302 (void) QueryColorCompliance(argument_list[1].string_reference,
9303 AllCompliance,&fill_color,exception);
9304 if (attribute_flag[2] != 0)
9305 image->fuzz=StringToDoubleInterval(
9306 argument_list[2].string_reference,(double) QuantumRange+1.0);
9307 if (attribute_flag[3] != 0)
9308 channel=(ChannelType) argument_list[3].integer_reference;
9309 invert=MagickFalse;
9310 if (attribute_flag[4] != 0)
9311 invert=(MagickBooleanType) argument_list[4].integer_reference;
9312 channel_mask=SetImageChannelMask(image,channel);
9313 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9314 (void) SetImageChannelMask(image,channel_mask);
9315 break;
9316 }
9317 case 48: /* Quantize */
9318 {
9319 QuantizeInfo
9320 *quantize_info;
9321
9322 quantize_info=AcquireQuantizeInfo(info->image_info);
9323 if (attribute_flag[0] != 0)
9324 quantize_info->number_colors=(size_t)
9325 argument_list[0].integer_reference;
9326 if (attribute_flag[1] != 0)
9327 quantize_info->tree_depth=(size_t)
9328 argument_list[1].integer_reference;
9329 if (attribute_flag[2] != 0)
9330 quantize_info->colorspace=(ColorspaceType)
9331 argument_list[2].integer_reference;
9332 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009333 quantize_info->dither_method=(DitherMethod)
9334 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009335 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009336 quantize_info->measure_error=
9337 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009338 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009339 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009340 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009341 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009342 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009343 argument_list[7].integer_reference;
9344 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009345 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009346 else
cristyf7563392014-03-25 13:54:04 +00009347 if ((image->storage_class == DirectClass) ||
9348 (image->colors > quantize_info->number_colors) ||
9349 (quantize_info->colorspace == GRAYColorspace))
9350 (void) QuantizeImage(quantize_info,image,exception);
9351 else
9352 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009353 quantize_info=DestroyQuantizeInfo(quantize_info);
9354 break;
9355 }
9356 case 49: /* Raise */
9357 {
9358 if (attribute_flag[0] != 0)
9359 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9360 &geometry,exception);
9361 if (attribute_flag[1] != 0)
9362 geometry.width=argument_list[1].integer_reference;
9363 if (attribute_flag[2] != 0)
9364 geometry.height=argument_list[2].integer_reference;
9365 if (attribute_flag[3] == 0)
9366 argument_list[3].integer_reference=1;
9367 (void) RaiseImage(image,&geometry,
9368 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9369 exception);
9370 break;
9371 }
9372 case 50: /* Segment */
9373 {
9374 ColorspaceType
9375 colorspace;
9376
9377 double
9378 cluster_threshold,
9379 smoothing_threshold;
9380
9381 MagickBooleanType
9382 verbose;
9383
9384 cluster_threshold=1.0;
9385 smoothing_threshold=1.5;
9386 colorspace=sRGBColorspace;
9387 verbose=MagickFalse;
9388 if (attribute_flag[0] != 0)
9389 {
9390 flags=ParseGeometry(argument_list[0].string_reference,
9391 &geometry_info);
9392 cluster_threshold=geometry_info.rho;
9393 if (flags & SigmaValue)
9394 smoothing_threshold=geometry_info.sigma;
9395 }
9396 if (attribute_flag[1] != 0)
9397 cluster_threshold=argument_list[1].real_reference;
9398 if (attribute_flag[2] != 0)
9399 smoothing_threshold=argument_list[2].real_reference;
9400 if (attribute_flag[3] != 0)
9401 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9402 if (attribute_flag[4] != 0)
9403 verbose=argument_list[4].integer_reference != 0 ?
9404 MagickTrue : MagickFalse;
9405 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9406 smoothing_threshold,exception);
9407 break;
9408 }
9409 case 51: /* Signature */
9410 {
9411 (void) SignatureImage(image,exception);
9412 break;
9413 }
9414 case 52: /* Solarize */
9415 {
9416 geometry_info.rho=QuantumRange/2.0;
9417 if (attribute_flag[0] != 0)
9418 flags=ParseGeometry(argument_list[0].string_reference,
9419 &geometry_info);
9420 if (attribute_flag[1] != 0)
9421 geometry_info.rho=StringToDoubleInterval(
9422 argument_list[1].string_reference,(double) QuantumRange+1.0);
9423 (void) SolarizeImage(image,geometry_info.rho,exception);
9424 break;
9425 }
9426 case 53: /* Sync */
9427 {
9428 (void) SyncImage(image,exception);
9429 break;
9430 }
9431 case 54: /* Texture */
9432 {
9433 if (attribute_flag[0] == 0)
9434 break;
9435 TextureImage(image,argument_list[0].image_reference,exception);
9436 break;
9437 }
9438 case 55: /* Evalute */
9439 {
9440 MagickEvaluateOperator
9441 op;
9442
9443 op=SetEvaluateOperator;
9444 if (attribute_flag[0] == MagickFalse)
9445 argument_list[0].real_reference=0.0;
9446 if (attribute_flag[1] != MagickFalse)
9447 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9448 if (attribute_flag[2] != MagickFalse)
9449 channel=(ChannelType) argument_list[2].integer_reference;
9450 channel_mask=SetImageChannelMask(image,channel);
9451 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9452 exception);
9453 (void) SetImageChannelMask(image,channel_mask);
9454 break;
9455 }
9456 case 56: /* Transparent */
9457 {
9458 double
9459 opacity;
9460
9461 MagickBooleanType
9462 invert;
9463
9464 PixelInfo
9465 target;
9466
9467 (void) QueryColorCompliance("none",AllCompliance,&target,
9468 exception);
9469 if (attribute_flag[0] != 0)
9470 (void) QueryColorCompliance(argument_list[0].string_reference,
9471 AllCompliance,&target,exception);
9472 opacity=TransparentAlpha;
9473 if (attribute_flag[1] != 0)
9474 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9475 (double) QuantumRange+1.0);
9476 if (attribute_flag[2] != 0)
9477 image->fuzz=StringToDoubleInterval(
9478 argument_list[2].string_reference,(double) QuantumRange+1.0);
9479 if (attribute_flag[3] == 0)
9480 argument_list[3].integer_reference=0;
9481 invert=MagickFalse;
9482 if (attribute_flag[3] != 0)
9483 invert=(MagickBooleanType) argument_list[3].integer_reference;
9484 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9485 invert,exception);
9486 break;
9487 }
9488 case 57: /* Threshold */
9489 {
9490 double
9491 threshold;
9492
9493 if (attribute_flag[0] == 0)
9494 argument_list[0].string_reference="50%";
9495 if (attribute_flag[1] != 0)
9496 channel=(ChannelType) argument_list[1].integer_reference;
9497 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9498 (double) QuantumRange+1.0);
9499 channel_mask=SetImageChannelMask(image,channel);
9500 (void) BilevelImage(image,threshold,exception);
9501 (void) SetImageChannelMask(image,channel_mask);
9502 break;
9503 }
9504 case 58: /* Charcoal */
9505 {
9506 if (attribute_flag[0] != 0)
9507 {
9508 flags=ParseGeometry(argument_list[0].string_reference,
9509 &geometry_info);
9510 if ((flags & SigmaValue) == 0)
9511 geometry_info.sigma=1.0;
9512 }
9513 if (attribute_flag[1] != 0)
9514 geometry_info.rho=argument_list[1].real_reference;
9515 if (attribute_flag[2] != 0)
9516 geometry_info.sigma=argument_list[2].real_reference;
9517 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9518 exception);
9519 break;
9520 }
9521 case 59: /* Trim */
9522 {
9523 if (attribute_flag[0] != 0)
9524 image->fuzz=StringToDoubleInterval(
9525 argument_list[0].string_reference,(double) QuantumRange+1.0);
9526 image=TrimImage(image,exception);
9527 break;
9528 }
9529 case 60: /* Wave */
9530 {
9531 PixelInterpolateMethod
9532 method;
9533
9534 if (attribute_flag[0] != 0)
9535 {
9536 flags=ParseGeometry(argument_list[0].string_reference,
9537 &geometry_info);
9538 if ((flags & SigmaValue) == 0)
9539 geometry_info.sigma=1.0;
9540 }
9541 if (attribute_flag[1] != 0)
9542 geometry_info.rho=argument_list[1].real_reference;
9543 if (attribute_flag[2] != 0)
9544 geometry_info.sigma=argument_list[2].real_reference;
9545 method=UndefinedInterpolatePixel;
9546 if (attribute_flag[3] != 0)
9547 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9548 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9549 method,exception);
9550 break;
9551 }
9552 case 61: /* Separate */
9553 {
9554 if (attribute_flag[0] != 0)
9555 channel=(ChannelType) argument_list[0].integer_reference;
9556 image=SeparateImage(image,channel,exception);
9557 break;
9558 }
9559 case 63: /* Stereo */
9560 {
9561 if (attribute_flag[0] == 0)
9562 {
9563 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9564 PackageName);
9565 goto PerlException;
9566 }
9567 if (attribute_flag[1] != 0)
9568 geometry.x=argument_list[1].integer_reference;
9569 if (attribute_flag[2] != 0)
9570 geometry.y=argument_list[2].integer_reference;
9571 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9572 geometry.x,geometry.y,exception);
9573 break;
9574 }
9575 case 64: /* Stegano */
9576 {
9577 if (attribute_flag[0] == 0)
9578 {
9579 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9580 PackageName);
9581 goto PerlException;
9582 }
9583 if (attribute_flag[1] == 0)
9584 argument_list[1].integer_reference=0;
9585 image->offset=argument_list[1].integer_reference;
9586 image=SteganoImage(image,argument_list[0].image_reference,exception);
9587 break;
9588 }
9589 case 65: /* Deconstruct */
9590 {
9591 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9592 break;
9593 }
9594 case 66: /* GaussianBlur */
9595 {
9596 if (attribute_flag[0] != 0)
9597 {
9598 flags=ParseGeometry(argument_list[0].string_reference,
9599 &geometry_info);
9600 if ((flags & SigmaValue) == 0)
9601 geometry_info.sigma=1.0;
9602 }
9603 if (attribute_flag[1] != 0)
9604 geometry_info.rho=argument_list[1].real_reference;
9605 if (attribute_flag[2] != 0)
9606 geometry_info.sigma=argument_list[2].real_reference;
9607 if (attribute_flag[3] != 0)
9608 channel=(ChannelType) argument_list[3].integer_reference;
9609 channel_mask=SetImageChannelMask(image,channel);
9610 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9611 exception);
9612 if (image != (Image *) NULL)
9613 (void) SetImageChannelMask(image,channel_mask);
9614 break;
9615 }
9616 case 67: /* Convolve */
9617 {
9618 KernelInfo
9619 *kernel;
9620
9621 kernel=(KernelInfo *) NULL;
9622 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9623 break;
9624 if (attribute_flag[0] != 0)
9625 {
9626 AV
9627 *av;
9628
9629 size_t
9630 order;
9631
cristy2c57b742014-10-31 00:40:34 +00009632 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009633 if (kernel == (KernelInfo *) NULL)
9634 break;
9635 av=(AV *) argument_list[0].array_reference;
9636 order=(size_t) sqrt(av_len(av)+1);
9637 kernel->width=order;
9638 kernel->height=order;
9639 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9640 order*sizeof(*kernel->values));
9641 if (kernel->values == (MagickRealType *) NULL)
9642 {
9643 kernel=DestroyKernelInfo(kernel);
9644 ThrowPerlException(exception,ResourceLimitFatalError,
9645 "MemoryAllocationFailed",PackageName);
9646 goto PerlException;
9647 }
9648 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9649 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9650 for ( ; j < (ssize_t) (order*order); j++)
9651 kernel->values[j]=0.0;
9652 }
9653 if (attribute_flag[1] != 0)
9654 channel=(ChannelType) argument_list[1].integer_reference;
9655 if (attribute_flag[2] != 0)
9656 SetImageArtifact(image,"filter:blur",
9657 argument_list[2].string_reference);
9658 if (attribute_flag[3] != 0)
9659 {
cristy2c57b742014-10-31 00:40:34 +00009660 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9661 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009662 if (kernel == (KernelInfo *) NULL)
9663 break;
9664 }
9665 channel_mask=SetImageChannelMask(image,channel);
9666 image=ConvolveImage(image,kernel,exception);
9667 if (image != (Image *) NULL)
9668 (void) SetImageChannelMask(image,channel_mask);
9669 kernel=DestroyKernelInfo(kernel);
9670 break;
9671 }
9672 case 68: /* Profile */
9673 {
9674 const char
9675 *name;
9676
9677 Image
9678 *profile_image;
9679
9680 ImageInfo
9681 *profile_info;
9682
9683 StringInfo
9684 *profile;
9685
9686 name="*";
9687 if (attribute_flag[0] != 0)
9688 name=argument_list[0].string_reference;
9689 if (attribute_flag[2] != 0)
9690 image->rendering_intent=(RenderingIntent)
9691 argument_list[2].integer_reference;
9692 if (attribute_flag[3] != 0)
9693 image->black_point_compensation=
9694 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9695 if (attribute_flag[1] != 0)
9696 {
9697 if (argument_list[1].length == 0)
9698 {
9699 /*
9700 Remove a profile from the image.
9701 */
9702 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9703 exception);
9704 break;
9705 }
9706 /*
9707 Associate user supplied profile with the image.
9708 */
9709 profile=AcquireStringInfo(argument_list[1].length);
9710 SetStringInfoDatum(profile,(const unsigned char *)
9711 argument_list[1].string_reference);
9712 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9713 (size_t) GetStringInfoLength(profile),exception);
9714 profile=DestroyStringInfo(profile);
9715 break;
9716 }
9717 /*
9718 Associate a profile with the image.
9719 */
9720 profile_info=CloneImageInfo(info ? info->image_info :
9721 (ImageInfo *) NULL);
9722 profile_image=ReadImages(profile_info,name,exception);
9723 if (profile_image == (Image *) NULL)
9724 break;
9725 ResetImageProfileIterator(profile_image);
9726 name=GetNextImageProfile(profile_image);
9727 while (name != (const char *) NULL)
9728 {
9729 const StringInfo
9730 *profile;
9731
9732 profile=GetImageProfile(profile_image,name);
9733 if (profile != (const StringInfo *) NULL)
9734 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9735 (size_t) GetStringInfoLength(profile),exception);
9736 name=GetNextImageProfile(profile_image);
9737 }
9738 profile_image=DestroyImage(profile_image);
9739 profile_info=DestroyImageInfo(profile_info);
9740 break;
9741 }
9742 case 69: /* UnsharpMask */
9743 {
9744 if (attribute_flag[0] != 0)
9745 {
9746 flags=ParseGeometry(argument_list[0].string_reference,
9747 &geometry_info);
9748 if ((flags & SigmaValue) == 0)
9749 geometry_info.sigma=1.0;
9750 if ((flags & XiValue) == 0)
9751 geometry_info.xi=1.0;
9752 if ((flags & PsiValue) == 0)
9753 geometry_info.psi=0.5;
9754 }
9755 if (attribute_flag[1] != 0)
9756 geometry_info.rho=argument_list[1].real_reference;
9757 if (attribute_flag[2] != 0)
9758 geometry_info.sigma=argument_list[2].real_reference;
9759 if (attribute_flag[3] != 0)
9760 geometry_info.xi=argument_list[3].real_reference;
9761 if (attribute_flag[4] != 0)
9762 geometry_info.psi=argument_list[4].real_reference;
9763 if (attribute_flag[5] != 0)
9764 channel=(ChannelType) argument_list[5].integer_reference;
9765 channel_mask=SetImageChannelMask(image,channel);
9766 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9767 geometry_info.xi,geometry_info.psi,exception);
9768 if (image != (Image *) NULL)
9769 (void) SetImageChannelMask(image,channel_mask);
9770 break;
9771 }
9772 case 70: /* MotionBlur */
9773 {
9774 if (attribute_flag[0] != 0)
9775 {
9776 flags=ParseGeometry(argument_list[0].string_reference,
9777 &geometry_info);
9778 if ((flags & SigmaValue) == 0)
9779 geometry_info.sigma=1.0;
9780 if ((flags & XiValue) == 0)
9781 geometry_info.xi=1.0;
9782 }
9783 if (attribute_flag[1] != 0)
9784 geometry_info.rho=argument_list[1].real_reference;
9785 if (attribute_flag[2] != 0)
9786 geometry_info.sigma=argument_list[2].real_reference;
9787 if (attribute_flag[3] != 0)
9788 geometry_info.xi=argument_list[3].real_reference;
9789 if (attribute_flag[4] != 0)
9790 channel=(ChannelType) argument_list[4].integer_reference;
9791 channel_mask=SetImageChannelMask(image,channel);
9792 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9793 geometry_info.xi,exception);
9794 if (image != (Image *) NULL)
9795 (void) SetImageChannelMask(image,channel_mask);
9796 break;
9797 }
9798 case 71: /* OrderedDither */
9799 {
9800 if (attribute_flag[0] == 0)
9801 argument_list[0].string_reference="o8x8";
9802 if (attribute_flag[1] != 0)
9803 channel=(ChannelType) argument_list[1].integer_reference;
9804 channel_mask=SetImageChannelMask(image,channel);
Cristy6b93c072016-02-04 07:45:48 -05009805 (void) OrderedDitherImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009806 exception);
9807 (void) SetImageChannelMask(image,channel_mask);
9808 break;
9809 }
9810 case 72: /* Shave */
9811 {
9812 if (attribute_flag[0] != 0)
9813 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9814 &geometry,exception);
9815 if (attribute_flag[1] != 0)
9816 geometry.width=argument_list[1].integer_reference;
9817 if (attribute_flag[2] != 0)
9818 geometry.height=argument_list[2].integer_reference;
9819 image=ShaveImage(image,&geometry,exception);
9820 break;
9821 }
9822 case 73: /* Level */
9823 {
9824 double
9825 black_point,
9826 gamma,
9827 white_point;
9828
9829 black_point=0.0;
9830 white_point=(double) image->columns*image->rows;
9831 gamma=1.0;
9832 if (attribute_flag[0] != 0)
9833 {
9834 flags=ParseGeometry(argument_list[0].string_reference,
9835 &geometry_info);
9836 black_point=geometry_info.rho;
9837 if ((flags & SigmaValue) != 0)
9838 white_point=geometry_info.sigma;
9839 if ((flags & XiValue) != 0)
9840 gamma=geometry_info.xi;
9841 if ((flags & PercentValue) != 0)
9842 {
9843 black_point*=(double) (QuantumRange/100.0);
9844 white_point*=(double) (QuantumRange/100.0);
9845 }
9846 if ((flags & SigmaValue) == 0)
9847 white_point=(double) QuantumRange-black_point;
9848 }
9849 if (attribute_flag[1] != 0)
9850 black_point=argument_list[1].real_reference;
9851 if (attribute_flag[2] != 0)
9852 white_point=argument_list[2].real_reference;
9853 if (attribute_flag[3] != 0)
9854 gamma=argument_list[3].real_reference;
9855 if (attribute_flag[4] != 0)
9856 channel=(ChannelType) argument_list[4].integer_reference;
9857 if (attribute_flag[5] != 0)
9858 {
9859 argument_list[0].real_reference=argument_list[5].real_reference;
9860 attribute_flag[0]=attribute_flag[5];
9861 }
9862 channel_mask=SetImageChannelMask(image,channel);
9863 (void) LevelImage(image,black_point,white_point,gamma,exception);
9864 (void) SetImageChannelMask(image,channel_mask);
9865 break;
9866 }
9867 case 74: /* Clip */
9868 {
9869 if (attribute_flag[0] == 0)
9870 argument_list[0].string_reference="#1";
9871 if (attribute_flag[1] == 0)
9872 argument_list[1].integer_reference=MagickTrue;
9873 (void) ClipImagePath(image,argument_list[0].string_reference,
9874 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9875 exception);
9876 break;
9877 }
9878 case 75: /* AffineTransform */
9879 {
9880 DrawInfo
9881 *draw_info;
9882
9883 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9884 (DrawInfo *) NULL);
9885 if (attribute_flag[0] != 0)
9886 {
9887 AV
9888 *av;
9889
9890 av=(AV *) argument_list[0].array_reference;
9891 if ((av_len(av) != 3) && (av_len(av) != 5))
9892 {
9893 ThrowPerlException(exception,OptionError,
9894 "affine matrix must have 4 or 6 elements",PackageName);
9895 goto PerlException;
9896 }
9897 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9898 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9899 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9900 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9901 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9902 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9903 {
9904 ThrowPerlException(exception,OptionError,
9905 "affine matrix is singular",PackageName);
9906 goto PerlException;
9907 }
9908 if (av_len(av) == 5)
9909 {
9910 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9911 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9912 }
9913 }
9914 for (j=1; j < 6; j++)
9915 {
9916 if (attribute_flag[j] == 0)
9917 continue;
9918 value=argument_list[j].string_reference;
9919 angle=argument_list[j].real_reference;
9920 current=draw_info->affine;
9921 GetAffineMatrix(&affine);
9922 switch (j)
9923 {
9924 case 1:
9925 {
9926 /*
9927 Translate.
9928 */
9929 flags=ParseGeometry(value,&geometry_info);
9930 affine.tx=geometry_info.xi;
9931 affine.ty=geometry_info.psi;
9932 if ((flags & PsiValue) == 0)
9933 affine.ty=affine.tx;
9934 break;
9935 }
9936 case 2:
9937 {
9938 /*
9939 Scale.
9940 */
9941 flags=ParseGeometry(value,&geometry_info);
9942 affine.sx=geometry_info.rho;
9943 affine.sy=geometry_info.sigma;
9944 if ((flags & SigmaValue) == 0)
9945 affine.sy=affine.sx;
9946 break;
9947 }
9948 case 3:
9949 {
9950 /*
9951 Rotate.
9952 */
9953 if (angle == 0.0)
9954 break;
9955 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9956 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9957 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9958 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9959 break;
9960 }
9961 case 4:
9962 {
9963 /*
9964 SkewX.
9965 */
9966 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9967 break;
9968 }
9969 case 5:
9970 {
9971 /*
9972 SkewY.
9973 */
9974 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9975 break;
9976 }
9977 }
9978 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9979 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9980 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9981 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9982 draw_info->affine.tx=
9983 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9984 draw_info->affine.ty=
9985 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9986 }
9987 if (attribute_flag[6] != 0)
9988 image->interpolate=(PixelInterpolateMethod)
9989 argument_list[6].integer_reference;
9990 if (attribute_flag[7] != 0)
9991 QueryColorCompliance(argument_list[7].string_reference,
9992 AllCompliance,&image->background_color,exception);
9993 image=AffineTransformImage(image,&draw_info->affine,exception);
9994 draw_info=DestroyDrawInfo(draw_info);
9995 break;
9996 }
9997 case 76: /* Difference */
9998 {
9999 if (attribute_flag[0] == 0)
10000 {
10001 ThrowPerlException(exception,OptionError,
10002 "ReferenceImageRequired",PackageName);
10003 goto PerlException;
10004 }
10005 if (attribute_flag[1] != 0)
10006 image->fuzz=StringToDoubleInterval(
10007 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -050010008 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +000010009 exception);
10010 break;
10011 }
10012 case 77: /* AdaptiveThreshold */
10013 {
10014 if (attribute_flag[0] != 0)
10015 {
10016 flags=ParseGeometry(argument_list[0].string_reference,
10017 &geometry_info);
10018 if ((flags & PercentValue) != 0)
10019 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10020 }
10021 if (attribute_flag[1] != 0)
10022 geometry_info.rho=argument_list[1].integer_reference;
10023 if (attribute_flag[2] != 0)
10024 geometry_info.sigma=argument_list[2].integer_reference;
10025 if (attribute_flag[3] != 0)
10026 geometry_info.xi=argument_list[3].integer_reference;;
10027 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
10028 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
10029 break;
10030 }
10031 case 78: /* Resample */
10032 {
10033 size_t
10034 height,
10035 width;
10036
10037 if (attribute_flag[0] != 0)
10038 {
10039 flags=ParseGeometry(argument_list[0].string_reference,
10040 &geometry_info);
10041 if ((flags & SigmaValue) == 0)
10042 geometry_info.sigma=geometry_info.rho;
10043 }
10044 if (attribute_flag[1] != 0)
10045 geometry_info.rho=argument_list[1].real_reference;
10046 if (attribute_flag[2] != 0)
10047 geometry_info.sigma=argument_list[2].real_reference;
10048 if (attribute_flag[3] == 0)
10049 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10050 if (attribute_flag[4] == 0)
10051 SetImageArtifact(image,"filter:support",
10052 argument_list[4].string_reference);
10053 width=(size_t) (geometry_info.rho*image->columns/
10054 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10055 height=(size_t) (geometry_info.sigma*image->rows/
10056 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
Cristy8645e042016-02-03 16:35:29 -050010057 image=ResizeImage(image,width,height,(FilterType)
cristy4a3ce0a2013-08-03 20:06:59 +000010058 argument_list[3].integer_reference,exception);
10059 if (image != (Image *) NULL)
10060 {
10061 image->resolution.x=geometry_info.rho;
10062 image->resolution.y=geometry_info.sigma;
10063 }
10064 break;
10065 }
10066 case 79: /* Describe */
10067 {
10068 if (attribute_flag[0] == 0)
10069 argument_list[0].file_reference=(FILE *) NULL;
10070 if (attribute_flag[1] != 0)
10071 (void) SetImageArtifact(image,"identify:features",
10072 argument_list[1].string_reference);
10073 (void) IdentifyImage(image,argument_list[0].file_reference,
10074 MagickTrue,exception);
10075 break;
10076 }
10077 case 80: /* BlackThreshold */
10078 {
10079 if (attribute_flag[0] == 0)
10080 argument_list[0].string_reference="50%";
10081 if (attribute_flag[2] != 0)
10082 channel=(ChannelType) argument_list[2].integer_reference;
10083 channel_mask=SetImageChannelMask(image,channel);
10084 BlackThresholdImage(image,argument_list[0].string_reference,
10085 exception);
10086 (void) SetImageChannelMask(image,channel_mask);
10087 break;
10088 }
10089 case 81: /* WhiteThreshold */
10090 {
10091 if (attribute_flag[0] == 0)
10092 argument_list[0].string_reference="50%";
10093 if (attribute_flag[2] != 0)
10094 channel=(ChannelType) argument_list[2].integer_reference;
10095 channel_mask=SetImageChannelMask(image,channel);
10096 WhiteThresholdImage(image,argument_list[0].string_reference,
10097 exception);
10098 (void) SetImageChannelMask(image,channel_mask);
10099 break;
10100 }
cristy60c73c02014-03-25 12:09:58 +000010101 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010102 {
10103 if (attribute_flag[0] != 0)
10104 {
10105 flags=ParseGeometry(argument_list[0].string_reference,
10106 &geometry_info);
10107 }
10108 if (attribute_flag[1] != 0)
10109 geometry_info.rho=argument_list[1].real_reference;
10110 if (attribute_flag[2] != 0)
10111 channel=(ChannelType) argument_list[2].integer_reference;
10112 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010113 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010114 if (image != (Image *) NULL)
10115 (void) SetImageChannelMask(image,channel_mask);
10116 break;
10117 }
10118 case 83: /* Thumbnail */
10119 {
10120 if (attribute_flag[0] != 0)
10121 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10122 &geometry,exception);
10123 if (attribute_flag[1] != 0)
10124 geometry.width=argument_list[1].integer_reference;
10125 if (attribute_flag[2] != 0)
10126 geometry.height=argument_list[2].integer_reference;
10127 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10128 break;
10129 }
10130 case 84: /* Strip */
10131 {
10132 (void) StripImage(image,exception);
10133 break;
10134 }
10135 case 85: /* Tint */
10136 {
10137 PixelInfo
10138 tint;
10139
10140 GetPixelInfo(image,&tint);
10141 if (attribute_flag[0] != 0)
10142 (void) QueryColorCompliance(argument_list[0].string_reference,
10143 AllCompliance,&tint,exception);
10144 if (attribute_flag[1] == 0)
10145 argument_list[1].string_reference="100";
10146 image=TintImage(image,argument_list[1].string_reference,&tint,
10147 exception);
10148 break;
10149 }
10150 case 86: /* Channel */
10151 {
10152 if (attribute_flag[0] != 0)
10153 channel=(ChannelType) argument_list[0].integer_reference;
10154 image=SeparateImage(image,channel,exception);
10155 break;
10156 }
10157 case 87: /* Splice */
10158 {
cristy260bd762014-08-15 12:46:34 +000010159 if (attribute_flag[7] != 0)
10160 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010161 if (attribute_flag[0] != 0)
10162 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10163 &geometry,exception);
10164 if (attribute_flag[1] != 0)
10165 geometry.width=argument_list[1].integer_reference;
10166 if (attribute_flag[2] != 0)
10167 geometry.height=argument_list[2].integer_reference;
10168 if (attribute_flag[3] != 0)
10169 geometry.x=argument_list[3].integer_reference;
10170 if (attribute_flag[4] != 0)
10171 geometry.y=argument_list[4].integer_reference;
10172 if (attribute_flag[5] != 0)
10173 image->fuzz=StringToDoubleInterval(
10174 argument_list[5].string_reference,(double) QuantumRange+1.0);
10175 if (attribute_flag[6] != 0)
10176 (void) QueryColorCompliance(argument_list[6].string_reference,
10177 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010178 image=SpliceImage(image,&geometry,exception);
10179 break;
10180 }
10181 case 88: /* Posterize */
10182 {
10183 if (attribute_flag[0] == 0)
10184 argument_list[0].integer_reference=3;
10185 if (attribute_flag[1] == 0)
10186 argument_list[1].integer_reference=0;
10187 (void) PosterizeImage(image,argument_list[0].integer_reference,
10188 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10189 NoDitherMethod,exception);
10190 break;
10191 }
10192 case 89: /* Shadow */
10193 {
10194 if (attribute_flag[0] != 0)
10195 {
10196 flags=ParseGeometry(argument_list[0].string_reference,
10197 &geometry_info);
10198 if ((flags & SigmaValue) == 0)
10199 geometry_info.sigma=1.0;
10200 if ((flags & XiValue) == 0)
10201 geometry_info.xi=4.0;
10202 if ((flags & PsiValue) == 0)
10203 geometry_info.psi=4.0;
10204 }
10205 if (attribute_flag[1] != 0)
10206 geometry_info.rho=argument_list[1].real_reference;
10207 if (attribute_flag[2] != 0)
10208 geometry_info.sigma=argument_list[2].real_reference;
10209 if (attribute_flag[3] != 0)
10210 geometry_info.xi=argument_list[3].integer_reference;
10211 if (attribute_flag[4] != 0)
10212 geometry_info.psi=argument_list[4].integer_reference;
10213 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10214 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10215 ceil(geometry_info.psi-0.5),exception);
10216 break;
10217 }
10218 case 90: /* Identify */
10219 {
10220 if (attribute_flag[0] == 0)
10221 argument_list[0].file_reference=(FILE *) NULL;
10222 if (attribute_flag[1] != 0)
10223 (void) SetImageArtifact(image,"identify:features",
10224 argument_list[1].string_reference);
10225 if ((attribute_flag[2] != 0) &&
10226 (argument_list[2].integer_reference != 0))
10227 (void) SetImageArtifact(image,"identify:unique","true");
10228 (void) IdentifyImage(image,argument_list[0].file_reference,
10229 MagickTrue,exception);
10230 break;
10231 }
10232 case 91: /* SepiaTone */
10233 {
10234 if (attribute_flag[0] == 0)
10235 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10236 image=SepiaToneImage(image,argument_list[0].real_reference,
10237 exception);
10238 break;
10239 }
10240 case 92: /* SigmoidalContrast */
10241 {
10242 MagickBooleanType
10243 sharpen;
10244
10245 if (attribute_flag[0] != 0)
10246 {
10247 flags=ParseGeometry(argument_list[0].string_reference,
10248 &geometry_info);
10249 if ((flags & SigmaValue) == 0)
10250 geometry_info.sigma=QuantumRange/2.0;
10251 if ((flags & PercentValue) != 0)
10252 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10253 }
10254 if (attribute_flag[1] != 0)
10255 geometry_info.rho=argument_list[1].real_reference;
10256 if (attribute_flag[2] != 0)
10257 geometry_info.sigma=argument_list[2].real_reference;
10258 if (attribute_flag[3] != 0)
10259 channel=(ChannelType) argument_list[3].integer_reference;
10260 sharpen=MagickTrue;
10261 if (attribute_flag[4] != 0)
10262 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10263 MagickFalse;
10264 channel_mask=SetImageChannelMask(image,channel);
10265 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10266 geometry_info.sigma,exception);
10267 (void) SetImageChannelMask(image,channel_mask);
10268 break;
10269 }
10270 case 93: /* Extent */
10271 {
10272 if (attribute_flag[7] != 0)
10273 image->gravity=(GravityType) argument_list[7].integer_reference;
10274 if (attribute_flag[0] != 0)
10275 {
10276 int
10277 flags;
10278
10279 flags=ParseGravityGeometry(image,
10280 argument_list[0].string_reference,&geometry,exception);
10281 (void) flags;
10282 if (geometry.width == 0)
10283 geometry.width=image->columns;
10284 if (geometry.height == 0)
10285 geometry.height=image->rows;
10286 }
10287 if (attribute_flag[1] != 0)
10288 geometry.width=argument_list[1].integer_reference;
10289 if (attribute_flag[2] != 0)
10290 geometry.height=argument_list[2].integer_reference;
10291 if (attribute_flag[3] != 0)
10292 geometry.x=argument_list[3].integer_reference;
10293 if (attribute_flag[4] != 0)
10294 geometry.y=argument_list[4].integer_reference;
10295 if (attribute_flag[5] != 0)
10296 image->fuzz=StringToDoubleInterval(
10297 argument_list[5].string_reference,(double) QuantumRange+1.0);
10298 if (attribute_flag[6] != 0)
10299 (void) QueryColorCompliance(argument_list[6].string_reference,
10300 AllCompliance,&image->background_color,exception);
10301 image=ExtentImage(image,&geometry,exception);
10302 break;
10303 }
10304 case 94: /* Vignette */
10305 {
10306 if (attribute_flag[0] != 0)
10307 {
10308 flags=ParseGeometry(argument_list[0].string_reference,
10309 &geometry_info);
10310 if ((flags & SigmaValue) == 0)
10311 geometry_info.sigma=1.0;
10312 if ((flags & XiValue) == 0)
10313 geometry_info.xi=0.1*image->columns;
10314 if ((flags & PsiValue) == 0)
10315 geometry_info.psi=0.1*image->rows;
10316 }
10317 if (attribute_flag[1] != 0)
10318 geometry_info.rho=argument_list[1].real_reference;
10319 if (attribute_flag[2] != 0)
10320 geometry_info.sigma=argument_list[2].real_reference;
10321 if (attribute_flag[3] != 0)
10322 geometry_info.xi=argument_list[3].integer_reference;
10323 if (attribute_flag[4] != 0)
10324 geometry_info.psi=argument_list[4].integer_reference;
10325 if (attribute_flag[5] != 0)
10326 (void) QueryColorCompliance(argument_list[5].string_reference,
10327 AllCompliance,&image->background_color,exception);
10328 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10329 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10330 ceil(geometry_info.psi-0.5),exception);
10331 break;
10332 }
10333 case 95: /* ContrastStretch */
10334 {
10335 double
10336 black_point,
10337 white_point;
10338
10339 black_point=0.0;
10340 white_point=(double) image->columns*image->rows;
10341 if (attribute_flag[0] != 0)
10342 {
10343 flags=ParseGeometry(argument_list[0].string_reference,
10344 &geometry_info);
10345 black_point=geometry_info.rho;
10346 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10347 black_point;
10348 if ((flags & PercentValue) != 0)
10349 {
10350 black_point*=(double) image->columns*image->rows/100.0;
10351 white_point*=(double) image->columns*image->rows/100.0;
10352 }
10353 white_point=(double) image->columns*image->rows-
10354 white_point;
10355 }
10356 if (attribute_flag[1] != 0)
10357 black_point=argument_list[1].real_reference;
10358 if (attribute_flag[2] != 0)
10359 white_point=argument_list[2].real_reference;
10360 if (attribute_flag[4] != 0)
10361 channel=(ChannelType) argument_list[4].integer_reference;
10362 channel_mask=SetImageChannelMask(image,channel);
10363 (void) ContrastStretchImage(image,black_point,white_point,exception);
10364 (void) SetImageChannelMask(image,channel_mask);
10365 break;
10366 }
10367 case 96: /* Sans0 */
10368 {
10369 break;
10370 }
10371 case 97: /* Sans1 */
10372 {
10373 break;
10374 }
10375 case 98: /* AdaptiveSharpen */
10376 {
10377 if (attribute_flag[0] != 0)
10378 {
10379 flags=ParseGeometry(argument_list[0].string_reference,
10380 &geometry_info);
10381 if ((flags & SigmaValue) == 0)
10382 geometry_info.sigma=1.0;
10383 if ((flags & XiValue) == 0)
10384 geometry_info.xi=0.0;
10385 }
10386 if (attribute_flag[1] != 0)
10387 geometry_info.rho=argument_list[1].real_reference;
10388 if (attribute_flag[2] != 0)
10389 geometry_info.sigma=argument_list[2].real_reference;
10390 if (attribute_flag[3] != 0)
10391 geometry_info.xi=argument_list[3].real_reference;
10392 if (attribute_flag[4] != 0)
10393 channel=(ChannelType) argument_list[4].integer_reference;
10394 channel_mask=SetImageChannelMask(image,channel);
10395 image=AdaptiveSharpenImage(image,geometry_info.rho,
10396 geometry_info.sigma,exception);
10397 if (image != (Image *) NULL)
10398 (void) SetImageChannelMask(image,channel_mask);
10399 break;
10400 }
10401 case 99: /* Transpose */
10402 {
10403 image=TransposeImage(image,exception);
10404 break;
10405 }
10406 case 100: /* Tranverse */
10407 {
10408 image=TransverseImage(image,exception);
10409 break;
10410 }
10411 case 101: /* AutoOrient */
10412 {
10413 image=AutoOrientImage(image,image->orientation,exception);
10414 break;
10415 }
10416 case 102: /* AdaptiveBlur */
10417 {
10418 if (attribute_flag[0] != 0)
10419 {
10420 flags=ParseGeometry(argument_list[0].string_reference,
10421 &geometry_info);
10422 if ((flags & SigmaValue) == 0)
10423 geometry_info.sigma=1.0;
10424 if ((flags & XiValue) == 0)
10425 geometry_info.xi=0.0;
10426 }
10427 if (attribute_flag[1] != 0)
10428 geometry_info.rho=argument_list[1].real_reference;
10429 if (attribute_flag[2] != 0)
10430 geometry_info.sigma=argument_list[2].real_reference;
10431 if (attribute_flag[3] != 0)
10432 channel=(ChannelType) argument_list[3].integer_reference;
10433 channel_mask=SetImageChannelMask(image,channel);
10434 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10435 exception);
10436 if (image != (Image *) NULL)
10437 (void) SetImageChannelMask(image,channel_mask);
10438 break;
10439 }
10440 case 103: /* Sketch */
10441 {
10442 if (attribute_flag[0] != 0)
10443 {
10444 flags=ParseGeometry(argument_list[0].string_reference,
10445 &geometry_info);
10446 if ((flags & SigmaValue) == 0)
10447 geometry_info.sigma=1.0;
10448 if ((flags & XiValue) == 0)
10449 geometry_info.xi=1.0;
10450 }
10451 if (attribute_flag[1] != 0)
10452 geometry_info.rho=argument_list[1].real_reference;
10453 if (attribute_flag[2] != 0)
10454 geometry_info.sigma=argument_list[2].real_reference;
10455 if (attribute_flag[3] != 0)
10456 geometry_info.xi=argument_list[3].real_reference;
10457 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10458 geometry_info.xi,exception);
10459 break;
10460 }
10461 case 104: /* UniqueColors */
10462 {
10463 image=UniqueImageColors(image,exception);
10464 break;
10465 }
10466 case 105: /* AdaptiveResize */
10467 {
10468 if (attribute_flag[0] != 0)
10469 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10470 &geometry,exception);
10471 if (attribute_flag[1] != 0)
10472 geometry.width=argument_list[1].integer_reference;
10473 if (attribute_flag[2] != 0)
10474 geometry.height=argument_list[2].integer_reference;
10475 if (attribute_flag[3] != 0)
Cristy8645e042016-02-03 16:35:29 -050010476 image->filter=(FilterType) argument_list[4].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010477 if (attribute_flag[4] != 0)
10478 SetImageArtifact(image,"filter:support",
10479 argument_list[4].string_reference);
10480 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10481 exception);
10482 break;
10483 }
10484 case 106: /* ClipMask */
10485 {
10486 Image
10487 *mask_image;
10488
10489 if (attribute_flag[0] == 0)
10490 {
10491 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10492 PackageName);
10493 goto PerlException;
10494 }
10495 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10496 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010497 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010498 mask_image=DestroyImage(mask_image);
10499 break;
10500 }
10501 case 107: /* LinearStretch */
10502 {
10503 double
10504 black_point,
10505 white_point;
10506
10507 black_point=0.0;
10508 white_point=(double) image->columns*image->rows;
10509 if (attribute_flag[0] != 0)
10510 {
10511 flags=ParseGeometry(argument_list[0].string_reference,
10512 &geometry_info);
10513 if ((flags & SigmaValue) != 0)
10514 white_point=geometry_info.sigma;
10515 if ((flags & PercentValue) != 0)
10516 {
10517 black_point*=(double) image->columns*image->rows/100.0;
10518 white_point*=(double) image->columns*image->rows/100.0;
10519 }
10520 if ((flags & SigmaValue) == 0)
10521 white_point=(double) image->columns*image->rows-black_point;
10522 }
10523 if (attribute_flag[1] != 0)
10524 black_point=argument_list[1].real_reference;
10525 if (attribute_flag[2] != 0)
10526 white_point=argument_list[2].real_reference;
10527 (void) LinearStretchImage(image,black_point,white_point,exception);
10528 break;
10529 }
10530 case 108: /* ColorMatrix */
10531 {
10532 AV
10533 *av;
10534
10535 double
10536 *color_matrix;
10537
10538 KernelInfo
10539 *kernel_info;
10540
10541 size_t
10542 order;
10543
10544 if (attribute_flag[0] == 0)
10545 break;
10546 av=(AV *) argument_list[0].array_reference;
10547 order=(size_t) sqrt(av_len(av)+1);
10548 color_matrix=(double *) AcquireQuantumMemory(order,order*
10549 sizeof(*color_matrix));
10550 if (color_matrix == (double *) NULL)
10551 {
10552 ThrowPerlException(exception,ResourceLimitFatalError,
10553 "MemoryAllocationFailed",PackageName);
10554 goto PerlException;
10555 }
10556 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10557 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10558 for ( ; j < (ssize_t) (order*order); j++)
10559 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010560 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010561 if (kernel_info == (KernelInfo *) NULL)
10562 break;
10563 kernel_info->width=order;
10564 kernel_info->height=order;
10565 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10566 order*sizeof(*kernel_info->values));
10567 if (kernel_info->values != (MagickRealType *) NULL)
10568 {
10569 for (i=0; i < (ssize_t) (order*order); i++)
10570 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10571 image=ColorMatrixImage(image,kernel_info,exception);
10572 }
10573 kernel_info=DestroyKernelInfo(kernel_info);
10574 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10575 break;
10576 }
10577 case 109: /* Mask */
10578 {
10579 Image
10580 *mask_image;
10581
10582 if (attribute_flag[0] == 0)
10583 {
10584 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10585 PackageName);
10586 goto PerlException;
10587 }
10588 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10589 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010590 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010591 mask_image=DestroyImage(mask_image);
10592 break;
10593 }
10594 case 110: /* Polaroid */
10595 {
10596 char
10597 *caption;
10598
10599 DrawInfo
10600 *draw_info;
10601
10602 double
10603 angle;
10604
10605 PixelInterpolateMethod
10606 method;
10607
10608 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10609 (DrawInfo *) NULL);
10610 caption=(char *) NULL;
10611 if (attribute_flag[0] != 0)
10612 caption=InterpretImageProperties(info ? info->image_info :
10613 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10614 exception);
10615 angle=0.0;
10616 if (attribute_flag[1] != 0)
10617 angle=argument_list[1].real_reference;
10618 if (attribute_flag[2] != 0)
10619 (void) CloneString(&draw_info->font,
10620 argument_list[2].string_reference);
10621 if (attribute_flag[3] != 0)
10622 (void) QueryColorCompliance(argument_list[3].string_reference,
10623 AllCompliance,&draw_info->stroke,exception);
10624 if (attribute_flag[4] != 0)
10625 (void) QueryColorCompliance(argument_list[4].string_reference,
10626 AllCompliance,&draw_info->fill,exception);
10627 if (attribute_flag[5] != 0)
10628 draw_info->stroke_width=argument_list[5].real_reference;
10629 if (attribute_flag[6] != 0)
10630 draw_info->pointsize=argument_list[6].real_reference;
10631 if (attribute_flag[7] != 0)
10632 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10633 if (attribute_flag[8] != 0)
10634 (void) QueryColorCompliance(argument_list[8].string_reference,
10635 AllCompliance,&image->background_color,exception);
10636 method=UndefinedInterpolatePixel;
10637 if (attribute_flag[9] != 0)
10638 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10639 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10640 draw_info=DestroyDrawInfo(draw_info);
10641 if (caption != (char *) NULL)
10642 caption=DestroyString(caption);
10643 break;
10644 }
10645 case 111: /* FloodfillPaint */
10646 {
10647 DrawInfo
10648 *draw_info;
10649
10650 MagickBooleanType
10651 invert;
10652
10653 PixelInfo
10654 target;
10655
10656 draw_info=CloneDrawInfo(info ? info->image_info :
10657 (ImageInfo *) NULL,(DrawInfo *) NULL);
10658 if (attribute_flag[0] != 0)
10659 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10660 &geometry,exception);
10661 if (attribute_flag[1] != 0)
10662 geometry.x=argument_list[1].integer_reference;
10663 if (attribute_flag[2] != 0)
10664 geometry.y=argument_list[2].integer_reference;
10665 if (attribute_flag[3] != 0)
10666 (void) QueryColorCompliance(argument_list[3].string_reference,
10667 AllCompliance,&draw_info->fill,exception);
10668 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10669 geometry.x,geometry.y,&target,exception);
10670 if (attribute_flag[4] != 0)
10671 QueryColorCompliance(argument_list[4].string_reference,
10672 AllCompliance,&target,exception);
10673 if (attribute_flag[5] != 0)
10674 image->fuzz=StringToDoubleInterval(
10675 argument_list[5].string_reference,(double) QuantumRange+1.0);
10676 if (attribute_flag[6] != 0)
10677 channel=(ChannelType) argument_list[6].integer_reference;
10678 invert=MagickFalse;
10679 if (attribute_flag[7] != 0)
10680 invert=(MagickBooleanType) argument_list[7].integer_reference;
10681 channel_mask=SetImageChannelMask(image,channel);
10682 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10683 geometry.y,invert,exception);
10684 (void) SetImageChannelMask(image,channel_mask);
10685 draw_info=DestroyDrawInfo(draw_info);
10686 break;
10687 }
10688 case 112: /* Distort */
10689 {
10690 AV
10691 *av;
10692
10693 double
10694 *coordinates;
10695
Cristy8645e042016-02-03 16:35:29 -050010696 DistortMethod
cristy4a3ce0a2013-08-03 20:06:59 +000010697 method;
10698
10699 size_t
10700 number_coordinates;
10701
10702 VirtualPixelMethod
10703 virtual_pixel;
10704
10705 if (attribute_flag[0] == 0)
10706 break;
10707 method=UndefinedDistortion;
10708 if (attribute_flag[1] != 0)
Cristy8645e042016-02-03 16:35:29 -050010709 method=(DistortMethod) argument_list[1].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010710 av=(AV *) argument_list[0].array_reference;
10711 number_coordinates=(size_t) av_len(av)+1;
10712 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10713 sizeof(*coordinates));
10714 if (coordinates == (double *) NULL)
10715 {
10716 ThrowPerlException(exception,ResourceLimitFatalError,
10717 "MemoryAllocationFailed",PackageName);
10718 goto PerlException;
10719 }
10720 for (j=0; j < (ssize_t) number_coordinates; j++)
10721 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10722 virtual_pixel=UndefinedVirtualPixelMethod;
10723 if (attribute_flag[2] != 0)
10724 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10725 argument_list[2].integer_reference,exception);
10726 image=DistortImage(image,method,number_coordinates,coordinates,
10727 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10728 exception);
10729 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10730 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10731 exception);
10732 coordinates=(double *) RelinquishMagickMemory(coordinates);
10733 break;
10734 }
10735 case 113: /* Clut */
10736 {
10737 PixelInterpolateMethod
10738 method;
10739
10740 if (attribute_flag[0] == 0)
10741 {
10742 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10743 PackageName);
10744 goto PerlException;
10745 }
10746 method=UndefinedInterpolatePixel;
10747 if (attribute_flag[1] != 0)
10748 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10749 if (attribute_flag[2] != 0)
10750 channel=(ChannelType) argument_list[2].integer_reference;
10751 channel_mask=SetImageChannelMask(image,channel);
10752 (void) ClutImage(image,argument_list[0].image_reference,method,
10753 exception);
10754 (void) SetImageChannelMask(image,channel_mask);
10755 break;
10756 }
10757 case 114: /* LiquidRescale */
10758 {
10759 if (attribute_flag[0] != 0)
10760 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10761 &geometry,exception);
10762 if (attribute_flag[1] != 0)
10763 geometry.width=argument_list[1].integer_reference;
10764 if (attribute_flag[2] != 0)
10765 geometry.height=argument_list[2].integer_reference;
10766 if (attribute_flag[3] == 0)
10767 argument_list[3].real_reference=1.0;
10768 if (attribute_flag[4] == 0)
10769 argument_list[4].real_reference=0.0;
10770 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10771 argument_list[3].real_reference,argument_list[4].real_reference,
10772 exception);
10773 break;
10774 }
10775 case 115: /* EncipherImage */
10776 {
10777 (void) EncipherImage(image,argument_list[0].string_reference,
10778 exception);
10779 break;
10780 }
10781 case 116: /* DecipherImage */
10782 {
10783 (void) DecipherImage(image,argument_list[0].string_reference,
10784 exception);
10785 break;
10786 }
10787 case 117: /* Deskew */
10788 {
10789 geometry_info.rho=QuantumRange/2.0;
10790 if (attribute_flag[0] != 0)
10791 flags=ParseGeometry(argument_list[0].string_reference,
10792 &geometry_info);
10793 if (attribute_flag[1] != 0)
10794 geometry_info.rho=StringToDoubleInterval(
10795 argument_list[1].string_reference,(double) QuantumRange+1.0);
10796 image=DeskewImage(image,geometry_info.rho,exception);
10797 break;
10798 }
10799 case 118: /* Remap */
10800 {
10801 QuantizeInfo
10802 *quantize_info;
10803
10804 if (attribute_flag[0] == 0)
10805 {
10806 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10807 PackageName);
10808 goto PerlException;
10809 }
10810 quantize_info=AcquireQuantizeInfo(info->image_info);
10811 if (attribute_flag[1] != 0)
10812 quantize_info->dither_method=(DitherMethod)
10813 argument_list[1].integer_reference;
10814 (void) RemapImages(quantize_info,image,
10815 argument_list[0].image_reference,exception);
10816 quantize_info=DestroyQuantizeInfo(quantize_info);
10817 break;
10818 }
10819 case 119: /* SparseColor */
10820 {
10821 AV
10822 *av;
10823
10824 double
10825 *coordinates;
10826
10827 SparseColorMethod
10828 method;
10829
10830 size_t
10831 number_coordinates;
10832
10833 VirtualPixelMethod
10834 virtual_pixel;
10835
10836 if (attribute_flag[0] == 0)
10837 break;
10838 method=UndefinedColorInterpolate;
10839 if (attribute_flag[1] != 0)
10840 method=(SparseColorMethod) argument_list[1].integer_reference;
10841 av=(AV *) argument_list[0].array_reference;
10842 number_coordinates=(size_t) av_len(av)+1;
10843 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10844 sizeof(*coordinates));
10845 if (coordinates == (double *) NULL)
10846 {
10847 ThrowPerlException(exception,ResourceLimitFatalError,
10848 "MemoryAllocationFailed",PackageName);
10849 goto PerlException;
10850 }
10851 for (j=0; j < (ssize_t) number_coordinates; j++)
10852 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10853 virtual_pixel=UndefinedVirtualPixelMethod;
10854 if (attribute_flag[2] != 0)
10855 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10856 argument_list[2].integer_reference,exception);
10857 if (attribute_flag[3] != 0)
10858 channel=(ChannelType) argument_list[3].integer_reference;
10859 channel_mask=SetImageChannelMask(image,channel);
10860 image=SparseColorImage(image,method,number_coordinates,coordinates,
10861 exception);
10862 if (image != (Image *) NULL)
10863 (void) SetImageChannelMask(image,channel_mask);
10864 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10865 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10866 exception);
10867 coordinates=(double *) RelinquishMagickMemory(coordinates);
10868 break;
10869 }
10870 case 120: /* Function */
10871 {
10872 AV
10873 *av;
10874
10875 double
10876 *parameters;
10877
10878 MagickFunction
10879 function;
10880
10881 size_t
10882 number_parameters;
10883
10884 VirtualPixelMethod
10885 virtual_pixel;
10886
10887 if (attribute_flag[0] == 0)
10888 break;
10889 function=UndefinedFunction;
10890 if (attribute_flag[1] != 0)
10891 function=(MagickFunction) argument_list[1].integer_reference;
10892 av=(AV *) argument_list[0].array_reference;
10893 number_parameters=(size_t) av_len(av)+1;
10894 parameters=(double *) AcquireQuantumMemory(number_parameters,
10895 sizeof(*parameters));
10896 if (parameters == (double *) NULL)
10897 {
10898 ThrowPerlException(exception,ResourceLimitFatalError,
10899 "MemoryAllocationFailed",PackageName);
10900 goto PerlException;
10901 }
10902 for (j=0; j < (ssize_t) number_parameters; j++)
10903 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10904 virtual_pixel=UndefinedVirtualPixelMethod;
10905 if (attribute_flag[2] != 0)
10906 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10907 argument_list[2].integer_reference,exception);
10908 (void) FunctionImage(image,function,number_parameters,parameters,
10909 exception);
10910 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10911 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10912 exception);
10913 parameters=(double *) RelinquishMagickMemory(parameters);
10914 break;
10915 }
10916 case 121: /* SelectiveBlur */
10917 {
10918 if (attribute_flag[0] != 0)
10919 {
10920 flags=ParseGeometry(argument_list[0].string_reference,
10921 &geometry_info);
10922 if ((flags & SigmaValue) == 0)
10923 geometry_info.sigma=1.0;
10924 if ((flags & PercentValue) != 0)
10925 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10926 }
10927 if (attribute_flag[1] != 0)
10928 geometry_info.rho=argument_list[1].real_reference;
10929 if (attribute_flag[2] != 0)
10930 geometry_info.sigma=argument_list[2].real_reference;
10931 if (attribute_flag[3] != 0)
10932 geometry_info.xi=argument_list[3].integer_reference;;
10933 if (attribute_flag[5] != 0)
10934 channel=(ChannelType) argument_list[5].integer_reference;
10935 channel_mask=SetImageChannelMask(image,channel);
10936 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10937 geometry_info.xi,exception);
10938 if (image != (Image *) NULL)
10939 (void) SetImageChannelMask(image,channel_mask);
10940 break;
10941 }
10942 case 122: /* HaldClut */
10943 {
10944 if (attribute_flag[0] == 0)
10945 {
10946 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10947 PackageName);
10948 goto PerlException;
10949 }
10950 if (attribute_flag[1] != 0)
10951 channel=(ChannelType) argument_list[1].integer_reference;
10952 channel_mask=SetImageChannelMask(image,channel);
10953 (void) HaldClutImage(image,argument_list[0].image_reference,
10954 exception);
10955 (void) SetImageChannelMask(image,channel_mask);
10956 break;
10957 }
10958 case 123: /* BlueShift */
10959 {
10960 if (attribute_flag[0] != 0)
10961 (void) ParseGeometry(argument_list[0].string_reference,
10962 &geometry_info);
10963 image=BlueShiftImage(image,geometry_info.rho,exception);
10964 break;
10965 }
10966 case 124: /* ForwardFourierTransformImage */
10967 {
10968 image=ForwardFourierTransformImage(image,
10969 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10970 exception);
10971 break;
10972 }
10973 case 125: /* InverseFourierTransformImage */
10974 {
10975 image=InverseFourierTransformImage(image,image->next,
10976 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10977 exception);
10978 break;
10979 }
10980 case 126: /* ColorDecisionList */
10981 {
10982 if (attribute_flag[0] == 0)
10983 argument_list[0].string_reference=(char *) NULL;
10984 (void) ColorDecisionListImage(image,
10985 argument_list[0].string_reference,exception);
10986 break;
10987 }
10988 case 127: /* AutoGamma */
10989 {
10990 if (attribute_flag[0] != 0)
10991 channel=(ChannelType) argument_list[0].integer_reference;
10992 channel_mask=SetImageChannelMask(image,channel);
10993 (void) AutoGammaImage(image,exception);
10994 (void) SetImageChannelMask(image,channel_mask);
10995 break;
10996 }
10997 case 128: /* AutoLevel */
10998 {
10999 if (attribute_flag[0] != 0)
11000 channel=(ChannelType) argument_list[0].integer_reference;
11001 channel_mask=SetImageChannelMask(image,channel);
11002 (void) AutoLevelImage(image,exception);
11003 (void) SetImageChannelMask(image,channel_mask);
11004 break;
11005 }
11006 case 129: /* LevelColors */
11007 {
11008 PixelInfo
11009 black_point,
11010 white_point;
11011
11012 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
11013 exception);
11014 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
11015 exception);
11016 if (attribute_flag[1] != 0)
11017 (void) QueryColorCompliance(
11018 argument_list[1].string_reference,AllCompliance,&black_point,
11019 exception);
11020 if (attribute_flag[2] != 0)
11021 (void) QueryColorCompliance(
11022 argument_list[2].string_reference,AllCompliance,&white_point,
11023 exception);
11024 if (attribute_flag[3] != 0)
11025 channel=(ChannelType) argument_list[3].integer_reference;
11026 channel_mask=SetImageChannelMask(image,channel);
11027 (void) LevelImageColors(image,&black_point,&white_point,
11028 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11029 exception);
11030 (void) SetImageChannelMask(image,channel_mask);
11031 break;
11032 }
11033 case 130: /* Clamp */
11034 {
11035 if (attribute_flag[0] != 0)
11036 channel=(ChannelType) argument_list[0].integer_reference;
11037 channel_mask=SetImageChannelMask(image,channel);
11038 (void) ClampImage(image,exception);
11039 (void) SetImageChannelMask(image,channel_mask);
11040 break;
11041 }
11042 case 131: /* BrightnessContrast */
11043 {
11044 double
11045 brightness,
11046 contrast;
11047
11048 brightness=0.0;
11049 contrast=0.0;
11050 if (attribute_flag[0] != 0)
11051 {
11052 flags=ParseGeometry(argument_list[0].string_reference,
11053 &geometry_info);
11054 brightness=geometry_info.rho;
11055 if ((flags & SigmaValue) == 0)
11056 contrast=geometry_info.sigma;
11057 }
11058 if (attribute_flag[1] != 0)
11059 brightness=argument_list[1].real_reference;
11060 if (attribute_flag[2] != 0)
11061 contrast=argument_list[2].real_reference;
11062 if (attribute_flag[4] != 0)
11063 channel=(ChannelType) argument_list[4].integer_reference;
11064 channel_mask=SetImageChannelMask(image,channel);
11065 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11066 (void) SetImageChannelMask(image,channel_mask);
11067 break;
11068 }
11069 case 132: /* Morphology */
11070 {
11071 KernelInfo
11072 *kernel;
11073
11074 MorphologyMethod
11075 method;
11076
11077 ssize_t
11078 iterations;
11079
11080 if (attribute_flag[0] == 0)
11081 break;
cristy2c57b742014-10-31 00:40:34 +000011082 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011083 if (kernel == (KernelInfo *) NULL)
11084 break;
11085 if (attribute_flag[1] != 0)
11086 channel=(ChannelType) argument_list[1].integer_reference;
11087 method=UndefinedMorphology;
11088 if (attribute_flag[2] != 0)
11089 method=argument_list[2].integer_reference;
11090 iterations=1;
11091 if (attribute_flag[3] != 0)
11092 iterations=argument_list[3].integer_reference;
11093 channel_mask=SetImageChannelMask(image,channel);
11094 image=MorphologyImage(image,method,iterations,kernel,exception);
11095 if (image != (Image *) NULL)
11096 (void) SetImageChannelMask(image,channel_mask);
11097 kernel=DestroyKernelInfo(kernel);
11098 break;
11099 }
11100 case 133: /* Mode */
11101 {
11102 if (attribute_flag[0] != 0)
11103 {
11104 flags=ParseGeometry(argument_list[0].string_reference,
11105 &geometry_info);
11106 if ((flags & SigmaValue) == 0)
11107 geometry_info.sigma=1.0;
11108 }
11109 if (attribute_flag[1] != 0)
11110 geometry_info.rho=argument_list[1].real_reference;
11111 if (attribute_flag[2] != 0)
11112 geometry_info.sigma=argument_list[2].real_reference;
11113 if (attribute_flag[3] != 0)
11114 channel=(ChannelType) argument_list[3].integer_reference;
11115 channel_mask=SetImageChannelMask(image,channel);
11116 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11117 (size_t) geometry_info.sigma,exception);
11118 if (image != (Image *) NULL)
11119 (void) SetImageChannelMask(image,channel_mask);
11120 break;
11121 }
11122 case 134: /* Statistic */
11123 {
11124 StatisticType
11125 statistic;
11126
11127 statistic=UndefinedStatistic;
11128 if (attribute_flag[0] != 0)
11129 {
11130 flags=ParseGeometry(argument_list[0].string_reference,
11131 &geometry_info);
11132 if ((flags & SigmaValue) == 0)
11133 geometry_info.sigma=1.0;
11134 }
11135 if (attribute_flag[1] != 0)
11136 geometry_info.rho=argument_list[1].real_reference;
11137 if (attribute_flag[2] != 0)
11138 geometry_info.sigma=argument_list[2].real_reference;
11139 if (attribute_flag[3] != 0)
11140 channel=(ChannelType) argument_list[3].integer_reference;
11141 if (attribute_flag[4] != 0)
11142 statistic=(StatisticType) argument_list[4].integer_reference;
11143 channel_mask=SetImageChannelMask(image,channel);
11144 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11145 (size_t) geometry_info.sigma,exception);
11146 if (image != (Image *) NULL)
11147 (void) SetImageChannelMask(image,channel_mask);
11148 break;
11149 }
11150 case 135: /* Perceptible */
11151 {
11152 double
11153 epsilon;
11154
11155 epsilon=MagickEpsilon;
11156 if (attribute_flag[0] != 0)
11157 epsilon=argument_list[0].real_reference;
11158 if (attribute_flag[1] != 0)
11159 channel=(ChannelType) argument_list[1].integer_reference;
11160 channel_mask=SetImageChannelMask(image,channel);
11161 (void) PerceptibleImage(image,epsilon,exception);
11162 (void) SetImageChannelMask(image,channel_mask);
11163 break;
11164 }
11165 case 136: /* Poly */
11166 {
11167 AV
11168 *av;
11169
11170 double
11171 *terms;
11172
11173 size_t
11174 number_terms;
11175
11176 if (attribute_flag[0] == 0)
11177 break;
11178 if (attribute_flag[1] != 0)
11179 channel=(ChannelType) argument_list[1].integer_reference;
11180 av=(AV *) argument_list[0].array_reference;
11181 number_terms=(size_t) av_len(av);
11182 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11183 if (terms == (double *) NULL)
11184 {
11185 ThrowPerlException(exception,ResourceLimitFatalError,
11186 "MemoryAllocationFailed",PackageName);
11187 goto PerlException;
11188 }
11189 for (j=0; j < av_len(av); j++)
11190 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11191 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11192 terms=(double *) RelinquishMagickMemory(terms);
11193 break;
11194 }
11195 case 137: /* Grayscale */
11196 {
11197 PixelIntensityMethod
11198 method;
11199
11200 method=UndefinedPixelIntensityMethod;
11201 if (attribute_flag[0] != 0)
11202 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11203 (void) GrayscaleImage(image,method,exception);
11204 break;
11205 }
cristy4ceadb82014-03-29 15:30:43 +000011206 case 138: /* Canny */
11207 {
11208 if (attribute_flag[0] != 0)
11209 {
11210 flags=ParseGeometry(argument_list[0].string_reference,
11211 &geometry_info);
11212 if ((flags & SigmaValue) == 0)
11213 geometry_info.sigma=1.0;
11214 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011215 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011216 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011217 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011218 if ((flags & PercentValue) != 0)
11219 {
11220 geometry_info.xi/=100.0;
11221 geometry_info.psi/=100.0;
11222 }
cristy4ceadb82014-03-29 15:30:43 +000011223 }
11224 if (attribute_flag[1] != 0)
11225 geometry_info.rho=argument_list[1].real_reference;
11226 if (attribute_flag[2] != 0)
11227 geometry_info.sigma=argument_list[2].real_reference;
11228 if (attribute_flag[3] != 0)
11229 geometry_info.xi=argument_list[3].real_reference;
11230 if (attribute_flag[4] != 0)
11231 geometry_info.psi=argument_list[4].real_reference;
11232 if (attribute_flag[5] != 0)
11233 channel=(ChannelType) argument_list[5].integer_reference;
11234 channel_mask=SetImageChannelMask(image,channel);
11235 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11236 geometry_info.xi,geometry_info.psi,exception);
11237 if (image != (Image *) NULL)
11238 (void) SetImageChannelMask(image,channel_mask);
11239 break;
11240 }
cristy2fc10e52014-04-26 14:13:53 +000011241 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011242 {
11243 if (attribute_flag[0] != 0)
11244 {
11245 flags=ParseGeometry(argument_list[0].string_reference,
11246 &geometry_info);
11247 if ((flags & SigmaValue) == 0)
11248 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011249 if ((flags & XiValue) == 0)
11250 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011251 }
11252 if (attribute_flag[1] != 0)
11253 geometry_info.rho=(double) argument_list[1].integer_reference;
11254 if (attribute_flag[2] != 0)
11255 geometry_info.sigma=(double) argument_list[2].integer_reference;
11256 if (attribute_flag[3] != 0)
11257 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011258 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11259 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11260 break;
11261 }
11262 case 140: /* MeanShift */
11263 {
11264 if (attribute_flag[0] != 0)
11265 {
11266 flags=ParseGeometry(argument_list[0].string_reference,
11267 &geometry_info);
11268 if ((flags & SigmaValue) == 0)
11269 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011270 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011271 geometry_info.xi=0.10*QuantumRange;
11272 if ((flags & PercentValue) != 0)
11273 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011274 }
11275 if (attribute_flag[1] != 0)
11276 geometry_info.rho=(double) argument_list[1].integer_reference;
11277 if (attribute_flag[2] != 0)
11278 geometry_info.sigma=(double) argument_list[2].integer_reference;
11279 if (attribute_flag[3] != 0)
11280 geometry_info.xi=(double) argument_list[3].integer_reference;
11281 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011282 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011283 break;
11284 }
cristy3b207f82014-09-27 14:21:20 +000011285 case 141: /* Kuwahara */
11286 {
11287 if (attribute_flag[0] != 0)
11288 {
11289 flags=ParseGeometry(argument_list[0].string_reference,
11290 &geometry_info);
11291 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011292 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011293 }
11294 if (attribute_flag[1] != 0)
11295 geometry_info.rho=argument_list[1].real_reference;
11296 if (attribute_flag[2] != 0)
11297 geometry_info.sigma=argument_list[2].real_reference;
11298 if (attribute_flag[3] != 0)
11299 channel=(ChannelType) argument_list[3].integer_reference;
11300 channel_mask=SetImageChannelMask(image,channel);
11301 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11302 exception);
11303 if (image != (Image *) NULL)
11304 (void) SetImageChannelMask(image,channel_mask);
11305 break;
11306 }
cristy6e0b3bc2014-10-19 17:51:42 +000011307 case 142: /* ConnectedComponent */
11308 {
11309 size_t
11310 connectivity;
11311
11312 connectivity=4;
11313 if (attribute_flag[0] != 0)
11314 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011315 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011316 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011317 break;
11318 }
cristy0b94b392015-06-22 18:56:37 +000011319 case 143: /* Copy */
11320 {
11321 Image
11322 *source_image;
11323
11324 OffsetInfo
11325 offset;
11326
cristy2ffdb092015-06-25 14:31:20 +000011327 RectangleInfo
11328 offset_geometry;
11329
cristyf3a724a2015-06-25 13:02:53 +000011330 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011331 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011332 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011333 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011334 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011335 flags=ParseGravityGeometry(source_image,
11336 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011337 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011338 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011339 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011340 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011341 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011342 geometry.x=argument_list[4].integer_reference;
11343 if (attribute_flag[5] != 0)
11344 geometry.y=argument_list[5].integer_reference;
11345 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011346 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011347 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011348 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011349 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11350 &offset_geometry,exception);
11351 offset.x=offset_geometry.x;
11352 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011353 if (attribute_flag[8] != 0)
11354 offset.x=argument_list[8].integer_reference;
11355 if (attribute_flag[9] != 0)
11356 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011357 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11358 exception);
cristy0b94b392015-06-22 18:56:37 +000011359 break;
11360 }
Cristy5488c982016-02-13 14:07:50 -050011361 case 144: /* Color */
11362 {
11363 PixelInfo
11364 color;
11365
Cristyf20e3562016-02-14 09:08:15 -050011366 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011367 if (attribute_flag[0] != 0)
Cristyf20e3562016-02-14 09:08:15 -050011368 (void) QueryColorCompliance(argument_list[0].string_reference,
11369 AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011370 (void) SetImageColor(image,&color,exception);
11371 break;
11372 }
Cristy2d830ed2016-02-21 10:54:16 -050011373 case 145: /* WaveletDenoise */
11374 {
Cristyc1759412016-02-27 12:17:58 -050011375 if (attribute_flag[0] != 0)
Cristyee21f7f2016-02-27 15:56:49 -050011376 {
11377 flags=ParseGeometry(argument_list[0].string_reference,
11378 &geometry_info);
11379 if ((flags & PercentValue) != 0)
Cristy23446632016-02-29 09:36:34 -050011380 {
11381 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11382 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
11383 }
Cristyee21f7f2016-02-27 15:56:49 -050011384 if ((flags & SigmaValue) == 0)
11385 geometry_info.sigma=0.0;
11386 }
Cristyc1759412016-02-27 12:17:58 -050011387 if (attribute_flag[1] != 0)
11388 geometry_info.rho=argument_list[1].real_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011389 if (attribute_flag[2] != 0)
Cristyc1759412016-02-27 12:17:58 -050011390 geometry_info.sigma=argument_list[2].real_reference;
11391 if (attribute_flag[3] != 0)
11392 channel=(ChannelType) argument_list[3].integer_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011393 channel_mask=SetImageChannelMask(image,channel);
Cristyc1759412016-02-27 12:17:58 -050011394 image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11395 exception);
Cristy2d830ed2016-02-21 10:54:16 -050011396 if (image != (Image *) NULL)
11397 (void) SetImageChannelMask(image,channel_mask);
11398 break;
11399 }
Cristy99a57162016-12-05 11:47:57 -050011400 case 146: /* Colorspace */
11401 {
11402 ColorspaceType
11403 colorspace;
11404
11405 colorspace=sRGBColorspace;
11406 if (attribute_flag[0] != 0)
11407 colorspace=(ColorspaceType) argument_list[0].integer_reference;
11408 (void) TransformImageColorspace(image,colorspace,exception);
11409 break;
11410 }
cristy4a3ce0a2013-08-03 20:06:59 +000011411 }
11412 if (next != (Image *) NULL)
11413 (void) CatchImageException(next);
11414 if (region_image != (Image *) NULL)
11415 {
11416 /*
11417 Composite region.
cristy83a28a02013-08-03 20:25:48 +000011418 */
cristy4a3ce0a2013-08-03 20:06:59 +000011419 status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11420 region_info.x,region_info.y,exception);
11421 (void) status;
11422 (void) CatchImageException(region_image);
11423 image=DestroyImage(image);
11424 image=region_image;
11425 }
11426 if (image != (Image *) NULL)
11427 {
11428 number_images++;
11429 if (next && (next != image))
11430 {
11431 image->next=next->next;
11432 if (image->next != (Image *) NULL)
11433 image->next->previous=image;
11434 DeleteImageFromRegistry(*pv,next);
11435 }
11436 sv_setiv(*pv,PTR2IV(image));
11437 next=image;
11438 }
11439 if (*pv)
11440 pv++;
11441 }
11442
11443 PerlException:
11444 if (reference_vector)
11445 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11446 InheritPerlException(exception,perl_exception);
11447 exception=DestroyExceptionInfo(exception);
11448 sv_setiv(perl_exception,(IV) number_images);
11449 SvPOK_on(perl_exception);
11450 ST(0)=sv_2mortal(perl_exception);
11451 XSRETURN(1);
11452 }
11453
11454#
11455###############################################################################
11456# #
11457# #
11458# #
11459# M o n t a g e #
11460# #
11461# #
11462# #
11463###############################################################################
11464#
11465#
11466void
11467Montage(ref,...)
11468 Image::Magick ref=NO_INIT
11469 ALIAS:
11470 MontageImage = 1
11471 montage = 2
11472 montageimage = 3
11473 PPCODE:
11474 {
11475 AV
11476 *av;
11477
11478 char
11479 *attribute;
11480
11481 ExceptionInfo
11482 *exception;
11483
11484 HV
11485 *hv;
11486
11487 Image
11488 *image,
11489 *next;
11490
11491 PixelInfo
11492 transparent_color;
11493
11494 MontageInfo
11495 *montage_info;
11496
11497 register ssize_t
11498 i;
11499
11500 ssize_t
11501 sp;
11502
11503 struct PackageInfo
11504 *info;
11505
11506 SV
11507 *av_reference,
11508 *perl_exception,
11509 *reference,
11510 *rv,
11511 *sv;
11512
11513 PERL_UNUSED_VAR(ref);
11514 PERL_UNUSED_VAR(ix);
11515 exception=AcquireExceptionInfo();
11516 perl_exception=newSVpv("",0);
11517 sv=NULL;
11518 attribute=NULL;
11519 if (sv_isobject(ST(0)) == 0)
11520 {
11521 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11522 PackageName);
11523 goto PerlException;
11524 }
11525 reference=SvRV(ST(0));
11526 hv=SvSTASH(reference);
11527 av=newAV();
11528 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11529 SvREFCNT_dec(av);
11530 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11531 if (image == (Image *) NULL)
11532 {
11533 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11534 PackageName);
11535 goto PerlException;
11536 }
11537 /*
11538 Get options.
11539 */
11540 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11541 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11542 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11543 exception);
11544 for (i=2; i < items; i+=2)
11545 {
11546 attribute=(char *) SvPV(ST(i-1),na);
11547 switch (*attribute)
11548 {
11549 case 'B':
11550 case 'b':
11551 {
11552 if (LocaleCompare(attribute,"background") == 0)
11553 {
11554 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11555 &montage_info->background_color,exception);
11556 for (next=image; next; next=next->next)
11557 next->background_color=montage_info->background_color;
11558 break;
11559 }
11560 if (LocaleCompare(attribute,"border") == 0)
11561 {
11562 montage_info->border_width=SvIV(ST(i));
11563 break;
11564 }
11565 if (LocaleCompare(attribute,"bordercolor") == 0)
11566 {
11567 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11568 &montage_info->border_color,exception);
11569 for (next=image; next; next=next->next)
11570 next->border_color=montage_info->border_color;
11571 break;
11572 }
11573 if (LocaleCompare(attribute,"borderwidth") == 0)
11574 {
11575 montage_info->border_width=SvIV(ST(i));
11576 break;
11577 }
11578 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11579 attribute);
11580 break;
11581 }
11582 case 'C':
11583 case 'c':
11584 {
11585 if (LocaleCompare(attribute,"compose") == 0)
11586 {
11587 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11588 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11589 if (sp < 0)
11590 {
11591 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11592 SvPV(ST(i),na));
11593 break;
11594 }
11595 for (next=image; next; next=next->next)
11596 next->compose=(CompositeOperator) sp;
11597 break;
11598 }
11599 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11600 attribute);
11601 break;
11602 }
11603 case 'F':
11604 case 'f':
11605 {
11606 if (LocaleCompare(attribute,"fill") == 0)
11607 {
11608 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11609 &montage_info->fill,exception);
11610 break;
11611 }
11612 if (LocaleCompare(attribute,"font") == 0)
11613 {
11614 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11615 break;
11616 }
11617 if (LocaleCompare(attribute,"frame") == 0)
11618 {
11619 char
11620 *p;
11621
11622 p=SvPV(ST(i),na);
11623 if (IsGeometry(p) == MagickFalse)
11624 {
11625 ThrowPerlException(exception,OptionError,"MissingGeometry",
11626 p);
11627 break;
11628 }
11629 (void) CloneString(&montage_info->frame,p);
11630 if (*p == '\0')
11631 montage_info->frame=(char *) NULL;
11632 break;
11633 }
11634 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11635 attribute);
11636 break;
11637 }
11638 case 'G':
11639 case 'g':
11640 {
11641 if (LocaleCompare(attribute,"geometry") == 0)
11642 {
11643 char
11644 *p;
11645
11646 p=SvPV(ST(i),na);
11647 if (IsGeometry(p) == MagickFalse)
11648 {
11649 ThrowPerlException(exception,OptionError,"MissingGeometry",
11650 p);
11651 break;
11652 }
11653 (void) CloneString(&montage_info->geometry,p);
11654 if (*p == '\0')
11655 montage_info->geometry=(char *) NULL;
11656 break;
11657 }
11658 if (LocaleCompare(attribute,"gravity") == 0)
11659 {
11660 ssize_t
11661 in;
11662
11663 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11664 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11665 if (in < 0)
11666 {
11667 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11668 SvPV(ST(i),na));
11669 return;
11670 }
11671 montage_info->gravity=(GravityType) in;
11672 for (next=image; next; next=next->next)
11673 next->gravity=(GravityType) in;
11674 break;
11675 }
11676 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11677 attribute);
11678 break;
11679 }
11680 case 'L':
11681 case 'l':
11682 {
11683 if (LocaleCompare(attribute,"label") == 0)
11684 {
11685 for (next=image; next; next=next->next)
Cristy935a4052017-03-31 17:45:37 -040011686 (void) SetImageProperty(next,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +000011687 info ? info->image_info : (ImageInfo *) NULL,next,
Cristy935a4052017-03-31 17:45:37 -040011688 SvPV(ST(i),na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011689 break;
11690 }
11691 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11692 attribute);
11693 break;
11694 }
11695 case 'M':
11696 case 'm':
11697 {
11698 if (LocaleCompare(attribute,"mattecolor") == 0)
11699 {
11700 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
Cristy8645e042016-02-03 16:35:29 -050011701 &montage_info->alpha_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011702 for (next=image; next; next=next->next)
Cristy8645e042016-02-03 16:35:29 -050011703 next->alpha_color=montage_info->alpha_color;
cristy4a3ce0a2013-08-03 20:06:59 +000011704 break;
11705 }
11706 if (LocaleCompare(attribute,"mode") == 0)
11707 {
11708 ssize_t
11709 in;
11710
11711 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11712 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11713 switch (in)
11714 {
11715 default:
11716 {
11717 ThrowPerlException(exception,OptionError,
11718 "UnrecognizedModeType",SvPV(ST(i),na));
11719 break;
11720 }
11721 case FrameMode:
11722 {
11723 (void) CloneString(&montage_info->frame,"15x15+3+3");
11724 montage_info->shadow=MagickTrue;
11725 break;
11726 }
11727 case UnframeMode:
11728 {
11729 montage_info->frame=(char *) NULL;
11730 montage_info->shadow=MagickFalse;
11731 montage_info->border_width=0;
11732 break;
11733 }
11734 case ConcatenateMode:
11735 {
11736 montage_info->frame=(char *) NULL;
11737 montage_info->shadow=MagickFalse;
11738 (void) CloneString(&montage_info->geometry,"+0+0");
11739 montage_info->border_width=0;
11740 }
11741 }
11742 break;
11743 }
11744 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11745 attribute);
11746 break;
11747 }
11748 case 'P':
11749 case 'p':
11750 {
11751 if (LocaleCompare(attribute,"pointsize") == 0)
11752 {
11753 montage_info->pointsize=SvIV(ST(i));
11754 break;
11755 }
11756 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11757 attribute);
11758 break;
11759 }
11760 case 'S':
11761 case 's':
11762 {
11763 if (LocaleCompare(attribute,"shadow") == 0)
11764 {
11765 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11766 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11767 if (sp < 0)
11768 {
11769 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11770 SvPV(ST(i),na));
11771 break;
11772 }
11773 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11774 break;
11775 }
11776 if (LocaleCompare(attribute,"stroke") == 0)
11777 {
11778 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11779 &montage_info->stroke,exception);
11780 break;
11781 }
11782 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11783 attribute);
11784 break;
11785 }
11786 case 'T':
11787 case 't':
11788 {
11789 if (LocaleCompare(attribute,"texture") == 0)
11790 {
11791 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11792 break;
11793 }
11794 if (LocaleCompare(attribute,"tile") == 0)
11795 {
11796 char *p=SvPV(ST(i),na);
11797 if (IsGeometry(p) == MagickFalse)
11798 {
11799 ThrowPerlException(exception,OptionError,"MissingGeometry",
11800 p);
11801 break;
11802 }
11803 (void) CloneString(&montage_info->tile,p);
11804 if (*p == '\0')
11805 montage_info->tile=(char *) NULL;
11806 break;
11807 }
11808 if (LocaleCompare(attribute,"title") == 0)
11809 {
11810 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11811 break;
11812 }
11813 if (LocaleCompare(attribute,"transparent") == 0)
11814 {
11815 PixelInfo
11816 transparent_color;
11817
11818 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11819 &transparent_color,exception);
11820 for (next=image; next; next=next->next)
11821 (void) TransparentPaintImage(next,&transparent_color,
11822 TransparentAlpha,MagickFalse,exception);
11823 break;
11824 }
11825 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11826 attribute);
11827 break;
11828 }
11829 default:
11830 {
11831 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11832 attribute);
11833 break;
11834 }
11835 }
11836 }
11837 image=MontageImageList(info->image_info,montage_info,image,exception);
11838 montage_info=DestroyMontageInfo(montage_info);
11839 if (image == (Image *) NULL)
11840 goto PerlException;
11841 if (transparent_color.alpha != TransparentAlpha)
11842 for (next=image; next; next=next->next)
11843 (void) TransparentPaintImage(next,&transparent_color,
11844 TransparentAlpha,MagickFalse,exception);
11845 for ( ; image; image=image->next)
11846 {
11847 AddImageToRegistry(sv,image);
11848 rv=newRV(sv);
11849 av_push(av,sv_bless(rv,hv));
11850 SvREFCNT_dec(sv);
11851 }
11852 exception=DestroyExceptionInfo(exception);
11853 ST(0)=av_reference;
11854 SvREFCNT_dec(perl_exception);
11855 XSRETURN(1);
11856
11857 PerlException:
11858 InheritPerlException(exception,perl_exception);
11859 exception=DestroyExceptionInfo(exception);
11860 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11861 SvPOK_on(perl_exception);
11862 ST(0)=sv_2mortal(perl_exception);
11863 XSRETURN(1);
11864 }
11865
11866#
11867###############################################################################
11868# #
11869# #
11870# #
11871# M o r p h #
11872# #
11873# #
11874# #
11875###############################################################################
11876#
11877#
11878void
11879Morph(ref,...)
11880 Image::Magick ref=NO_INIT
11881 ALIAS:
11882 MorphImage = 1
11883 morph = 2
11884 morphimage = 3
11885 PPCODE:
11886 {
11887 AV
11888 *av;
11889
11890 char
11891 *attribute;
11892
11893 ExceptionInfo
11894 *exception;
11895
11896 HV
11897 *hv;
11898
11899 Image
11900 *image;
11901
11902 register ssize_t
11903 i;
11904
11905 ssize_t
11906 number_frames;
11907
11908 struct PackageInfo
11909 *info;
11910
11911 SV
11912 *av_reference,
11913 *perl_exception,
11914 *reference,
11915 *rv,
11916 *sv;
11917
11918 PERL_UNUSED_VAR(ref);
11919 PERL_UNUSED_VAR(ix);
11920 exception=AcquireExceptionInfo();
11921 perl_exception=newSVpv("",0);
11922 sv=NULL;
11923 av=NULL;
11924 attribute=NULL;
11925 if (sv_isobject(ST(0)) == 0)
11926 {
11927 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11928 PackageName);
11929 goto PerlException;
11930 }
11931 reference=SvRV(ST(0));
11932 hv=SvSTASH(reference);
11933 av=newAV();
11934 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11935 SvREFCNT_dec(av);
11936 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11937 if (image == (Image *) NULL)
11938 {
11939 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11940 PackageName);
11941 goto PerlException;
11942 }
11943 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11944 /*
11945 Get attribute.
11946 */
11947 number_frames=30;
11948 for (i=2; i < items; i+=2)
11949 {
11950 attribute=(char *) SvPV(ST(i-1),na);
11951 switch (*attribute)
11952 {
11953 case 'F':
11954 case 'f':
11955 {
11956 if (LocaleCompare(attribute,"frames") == 0)
11957 {
11958 number_frames=SvIV(ST(i));
11959 break;
11960 }
11961 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11962 attribute);
11963 break;
11964 }
11965 default:
11966 {
11967 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11968 attribute);
11969 break;
11970 }
11971 }
11972 }
11973 image=MorphImages(image,number_frames,exception);
11974 if (image == (Image *) NULL)
11975 goto PerlException;
11976 for ( ; image; image=image->next)
11977 {
11978 AddImageToRegistry(sv,image);
11979 rv=newRV(sv);
11980 av_push(av,sv_bless(rv,hv));
11981 SvREFCNT_dec(sv);
11982 }
11983 exception=DestroyExceptionInfo(exception);
11984 ST(0)=av_reference;
11985 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11986 XSRETURN(1);
11987
11988 PerlException:
11989 InheritPerlException(exception,perl_exception);
11990 exception=DestroyExceptionInfo(exception);
11991 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11992 SvPOK_on(perl_exception);
11993 ST(0)=sv_2mortal(perl_exception);
11994 XSRETURN(1);
11995 }
11996
11997#
11998###############################################################################
11999# #
12000# #
12001# #
12002# M o s a i c #
12003# #
12004# #
12005# #
12006###############################################################################
12007#
12008#
12009void
12010Mosaic(ref)
12011 Image::Magick ref=NO_INIT
12012 ALIAS:
12013 MosaicImage = 1
12014 mosaic = 2
12015 mosaicimage = 3
12016 PPCODE:
12017 {
12018 AV
12019 *av;
12020
12021 ExceptionInfo
12022 *exception;
12023
12024 HV
12025 *hv;
12026
12027 Image
12028 *image;
12029
12030 struct PackageInfo
12031 *info;
12032
12033 SV
12034 *perl_exception,
12035 *reference,
12036 *rv,
12037 *sv;
12038
12039 PERL_UNUSED_VAR(ref);
12040 PERL_UNUSED_VAR(ix);
12041 exception=AcquireExceptionInfo();
12042 perl_exception=newSVpv("",0);
12043 sv=NULL;
12044 if (sv_isobject(ST(0)) == 0)
12045 {
12046 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12047 PackageName);
12048 goto PerlException;
12049 }
12050 reference=SvRV(ST(0));
12051 hv=SvSTASH(reference);
12052 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12053 if (image == (Image *) NULL)
12054 {
12055 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12056 PackageName);
12057 goto PerlException;
12058 }
12059 image=MergeImageLayers(image,MosaicLayer,exception);
12060 /*
12061 Create blessed Perl array for the returned image.
12062 */
12063 av=newAV();
12064 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12065 SvREFCNT_dec(av);
12066 AddImageToRegistry(sv,image);
12067 rv=newRV(sv);
12068 av_push(av,sv_bless(rv,hv));
12069 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000012070 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000012071 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012072 SetImageInfo(info->image_info,0,exception);
12073 exception=DestroyExceptionInfo(exception);
12074 SvREFCNT_dec(perl_exception);
12075 XSRETURN(1);
12076
12077 PerlException:
12078 InheritPerlException(exception,perl_exception);
12079 exception=DestroyExceptionInfo(exception);
12080 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12081 SvPOK_on(perl_exception); /* return messages in string context */
12082 ST(0)=sv_2mortal(perl_exception);
12083 XSRETURN(1);
12084 }
12085
12086#
12087###############################################################################
12088# #
12089# #
12090# #
12091# P i n g #
12092# #
12093# #
12094# #
12095###############################################################################
12096#
12097#
12098void
12099Ping(ref,...)
12100 Image::Magick ref=NO_INIT
12101 ALIAS:
12102 PingImage = 1
12103 ping = 2
12104 pingimage = 3
12105 PPCODE:
12106 {
12107 AV
12108 *av;
12109
12110 char
12111 **keep,
12112 **list;
12113
12114 ExceptionInfo
12115 *exception;
12116
12117 Image
12118 *image,
12119 *next;
12120
12121 int
12122 n;
12123
12124 MagickBooleanType
12125 status;
12126
12127 register char
12128 **p;
12129
12130 register ssize_t
12131 i;
12132
12133 ssize_t
12134 ac;
12135
12136 STRLEN
12137 *length;
12138
12139 struct PackageInfo
12140 *info,
12141 *package_info;
12142
12143 SV
12144 *perl_exception,
12145 *reference;
12146
12147 size_t
12148 count;
12149
12150 PERL_UNUSED_VAR(ref);
12151 PERL_UNUSED_VAR(ix);
12152 exception=AcquireExceptionInfo();
12153 perl_exception=newSVpv("",0);
12154 package_info=(struct PackageInfo *) NULL;
12155 ac=(items < 2) ? 1 : items-1;
12156 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12157 keep=list;
12158 length=(STRLEN *) NULL;
12159 if (list == (char **) NULL)
12160 {
12161 ThrowPerlException(exception,ResourceLimitError,
12162 "MemoryAllocationFailed",PackageName);
12163 goto PerlException;
12164 }
12165 keep=list;
12166 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12167 if (length == (STRLEN *) NULL)
12168 {
12169 ThrowPerlException(exception,ResourceLimitError,
12170 "MemoryAllocationFailed",PackageName);
12171 goto PerlException;
12172 }
12173 if (sv_isobject(ST(0)) == 0)
12174 {
12175 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12176 PackageName);
12177 goto PerlException;
12178 }
12179 reference=SvRV(ST(0));
12180 if (SvTYPE(reference) != SVt_PVAV)
12181 {
12182 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12183 PackageName);
12184 goto PerlException;
12185 }
12186 av=(AV *) reference;
12187 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12188 exception);
12189 package_info=ClonePackageInfo(info,exception);
12190 n=1;
12191 if (items <= 1)
12192 *list=(char *) (*package_info->image_info->filename ?
12193 package_info->image_info->filename : "XC:black");
12194 else
12195 for (n=0, i=0; i < ac; i++)
12196 {
12197 list[n]=(char *) SvPV(ST(i+1),length[n]);
12198 if ((items >= 3) && strEQcase(list[n],"blob"))
12199 {
12200 void
12201 *blob;
12202
12203 i++;
12204 blob=(void *) (SvPV(ST(i+1),length[n]));
12205 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12206 }
12207 if ((items >= 3) && strEQcase(list[n],"filename"))
12208 continue;
12209 if ((items >= 3) && strEQcase(list[n],"file"))
12210 {
12211 FILE
12212 *file;
12213
12214 PerlIO
12215 *io_info;
12216
12217 i++;
12218 io_info=IoIFP(sv_2io(ST(i+1)));
12219 if (io_info == (PerlIO *) NULL)
12220 {
12221 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12222 PackageName);
12223 continue;
12224 }
12225 file=PerlIO_findFILE(io_info);
12226 if (file == (FILE *) NULL)
12227 {
12228 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12229 PackageName);
12230 continue;
12231 }
12232 SetImageInfoFile(package_info->image_info,file);
12233 }
12234 if ((items >= 3) && strEQcase(list[n],"magick"))
12235 continue;
12236 n++;
12237 }
12238 list[n]=(char *) NULL;
12239 keep=list;
12240 status=ExpandFilenames(&n,&list);
12241 if (status == MagickFalse)
12242 {
12243 ThrowPerlException(exception,ResourceLimitError,
12244 "MemoryAllocationFailed",PackageName);
12245 goto PerlException;
12246 }
12247 count=0;
12248 for (i=0; i < n; i++)
12249 {
12250 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012251 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012252 image=PingImage(package_info->image_info,exception);
12253 if (image == (Image *) NULL)
12254 break;
12255 if ((package_info->image_info->file != (FILE *) NULL) ||
12256 (package_info->image_info->blob != (void *) NULL))
12257 DisassociateImageStream(image);
12258 count+=GetImageListLength(image);
12259 EXTEND(sp,4*count);
12260 for (next=image; next; next=next->next)
12261 {
12262 PUSHs(sv_2mortal(newSViv(next->columns)));
12263 PUSHs(sv_2mortal(newSViv(next->rows)));
12264 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12265 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12266 }
12267 image=DestroyImageList(image);
12268 }
12269 /*
12270 Free resources.
12271 */
12272 for (i=0; i < n; i++)
12273 if (list[i] != (char *) NULL)
12274 for (p=keep; list[i] != *p++; )
12275 if (*p == NULL)
12276 {
12277 list[i]=(char *) RelinquishMagickMemory(list[i]);
12278 break;
12279 }
12280
12281 PerlException:
12282 if (package_info != (struct PackageInfo *) NULL)
12283 DestroyPackageInfo(package_info);
12284 if (list && (list != keep))
12285 list=(char **) RelinquishMagickMemory(list);
12286 if (keep)
12287 keep=(char **) RelinquishMagickMemory(keep);
12288 if (length)
12289 length=(STRLEN *) RelinquishMagickMemory(length);
12290 InheritPerlException(exception,perl_exception);
12291 exception=DestroyExceptionInfo(exception);
12292 SvREFCNT_dec(perl_exception); /* throw away all errors */
12293 }
12294
12295#
12296###############################################################################
12297# #
12298# #
12299# #
12300# P r e v i e w #
12301# #
12302# #
12303# #
12304###############################################################################
12305#
12306#
12307void
12308Preview(ref,...)
12309 Image::Magick ref=NO_INIT
12310 ALIAS:
12311 PreviewImage = 1
12312 preview = 2
12313 previewimage = 3
12314 PPCODE:
12315 {
12316 AV
12317 *av;
12318
12319 ExceptionInfo
12320 *exception;
12321
12322 HV
12323 *hv;
12324
12325 Image
12326 *image,
12327 *preview_image;
12328
12329 PreviewType
12330 preview_type;
12331
12332 struct PackageInfo
12333 *info;
12334
12335 SV
12336 *av_reference,
12337 *perl_exception,
12338 *reference,
12339 *rv,
12340 *sv;
12341
12342 PERL_UNUSED_VAR(ref);
12343 PERL_UNUSED_VAR(ix);
12344 exception=AcquireExceptionInfo();
12345 perl_exception=newSVpv("",0);
12346 sv=NULL;
12347 av=NULL;
12348 if (sv_isobject(ST(0)) == 0)
12349 {
12350 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12351 PackageName);
12352 goto PerlException;
12353 }
12354 reference=SvRV(ST(0));
12355 hv=SvSTASH(reference);
12356 av=newAV();
12357 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12358 SvREFCNT_dec(av);
12359 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12360 if (image == (Image *) NULL)
12361 {
12362 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12363 PackageName);
12364 goto PerlException;
12365 }
12366 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12367 preview_type=GammaPreview;
12368 if (items > 1)
12369 preview_type=(PreviewType)
12370 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12371 for ( ; image; image=image->next)
12372 {
12373 preview_image=PreviewImage(image,preview_type,exception);
12374 if (preview_image == (Image *) NULL)
12375 goto PerlException;
12376 AddImageToRegistry(sv,preview_image);
12377 rv=newRV(sv);
12378 av_push(av,sv_bless(rv,hv));
12379 SvREFCNT_dec(sv);
12380 }
12381 exception=DestroyExceptionInfo(exception);
12382 ST(0)=av_reference;
12383 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12384 XSRETURN(1);
12385
12386 PerlException:
12387 InheritPerlException(exception,perl_exception);
12388 exception=DestroyExceptionInfo(exception);
12389 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12390 SvPOK_on(perl_exception);
12391 ST(0)=sv_2mortal(perl_exception);
12392 XSRETURN(1);
12393 }
12394
12395#
12396###############################################################################
12397# #
12398# #
12399# #
12400# Q u e r y C o l o r #
12401# #
12402# #
12403# #
12404###############################################################################
12405#
12406#
12407void
12408QueryColor(ref,...)
12409 Image::Magick ref=NO_INIT
12410 ALIAS:
12411 querycolor = 1
12412 PPCODE:
12413 {
12414 char
12415 *name;
12416
12417 ExceptionInfo
12418 *exception;
12419
12420 PixelInfo
12421 color;
12422
12423 register ssize_t
12424 i;
12425
12426 SV
12427 *perl_exception;
12428
12429 PERL_UNUSED_VAR(ref);
12430 PERL_UNUSED_VAR(ix);
12431 exception=AcquireExceptionInfo();
12432 perl_exception=newSVpv("",0);
12433 if (items == 1)
12434 {
12435 const ColorInfo
12436 **colorlist;
12437
12438 size_t
12439 colors;
12440
12441 colorlist=GetColorInfoList("*",&colors,exception);
12442 EXTEND(sp,colors);
12443 for (i=0; i < (ssize_t) colors; i++)
12444 {
12445 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12446 }
12447 colorlist=(const ColorInfo **)
12448 RelinquishMagickMemory((ColorInfo **) colorlist);
12449 goto PerlException;
12450 }
12451 EXTEND(sp,5*items);
12452 for (i=1; i < items; i++)
12453 {
12454 name=(char *) SvPV(ST(i),na);
12455 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12456 {
12457 PUSHs(&sv_undef);
12458 continue;
12459 }
12460 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12461 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12462 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12463 if (color.colorspace == CMYKColorspace)
12464 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012465 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012466 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12467 }
12468
12469 PerlException:
12470 InheritPerlException(exception,perl_exception);
12471 exception=DestroyExceptionInfo(exception);
12472 SvREFCNT_dec(perl_exception);
12473 }
12474
12475#
12476###############################################################################
12477# #
12478# #
12479# #
12480# Q u e r y C o l o r N a m e #
12481# #
12482# #
12483# #
12484###############################################################################
12485#
12486#
12487void
12488QueryColorname(ref,...)
12489 Image::Magick ref=NO_INIT
12490 ALIAS:
12491 querycolorname = 1
12492 PPCODE:
12493 {
12494 AV
12495 *av;
12496
12497 char
cristy151b66d2015-04-15 10:50:31 +000012498 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012499
12500 ExceptionInfo
12501 *exception;
12502
12503 Image
12504 *image;
12505
12506 PixelInfo
12507 target_color;
12508
12509 register ssize_t
12510 i;
12511
12512 struct PackageInfo
12513 *info;
12514
12515 SV
12516 *perl_exception,
12517 *reference; /* reference is the SV* of ref=SvIV(reference) */
12518
12519 PERL_UNUSED_VAR(ref);
12520 PERL_UNUSED_VAR(ix);
12521 exception=AcquireExceptionInfo();
12522 perl_exception=newSVpv("",0);
12523 reference=SvRV(ST(0));
12524 av=(AV *) reference;
12525 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12526 exception);
12527 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12528 if (image == (Image *) NULL)
12529 {
12530 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12531 PackageName);
12532 goto PerlException;
12533 }
12534 EXTEND(sp,items);
12535 for (i=1; i < items; i++)
12536 {
12537 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12538 exception);
12539 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12540 exception);
12541 PUSHs(sv_2mortal(newSVpv(message,0)));
12542 }
12543
12544 PerlException:
12545 InheritPerlException(exception,perl_exception);
12546 exception=DestroyExceptionInfo(exception);
12547 SvREFCNT_dec(perl_exception);
12548 }
12549
12550#
12551###############################################################################
12552# #
12553# #
12554# #
12555# Q u e r y F o n t #
12556# #
12557# #
12558# #
12559###############################################################################
12560#
12561#
12562void
12563QueryFont(ref,...)
12564 Image::Magick ref=NO_INIT
12565 ALIAS:
12566 queryfont = 1
12567 PPCODE:
12568 {
12569 char
12570 *name,
cristy151b66d2015-04-15 10:50:31 +000012571 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012572
12573 ExceptionInfo
12574 *exception;
12575
12576 register ssize_t
12577 i;
12578
12579 SV
12580 *perl_exception;
12581
12582 volatile const TypeInfo
12583 *type_info;
12584
12585 PERL_UNUSED_VAR(ref);
12586 PERL_UNUSED_VAR(ix);
12587 exception=AcquireExceptionInfo();
12588 perl_exception=newSVpv("",0);
12589 if (items == 1)
12590 {
12591 const TypeInfo
12592 **typelist;
12593
12594 size_t
12595 types;
12596
12597 typelist=GetTypeInfoList("*",&types,exception);
12598 EXTEND(sp,types);
12599 for (i=0; i < (ssize_t) types; i++)
12600 {
12601 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12602 }
12603 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12604 typelist);
12605 goto PerlException;
12606 }
12607 EXTEND(sp,10*items);
12608 for (i=1; i < items; i++)
12609 {
12610 name=(char *) SvPV(ST(i),na);
12611 type_info=GetTypeInfo(name,exception);
12612 if (type_info == (TypeInfo *) NULL)
12613 {
12614 PUSHs(&sv_undef);
12615 continue;
12616 }
12617 if (type_info->name == (char *) NULL)
12618 PUSHs(&sv_undef);
12619 else
12620 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12621 if (type_info->description == (char *) NULL)
12622 PUSHs(&sv_undef);
12623 else
12624 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12625 if (type_info->family == (char *) NULL)
12626 PUSHs(&sv_undef);
12627 else
12628 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12629 if (type_info->style == UndefinedStyle)
12630 PUSHs(&sv_undef);
12631 else
12632 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12633 type_info->style),0)));
12634 if (type_info->stretch == UndefinedStretch)
12635 PUSHs(&sv_undef);
12636 else
12637 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12638 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012639 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012640 type_info->weight);
12641 PUSHs(sv_2mortal(newSVpv(message,0)));
12642 if (type_info->encoding == (char *) NULL)
12643 PUSHs(&sv_undef);
12644 else
12645 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12646 if (type_info->foundry == (char *) NULL)
12647 PUSHs(&sv_undef);
12648 else
12649 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12650 if (type_info->format == (char *) NULL)
12651 PUSHs(&sv_undef);
12652 else
12653 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12654 if (type_info->metrics == (char *) NULL)
12655 PUSHs(&sv_undef);
12656 else
12657 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12658 if (type_info->glyphs == (char *) NULL)
12659 PUSHs(&sv_undef);
12660 else
12661 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12662 }
12663
12664 PerlException:
12665 InheritPerlException(exception,perl_exception);
12666 exception=DestroyExceptionInfo(exception);
12667 SvREFCNT_dec(perl_exception);
12668 }
12669
12670#
12671###############################################################################
12672# #
12673# #
12674# #
12675# Q u e r y F o n t M e t r i c s #
12676# #
12677# #
12678# #
12679###############################################################################
12680#
12681#
12682void
12683QueryFontMetrics(ref,...)
12684 Image::Magick ref=NO_INIT
12685 ALIAS:
12686 queryfontmetrics = 1
12687 PPCODE:
12688 {
12689 AffineMatrix
12690 affine,
12691 current;
12692
12693 AV
12694 *av;
12695
12696 char
12697 *attribute;
12698
12699 double
12700 x,
12701 y;
12702
12703 DrawInfo
12704 *draw_info;
12705
12706 ExceptionInfo
12707 *exception;
12708
12709 GeometryInfo
12710 geometry_info;
12711
12712 Image
12713 *image;
12714
12715 MagickBooleanType
12716 status;
12717
12718 MagickStatusType
12719 flags;
12720
12721 register ssize_t
12722 i;
12723
12724 ssize_t
12725 type;
12726
12727 struct PackageInfo
12728 *info,
12729 *package_info;
12730
12731 SV
12732 *perl_exception,
12733 *reference; /* reference is the SV* of ref=SvIV(reference) */
12734
12735 TypeMetric
12736 metrics;
12737
12738 PERL_UNUSED_VAR(ref);
12739 PERL_UNUSED_VAR(ix);
12740 exception=AcquireExceptionInfo();
12741 package_info=(struct PackageInfo *) NULL;
12742 perl_exception=newSVpv("",0);
12743 reference=SvRV(ST(0));
12744 av=(AV *) reference;
12745 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12746 exception);
12747 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12748 if (image == (Image *) NULL)
12749 {
12750 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12751 PackageName);
12752 goto PerlException;
12753 }
12754 package_info=ClonePackageInfo(info,exception);
12755 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12756 CloneString(&draw_info->text,"");
12757 current=draw_info->affine;
12758 GetAffineMatrix(&affine);
12759 x=0.0;
12760 y=0.0;
12761 EXTEND(sp,7*items);
12762 for (i=2; i < items; i+=2)
12763 {
12764 attribute=(char *) SvPV(ST(i-1),na);
12765 switch (*attribute)
12766 {
12767 case 'A':
12768 case 'a':
12769 {
12770 if (LocaleCompare(attribute,"antialias") == 0)
12771 {
12772 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12773 SvPV(ST(i),na));
12774 if (type < 0)
12775 {
12776 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12777 SvPV(ST(i),na));
12778 break;
12779 }
12780 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12781 break;
12782 }
12783 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12784 attribute);
12785 break;
12786 }
12787 case 'd':
12788 case 'D':
12789 {
12790 if (LocaleCompare(attribute,"density") == 0)
12791 {
12792 CloneString(&draw_info->density,SvPV(ST(i),na));
12793 break;
12794 }
12795 if (LocaleCompare(attribute,"direction") == 0)
12796 {
12797 draw_info->direction=(DirectionType) ParseCommandOption(
12798 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12799 break;
12800 }
12801 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12802 attribute);
12803 break;
12804 }
12805 case 'e':
12806 case 'E':
12807 {
12808 if (LocaleCompare(attribute,"encoding") == 0)
12809 {
12810 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12811 break;
12812 }
12813 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12814 attribute);
12815 break;
12816 }
12817 case 'f':
12818 case 'F':
12819 {
12820 if (LocaleCompare(attribute,"family") == 0)
12821 {
12822 CloneString(&draw_info->family,SvPV(ST(i),na));
12823 break;
12824 }
12825 if (LocaleCompare(attribute,"fill") == 0)
12826 {
12827 if (info)
12828 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12829 &draw_info->fill,exception);
12830 break;
12831 }
12832 if (LocaleCompare(attribute,"font") == 0)
12833 {
12834 CloneString(&draw_info->font,SvPV(ST(i),na));
12835 break;
12836 }
12837 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12838 attribute);
12839 break;
12840 }
12841 case 'g':
12842 case 'G':
12843 {
12844 if (LocaleCompare(attribute,"geometry") == 0)
12845 {
12846 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12847 break;
12848 }
12849 if (LocaleCompare(attribute,"gravity") == 0)
12850 {
12851 draw_info->gravity=(GravityType) ParseCommandOption(
12852 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12853 break;
12854 }
12855 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12856 attribute);
12857 break;
12858 }
12859 case 'i':
12860 case 'I':
12861 {
12862 if (LocaleCompare(attribute,"interline-spacing") == 0)
12863 {
12864 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12865 draw_info->interline_spacing=geometry_info.rho;
12866 break;
12867 }
12868 if (LocaleCompare(attribute,"interword-spacing") == 0)
12869 {
12870 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12871 draw_info->interword_spacing=geometry_info.rho;
12872 break;
12873 }
12874 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12875 attribute);
12876 break;
12877 }
12878 case 'k':
12879 case 'K':
12880 {
12881 if (LocaleCompare(attribute,"kerning") == 0)
12882 {
12883 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12884 draw_info->kerning=geometry_info.rho;
12885 break;
12886 }
12887 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12888 attribute);
12889 break;
12890 }
12891 case 'p':
12892 case 'P':
12893 {
12894 if (LocaleCompare(attribute,"pointsize") == 0)
12895 {
12896 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12897 draw_info->pointsize=geometry_info.rho;
12898 break;
12899 }
12900 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12901 attribute);
12902 break;
12903 }
12904 case 'r':
12905 case 'R':
12906 {
12907 if (LocaleCompare(attribute,"rotate") == 0)
12908 {
12909 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12910 affine.rx=geometry_info.rho;
12911 affine.ry=geometry_info.sigma;
12912 if ((flags & SigmaValue) == 0)
12913 affine.ry=affine.rx;
12914 break;
12915 }
12916 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12917 attribute);
12918 break;
12919 }
12920 case 's':
12921 case 'S':
12922 {
12923 if (LocaleCompare(attribute,"scale") == 0)
12924 {
12925 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12926 affine.sx=geometry_info.rho;
12927 affine.sy=geometry_info.sigma;
12928 if ((flags & SigmaValue) == 0)
12929 affine.sy=affine.sx;
12930 break;
12931 }
12932 if (LocaleCompare(attribute,"skew") == 0)
12933 {
12934 double
12935 x_angle,
12936 y_angle;
12937
12938 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12939 x_angle=geometry_info.rho;
12940 y_angle=geometry_info.sigma;
12941 if ((flags & SigmaValue) == 0)
12942 y_angle=x_angle;
12943 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12944 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12945 break;
12946 }
12947 if (LocaleCompare(attribute,"stroke") == 0)
12948 {
12949 if (info)
12950 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12951 &draw_info->stroke,exception);
12952 break;
12953 }
12954 if (LocaleCompare(attribute,"style") == 0)
12955 {
12956 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12957 SvPV(ST(i),na));
12958 if (type < 0)
12959 {
12960 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12961 SvPV(ST(i),na));
12962 break;
12963 }
12964 draw_info->style=(StyleType) type;
12965 break;
12966 }
12967 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12968 attribute);
12969 break;
12970 }
12971 case 't':
12972 case 'T':
12973 {
12974 if (LocaleCompare(attribute,"text") == 0)
12975 {
12976 CloneString(&draw_info->text,SvPV(ST(i),na));
12977 break;
12978 }
12979 if (LocaleCompare(attribute,"translate") == 0)
12980 {
12981 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12982 affine.tx=geometry_info.rho;
12983 affine.ty=geometry_info.sigma;
12984 if ((flags & SigmaValue) == 0)
12985 affine.ty=affine.tx;
12986 break;
12987 }
12988 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12989 attribute);
12990 break;
12991 }
12992 case 'w':
12993 case 'W':
12994 {
12995 if (LocaleCompare(attribute,"weight") == 0)
12996 {
12997 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12998 draw_info->weight=(size_t) geometry_info.rho;
12999 break;
13000 }
13001 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13002 attribute);
13003 break;
13004 }
13005 case 'x':
13006 case 'X':
13007 {
13008 if (LocaleCompare(attribute,"x") == 0)
13009 {
13010 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13011 x=geometry_info.rho;
13012 break;
13013 }
13014 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13015 attribute);
13016 break;
13017 }
13018 case 'y':
13019 case 'Y':
13020 {
13021 if (LocaleCompare(attribute,"y") == 0)
13022 {
13023 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13024 y=geometry_info.rho;
13025 break;
13026 }
13027 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13028 attribute);
13029 break;
13030 }
13031 default:
13032 {
13033 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13034 attribute);
13035 break;
13036 }
13037 }
13038 }
13039 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13040 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13041 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13042 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13043 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13044 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13045 if (draw_info->geometry == (char *) NULL)
13046 {
13047 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013048 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013049 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013050 }
13051 status=GetTypeMetrics(image,draw_info,&metrics,exception);
13052 (void) CatchImageException(image);
13053 if (status == MagickFalse)
13054 PUSHs(&sv_undef);
13055 else
13056 {
13057 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13058 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13059 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13060 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13061 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13062 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13063 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13064 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13065 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13066 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13067 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13068 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13069 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13070 }
13071 draw_info=DestroyDrawInfo(draw_info);
13072
13073 PerlException:
13074 if (package_info != (struct PackageInfo *) NULL)
13075 DestroyPackageInfo(package_info);
13076 InheritPerlException(exception,perl_exception);
13077 exception=DestroyExceptionInfo(exception);
13078 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13079 }
13080
13081#
13082###############################################################################
13083# #
13084# #
13085# #
13086# 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 #
13087# #
13088# #
13089# #
13090###############################################################################
13091#
13092#
13093void
13094QueryMultilineFontMetrics(ref,...)
13095 Image::Magick ref=NO_INIT
13096 ALIAS:
13097 querymultilinefontmetrics = 1
13098 PPCODE:
13099 {
13100 AffineMatrix
13101 affine,
13102 current;
13103
13104 AV
13105 *av;
13106
13107 char
13108 *attribute;
13109
13110 double
13111 x,
13112 y;
13113
13114 DrawInfo
13115 *draw_info;
13116
13117 ExceptionInfo
13118 *exception;
13119
13120 GeometryInfo
13121 geometry_info;
13122
13123 Image
13124 *image;
13125
13126 MagickBooleanType
13127 status;
13128
13129 MagickStatusType
13130 flags;
13131
13132 register ssize_t
13133 i;
13134
13135 ssize_t
13136 type;
13137
13138 struct PackageInfo
13139 *info,
13140 *package_info;
13141
13142 SV
13143 *perl_exception,
13144 *reference; /* reference is the SV* of ref=SvIV(reference) */
13145
13146 TypeMetric
13147 metrics;
13148
13149 PERL_UNUSED_VAR(ref);
13150 PERL_UNUSED_VAR(ix);
13151 exception=AcquireExceptionInfo();
13152 package_info=(struct PackageInfo *) NULL;
13153 perl_exception=newSVpv("",0);
13154 reference=SvRV(ST(0));
13155 av=(AV *) reference;
13156 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13157 exception);
13158 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13159 if (image == (Image *) NULL)
13160 {
13161 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13162 PackageName);
13163 goto PerlException;
13164 }
13165 package_info=ClonePackageInfo(info,exception);
13166 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13167 CloneString(&draw_info->text,"");
13168 current=draw_info->affine;
13169 GetAffineMatrix(&affine);
13170 x=0.0;
13171 y=0.0;
13172 EXTEND(sp,7*items);
13173 for (i=2; i < items; i+=2)
13174 {
13175 attribute=(char *) SvPV(ST(i-1),na);
13176 switch (*attribute)
13177 {
13178 case 'A':
13179 case 'a':
13180 {
13181 if (LocaleCompare(attribute,"antialias") == 0)
13182 {
13183 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13184 SvPV(ST(i),na));
13185 if (type < 0)
13186 {
13187 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13188 SvPV(ST(i),na));
13189 break;
13190 }
13191 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13192 break;
13193 }
13194 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13195 attribute);
13196 break;
13197 }
13198 case 'd':
13199 case 'D':
13200 {
13201 if (LocaleCompare(attribute,"density") == 0)
13202 {
13203 CloneString(&draw_info->density,SvPV(ST(i),na));
13204 break;
13205 }
13206 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13207 attribute);
13208 break;
13209 }
13210 case 'e':
13211 case 'E':
13212 {
13213 if (LocaleCompare(attribute,"encoding") == 0)
13214 {
13215 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13216 break;
13217 }
13218 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13219 attribute);
13220 break;
13221 }
13222 case 'f':
13223 case 'F':
13224 {
13225 if (LocaleCompare(attribute,"family") == 0)
13226 {
13227 CloneString(&draw_info->family,SvPV(ST(i),na));
13228 break;
13229 }
13230 if (LocaleCompare(attribute,"fill") == 0)
13231 {
13232 if (info)
13233 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13234 &draw_info->fill,exception);
13235 break;
13236 }
13237 if (LocaleCompare(attribute,"font") == 0)
13238 {
13239 CloneString(&draw_info->font,SvPV(ST(i),na));
13240 break;
13241 }
13242 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13243 attribute);
13244 break;
13245 }
13246 case 'g':
13247 case 'G':
13248 {
13249 if (LocaleCompare(attribute,"geometry") == 0)
13250 {
13251 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13252 break;
13253 }
13254 if (LocaleCompare(attribute,"gravity") == 0)
13255 {
13256 draw_info->gravity=(GravityType) ParseCommandOption(
13257 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13258 break;
13259 }
13260 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13261 attribute);
13262 break;
13263 }
13264 case 'p':
13265 case 'P':
13266 {
13267 if (LocaleCompare(attribute,"pointsize") == 0)
13268 {
13269 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13270 draw_info->pointsize=geometry_info.rho;
13271 break;
13272 }
13273 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13274 attribute);
13275 break;
13276 }
13277 case 'r':
13278 case 'R':
13279 {
13280 if (LocaleCompare(attribute,"rotate") == 0)
13281 {
13282 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13283 affine.rx=geometry_info.rho;
13284 affine.ry=geometry_info.sigma;
13285 if ((flags & SigmaValue) == 0)
13286 affine.ry=affine.rx;
13287 break;
13288 }
13289 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13290 attribute);
13291 break;
13292 }
13293 case 's':
13294 case 'S':
13295 {
13296 if (LocaleCompare(attribute,"scale") == 0)
13297 {
13298 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13299 affine.sx=geometry_info.rho;
13300 affine.sy=geometry_info.sigma;
13301 if ((flags & SigmaValue) == 0)
13302 affine.sy=affine.sx;
13303 break;
13304 }
13305 if (LocaleCompare(attribute,"skew") == 0)
13306 {
13307 double
13308 x_angle,
13309 y_angle;
13310
13311 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13312 x_angle=geometry_info.rho;
13313 y_angle=geometry_info.sigma;
13314 if ((flags & SigmaValue) == 0)
13315 y_angle=x_angle;
13316 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13317 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13318 break;
13319 }
13320 if (LocaleCompare(attribute,"stroke") == 0)
13321 {
13322 if (info)
13323 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13324 &draw_info->stroke,exception);
13325 break;
13326 }
13327 if (LocaleCompare(attribute,"style") == 0)
13328 {
13329 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13330 SvPV(ST(i),na));
13331 if (type < 0)
13332 {
13333 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13334 SvPV(ST(i),na));
13335 break;
13336 }
13337 draw_info->style=(StyleType) type;
13338 break;
13339 }
13340 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13341 attribute);
13342 break;
13343 }
13344 case 't':
13345 case 'T':
13346 {
13347 if (LocaleCompare(attribute,"text") == 0)
13348 {
13349 CloneString(&draw_info->text,SvPV(ST(i),na));
13350 break;
13351 }
13352 if (LocaleCompare(attribute,"translate") == 0)
13353 {
13354 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13355 affine.tx=geometry_info.rho;
13356 affine.ty=geometry_info.sigma;
13357 if ((flags & SigmaValue) == 0)
13358 affine.ty=affine.tx;
13359 break;
13360 }
13361 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13362 attribute);
13363 break;
13364 }
13365 case 'w':
13366 case 'W':
13367 {
13368 if (LocaleCompare(attribute,"weight") == 0)
13369 {
13370 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13371 draw_info->weight=(size_t) geometry_info.rho;
13372 break;
13373 }
13374 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13375 attribute);
13376 break;
13377 }
13378 case 'x':
13379 case 'X':
13380 {
13381 if (LocaleCompare(attribute,"x") == 0)
13382 {
13383 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13384 x=geometry_info.rho;
13385 break;
13386 }
13387 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13388 attribute);
13389 break;
13390 }
13391 case 'y':
13392 case 'Y':
13393 {
13394 if (LocaleCompare(attribute,"y") == 0)
13395 {
13396 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13397 y=geometry_info.rho;
13398 break;
13399 }
13400 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13401 attribute);
13402 break;
13403 }
13404 default:
13405 {
13406 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13407 attribute);
13408 break;
13409 }
13410 }
13411 }
13412 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13413 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13414 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13415 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13416 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13417 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13418 if (draw_info->geometry == (char *) NULL)
13419 {
13420 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013421 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013422 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013423 }
13424 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13425 (void) CatchException(exception);
13426 if (status == MagickFalse)
13427 PUSHs(&sv_undef);
13428 else
13429 {
13430 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13431 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13432 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13433 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13434 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13435 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13436 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13437 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13438 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13439 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13440 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13441 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13442 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13443 }
13444 draw_info=DestroyDrawInfo(draw_info);
13445
13446 PerlException:
13447 if (package_info != (struct PackageInfo *) NULL)
13448 DestroyPackageInfo(package_info);
13449 InheritPerlException(exception,perl_exception);
13450 exception=DestroyExceptionInfo(exception);
13451 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13452 }
13453
13454#
13455###############################################################################
13456# #
13457# #
13458# #
13459# Q u e r y F o r m a t #
13460# #
13461# #
13462# #
13463###############################################################################
13464#
13465#
13466void
13467QueryFormat(ref,...)
13468 Image::Magick ref=NO_INIT
13469 ALIAS:
13470 queryformat = 1
13471 PPCODE:
13472 {
13473 char
13474 *name;
13475
13476 ExceptionInfo
13477 *exception;
13478
13479 register ssize_t
13480 i;
13481
13482 SV
13483 *perl_exception;
13484
13485 volatile const MagickInfo
13486 *magick_info;
13487
13488 PERL_UNUSED_VAR(ref);
13489 PERL_UNUSED_VAR(ix);
13490 exception=AcquireExceptionInfo();
13491 perl_exception=newSVpv("",0);
13492 if (items == 1)
13493 {
13494 char
cristy151b66d2015-04-15 10:50:31 +000013495 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013496
13497 const MagickInfo
13498 **format_list;
13499
13500 size_t
13501 types;
13502
13503 format_list=GetMagickInfoList("*",&types,exception);
13504 EXTEND(sp,types);
13505 for (i=0; i < (ssize_t) types; i++)
13506 {
cristy151b66d2015-04-15 10:50:31 +000013507 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013508 LocaleLower(format);
13509 PUSHs(sv_2mortal(newSVpv(format,0)));
13510 }
13511 format_list=(const MagickInfo **)
13512 RelinquishMagickMemory((MagickInfo *) format_list);
13513 goto PerlException;
13514 }
13515 EXTEND(sp,8*items);
13516 for (i=1; i < items; i++)
13517 {
13518 name=(char *) SvPV(ST(i),na);
13519 magick_info=GetMagickInfo(name,exception);
13520 if (magick_info == (const MagickInfo *) NULL)
13521 {
13522 PUSHs(&sv_undef);
13523 continue;
13524 }
cristy4a3ce0a2013-08-03 20:06:59 +000013525 if (magick_info->description == (char *) NULL)
13526 PUSHs(&sv_undef);
13527 else
13528 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13529 if (magick_info->module == (char *) NULL)
13530 PUSHs(&sv_undef);
13531 else
13532 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13533 }
13534
13535 PerlException:
13536 InheritPerlException(exception,perl_exception);
13537 exception=DestroyExceptionInfo(exception);
13538 SvREFCNT_dec(perl_exception);
13539 }
13540
13541#
13542###############################################################################
13543# #
13544# #
13545# #
13546# Q u e r y O p t i o n #
13547# #
13548# #
13549# #
13550###############################################################################
13551#
13552#
13553void
13554QueryOption(ref,...)
13555 Image::Magick ref=NO_INIT
13556 ALIAS:
13557 queryoption = 1
13558 PPCODE:
13559 {
13560 char
13561 **options;
13562
13563 ExceptionInfo
13564 *exception;
13565
13566 register ssize_t
13567 i;
13568
13569 ssize_t
13570 j,
13571 option;
13572
13573 SV
13574 *perl_exception;
13575
13576 PERL_UNUSED_VAR(ref);
13577 PERL_UNUSED_VAR(ix);
13578 exception=AcquireExceptionInfo();
13579 perl_exception=newSVpv("",0);
13580 EXTEND(sp,8*items);
13581 for (i=1; i < items; i++)
13582 {
13583 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13584 SvPV(ST(i),na));
13585 options=GetCommandOptions((CommandOption) option);
13586 if (options == (char **) NULL)
13587 PUSHs(&sv_undef);
13588 else
13589 {
13590 for (j=0; options[j] != (char *) NULL; j++)
13591 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13592 options=DestroyStringList(options);
13593 }
13594 }
13595
13596 InheritPerlException(exception,perl_exception);
13597 exception=DestroyExceptionInfo(exception);
13598 SvREFCNT_dec(perl_exception);
13599 }
13600
13601#
13602###############################################################################
13603# #
13604# #
13605# #
13606# R e a d #
13607# #
13608# #
13609# #
13610###############################################################################
13611#
13612#
13613void
13614Read(ref,...)
13615 Image::Magick ref=NO_INIT
13616 ALIAS:
13617 ReadImage = 1
13618 read = 2
13619 readimage = 3
13620 PPCODE:
13621 {
13622 AV
13623 *av;
13624
13625 char
13626 **keep,
13627 **list;
13628
13629 ExceptionInfo
13630 *exception;
13631
13632 HV
13633 *hv;
13634
13635 Image
13636 *image;
13637
13638 int
13639 n;
13640
13641 MagickBooleanType
13642 status;
13643
13644 register char
13645 **p;
13646
13647 register ssize_t
13648 i;
13649
13650 ssize_t
13651 ac,
13652 number_images;
13653
13654 STRLEN
13655 *length;
13656
13657 struct PackageInfo
13658 *info,
13659 *package_info;
13660
13661 SV
13662 *perl_exception, /* Perl variable for storing messages */
13663 *reference,
13664 *rv,
13665 *sv;
13666
13667 PERL_UNUSED_VAR(ref);
13668 PERL_UNUSED_VAR(ix);
13669 exception=AcquireExceptionInfo();
13670 perl_exception=newSVpv("",0);
13671 sv=NULL;
13672 package_info=(struct PackageInfo *) NULL;
13673 number_images=0;
13674 ac=(items < 2) ? 1 : items-1;
13675 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13676 keep=list;
13677 length=(STRLEN *) NULL;
13678 if (list == (char **) NULL)
13679 {
13680 ThrowPerlException(exception,ResourceLimitError,
13681 "MemoryAllocationFailed",PackageName);
13682 goto PerlException;
13683 }
13684 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13685 if (length == (STRLEN *) NULL)
13686 {
13687 ThrowPerlException(exception,ResourceLimitError,
13688 "MemoryAllocationFailed",PackageName);
13689 goto PerlException;
13690 }
13691 if (sv_isobject(ST(0)) == 0)
13692 {
13693 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13694 PackageName);
13695 goto PerlException;
13696 }
13697 reference=SvRV(ST(0));
13698 hv=SvSTASH(reference);
13699 if (SvTYPE(reference) != SVt_PVAV)
13700 {
13701 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13702 PackageName);
13703 goto PerlException;
13704 }
13705 av=(AV *) reference;
13706 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13707 exception);
13708 package_info=ClonePackageInfo(info,exception);
13709 n=1;
13710 if (items <= 1)
13711 *list=(char *) (*package_info->image_info->filename ?
13712 package_info->image_info->filename : "XC:black");
13713 else
13714 for (n=0, i=0; i < ac; i++)
13715 {
13716 list[n]=(char *) SvPV(ST(i+1),length[n]);
13717 if ((items >= 3) && strEQcase(list[n],"blob"))
13718 {
13719 void
13720 *blob;
13721
13722 i++;
13723 blob=(void *) (SvPV(ST(i+1),length[n]));
13724 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13725 }
13726 if ((items >= 3) && strEQcase(list[n],"filename"))
13727 continue;
13728 if ((items >= 3) && strEQcase(list[n],"file"))
13729 {
13730 FILE
13731 *file;
13732
13733 PerlIO
13734 *io_info;
13735
13736 i++;
13737 io_info=IoIFP(sv_2io(ST(i+1)));
13738 if (io_info == (PerlIO *) NULL)
13739 {
13740 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13741 PackageName);
13742 continue;
13743 }
13744 file=PerlIO_findFILE(io_info);
13745 if (file == (FILE *) NULL)
13746 {
13747 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13748 PackageName);
13749 continue;
13750 }
13751 SetImageInfoFile(package_info->image_info,file);
13752 }
13753 if ((items >= 3) && strEQcase(list[n],"magick"))
13754 continue;
13755 n++;
13756 }
13757 list[n]=(char *) NULL;
13758 keep=list;
13759 status=ExpandFilenames(&n,&list);
13760 if (status == MagickFalse)
13761 {
13762 ThrowPerlException(exception,ResourceLimitError,
13763 "MemoryAllocationFailed",PackageName);
13764 goto PerlException;
13765 }
13766 number_images=0;
13767 for (i=0; i < n; i++)
13768 {
13769 if ((package_info->image_info->file == (FILE *) NULL) &&
13770 (package_info->image_info->blob == (void *) NULL))
13771 image=ReadImages(package_info->image_info,list[i],exception);
13772 else
13773 {
13774 image=ReadImages(package_info->image_info,
13775 package_info->image_info->filename,exception);
13776 if (image != (Image *) NULL)
13777 DisassociateImageStream(image);
13778 }
13779 if (image == (Image *) NULL)
13780 break;
13781 for ( ; image; image=image->next)
13782 {
13783 AddImageToRegistry(sv,image);
13784 rv=newRV(sv);
13785 av_push(av,sv_bless(rv,hv));
13786 SvREFCNT_dec(sv);
13787 number_images++;
13788 }
13789 }
13790 /*
13791 Free resources.
13792 */
13793 for (i=0; i < n; i++)
13794 if (list[i] != (char *) NULL)
13795 for (p=keep; list[i] != *p++; )
13796 if (*p == (char *) NULL)
13797 {
13798 list[i]=(char *) RelinquishMagickMemory(list[i]);
13799 break;
13800 }
13801
13802 PerlException:
13803 if (package_info != (struct PackageInfo *) NULL)
13804 DestroyPackageInfo(package_info);
13805 if (list && (list != keep))
13806 list=(char **) RelinquishMagickMemory(list);
13807 if (keep)
13808 keep=(char **) RelinquishMagickMemory(keep);
13809 if (length)
13810 length=(STRLEN *) RelinquishMagickMemory(length);
13811 InheritPerlException(exception,perl_exception);
13812 exception=DestroyExceptionInfo(exception);
13813 sv_setiv(perl_exception,(IV) number_images);
13814 SvPOK_on(perl_exception);
13815 ST(0)=sv_2mortal(perl_exception);
13816 XSRETURN(1);
13817 }
13818
13819#
13820###############################################################################
13821# #
13822# #
13823# #
13824# R e m o t e #
13825# #
13826# #
13827# #
13828###############################################################################
13829#
13830#
13831void
13832Remote(ref,...)
13833 Image::Magick ref=NO_INIT
13834 ALIAS:
13835 RemoteCommand = 1
13836 remote = 2
13837 remoteCommand = 3
13838 PPCODE:
13839 {
13840 AV
13841 *av;
13842
13843 ExceptionInfo
13844 *exception;
13845
13846 register ssize_t
13847 i;
13848
13849 SV
13850 *perl_exception,
13851 *reference;
13852
13853 struct PackageInfo
13854 *info;
13855
13856 PERL_UNUSED_VAR(ref);
13857 PERL_UNUSED_VAR(ix);
13858 exception=AcquireExceptionInfo();
13859 perl_exception=newSVpv("",0);
13860 reference=SvRV(ST(0));
13861 av=(AV *) reference;
13862 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13863 exception);
13864 for (i=1; i < items; i++)
13865 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13866 SvPV(ST(i),na),exception);
13867 InheritPerlException(exception,perl_exception);
13868 exception=DestroyExceptionInfo(exception);
13869 SvREFCNT_dec(perl_exception); /* throw away all errors */
13870 }
13871
13872#
13873###############################################################################
13874# #
13875# #
13876# #
13877# S e t #
13878# #
13879# #
13880# #
13881###############################################################################
13882#
13883#
13884void
13885Set(ref,...)
13886 Image::Magick ref=NO_INIT
13887 ALIAS:
13888 SetAttributes = 1
13889 SetAttribute = 2
13890 set = 3
13891 setattributes = 4
13892 setattribute = 5
13893 PPCODE:
13894 {
13895 ExceptionInfo
13896 *exception;
13897
13898 Image
13899 *image;
13900
13901 register ssize_t
13902 i;
13903
13904 struct PackageInfo
13905 *info;
13906
13907 SV
13908 *perl_exception,
13909 *reference; /* reference is the SV* of ref=SvIV(reference) */
13910
13911 PERL_UNUSED_VAR(ref);
13912 PERL_UNUSED_VAR(ix);
13913 exception=AcquireExceptionInfo();
13914 perl_exception=newSVpv("",0);
13915 if (sv_isobject(ST(0)) == 0)
13916 {
13917 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13918 PackageName);
13919 goto PerlException;
13920 }
13921 reference=SvRV(ST(0));
13922 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13923 if (items == 2)
13924 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13925 else
13926 for (i=2; i < items; i+=2)
13927 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13928
13929 PerlException:
13930 InheritPerlException(exception,perl_exception);
13931 exception=DestroyExceptionInfo(exception);
13932 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13933 SvPOK_on(perl_exception);
13934 ST(0)=sv_2mortal(perl_exception);
13935 XSRETURN(1);
13936 }
13937
13938#
13939###############################################################################
13940# #
13941# #
13942# #
13943# S e t P i x e l #
13944# #
13945# #
13946# #
13947###############################################################################
13948#
13949#
13950void
13951SetPixel(ref,...)
13952 Image::Magick ref=NO_INIT
13953 ALIAS:
13954 setpixel = 1
13955 setPixel = 2
13956 PPCODE:
13957 {
13958 AV
13959 *av;
13960
13961 char
13962 *attribute;
13963
13964 ChannelType
13965 channel,
13966 channel_mask;
13967
13968 ExceptionInfo
13969 *exception;
13970
13971 Image
13972 *image;
13973
13974 MagickBooleanType
13975 normalize;
13976
13977 RectangleInfo
13978 region;
13979
13980 register ssize_t
13981 i;
13982
13983 register Quantum
13984 *q;
13985
13986 ssize_t
13987 option;
13988
13989 struct PackageInfo
13990 *info;
13991
13992 SV
13993 *perl_exception,
13994 *reference; /* reference is the SV* of ref=SvIV(reference) */
13995
13996 PERL_UNUSED_VAR(ref);
13997 PERL_UNUSED_VAR(ix);
13998 exception=AcquireExceptionInfo();
13999 perl_exception=newSVpv("",0);
14000 reference=SvRV(ST(0));
14001 av=(AV *) reference;
14002 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14003 exception);
14004 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14005 if (image == (Image *) NULL)
14006 {
14007 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14008 PackageName);
14009 goto PerlException;
14010 }
14011 av=(AV *) NULL;
14012 normalize=MagickTrue;
14013 region.x=0;
14014 region.y=0;
14015 region.width=image->columns;
14016 region.height=1;
14017 if (items == 1)
14018 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
14019 channel=DefaultChannels;
14020 for (i=2; i < items; i+=2)
14021 {
14022 attribute=(char *) SvPV(ST(i-1),na);
14023 switch (*attribute)
14024 {
14025 case 'C':
14026 case 'c':
14027 {
14028 if (LocaleCompare(attribute,"channel") == 0)
14029 {
14030 ssize_t
14031 option;
14032
14033 option=ParseChannelOption(SvPV(ST(i),na));
14034 if (option < 0)
14035 {
14036 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14037 SvPV(ST(i),na));
14038 return;
14039 }
14040 channel=(ChannelType) option;
14041 break;
14042 }
14043 if (LocaleCompare(attribute,"color") == 0)
14044 {
14045 if (SvTYPE(ST(i)) != SVt_RV)
14046 {
14047 char
cristy151b66d2015-04-15 10:50:31 +000014048 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014049
cristy151b66d2015-04-15 10:50:31 +000014050 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000014051 "invalid %.60s value",attribute);
14052 ThrowPerlException(exception,OptionError,message,
14053 SvPV(ST(i),na));
14054 }
14055 av=(AV *) SvRV(ST(i));
14056 break;
14057 }
14058 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14059 attribute);
14060 break;
14061 }
14062 case 'g':
14063 case 'G':
14064 {
14065 if (LocaleCompare(attribute,"geometry") == 0)
14066 {
14067 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14068 break;
14069 }
14070 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14071 attribute);
14072 break;
14073 }
14074 case 'N':
14075 case 'n':
14076 {
14077 if (LocaleCompare(attribute,"normalize") == 0)
14078 {
14079 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14080 SvPV(ST(i),na));
14081 if (option < 0)
14082 {
14083 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14084 SvPV(ST(i),na));
14085 break;
14086 }
14087 normalize=option != 0 ? MagickTrue : MagickFalse;
14088 break;
14089 }
14090 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14091 attribute);
14092 break;
14093 }
14094 case 'x':
14095 case 'X':
14096 {
14097 if (LocaleCompare(attribute,"x") == 0)
14098 {
14099 region.x=SvIV(ST(i));
14100 break;
14101 }
14102 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14103 attribute);
14104 break;
14105 }
14106 case 'y':
14107 case 'Y':
14108 {
14109 if (LocaleCompare(attribute,"y") == 0)
14110 {
14111 region.y=SvIV(ST(i));
14112 break;
14113 }
14114 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14115 attribute);
14116 break;
14117 }
14118 default:
14119 {
14120 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14121 attribute);
14122 break;
14123 }
14124 }
14125 }
14126 (void) SetImageStorageClass(image,DirectClass,exception);
14127 channel_mask=SetImageChannelMask(image,channel);
14128 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14129 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14130 (SvTYPE(av) != SVt_PVAV))
14131 PUSHs(&sv_undef);
14132 else
14133 {
14134 double
14135 scale;
14136
14137 register ssize_t
14138 i;
14139
14140 i=0;
14141 scale=1.0;
14142 if (normalize != MagickFalse)
14143 scale=QuantumRange;
14144 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14145 (i <= av_len(av)))
14146 {
14147 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14148 av_fetch(av,i,0)))),q);
14149 i++;
14150 }
14151 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14152 (i <= av_len(av)))
14153 {
14154 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14155 av_fetch(av,i,0)))),q);
14156 i++;
14157 }
14158 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14159 (i <= av_len(av)))
14160 {
14161 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14162 av_fetch(av,i,0)))),q);
14163 i++;
14164 }
14165 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14166 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14167 {
14168 SetPixelBlack(image,ClampToQuantum(scale*
14169 SvNV(*(av_fetch(av,i,0)))),q);
14170 i++;
14171 }
14172 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14173 (i <= av_len(av)))
14174 {
14175 SetPixelAlpha(image,ClampToQuantum(scale*
14176 SvNV(*(av_fetch(av,i,0)))),q);
14177 i++;
14178 }
14179 (void) SyncAuthenticPixels(image,exception);
14180 }
14181 (void) SetImageChannelMask(image,channel_mask);
14182
14183 PerlException:
14184 InheritPerlException(exception,perl_exception);
14185 exception=DestroyExceptionInfo(exception);
14186 SvREFCNT_dec(perl_exception);
14187 }
14188
14189#
14190###############################################################################
14191# #
14192# #
14193# #
14194# S m u s h #
14195# #
14196# #
14197# #
14198###############################################################################
14199#
14200#
14201void
14202Smush(ref,...)
14203 Image::Magick ref=NO_INIT
14204 ALIAS:
14205 SmushImage = 1
14206 smush = 2
14207 smushimage = 3
14208 PPCODE:
14209 {
14210 AV
14211 *av;
14212
14213 char
14214 *attribute;
14215
14216 ExceptionInfo
14217 *exception;
14218
14219 HV
14220 *hv;
14221
14222 Image
14223 *image;
14224
14225 register ssize_t
14226 i;
14227
14228 ssize_t
14229 offset,
14230 stack;
14231
14232 struct PackageInfo
14233 *info;
14234
14235 SV
14236 *av_reference,
14237 *perl_exception,
14238 *reference,
14239 *rv,
14240 *sv;
14241
14242 PERL_UNUSED_VAR(ref);
14243 PERL_UNUSED_VAR(ix);
14244 exception=AcquireExceptionInfo();
14245 perl_exception=newSVpv("",0);
14246 sv=NULL;
14247 attribute=NULL;
14248 av=NULL;
14249 if (sv_isobject(ST(0)) == 0)
14250 {
14251 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14252 PackageName);
14253 goto PerlException;
14254 }
14255 reference=SvRV(ST(0));
14256 hv=SvSTASH(reference);
14257 av=newAV();
14258 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14259 SvREFCNT_dec(av);
14260 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14261 if (image == (Image *) NULL)
14262 {
14263 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14264 PackageName);
14265 goto PerlException;
14266 }
14267 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14268 /*
14269 Get options.
14270 */
14271 offset=0;
14272 stack=MagickTrue;
14273 for (i=2; i < items; i+=2)
14274 {
14275 attribute=(char *) SvPV(ST(i-1),na);
14276 switch (*attribute)
14277 {
14278 case 'O':
14279 case 'o':
14280 {
14281 if (LocaleCompare(attribute,"offset") == 0)
14282 {
14283 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14284 break;
14285 }
14286 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14287 attribute);
14288 break;
14289 }
14290 case 'S':
14291 case 's':
14292 {
14293 if (LocaleCompare(attribute,"stack") == 0)
14294 {
14295 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14296 SvPV(ST(i),na));
14297 if (stack < 0)
14298 {
14299 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14300 SvPV(ST(i),na));
14301 return;
14302 }
14303 break;
14304 }
14305 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14306 attribute);
14307 break;
14308 }
14309 default:
14310 {
14311 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14312 attribute);
14313 break;
14314 }
14315 }
14316 }
14317 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14318 exception);
14319 if (image == (Image *) NULL)
14320 goto PerlException;
14321 for ( ; image; image=image->next)
14322 {
14323 AddImageToRegistry(sv,image);
14324 rv=newRV(sv);
14325 av_push(av,sv_bless(rv,hv));
14326 SvREFCNT_dec(sv);
14327 }
14328 exception=DestroyExceptionInfo(exception);
14329 ST(0)=av_reference;
14330 SvREFCNT_dec(perl_exception);
14331 XSRETURN(1);
14332
14333 PerlException:
14334 InheritPerlException(exception,perl_exception);
14335 exception=DestroyExceptionInfo(exception);
14336 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14337 SvPOK_on(perl_exception);
14338 ST(0)=sv_2mortal(perl_exception);
14339 XSRETURN(1);
14340 }
14341
14342#
14343###############################################################################
14344# #
14345# #
14346# #
14347# S t a t i s t i c s #
14348# #
14349# #
14350# #
14351###############################################################################
14352#
14353#
14354void
14355Statistics(ref,...)
14356 Image::Magick ref=NO_INIT
14357 ALIAS:
14358 StatisticsImage = 1
14359 statistics = 2
14360 statisticsimage = 3
14361 PPCODE:
14362 {
14363#define ChannelStatistics(channel) \
14364{ \
cristy151b66d2015-04-15 10:50:31 +000014365 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014366 (double) channel_statistics[channel].depth); \
14367 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014368 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014369 channel_statistics[channel].minima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014370 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014371 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014372 channel_statistics[channel].maxima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014373 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014374 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014375 channel_statistics[channel].mean/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014376 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014377 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014378 channel_statistics[channel].standard_deviation/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014379 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014380 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014381 channel_statistics[channel].kurtosis); \
14382 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014383 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014384 channel_statistics[channel].skewness); \
14385 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014386 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy275bdd92014-11-08 23:45:03 +000014387 channel_statistics[channel].entropy); \
14388 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014389}
14390
14391 AV
14392 *av;
14393
14394 char
cristy151b66d2015-04-15 10:50:31 +000014395 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014396
14397 ChannelStatistics
14398 *channel_statistics;
14399
cristy4a3ce0a2013-08-03 20:06:59 +000014400 ExceptionInfo
14401 *exception;
14402
14403 Image
14404 *image;
14405
14406 ssize_t
14407 count;
14408
14409 struct PackageInfo
14410 *info;
14411
14412 SV
14413 *perl_exception,
14414 *reference;
14415
14416 PERL_UNUSED_VAR(ref);
14417 PERL_UNUSED_VAR(ix);
14418 exception=AcquireExceptionInfo();
14419 perl_exception=newSVpv("",0);
14420 av=NULL;
14421 if (sv_isobject(ST(0)) == 0)
14422 {
14423 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14424 PackageName);
14425 goto PerlException;
14426 }
14427 reference=SvRV(ST(0));
14428 av=newAV();
14429 SvREFCNT_dec(av);
14430 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14431 if (image == (Image *) NULL)
14432 {
14433 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14434 PackageName);
14435 goto PerlException;
14436 }
cristy4a3ce0a2013-08-03 20:06:59 +000014437 count=0;
14438 for ( ; image; image=image->next)
14439 {
Cristyb1710fe2017-02-11 13:51:48 -050014440 register size_t
14441 i;
14442
cristy4a3ce0a2013-08-03 20:06:59 +000014443 channel_statistics=GetImageStatistics(image,exception);
14444 if (channel_statistics == (ChannelStatistics *) NULL)
14445 continue;
14446 count++;
Cristyb1710fe2017-02-11 13:51:48 -050014447 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
14448 {
14449 PixelChannel channel=GetPixelChannelChannel(image,i);
14450 PixelTrait traits=GetPixelChannelTraits(image,channel);
Cristy5a854dc2017-02-11 15:43:46 -050014451 if (traits == UndefinedPixelTrait)
Cristyb1710fe2017-02-11 13:51:48 -050014452 continue;
Cristy5a854dc2017-02-11 15:43:46 -050014453 EXTEND(sp,8*(i+1)*count);
Cristyb1710fe2017-02-11 13:51:48 -050014454 ChannelStatistics(channel);
14455 }
Cristy25813902017-02-11 15:47:52 -050014456 EXTEND(sp,8*(i+1)*count);
14457 ChannelStatistics(CompositePixelChannel);
cristy4a3ce0a2013-08-03 20:06:59 +000014458 channel_statistics=(ChannelStatistics *)
14459 RelinquishMagickMemory(channel_statistics);
14460 }
14461
14462 PerlException:
14463 InheritPerlException(exception,perl_exception);
14464 exception=DestroyExceptionInfo(exception);
14465 SvREFCNT_dec(perl_exception);
14466 }
14467
14468#
14469###############################################################################
14470# #
14471# #
14472# #
14473# S y n c A u t h e n t i c P i x e l s #
14474# #
14475# #
14476# #
14477###############################################################################
14478#
14479#
14480void
14481SyncAuthenticPixels(ref,...)
14482 Image::Magick ref = NO_INIT
14483 ALIAS:
14484 Syncauthenticpixels = 1
14485 SyncImagePixels = 2
14486 syncimagepixels = 3
14487 CODE:
14488 {
14489 ExceptionInfo
14490 *exception;
14491
14492 Image
14493 *image;
14494
14495 MagickBooleanType
14496 status;
14497
14498 struct PackageInfo
14499 *info;
14500
14501 SV
14502 *perl_exception,
14503 *reference;
14504
14505 PERL_UNUSED_VAR(ref);
14506 PERL_UNUSED_VAR(ix);
14507 exception=AcquireExceptionInfo();
14508 perl_exception=newSVpv("",0);
14509 if (sv_isobject(ST(0)) == 0)
14510 {
14511 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14512 PackageName);
14513 goto PerlException;
14514 }
14515
14516 reference=SvRV(ST(0));
14517 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14518 if (image == (Image *) NULL)
14519 {
14520 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14521 PackageName);
14522 goto PerlException;
14523 }
14524
14525 status=SyncAuthenticPixels(image,exception);
14526 if (status != MagickFalse)
14527 return;
14528
14529 PerlException:
14530 InheritPerlException(exception,perl_exception);
14531 exception=DestroyExceptionInfo(exception);
14532 SvREFCNT_dec(perl_exception); /* throw away all errors */
14533 }
14534
14535#
14536###############################################################################
14537# #
14538# #
14539# #
cristy4a3ce0a2013-08-03 20:06:59 +000014540# W r i t e #
14541# #
14542# #
14543# #
14544###############################################################################
14545#
14546#
14547void
14548Write(ref,...)
14549 Image::Magick ref=NO_INIT
14550 ALIAS:
14551 WriteImage = 1
14552 write = 2
14553 writeimage = 3
14554 PPCODE:
14555 {
14556 char
cristy151b66d2015-04-15 10:50:31 +000014557 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014558
14559 ExceptionInfo
14560 *exception;
14561
14562 Image
14563 *image,
14564 *next;
14565
14566 register ssize_t
14567 i;
14568
14569 ssize_t
14570 number_images,
14571 scene;
14572
14573 struct PackageInfo
14574 *info,
14575 *package_info;
14576
14577 SV
14578 *perl_exception,
14579 *reference;
14580
14581 PERL_UNUSED_VAR(ref);
14582 PERL_UNUSED_VAR(ix);
14583 exception=AcquireExceptionInfo();
14584 perl_exception=newSVpv("",0);
14585 number_images=0;
14586 package_info=(struct PackageInfo *) NULL;
14587 if (sv_isobject(ST(0)) == 0)
14588 {
14589 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14590 PackageName);
14591 goto PerlException;
14592 }
14593 reference=SvRV(ST(0));
14594 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14595 if (image == (Image *) NULL)
14596 {
14597 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14598 PackageName);
14599 goto PerlException;
14600 }
14601 package_info=ClonePackageInfo(info,exception);
14602 if (items == 2)
14603 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14604 else
14605 if (items > 2)
14606 for (i=2; i < items; i+=2)
14607 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14608 exception);
14609 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014610 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014611 scene=0;
14612 for (next=image; next; next=next->next)
14613 {
cristy151b66d2015-04-15 10:50:31 +000014614 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014615 next->scene=scene++;
14616 }
cristy68bd79a2015-02-25 12:23:36 +000014617 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014618 SetImageInfo(package_info->image_info,(unsigned int)
14619 GetImageListLength(image),exception);
14620 for (next=image; next; next=next->next)
14621 {
14622 (void) WriteImage(package_info->image_info,next,exception);
14623 number_images++;
14624 if (package_info->image_info->adjoin)
14625 break;
14626 }
14627
14628 PerlException:
14629 if (package_info != (struct PackageInfo *) NULL)
14630 DestroyPackageInfo(package_info);
14631 InheritPerlException(exception,perl_exception);
14632 exception=DestroyExceptionInfo(exception);
14633 sv_setiv(perl_exception,(IV) number_images);
14634 SvPOK_on(perl_exception);
14635 ST(0)=sv_2mortal(perl_exception);
14636 XSRETURN(1);
14637 }