blob: 2e10c8dc92705a05052d2ca50e18c01db3662d62 [file] [log] [blame]
cristy4a3ce0a2013-08-03 20:06:59 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% PPPP EEEEE RRRR L %
6% P P E R R L %
7% PPPP EEE RRRR L %
8% P E R R L %
9% P EEEEE R R LLLLL %
10% %
11% M M AAA GGGG IIIII CCCC K K %
12% MM MM A A G I C K K %
13% M M M AAAAA G GGG I C KKK %
14% M M A A G G I C K K %
15% M M A A GGGG IIIII CCCC K K %
16% %
17% %
18% Object-oriented Perl interface to ImageMagick %
19% %
20% Software Design %
21% Kyle Shorter %
cristyde984cd2013-12-01 14:49:27 +000022% Cristy %
cristy4a3ce0a2013-08-03 20:06:59 +000023% February 1997 %
24% %
25% %
Cristyf6ff9ea2016-12-05 09:53:35 -050026% Copyright 1999-2017 ImageMagick Studio LLC, a non-profit organization %
cristy4a3ce0a2013-08-03 20:06:59 +000027% dedicated to making software imaging solutions freely available. %
28% %
29% You may not use this file except in compliance with the License. You may %
30% obtain a copy of the License at %
31% %
32% http://www.imagemagick.org/script/license.php %
33% %
34% Unless required by applicable law or agreed to in writing, software %
35% distributed under the License is distributed on an "AS IS" BASIS, %
36% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
37% See the License for the specific language governing permissions and %
38% limitations under the License. %
39% %
40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41%
42% PerlMagick is an objected-oriented Perl interface to ImageMagick. Use
43% the module to read, manipulate, or write an image or image sequence from
44% within a Perl script. This makes PerlMagick suitable for Web CGI scripts.
45%
46*/
47
48/*
49 Include declarations.
50*/
51#if defined(__cplusplus) || defined(c_plusplus)
52extern "C" {
53#endif
54
55#define PERL_NO_GET_CONTEXT
dirk190cc1c2015-06-16 11:48:37 +000056#include <MagickCore/MagickCore.h>
cristy4a3ce0a2013-08-03 20:06:59 +000057#include "EXTERN.h"
58#include "perl.h"
59#include "XSUB.h"
60#include <math.h>
cristy4a3ce0a2013-08-03 20:06:59 +000061#undef tainted
62
63#if defined(__cplusplus) || defined(c_plusplus)
64}
65#endif
66
67/*
68 Define declarations.
69*/
70#ifndef aTHX_
71#define aTHX_
72#define pTHX_
73#define dTHX
74#endif
75#define DegreesToRadians(x) (MagickPI*(x)/180.0)
76#define EndOf(array) (&array[NumberOf(array)])
cristy3249b7b2014-02-09 21:43:14 +000077#define MagickPI 3.14159265358979323846264338327950288419716939937510
cristy4a3ce0a2013-08-03 20:06:59 +000078#define MaxArguments 33
79#ifndef na
80#define na PL_na
81#endif
82#define NumberOf(array) (sizeof(array)/sizeof(*array))
83#define PackageName "Image::Magick"
84#if PERL_VERSION <= 6
85#define PerlIO FILE
86#define PerlIO_importFILE(f, fl) (f)
87#define PerlIO_findFILE(f) NULL
88#endif
89#ifndef sv_undef
90#define sv_undef PL_sv_undef
91#endif
92
93#define AddImageToRegistry(sv,image) \
94{ \
95 if (magick_registry != (SplayTreeInfo *) NULL) \
96 { \
97 (void) AddValueToSplayTree(magick_registry,image,image); \
98 (sv)=newSViv(PTR2IV(image)); \
99 } \
100}
101
102#define DeleteImageFromRegistry(reference,image) \
103{ \
104 if (magick_registry != (SplayTreeInfo *) NULL) \
105 { \
106 if (GetImageReferenceCount(image) == 1) \
107 (void) DeleteNodeByValueFromSplayTree(magick_registry,image); \
108 image=DestroyImage(image); \
109 sv_setiv(reference,0); \
110 } \
111}
112
113#define InheritPerlException(exception,perl_exception) \
114{ \
115 char \
cristy151b66d2015-04-15 10:50:31 +0000116 message[MagickPathExtent]; \
cristy4a3ce0a2013-08-03 20:06:59 +0000117 \
118 if ((exception)->severity != UndefinedException) \
119 { \
cristy151b66d2015-04-15 10:50:31 +0000120 (void) FormatLocaleString(message,MagickPathExtent,"Exception %d: %s%s%s%s",\
cristy4a3ce0a2013-08-03 20:06:59 +0000121 (exception)->severity, (exception)->reason ? \
122 GetLocaleExceptionMessage((exception)->severity,(exception)->reason) : \
123 "Unknown", (exception)->description ? " (" : "", \
124 (exception)->description ? GetLocaleExceptionMessage( \
125 (exception)->severity,(exception)->description) : "", \
126 (exception)->description ? ")" : ""); \
127 if ((perl_exception) != (SV *) NULL) \
128 { \
129 if (SvCUR(perl_exception)) \
130 sv_catpv(perl_exception,"\n"); \
131 sv_catpv(perl_exception,message); \
132 } \
133 } \
134}
135
136#define ThrowPerlException(exception,severity,tag,reason) \
137 (void) ThrowMagickException(exception,GetMagickModule(),severity, \
138 tag,"`%s'",reason); \
139
140/*
141 Typedef and structure declarations.
142*/
143typedef enum
144{
145 ArrayReference = (~0),
146 RealReference = (~0)-1,
147 FileReference = (~0)-2,
148 ImageReference = (~0)-3,
149 IntegerReference = (~0)-4,
150 StringReference = (~0)-5
151} MagickReference;
152
153typedef struct _Arguments
154{
155 const char
156 *method;
157
158 ssize_t
159 type;
160} Arguments;
161
162struct ArgumentList
163{
164 ssize_t
165 integer_reference;
166
167 double
168 real_reference;
169
170 const char
171 *string_reference;
172
173 Image
174 *image_reference;
175
176 SV
177 *array_reference;
178
179 FILE
180 *file_reference;
181
182 size_t
183 length;
184};
185
186struct PackageInfo
187{
188 ImageInfo
189 *image_info;
190};
191
192typedef void
193 *Image__Magick; /* data type for the Image::Magick package */
194
195/*
196 Static declarations.
197*/
198static struct
199 Methods
200 {
201 const char
202 *name;
203
204 Arguments
205 arguments[MaxArguments];
206 } Methods[] =
207 {
208 { "Comment", { {"comment", StringReference} } },
209 { "Label", { {"label", StringReference} } },
210 { "AddNoise", { {"noise", MagickNoiseOptions}, {"attenuate", RealReference},
211 {"channel", MagickChannelOptions} } },
212 { "Colorize", { {"fill", StringReference}, {"blend", StringReference} } },
213 { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
214 {"height", IntegerReference}, {"fill", StringReference},
215 {"bordercolor", StringReference}, {"color", StringReference},
216 {"compose", MagickComposeOptions} } },
217 { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
218 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
219 { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
220 {"height", IntegerReference}, {"x", IntegerReference},
cristy260bd762014-08-15 12:46:34 +0000221 {"y", IntegerReference}, {"gravity", MagickGravityOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000222 { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
223 {"height", IntegerReference}, {"x", IntegerReference},
224 {"y", IntegerReference}, {"fuzz", StringReference},
225 {"gravity", MagickGravityOptions} } },
226 { "Despeckle", },
227 { "Edge", { {"radius", RealReference} } },
228 { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
229 {"sigma", RealReference} } },
230 { "Enhance", },
231 { "Flip", },
232 { "Flop", },
233 { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
234 {"height", IntegerReference}, {"inner", IntegerReference},
235 {"outer", IntegerReference}, {"fill", StringReference},
236 {"color", StringReference}, {"compose", MagickComposeOptions} } },
237 { "Implode", { {"amount", RealReference},
238 {"interpolate", MagickInterpolateOptions} } },
239 { "Magnify", },
240 { "MedianFilter", { {"geometry", StringReference},
241 {"width", IntegerReference}, {"height", IntegerReference},
242 {"channel", MagickChannelOptions} } },
243 { "Minify", },
244 { "OilPaint", { {"radius", RealReference}, {"sigma", RealReference} } },
245 { "ReduceNoise", { {"geometry", StringReference},
246 {"width", IntegerReference},{"height", IntegerReference},
247 {"channel", MagickChannelOptions} } },
248 { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
249 {"y", IntegerReference} } },
cristy83a28a02013-08-03 20:25:48 +0000250 { "Rotate", { {"degrees", RealReference},
cristy4a3ce0a2013-08-03 20:06:59 +0000251 {"background", StringReference} } },
252 { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
253 {"height", IntegerReference} } },
254 { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
255 {"height", IntegerReference} } },
256 { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
257 {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
258 { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
259 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
260 { "Shear", { {"geometry", StringReference}, {"x", RealReference},
261 {"y", RealReference}, { "fill", StringReference},
262 {"color", StringReference} } },
Cristye3319c12015-08-24 07:11:48 -0400263 { "Spread", { {"radius", RealReference},
Cristy3ca633e2016-02-13 12:49:01 -0500264 {"interpolate", MagickInterpolateOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000265 { "Swirl", { {"degrees", RealReference},
266 {"interpolate", MagickInterpolateOptions} } },
267 { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
268 {"height", IntegerReference}, {"filter", MagickFilterOptions},
269 {"support", StringReference } } },
270 { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
271 {"height", IntegerReference}, {"filter", MagickFilterOptions},
272 {"support", RealReference } } },
273 { "Annotate", { {"text", StringReference}, {"font", StringReference},
274 {"pointsize", RealReference}, {"density", StringReference},
275 {"undercolor", StringReference}, {"stroke", StringReference},
276 {"fill", StringReference}, {"geometry", StringReference},
277 {"sans", StringReference}, {"x", RealReference},
278 {"y", RealReference}, {"gravity", MagickGravityOptions},
279 {"translate", StringReference}, {"scale", StringReference},
280 {"rotate", RealReference}, {"skewX", RealReference},
281 {"skewY", RealReference}, {"strokewidth", RealReference},
282 {"antialias", MagickBooleanOptions}, {"family", StringReference},
283 {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
284 {"weight", IntegerReference}, {"align", MagickAlignOptions},
285 {"encoding", StringReference}, {"affine", ArrayReference},
286 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
287 {"tile", ImageReference}, {"kerning", RealReference},
288 {"interline-spacing", RealReference},
289 {"interword-spacing", RealReference},
290 {"direction", MagickDirectionOptions} } },
291 { "ColorFloodfill", { {"geometry", StringReference},
292 {"x", IntegerReference}, {"y", IntegerReference},
293 {"fill", StringReference}, {"bordercolor", StringReference},
294 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
295 { "Composite", { {"image", ImageReference},
296 {"compose", MagickComposeOptions}, {"geometry", StringReference},
297 {"x", IntegerReference}, {"y", IntegerReference},
298 {"gravity", MagickGravityOptions}, {"opacity", StringReference},
299 {"tile", MagickBooleanOptions}, {"rotate", RealReference},
300 {"color", StringReference}, {"mask", ImageReference},
301 {"channel", MagickChannelOptions},
302 {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
303 {"blend", StringReference}, {"crop-to-self", MagickBooleanOptions} } },
304 { "Contrast", { {"sharpen", MagickBooleanOptions} } },
305 { "CycleColormap", { {"display", IntegerReference} } },
306 { "Draw", { {"primitive", MagickPrimitiveOptions},
307 {"points", StringReference}, {"method", MagickMethodOptions},
308 {"stroke", StringReference}, {"fill", StringReference},
309 {"strokewidth", RealReference}, {"font", StringReference},
310 {"bordercolor", StringReference}, {"x", RealReference},
311 {"y", RealReference}, {"translate", StringReference},
312 {"scale", StringReference}, {"rotate", RealReference},
313 {"skewX", RealReference}, {"skewY", RealReference},
314 {"tile", ImageReference}, {"pointsize", RealReference},
315 {"antialias", MagickBooleanOptions}, {"density", StringReference},
316 {"linewidth", RealReference}, {"affine", ArrayReference},
317 {"stroke-dashoffset", RealReference},
318 {"stroke-dasharray", ArrayReference},
319 {"interpolate", MagickInterpolateOptions},
320 {"origin", StringReference}, {"text", StringReference},
321 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
322 {"vector-graphics", StringReference}, {"kerning", RealReference},
323 {"interline-spacing", RealReference},
324 {"interword-spacing", RealReference},
325 {"direction", MagickDirectionOptions} } },
326 { "Equalize", { {"channel", MagickChannelOptions} } },
327 { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
328 {"red", RealReference}, {"green", RealReference},
329 {"blue", RealReference} } },
330 { "Map", { {"image", ImageReference},
331 {"dither-method", MagickDitherOptions} } },
332 { "MatteFloodfill", { {"geometry", StringReference},
333 {"x", IntegerReference}, {"y", IntegerReference},
334 {"opacity", StringReference}, {"bordercolor", StringReference},
335 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
336 { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
337 {"saturation", RealReference}, {"whiteness", RealReference},
338 {"brightness", RealReference}, {"lightness", RealReference},
339 {"blackness", RealReference} } },
340 { "Negate", { {"gray", MagickBooleanOptions},
341 {"channel", MagickChannelOptions} } },
342 { "Normalize", { {"channel", MagickChannelOptions} } },
343 { "NumberColors", },
344 { "Opaque", { {"color", StringReference}, {"fill", StringReference},
345 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
346 {"invert", MagickBooleanOptions} } },
347 { "Quantize", { {"colors", IntegerReference},
348 {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
349 {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
350 {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
351 {"dither-method", MagickDitherOptions} } },
352 { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
353 {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
354 { "Segment", { {"geometry", StringReference},
355 {"cluster-threshold", RealReference},
356 {"smoothing-threshold", RealReference},
357 {"colorspace", MagickColorspaceOptions},
358 {"verbose", MagickBooleanOptions} } },
359 { "Signature", },
360 { "Solarize", { {"geometry", StringReference},
361 {"threshold", StringReference} } },
362 { "Sync", },
363 { "Texture", { {"texture", ImageReference} } },
364 { "Evaluate", { {"value", RealReference},
365 {"operator", MagickEvaluateOptions},
366 {"channel", MagickChannelOptions} } },
367 { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
368 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
369 { "Threshold", { {"threshold", StringReference},
370 {"channel", MagickChannelOptions} } },
371 { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
372 {"sigma", RealReference} } },
373 { "Trim", { {"fuzz", StringReference} } },
374 { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
375 {"wavelength", RealReference},
376 {"interpolate", MagickInterpolateOptions} } },
377 { "Separate", { {"channel", MagickChannelOptions} } },
378 { "Condense", },
379 { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
380 {"y", IntegerReference} } },
381 { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
382 { "Deconstruct", },
383 { "GaussianBlur", { {"geometry", StringReference},
384 {"radius", RealReference}, {"sigma", RealReference},
385 {"channel", MagickChannelOptions} } },
386 { "Convolve", { {"coefficients", ArrayReference},
387 {"channel", MagickChannelOptions}, {"bias", StringReference},
388 {"kernel", StringReference} } },
389 { "Profile", { {"name", StringReference}, {"profile", StringReference},
390 { "rendering-intent", MagickIntentOptions},
391 { "black-point-compensation", MagickBooleanOptions} } },
392 { "UnsharpMask", { {"geometry", StringReference},
393 {"radius", RealReference}, {"sigma", RealReference},
394 {"gain", RealReference}, {"threshold", RealReference},
395 {"channel", MagickChannelOptions} } },
396 { "MotionBlur", { {"geometry", StringReference},
397 {"radius", RealReference}, {"sigma", RealReference},
398 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
399 { "OrderedDither", { {"threshold", StringReference},
400 {"channel", MagickChannelOptions} } },
401 { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
402 {"height", IntegerReference} } },
403 { "Level", { {"levels", StringReference}, {"black-point", RealReference},
404 {"white-point", RealReference}, {"gamma", RealReference},
405 {"channel", MagickChannelOptions}, {"level", StringReference} } },
406 { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
407 { "AffineTransform", { {"affine", ArrayReference},
408 {"translate", StringReference}, {"scale", StringReference},
409 {"rotate", RealReference}, {"skewX", RealReference},
410 {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
411 {"background", StringReference} } },
412 { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
413 { "AdaptiveThreshold", { {"geometry", StringReference},
414 {"width", IntegerReference}, {"height", IntegerReference} } },
415 { "Resample", { {"density", StringReference}, {"x", RealReference},
416 {"y", RealReference}, {"filter", MagickFilterOptions},
417 {"support", RealReference } } },
418 { "Describe", { {"file", FileReference} } },
419 { "BlackThreshold", { {"threshold", StringReference},
420 {"channel", MagickChannelOptions} } },
421 { "WhiteThreshold", { {"threshold", StringReference},
422 {"channel", MagickChannelOptions} } },
cristy60c73c02014-03-25 12:09:58 +0000423 { "RotationalBlur", { {"geometry", StringReference},
424 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000425 { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
426 {"height", IntegerReference} } },
427 { "Strip", },
428 { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
429 { "Channel", { {"channel", MagickChannelOptions} } },
430 { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
431 {"height", IntegerReference}, {"x", IntegerReference},
432 {"y", IntegerReference}, {"fuzz", StringReference},
433 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
434 { "Posterize", { {"levels", IntegerReference},
435 {"dither", MagickBooleanOptions} } },
436 { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
437 {"sigma", RealReference}, {"x", IntegerReference},
438 {"y", IntegerReference} } },
439 { "Identify", { {"file", FileReference}, {"features", StringReference},
440 {"unique", MagickBooleanOptions} } },
441 { "SepiaTone", { {"threshold", RealReference} } },
442 { "SigmoidalContrast", { {"geometry", StringReference},
443 {"contrast", RealReference}, {"mid-point", RealReference},
444 {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
445 { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
446 {"height", IntegerReference}, {"x", IntegerReference},
447 {"y", IntegerReference}, {"fuzz", StringReference},
448 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
449 { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
450 {"sigma", RealReference}, {"x", IntegerReference},
451 {"y", IntegerReference}, {"background", StringReference} } },
452 { "ContrastStretch", { {"levels", StringReference},
453 {"black-point", RealReference},{"white-point", RealReference},
454 {"channel", MagickChannelOptions} } },
455 { "Sans0", },
456 { "Sans1", },
457 { "AdaptiveSharpen", { {"geometry", StringReference},
458 {"radius", RealReference}, {"sigma", RealReference},
459 {"bias", RealReference}, {"channel", MagickChannelOptions} } },
460 { "Transpose", },
461 { "Transverse", },
462 { "AutoOrient", },
463 { "AdaptiveBlur", { {"geometry", StringReference},
464 {"radius", RealReference}, {"sigma", RealReference},
465 {"channel", MagickChannelOptions} } },
466 { "Sketch", { {"geometry", StringReference},
467 {"radius", RealReference}, {"sigma", RealReference},
468 {"angle", RealReference} } },
469 { "UniqueColors", },
470 { "AdaptiveResize", { {"geometry", StringReference},
471 {"width", IntegerReference}, {"height", IntegerReference},
472 {"filter", MagickFilterOptions}, {"support", StringReference },
473 {"blur", RealReference } } },
474 { "ClipMask", { {"mask", ImageReference} } },
475 { "LinearStretch", { {"levels", StringReference},
476 {"black-point", RealReference},{"white-point", RealReference} } },
477 { "ColorMatrix", { {"matrix", ArrayReference} } },
478 { "Mask", { {"mask", ImageReference} } },
479 { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
480 {"font", StringReference}, {"stroke", StringReference},
481 {"fill", StringReference}, {"strokewidth", RealReference},
482 {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
483 {"background", StringReference},
484 {"interpolate", MagickInterpolateOptions} } },
485 { "FloodfillPaint", { {"geometry", StringReference},
486 {"x", IntegerReference}, {"y", IntegerReference},
487 {"fill", StringReference}, {"bordercolor", StringReference},
488 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
489 {"invert", MagickBooleanOptions} } },
490 { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
491 {"virtual-pixel", MagickVirtualPixelOptions},
492 {"best-fit", MagickBooleanOptions} } },
493 { "Clut", { {"image", ImageReference},
494 {"interpolate", MagickInterpolateOptions},
495 {"channel", MagickChannelOptions} } },
496 { "LiquidRescale", { {"geometry", StringReference},
497 {"width", IntegerReference}, {"height", IntegerReference},
498 {"delta-x", RealReference}, {"rigidity", RealReference } } },
499 { "Encipher", { {"passphrase", StringReference} } },
500 { "Decipher", { {"passphrase", StringReference} } },
501 { "Deskew", { {"geometry", StringReference},
502 {"threshold", StringReference} } },
503 { "Remap", { {"image", ImageReference},
504 {"dither-method", MagickDitherOptions} } },
505 { "SparseColor", { {"points", ArrayReference},
506 {"method", MagickSparseColorOptions},
507 {"virtual-pixel", MagickVirtualPixelOptions},
508 {"channel", MagickChannelOptions} } },
509 { "Function", { {"parameters", ArrayReference},
510 {"function", MagickFunctionOptions},
511 {"virtual-pixel", MagickVirtualPixelOptions} } },
512 { "SelectiveBlur", { {"geometry", StringReference},
513 {"radius", RealReference}, {"sigma", RealReference},
514 {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
515 { "HaldClut", { {"image", ImageReference},
516 {"channel", MagickChannelOptions} } },
517 { "BlueShift", { {"factor", StringReference} } },
518 { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
519 { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
520 { "ColorDecisionList", {
521 {"color-correction-collection", StringReference} } },
522 { "AutoGamma", { {"channel", MagickChannelOptions} } },
523 { "AutoLevel", { {"channel", MagickChannelOptions} } },
524 { "LevelColors", { {"invert", MagickBooleanOptions},
525 {"black-point", StringReference}, {"white-point", StringReference},
526 {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
527 { "Clamp", { {"channel", MagickChannelOptions} } },
528 { "BrightnessContrast", { {"levels", StringReference},
529 {"brightness", RealReference},{"contrast", RealReference},
530 {"channel", MagickChannelOptions} } },
531 { "Morphology", { {"kernel", StringReference},
532 {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
533 {"iterations", IntegerReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000534 { "Mode", { {"geometry", StringReference},
535 {"width", IntegerReference},{"height", IntegerReference},
536 {"channel", MagickChannelOptions} } },
537 { "Statistic", { {"geometry", StringReference},
538 {"width", IntegerReference},{"height", IntegerReference},
539 {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
540 { "Perceptible", { {"epsilon", RealReference},
541 {"channel", MagickChannelOptions} } },
542 { "Poly", { {"terms", ArrayReference},
543 {"channel", MagickChannelOptions} } },
544 { "Grayscale", { {"method", MagickNoiseOptions} } },
cristy4ceadb82014-03-29 15:30:43 +0000545 { "CannyEdge", { {"geometry", StringReference},
546 {"radius", RealReference}, {"sigma", RealReference},
cristycfe7bf02014-04-04 15:31:52 +0000547 {"lower-percent", RealReference}, {"upper-percent", RealReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000548 { "HoughLine", { {"geometry", StringReference},
cristy4e215022014-04-19 18:02:35 +0000549 {"width", IntegerReference}, {"height", IntegerReference},
550 {"threshold", IntegerReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000551 { "MeanShift", { {"geometry", StringReference},
552 {"width", IntegerReference}, {"height", IntegerReference},
cristy1309fc32014-04-26 18:48:37 +0000553 {"distance", RealReference} } },
cristy3b207f82014-09-27 14:21:20 +0000554 { "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
555 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
Cristy2ca0e9a2016-01-01 08:36:14 -0500556 { "ConnectedComponents", { {"connectivity", IntegerReference} } },
cristyf3a724a2015-06-25 13:02:53 +0000557 { "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
558 {"width", IntegerReference}, {"height", IntegerReference},
559 {"x", IntegerReference}, {"y", IntegerReference},
560 {"gravity", MagickGravityOptions}, {"offset", StringReference},
561 {"dx", IntegerReference}, {"dy", IntegerReference} } },
Cristy5488c982016-02-13 14:07:50 -0500562 { "Color", { {"color", StringReference} } },
Cristyc1759412016-02-27 12:17:58 -0500563 { "WaveletDenoise", { {"geometry", StringReference},
564 {"threshold", RealReference}, {"softness", RealReference},
Cristy2d830ed2016-02-21 10:54:16 -0500565 {"channel", MagickChannelOptions} } },
Cristy99a57162016-12-05 11:47:57 -0500566 { "Colorspace", { {"colorspace", MagickColorspaceOptions} } },
Cristy53353872017-07-02 12:24:24 -0400567 { "AutoThreshold", { {"method", MagickAutoThresholdOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000568 };
569
570static SplayTreeInfo
571 *magick_registry = (SplayTreeInfo *) NULL;
572
573/*
574 Forward declarations.
575*/
576static Image
577 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
578
579static ssize_t
580 strEQcase(const char *,const char *);
581
582/*
583%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
584% %
585% %
586% %
587% C l o n e P a c k a g e I n f o %
588% %
589% %
590% %
591%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
592%
593% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
594% a new one.
595%
596% The format of the ClonePackageInfo routine is:
597%
598% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
599% exception)
600%
601% A description of each parameter follows:
602%
603% o info: a structure of type info.
604%
605% o exception: Return any errors or warnings in this structure.
606%
607*/
608static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
609 ExceptionInfo *exception)
610{
611 struct PackageInfo
612 *clone_info;
613
614 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
615 if (clone_info == (struct PackageInfo *) NULL)
616 {
617 ThrowPerlException(exception,ResourceLimitError,
618 "UnableToClonePackageInfo",PackageName);
619 return((struct PackageInfo *) NULL);
620 }
621 if (info == (struct PackageInfo *) NULL)
622 {
623 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
624 return(clone_info);
625 }
626 *clone_info=(*info);
627 clone_info->image_info=CloneImageInfo(info->image_info);
628 return(clone_info);
629}
630
631/*
632%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
633% %
634% %
635% %
636% c o n s t a n t %
637% %
638% %
639% %
640%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
641%
642% constant() returns a double value for the specified name.
643%
644% The format of the constant routine is:
645%
646% double constant(char *name,ssize_t sans)
647%
648% A description of each parameter follows:
649%
650% o value: Method constant returns a double value for the specified name.
651%
652% o name: The name of the constant.
653%
654% o sans: This integer value is not used.
655%
656*/
657static double constant(char *name,ssize_t sans)
658{
659 (void) sans;
660 errno=0;
661 switch (*name)
662 {
663 case 'B':
664 {
665 if (strEQ(name,"BlobError"))
666 return(BlobError);
667 if (strEQ(name,"BlobWarning"))
668 return(BlobWarning);
669 break;
670 }
671 case 'C':
672 {
673 if (strEQ(name,"CacheError"))
674 return(CacheError);
675 if (strEQ(name,"CacheWarning"))
676 return(CacheWarning);
677 if (strEQ(name,"CoderError"))
678 return(CoderError);
679 if (strEQ(name,"CoderWarning"))
680 return(CoderWarning);
681 if (strEQ(name,"ConfigureError"))
682 return(ConfigureError);
683 if (strEQ(name,"ConfigureWarning"))
684 return(ConfigureWarning);
685 if (strEQ(name,"CorruptImageError"))
686 return(CorruptImageError);
687 if (strEQ(name,"CorruptImageWarning"))
688 return(CorruptImageWarning);
689 break;
690 }
691 case 'D':
692 {
693 if (strEQ(name,"DelegateError"))
694 return(DelegateError);
695 if (strEQ(name,"DelegateWarning"))
696 return(DelegateWarning);
697 if (strEQ(name,"DrawError"))
698 return(DrawError);
699 if (strEQ(name,"DrawWarning"))
700 return(DrawWarning);
701 break;
702 }
703 case 'E':
704 {
705 if (strEQ(name,"ErrorException"))
706 return(ErrorException);
707 if (strEQ(name,"ExceptionError"))
708 return(CoderError);
709 if (strEQ(name,"ExceptionWarning"))
710 return(CoderWarning);
711 break;
712 }
713 case 'F':
714 {
715 if (strEQ(name,"FatalErrorException"))
716 return(FatalErrorException);
717 if (strEQ(name,"FileOpenError"))
718 return(FileOpenError);
719 if (strEQ(name,"FileOpenWarning"))
720 return(FileOpenWarning);
721 break;
722 }
723 case 'I':
724 {
725 if (strEQ(name,"ImageError"))
726 return(ImageError);
727 if (strEQ(name,"ImageWarning"))
728 return(ImageWarning);
729 break;
730 }
731 case 'M':
732 {
733 if (strEQ(name,"MaxRGB"))
734 return(QuantumRange);
735 if (strEQ(name,"MissingDelegateError"))
736 return(MissingDelegateError);
737 if (strEQ(name,"MissingDelegateWarning"))
738 return(MissingDelegateWarning);
739 if (strEQ(name,"ModuleError"))
740 return(ModuleError);
741 if (strEQ(name,"ModuleWarning"))
742 return(ModuleWarning);
743 break;
744 }
745 case 'O':
746 {
747 if (strEQ(name,"Opaque"))
748 return(OpaqueAlpha);
749 if (strEQ(name,"OptionError"))
750 return(OptionError);
751 if (strEQ(name,"OptionWarning"))
752 return(OptionWarning);
753 break;
754 }
755 case 'Q':
756 {
757 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
758 return(MAGICKCORE_QUANTUM_DEPTH);
759 if (strEQ(name,"QuantumDepth"))
760 return(MAGICKCORE_QUANTUM_DEPTH);
761 if (strEQ(name,"QuantumRange"))
762 return(QuantumRange);
763 break;
764 }
765 case 'R':
766 {
767 if (strEQ(name,"ResourceLimitError"))
768 return(ResourceLimitError);
769 if (strEQ(name,"ResourceLimitWarning"))
770 return(ResourceLimitWarning);
771 if (strEQ(name,"RegistryError"))
772 return(RegistryError);
773 if (strEQ(name,"RegistryWarning"))
774 return(RegistryWarning);
775 break;
776 }
777 case 'S':
778 {
779 if (strEQ(name,"StreamError"))
780 return(StreamError);
781 if (strEQ(name,"StreamWarning"))
782 return(StreamWarning);
783 if (strEQ(name,"Success"))
784 return(0);
785 break;
786 }
787 case 'T':
788 {
789 if (strEQ(name,"Transparent"))
790 return(TransparentAlpha);
791 if (strEQ(name,"TypeError"))
792 return(TypeError);
793 if (strEQ(name,"TypeWarning"))
794 return(TypeWarning);
795 break;
796 }
797 case 'W':
798 {
799 if (strEQ(name,"WarningException"))
800 return(WarningException);
801 break;
802 }
803 case 'X':
804 {
805 if (strEQ(name,"XServerError"))
806 return(XServerError);
807 if (strEQ(name,"XServerWarning"))
808 return(XServerWarning);
809 break;
810 }
811 }
812 errno=EINVAL;
813 return(0);
814}
815
816/*
817%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
818% %
819% %
820% %
821% D e s t r o y P a c k a g e I n f o %
822% %
823% %
824% %
825%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
826%
827% Method DestroyPackageInfo frees a previously created info structure.
828%
829% The format of the DestroyPackageInfo routine is:
830%
831% DestroyPackageInfo(struct PackageInfo *info)
832%
833% A description of each parameter follows:
834%
835% o info: a structure of type info.
836%
837*/
838static void DestroyPackageInfo(struct PackageInfo *info)
839{
840 info->image_info=DestroyImageInfo(info->image_info);
841 info=(struct PackageInfo *) RelinquishMagickMemory(info);
842}
843
844/*
845%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
846% %
847% %
848% %
849% G e t L i s t %
850% %
851% %
852% %
853%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
854%
855% Method GetList is recursively called by SetupList to traverse the
856% Image__Magick reference. If building an reference_vector (see SetupList),
857% *current is the current position in *reference_vector and *last is the final
858% entry in *reference_vector.
859%
860% The format of the GetList routine is:
861%
862% GetList(info)
863%
864% A description of each parameter follows:
865%
866% o info: a structure of type info.
867%
868*/
869static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
870 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
871{
872 Image
873 *image;
874
875 if (reference == (SV *) NULL)
876 return(NULL);
877 switch (SvTYPE(reference))
878 {
879 case SVt_PVAV:
880 {
881 AV
882 *av;
883
884 Image
885 *head,
886 *previous;
887
888 register ssize_t
889 i;
890
891 ssize_t
892 n;
893
894 /*
895 Array of images.
896 */
897 previous=(Image *) NULL;
898 head=(Image *) NULL;
899 av=(AV *) reference;
900 n=av_len(av);
901 for (i=0; i <= n; i++)
902 {
903 SV
904 **rv;
905
906 rv=av_fetch(av,i,0);
907 if (rv && *rv && sv_isobject(*rv))
908 {
909 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
910 exception);
911 if (image == (Image *) NULL)
912 continue;
913 if (image == previous)
914 {
915 image=CloneImage(image,0,0,MagickTrue,exception);
916 if (image == (Image *) NULL)
917 return(NULL);
918 }
919 image->previous=previous;
920 *(previous ? &previous->next : &head)=image;
921 for (previous=image; previous->next; previous=previous->next) ;
922 }
923 }
924 return(head);
925 }
926 case SVt_PVMG:
927 {
928 /*
929 Blessed scalar, one image.
930 */
931 image=INT2PTR(Image *,SvIV(reference));
932 if (image == (Image *) NULL)
933 return(NULL);
934 image->previous=(Image *) NULL;
935 image->next=(Image *) NULL;
936 if (reference_vector)
937 {
938 if (*current == *last)
939 {
940 *last+=256;
941 if (*reference_vector == (SV **) NULL)
942 *reference_vector=(SV **) AcquireQuantumMemory(*last,
943 sizeof(*reference_vector));
944 else
945 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
946 *last,sizeof(*reference_vector));
947 }
948 if (*reference_vector == (SV **) NULL)
949 {
950 ThrowPerlException(exception,ResourceLimitError,
951 "MemoryAllocationFailed",PackageName);
952 return((Image *) NULL);
953 }
954 (*reference_vector)[*current]=reference;
955 (*reference_vector)[++(*current)]=NULL;
956 }
957 return(image);
958 }
959 default:
960 break;
961 }
962 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
963 (double) SvTYPE(reference));
964 return((Image *) NULL);
965}
966
967/*
968%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
969% %
970% %
971% %
972% G e t P a c k a g e I n f o %
973% %
974% %
975% %
976%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
977%
978% Method GetPackageInfo looks up or creates an info structure for the given
979% Image__Magick reference. If it does create a new one, the information in
980% package_info is used to initialize it.
981%
982% The format of the GetPackageInfo routine is:
983%
984% struct PackageInfo *GetPackageInfo(void *reference,
985% struct PackageInfo *package_info,ExceptionInfo *exception)
986%
987% A description of each parameter follows:
988%
989% o info: a structure of type info.
990%
991% o exception: Return any errors or warnings in this structure.
992%
993*/
994static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
995 struct PackageInfo *package_info,ExceptionInfo *exception)
996{
997 char
cristy151b66d2015-04-15 10:50:31 +0000998 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +0000999
1000 struct PackageInfo
1001 *clone_info;
1002
1003 SV
1004 *sv;
1005
cristy151b66d2015-04-15 10:50:31 +00001006 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00001007 PackageName,XS_VERSION,reference);
1008 sv=perl_get_sv(message,(TRUE | 0x02));
1009 if (sv == (SV *) NULL)
1010 {
1011 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1012 message);
1013 return(package_info);
1014 }
1015 if (SvREFCNT(sv) == 0)
1016 (void) SvREFCNT_inc(sv);
1017 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1018 return(clone_info);
1019 clone_info=ClonePackageInfo(package_info,exception);
1020 sv_setiv(sv,PTR2IV(clone_info));
1021 return(clone_info);
1022}
1023
1024/*
1025%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1026% %
1027% %
1028% %
1029% S e t A t t r i b u t e %
1030% %
1031% %
1032% %
1033%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1034%
1035% SetAttribute() sets the attribute to the value in sval. This can change
1036% either or both of image or info.
1037%
1038% The format of the SetAttribute routine is:
1039%
1040% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1041% SV *sval,ExceptionInfo *exception)
1042%
1043% A description of each parameter follows:
1044%
1045% o list: a list of strings.
1046%
1047% o string: a character string.
1048%
1049*/
1050
1051static double SiPrefixToDoubleInterval(const char *string,const double interval)
1052{
1053 char
1054 *q;
1055
1056 double
1057 value;
1058
1059 value=InterpretSiPrefixValue(string,&q);
1060 if (*q == '%')
1061 value*=interval/100.0;
1062 return(value);
1063}
1064
1065static inline double StringToDouble(const char *string,char **sentinal)
1066{
1067 return(InterpretLocaleValue(string,sentinal));
1068}
1069
1070static double StringToDoubleInterval(const char *string,const double interval)
1071{
1072 char
1073 *q;
1074
1075 double
1076 value;
1077
1078 value=InterpretLocaleValue(string,&q);
1079 if (*q == '%')
1080 value*=interval/100.0;
1081 return(value);
1082}
1083
1084static inline ssize_t StringToLong(const char *value)
1085{
1086 return(strtol(value,(char **) NULL,10));
1087}
1088
1089static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1090 const char *attribute,SV *sval,ExceptionInfo *exception)
1091{
1092 GeometryInfo
1093 geometry_info;
1094
1095 long
1096 x,
1097 y;
1098
1099 PixelInfo
1100 pixel;
1101
1102 MagickStatusType
1103 flags;
1104
1105 PixelInfo
1106 *color,
1107 target_color;
1108
1109 ssize_t
1110 sp;
1111
1112 switch (*attribute)
1113 {
1114 case 'A':
1115 case 'a':
1116 {
1117 if (LocaleCompare(attribute,"adjoin") == 0)
1118 {
1119 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1120 SvPV(sval,na)) : SvIV(sval);
1121 if (sp < 0)
1122 {
1123 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1124 SvPV(sval,na));
1125 break;
1126 }
1127 if (info)
1128 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1129 break;
1130 }
1131 if (LocaleCompare(attribute,"alpha") == 0)
1132 {
1133 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1134 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1135 if (sp < 0)
1136 {
1137 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1138 SvPV(sval,na));
1139 break;
1140 }
1141 for ( ; image; image=image->next)
1142 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1143 exception);
1144 break;
1145 }
1146 if (LocaleCompare(attribute,"antialias") == 0)
1147 {
1148 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1149 SvPV(sval,na)) : SvIV(sval);
1150 if (sp < 0)
1151 {
1152 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1153 SvPV(sval,na));
1154 break;
1155 }
1156 if (info)
1157 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1158 break;
1159 }
1160 if (LocaleCompare(attribute,"area-limit") == 0)
1161 {
1162 MagickSizeType
1163 limit;
1164
1165 limit=MagickResourceInfinity;
1166 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1167 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1168 100.0);
1169 (void) SetMagickResourceLimit(AreaResource,limit);
1170 break;
1171 }
1172 if (LocaleCompare(attribute,"attenuate") == 0)
1173 {
1174 if (info)
1175 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1176 break;
1177 }
1178 if (LocaleCompare(attribute,"authenticate") == 0)
1179 {
1180 if (info)
1181 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1182 break;
1183 }
1184 if (info)
1185 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1186 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001187 {
1188 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstra337c9bc2017-04-03 16:04:21 +02001189 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001190 }
cristy4a3ce0a2013-08-03 20:06:59 +00001191 break;
1192 }
1193 case 'B':
1194 case 'b':
1195 {
1196 if (LocaleCompare(attribute,"background") == 0)
1197 {
1198 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1199 exception);
1200 if (info)
1201 info->image_info->background_color=target_color;
1202 for ( ; image; image=image->next)
1203 image->background_color=target_color;
1204 break;
1205 }
1206 if (LocaleCompare(attribute,"blue-primary") == 0)
1207 {
1208 for ( ; image; image=image->next)
1209 {
1210 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1211 image->chromaticity.blue_primary.x=geometry_info.rho;
1212 image->chromaticity.blue_primary.y=geometry_info.sigma;
1213 if ((flags & SigmaValue) == 0)
1214 image->chromaticity.blue_primary.y=
1215 image->chromaticity.blue_primary.x;
1216 }
1217 break;
1218 }
1219 if (LocaleCompare(attribute,"bordercolor") == 0)
1220 {
1221 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1222 exception);
1223 if (info)
1224 info->image_info->border_color=target_color;
1225 for ( ; image; image=image->next)
1226 image->border_color=target_color;
1227 break;
1228 }
1229 if (info)
1230 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1231 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001232 {
1233 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001234 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001235 }
cristy4a3ce0a2013-08-03 20:06:59 +00001236 break;
1237 }
1238 case 'C':
1239 case 'c':
1240 {
1241 if (LocaleCompare(attribute,"cache-threshold") == 0)
1242 {
1243 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1244 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1245 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1246 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1247 break;
1248 }
1249 if (LocaleCompare(attribute,"clip-mask") == 0)
1250 {
1251 Image
1252 *clip_mask;
1253
1254 clip_mask=(Image *) NULL;
1255 if (SvPOK(sval))
1256 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1257 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001258 SetImageMask(image,ReadPixelMask,clip_mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001259 break;
1260 }
1261 if (LocaleNCompare(attribute,"colormap",8) == 0)
1262 {
1263 for ( ; image; image=image->next)
1264 {
1265 int
1266 items;
1267
1268 long
1269 i;
1270
1271 if (image->storage_class == DirectClass)
1272 continue;
1273 i=0;
1274 items=sscanf(attribute,"%*[^[][%ld",&i);
1275 (void) items;
1276 if (i > (ssize_t) image->colors)
1277 i%=image->colors;
1278 if ((strchr(SvPV(sval,na),',') == 0) ||
1279 (strchr(SvPV(sval,na),')') != 0))
1280 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1281 image->colormap+i,exception);
1282 else
1283 {
1284 color=image->colormap+i;
1285 pixel.red=color->red;
1286 pixel.green=color->green;
1287 pixel.blue=color->blue;
1288 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1289 pixel.red=geometry_info.rho;
1290 pixel.green=geometry_info.sigma;
1291 pixel.blue=geometry_info.xi;
1292 color->red=ClampToQuantum(pixel.red);
1293 color->green=ClampToQuantum(pixel.green);
1294 color->blue=ClampToQuantum(pixel.blue);
1295 }
1296 }
1297 break;
1298 }
1299 if (LocaleCompare(attribute,"colorspace") == 0)
1300 {
1301 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1302 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1303 if (sp < 0)
1304 {
1305 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1306 SvPV(sval,na));
1307 break;
1308 }
1309 for ( ; image; image=image->next)
Cristy59262d92016-12-05 15:21:50 -05001310 (void) SetImageColorspace(image,(ColorspaceType) sp,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001311 break;
1312 }
1313 if (LocaleCompare(attribute,"comment") == 0)
1314 {
1315 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001316 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001317 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001318 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001319 break;
1320 }
1321 if (LocaleCompare(attribute,"compression") == 0)
1322 {
1323 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1324 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1325 if (sp < 0)
1326 {
1327 ThrowPerlException(exception,OptionError,
1328 "UnrecognizedImageCompression",SvPV(sval,na));
1329 break;
1330 }
1331 if (info)
1332 info->image_info->compression=(CompressionType) sp;
1333 for ( ; image; image=image->next)
1334 image->compression=(CompressionType) sp;
1335 break;
1336 }
1337 if (info)
1338 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1339 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001340 {
1341 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001342 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001343 }
cristy4a3ce0a2013-08-03 20:06:59 +00001344 break;
1345 }
1346 case 'D':
1347 case 'd':
1348 {
1349 if (LocaleCompare(attribute,"debug") == 0)
1350 {
1351 SetLogEventMask(SvPV(sval,na));
1352 break;
1353 }
1354 if (LocaleCompare(attribute,"delay") == 0)
1355 {
1356 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1357 for ( ; image; image=image->next)
1358 {
1359 image->delay=(size_t) floor(geometry_info.rho+0.5);
1360 if ((flags & SigmaValue) != 0)
1361 image->ticks_per_second=(ssize_t)
1362 floor(geometry_info.sigma+0.5);
1363 }
1364 break;
1365 }
1366 if (LocaleCompare(attribute,"disk-limit") == 0)
1367 {
1368 MagickSizeType
1369 limit;
1370
1371 limit=MagickResourceInfinity;
1372 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1373 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1374 100.0);
1375 (void) SetMagickResourceLimit(DiskResource,limit);
1376 break;
1377 }
1378 if (LocaleCompare(attribute,"density") == 0)
1379 {
1380 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1381 {
1382 ThrowPerlException(exception,OptionError,"MissingGeometry",
1383 SvPV(sval,na));
1384 break;
1385 }
1386 if (info)
1387 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1388 for ( ; image; image=image->next)
1389 {
1390 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1391 image->resolution.x=geometry_info.rho;
1392 image->resolution.y=geometry_info.sigma;
1393 if ((flags & SigmaValue) == 0)
1394 image->resolution.y=image->resolution.x;
1395 }
1396 break;
1397 }
1398 if (LocaleCompare(attribute,"depth") == 0)
1399 {
1400 if (info)
1401 info->image_info->depth=SvIV(sval);
1402 for ( ; image; image=image->next)
1403 (void) SetImageDepth(image,SvIV(sval),exception);
1404 break;
1405 }
1406 if (LocaleCompare(attribute,"dispose") == 0)
1407 {
1408 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1409 SvPV(sval,na)) : SvIV(sval);
1410 if (sp < 0)
1411 {
1412 ThrowPerlException(exception,OptionError,
1413 "UnrecognizedDisposeMethod",SvPV(sval,na));
1414 break;
1415 }
1416 for ( ; image; image=image->next)
1417 image->dispose=(DisposeType) sp;
1418 break;
1419 }
1420 if (LocaleCompare(attribute,"dither") == 0)
1421 {
1422 if (info)
1423 {
1424 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1425 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1426 if (sp < 0)
1427 {
1428 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1429 SvPV(sval,na));
1430 break;
1431 }
1432 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1433 }
1434 break;
1435 }
1436 if (LocaleCompare(attribute,"display") == 0)
1437 {
1438 display:
1439 if (info)
1440 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1441 break;
1442 }
1443 if (info)
1444 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1445 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001446 {
1447 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001448 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001449 }
cristy4a3ce0a2013-08-03 20:06:59 +00001450 break;
1451 }
1452 case 'E':
1453 case 'e':
1454 {
1455 if (LocaleCompare(attribute,"endian") == 0)
1456 {
1457 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1458 SvPV(sval,na)) : SvIV(sval);
1459 if (sp < 0)
1460 {
1461 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1462 SvPV(sval,na));
1463 break;
1464 }
1465 if (info)
1466 info->image_info->endian=(EndianType) sp;
1467 for ( ; image; image=image->next)
1468 image->endian=(EndianType) sp;
1469 break;
1470 }
1471 if (LocaleCompare(attribute,"extract") == 0)
1472 {
1473 /*
1474 Set image extract geometry.
1475 */
1476 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1477 break;
1478 }
1479 if (info)
1480 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1481 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001482 {
1483 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001484 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001485 }
cristy4a3ce0a2013-08-03 20:06:59 +00001486 break;
1487 }
1488 case 'F':
1489 case 'f':
1490 {
1491 if (LocaleCompare(attribute,"filename") == 0)
1492 {
1493 if (info)
1494 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001495 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001496 for ( ; image; image=image->next)
1497 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001498 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001499 break;
1500 }
1501 if (LocaleCompare(attribute,"file") == 0)
1502 {
1503 FILE
1504 *file;
1505
1506 PerlIO
1507 *io_info;
1508
1509 if (info == (struct PackageInfo *) NULL)
1510 break;
1511 io_info=IoIFP(sv_2io(sval));
1512 if (io_info == (PerlIO *) NULL)
1513 {
1514 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1515 PackageName);
1516 break;
1517 }
1518 file=PerlIO_findFILE(io_info);
1519 if (file == (FILE *) NULL)
1520 {
1521 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1522 PackageName);
1523 break;
1524 }
1525 SetImageInfoFile(info->image_info,file);
1526 break;
1527 }
1528 if (LocaleCompare(attribute,"fill") == 0)
1529 {
1530 if (info)
1531 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1532 break;
1533 }
1534 if (LocaleCompare(attribute,"font") == 0)
1535 {
1536 if (info)
1537 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1538 break;
1539 }
1540 if (LocaleCompare(attribute,"foreground") == 0)
1541 break;
1542 if (LocaleCompare(attribute,"fuzz") == 0)
1543 {
1544 if (info)
1545 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1546 QuantumRange+1.0);
1547 for ( ; image; image=image->next)
1548 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1549 QuantumRange+1.0);
1550 break;
1551 }
1552 if (info)
1553 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1554 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001555 {
1556 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001557 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001558 }
cristy4a3ce0a2013-08-03 20:06:59 +00001559 break;
1560 }
1561 case 'G':
1562 case 'g':
1563 {
1564 if (LocaleCompare(attribute,"gamma") == 0)
1565 {
1566 for ( ; image; image=image->next)
1567 image->gamma=SvNV(sval);
1568 break;
1569 }
1570 if (LocaleCompare(attribute,"gravity") == 0)
1571 {
1572 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1573 SvPV(sval,na)) : SvIV(sval);
1574 if (sp < 0)
1575 {
1576 ThrowPerlException(exception,OptionError,
1577 "UnrecognizedGravityType",SvPV(sval,na));
1578 break;
1579 }
1580 if (info)
1581 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1582 for ( ; image; image=image->next)
1583 image->gravity=(GravityType) sp;
1584 break;
1585 }
1586 if (LocaleCompare(attribute,"green-primary") == 0)
1587 {
1588 for ( ; image; image=image->next)
1589 {
1590 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1591 image->chromaticity.green_primary.x=geometry_info.rho;
1592 image->chromaticity.green_primary.y=geometry_info.sigma;
1593 if ((flags & SigmaValue) == 0)
1594 image->chromaticity.green_primary.y=
1595 image->chromaticity.green_primary.x;
1596 }
1597 break;
1598 }
1599 if (info)
1600 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1601 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001602 {
1603 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001604 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001605 }
cristy4a3ce0a2013-08-03 20:06:59 +00001606 break;
1607 }
1608 case 'I':
1609 case 'i':
1610 {
1611 if (LocaleNCompare(attribute,"index",5) == 0)
1612 {
1613 int
1614 items;
1615
1616 long
1617 index;
1618
1619 register Quantum
1620 *q;
1621
1622 CacheView
1623 *image_view;
1624
1625 for ( ; image; image=image->next)
1626 {
1627 if (image->storage_class != PseudoClass)
1628 continue;
1629 x=0;
1630 y=0;
1631 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1632 (void) items;
1633 image_view=AcquireAuthenticCacheView(image,exception);
1634 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1635 if (q != (Quantum *) NULL)
1636 {
1637 items=sscanf(SvPV(sval,na),"%ld",&index);
1638 if ((index >= 0) && (index < (ssize_t) image->colors))
1639 SetPixelIndex(image,index,q);
1640 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1641 }
1642 image_view=DestroyCacheView(image_view);
1643 }
1644 break;
1645 }
1646 if (LocaleCompare(attribute,"iterations") == 0)
1647 {
1648 iterations:
1649 for ( ; image; image=image->next)
1650 image->iterations=SvIV(sval);
1651 break;
1652 }
1653 if (LocaleCompare(attribute,"interlace") == 0)
1654 {
1655 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1656 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1657 if (sp < 0)
1658 {
1659 ThrowPerlException(exception,OptionError,
1660 "UnrecognizedInterlaceType",SvPV(sval,na));
1661 break;
1662 }
1663 if (info)
1664 info->image_info->interlace=(InterlaceType) sp;
1665 for ( ; image; image=image->next)
1666 image->interlace=(InterlaceType) sp;
1667 break;
1668 }
1669 if (info)
1670 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1671 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001672 {
1673 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001674 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001675 }
cristy4a3ce0a2013-08-03 20:06:59 +00001676 break;
1677 }
1678 case 'L':
1679 case 'l':
1680 {
1681 if (LocaleCompare(attribute,"label") == 0)
1682 {
1683 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001684 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001685 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001686 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001687 break;
1688 }
1689 if (LocaleCompare(attribute,"loop") == 0)
1690 goto iterations;
1691 if (info)
1692 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1693 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001694 {
1695 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001696 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001697 }
cristy4a3ce0a2013-08-03 20:06:59 +00001698 break;
1699 }
1700 case 'M':
1701 case 'm':
1702 {
1703 if (LocaleCompare(attribute,"magick") == 0)
1704 {
1705 if (info)
Cristyb5b1f5d2017-03-31 16:42:35 -04001706 (void) FormatLocaleString(info->image_info->filename,
1707 MagickPathExtent,"%s:",SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001708 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001709 (void) CopyMagickString(image->magick,SvPV(sval,na),
1710 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001711 break;
1712 }
1713 if (LocaleCompare(attribute,"map-limit") == 0)
1714 {
1715 MagickSizeType
1716 limit;
1717
1718 limit=MagickResourceInfinity;
1719 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1720 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1721 100.0);
1722 (void) SetMagickResourceLimit(MapResource,limit);
1723 break;
1724 }
1725 if (LocaleCompare(attribute,"mask") == 0)
1726 {
1727 Image
1728 *mask;
1729
1730 mask=(Image *) NULL;
1731 if (SvPOK(sval))
1732 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1733 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001734 SetImageMask(image,ReadPixelMask,mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001735 break;
1736 }
1737 if (LocaleCompare(attribute,"mattecolor") == 0)
1738 {
1739 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1740 exception);
1741 if (info)
Cristy8645e042016-02-03 16:35:29 -05001742 info->image_info->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001743 for ( ; image; image=image->next)
Cristy8645e042016-02-03 16:35:29 -05001744 image->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001745 break;
1746 }
1747 if (LocaleCompare(attribute,"matte") == 0)
1748 {
1749 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1750 SvPV(sval,na)) : SvIV(sval);
1751 if (sp < 0)
1752 {
1753 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1754 SvPV(sval,na));
1755 break;
1756 }
1757 for ( ; image; image=image->next)
1758 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1759 break;
1760 }
1761 if (LocaleCompare(attribute,"memory-limit") == 0)
1762 {
1763 MagickSizeType
1764 limit;
1765
1766 limit=MagickResourceInfinity;
1767 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1768 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1769 100.0);
1770 (void) SetMagickResourceLimit(MemoryResource,limit);
1771 break;
1772 }
1773 if (LocaleCompare(attribute,"monochrome") == 0)
1774 {
1775 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1776 SvPV(sval,na)) : SvIV(sval);
1777 if (sp < 0)
1778 {
1779 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1780 SvPV(sval,na));
1781 break;
1782 }
1783 if (info)
1784 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1785 for ( ; image; image=image->next)
1786 (void) SetImageType(image,BilevelType,exception);
1787 break;
1788 }
1789 if (info)
1790 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1791 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001792 {
1793 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001794 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001795 }
cristy4a3ce0a2013-08-03 20:06:59 +00001796 break;
1797 }
1798 case 'O':
1799 case 'o':
1800 {
1801 if (LocaleCompare(attribute,"option") == 0)
1802 {
1803 if (info)
1804 DefineImageOption(info->image_info,SvPV(sval,na));
1805 break;
1806 }
1807 if (LocaleCompare(attribute,"orientation") == 0)
1808 {
1809 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1810 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1811 if (sp < 0)
1812 {
1813 ThrowPerlException(exception,OptionError,
1814 "UnrecognizedOrientationType",SvPV(sval,na));
1815 break;
1816 }
1817 if (info)
1818 info->image_info->orientation=(OrientationType) sp;
1819 for ( ; image; image=image->next)
1820 image->orientation=(OrientationType) sp;
1821 break;
1822 }
1823 if (info)
1824 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1825 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001826 {
1827 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001828 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001829 }
cristy4a3ce0a2013-08-03 20:06:59 +00001830 break;
1831 }
1832 case 'P':
1833 case 'p':
1834 {
1835 if (LocaleCompare(attribute,"page") == 0)
1836 {
1837 char
1838 *geometry;
1839
1840 geometry=GetPageGeometry(SvPV(sval,na));
1841 if (info)
1842 (void) CloneString(&info->image_info->page,geometry);
1843 for ( ; image; image=image->next)
1844 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1845 geometry=(char *) RelinquishMagickMemory(geometry);
1846 break;
1847 }
1848 if (LocaleNCompare(attribute,"pixel",5) == 0)
1849 {
1850 int
1851 items;
1852
1853 PixelInfo
1854 pixel;
1855
1856 register Quantum
1857 *q;
1858
1859 CacheView
1860 *image_view;
1861
1862 for ( ; image; image=image->next)
1863 {
1864 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1865 break;
1866 x=0;
1867 y=0;
1868 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1869 (void) items;
1870 image_view=AcquireVirtualCacheView(image,exception);
1871 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1872 if (q != (Quantum *) NULL)
1873 {
1874 if ((strchr(SvPV(sval,na),',') == 0) ||
1875 (strchr(SvPV(sval,na),')') != 0))
1876 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1877 &pixel,exception);
1878 else
1879 {
1880 GetPixelInfo(image,&pixel);
1881 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1882 pixel.red=geometry_info.rho;
1883 if ((flags & SigmaValue) != 0)
1884 pixel.green=geometry_info.sigma;
1885 if ((flags & XiValue) != 0)
1886 pixel.blue=geometry_info.xi;
1887 if ((flags & PsiValue) != 0)
1888 pixel.alpha=geometry_info.psi;
1889 if ((flags & ChiValue) != 0)
1890 pixel.black=geometry_info.chi;
1891 }
1892 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1893 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1894 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1895 if (image->colorspace == CMYKColorspace)
1896 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1897 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1898 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1899 }
1900 image_view=DestroyCacheView(image_view);
1901 }
1902 break;
1903 }
1904 if (LocaleCompare(attribute,"pointsize") == 0)
1905 {
1906 if (info)
1907 {
1908 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1909 info->image_info->pointsize=geometry_info.rho;
1910 }
1911 break;
1912 }
cristy4a3ce0a2013-08-03 20:06:59 +00001913 if (info)
1914 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1915 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001916 {
1917 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001918 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001919 }
cristy4a3ce0a2013-08-03 20:06:59 +00001920 break;
1921 }
1922 case 'Q':
1923 case 'q':
1924 {
1925 if (LocaleCompare(attribute,"quality") == 0)
1926 {
1927 if (info)
1928 info->image_info->quality=SvIV(sval);
1929 for ( ; image; image=image->next)
1930 image->quality=SvIV(sval);
1931 break;
1932 }
1933 if (info)
1934 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1935 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001936 {
1937 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001938 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001939 }
cristy4a3ce0a2013-08-03 20:06:59 +00001940 break;
1941 }
1942 case 'R':
1943 case 'r':
1944 {
cristyc0fe4752015-07-27 18:02:39 +00001945 if (LocaleCompare(attribute,"read-mask") == 0)
1946 {
1947 Image
1948 *mask;
1949
1950 mask=(Image *) NULL;
1951 if (SvPOK(sval))
1952 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1953 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001954 SetImageMask(image,ReadPixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00001955 break;
1956 }
cristy4a3ce0a2013-08-03 20:06:59 +00001957 if (LocaleCompare(attribute,"red-primary") == 0)
1958 {
1959 for ( ; image; image=image->next)
1960 {
1961 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1962 image->chromaticity.red_primary.x=geometry_info.rho;
1963 image->chromaticity.red_primary.y=geometry_info.sigma;
1964 if ((flags & SigmaValue) == 0)
1965 image->chromaticity.red_primary.y=
1966 image->chromaticity.red_primary.x;
1967 }
1968 break;
1969 }
1970 if (LocaleCompare(attribute,"render") == 0)
1971 {
1972 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1973 SvPV(sval,na)) : SvIV(sval);
1974 if (sp < 0)
1975 {
1976 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1977 SvPV(sval,na));
1978 break;
1979 }
1980 for ( ; image; image=image->next)
1981 image->rendering_intent=(RenderingIntent) sp;
1982 break;
1983 }
1984 if (LocaleCompare(attribute,"repage") == 0)
1985 {
1986 RectangleInfo
1987 geometry;
1988
1989 for ( ; image; image=image->next)
1990 {
1991 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1992 if ((flags & WidthValue) != 0)
1993 {
1994 if ((flags & HeightValue) == 0)
1995 geometry.height=geometry.width;
1996 image->page.width=geometry.width;
1997 image->page.height=geometry.height;
1998 }
1999 if ((flags & AspectValue) != 0)
2000 {
2001 if ((flags & XValue) != 0)
2002 image->page.x+=geometry.x;
2003 if ((flags & YValue) != 0)
2004 image->page.y+=geometry.y;
2005 }
2006 else
2007 {
2008 if ((flags & XValue) != 0)
2009 {
2010 image->page.x=geometry.x;
2011 if (((flags & WidthValue) != 0) && (geometry.x > 0))
2012 image->page.width=image->columns+geometry.x;
2013 }
2014 if ((flags & YValue) != 0)
2015 {
2016 image->page.y=geometry.y;
2017 if (((flags & HeightValue) != 0) && (geometry.y > 0))
2018 image->page.height=image->rows+geometry.y;
2019 }
2020 }
2021 }
2022 break;
2023 }
2024 if (info)
2025 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2026 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002027 {
2028 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002029 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002030 }
cristy4a3ce0a2013-08-03 20:06:59 +00002031 break;
2032 }
2033 case 'S':
2034 case 's':
2035 {
2036 if (LocaleCompare(attribute,"sampling-factor") == 0)
2037 {
2038 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2039 {
2040 ThrowPerlException(exception,OptionError,"MissingGeometry",
2041 SvPV(sval,na));
2042 break;
2043 }
2044 if (info)
2045 (void) CloneString(&info->image_info->sampling_factor,
2046 SvPV(sval,na));
2047 break;
2048 }
2049 if (LocaleCompare(attribute,"scene") == 0)
2050 {
2051 for ( ; image; image=image->next)
2052 image->scene=SvIV(sval);
2053 break;
2054 }
2055 if (LocaleCompare(attribute,"server") == 0)
2056 goto display;
2057 if (LocaleCompare(attribute,"size") == 0)
2058 {
2059 if (info)
2060 {
2061 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2062 {
2063 ThrowPerlException(exception,OptionError,"MissingGeometry",
2064 SvPV(sval,na));
2065 break;
2066 }
2067 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2068 }
2069 break;
2070 }
2071 if (LocaleCompare(attribute,"stroke") == 0)
2072 {
2073 if (info)
2074 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2075 break;
2076 }
2077 if (info)
2078 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2079 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002080 {
2081 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002082 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002083 }
cristy4a3ce0a2013-08-03 20:06:59 +00002084 break;
2085 }
2086 case 'T':
2087 case 't':
2088 {
2089 if (LocaleCompare(attribute,"texture") == 0)
2090 {
2091 if (info)
2092 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2093 break;
2094 }
2095 if (LocaleCompare(attribute,"thread-limit") == 0)
2096 {
2097 MagickSizeType
2098 limit;
2099
2100 limit=MagickResourceInfinity;
2101 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2102 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2103 100.0);
2104 (void) SetMagickResourceLimit(ThreadResource,limit);
2105 break;
2106 }
2107 if (LocaleCompare(attribute,"tile-offset") == 0)
2108 {
2109 char
2110 *geometry;
2111
2112 geometry=GetPageGeometry(SvPV(sval,na));
2113 if (info)
2114 (void) CloneString(&info->image_info->page,geometry);
2115 for ( ; image; image=image->next)
2116 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2117 exception);
2118 geometry=(char *) RelinquishMagickMemory(geometry);
2119 break;
2120 }
2121 if (LocaleCompare(attribute,"time-limit") == 0)
2122 {
2123 MagickSizeType
2124 limit;
2125
2126 limit=MagickResourceInfinity;
2127 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2128 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2129 100.0);
2130 (void) SetMagickResourceLimit(TimeResource,limit);
2131 break;
2132 }
2133 if (LocaleCompare(attribute,"transparent-color") == 0)
2134 {
2135 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2136 exception);
2137 if (info)
2138 info->image_info->transparent_color=target_color;
2139 for ( ; image; image=image->next)
2140 image->transparent_color=target_color;
2141 break;
2142 }
2143 if (LocaleCompare(attribute,"type") == 0)
2144 {
2145 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2146 SvPV(sval,na)) : SvIV(sval);
2147 if (sp < 0)
2148 {
2149 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2150 SvPV(sval,na));
2151 break;
2152 }
2153 if (info)
2154 info->image_info->type=(ImageType) sp;
2155 for ( ; image; image=image->next)
2156 SetImageType(image,(ImageType) sp,exception);
2157 break;
2158 }
2159 if (info)
2160 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2161 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002162 {
2163 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002164 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002165 }
cristy4a3ce0a2013-08-03 20:06:59 +00002166 break;
2167 }
2168 case 'U':
2169 case 'u':
2170 {
2171 if (LocaleCompare(attribute,"units") == 0)
2172 {
2173 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2174 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2175 if (sp < 0)
2176 {
2177 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2178 SvPV(sval,na));
2179 break;
2180 }
2181 if (info)
2182 info->image_info->units=(ResolutionType) sp;
2183 for ( ; image; image=image->next)
2184 {
2185 ResolutionType
2186 units;
2187
2188 units=(ResolutionType) sp;
2189 if (image->units != units)
2190 switch (image->units)
2191 {
2192 case UndefinedResolution:
2193 case PixelsPerInchResolution:
2194 {
2195 if (units == PixelsPerCentimeterResolution)
2196 {
2197 image->resolution.x*=2.54;
2198 image->resolution.y*=2.54;
2199 }
2200 break;
2201 }
2202 case PixelsPerCentimeterResolution:
2203 {
2204 if (units == PixelsPerInchResolution)
2205 {
2206 image->resolution.x/=2.54;
2207 image->resolution.y/=2.54;
2208 }
2209 break;
2210 }
2211 }
2212 image->units=units;
2213 }
2214 break;
2215 }
2216 if (info)
2217 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2218 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002219 {
2220 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002221 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002222 }
cristy4a3ce0a2013-08-03 20:06:59 +00002223 break;
2224 }
2225 case 'V':
2226 case 'v':
2227 {
2228 if (LocaleCompare(attribute,"verbose") == 0)
2229 {
2230 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2231 SvPV(sval,na)) : SvIV(sval);
2232 if (sp < 0)
2233 {
2234 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2235 SvPV(sval,na));
2236 break;
2237 }
2238 if (info)
2239 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2240 break;
2241 }
cristy4a3ce0a2013-08-03 20:06:59 +00002242 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2243 {
2244 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2245 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2246 if (sp < 0)
2247 {
2248 ThrowPerlException(exception,OptionError,
2249 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2250 break;
2251 }
2252 for ( ; image; image=image->next)
2253 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2254 break;
2255 }
2256 if (info)
2257 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2258 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002259 {
2260 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002261 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002262 }
cristy4a3ce0a2013-08-03 20:06:59 +00002263 break;
2264 }
2265 case 'W':
2266 case 'w':
2267 {
2268 if (LocaleCompare(attribute,"white-point") == 0)
2269 {
2270 for ( ; image; image=image->next)
2271 {
2272 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2273 image->chromaticity.white_point.x=geometry_info.rho;
2274 image->chromaticity.white_point.y=geometry_info.sigma;
2275 if ((flags & SigmaValue) == 0)
2276 image->chromaticity.white_point.y=
2277 image->chromaticity.white_point.x;
2278 }
2279 break;
2280 }
cristyc0fe4752015-07-27 18:02:39 +00002281 if (LocaleCompare(attribute,"write-mask") == 0)
2282 {
2283 Image
2284 *mask;
2285
2286 mask=(Image *) NULL;
2287 if (SvPOK(sval))
2288 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2289 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002290 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002291 break;
2292 }
cristy4a3ce0a2013-08-03 20:06:59 +00002293 if (info)
2294 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2295 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002296 {
2297 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002298 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002299 }
cristy4a3ce0a2013-08-03 20:06:59 +00002300 break;
2301 }
2302 default:
2303 {
2304 if (info)
2305 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2306 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002307 {
2308 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002309 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002310 }
cristy4a3ce0a2013-08-03 20:06:59 +00002311 break;
2312 }
2313 }
2314}
2315
2316/*
2317%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2318% %
2319% %
2320% %
2321% S e t u p L i s t %
2322% %
2323% %
2324% %
2325%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2326%
2327% Method SetupList returns the list of all the images linked by their
2328% image->next and image->previous link lists for use with ImageMagick. If
2329% info is non-NULL, an info structure is returned in *info. If
2330% reference_vector is non-NULL,an array of SV* are returned in
2331% *reference_vector. Reference_vector is used when the images are going to be
2332% replaced with new Image*'s.
2333%
2334% The format of the SetupList routine is:
2335%
2336% Image *SetupList(SV *reference,struct PackageInfo **info,
2337% SV ***reference_vector,ExceptionInfo *exception)
2338%
2339% A description of each parameter follows:
2340%
2341% o list: a list of strings.
2342%
2343% o string: a character string.
2344%
2345% o exception: Return any errors or warnings in this structure.
2346%
2347*/
2348static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2349 SV ***reference_vector,ExceptionInfo *exception)
2350{
2351 Image
2352 *image;
2353
2354 ssize_t
2355 current,
2356 last;
2357
2358 if (reference_vector)
2359 *reference_vector=NULL;
2360 if (info)
2361 *info=NULL;
2362 current=0;
2363 last=0;
2364 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2365 if (info && (SvTYPE(reference) == SVt_PVAV))
2366 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2367 exception);
2368 return(image);
2369}
2370
2371/*
2372%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2373% %
2374% %
2375% %
2376% s t r E Q c a s e %
2377% %
2378% %
2379% %
2380%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2381%
2382% strEQcase() compares two strings and returns 0 if they are the
2383% same or if the second string runs out first. The comparison is case
2384% insensitive.
2385%
2386% The format of the strEQcase routine is:
2387%
2388% ssize_t strEQcase(const char *p,const char *q)
2389%
2390% A description of each parameter follows:
2391%
2392% o p: a character string.
2393%
2394% o q: a character string.
2395%
2396%
2397*/
2398static ssize_t strEQcase(const char *p,const char *q)
2399{
2400 char
2401 c;
2402
2403 register ssize_t
2404 i;
2405
2406 for (i=0 ; (c=(*q)) != 0; i++)
2407 {
2408 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2409 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2410 return(0);
2411 p++;
2412 q++;
2413 }
2414 return(((*q == 0) && (*p == 0)) ? i : 0);
2415}
2416
2417/*
2418%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2419% %
2420% %
2421% %
2422% I m a g e : : M a g i c k %
2423% %
2424% %
2425% %
2426%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2427%
2428%
2429*/
2430MODULE = Image::Magick PACKAGE = Image::Magick
2431
2432PROTOTYPES: ENABLE
2433
2434BOOT:
2435 MagickCoreGenesis("PerlMagick",MagickFalse);
2436 SetWarningHandler(NULL);
2437 SetErrorHandler(NULL);
2438 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2439 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2440
2441void
2442UNLOAD()
2443 PPCODE:
2444 {
2445 if (magick_registry != (SplayTreeInfo *) NULL)
2446 magick_registry=DestroySplayTree(magick_registry);
2447 MagickCoreTerminus();
2448 }
2449
2450double
2451constant(name,argument)
2452 char *name
2453 ssize_t argument
2454
2455#
2456###############################################################################
2457# #
2458# #
2459# #
2460# A n i m a t e #
2461# #
2462# #
2463# #
2464###############################################################################
2465#
2466#
2467void
2468Animate(ref,...)
2469 Image::Magick ref=NO_INIT
2470 ALIAS:
2471 AnimateImage = 1
2472 animate = 2
2473 animateimage = 3
2474 PPCODE:
2475 {
2476 ExceptionInfo
2477 *exception;
2478
2479 Image
2480 *image;
2481
2482 register ssize_t
2483 i;
2484
2485 struct PackageInfo
2486 *info,
2487 *package_info;
2488
2489 SV
2490 *perl_exception,
2491 *reference;
2492
2493 PERL_UNUSED_VAR(ref);
2494 PERL_UNUSED_VAR(ix);
2495 exception=AcquireExceptionInfo();
2496 perl_exception=newSVpv("",0);
2497 package_info=(struct PackageInfo *) NULL;
2498 if (sv_isobject(ST(0)) == 0)
2499 {
2500 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2501 PackageName);
2502 goto PerlException;
2503 }
2504 reference=SvRV(ST(0));
2505 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2506 if (image == (Image *) NULL)
2507 {
2508 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2509 PackageName);
2510 goto PerlException;
2511 }
2512 package_info=ClonePackageInfo(info,exception);
2513 if (items == 2)
2514 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2515 else
2516 if (items > 2)
2517 for (i=2; i < items; i+=2)
2518 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2519 exception);
2520 (void) AnimateImages(package_info->image_info,image,exception);
2521 (void) CatchImageException(image);
2522
2523 PerlException:
2524 if (package_info != (struct PackageInfo *) NULL)
2525 DestroyPackageInfo(package_info);
2526 InheritPerlException(exception,perl_exception);
2527 exception=DestroyExceptionInfo(exception);
2528 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2529 SvPOK_on(perl_exception);
2530 ST(0)=sv_2mortal(perl_exception);
2531 XSRETURN(1);
2532 }
2533
2534#
2535###############################################################################
2536# #
2537# #
2538# #
2539# A p p e n d #
2540# #
2541# #
2542# #
2543###############################################################################
2544#
2545#
2546void
2547Append(ref,...)
2548 Image::Magick ref=NO_INIT
2549 ALIAS:
2550 AppendImage = 1
2551 append = 2
2552 appendimage = 3
2553 PPCODE:
2554 {
2555 AV
2556 *av;
2557
2558 char
2559 *attribute;
2560
2561 ExceptionInfo
2562 *exception;
2563
2564 HV
2565 *hv;
2566
2567 Image
2568 *image;
2569
2570 register ssize_t
2571 i;
2572
2573 ssize_t
2574 stack;
2575
2576 struct PackageInfo
2577 *info;
2578
2579 SV
2580 *av_reference,
2581 *perl_exception,
2582 *reference,
2583 *rv,
2584 *sv;
2585
2586 PERL_UNUSED_VAR(ref);
2587 PERL_UNUSED_VAR(ix);
2588 exception=AcquireExceptionInfo();
2589 perl_exception=newSVpv("",0);
2590 sv=NULL;
2591 attribute=NULL;
2592 av=NULL;
2593 if (sv_isobject(ST(0)) == 0)
2594 {
2595 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2596 PackageName);
2597 goto PerlException;
2598 }
2599 reference=SvRV(ST(0));
2600 hv=SvSTASH(reference);
2601 av=newAV();
2602 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2603 SvREFCNT_dec(av);
2604 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2605 if (image == (Image *) NULL)
2606 {
2607 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2608 PackageName);
2609 goto PerlException;
2610 }
2611 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2612 /*
2613 Get options.
2614 */
2615 stack=MagickTrue;
2616 for (i=2; i < items; i+=2)
2617 {
2618 attribute=(char *) SvPV(ST(i-1),na);
2619 switch (*attribute)
2620 {
2621 case 'S':
2622 case 's':
2623 {
2624 if (LocaleCompare(attribute,"stack") == 0)
2625 {
2626 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2627 SvPV(ST(i),na));
2628 if (stack < 0)
2629 {
2630 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2631 SvPV(ST(i),na));
2632 return;
2633 }
2634 break;
2635 }
2636 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2637 attribute);
2638 break;
2639 }
2640 default:
2641 {
2642 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2643 attribute);
2644 break;
2645 }
2646 }
2647 }
2648 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2649 if (image == (Image *) NULL)
2650 goto PerlException;
2651 for ( ; image; image=image->next)
2652 {
2653 AddImageToRegistry(sv,image);
2654 rv=newRV(sv);
2655 av_push(av,sv_bless(rv,hv));
2656 SvREFCNT_dec(sv);
2657 }
2658 exception=DestroyExceptionInfo(exception);
2659 ST(0)=av_reference;
2660 SvREFCNT_dec(perl_exception);
2661 XSRETURN(1);
2662
2663 PerlException:
2664 InheritPerlException(exception,perl_exception);
2665 exception=DestroyExceptionInfo(exception);
2666 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2667 SvPOK_on(perl_exception);
2668 ST(0)=sv_2mortal(perl_exception);
2669 XSRETURN(1);
2670 }
2671
2672#
2673###############################################################################
2674# #
2675# #
2676# #
2677# A v e r a g e #
2678# #
2679# #
2680# #
2681###############################################################################
2682#
2683#
2684void
2685Average(ref)
2686 Image::Magick ref=NO_INIT
2687 ALIAS:
2688 AverageImage = 1
2689 average = 2
2690 averageimage = 3
2691 PPCODE:
2692 {
2693 AV
2694 *av;
2695
2696 char
2697 *p;
2698
2699 ExceptionInfo
2700 *exception;
2701
2702 HV
2703 *hv;
2704
2705 Image
2706 *image;
2707
2708 struct PackageInfo
2709 *info;
2710
2711 SV
2712 *perl_exception,
2713 *reference,
2714 *rv,
2715 *sv;
2716
2717 PERL_UNUSED_VAR(ref);
2718 PERL_UNUSED_VAR(ix);
2719 exception=AcquireExceptionInfo();
2720 perl_exception=newSVpv("",0);
2721 sv=NULL;
2722 if (sv_isobject(ST(0)) == 0)
2723 {
2724 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2725 PackageName);
2726 goto PerlException;
2727 }
2728 reference=SvRV(ST(0));
2729 hv=SvSTASH(reference);
2730 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2731 if (image == (Image *) NULL)
2732 {
2733 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2734 PackageName);
2735 goto PerlException;
2736 }
2737 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2738 if (image == (Image *) NULL)
2739 goto PerlException;
2740 /*
2741 Create blessed Perl array for the returned image.
2742 */
2743 av=newAV();
2744 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2745 SvREFCNT_dec(av);
2746 AddImageToRegistry(sv,image);
2747 rv=newRV(sv);
2748 av_push(av,sv_bless(rv,hv));
2749 SvREFCNT_dec(sv);
2750 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002751 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2752 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002753 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2754 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002755 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002756 SetImageInfo(info->image_info,0,exception);
2757 exception=DestroyExceptionInfo(exception);
2758 SvREFCNT_dec(perl_exception);
2759 XSRETURN(1);
2760
2761 PerlException:
2762 InheritPerlException(exception,perl_exception);
2763 exception=DestroyExceptionInfo(exception);
2764 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2765 SvPOK_on(perl_exception);
2766 ST(0)=sv_2mortal(perl_exception);
2767 XSRETURN(1);
2768 }
2769
2770#
2771###############################################################################
2772# #
2773# #
2774# #
2775# B l o b T o I m a g e #
2776# #
2777# #
2778# #
2779###############################################################################
2780#
2781#
2782void
2783BlobToImage(ref,...)
2784 Image::Magick ref=NO_INIT
2785 ALIAS:
2786 BlobToImage = 1
2787 blobtoimage = 2
2788 blobto = 3
2789 PPCODE:
2790 {
2791 AV
2792 *av;
2793
2794 char
2795 **keep,
2796 **list;
2797
2798 ExceptionInfo
2799 *exception;
2800
2801 HV
2802 *hv;
2803
2804 Image
2805 *image;
2806
2807 register char
2808 **p;
2809
2810 register ssize_t
2811 i;
2812
2813 ssize_t
2814 ac,
2815 n,
2816 number_images;
2817
2818 STRLEN
2819 *length;
2820
2821 struct PackageInfo
2822 *info;
2823
2824 SV
2825 *perl_exception,
2826 *reference,
2827 *rv,
2828 *sv;
2829
2830 PERL_UNUSED_VAR(ref);
2831 PERL_UNUSED_VAR(ix);
2832 exception=AcquireExceptionInfo();
2833 perl_exception=newSVpv("",0);
2834 sv=NULL;
2835 number_images=0;
2836 ac=(items < 2) ? 1 : items-1;
2837 length=(STRLEN *) NULL;
2838 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2839 if (list == (char **) NULL)
2840 {
2841 ThrowPerlException(exception,ResourceLimitError,
2842 "MemoryAllocationFailed",PackageName);
2843 goto PerlException;
2844 }
2845 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2846 if (length == (STRLEN *) NULL)
2847 {
2848 ThrowPerlException(exception,ResourceLimitError,
2849 "MemoryAllocationFailed",PackageName);
2850 goto PerlException;
2851 }
2852 if (sv_isobject(ST(0)) == 0)
2853 {
2854 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2855 PackageName);
2856 goto PerlException;
2857 }
2858 reference=SvRV(ST(0));
2859 hv=SvSTASH(reference);
2860 if (SvTYPE(reference) != SVt_PVAV)
2861 {
2862 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2863 PackageName);
2864 goto PerlException;
2865 }
2866 av=(AV *) reference;
2867 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2868 exception);
2869 n=1;
2870 if (items <= 1)
2871 {
2872 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2873 goto PerlException;
2874 }
2875 for (n=0, i=0; i < ac; i++)
2876 {
2877 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2878 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2879 {
2880 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2881 continue;
2882 }
2883 n++;
2884 }
2885 list[n]=(char *) NULL;
2886 keep=list;
2887 for (i=number_images=0; i < n; i++)
2888 {
2889 image=BlobToImage(info->image_info,list[i],length[i],exception);
2890 if (image == (Image *) NULL)
2891 break;
2892 for ( ; image; image=image->next)
2893 {
2894 AddImageToRegistry(sv,image);
2895 rv=newRV(sv);
2896 av_push(av,sv_bless(rv,hv));
2897 SvREFCNT_dec(sv);
2898 number_images++;
2899 }
2900 }
2901 /*
2902 Free resources.
2903 */
2904 for (i=0; i < n; i++)
2905 if (list[i] != (char *) NULL)
2906 for (p=keep; list[i] != *p++; )
2907 if (*p == (char *) NULL)
2908 {
2909 list[i]=(char *) RelinquishMagickMemory(list[i]);
2910 break;
2911 }
2912
2913 PerlException:
2914 if (list)
2915 list=(char **) RelinquishMagickMemory(list);
2916 if (length)
2917 length=(STRLEN *) RelinquishMagickMemory(length);
2918 InheritPerlException(exception,perl_exception);
2919 exception=DestroyExceptionInfo(exception);
2920 sv_setiv(perl_exception,(IV) number_images);
2921 SvPOK_on(perl_exception);
2922 ST(0)=sv_2mortal(perl_exception);
2923 XSRETURN(1);
2924 }
2925
2926#
2927###############################################################################
2928# #
2929# #
2930# #
2931# C h a n n e l F x #
2932# #
2933# #
2934# #
2935###############################################################################
2936#
2937#
2938void
2939ChannelFx(ref,...)
2940 Image::Magick ref=NO_INIT
2941 ALIAS:
2942 ChannelFxImage = 1
2943 channelfx = 2
2944 channelfximage = 3
2945 PPCODE:
2946 {
2947 AV
2948 *av;
2949
2950 char
2951 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002952 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002953
2954 ChannelType
2955 channel,
2956 channel_mask;
2957
2958 ExceptionInfo
2959 *exception;
2960
2961 HV
2962 *hv;
2963
2964 Image
2965 *image;
2966
2967 register ssize_t
2968 i;
2969
2970 struct PackageInfo
2971 *info;
2972
2973 SV
2974 *av_reference,
2975 *perl_exception,
2976 *reference,
2977 *rv,
2978 *sv;
2979
2980 PERL_UNUSED_VAR(ref);
2981 PERL_UNUSED_VAR(ix);
2982 exception=AcquireExceptionInfo();
2983 perl_exception=newSVpv("",0);
2984 sv=NULL;
2985 attribute=NULL;
2986 av=NULL;
2987 if (sv_isobject(ST(0)) == 0)
2988 {
2989 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2990 PackageName);
2991 goto PerlException;
2992 }
2993 reference=SvRV(ST(0));
2994 hv=SvSTASH(reference);
2995 av=newAV();
2996 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2997 SvREFCNT_dec(av);
2998 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2999 if (image == (Image *) NULL)
3000 {
3001 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3002 PackageName);
3003 goto PerlException;
3004 }
3005 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3006 /*
3007 Get options.
3008 */
3009 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00003010 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003011 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00003012 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003013 else
3014 for (i=2; i < items; i+=2)
3015 {
3016 attribute=(char *) SvPV(ST(i-1),na);
3017 switch (*attribute)
3018 {
3019 case 'C':
3020 case 'c':
3021 {
3022 if (LocaleCompare(attribute,"channel") == 0)
3023 {
3024 ssize_t
3025 option;
3026
3027 option=ParseChannelOption(SvPV(ST(i),na));
3028 if (option < 0)
3029 {
3030 ThrowPerlException(exception,OptionError,
3031 "UnrecognizedType",SvPV(ST(i),na));
3032 return;
3033 }
3034 channel=(ChannelType) option;
3035 break;
3036 }
3037 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3038 attribute);
3039 break;
3040 }
3041 case 'E':
3042 case 'e':
3043 {
3044 if (LocaleCompare(attribute,"expression") == 0)
3045 {
3046 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00003047 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003048 break;
3049 }
3050 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3051 attribute);
3052 break;
3053 }
3054 default:
3055 {
3056 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3057 attribute);
3058 break;
3059 }
3060 }
3061 }
3062 channel_mask=SetImageChannelMask(image,channel);
3063 image=ChannelFxImage(image,expression,exception);
3064 if (image != (Image *) NULL)
3065 (void) SetImageChannelMask(image,channel_mask);
3066 if (image == (Image *) NULL)
3067 goto PerlException;
3068 for ( ; image; image=image->next)
3069 {
3070 AddImageToRegistry(sv,image);
3071 rv=newRV(sv);
3072 av_push(av,sv_bless(rv,hv));
3073 SvREFCNT_dec(sv);
3074 }
3075 exception=DestroyExceptionInfo(exception);
3076 ST(0)=av_reference;
3077 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3078 XSRETURN(1);
3079
3080 PerlException:
3081 InheritPerlException(exception,perl_exception);
3082 exception=DestroyExceptionInfo(exception);
3083 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3084 SvPOK_on(perl_exception);
3085 ST(0)=sv_2mortal(perl_exception);
3086 XSRETURN(1);
3087 }
3088
3089#
3090###############################################################################
3091# #
3092# #
3093# #
3094# C l o n e #
3095# #
3096# #
3097# #
3098###############################################################################
3099#
3100#
3101void
3102Clone(ref)
3103 Image::Magick ref=NO_INIT
3104 ALIAS:
3105 CopyImage = 1
3106 copy = 2
3107 copyimage = 3
3108 CloneImage = 4
3109 clone = 5
3110 cloneimage = 6
3111 Clone = 7
3112 PPCODE:
3113 {
3114 AV
3115 *av;
3116
3117 ExceptionInfo
3118 *exception;
3119
3120 HV
3121 *hv;
3122
3123 Image
3124 *clone,
3125 *image;
3126
3127 struct PackageInfo
3128 *info;
3129
3130 SV
3131 *perl_exception,
3132 *reference,
3133 *rv,
3134 *sv;
3135
3136 PERL_UNUSED_VAR(ref);
3137 PERL_UNUSED_VAR(ix);
3138 exception=AcquireExceptionInfo();
3139 perl_exception=newSVpv("",0);
3140 sv=NULL;
3141 if (sv_isobject(ST(0)) == 0)
3142 {
3143 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3144 PackageName);
3145 goto PerlException;
3146 }
3147 reference=SvRV(ST(0));
3148 hv=SvSTASH(reference);
3149 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3150 if (image == (Image *) NULL)
3151 {
3152 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3153 PackageName);
3154 goto PerlException;
3155 }
3156 /*
3157 Create blessed Perl array for the returned image.
3158 */
3159 av=newAV();
3160 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3161 SvREFCNT_dec(av);
3162 for ( ; image; image=image->next)
3163 {
3164 clone=CloneImage(image,0,0,MagickTrue,exception);
3165 if (clone == (Image *) NULL)
3166 break;
3167 AddImageToRegistry(sv,clone);
3168 rv=newRV(sv);
3169 av_push(av,sv_bless(rv,hv));
3170 SvREFCNT_dec(sv);
3171 }
3172 exception=DestroyExceptionInfo(exception);
3173 SvREFCNT_dec(perl_exception);
3174 XSRETURN(1);
3175
3176 PerlException:
3177 InheritPerlException(exception,perl_exception);
3178 exception=DestroyExceptionInfo(exception);
3179 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3180 SvPOK_on(perl_exception);
3181 ST(0)=sv_2mortal(perl_exception);
3182 XSRETURN(1);
3183 }
3184
3185#
3186###############################################################################
3187# #
3188# #
3189# #
3190# C L O N E #
3191# #
3192# #
3193# #
3194###############################################################################
3195#
3196#
3197void
3198CLONE(ref,...)
3199 SV *ref;
3200 CODE:
3201 {
3202 PERL_UNUSED_VAR(ref);
3203 if (magick_registry != (SplayTreeInfo *) NULL)
3204 {
3205 register Image
3206 *p;
3207
3208 ResetSplayTreeIterator(magick_registry);
3209 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3210 while (p != (Image *) NULL)
3211 {
3212 ReferenceImage(p);
3213 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3214 }
3215 }
3216 }
3217
3218#
3219###############################################################################
3220# #
3221# #
3222# #
3223# C o a l e s c e #
3224# #
3225# #
3226# #
3227###############################################################################
3228#
3229#
3230void
3231Coalesce(ref)
3232 Image::Magick ref=NO_INIT
3233 ALIAS:
3234 CoalesceImage = 1
3235 coalesce = 2
3236 coalesceimage = 3
3237 PPCODE:
3238 {
3239 AV
3240 *av;
3241
3242 ExceptionInfo
3243 *exception;
3244
3245 HV
3246 *hv;
3247
3248 Image
3249 *image;
3250
3251 struct PackageInfo
3252 *info;
3253
3254 SV
3255 *av_reference,
3256 *perl_exception,
3257 *reference,
3258 *rv,
3259 *sv;
3260
3261 PERL_UNUSED_VAR(ref);
3262 PERL_UNUSED_VAR(ix);
3263 exception=AcquireExceptionInfo();
3264 perl_exception=newSVpv("",0);
3265 sv=NULL;
3266 if (sv_isobject(ST(0)) == 0)
3267 {
3268 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3269 PackageName);
3270 goto PerlException;
3271 }
3272 reference=SvRV(ST(0));
3273 hv=SvSTASH(reference);
3274 av=newAV();
3275 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3276 SvREFCNT_dec(av);
3277 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3278 if (image == (Image *) NULL)
3279 {
3280 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3281 PackageName);
3282 goto PerlException;
3283 }
3284 image=CoalesceImages(image,exception);
3285 if (image == (Image *) NULL)
3286 goto PerlException;
3287 for ( ; image; image=image->next)
3288 {
3289 AddImageToRegistry(sv,image);
3290 rv=newRV(sv);
3291 av_push(av,sv_bless(rv,hv));
3292 SvREFCNT_dec(sv);
3293 }
3294 exception=DestroyExceptionInfo(exception);
3295 ST(0)=av_reference;
3296 SvREFCNT_dec(perl_exception);
3297 XSRETURN(1);
3298
3299 PerlException:
3300 InheritPerlException(exception,perl_exception);
3301 exception=DestroyExceptionInfo(exception);
3302 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3303 SvPOK_on(perl_exception);
3304 ST(0)=sv_2mortal(perl_exception);
3305 XSRETURN(1);
3306 }
3307
3308#
3309###############################################################################
3310# #
3311# #
3312# #
3313# C o m p a r e #
3314# #
3315# #
3316# #
3317###############################################################################
3318#
3319#
3320void
3321Compare(ref,...)
3322 Image::Magick ref=NO_INIT
3323 ALIAS:
3324 CompareImages = 1
3325 compare = 2
3326 compareimage = 3
3327 PPCODE:
3328 {
3329 AV
3330 *av;
3331
3332 char
3333 *attribute;
3334
3335 double
3336 distortion;
3337
3338 ExceptionInfo
3339 *exception;
3340
3341 HV
3342 *hv;
3343
3344 Image
3345 *difference_image,
3346 *image,
3347 *reconstruct_image;
3348
3349 MetricType
3350 metric;
3351
3352 register ssize_t
3353 i;
3354
3355 ssize_t
3356 option;
3357
3358 struct PackageInfo
3359 *info;
3360
3361 SV
3362 *av_reference,
3363 *perl_exception,
3364 *reference,
3365 *rv,
3366 *sv;
3367
3368 PERL_UNUSED_VAR(ref);
3369 PERL_UNUSED_VAR(ix);
3370 exception=AcquireExceptionInfo();
3371 perl_exception=newSVpv("",0);
3372 sv=NULL;
3373 av=NULL;
3374 attribute=NULL;
3375 if (sv_isobject(ST(0)) == 0)
3376 {
3377 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3378 PackageName);
3379 goto PerlException;
3380 }
3381 reference=SvRV(ST(0));
3382 hv=SvSTASH(reference);
3383 av=newAV();
3384 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3385 SvREFCNT_dec(av);
3386 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3387 if (image == (Image *) NULL)
3388 {
3389 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3390 PackageName);
3391 goto PerlException;
3392 }
3393 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3394 /*
3395 Get attribute.
3396 */
3397 reconstruct_image=image;
3398 metric=RootMeanSquaredErrorMetric;
3399 for (i=2; i < items; i+=2)
3400 {
3401 attribute=(char *) SvPV(ST(i-1),na);
3402 switch (*attribute)
3403 {
3404 case 'C':
3405 case 'c':
3406 {
3407 if (LocaleCompare(attribute,"channel") == 0)
3408 {
3409 ssize_t
3410 option;
3411
3412 option=ParseChannelOption(SvPV(ST(i),na));
3413 if (option < 0)
3414 {
3415 ThrowPerlException(exception,OptionError,
3416 "UnrecognizedType",SvPV(ST(i),na));
3417 return;
3418 }
cristybcd59342015-06-07 14:07:19 +00003419 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003420 break;
3421 }
3422 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3423 attribute);
3424 break;
3425 }
3426 case 'F':
3427 case 'f':
3428 {
3429 if (LocaleCompare(attribute,"fuzz") == 0)
3430 {
3431 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3432 break;
3433 }
3434 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3435 attribute);
3436 break;
3437 }
3438 case 'I':
3439 case 'i':
3440 {
3441 if (LocaleCompare(attribute,"image") == 0)
3442 {
3443 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3444 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3445 break;
3446 }
3447 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3448 attribute);
3449 break;
3450 }
3451 case 'M':
3452 case 'm':
3453 {
3454 if (LocaleCompare(attribute,"metric") == 0)
3455 {
3456 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3457 SvPV(ST(i),na));
3458 if (option < 0)
3459 {
3460 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3461 SvPV(ST(i),na));
3462 break;
3463 }
3464 metric=(MetricType) option;
3465 break;
3466 }
3467 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3468 attribute);
3469 break;
3470 }
3471 default:
3472 {
3473 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3474 attribute);
3475 break;
3476 }
3477 }
3478 }
3479 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3480 exception);
3481 if (difference_image != (Image *) NULL)
3482 {
3483 difference_image->error.mean_error_per_pixel=distortion;
3484 AddImageToRegistry(sv,difference_image);
3485 rv=newRV(sv);
3486 av_push(av,sv_bless(rv,hv));
3487 SvREFCNT_dec(sv);
3488 }
3489 exception=DestroyExceptionInfo(exception);
3490 ST(0)=av_reference;
3491 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3492 XSRETURN(1);
3493
3494 PerlException:
3495 InheritPerlException(exception,perl_exception);
3496 exception=DestroyExceptionInfo(exception);
3497 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3498 SvPOK_on(perl_exception);
3499 ST(0)=sv_2mortal(perl_exception);
3500 XSRETURN(1);
3501 }
3502
3503#
3504###############################################################################
3505# #
3506# #
3507# #
cristy15655332013-10-06 00:27:33 +00003508# C o m p l e x I m a g e s #
3509# #
3510# #
3511# #
3512###############################################################################
3513#
3514#
3515void
3516ComplexImages(ref)
3517 Image::Magick ref=NO_INIT
3518 ALIAS:
3519 ComplexImages = 1
3520 compleximages = 2
3521 PPCODE:
3522 {
3523 AV
3524 *av;
3525
3526 char
3527 *attribute,
3528 *p;
3529
cristyfa21e9e2013-10-07 10:37:38 +00003530 ComplexOperator
3531 op;
3532
cristy15655332013-10-06 00:27:33 +00003533 ExceptionInfo
3534 *exception;
3535
3536 HV
3537 *hv;
3538
3539 Image
3540 *image;
3541
cristy15655332013-10-06 00:27:33 +00003542 register ssize_t
3543 i;
3544
3545 struct PackageInfo
3546 *info;
3547
3548 SV
3549 *perl_exception,
3550 *reference,
3551 *rv,
3552 *sv;
3553
3554 PERL_UNUSED_VAR(ref);
3555 PERL_UNUSED_VAR(ix);
3556 exception=AcquireExceptionInfo();
3557 perl_exception=newSVpv("",0);
3558 sv=NULL;
3559 if (sv_isobject(ST(0)) == 0)
3560 {
3561 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3562 PackageName);
3563 goto PerlException;
3564 }
3565 reference=SvRV(ST(0));
3566 hv=SvSTASH(reference);
3567 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3568 if (image == (Image *) NULL)
3569 {
3570 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3571 PackageName);
3572 goto PerlException;
3573 }
cristyfd168722013-10-07 15:59:31 +00003574 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003575 if (items == 2)
3576 {
3577 ssize_t
3578 in;
3579
3580 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3581 SvPV(ST(1),na));
3582 if (in < 0)
3583 {
3584 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3585 SvPV(ST(1),na));
3586 return;
3587 }
cristyfa21e9e2013-10-07 10:37:38 +00003588 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003589 }
3590 else
3591 for (i=2; i < items; i+=2)
3592 {
3593 attribute=(char *) SvPV(ST(i-1),na);
3594 switch (*attribute)
3595 {
3596 case 'O':
3597 case 'o':
3598 {
3599 if (LocaleCompare(attribute,"operator") == 0)
3600 {
3601 ssize_t
3602 in;
3603
3604 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3605 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3606 if (in < 0)
3607 {
3608 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3609 SvPV(ST(i),na));
3610 return;
3611 }
cristyfa21e9e2013-10-07 10:37:38 +00003612 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003613 break;
3614 }
3615 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3616 attribute);
3617 break;
3618 }
3619 default:
3620 {
3621 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3622 attribute);
3623 break;
3624 }
3625 }
3626 }
3627 image=ComplexImages(image,op,exception);
3628 if (image == (Image *) NULL)
3629 goto PerlException;
3630 /*
3631 Create blessed Perl array for the returned image.
3632 */
3633 av=newAV();
3634 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3635 SvREFCNT_dec(av);
3636 AddImageToRegistry(sv,image);
3637 rv=newRV(sv);
3638 av_push(av,sv_bless(rv,hv));
3639 SvREFCNT_dec(sv);
3640 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003641 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3642 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003643 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3644 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003645 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003646 SetImageInfo(info->image_info,0,exception);
3647 exception=DestroyExceptionInfo(exception);
3648 SvREFCNT_dec(perl_exception);
3649 XSRETURN(1);
3650
3651 PerlException:
3652 InheritPerlException(exception,perl_exception);
3653 exception=DestroyExceptionInfo(exception);
3654 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3655 SvPOK_on(perl_exception);
3656 ST(0)=sv_2mortal(perl_exception);
3657 XSRETURN(1);
3658 }
3659
3660#
3661###############################################################################
3662# #
3663# #
3664# #
cristy4a3ce0a2013-08-03 20:06:59 +00003665# C o m p a r e L a y e r s #
3666# #
3667# #
3668# #
3669###############################################################################
3670#
3671#
3672void
3673CompareLayers(ref)
3674 Image::Magick ref=NO_INIT
3675 ALIAS:
3676 CompareImagesLayers = 1
3677 comparelayers = 2
3678 compareimagelayers = 3
3679 PPCODE:
3680 {
3681 AV
3682 *av;
3683
3684 char
3685 *attribute;
3686
3687 ExceptionInfo
3688 *exception;
3689
3690 HV
3691 *hv;
3692
3693 Image
3694 *image;
3695
3696 LayerMethod
3697 method;
3698
3699 register ssize_t
3700 i;
3701
3702 ssize_t
3703 option;
3704
3705 struct PackageInfo
3706 *info;
3707
3708 SV
3709 *av_reference,
3710 *perl_exception,
3711 *reference,
3712 *rv,
3713 *sv;
3714
3715 PERL_UNUSED_VAR(ref);
3716 PERL_UNUSED_VAR(ix);
3717 exception=AcquireExceptionInfo();
3718 perl_exception=newSVpv("",0);
3719 sv=NULL;
3720 if (sv_isobject(ST(0)) == 0)
3721 {
3722 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3723 PackageName);
3724 goto PerlException;
3725 }
3726 reference=SvRV(ST(0));
3727 hv=SvSTASH(reference);
3728 av=newAV();
3729 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3730 SvREFCNT_dec(av);
3731 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3732 if (image == (Image *) NULL)
3733 {
3734 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3735 PackageName);
3736 goto PerlException;
3737 }
3738 method=CompareAnyLayer;
3739 for (i=2; i < items; i+=2)
3740 {
3741 attribute=(char *) SvPV(ST(i-1),na);
3742 switch (*attribute)
3743 {
3744 case 'M':
3745 case 'm':
3746 {
3747 if (LocaleCompare(attribute,"method") == 0)
3748 {
3749 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3750 SvPV(ST(i),na));
3751 if (option < 0)
3752 {
3753 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3754 SvPV(ST(i),na));
3755 break;
3756 }
3757 method=(LayerMethod) option;
3758 break;
3759 }
3760 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3761 attribute);
3762 break;
3763 }
3764 default:
3765 {
3766 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3767 attribute);
3768 break;
3769 }
3770 }
3771 }
3772 image=CompareImagesLayers(image,method,exception);
3773 if (image == (Image *) NULL)
3774 goto PerlException;
3775 for ( ; image; image=image->next)
3776 {
3777 AddImageToRegistry(sv,image);
3778 rv=newRV(sv);
3779 av_push(av,sv_bless(rv,hv));
3780 SvREFCNT_dec(sv);
3781 }
3782 exception=DestroyExceptionInfo(exception);
3783 ST(0)=av_reference;
3784 SvREFCNT_dec(perl_exception);
3785 XSRETURN(1);
3786
3787 PerlException:
3788 InheritPerlException(exception,perl_exception);
3789 exception=DestroyExceptionInfo(exception);
3790 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3791 SvPOK_on(perl_exception);
3792 ST(0)=sv_2mortal(perl_exception);
3793 XSRETURN(1);
3794 }
3795
3796#
3797###############################################################################
3798# #
3799# #
3800# #
3801# D e s t r o y #
3802# #
3803# #
3804# #
3805###############################################################################
3806#
3807#
3808void
3809DESTROY(ref)
3810 Image::Magick ref=NO_INIT
3811 PPCODE:
3812 {
3813 SV
3814 *reference;
3815
3816 PERL_UNUSED_VAR(ref);
3817 if (sv_isobject(ST(0)) == 0)
3818 croak("ReferenceIsNotMyType");
3819 reference=SvRV(ST(0));
3820 switch (SvTYPE(reference))
3821 {
3822 case SVt_PVAV:
3823 {
3824 char
cristy151b66d2015-04-15 10:50:31 +00003825 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003826
3827 const SV
3828 *key;
3829
3830 HV
3831 *hv;
3832
3833 GV
3834 **gvp;
3835
3836 struct PackageInfo
3837 *info;
3838
3839 SV
3840 *sv;
3841
3842 /*
3843 Array (AV *) reference
3844 */
cristy151b66d2015-04-15 10:50:31 +00003845 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003846 XS_VERSION,reference);
3847 hv=gv_stashpv(PackageName, FALSE);
3848 if (!hv)
3849 break;
3850 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3851 if (!gvp)
3852 break;
3853 sv=GvSV(*gvp);
3854 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3855 {
3856 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3857 DestroyPackageInfo(info);
3858 }
3859 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3860 (void) key;
3861 break;
3862 }
3863 case SVt_PVMG:
3864 {
3865 Image
3866 *image;
3867
3868 /*
3869 Blessed scalar = (Image *) SvIV(reference)
3870 */
3871 image=INT2PTR(Image *,SvIV(reference));
3872 if (image != (Image *) NULL)
3873 DeleteImageFromRegistry(reference,image);
3874 break;
3875 }
3876 default:
3877 break;
3878 }
3879 }
3880
3881#
3882###############################################################################
3883# #
3884# #
3885# #
3886# D i s p l a y #
3887# #
3888# #
3889# #
3890###############################################################################
3891#
3892#
3893void
3894Display(ref,...)
3895 Image::Magick ref=NO_INIT
3896 ALIAS:
3897 DisplayImage = 1
3898 display = 2
3899 displayimage = 3
3900 PPCODE:
3901 {
3902 ExceptionInfo
3903 *exception;
3904
3905 Image
3906 *image;
3907
3908 register ssize_t
3909 i;
3910
3911 struct PackageInfo
3912 *info,
3913 *package_info;
3914
3915 SV
3916 *perl_exception,
3917 *reference;
3918
3919 PERL_UNUSED_VAR(ref);
3920 PERL_UNUSED_VAR(ix);
3921 exception=AcquireExceptionInfo();
3922 perl_exception=newSVpv("",0);
3923 package_info=(struct PackageInfo *) NULL;
3924 if (sv_isobject(ST(0)) == 0)
3925 {
3926 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3927 PackageName);
3928 goto PerlException;
3929 }
3930 reference=SvRV(ST(0));
3931 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3932 if (image == (Image *) NULL)
3933 {
3934 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3935 PackageName);
3936 goto PerlException;
3937 }
3938 package_info=ClonePackageInfo(info,exception);
3939 if (items == 2)
3940 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3941 else
3942 if (items > 2)
3943 for (i=2; i < items; i+=2)
3944 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3945 exception);
3946 (void) DisplayImages(package_info->image_info,image,exception);
3947 (void) CatchImageException(image);
3948
3949 PerlException:
3950 if (package_info != (struct PackageInfo *) NULL)
3951 DestroyPackageInfo(package_info);
3952 InheritPerlException(exception,perl_exception);
3953 exception=DestroyExceptionInfo(exception);
3954 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3955 SvPOK_on(perl_exception);
3956 ST(0)=sv_2mortal(perl_exception);
3957 XSRETURN(1);
3958 }
3959
3960#
3961###############################################################################
3962# #
3963# #
3964# #
3965# E v a l u a t e I m a g e s #
3966# #
3967# #
3968# #
3969###############################################################################
3970#
3971#
3972void
3973EvaluateImages(ref)
3974 Image::Magick ref=NO_INIT
3975 ALIAS:
3976 EvaluateImages = 1
3977 evaluateimages = 2
3978 PPCODE:
3979 {
3980 AV
3981 *av;
3982
3983 char
3984 *attribute,
3985 *p;
3986
3987 ExceptionInfo
3988 *exception;
3989
3990 HV
3991 *hv;
3992
3993 Image
3994 *image;
3995
3996 MagickEvaluateOperator
3997 op;
3998
3999 register ssize_t
4000 i;
4001
4002 struct PackageInfo
4003 *info;
4004
4005 SV
4006 *perl_exception,
4007 *reference,
4008 *rv,
4009 *sv;
4010
4011 PERL_UNUSED_VAR(ref);
4012 PERL_UNUSED_VAR(ix);
4013 exception=AcquireExceptionInfo();
4014 perl_exception=newSVpv("",0);
4015 sv=NULL;
4016 if (sv_isobject(ST(0)) == 0)
4017 {
4018 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4019 PackageName);
4020 goto PerlException;
4021 }
4022 reference=SvRV(ST(0));
4023 hv=SvSTASH(reference);
4024 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4025 if (image == (Image *) NULL)
4026 {
4027 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4028 PackageName);
4029 goto PerlException;
4030 }
4031 op=MeanEvaluateOperator;
4032 if (items == 2)
4033 {
4034 ssize_t
4035 in;
4036
4037 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
4038 SvPV(ST(1),na));
4039 if (in < 0)
4040 {
4041 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4042 SvPV(ST(1),na));
4043 return;
4044 }
4045 op=(MagickEvaluateOperator) in;
4046 }
4047 else
4048 for (i=2; i < items; i+=2)
4049 {
4050 attribute=(char *) SvPV(ST(i-1),na);
4051 switch (*attribute)
4052 {
4053 case 'O':
4054 case 'o':
4055 {
4056 if (LocaleCompare(attribute,"operator") == 0)
4057 {
4058 ssize_t
4059 in;
4060
4061 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4062 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4063 if (in < 0)
4064 {
4065 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4066 SvPV(ST(i),na));
4067 return;
4068 }
4069 op=(MagickEvaluateOperator) in;
4070 break;
4071 }
4072 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4073 attribute);
4074 break;
4075 }
4076 default:
4077 {
4078 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4079 attribute);
4080 break;
4081 }
4082 }
4083 }
4084 image=EvaluateImages(image,op,exception);
4085 if (image == (Image *) NULL)
4086 goto PerlException;
4087 /*
4088 Create blessed Perl array for the returned image.
4089 */
4090 av=newAV();
4091 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4092 SvREFCNT_dec(av);
4093 AddImageToRegistry(sv,image);
4094 rv=newRV(sv);
4095 av_push(av,sv_bless(rv,hv));
4096 SvREFCNT_dec(sv);
4097 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004098 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4099 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004100 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4101 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004102 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004103 SetImageInfo(info->image_info,0,exception);
4104 exception=DestroyExceptionInfo(exception);
4105 SvREFCNT_dec(perl_exception);
4106 XSRETURN(1);
4107
4108 PerlException:
4109 InheritPerlException(exception,perl_exception);
4110 exception=DestroyExceptionInfo(exception);
4111 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4112 SvPOK_on(perl_exception);
4113 ST(0)=sv_2mortal(perl_exception);
4114 XSRETURN(1);
4115 }
4116
4117#
4118###############################################################################
4119# #
4120# #
4121# #
4122# F e a t u r e s #
4123# #
4124# #
4125# #
4126###############################################################################
4127#
4128#
4129void
4130Features(ref,...)
4131 Image::Magick ref=NO_INIT
4132 ALIAS:
4133 FeaturesImage = 1
4134 features = 2
4135 featuresimage = 3
4136 PPCODE:
4137 {
4138#define ChannelFeatures(channel,direction) \
4139{ \
Cristyb1710fe2017-02-11 13:51:48 -05004140 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004141 channel_features[channel].angular_second_moment[direction]); \
4142 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004143 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004144 channel_features[channel].contrast[direction]); \
4145 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004146 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004147 channel_features[channel].contrast[direction]); \
4148 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004149 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004150 channel_features[channel].variance_sum_of_squares[direction]); \
4151 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004152 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004153 channel_features[channel].inverse_difference_moment[direction]); \
4154 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004155 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004156 channel_features[channel].sum_average[direction]); \
4157 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004158 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004159 channel_features[channel].sum_variance[direction]); \
4160 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004161 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004162 channel_features[channel].sum_entropy[direction]); \
4163 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004164 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004165 channel_features[channel].entropy[direction]); \
4166 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004167 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004168 channel_features[channel].difference_variance[direction]); \
4169 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004170 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004171 channel_features[channel].difference_entropy[direction]); \
4172 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004173 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004174 channel_features[channel].measure_of_correlation_1[direction]); \
4175 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004176 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004177 channel_features[channel].measure_of_correlation_2[direction]); \
4178 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004179 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004180 channel_features[channel].maximum_correlation_coefficient[direction]); \
4181 PUSHs(sv_2mortal(newSVpv(message,0))); \
4182}
4183
4184 AV
4185 *av;
4186
4187 char
4188 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004189 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004190
4191 ChannelFeatures
4192 *channel_features;
4193
4194 double
4195 distance;
4196
4197 ExceptionInfo
4198 *exception;
4199
4200 Image
4201 *image;
4202
4203 register ssize_t
4204 i;
4205
4206 ssize_t
4207 count;
4208
4209 struct PackageInfo
4210 *info;
4211
4212 SV
4213 *perl_exception,
4214 *reference;
4215
4216 PERL_UNUSED_VAR(ref);
4217 PERL_UNUSED_VAR(ix);
4218 exception=AcquireExceptionInfo();
4219 perl_exception=newSVpv("",0);
4220 av=NULL;
4221 if (sv_isobject(ST(0)) == 0)
4222 {
4223 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4224 PackageName);
4225 goto PerlException;
4226 }
4227 reference=SvRV(ST(0));
4228 av=newAV();
4229 SvREFCNT_dec(av);
4230 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4231 if (image == (Image *) NULL)
4232 {
4233 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4234 PackageName);
4235 goto PerlException;
4236 }
cristy7dbd9262014-07-02 17:53:42 +00004237 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004238 for (i=2; i < items; i+=2)
4239 {
4240 attribute=(char *) SvPV(ST(i-1),na);
4241 switch (*attribute)
4242 {
4243 case 'D':
4244 case 'd':
4245 {
4246 if (LocaleCompare(attribute,"distance") == 0)
4247 {
4248 distance=StringToLong((char *) SvPV(ST(1),na));
4249 break;
4250 }
4251 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4252 attribute);
4253 break;
4254 }
4255 default:
4256 {
4257 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4258 attribute);
4259 break;
4260 }
4261 }
4262 }
4263 count=0;
4264 for ( ; image; image=image->next)
4265 {
Cristy5a854dc2017-02-11 15:43:46 -05004266 register ssize_t
4267 j;
4268
cristy4a3ce0a2013-08-03 20:06:59 +00004269 channel_features=GetImageFeatures(image,distance,exception);
4270 if (channel_features == (ChannelFeatures *) NULL)
4271 continue;
4272 count++;
Cristy5a854dc2017-02-11 15:43:46 -05004273 for (j=0; j < 4; j++)
cristy4a3ce0a2013-08-03 20:06:59 +00004274 {
Cristy5a854dc2017-02-11 15:43:46 -05004275 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
4276 {
4277 PixelChannel channel=GetPixelChannelChannel(image,i);
4278 PixelTrait traits=GetPixelChannelTraits(image,channel);
4279 if (traits == UndefinedPixelTrait)
4280 continue;
4281 EXTEND(sp,14*(i+1)*count);
4282 ChannelFeatures(channel,j);
4283 }
cristy4a3ce0a2013-08-03 20:06:59 +00004284 }
4285 channel_features=(ChannelFeatures *)
4286 RelinquishMagickMemory(channel_features);
4287 }
4288
4289 PerlException:
4290 InheritPerlException(exception,perl_exception);
4291 exception=DestroyExceptionInfo(exception);
4292 SvREFCNT_dec(perl_exception);
4293 }
4294
4295#
4296###############################################################################
4297# #
4298# #
4299# #
4300# F l a t t e n #
4301# #
4302# #
4303# #
4304###############################################################################
4305#
4306#
4307void
4308Flatten(ref)
4309 Image::Magick ref=NO_INIT
4310 ALIAS:
4311 FlattenImage = 1
4312 flatten = 2
4313 flattenimage = 3
4314 PPCODE:
4315 {
4316 AV
4317 *av;
4318
4319 char
4320 *attribute,
4321 *p;
4322
4323 ExceptionInfo
4324 *exception;
4325
4326 HV
4327 *hv;
4328
4329 Image
4330 *image;
4331
4332 PixelInfo
4333 background_color;
4334
4335 register ssize_t
4336 i;
4337
4338 struct PackageInfo
4339 *info;
4340
4341 SV
4342 *perl_exception,
4343 *reference,
4344 *rv,
4345 *sv;
4346
4347 PERL_UNUSED_VAR(ref);
4348 PERL_UNUSED_VAR(ix);
4349 exception=AcquireExceptionInfo();
4350 perl_exception=newSVpv("",0);
4351 sv=NULL;
4352 if (sv_isobject(ST(0)) == 0)
4353 {
4354 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4355 PackageName);
4356 goto PerlException;
4357 }
4358 reference=SvRV(ST(0));
4359 hv=SvSTASH(reference);
4360 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4361 if (image == (Image *) NULL)
4362 {
4363 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4364 PackageName);
4365 goto PerlException;
4366 }
4367 background_color=image->background_color;
4368 if (items == 2)
4369 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4370 &background_color,exception);
4371 else
4372 for (i=2; i < items; i+=2)
4373 {
4374 attribute=(char *) SvPV(ST(i-1),na);
4375 switch (*attribute)
4376 {
4377 case 'B':
4378 case 'b':
4379 {
4380 if (LocaleCompare(attribute,"background") == 0)
4381 {
4382 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4383 AllCompliance,&background_color,exception);
4384 break;
4385 }
4386 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4387 attribute);
4388 break;
4389 }
4390 default:
4391 {
4392 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4393 attribute);
4394 break;
4395 }
4396 }
4397 }
4398 image->background_color=background_color;
4399 image=MergeImageLayers(image,FlattenLayer,exception);
4400 if (image == (Image *) NULL)
4401 goto PerlException;
4402 /*
4403 Create blessed Perl array for the returned image.
4404 */
4405 av=newAV();
4406 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4407 SvREFCNT_dec(av);
4408 AddImageToRegistry(sv,image);
4409 rv=newRV(sv);
4410 av_push(av,sv_bless(rv,hv));
4411 SvREFCNT_dec(sv);
4412 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004413 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4414 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004415 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4416 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004417 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004418 SetImageInfo(info->image_info,0,exception);
4419 exception=DestroyExceptionInfo(exception);
4420 SvREFCNT_dec(perl_exception);
4421 XSRETURN(1);
4422
4423 PerlException:
4424 InheritPerlException(exception,perl_exception);
4425 exception=DestroyExceptionInfo(exception);
4426 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4427 SvPOK_on(perl_exception); /* return messages in string context */
4428 ST(0)=sv_2mortal(perl_exception);
4429 XSRETURN(1);
4430 }
4431
4432#
4433###############################################################################
4434# #
4435# #
4436# #
4437# F x #
4438# #
4439# #
4440# #
4441###############################################################################
4442#
4443#
4444void
4445Fx(ref,...)
4446 Image::Magick ref=NO_INIT
4447 ALIAS:
4448 FxImage = 1
4449 fx = 2
4450 fximage = 3
4451 PPCODE:
4452 {
4453 AV
4454 *av;
4455
4456 char
4457 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004458 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004459
4460 ChannelType
4461 channel,
4462 channel_mask;
4463
4464 ExceptionInfo
4465 *exception;
4466
4467 HV
4468 *hv;
4469
4470 Image
4471 *image;
4472
4473 register ssize_t
4474 i;
4475
4476 struct PackageInfo
4477 *info;
4478
4479 SV
4480 *av_reference,
4481 *perl_exception,
4482 *reference,
4483 *rv,
4484 *sv;
4485
4486 PERL_UNUSED_VAR(ref);
4487 PERL_UNUSED_VAR(ix);
4488 exception=AcquireExceptionInfo();
4489 perl_exception=newSVpv("",0);
4490 sv=NULL;
4491 attribute=NULL;
4492 av=NULL;
4493 if (sv_isobject(ST(0)) == 0)
4494 {
4495 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4496 PackageName);
4497 goto PerlException;
4498 }
4499 reference=SvRV(ST(0));
4500 hv=SvSTASH(reference);
4501 av=newAV();
4502 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4503 SvREFCNT_dec(av);
4504 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4505 if (image == (Image *) NULL)
4506 {
4507 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4508 PackageName);
4509 goto PerlException;
4510 }
4511 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4512 /*
4513 Get options.
4514 */
4515 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004516 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004517 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004518 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004519 else
4520 for (i=2; i < items; i+=2)
4521 {
4522 attribute=(char *) SvPV(ST(i-1),na);
4523 switch (*attribute)
4524 {
4525 case 'C':
4526 case 'c':
4527 {
4528 if (LocaleCompare(attribute,"channel") == 0)
4529 {
4530 ssize_t
4531 option;
4532
4533 option=ParseChannelOption(SvPV(ST(i),na));
4534 if (option < 0)
4535 {
4536 ThrowPerlException(exception,OptionError,
4537 "UnrecognizedType",SvPV(ST(i),na));
4538 return;
4539 }
4540 channel=(ChannelType) option;
4541 break;
4542 }
4543 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4544 attribute);
4545 break;
4546 }
4547 case 'E':
4548 case 'e':
4549 {
4550 if (LocaleCompare(attribute,"expression") == 0)
4551 {
4552 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004553 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004554 break;
4555 }
4556 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4557 attribute);
4558 break;
4559 }
4560 default:
4561 {
4562 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4563 attribute);
4564 break;
4565 }
4566 }
4567 }
4568 channel_mask=SetImageChannelMask(image,channel);
4569 image=FxImage(image,expression,exception);
4570 if (image != (Image *) NULL)
4571 (void) SetImageChannelMask(image,channel_mask);
4572 if (image == (Image *) NULL)
4573 goto PerlException;
4574 for ( ; image; image=image->next)
4575 {
4576 AddImageToRegistry(sv,image);
4577 rv=newRV(sv);
4578 av_push(av,sv_bless(rv,hv));
4579 SvREFCNT_dec(sv);
4580 }
4581 exception=DestroyExceptionInfo(exception);
4582 ST(0)=av_reference;
4583 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4584 XSRETURN(1);
4585
4586 PerlException:
4587 InheritPerlException(exception,perl_exception);
4588 exception=DestroyExceptionInfo(exception);
4589 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4590 SvPOK_on(perl_exception);
4591 ST(0)=sv_2mortal(perl_exception);
4592 XSRETURN(1);
4593 }
4594
4595#
4596###############################################################################
4597# #
4598# #
4599# #
4600# G e t #
4601# #
4602# #
4603# #
4604###############################################################################
4605#
4606#
4607void
4608Get(ref,...)
4609 Image::Magick ref=NO_INIT
4610 ALIAS:
4611 GetAttributes = 1
4612 GetAttribute = 2
4613 get = 3
4614 getattributes = 4
4615 getattribute = 5
4616 PPCODE:
4617 {
4618 char
4619 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004620 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004621
4622 const char
4623 *value;
4624
4625 ExceptionInfo
4626 *exception;
4627
4628 Image
4629 *image;
4630
4631 long
4632 j;
4633
4634 register ssize_t
4635 i;
4636
4637 struct PackageInfo
4638 *info;
4639
4640 SV
4641 *perl_exception,
4642 *reference,
4643 *s;
4644
4645 PERL_UNUSED_VAR(ref);
4646 PERL_UNUSED_VAR(ix);
4647 exception=AcquireExceptionInfo();
4648 perl_exception=newSVpv("",0);
4649 if (sv_isobject(ST(0)) == 0)
4650 {
4651 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4652 PackageName);
4653 XSRETURN_EMPTY;
4654 }
4655 reference=SvRV(ST(0));
4656 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4657 if (image == (Image *) NULL && !info)
4658 XSRETURN_EMPTY;
4659 EXTEND(sp,items);
4660 for (i=1; i < items; i++)
4661 {
4662 attribute=(char *) SvPV(ST(i),na);
4663 s=NULL;
4664 switch (*attribute)
4665 {
4666 case 'A':
4667 case 'a':
4668 {
4669 if (LocaleCompare(attribute,"adjoin") == 0)
4670 {
4671 if (info)
4672 s=newSViv((ssize_t) info->image_info->adjoin);
4673 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4674 continue;
4675 }
4676 if (LocaleCompare(attribute,"antialias") == 0)
4677 {
4678 if (info)
4679 s=newSViv((ssize_t) info->image_info->antialias);
4680 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4681 continue;
4682 }
4683 if (LocaleCompare(attribute,"area") == 0)
4684 {
4685 s=newSViv(GetMagickResource(AreaResource));
4686 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4687 continue;
4688 }
4689 if (LocaleCompare(attribute,"attenuate") == 0)
4690 {
4691 const char
4692 *value;
4693
4694 value=GetImageProperty(image,attribute,exception);
4695 if (value != (const char *) NULL)
4696 s=newSVpv(value,0);
4697 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4698 continue;
4699 }
4700 if (LocaleCompare(attribute,"authenticate") == 0)
4701 {
4702 if (info)
4703 {
4704 const char
4705 *option;
4706
4707 option=GetImageOption(info->image_info,attribute);
4708 if (option != (const char *) NULL)
4709 s=newSVpv(option,0);
4710 }
4711 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4712 continue;
4713 }
4714 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4715 attribute);
4716 break;
4717 }
4718 case 'B':
4719 case 'b':
4720 {
4721 if (LocaleCompare(attribute,"background") == 0)
4722 {
4723 if (image == (Image *) NULL)
4724 break;
cristy151b66d2015-04-15 10:50:31 +00004725 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004726 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4727 (double) image->background_color.green,
4728 (double) image->background_color.blue,
4729 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004730 s=newSVpv(color,0);
4731 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4732 continue;
4733 }
4734 if (LocaleCompare(attribute,"base-columns") == 0)
4735 {
4736 if (image != (Image *) NULL)
4737 s=newSViv((ssize_t) image->magick_columns);
4738 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4739 continue;
4740 }
4741 if (LocaleCompare(attribute,"base-filename") == 0)
4742 {
4743 if (image != (Image *) NULL)
4744 s=newSVpv(image->magick_filename,0);
4745 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4746 continue;
4747 }
4748 if (LocaleCompare(attribute,"base-height") == 0)
4749 {
4750 if (image != (Image *) NULL)
4751 s=newSViv((ssize_t) image->magick_rows);
4752 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4753 continue;
4754 }
4755 if (LocaleCompare(attribute,"base-rows") == 0)
4756 {
4757 if (image != (Image *) NULL)
4758 s=newSViv((ssize_t) image->magick_rows);
4759 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4760 continue;
4761 }
4762 if (LocaleCompare(attribute,"base-width") == 0)
4763 {
4764 if (image != (Image *) NULL)
4765 s=newSViv((ssize_t) image->magick_columns);
4766 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4767 continue;
4768 }
4769 if (LocaleCompare(attribute,"blue-primary") == 0)
4770 {
4771 if (image == (Image *) NULL)
4772 break;
Cristyb1710fe2017-02-11 13:51:48 -05004773 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004774 image->chromaticity.blue_primary.x,
4775 image->chromaticity.blue_primary.y);
4776 s=newSVpv(color,0);
4777 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4778 continue;
4779 }
4780 if (LocaleCompare(attribute,"bordercolor") == 0)
4781 {
4782 if (image == (Image *) NULL)
4783 break;
cristy151b66d2015-04-15 10:50:31 +00004784 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004785 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4786 (double) image->border_color.green,
4787 (double) image->border_color.blue,
4788 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004789 s=newSVpv(color,0);
4790 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4791 continue;
4792 }
4793 if (LocaleCompare(attribute,"bounding-box") == 0)
4794 {
4795 char
cristy151b66d2015-04-15 10:50:31 +00004796 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004797
4798 RectangleInfo
4799 page;
4800
4801 if (image == (Image *) NULL)
4802 break;
4803 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004804 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004805 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4806 page.height,(double) page.x,(double) page.y);
4807 s=newSVpv(geometry,0);
4808 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4809 continue;
4810 }
4811 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4812 attribute);
4813 break;
4814 }
4815 case 'C':
4816 case 'c':
4817 {
4818 if (LocaleCompare(attribute,"class") == 0)
4819 {
4820 if (image == (Image *) NULL)
4821 break;
4822 s=newSViv(image->storage_class);
4823 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4824 image->storage_class));
4825 SvIOK_on(s);
4826 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4827 continue;
4828 }
4829 if (LocaleCompare(attribute,"clip-mask") == 0)
4830 {
4831 if (image != (Image *) NULL)
4832 {
4833 Image
4834 *mask_image;
4835
4836 SV
4837 *sv;
4838
4839 sv=NULL;
4840 if (image->read_mask == MagickFalse)
4841 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004842 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004843 if (mask_image != (Image *) NULL)
4844 {
4845 AddImageToRegistry(sv,mask_image);
4846 s=sv_bless(newRV(sv),SvSTASH(reference));
4847 }
4848 }
4849 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4850 continue;
4851 }
4852 if (LocaleCompare(attribute,"clip-path") == 0)
4853 {
4854 if (image != (Image *) NULL)
4855 {
4856 Image
4857 *mask_image;
4858
4859 SV
4860 *sv;
4861
4862 sv=NULL;
4863 if (image->read_mask != MagickFalse)
4864 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004865 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004866 if (mask_image != (Image *) NULL)
4867 {
4868 AddImageToRegistry(sv,mask_image);
4869 s=sv_bless(newRV(sv),SvSTASH(reference));
4870 }
4871 }
4872 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4873 continue;
4874 }
4875 if (LocaleCompare(attribute,"compression") == 0)
4876 {
4877 j=info ? info->image_info->compression : image ?
4878 image->compression : UndefinedCompression;
4879 if (info)
4880 if (info->image_info->compression == UndefinedCompression)
4881 j=image->compression;
4882 s=newSViv(j);
4883 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4884 j));
4885 SvIOK_on(s);
4886 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4887 continue;
4888 }
4889 if (LocaleCompare(attribute,"colorspace") == 0)
4890 {
4891 j=image ? image->colorspace : RGBColorspace;
4892 s=newSViv(j);
4893 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4894 j));
4895 SvIOK_on(s);
4896 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4897 continue;
4898 }
4899 if (LocaleCompare(attribute,"colors") == 0)
4900 {
4901 if (image != (Image *) NULL)
4902 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4903 exception));
4904 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4905 continue;
4906 }
4907 if (LocaleNCompare(attribute,"colormap",8) == 0)
4908 {
4909 int
4910 items;
4911
4912 if (image == (Image *) NULL || !image->colormap)
4913 break;
4914 j=0;
4915 items=sscanf(attribute,"%*[^[][%ld",&j);
4916 (void) items;
4917 if (j > (ssize_t) image->colors)
4918 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004919 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004920 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4921 (double) image->colormap[j].green,
4922 (double) image->colormap[j].blue,
4923 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004924 s=newSVpv(color,0);
4925 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4926 continue;
4927 }
4928 if (LocaleCompare(attribute,"columns") == 0)
4929 {
4930 if (image != (Image *) NULL)
4931 s=newSViv((ssize_t) image->columns);
4932 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4933 continue;
4934 }
4935 if (LocaleCompare(attribute,"comment") == 0)
4936 {
4937 const char
4938 *value;
4939
Cristy935a4052017-03-31 17:45:37 -04004940 value=GetImageProperty(image,attribute,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004941 if (value != (const char *) NULL)
4942 s=newSVpv(value,0);
4943 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4944 continue;
4945 }
4946 if (LocaleCompare(attribute,"copyright") == 0)
4947 {
4948 s=newSVpv(GetMagickCopyright(),0);
4949 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4950 continue;
4951 }
4952 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4953 attribute);
4954 break;
4955 }
4956 case 'D':
4957 case 'd':
4958 {
4959 if (LocaleCompare(attribute,"density") == 0)
4960 {
4961 char
cristy151b66d2015-04-15 10:50:31 +00004962 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004963
4964 if (image == (Image *) NULL)
4965 break;
Cristyb1710fe2017-02-11 13:51:48 -05004966 (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004967 image->resolution.x,image->resolution.y);
4968 s=newSVpv(geometry,0);
4969 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4970 continue;
4971 }
4972 if (LocaleCompare(attribute,"delay") == 0)
4973 {
4974 if (image != (Image *) NULL)
4975 s=newSViv((ssize_t) image->delay);
4976 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4977 continue;
4978 }
4979 if (LocaleCompare(attribute,"depth") == 0)
4980 {
4981 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4982 if (image != (Image *) NULL)
4983 s=newSViv((ssize_t) GetImageDepth(image,exception));
4984 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4985 continue;
4986 }
4987 if (LocaleCompare(attribute,"directory") == 0)
4988 {
4989 if (image && image->directory)
4990 s=newSVpv(image->directory,0);
4991 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4992 continue;
4993 }
4994 if (LocaleCompare(attribute,"dispose") == 0)
4995 {
4996 if (image == (Image *) NULL)
4997 break;
4998
4999 s=newSViv(image->dispose);
5000 (void) sv_setpv(s,
5001 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
5002 SvIOK_on(s);
5003 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5004 continue;
5005 }
5006 if (LocaleCompare(attribute,"disk") == 0)
5007 {
5008 s=newSViv(GetMagickResource(DiskResource));
5009 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5010 continue;
5011 }
5012 if (LocaleCompare(attribute,"dither") == 0)
5013 {
5014 if (info)
5015 s=newSViv((ssize_t) info->image_info->dither);
5016 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5017 continue;
5018 }
5019 if (LocaleCompare(attribute,"display") == 0) /* same as server */
5020 {
5021 if (info && info->image_info->server_name)
5022 s=newSVpv(info->image_info->server_name,0);
5023 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5024 continue;
5025 }
5026 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5027 attribute);
5028 break;
5029 }
5030 case 'E':
5031 case 'e':
5032 {
5033 if (LocaleCompare(attribute,"elapsed-time") == 0)
5034 {
5035 if (image != (Image *) NULL)
5036 s=newSVnv(GetElapsedTime(&image->timer));
5037 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5038 continue;
5039 }
5040 if (LocaleCompare(attribute,"endian") == 0)
5041 {
5042 j=info ? info->image_info->endian : image ? image->endian :
5043 UndefinedEndian;
5044 s=newSViv(j);
5045 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
5046 SvIOK_on(s);
5047 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5048 continue;
5049 }
5050 if (LocaleCompare(attribute,"error") == 0)
5051 {
5052 if (image != (Image *) NULL)
5053 s=newSVnv(image->error.mean_error_per_pixel);
5054 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5055 continue;
5056 }
5057 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5058 attribute);
5059 break;
5060 }
5061 case 'F':
5062 case 'f':
5063 {
5064 if (LocaleCompare(attribute,"filesize") == 0)
5065 {
5066 if (image != (Image *) NULL)
5067 s=newSViv((ssize_t) GetBlobSize(image));
5068 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5069 continue;
5070 }
5071 if (LocaleCompare(attribute,"filename") == 0)
5072 {
5073 if (info && info->image_info->filename &&
5074 *info->image_info->filename)
5075 s=newSVpv(info->image_info->filename,0);
5076 if (image != (Image *) NULL)
5077 s=newSVpv(image->filename,0);
5078 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5079 continue;
5080 }
5081 if (LocaleCompare(attribute,"filter") == 0)
5082 {
5083 s=image ? newSViv(image->filter) : newSViv(0);
5084 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5085 image->filter));
5086 SvIOK_on(s);
5087 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5088 continue;
5089 }
5090 if (LocaleCompare(attribute,"font") == 0)
5091 {
5092 if (info && info->image_info->font)
5093 s=newSVpv(info->image_info->font,0);
5094 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5095 continue;
5096 }
5097 if (LocaleCompare(attribute,"foreground") == 0)
5098 continue;
5099 if (LocaleCompare(attribute,"format") == 0)
5100 {
5101 const MagickInfo
5102 *magick_info;
5103
5104 magick_info=(const MagickInfo *) NULL;
5105 if (info && (*info->image_info->magick != '\0'))
5106 magick_info=GetMagickInfo(info->image_info->magick,exception);
5107 if (image != (Image *) NULL)
5108 magick_info=GetMagickInfo(image->magick,exception);
5109 if ((magick_info != (const MagickInfo *) NULL) &&
5110 (*magick_info->description != '\0'))
5111 s=newSVpv((char *) magick_info->description,0);
5112 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5113 continue;
5114 }
5115 if (LocaleCompare(attribute,"fuzz") == 0)
5116 {
5117 if (info)
5118 s=newSVnv(info->image_info->fuzz);
5119 if (image != (Image *) NULL)
5120 s=newSVnv(image->fuzz);
5121 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5122 continue;
5123 }
5124 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5125 attribute);
5126 break;
5127 }
5128 case 'G':
5129 case 'g':
5130 {
5131 if (LocaleCompare(attribute,"gamma") == 0)
5132 {
5133 if (image != (Image *) NULL)
5134 s=newSVnv(image->gamma);
5135 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5136 continue;
5137 }
5138 if (LocaleCompare(attribute,"geometry") == 0)
5139 {
5140 if (image && image->geometry)
5141 s=newSVpv(image->geometry,0);
5142 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5143 continue;
5144 }
5145 if (LocaleCompare(attribute,"gravity") == 0)
5146 {
5147 s=image ? newSViv(image->gravity) : newSViv(0);
5148 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5149 image->gravity));
5150 SvIOK_on(s);
5151 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5152 continue;
5153 }
5154 if (LocaleCompare(attribute,"green-primary") == 0)
5155 {
5156 if (image == (Image *) NULL)
5157 break;
Cristyb1710fe2017-02-11 13:51:48 -05005158 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005159 image->chromaticity.green_primary.x,
5160 image->chromaticity.green_primary.y);
5161 s=newSVpv(color,0);
5162 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5163 continue;
5164 }
5165 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5166 attribute);
5167 break;
5168 }
5169 case 'H':
5170 case 'h':
5171 {
5172 if (LocaleCompare(attribute,"height") == 0)
5173 {
5174 if (image != (Image *) NULL)
5175 s=newSViv((ssize_t) image->rows);
5176 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5177 continue;
5178 }
5179 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5180 attribute);
5181 break;
5182 }
5183 case 'I':
5184 case 'i':
5185 {
5186 if (LocaleCompare(attribute,"icc") == 0)
5187 {
5188 if (image != (Image *) NULL)
5189 {
5190 const StringInfo
5191 *profile;
5192
5193 profile=GetImageProfile(image,"icc");
5194 if (profile != (StringInfo *) NULL)
5195 s=newSVpv((const char *) GetStringInfoDatum(profile),
5196 GetStringInfoLength(profile));
5197 }
5198 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5199 continue;
5200 }
5201 if (LocaleCompare(attribute,"icm") == 0)
5202 {
5203 if (image != (Image *) NULL)
5204 {
5205 const StringInfo
5206 *profile;
5207
5208 profile=GetImageProfile(image,"icm");
5209 if (profile != (const StringInfo *) NULL)
5210 s=newSVpv((const char *) GetStringInfoDatum(profile),
5211 GetStringInfoLength(profile));
5212 }
5213 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5214 continue;
5215 }
5216 if (LocaleCompare(attribute,"id") == 0)
5217 {
5218 if (image != (Image *) NULL)
5219 {
5220 char
cristy151b66d2015-04-15 10:50:31 +00005221 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005222
5223 MagickBooleanType
5224 status;
5225
5226 static ssize_t
5227 id = 0;
5228
cristy151b66d2015-04-15 10:50:31 +00005229 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005230 id);
5231 status=SetImageRegistry(ImageRegistryType,key,image,
5232 exception);
5233 (void) status;
5234 s=newSViv(id++);
5235 }
5236 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5237 continue;
5238 }
5239 if (LocaleNCompare(attribute,"index",5) == 0)
5240 {
5241 char
cristy151b66d2015-04-15 10:50:31 +00005242 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005243
5244 int
5245 items;
5246
5247 long
5248 x,
5249 y;
5250
5251 register const Quantum
5252 *p;
5253
5254 CacheView
5255 *image_view;
5256
5257 if (image == (Image *) NULL)
5258 break;
5259 if (image->storage_class != PseudoClass)
5260 break;
5261 x=0;
5262 y=0;
5263 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5264 (void) items;
5265 image_view=AcquireVirtualCacheView(image,exception);
5266 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5267 if (p != (const Quantum *) NULL)
5268 {
cristy151b66d2015-04-15 10:50:31 +00005269 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005270 GetPixelIndex(image,p));
5271 s=newSVpv(name,0);
5272 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5273 }
5274 image_view=DestroyCacheView(image_view);
5275 continue;
5276 }
5277 if (LocaleCompare(attribute,"iptc") == 0)
5278 {
5279 if (image != (Image *) NULL)
5280 {
5281 const StringInfo
5282 *profile;
5283
5284 profile=GetImageProfile(image,"iptc");
5285 if (profile != (const StringInfo *) NULL)
5286 s=newSVpv((const char *) GetStringInfoDatum(profile),
5287 GetStringInfoLength(profile));
5288 }
5289 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5290 continue;
5291 }
5292 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5293 {
5294 if (image != (Image *) NULL)
5295 s=newSViv((ssize_t) image->iterations);
5296 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5297 continue;
5298 }
5299 if (LocaleCompare(attribute,"interlace") == 0)
5300 {
5301 j=info ? info->image_info->interlace : image ? image->interlace :
5302 UndefinedInterlace;
5303 s=newSViv(j);
5304 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5305 j));
5306 SvIOK_on(s);
5307 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5308 continue;
5309 }
5310 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5311 attribute);
5312 break;
5313 }
5314 case 'L':
5315 case 'l':
5316 {
5317 if (LocaleCompare(attribute,"label") == 0)
5318 {
5319 const char
5320 *value;
5321
5322 if (image == (Image *) NULL)
5323 break;
Cristy935a4052017-03-31 17:45:37 -04005324 value=GetImageProperty(image,"Label",exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005325 if (value != (const char *) NULL)
5326 s=newSVpv(value,0);
5327 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5328 continue;
5329 }
5330 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5331 {
5332 if (image != (Image *) NULL)
5333 s=newSViv((ssize_t) image->iterations);
5334 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5335 continue;
5336 }
5337 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5338 attribute);
5339 break;
5340 }
5341 case 'M':
5342 case 'm':
5343 {
5344 if (LocaleCompare(attribute,"magick") == 0)
5345 {
5346 if (info && *info->image_info->magick)
5347 s=newSVpv(info->image_info->magick,0);
5348 if (image != (Image *) NULL)
5349 s=newSVpv(image->magick,0);
5350 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5351 continue;
5352 }
5353 if (LocaleCompare(attribute,"map") == 0)
5354 {
5355 s=newSViv(GetMagickResource(MapResource));
5356 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5357 continue;
5358 }
5359 if (LocaleCompare(attribute,"maximum-error") == 0)
5360 {
5361 if (image != (Image *) NULL)
5362 s=newSVnv(image->error.normalized_maximum_error);
5363 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5364 continue;
5365 }
5366 if (LocaleCompare(attribute,"memory") == 0)
5367 {
5368 s=newSViv(GetMagickResource(MemoryResource));
5369 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5370 continue;
5371 }
5372 if (LocaleCompare(attribute,"mean-error") == 0)
5373 {
5374 if (image != (Image *) NULL)
5375 s=newSVnv(image->error.normalized_mean_error);
5376 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5377 continue;
5378 }
5379 if (LocaleCompare(attribute,"mime") == 0)
5380 {
5381 if (info && *info->image_info->magick)
5382 s=newSVpv(MagickToMime(info->image_info->magick),0);
5383 if (image != (Image *) NULL)
5384 s=newSVpv(MagickToMime(image->magick),0);
5385 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5386 continue;
5387 }
5388 if (LocaleCompare(attribute,"mattecolor") == 0)
5389 {
5390 if (image == (Image *) NULL)
5391 break;
cristy151b66d2015-04-15 10:50:31 +00005392 (void) FormatLocaleString(color,MagickPathExtent,
Cristy8645e042016-02-03 16:35:29 -05005393 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5394 (double) image->alpha_color.green,
5395 (double) image->alpha_color.blue,
5396 (double) image->alpha_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005397 s=newSVpv(color,0);
5398 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5399 continue;
5400 }
5401 if (LocaleCompare(attribute,"matte") == 0)
5402 {
5403 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005404 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005405 1 : 0);
5406 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5407 continue;
5408 }
5409 if (LocaleCompare(attribute,"mime") == 0)
5410 {
5411 const char
5412 *magick;
5413
5414 magick=NULL;
5415 if (info && *info->image_info->magick)
5416 magick=info->image_info->magick;
5417 if (image != (Image *) NULL)
5418 magick=image->magick;
5419 if (magick)
5420 {
5421 char
5422 *mime;
5423
5424 mime=MagickToMime(magick);
5425 s=newSVpv(mime,0);
5426 mime=(char *) RelinquishMagickMemory(mime);
5427 }
5428 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5429 continue;
5430 }
5431 if (LocaleCompare(attribute,"monochrome") == 0)
5432 {
5433 if (image == (Image *) NULL)
5434 continue;
5435 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005436 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005437 s=newSViv(j);
5438 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5439 continue;
5440 }
5441 if (LocaleCompare(attribute,"montage") == 0)
5442 {
5443 if (image && image->montage)
5444 s=newSVpv(image->montage,0);
5445 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5446 continue;
5447 }
5448 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5449 attribute);
5450 break;
5451 }
5452 case 'O':
5453 case 'o':
5454 {
5455 if (LocaleCompare(attribute,"orientation") == 0)
5456 {
5457 j=info ? info->image_info->orientation : image ?
5458 image->orientation : UndefinedOrientation;
5459 s=newSViv(j);
5460 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5461 j));
5462 SvIOK_on(s);
5463 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5464 continue;
5465 }
5466 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5467 attribute);
5468 break;
5469 }
5470 case 'P':
5471 case 'p':
5472 {
5473 if (LocaleCompare(attribute,"page") == 0)
5474 {
5475 if (info && info->image_info->page)
5476 s=newSVpv(info->image_info->page,0);
5477 if (image != (Image *) NULL)
5478 {
5479 char
cristy151b66d2015-04-15 10:50:31 +00005480 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005481
cristy151b66d2015-04-15 10:50:31 +00005482 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005483 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5484 (double) image->page.height,(double) image->page.x,(double)
5485 image->page.y);
5486 s=newSVpv(geometry,0);
5487 }
5488 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5489 continue;
5490 }
5491 if (LocaleCompare(attribute,"page.x") == 0)
5492 {
5493 if (image != (Image *) NULL)
5494 s=newSViv((ssize_t) image->page.x);
5495 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5496 continue;
5497 }
5498 if (LocaleCompare(attribute,"page.y") == 0)
5499 {
5500 if (image != (Image *) NULL)
5501 s=newSViv((ssize_t) image->page.y);
5502 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5503 continue;
5504 }
5505 if (LocaleNCompare(attribute,"pixel",5) == 0)
5506 {
5507 char
cristy151b66d2015-04-15 10:50:31 +00005508 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005509
5510 int
5511 items;
5512
5513 long
5514 x,
5515 y;
5516
5517 register const Quantum
5518 *p;
5519
5520 if (image == (Image *) NULL)
5521 break;
5522 x=0;
5523 y=0;
5524 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5525 (void) items;
5526 p=GetVirtualPixels(image,x,y,1,1,exception);
5527 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005528 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005529 QuantumFormat "," QuantumFormat "," QuantumFormat,
5530 GetPixelRed(image,p),GetPixelGreen(image,p),
5531 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5532 else
cristy151b66d2015-04-15 10:50:31 +00005533 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005534 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5535 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5536 GetPixelBlue(image,p),GetPixelBlack(image,p),
5537 GetPixelAlpha(image,p));
5538 s=newSVpv(tuple,0);
5539 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5540 continue;
5541 }
5542 if (LocaleCompare(attribute,"pointsize") == 0)
5543 {
5544 if (info)
5545 s=newSViv((ssize_t) info->image_info->pointsize);
5546 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5547 continue;
5548 }
cristy4a3ce0a2013-08-03 20:06:59 +00005549 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5550 attribute);
5551 break;
5552 }
5553 case 'Q':
5554 case 'q':
5555 {
5556 if (LocaleCompare(attribute,"quality") == 0)
5557 {
5558 if (info)
5559 s=newSViv((ssize_t) info->image_info->quality);
5560 if (image != (Image *) NULL)
5561 s=newSViv((ssize_t) image->quality);
5562 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5563 continue;
5564 }
5565 if (LocaleCompare(attribute,"quantum") == 0)
5566 {
5567 if (info)
5568 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5569 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5570 continue;
5571 }
5572 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5573 attribute);
5574 break;
5575 }
5576 case 'R':
5577 case 'r':
5578 {
5579 if (LocaleCompare(attribute,"rendering-intent") == 0)
5580 {
5581 s=newSViv(image->rendering_intent);
5582 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5583 image->rendering_intent));
5584 SvIOK_on(s);
5585 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5586 continue;
5587 }
5588 if (LocaleCompare(attribute,"red-primary") == 0)
5589 {
5590 if (image == (Image *) NULL)
5591 break;
Cristyb1710fe2017-02-11 13:51:48 -05005592 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005593 image->chromaticity.red_primary.x,
5594 image->chromaticity.red_primary.y);
5595 s=newSVpv(color,0);
5596 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5597 continue;
5598 }
5599 if (LocaleCompare(attribute,"rows") == 0)
5600 {
5601 if (image != (Image *) NULL)
5602 s=newSViv((ssize_t) image->rows);
5603 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5604 continue;
5605 }
5606 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5607 attribute);
5608 break;
5609 }
5610 case 'S':
5611 case 's':
5612 {
5613 if (LocaleCompare(attribute,"sampling-factor") == 0)
5614 {
5615 if (info && info->image_info->sampling_factor)
5616 s=newSVpv(info->image_info->sampling_factor,0);
5617 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5618 continue;
5619 }
5620 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5621 {
5622 if (info && info->image_info->server_name)
5623 s=newSVpv(info->image_info->server_name,0);
5624 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5625 continue;
5626 }
5627 if (LocaleCompare(attribute,"size") == 0)
5628 {
5629 if (info && info->image_info->size)
5630 s=newSVpv(info->image_info->size,0);
5631 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5632 continue;
5633 }
5634 if (LocaleCompare(attribute,"scene") == 0)
5635 {
5636 if (image != (Image *) NULL)
5637 s=newSViv((ssize_t) image->scene);
5638 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5639 continue;
5640 }
5641 if (LocaleCompare(attribute,"scenes") == 0)
5642 {
5643 if (image != (Image *) NULL)
5644 s=newSViv((ssize_t) info->image_info->number_scenes);
5645 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5646 continue;
5647 }
5648 if (LocaleCompare(attribute,"signature") == 0)
5649 {
5650 const char
5651 *value;
5652
5653 if (image == (Image *) NULL)
5654 break;
5655 (void) SignatureImage(image,exception);
5656 value=GetImageProperty(image,"Signature",exception);
5657 if (value != (const char *) NULL)
5658 s=newSVpv(value,0);
5659 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5660 continue;
5661 }
5662 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5663 attribute);
5664 break;
5665 }
5666 case 'T':
5667 case 't':
5668 {
5669 if (LocaleCompare(attribute,"taint") == 0)
5670 {
5671 if (image != (Image *) NULL)
5672 s=newSViv((ssize_t) IsTaintImage(image));
5673 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5674 continue;
5675 }
5676 if (LocaleCompare(attribute,"texture") == 0)
5677 {
5678 if (info && info->image_info->texture)
5679 s=newSVpv(info->image_info->texture,0);
5680 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5681 continue;
5682 }
5683 if (LocaleCompare(attribute,"total-ink-density") == 0)
5684 {
5685 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5686 if (image != (Image *) NULL)
5687 s=newSVnv(GetImageTotalInkDensity(image,exception));
5688 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5689 continue;
5690 }
5691 if (LocaleCompare(attribute,"transparent-color") == 0)
5692 {
5693 if (image == (Image *) NULL)
5694 break;
cristy151b66d2015-04-15 10:50:31 +00005695 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005696 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5697 (double) image->transparent_color.green,
5698 (double) image->transparent_color.blue,
5699 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005700 s=newSVpv(color,0);
5701 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5702 continue;
5703 }
5704 if (LocaleCompare(attribute,"type") == 0)
5705 {
5706 if (image == (Image *) NULL)
5707 break;
cristya26f54c2015-07-29 12:26:12 +00005708 j=(ssize_t) GetImageType(image);
cristy4a3ce0a2013-08-03 20:06:59 +00005709 s=newSViv(j);
5710 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5711 SvIOK_on(s);
5712 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5713 continue;
5714 }
5715 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5716 attribute);
5717 break;
5718 }
5719 case 'U':
5720 case 'u':
5721 {
5722 if (LocaleCompare(attribute,"units") == 0)
5723 {
5724 j=info ? info->image_info->units : image ? image->units :
5725 UndefinedResolution;
5726 if (info && (info->image_info->units == UndefinedResolution))
5727 if (image)
5728 j=image->units;
5729 if (j == UndefinedResolution)
5730 s=newSVpv("undefined units",0);
5731 else
5732 if (j == PixelsPerInchResolution)
5733 s=newSVpv("pixels / inch",0);
5734 else
5735 s=newSVpv("pixels / centimeter",0);
5736 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5737 continue;
5738 }
5739 if (LocaleCompare(attribute,"user-time") == 0)
5740 {
5741 if (image != (Image *) NULL)
5742 s=newSVnv(GetUserTime(&image->timer));
5743 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5744 continue;
5745 }
5746 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5747 attribute);
5748 break;
5749 }
5750 case 'V':
5751 case 'v':
5752 {
5753 if (LocaleCompare(attribute,"verbose") == 0)
5754 {
5755 if (info)
5756 s=newSViv((ssize_t) info->image_info->verbose);
5757 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5758 continue;
5759 }
5760 if (LocaleCompare(attribute,"version") == 0)
5761 {
5762 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5763 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5764 continue;
5765 }
cristy4a3ce0a2013-08-03 20:06:59 +00005766 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5767 {
5768 if (image == (Image *) NULL)
5769 break;
5770 j=(ssize_t) GetImageVirtualPixelMethod(image);
5771 s=newSViv(j);
5772 (void) sv_setpv(s,CommandOptionToMnemonic(
5773 MagickVirtualPixelOptions,j));
5774 SvIOK_on(s);
5775 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5776 continue;
5777 }
5778 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5779 attribute);
5780 break;
5781 }
5782 case 'W':
5783 case 'w':
5784 {
5785 if (LocaleCompare(attribute,"white-point") == 0)
5786 {
5787 if (image == (Image *) NULL)
5788 break;
Cristyb1710fe2017-02-11 13:51:48 -05005789 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005790 image->chromaticity.white_point.x,
5791 image->chromaticity.white_point.y);
5792 s=newSVpv(color,0);
5793 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5794 continue;
5795 }
5796 if (LocaleCompare(attribute,"width") == 0)
5797 {
5798 if (image != (Image *) NULL)
5799 s=newSViv((ssize_t) image->columns);
5800 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5801 continue;
5802 }
5803 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5804 attribute);
5805 break;
5806 }
5807 case 'X':
5808 case 'x':
5809 {
Cristyc1f9f9f2016-01-05 08:19:28 -05005810 if (LocaleCompare(attribute,"xmp") == 0)
5811 {
5812 if (image != (Image *) NULL)
5813 {
5814 const StringInfo
5815 *profile;
5816
5817 profile=GetImageProfile(image,"xmp");
5818 if (profile != (StringInfo *) NULL)
5819 s=newSVpv((const char *) GetStringInfoDatum(profile),
5820 GetStringInfoLength(profile));
5821 }
5822 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5823 continue;
5824 }
cristy4a3ce0a2013-08-03 20:06:59 +00005825 if (LocaleCompare(attribute,"x-resolution") == 0)
5826 {
5827 if (image != (Image *) NULL)
5828 s=newSVnv(image->resolution.x);
5829 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5830 continue;
5831 }
5832 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5833 attribute);
5834 break;
5835 }
5836 case 'Y':
5837 case 'y':
5838 {
5839 if (LocaleCompare(attribute,"y-resolution") == 0)
5840 {
5841 if (image != (Image *) NULL)
5842 s=newSVnv(image->resolution.y);
5843 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5844 continue;
5845 }
5846 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5847 attribute);
5848 break;
5849 }
5850 default:
5851 break;
5852 }
5853 if (image == (Image *) NULL)
5854 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5855 attribute)
5856 else
5857 {
5858 value=GetImageProperty(image,attribute,exception);
5859 if (value != (const char *) NULL)
5860 {
5861 s=newSVpv(value,0);
5862 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5863 }
5864 else
5865 if (*attribute != '%')
5866 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5867 attribute)
5868 else
5869 {
5870 char
5871 *meta;
5872
5873 meta=InterpretImageProperties(info ? info->image_info :
5874 (ImageInfo *) NULL,image,attribute,exception);
5875 s=newSVpv(meta,0);
5876 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5877 meta=(char *) RelinquishMagickMemory(meta);
5878 }
5879 }
5880 }
5881 exception=DestroyExceptionInfo(exception);
5882 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5883 }
5884
5885#
5886###############################################################################
5887# #
5888# #
5889# #
5890# G e t A u t h e n t i c P i x e l s #
5891# #
5892# #
5893# #
5894###############################################################################
5895#
5896#
5897void *
5898GetAuthenticPixels(ref,...)
5899 Image::Magick ref = NO_INIT
5900 ALIAS:
5901 getauthenticpixels = 1
5902 GetImagePixels = 2
5903 getimagepixels = 3
5904 CODE:
5905 {
5906 char
5907 *attribute;
5908
5909 ExceptionInfo
5910 *exception;
5911
5912 Image
5913 *image;
5914
5915 RectangleInfo
5916 region;
5917
5918 ssize_t
5919 i;
5920
5921 struct PackageInfo
5922 *info;
5923
5924 SV
5925 *perl_exception,
5926 *reference;
5927
5928 void
5929 *blob = NULL;
5930
5931 PERL_UNUSED_VAR(ref);
5932 PERL_UNUSED_VAR(ix);
5933 exception=AcquireExceptionInfo();
5934 perl_exception=newSVpv("",0);
5935 if (sv_isobject(ST(0)) == 0)
5936 {
5937 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5938 PackageName);
5939 goto PerlException;
5940 }
5941 reference=SvRV(ST(0));
5942
5943 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5944 if (image == (Image *) NULL)
5945 {
5946 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5947 PackageName);
5948 goto PerlException;
5949 }
5950
5951 region.x=0;
5952 region.y=0;
5953 region.width=image->columns;
5954 region.height=1;
5955 if (items == 1)
5956 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5957 for (i=2; i < items; i+=2)
5958 {
5959 attribute=(char *) SvPV(ST(i-1),na);
5960 switch (*attribute)
5961 {
5962 case 'g':
5963 case 'G':
5964 {
5965 if (LocaleCompare(attribute,"geometry") == 0)
5966 {
5967 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5968 break;
5969 }
5970 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5971 attribute);
5972 break;
5973 }
5974 case 'H':
5975 case 'h':
5976 {
5977 if (LocaleCompare(attribute,"height") == 0)
5978 {
5979 region.height=SvIV(ST(i));
5980 continue;
5981 }
5982 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5983 attribute);
5984 break;
5985 }
5986 case 'X':
5987 case 'x':
5988 {
5989 if (LocaleCompare(attribute,"x") == 0)
5990 {
5991 region.x=SvIV(ST(i));
5992 continue;
5993 }
5994 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5995 attribute);
5996 break;
5997 }
5998 case 'Y':
5999 case 'y':
6000 {
6001 if (LocaleCompare(attribute,"y") == 0)
6002 {
6003 region.y=SvIV(ST(i));
6004 continue;
6005 }
6006 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6007 attribute);
6008 break;
6009 }
6010 case 'W':
6011 case 'w':
6012 {
6013 if (LocaleCompare(attribute,"width") == 0)
6014 {
6015 region.width=SvIV(ST(i));
6016 continue;
6017 }
6018 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6019 attribute);
6020 break;
6021 }
6022 }
6023 }
6024 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
6025 region.height,exception);
6026 if (blob != (void *) NULL)
6027 goto PerlEnd;
6028
6029 PerlException:
6030 InheritPerlException(exception,perl_exception);
6031 exception=DestroyExceptionInfo(exception);
6032 SvREFCNT_dec(perl_exception); /* throw away all errors */
6033
6034 PerlEnd:
6035 RETVAL = blob;
6036 }
6037 OUTPUT:
6038 RETVAL
6039
6040#
6041###############################################################################
6042# #
6043# #
6044# #
6045# G e t V i r t u a l P i x e l s #
6046# #
6047# #
6048# #
6049###############################################################################
6050#
6051#
6052void *
6053GetVirtualPixels(ref,...)
6054 Image::Magick ref = NO_INIT
6055 ALIAS:
6056 getvirtualpixels = 1
6057 AcquireImagePixels = 2
6058 acquireimagepixels = 3
6059 CODE:
6060 {
6061 char
6062 *attribute;
6063
6064 const void
6065 *blob = NULL;
6066
6067 ExceptionInfo
6068 *exception;
6069
6070 Image
6071 *image;
6072
6073 RectangleInfo
6074 region;
6075
6076 ssize_t
6077 i;
6078
6079 struct PackageInfo
6080 *info;
6081
6082 SV
6083 *perl_exception,
6084 *reference;
6085
6086 PERL_UNUSED_VAR(ref);
6087 PERL_UNUSED_VAR(ix);
6088 exception=AcquireExceptionInfo();
6089 perl_exception=newSVpv("",0);
6090 if (sv_isobject(ST(0)) == 0)
6091 {
6092 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6093 PackageName);
6094 goto PerlException;
6095 }
6096 reference=SvRV(ST(0));
6097
6098 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6099 if (image == (Image *) NULL)
6100 {
6101 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6102 PackageName);
6103 goto PerlException;
6104 }
6105
6106 region.x=0;
6107 region.y=0;
6108 region.width=image->columns;
6109 region.height=1;
6110 if (items == 1)
6111 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6112 for (i=2; i < items; i+=2)
6113 {
6114 attribute=(char *) SvPV(ST(i-1),na);
6115 switch (*attribute)
6116 {
6117 case 'g':
6118 case 'G':
6119 {
6120 if (LocaleCompare(attribute,"geometry") == 0)
6121 {
6122 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6123 break;
6124 }
6125 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6126 attribute);
6127 break;
6128 }
6129 case 'H':
6130 case 'h':
6131 {
6132 if (LocaleCompare(attribute,"height") == 0)
6133 {
6134 region.height=SvIV(ST(i));
6135 continue;
6136 }
6137 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6138 attribute);
6139 break;
6140 }
6141 case 'X':
6142 case 'x':
6143 {
6144 if (LocaleCompare(attribute,"x") == 0)
6145 {
6146 region.x=SvIV(ST(i));
6147 continue;
6148 }
6149 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6150 attribute);
6151 break;
6152 }
6153 case 'Y':
6154 case 'y':
6155 {
6156 if (LocaleCompare(attribute,"y") == 0)
6157 {
6158 region.y=SvIV(ST(i));
6159 continue;
6160 }
6161 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6162 attribute);
6163 break;
6164 }
6165 case 'W':
6166 case 'w':
6167 {
6168 if (LocaleCompare(attribute,"width") == 0)
6169 {
6170 region.width=SvIV(ST(i));
6171 continue;
6172 }
6173 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6174 attribute);
6175 break;
6176 }
6177 }
6178 }
6179 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6180 region.height,exception);
6181 if (blob != (void *) NULL)
6182 goto PerlEnd;
6183
6184 PerlException:
6185 InheritPerlException(exception,perl_exception);
6186 exception=DestroyExceptionInfo(exception);
6187 SvREFCNT_dec(perl_exception); /* throw away all errors */
6188
6189 PerlEnd:
6190 RETVAL = (void *) blob;
6191 }
6192 OUTPUT:
6193 RETVAL
6194
6195#
6196###############################################################################
6197# #
6198# #
6199# #
6200# G e t A u t h e n t i c M e t a c o n t e n t #
6201# #
6202# #
6203# #
6204###############################################################################
6205#
6206#
6207void *
6208GetAuthenticMetacontent(ref,...)
6209 Image::Magick ref = NO_INIT
6210 ALIAS:
6211 getauthenticmetacontent = 1
6212 GetMetacontent = 2
6213 getmetacontent = 3
6214 CODE:
6215 {
6216 ExceptionInfo
6217 *exception;
6218
6219 Image
6220 *image;
6221
6222 struct PackageInfo
6223 *info;
6224
6225 SV
6226 *perl_exception,
6227 *reference;
6228
6229 void
6230 *blob = NULL;
6231
6232 PERL_UNUSED_VAR(ref);
6233 PERL_UNUSED_VAR(ix);
6234 exception=AcquireExceptionInfo();
6235 perl_exception=newSVpv("",0);
6236 if (sv_isobject(ST(0)) == 0)
6237 {
6238 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6239 PackageName);
6240 goto PerlException;
6241 }
6242 reference=SvRV(ST(0));
6243
6244 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6245 if (image == (Image *) NULL)
6246 {
6247 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6248 PackageName);
6249 goto PerlException;
6250 }
6251
6252 blob=(void *) GetAuthenticMetacontent(image);
6253 if (blob != (void *) NULL)
6254 goto PerlEnd;
6255
6256 PerlException:
6257 InheritPerlException(exception,perl_exception);
6258 exception=DestroyExceptionInfo(exception);
6259 SvREFCNT_dec(perl_exception); /* throw away all errors */
6260
6261 PerlEnd:
6262 RETVAL = blob;
6263 }
6264 OUTPUT:
6265 RETVAL
6266
6267#
6268###############################################################################
6269# #
6270# #
6271# #
6272# G e t V i r t u a l M e t a c o n t e n t #
6273# #
6274# #
6275# #
6276###############################################################################
6277#
6278#
6279void *
6280GetVirtualMetacontent(ref,...)
6281 Image::Magick ref = NO_INIT
6282 ALIAS:
6283 getvirtualmetacontent = 1
6284 CODE:
6285 {
6286 ExceptionInfo
6287 *exception;
6288
6289 Image
6290 *image;
6291
6292 struct PackageInfo
6293 *info;
6294
6295 SV
6296 *perl_exception,
6297 *reference;
6298
6299 void
6300 *blob = NULL;
6301
6302 PERL_UNUSED_VAR(ref);
6303 PERL_UNUSED_VAR(ix);
6304 exception=AcquireExceptionInfo();
6305 perl_exception=newSVpv("",0);
6306 if (sv_isobject(ST(0)) == 0)
6307 {
6308 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6309 PackageName);
6310 goto PerlException;
6311 }
6312 reference=SvRV(ST(0));
6313
6314 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6315 if (image == (Image *) NULL)
6316 {
6317 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6318 PackageName);
6319 goto PerlException;
6320 }
6321
6322 blob=(void *) GetVirtualMetacontent(image);
6323 if (blob != (void *) NULL)
6324 goto PerlEnd;
6325
6326 PerlException:
6327 InheritPerlException(exception,perl_exception);
6328 exception=DestroyExceptionInfo(exception);
6329 SvREFCNT_dec(perl_exception); /* throw away all errors */
6330
6331 PerlEnd:
6332 RETVAL = blob;
6333 }
6334 OUTPUT:
6335 RETVAL
6336
6337#
6338###############################################################################
6339# #
6340# #
6341# #
6342# H i s t o g r a m #
6343# #
6344# #
6345# #
6346###############################################################################
6347#
6348#
6349void
6350Histogram(ref,...)
6351 Image::Magick ref=NO_INIT
6352 ALIAS:
6353 HistogramImage = 1
6354 histogram = 2
6355 histogramimage = 3
6356 PPCODE:
6357 {
6358 AV
6359 *av;
6360
6361 char
cristy151b66d2015-04-15 10:50:31 +00006362 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006363
6364 PixelInfo
6365 *histogram;
6366
6367 ExceptionInfo
6368 *exception;
6369
6370 Image
6371 *image;
6372
6373 register ssize_t
6374 i;
6375
6376 ssize_t
6377 count;
6378
6379 struct PackageInfo
6380 *info;
6381
6382 SV
6383 *perl_exception,
6384 *reference;
6385
6386 size_t
6387 number_colors;
6388
6389 PERL_UNUSED_VAR(ref);
6390 PERL_UNUSED_VAR(ix);
6391 exception=AcquireExceptionInfo();
6392 perl_exception=newSVpv("",0);
6393 av=NULL;
6394 if (sv_isobject(ST(0)) == 0)
6395 {
6396 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6397 PackageName);
6398 goto PerlException;
6399 }
6400 reference=SvRV(ST(0));
6401 av=newAV();
6402 SvREFCNT_dec(av);
6403 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6404 if (image == (Image *) NULL)
6405 {
6406 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6407 PackageName);
6408 goto PerlException;
6409 }
cristy4a3ce0a2013-08-03 20:06:59 +00006410 count=0;
6411 for ( ; image; image=image->next)
6412 {
6413 histogram=GetImageHistogram(image,&number_colors,exception);
6414 if (histogram == (PixelInfo *) NULL)
6415 continue;
6416 count+=(ssize_t) number_colors;
6417 EXTEND(sp,6*count);
6418 for (i=0; i < (ssize_t) number_colors; i++)
6419 {
cristy151b66d2015-04-15 10:50:31 +00006420 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006421 histogram[i].red);
6422 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006423 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006424 histogram[i].green);
6425 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006426 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006427 histogram[i].blue);
6428 PUSHs(sv_2mortal(newSVpv(message,0)));
6429 if (image->colorspace == CMYKColorspace)
6430 {
cristy151b66d2015-04-15 10:50:31 +00006431 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006432 histogram[i].black);
6433 PUSHs(sv_2mortal(newSVpv(message,0)));
6434 }
cristy151b66d2015-04-15 10:50:31 +00006435 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006436 histogram[i].alpha);
6437 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006438 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006439 histogram[i].count);
6440 PUSHs(sv_2mortal(newSVpv(message,0)));
6441 }
6442 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6443 }
6444
6445 PerlException:
6446 InheritPerlException(exception,perl_exception);
6447 exception=DestroyExceptionInfo(exception);
6448 SvREFCNT_dec(perl_exception);
6449 }
6450
6451#
6452###############################################################################
6453# #
6454# #
6455# #
6456# G e t P i x e l #
6457# #
6458# #
6459# #
6460###############################################################################
6461#
6462#
6463void
6464GetPixel(ref,...)
6465 Image::Magick ref=NO_INIT
6466 ALIAS:
6467 getpixel = 1
6468 getPixel = 2
6469 PPCODE:
6470 {
6471 AV
6472 *av;
6473
6474 char
6475 *attribute;
6476
6477 ExceptionInfo
6478 *exception;
6479
6480 Image
6481 *image;
6482
6483 MagickBooleanType
6484 normalize;
6485
6486 RectangleInfo
6487 region;
6488
6489 register const Quantum
6490 *p;
6491
6492 register ssize_t
6493 i;
6494
6495 ssize_t
6496 option;
6497
6498 struct PackageInfo
6499 *info;
6500
6501 SV
6502 *perl_exception,
6503 *reference; /* reference is the SV* of ref=SvIV(reference) */
6504
6505 PERL_UNUSED_VAR(ref);
6506 PERL_UNUSED_VAR(ix);
6507 exception=AcquireExceptionInfo();
6508 perl_exception=newSVpv("",0);
6509 reference=SvRV(ST(0));
6510 av=(AV *) reference;
6511 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6512 exception);
6513 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6514 if (image == (Image *) NULL)
6515 {
6516 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6517 PackageName);
6518 goto PerlException;
6519 }
6520 normalize=MagickTrue;
6521 region.x=0;
6522 region.y=0;
6523 region.width=image->columns;
6524 region.height=1;
6525 if (items == 1)
6526 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6527 for (i=2; i < items; i+=2)
6528 {
6529 attribute=(char *) SvPV(ST(i-1),na);
6530 switch (*attribute)
6531 {
6532 case 'C':
6533 case 'c':
6534 {
6535 if (LocaleCompare(attribute,"channel") == 0)
6536 {
6537 ssize_t
6538 option;
6539
6540 option=ParseChannelOption(SvPV(ST(i),na));
6541 if (option < 0)
6542 {
6543 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6544 SvPV(ST(i),na));
6545 return;
6546 }
cristybcd59342015-06-07 14:07:19 +00006547 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00006548 break;
6549 }
6550 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6551 attribute);
6552 break;
6553 }
6554 case 'g':
6555 case 'G':
6556 {
6557 if (LocaleCompare(attribute,"geometry") == 0)
6558 {
6559 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6560 break;
6561 }
6562 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6563 attribute);
6564 break;
6565 }
6566 case 'N':
6567 case 'n':
6568 {
6569 if (LocaleCompare(attribute,"normalize") == 0)
6570 {
6571 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6572 SvPV(ST(i),na));
6573 if (option < 0)
6574 {
6575 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6576 SvPV(ST(i),na));
6577 break;
6578 }
6579 normalize=option != 0 ? MagickTrue : MagickFalse;
6580 break;
6581 }
6582 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6583 attribute);
6584 break;
6585 }
6586 case 'x':
6587 case 'X':
6588 {
6589 if (LocaleCompare(attribute,"x") == 0)
6590 {
6591 region.x=SvIV(ST(i));
6592 break;
6593 }
6594 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6595 attribute);
6596 break;
6597 }
6598 case 'y':
6599 case 'Y':
6600 {
6601 if (LocaleCompare(attribute,"y") == 0)
6602 {
6603 region.y=SvIV(ST(i));
6604 break;
6605 }
6606 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6607 attribute);
6608 break;
6609 }
6610 default:
6611 {
6612 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6613 attribute);
6614 break;
6615 }
6616 }
6617 }
6618 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6619 if (p == (const Quantum *) NULL)
6620 PUSHs(&sv_undef);
6621 else
6622 {
6623 double
6624 scale;
6625
6626 scale=1.0;
6627 if (normalize != MagickFalse)
6628 scale=1.0/QuantumRange;
6629 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6630 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6631 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6632 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6633 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6634 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6635 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6636 (image->colorspace == CMYKColorspace))
6637 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6638 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6639 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6640 }
6641
6642 PerlException:
6643 InheritPerlException(exception,perl_exception);
6644 exception=DestroyExceptionInfo(exception);
6645 SvREFCNT_dec(perl_exception);
6646 }
6647
6648#
6649###############################################################################
6650# #
6651# #
6652# #
6653# G e t P i x e l s #
6654# #
6655# #
6656# #
6657###############################################################################
6658#
6659#
6660void
6661GetPixels(ref,...)
6662 Image::Magick ref=NO_INIT
6663 ALIAS:
6664 getpixels = 1
6665 getPixels = 2
6666 PPCODE:
6667 {
6668 AV
6669 *av;
6670
6671 char
6672 *attribute;
6673
6674 const char
6675 *map;
6676
6677 ExceptionInfo
6678 *exception;
6679
6680 Image
6681 *image;
6682
6683 MagickBooleanType
6684 normalize,
6685 status;
6686
6687 RectangleInfo
6688 region;
6689
6690 register ssize_t
6691 i;
6692
6693 ssize_t
6694 option;
6695
6696 struct PackageInfo
6697 *info;
6698
6699 SV
6700 *perl_exception,
6701 *reference; /* reference is the SV* of ref=SvIV(reference) */
6702
6703 PERL_UNUSED_VAR(ref);
6704 PERL_UNUSED_VAR(ix);
6705 exception=AcquireExceptionInfo();
6706 perl_exception=newSVpv("",0);
6707 reference=SvRV(ST(0));
6708 av=(AV *) reference;
6709 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6710 exception);
6711 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6712 if (image == (Image *) NULL)
6713 {
6714 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6715 PackageName);
6716 goto PerlException;
6717 }
6718 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006719 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006720 map="RGBA";
6721 if (image->colorspace == CMYKColorspace)
6722 {
6723 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006724 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006725 map="CMYKA";
6726 }
6727 normalize=MagickFalse;
6728 region.x=0;
6729 region.y=0;
6730 region.width=image->columns;
6731 region.height=1;
6732 if (items == 1)
6733 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6734 for (i=2; i < items; i+=2)
6735 {
6736 attribute=(char *) SvPV(ST(i-1),na);
6737 switch (*attribute)
6738 {
6739 case 'g':
6740 case 'G':
6741 {
6742 if (LocaleCompare(attribute,"geometry") == 0)
6743 {
6744 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6745 break;
6746 }
6747 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6748 attribute);
6749 break;
6750 }
6751 case 'H':
6752 case 'h':
6753 {
6754 if (LocaleCompare(attribute,"height") == 0)
6755 {
6756 region.height=SvIV(ST(i));
6757 break;
6758 }
6759 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6760 attribute);
6761 break;
6762 }
6763 case 'M':
6764 case 'm':
6765 {
6766 if (LocaleCompare(attribute,"map") == 0)
6767 {
6768 map=SvPV(ST(i),na);
6769 break;
6770 }
6771 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6772 attribute);
6773 break;
6774 }
6775 case 'N':
6776 case 'n':
6777 {
6778 if (LocaleCompare(attribute,"normalize") == 0)
6779 {
6780 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6781 SvPV(ST(i),na));
6782 if (option < 0)
6783 {
6784 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6785 SvPV(ST(i),na));
6786 break;
6787 }
6788 normalize=option != 0 ? MagickTrue : MagickFalse;
6789 break;
6790 }
6791 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6792 attribute);
6793 break;
6794 }
6795 case 'W':
6796 case 'w':
6797 {
6798 if (LocaleCompare(attribute,"width") == 0)
6799 {
6800 region.width=SvIV(ST(i));
6801 break;
6802 }
6803 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6804 attribute);
6805 break;
6806 }
6807 case 'x':
6808 case 'X':
6809 {
6810 if (LocaleCompare(attribute,"x") == 0)
6811 {
6812 region.x=SvIV(ST(i));
6813 break;
6814 }
6815 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6816 attribute);
6817 break;
6818 }
6819 case 'y':
6820 case 'Y':
6821 {
6822 if (LocaleCompare(attribute,"y") == 0)
6823 {
6824 region.y=SvIV(ST(i));
6825 break;
6826 }
6827 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6828 attribute);
6829 break;
6830 }
6831 default:
6832 {
6833 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6834 attribute);
6835 break;
6836 }
6837 }
6838 }
6839 if (normalize != MagickFalse)
6840 {
6841 float
6842 *pixels;
6843
6844 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6845 region.height*sizeof(*pixels));
6846 if (pixels == (float *) NULL)
6847 {
6848 ThrowPerlException(exception,ResourceLimitError,
6849 "MemoryAllocationFailed",PackageName);
6850 goto PerlException;
6851 }
6852 status=ExportImagePixels(image,region.x,region.y,region.width,
6853 region.height,map,FloatPixel,pixels,exception);
6854 if (status == MagickFalse)
6855 PUSHs(&sv_undef);
6856 else
6857 {
6858 EXTEND(sp,strlen(map)*region.width*region.height);
6859 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6860 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6861 }
6862 pixels=(float *) RelinquishMagickMemory(pixels);
6863 }
6864 else
6865 {
6866 Quantum
6867 *pixels;
6868
6869 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6870 region.height*sizeof(*pixels));
6871 if (pixels == (Quantum *) NULL)
6872 {
6873 ThrowPerlException(exception,ResourceLimitError,
6874 "MemoryAllocationFailed",PackageName);
6875 goto PerlException;
6876 }
6877 status=ExportImagePixels(image,region.x,region.y,region.width,
6878 region.height,map,QuantumPixel,pixels,exception);
6879 if (status == MagickFalse)
6880 PUSHs(&sv_undef);
6881 else
6882 {
6883 EXTEND(sp,strlen(map)*region.width*region.height);
6884 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6885 PUSHs(sv_2mortal(newSViv(pixels[i])));
6886 }
6887 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6888 }
6889
6890 PerlException:
6891 InheritPerlException(exception,perl_exception);
6892 exception=DestroyExceptionInfo(exception);
6893 SvREFCNT_dec(perl_exception);
6894 }
6895
6896#
6897###############################################################################
6898# #
6899# #
6900# #
6901# I m a g e T o B l o b #
6902# #
6903# #
6904# #
6905###############################################################################
6906#
6907#
6908void
6909ImageToBlob(ref,...)
6910 Image::Magick ref=NO_INIT
6911 ALIAS:
6912 ImageToBlob = 1
6913 imagetoblob = 2
6914 toblob = 3
6915 blob = 4
6916 PPCODE:
6917 {
6918 char
cristy151b66d2015-04-15 10:50:31 +00006919 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006920
6921 ExceptionInfo
6922 *exception;
6923
6924 Image
6925 *image,
6926 *next;
6927
6928 register ssize_t
6929 i;
6930
6931 struct PackageInfo
6932 *info,
6933 *package_info;
6934
6935 size_t
6936 length;
6937
6938 ssize_t
6939 scene;
6940
6941 SV
6942 *perl_exception,
6943 *reference;
6944
6945 void
6946 *blob;
6947
6948 PERL_UNUSED_VAR(ref);
6949 PERL_UNUSED_VAR(ix);
6950 exception=AcquireExceptionInfo();
6951 perl_exception=newSVpv("",0);
6952 package_info=(struct PackageInfo *) NULL;
6953 if (sv_isobject(ST(0)) == 0)
6954 {
6955 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6956 PackageName);
6957 goto PerlException;
6958 }
6959 reference=SvRV(ST(0));
6960 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6961 if (image == (Image *) NULL)
6962 {
6963 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6964 PackageName);
6965 goto PerlException;
6966 }
6967 package_info=ClonePackageInfo(info,exception);
6968 for (i=2; i < items; i+=2)
6969 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6970 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006971 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006972 scene=0;
6973 for (next=image; next; next=next->next)
6974 {
cristy151b66d2015-04-15 10:50:31 +00006975 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006976 next->scene=scene++;
6977 }
6978 SetImageInfo(package_info->image_info,(unsigned int)
6979 GetImageListLength(image),exception);
6980 EXTEND(sp,(ssize_t) GetImageListLength(image));
6981 for ( ; image; image=image->next)
6982 {
6983 length=0;
6984 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6985 if (blob != (char *) NULL)
6986 {
6987 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6988 blob=(unsigned char *) RelinquishMagickMemory(blob);
6989 }
6990 if (package_info->image_info->adjoin)
6991 break;
6992 }
6993
6994 PerlException:
6995 if (package_info != (struct PackageInfo *) NULL)
6996 DestroyPackageInfo(package_info);
6997 InheritPerlException(exception,perl_exception);
6998 exception=DestroyExceptionInfo(exception);
6999 SvREFCNT_dec(perl_exception); /* throw away all errors */
7000 }
7001
7002#
7003###############################################################################
7004# #
7005# #
7006# #
7007# L a y e r s #
7008# #
7009# #
7010# #
7011###############################################################################
7012#
7013#
7014void
7015Layers(ref,...)
7016 Image::Magick ref=NO_INIT
7017 ALIAS:
7018 Layers = 1
7019 layers = 2
7020 OptimizeImageLayers = 3
7021 optimizelayers = 4
7022 optimizeimagelayers = 5
7023 PPCODE:
7024 {
7025 AV
7026 *av;
7027
7028 char
7029 *attribute;
7030
7031 CompositeOperator
7032 compose;
7033
7034 ExceptionInfo
7035 *exception;
7036
7037 HV
7038 *hv;
7039
7040 Image
7041 *image,
7042 *layers;
7043
7044 LayerMethod
7045 method;
7046
7047 register ssize_t
7048 i;
7049
7050 ssize_t
7051 option,
7052 sp;
7053
7054 struct PackageInfo
7055 *info;
7056
7057 SV
7058 *av_reference,
7059 *perl_exception,
7060 *reference,
7061 *rv,
7062 *sv;
7063
7064 PERL_UNUSED_VAR(ref);
7065 PERL_UNUSED_VAR(ix);
7066 exception=AcquireExceptionInfo();
7067 perl_exception=newSVpv("",0);
7068 sv=NULL;
7069 if (sv_isobject(ST(0)) == 0)
7070 {
7071 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7072 PackageName);
7073 goto PerlException;
7074 }
7075 reference=SvRV(ST(0));
7076 hv=SvSTASH(reference);
7077 av=newAV();
7078 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7079 SvREFCNT_dec(av);
7080 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7081 if (image == (Image *) NULL)
7082 {
7083 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7084 PackageName);
7085 goto PerlException;
7086 }
7087 compose=image->compose;
7088 method=OptimizeLayer;
7089 for (i=2; i < items; i+=2)
7090 {
7091 attribute=(char *) SvPV(ST(i-1),na);
7092 switch (*attribute)
7093 {
7094 case 'C':
7095 case 'c':
7096 {
7097 if (LocaleCompare(attribute,"compose") == 0)
7098 {
7099 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7100 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7101 if (sp < 0)
7102 {
7103 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7104 SvPV(ST(i),na));
7105 break;
7106 }
7107 compose=(CompositeOperator) sp;
7108 break;
7109 }
7110 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7111 attribute);
7112 break;
7113 }
7114 case 'M':
7115 case 'm':
7116 {
7117 if (LocaleCompare(attribute,"method") == 0)
7118 {
7119 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7120 SvPV(ST(i),na));
7121 if (option < 0)
7122 {
7123 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7124 SvPV(ST(i),na));
7125 break;
7126 }
7127 method=(LayerMethod) option;
7128 break;
7129 }
7130 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7131 attribute);
7132 break;
7133 }
7134 default:
7135 {
7136 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7137 attribute);
7138 break;
7139 }
7140 }
7141 }
7142 layers=(Image *) NULL;
7143 switch (method)
7144 {
7145 case CompareAnyLayer:
7146 case CompareClearLayer:
7147 case CompareOverlayLayer:
7148 default:
7149 {
7150 layers=CompareImagesLayers(image,method,exception);
7151 break;
7152 }
7153 case MergeLayer:
7154 case FlattenLayer:
7155 case MosaicLayer:
7156 {
7157 layers=MergeImageLayers(image,method,exception);
7158 break;
7159 }
7160 case DisposeLayer:
7161 {
7162 layers=DisposeImages(image,exception);
7163 break;
7164 }
7165 case OptimizeImageLayer:
7166 {
7167 layers=OptimizeImageLayers(image,exception);
7168 break;
7169 }
7170 case OptimizePlusLayer:
7171 {
7172 layers=OptimizePlusImageLayers(image,exception);
7173 break;
7174 }
7175 case OptimizeTransLayer:
7176 {
7177 OptimizeImageTransparency(image,exception);
7178 break;
7179 }
7180 case RemoveDupsLayer:
7181 {
7182 RemoveDuplicateLayers(&image,exception);
7183 break;
7184 }
7185 case RemoveZeroLayer:
7186 {
7187 RemoveZeroDelayLayers(&image,exception);
7188 break;
7189 }
7190 case OptimizeLayer:
7191 {
7192 QuantizeInfo
7193 *quantize_info;
7194
7195 /*
7196 General Purpose, GIF Animation Optimizer.
7197 */
7198 layers=CoalesceImages(image,exception);
7199 if (layers == (Image *) NULL)
7200 break;
7201 image=layers;
7202 layers=OptimizeImageLayers(image,exception);
7203 if (layers == (Image *) NULL)
7204 break;
7205 image=DestroyImageList(image);
7206 image=layers;
7207 layers=(Image *) NULL;
7208 OptimizeImageTransparency(image,exception);
7209 quantize_info=AcquireQuantizeInfo(info->image_info);
7210 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7211 quantize_info=DestroyQuantizeInfo(quantize_info);
7212 break;
7213 }
7214 case CompositeLayer:
7215 {
7216 Image
7217 *source;
7218
7219 RectangleInfo
7220 geometry;
7221
7222 /*
7223 Split image sequence at the first 'NULL:' image.
7224 */
7225 source=image;
7226 while (source != (Image *) NULL)
7227 {
7228 source=GetNextImageInList(source);
7229 if ((source != (Image *) NULL) &&
7230 (LocaleCompare(source->magick,"NULL") == 0))
7231 break;
7232 }
7233 if (source != (Image *) NULL)
7234 {
7235 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7236 (GetNextImageInList(source) == (Image *) NULL))
7237 source=(Image *) NULL;
7238 else
7239 {
7240 /*
7241 Separate the two lists, junk the null: image.
7242 */
7243 source=SplitImageList(source->previous);
7244 DeleteImageFromList(&source);
7245 }
7246 }
7247 if (source == (Image *) NULL)
7248 {
7249 (void) ThrowMagickException(exception,GetMagickModule(),
7250 OptionError,"MissingNullSeparator","layers Composite");
7251 break;
7252 }
7253 /*
7254 Adjust offset with gravity and virtual canvas.
7255 */
7256 SetGeometry(image,&geometry);
7257 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7258 geometry.width=source->page.width != 0 ? source->page.width :
7259 source->columns;
7260 geometry.height=source->page.height != 0 ? source->page.height :
7261 source->rows;
7262 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7263 image->columns,image->page.height != 0 ? image->page.height :
7264 image->rows,image->gravity,&geometry);
7265 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7266 source=DestroyImageList(source);
7267 break;
7268 }
7269 }
7270 if (layers != (Image *) NULL)
7271 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007272 else
7273 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007274 if (image == (Image *) NULL)
7275 goto PerlException;
7276 for ( ; image; image=image->next)
7277 {
7278 AddImageToRegistry(sv,image);
7279 rv=newRV(sv);
7280 av_push(av,sv_bless(rv,hv));
7281 SvREFCNT_dec(sv);
7282 }
7283 exception=DestroyExceptionInfo(exception);
7284 ST(0)=av_reference;
7285 SvREFCNT_dec(perl_exception);
7286 XSRETURN(1);
7287
7288 PerlException:
7289 InheritPerlException(exception,perl_exception);
7290 exception=DestroyExceptionInfo(exception);
7291 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7292 SvPOK_on(perl_exception);
7293 ST(0)=sv_2mortal(perl_exception);
7294 XSRETURN(1);
7295 }
7296
7297#
7298###############################################################################
7299# #
7300# #
7301# #
7302# M a g i c k T o M i m e #
7303# #
7304# #
7305# #
7306###############################################################################
7307#
7308#
7309SV *
7310MagickToMime(ref,name)
7311 Image::Magick ref=NO_INIT
7312 char *name
7313 ALIAS:
7314 magicktomime = 1
7315 CODE:
7316 {
7317 char
7318 *mime;
7319
7320 PERL_UNUSED_VAR(ref);
7321 PERL_UNUSED_VAR(ix);
7322 mime=MagickToMime(name);
7323 RETVAL=newSVpv(mime,0);
7324 mime=(char *) RelinquishMagickMemory(mime);
7325 }
7326 OUTPUT:
7327 RETVAL
7328
7329#
7330###############################################################################
7331# #
7332# #
7333# #
7334# M o g r i f y #
7335# #
7336# #
7337# #
7338###############################################################################
7339#
7340#
7341void
7342Mogrify(ref,...)
7343 Image::Magick ref=NO_INIT
7344 ALIAS:
7345 Comment = 1
7346 CommentImage = 2
7347 Label = 3
7348 LabelImage = 4
7349 AddNoise = 5
7350 AddNoiseImage = 6
7351 Colorize = 7
7352 ColorizeImage = 8
7353 Border = 9
7354 BorderImage = 10
7355 Blur = 11
7356 BlurImage = 12
7357 Chop = 13
7358 ChopImage = 14
7359 Crop = 15
7360 CropImage = 16
7361 Despeckle = 17
7362 DespeckleImage = 18
7363 Edge = 19
7364 EdgeImage = 20
7365 Emboss = 21
7366 EmbossImage = 22
7367 Enhance = 23
7368 EnhanceImage = 24
7369 Flip = 25
7370 FlipImage = 26
7371 Flop = 27
7372 FlopImage = 28
7373 Frame = 29
7374 FrameImage = 30
7375 Implode = 31
7376 ImplodeImage = 32
7377 Magnify = 33
7378 MagnifyImage = 34
7379 MedianFilter = 35
7380 MedianConvolveImage = 36
7381 Minify = 37
7382 MinifyImage = 38
7383 OilPaint = 39
7384 OilPaintImage = 40
7385 ReduceNoise = 41
7386 ReduceNoiseImage = 42
7387 Roll = 43
7388 RollImage = 44
7389 Rotate = 45
7390 RotateImage = 46
7391 Sample = 47
7392 SampleImage = 48
7393 Scale = 49
7394 ScaleImage = 50
7395 Shade = 51
7396 ShadeImage = 52
7397 Sharpen = 53
7398 SharpenImage = 54
7399 Shear = 55
7400 ShearImage = 56
7401 Spread = 57
7402 SpreadImage = 58
7403 Swirl = 59
7404 SwirlImage = 60
7405 Resize = 61
7406 ResizeImage = 62
7407 Zoom = 63
7408 ZoomImage = 64
7409 Annotate = 65
7410 AnnotateImage = 66
7411 ColorFloodfill = 67
7412 ColorFloodfillImage= 68
7413 Composite = 69
7414 CompositeImage = 70
7415 Contrast = 71
7416 ContrastImage = 72
7417 CycleColormap = 73
7418 CycleColormapImage = 74
7419 Draw = 75
7420 DrawImage = 76
7421 Equalize = 77
7422 EqualizeImage = 78
7423 Gamma = 79
7424 GammaImage = 80
7425 Map = 81
7426 MapImage = 82
7427 MatteFloodfill = 83
7428 MatteFloodfillImage= 84
7429 Modulate = 85
7430 ModulateImage = 86
7431 Negate = 87
7432 NegateImage = 88
7433 Normalize = 89
7434 NormalizeImage = 90
7435 NumberColors = 91
7436 NumberColorsImage = 92
7437 Opaque = 93
7438 OpaqueImage = 94
7439 Quantize = 95
7440 QuantizeImage = 96
7441 Raise = 97
7442 RaiseImage = 98
7443 Segment = 99
7444 SegmentImage = 100
7445 Signature = 101
7446 SignatureImage = 102
7447 Solarize = 103
7448 SolarizeImage = 104
7449 Sync = 105
7450 SyncImage = 106
7451 Texture = 107
7452 TextureImage = 108
7453 Evaluate = 109
7454 EvaluateImage = 110
7455 Transparent = 111
7456 TransparentImage = 112
7457 Threshold = 113
7458 ThresholdImage = 114
7459 Charcoal = 115
7460 CharcoalImage = 116
7461 Trim = 117
7462 TrimImage = 118
7463 Wave = 119
7464 WaveImage = 120
7465 Separate = 121
7466 SeparateImage = 122
7467 Stereo = 125
7468 StereoImage = 126
7469 Stegano = 127
7470 SteganoImage = 128
7471 Deconstruct = 129
7472 DeconstructImage = 130
7473 GaussianBlur = 131
7474 GaussianBlurImage = 132
7475 Convolve = 133
7476 ConvolveImage = 134
7477 Profile = 135
7478 ProfileImage = 136
7479 UnsharpMask = 137
7480 UnsharpMaskImage = 138
7481 MotionBlur = 139
7482 MotionBlurImage = 140
7483 OrderedDither = 141
7484 OrderedDitherImage = 142
7485 Shave = 143
7486 ShaveImage = 144
7487 Level = 145
7488 LevelImage = 146
7489 Clip = 147
7490 ClipImage = 148
7491 AffineTransform = 149
7492 AffineTransformImage = 150
7493 Difference = 151
7494 DifferenceImage = 152
7495 AdaptiveThreshold = 153
7496 AdaptiveThresholdImage = 154
7497 Resample = 155
7498 ResampleImage = 156
7499 Describe = 157
7500 DescribeImage = 158
7501 BlackThreshold = 159
7502 BlackThresholdImage= 160
7503 WhiteThreshold = 161
7504 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007505 RotationalBlur = 163
7506 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007507 Thumbnail = 165
7508 ThumbnailImage = 166
7509 Strip = 167
7510 StripImage = 168
7511 Tint = 169
7512 TintImage = 170
7513 Channel = 171
7514 ChannelImage = 172
7515 Splice = 173
7516 SpliceImage = 174
7517 Posterize = 175
7518 PosterizeImage = 176
7519 Shadow = 177
7520 ShadowImage = 178
7521 Identify = 179
7522 IdentifyImage = 180
7523 SepiaTone = 181
7524 SepiaToneImage = 182
7525 SigmoidalContrast = 183
7526 SigmoidalContrastImage = 184
7527 Extent = 185
7528 ExtentImage = 186
7529 Vignette = 187
7530 VignetteImage = 188
7531 ContrastStretch = 189
7532 ContrastStretchImage = 190
7533 Sans0 = 191
7534 Sans0Image = 192
7535 Sans1 = 193
7536 Sans1Image = 194
7537 AdaptiveSharpen = 195
7538 AdaptiveSharpenImage = 196
7539 Transpose = 197
7540 TransposeImage = 198
7541 Transverse = 199
7542 TransverseImage = 200
7543 AutoOrient = 201
7544 AutoOrientImage = 202
7545 AdaptiveBlur = 203
7546 AdaptiveBlurImage = 204
7547 Sketch = 205
7548 SketchImage = 206
7549 UniqueColors = 207
7550 UniqueColorsImage = 208
7551 AdaptiveResize = 209
7552 AdaptiveResizeImage= 210
7553 ClipMask = 211
7554 ClipMaskImage = 212
7555 LinearStretch = 213
7556 LinearStretchImage = 214
7557 ColorMatrix = 215
7558 ColorMatrixImage = 216
7559 Mask = 217
7560 MaskImage = 218
7561 Polaroid = 219
7562 PolaroidImage = 220
7563 FloodfillPaint = 221
7564 FloodfillPaintImage= 222
7565 Distort = 223
7566 DistortImage = 224
7567 Clut = 225
7568 ClutImage = 226
7569 LiquidRescale = 227
7570 LiquidRescaleImage = 228
7571 Encipher = 229
7572 EncipherImage = 230
7573 Decipher = 231
7574 DecipherImage = 232
7575 Deskew = 233
7576 DeskewImage = 234
7577 Remap = 235
7578 RemapImage = 236
7579 SparseColor = 237
7580 SparseColorImage = 238
7581 Function = 239
7582 FunctionImage = 240
7583 SelectiveBlur = 241
7584 SelectiveBlurImage = 242
7585 HaldClut = 243
7586 HaldClutImage = 244
7587 BlueShift = 245
7588 BlueShiftImage = 246
7589 ForwardFourierTransform = 247
7590 ForwardFourierTransformImage = 248
7591 InverseFourierTransform = 249
7592 InverseFourierTransformImage = 250
7593 ColorDecisionList = 251
7594 ColorDecisionListImage = 252
7595 AutoGamma = 253
7596 AutoGammaImage = 254
7597 AutoLevel = 255
7598 AutoLevelImage = 256
7599 LevelColors = 257
7600 LevelImageColors = 258
7601 Clamp = 259
7602 ClampImage = 260
7603 BrightnessContrast = 261
7604 BrightnessContrastImage = 262
7605 Morphology = 263
7606 MorphologyImage = 264
Cristy3ca633e2016-02-13 12:49:01 -05007607 Mode = 265
7608 ModeImage = 266
7609 Statistic = 267
7610 StatisticImage = 268
7611 Perceptible = 269
7612 PerceptibleImage = 270
7613 Poly = 271
7614 PolyImage = 272
7615 Grayscale = 273
7616 GrayscaleImage = 274
7617 CannyEdge = 275
7618 CannyEdgeImage = 276
7619 HoughLine = 277
7620 HoughLineImage = 278
7621 MeanShift = 279
7622 MeanShiftImage = 280
7623 Kuwahara = 281
7624 KuwaharaImage = 282
7625 ConnectedComponent = 283
7626 ConnectedComponentImage = 284
7627 CopyPixels = 285
7628 CopyImagePixels = 286
Cristy5488c982016-02-13 14:07:50 -05007629 Color = 287
7630 ColorImage = 288
Cristy2d830ed2016-02-21 10:54:16 -05007631 WaveletDenoise = 289
7632 WaveletDenoiseImage= 290
Cristy99a57162016-12-05 11:47:57 -05007633 Colorspace = 291
7634 ColorspaceImage = 292
Cristy53353872017-07-02 12:24:24 -04007635 AutoThreshold = 293
7636 AutoThresholdImage = 294
cristy4a3ce0a2013-08-03 20:06:59 +00007637 MogrifyRegion = 666
7638 PPCODE:
7639 {
7640 AffineMatrix
7641 affine,
7642 current;
7643
7644 char
7645 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007646 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007647
7648 ChannelType
7649 channel,
7650 channel_mask;
7651
7652 CompositeOperator
7653 compose;
7654
7655 const char
7656 *attribute,
7657 *value;
7658
7659 double
7660 angle;
7661
7662 ExceptionInfo
7663 *exception;
7664
7665 GeometryInfo
7666 geometry_info;
7667
7668 Image
7669 *image,
7670 *next,
7671 *region_image;
7672
7673 MagickBooleanType
7674 status;
7675
7676 MagickStatusType
7677 flags;
7678
7679 PixelInfo
7680 fill_color;
7681
7682 RectangleInfo
7683 geometry,
7684 region_info;
7685
7686 register ssize_t
7687 i;
7688
7689 ssize_t
7690 base,
7691 j,
7692 number_images;
7693
7694 struct Methods
7695 *rp;
7696
7697 struct PackageInfo
7698 *info;
7699
7700 SV
7701 *perl_exception,
7702 **pv,
7703 *reference,
7704 **reference_vector;
7705
7706 struct ArgumentList
7707 argument_list[MaxArguments];
7708
7709 PERL_UNUSED_VAR(ref);
7710 PERL_UNUSED_VAR(ix);
7711 exception=AcquireExceptionInfo();
7712 perl_exception=newSVpv("",0);
7713 reference_vector=NULL;
7714 region_image=NULL;
7715 number_images=0;
7716 base=2;
7717 if (sv_isobject(ST(0)) == 0)
7718 {
7719 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7720 PackageName);
7721 goto PerlException;
7722 }
7723 reference=SvRV(ST(0));
7724 region_info.width=0;
7725 region_info.height=0;
7726 region_info.x=0;
7727 region_info.y=0;
7728 region_image=(Image *) NULL;
7729 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7730 if (ix && (ix != 666))
7731 {
7732 /*
7733 Called as Method(...)
7734 */
7735 ix=(ix+1)/2;
7736 rp=(&Methods[ix-1]);
7737 attribute=rp->name;
7738 }
7739 else
7740 {
7741 /*
7742 Called as Mogrify("Method",...)
7743 */
7744 attribute=(char *) SvPV(ST(1),na);
7745 if (ix)
7746 {
7747 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7748 attribute=(char *) SvPV(ST(2),na);
7749 base++;
7750 }
7751 for (rp=Methods; ; rp++)
7752 {
7753 if (rp >= EndOf(Methods))
7754 {
7755 ThrowPerlException(exception,OptionError,
7756 "UnrecognizedPerlMagickMethod",attribute);
7757 goto PerlException;
7758 }
7759 if (strEQcase(attribute,rp->name))
7760 break;
7761 }
7762 ix=rp-Methods+1;
7763 base++;
7764 }
7765 if (image == (Image *) NULL)
7766 {
7767 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7768 goto PerlException;
7769 }
7770 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7771 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7772 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7773 {
7774 Arguments
7775 *pp,
7776 *qq;
7777
7778 ssize_t
7779 ssize_test;
7780
7781 struct ArgumentList
7782 *al;
7783
7784 SV
7785 *sv;
7786
7787 sv=NULL;
7788 ssize_test=0;
7789 pp=(Arguments *) NULL;
7790 qq=rp->arguments;
7791 if (i == items)
7792 {
7793 pp=rp->arguments,
7794 sv=ST(i-1);
7795 }
7796 else
7797 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7798 {
7799 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7800 break;
7801 if (strEQcase(attribute,qq->method) > ssize_test)
7802 {
7803 pp=qq;
7804 ssize_test=strEQcase(attribute,qq->method);
7805 }
7806 }
7807 if (pp == (Arguments *) NULL)
7808 {
7809 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7810 attribute);
7811 goto continue_outer_loop;
7812 }
7813 al=(&argument_list[pp-rp->arguments]);
7814 switch (pp->type)
7815 {
7816 case ArrayReference:
7817 {
7818 if (SvTYPE(sv) != SVt_RV)
7819 {
cristy151b66d2015-04-15 10:50:31 +00007820 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007821 "invalid %.60s value",pp->method);
7822 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7823 goto continue_outer_loop;
7824 }
7825 al->array_reference=SvRV(sv);
7826 break;
7827 }
7828 case RealReference:
7829 {
7830 al->real_reference=SvNV(sv);
7831 break;
7832 }
7833 case FileReference:
7834 {
7835 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7836 break;
7837 }
7838 case ImageReference:
7839 {
7840 if (!sv_isobject(sv) ||
7841 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7842 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7843 {
7844 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7845 PackageName);
7846 goto PerlException;
7847 }
7848 break;
7849 }
7850 case IntegerReference:
7851 {
7852 al->integer_reference=SvIV(sv);
7853 break;
7854 }
7855 case StringReference:
7856 {
7857 al->string_reference=(char *) SvPV(sv,al->length);
7858 if (sv_isobject(sv))
7859 al->image_reference=SetupList(aTHX_ SvRV(sv),
7860 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7861 break;
7862 }
7863 default:
7864 {
7865 /*
7866 Is a string; look up name.
7867 */
7868 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7869 {
7870 al->string_reference=(char *) SvPV(sv,al->length);
7871 al->integer_reference=(-1);
7872 break;
7873 }
7874 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7875 MagickFalse,SvPV(sv,na));
7876 if (pp->type == MagickChannelOptions)
7877 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7878 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7879 {
cristy151b66d2015-04-15 10:50:31 +00007880 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007881 "invalid %.60s value",pp->method);
7882 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7883 goto continue_outer_loop;
7884 }
7885 break;
7886 }
7887 }
7888 attribute_flag[pp-rp->arguments]++;
7889 continue_outer_loop: ;
7890 }
7891 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7892 pv=reference_vector;
7893 SetGeometryInfo(&geometry_info);
7894 channel=DefaultChannels;
7895 for (next=image; next; next=next->next)
7896 {
7897 image=next;
7898 SetGeometry(image,&geometry);
7899 if ((region_info.width*region_info.height) != 0)
7900 {
7901 region_image=image;
7902 image=CropImage(image,&region_info,exception);
7903 }
7904 switch (ix)
7905 {
7906 default:
7907 {
cristy151b66d2015-04-15 10:50:31 +00007908 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007909 ThrowPerlException(exception,OptionError,
7910 "UnrecognizedPerlMagickMethod",message);
7911 goto PerlException;
7912 }
7913 case 1: /* Comment */
7914 {
7915 if (attribute_flag[0] == 0)
7916 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007917 (void) SetImageProperty(image,"comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007918 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007919 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007920 break;
7921 }
7922 case 2: /* Label */
7923 {
7924 if (attribute_flag[0] == 0)
7925 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007926 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007927 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007928 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007929 break;
7930 }
7931 case 3: /* AddNoise */
7932 {
7933 double
7934 attenuate;
7935
7936 if (attribute_flag[0] == 0)
7937 argument_list[0].integer_reference=UniformNoise;
7938 attenuate=1.0;
7939 if (attribute_flag[1] != 0)
7940 attenuate=argument_list[1].real_reference;
7941 if (attribute_flag[2] != 0)
7942 channel=(ChannelType) argument_list[2].integer_reference;
7943 channel_mask=SetImageChannelMask(image,channel);
7944 image=AddNoiseImage(image,(NoiseType)
7945 argument_list[0].integer_reference,attenuate,exception);
7946 if (image != (Image *) NULL)
7947 (void) SetImageChannelMask(image,channel_mask);
7948 break;
7949 }
7950 case 4: /* Colorize */
7951 {
7952 PixelInfo
7953 target;
7954
7955 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7956 0,0,&target,exception);
7957 if (attribute_flag[0] != 0)
7958 (void) QueryColorCompliance(argument_list[0].string_reference,
7959 AllCompliance,&target,exception);
7960 if (attribute_flag[1] == 0)
7961 argument_list[1].string_reference="100%";
7962 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7963 exception);
7964 break;
7965 }
7966 case 5: /* Border */
7967 {
7968 CompositeOperator
7969 compose;
7970
7971 geometry.width=0;
7972 geometry.height=0;
7973 if (attribute_flag[0] != 0)
7974 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7975 &geometry,exception);
7976 if (attribute_flag[1] != 0)
7977 geometry.width=argument_list[1].integer_reference;
7978 if (attribute_flag[2] != 0)
7979 geometry.height=argument_list[2].integer_reference;
7980 if (attribute_flag[3] != 0)
7981 QueryColorCompliance(argument_list[3].string_reference,
7982 AllCompliance,&image->border_color,exception);
7983 if (attribute_flag[4] != 0)
7984 QueryColorCompliance(argument_list[4].string_reference,
7985 AllCompliance,&image->border_color,exception);
7986 if (attribute_flag[5] != 0)
7987 QueryColorCompliance(argument_list[5].string_reference,
7988 AllCompliance,&image->border_color,exception);
7989 compose=image->compose;
7990 if (attribute_flag[6] != 0)
7991 compose=(CompositeOperator) argument_list[6].integer_reference;
7992 image=BorderImage(image,&geometry,compose,exception);
7993 break;
7994 }
7995 case 6: /* Blur */
7996 {
7997 if (attribute_flag[0] != 0)
7998 {
7999 flags=ParseGeometry(argument_list[0].string_reference,
8000 &geometry_info);
8001 if ((flags & SigmaValue) == 0)
8002 geometry_info.sigma=1.0;
8003 }
8004 if (attribute_flag[1] != 0)
8005 geometry_info.rho=argument_list[1].real_reference;
8006 if (attribute_flag[2] != 0)
8007 geometry_info.sigma=argument_list[2].real_reference;
8008 if (attribute_flag[3] != 0)
8009 channel=(ChannelType) argument_list[3].integer_reference;
8010 channel_mask=SetImageChannelMask(image,channel);
8011 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
8012 exception);
8013 if (image != (Image *) NULL)
8014 (void) SetImageChannelMask(image,channel_mask);
8015 break;
8016 }
8017 case 7: /* Chop */
8018 {
cristy260bd762014-08-15 12:46:34 +00008019 if (attribute_flag[5] != 0)
8020 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00008021 if (attribute_flag[0] != 0)
8022 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8023 &geometry,exception);
8024 if (attribute_flag[1] != 0)
8025 geometry.width=argument_list[1].integer_reference;
8026 if (attribute_flag[2] != 0)
8027 geometry.height=argument_list[2].integer_reference;
8028 if (attribute_flag[3] != 0)
8029 geometry.x=argument_list[3].integer_reference;
8030 if (attribute_flag[4] != 0)
8031 geometry.y=argument_list[4].integer_reference;
8032 image=ChopImage(image,&geometry,exception);
8033 break;
8034 }
8035 case 8: /* Crop */
8036 {
8037 if (attribute_flag[6] != 0)
8038 image->gravity=(GravityType) argument_list[6].integer_reference;
8039 if (attribute_flag[0] != 0)
8040 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8041 &geometry,exception);
8042 if (attribute_flag[1] != 0)
8043 geometry.width=argument_list[1].integer_reference;
8044 if (attribute_flag[2] != 0)
8045 geometry.height=argument_list[2].integer_reference;
8046 if (attribute_flag[3] != 0)
8047 geometry.x=argument_list[3].integer_reference;
8048 if (attribute_flag[4] != 0)
8049 geometry.y=argument_list[4].integer_reference;
8050 if (attribute_flag[5] != 0)
8051 image->fuzz=StringToDoubleInterval(
8052 argument_list[5].string_reference,(double) QuantumRange+1.0);
8053 image=CropImage(image,&geometry,exception);
8054 break;
8055 }
8056 case 9: /* Despeckle */
8057 {
8058 image=DespeckleImage(image,exception);
8059 break;
8060 }
8061 case 10: /* Edge */
8062 {
8063 if (attribute_flag[0] != 0)
8064 geometry_info.rho=argument_list[0].real_reference;
8065 image=EdgeImage(image,geometry_info.rho,exception);
8066 break;
8067 }
8068 case 11: /* Emboss */
8069 {
8070 if (attribute_flag[0] != 0)
8071 {
8072 flags=ParseGeometry(argument_list[0].string_reference,
8073 &geometry_info);
8074 if ((flags & SigmaValue) == 0)
8075 geometry_info.sigma=1.0;
8076 }
8077 if (attribute_flag[1] != 0)
8078 geometry_info.rho=argument_list[1].real_reference;
8079 if (attribute_flag[2] != 0)
8080 geometry_info.sigma=argument_list[2].real_reference;
8081 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8082 exception);
8083 break;
8084 }
8085 case 12: /* Enhance */
8086 {
8087 image=EnhanceImage(image,exception);
8088 break;
8089 }
8090 case 13: /* Flip */
8091 {
8092 image=FlipImage(image,exception);
8093 break;
8094 }
8095 case 14: /* Flop */
8096 {
8097 image=FlopImage(image,exception);
8098 break;
8099 }
8100 case 15: /* Frame */
8101 {
8102 CompositeOperator
8103 compose;
8104
8105 FrameInfo
8106 frame_info;
8107
8108 if (attribute_flag[0] != 0)
8109 {
8110 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8111 &geometry,exception);
8112 frame_info.width=geometry.width;
8113 frame_info.height=geometry.height;
8114 frame_info.outer_bevel=geometry.x;
8115 frame_info.inner_bevel=geometry.y;
8116 }
8117 if (attribute_flag[1] != 0)
8118 frame_info.width=argument_list[1].integer_reference;
8119 if (attribute_flag[2] != 0)
8120 frame_info.height=argument_list[2].integer_reference;
8121 if (attribute_flag[3] != 0)
8122 frame_info.inner_bevel=argument_list[3].integer_reference;
8123 if (attribute_flag[4] != 0)
8124 frame_info.outer_bevel=argument_list[4].integer_reference;
8125 if (attribute_flag[5] != 0)
8126 QueryColorCompliance(argument_list[5].string_reference,
8127 AllCompliance,&fill_color,exception);
8128 if (attribute_flag[6] != 0)
8129 QueryColorCompliance(argument_list[6].string_reference,
8130 AllCompliance,&fill_color,exception);
8131 frame_info.x=(ssize_t) frame_info.width;
8132 frame_info.y=(ssize_t) frame_info.height;
8133 frame_info.width=image->columns+2*frame_info.x;
8134 frame_info.height=image->rows+2*frame_info.y;
8135 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
Cristy8645e042016-02-03 16:35:29 -05008136 image->alpha_color=fill_color;
cristy4a3ce0a2013-08-03 20:06:59 +00008137 compose=image->compose;
8138 if (attribute_flag[7] != 0)
8139 compose=(CompositeOperator) argument_list[7].integer_reference;
8140 image=FrameImage(image,&frame_info,compose,exception);
8141 break;
8142 }
8143 case 16: /* Implode */
8144 {
8145 PixelInterpolateMethod
8146 method;
8147
8148 if (attribute_flag[0] == 0)
8149 argument_list[0].real_reference=0.5;
8150 method=UndefinedInterpolatePixel;
8151 if (attribute_flag[1] != 0)
8152 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8153 image=ImplodeImage(image,argument_list[0].real_reference,
8154 method,exception);
8155 break;
8156 }
8157 case 17: /* Magnify */
8158 {
8159 image=MagnifyImage(image,exception);
8160 break;
8161 }
8162 case 18: /* MedianFilter */
8163 {
8164 if (attribute_flag[0] != 0)
8165 {
8166 flags=ParseGeometry(argument_list[0].string_reference,
8167 &geometry_info);
8168 if ((flags & SigmaValue) == 0)
8169 geometry_info.sigma=geometry_info.rho;
8170 }
8171 if (attribute_flag[1] != 0)
8172 geometry_info.rho=argument_list[1].real_reference;
8173 if (attribute_flag[2] != 0)
8174 geometry_info.sigma=argument_list[2].real_reference;
8175 if (attribute_flag[3] != 0)
8176 channel=(ChannelType) argument_list[3].integer_reference;
8177 channel_mask=SetImageChannelMask(image,channel);
8178 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8179 (size_t) geometry_info.sigma,exception);
8180 if (image != (Image *) NULL)
8181 (void) SetImageChannelMask(image,channel_mask);
8182 break;
8183 }
8184 case 19: /* Minify */
8185 {
8186 image=MinifyImage(image,exception);
8187 break;
8188 }
8189 case 20: /* OilPaint */
8190 {
8191 if (attribute_flag[0] == 0)
8192 argument_list[0].real_reference=0.0;
8193 if (attribute_flag[1] == 0)
8194 argument_list[1].real_reference=1.0;
8195 image=OilPaintImage(image,argument_list[0].real_reference,
8196 argument_list[1].real_reference,exception);
8197 break;
8198 }
8199 case 21: /* ReduceNoise */
8200 {
8201 if (attribute_flag[0] != 0)
8202 {
8203 flags=ParseGeometry(argument_list[0].string_reference,
8204 &geometry_info);
8205 if ((flags & SigmaValue) == 0)
8206 geometry_info.sigma=1.0;
8207 }
8208 if (attribute_flag[1] != 0)
8209 geometry_info.rho=argument_list[1].real_reference;
8210 if (attribute_flag[2] != 0)
8211 geometry_info.sigma=argument_list[2].real_reference;
8212 if (attribute_flag[3] != 0)
8213 channel=(ChannelType) argument_list[3].integer_reference;
8214 channel_mask=SetImageChannelMask(image,channel);
8215 image=StatisticImage(image,NonpeakStatistic,(size_t)
8216 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8217 if (image != (Image *) NULL)
8218 (void) SetImageChannelMask(image,channel_mask);
8219 break;
8220 }
8221 case 22: /* Roll */
8222 {
8223 if (attribute_flag[0] != 0)
8224 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8225 &geometry,exception);
8226 if (attribute_flag[1] != 0)
8227 geometry.x=argument_list[1].integer_reference;
8228 if (attribute_flag[2] != 0)
8229 geometry.y=argument_list[2].integer_reference;
8230 image=RollImage(image,geometry.x,geometry.y,exception);
8231 break;
8232 }
8233 case 23: /* Rotate */
8234 {
8235 if (attribute_flag[0] == 0)
8236 argument_list[0].real_reference=90.0;
8237 if (attribute_flag[1] != 0)
8238 {
8239 QueryColorCompliance(argument_list[1].string_reference,
8240 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008241 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8242 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008243 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8244 }
8245 image=RotateImage(image,argument_list[0].real_reference,exception);
8246 break;
8247 }
8248 case 24: /* Sample */
8249 {
8250 if (attribute_flag[0] != 0)
8251 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8252 &geometry,exception);
8253 if (attribute_flag[1] != 0)
8254 geometry.width=argument_list[1].integer_reference;
8255 if (attribute_flag[2] != 0)
8256 geometry.height=argument_list[2].integer_reference;
8257 image=SampleImage(image,geometry.width,geometry.height,exception);
8258 break;
8259 }
8260 case 25: /* Scale */
8261 {
8262 if (attribute_flag[0] != 0)
8263 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8264 &geometry,exception);
8265 if (attribute_flag[1] != 0)
8266 geometry.width=argument_list[1].integer_reference;
8267 if (attribute_flag[2] != 0)
8268 geometry.height=argument_list[2].integer_reference;
8269 image=ScaleImage(image,geometry.width,geometry.height,exception);
8270 break;
8271 }
8272 case 26: /* Shade */
8273 {
8274 if (attribute_flag[0] != 0)
8275 {
8276 flags=ParseGeometry(argument_list[0].string_reference,
8277 &geometry_info);
8278 if ((flags & SigmaValue) == 0)
8279 geometry_info.sigma=0.0;
8280 }
8281 if (attribute_flag[1] != 0)
8282 geometry_info.rho=argument_list[1].real_reference;
8283 if (attribute_flag[2] != 0)
8284 geometry_info.sigma=argument_list[2].real_reference;
8285 image=ShadeImage(image,
8286 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8287 geometry_info.rho,geometry_info.sigma,exception);
8288 break;
8289 }
8290 case 27: /* Sharpen */
8291 {
8292 if (attribute_flag[0] != 0)
8293 {
8294 flags=ParseGeometry(argument_list[0].string_reference,
8295 &geometry_info);
8296 if ((flags & SigmaValue) == 0)
8297 geometry_info.sigma=1.0;
8298 }
8299 if (attribute_flag[1] != 0)
8300 geometry_info.rho=argument_list[1].real_reference;
8301 if (attribute_flag[2] != 0)
8302 geometry_info.sigma=argument_list[2].real_reference;
8303 if (attribute_flag[3] != 0)
8304 channel=(ChannelType) argument_list[3].integer_reference;
8305 channel_mask=SetImageChannelMask(image,channel);
8306 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8307 exception);
8308 if (image != (Image *) NULL)
8309 (void) SetImageChannelMask(image,channel_mask);
8310 break;
8311 }
8312 case 28: /* Shear */
8313 {
8314 if (attribute_flag[0] != 0)
8315 {
8316 flags=ParseGeometry(argument_list[0].string_reference,
8317 &geometry_info);
8318 if ((flags & SigmaValue) == 0)
8319 geometry_info.sigma=geometry_info.rho;
8320 }
8321 if (attribute_flag[1] != 0)
8322 geometry_info.rho=argument_list[1].real_reference;
8323 if (attribute_flag[2] != 0)
8324 geometry_info.sigma=argument_list[2].real_reference;
8325 if (attribute_flag[3] != 0)
8326 QueryColorCompliance(argument_list[3].string_reference,
8327 AllCompliance,&image->background_color,exception);
8328 if (attribute_flag[4] != 0)
8329 QueryColorCompliance(argument_list[4].string_reference,
8330 AllCompliance,&image->background_color,exception);
8331 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8332 exception);
8333 break;
8334 }
8335 case 29: /* Spread */
8336 {
Cristye3319c12015-08-24 07:11:48 -04008337 PixelInterpolateMethod
8338 method;
8339
cristy4a3ce0a2013-08-03 20:06:59 +00008340 if (attribute_flag[0] == 0)
8341 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008342 method=UndefinedInterpolatePixel;
8343 if (attribute_flag[1] != 0)
8344 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8345 image=SpreadImage(image,method,argument_list[0].real_reference,
8346 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008347 break;
8348 }
8349 case 30: /* Swirl */
8350 {
8351 PixelInterpolateMethod
8352 method;
8353
8354 if (attribute_flag[0] == 0)
8355 argument_list[0].real_reference=50.0;
8356 method=UndefinedInterpolatePixel;
8357 if (attribute_flag[1] != 0)
8358 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8359 image=SwirlImage(image,argument_list[0].real_reference,
8360 method,exception);
8361 break;
8362 }
8363 case 31: /* Resize */
8364 case 32: /* Zoom */
8365 {
8366 if (attribute_flag[0] != 0)
8367 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8368 &geometry,exception);
8369 if (attribute_flag[1] != 0)
8370 geometry.width=argument_list[1].integer_reference;
8371 if (attribute_flag[2] != 0)
8372 geometry.height=argument_list[2].integer_reference;
8373 if (attribute_flag[3] == 0)
8374 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8375 if (attribute_flag[4] != 0)
8376 SetImageArtifact(image,"filter:support",
8377 argument_list[4].string_reference);
8378 image=ResizeImage(image,geometry.width,geometry.height,
Cristy8645e042016-02-03 16:35:29 -05008379 (FilterType) argument_list[3].integer_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00008380 exception);
8381 break;
8382 }
8383 case 33: /* Annotate */
8384 {
8385 DrawInfo
8386 *draw_info;
8387
8388 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8389 (DrawInfo *) NULL);
8390 if (attribute_flag[0] != 0)
8391 {
8392 char
8393 *text;
8394
8395 text=InterpretImageProperties(info ? info->image_info :
8396 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8397 exception);
8398 (void) CloneString(&draw_info->text,text);
8399 text=DestroyString(text);
8400 }
8401 if (attribute_flag[1] != 0)
8402 (void) CloneString(&draw_info->font,
8403 argument_list[1].string_reference);
8404 if (attribute_flag[2] != 0)
8405 draw_info->pointsize=argument_list[2].real_reference;
8406 if (attribute_flag[3] != 0)
8407 (void) CloneString(&draw_info->density,
8408 argument_list[3].string_reference);
8409 if (attribute_flag[4] != 0)
8410 (void) QueryColorCompliance(argument_list[4].string_reference,
8411 AllCompliance,&draw_info->undercolor,exception);
8412 if (attribute_flag[5] != 0)
8413 {
8414 (void) QueryColorCompliance(argument_list[5].string_reference,
8415 AllCompliance,&draw_info->stroke,exception);
8416 if (argument_list[5].image_reference != (Image *) NULL)
8417 draw_info->stroke_pattern=CloneImage(
8418 argument_list[5].image_reference,0,0,MagickTrue,exception);
8419 }
8420 if (attribute_flag[6] != 0)
8421 {
8422 (void) QueryColorCompliance(argument_list[6].string_reference,
8423 AllCompliance,&draw_info->fill,exception);
8424 if (argument_list[6].image_reference != (Image *) NULL)
8425 draw_info->fill_pattern=CloneImage(
8426 argument_list[6].image_reference,0,0,MagickTrue,exception);
8427 }
8428 if (attribute_flag[7] != 0)
8429 {
8430 (void) CloneString(&draw_info->geometry,
8431 argument_list[7].string_reference);
8432 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8433 &geometry,exception);
8434 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8435 geometry_info.sigma=geometry_info.xi;
8436 }
8437 if (attribute_flag[8] != 0)
8438 (void) QueryColorCompliance(argument_list[8].string_reference,
8439 AllCompliance,&draw_info->fill,exception);
8440 if (attribute_flag[11] != 0)
8441 draw_info->gravity=(GravityType)
8442 argument_list[11].integer_reference;
8443 if (attribute_flag[25] != 0)
8444 {
8445 AV
8446 *av;
8447
8448 av=(AV *) argument_list[25].array_reference;
8449 if ((av_len(av) != 3) && (av_len(av) != 5))
8450 {
8451 ThrowPerlException(exception,OptionError,
8452 "affine matrix must have 4 or 6 elements",PackageName);
8453 goto PerlException;
8454 }
8455 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8456 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8457 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8458 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8459 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8460 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8461 {
8462 ThrowPerlException(exception,OptionError,
8463 "affine matrix is singular",PackageName);
8464 goto PerlException;
8465 }
8466 if (av_len(av) == 5)
8467 {
8468 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8469 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8470 }
8471 }
8472 for (j=12; j < 17; j++)
8473 {
8474 if (attribute_flag[j] == 0)
8475 continue;
8476 value=argument_list[j].string_reference;
8477 angle=argument_list[j].real_reference;
8478 current=draw_info->affine;
8479 GetAffineMatrix(&affine);
8480 switch (j)
8481 {
8482 case 12:
8483 {
8484 /*
8485 Translate.
8486 */
8487 flags=ParseGeometry(value,&geometry_info);
8488 affine.tx=geometry_info.xi;
8489 affine.ty=geometry_info.psi;
8490 if ((flags & PsiValue) == 0)
8491 affine.ty=affine.tx;
8492 break;
8493 }
8494 case 13:
8495 {
8496 /*
8497 Scale.
8498 */
8499 flags=ParseGeometry(value,&geometry_info);
8500 affine.sx=geometry_info.rho;
8501 affine.sy=geometry_info.sigma;
8502 if ((flags & SigmaValue) == 0)
8503 affine.sy=affine.sx;
8504 break;
8505 }
8506 case 14:
8507 {
8508 /*
8509 Rotate.
8510 */
8511 if (angle == 0.0)
8512 break;
8513 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8514 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8515 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8516 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8517 break;
8518 }
8519 case 15:
8520 {
8521 /*
8522 SkewX.
8523 */
8524 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8525 break;
8526 }
8527 case 16:
8528 {
8529 /*
8530 SkewY.
8531 */
8532 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8533 break;
8534 }
8535 }
8536 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8537 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8538 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8539 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8540 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8541 current.tx;
8542 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8543 current.ty;
8544 }
8545 if (attribute_flag[9] == 0)
8546 argument_list[9].real_reference=0.0;
8547 if (attribute_flag[10] == 0)
8548 argument_list[10].real_reference=0.0;
8549 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8550 {
8551 char
cristy151b66d2015-04-15 10:50:31 +00008552 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008553
cristy151b66d2015-04-15 10:50:31 +00008554 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008555 (double) argument_list[9].real_reference+draw_info->affine.tx,
8556 (double) argument_list[10].real_reference+draw_info->affine.ty);
8557 (void) CloneString(&draw_info->geometry,geometry);
8558 }
8559 if (attribute_flag[17] != 0)
8560 draw_info->stroke_width=argument_list[17].real_reference;
8561 if (attribute_flag[18] != 0)
8562 {
8563 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8564 MagickTrue : MagickFalse;
8565 draw_info->stroke_antialias=draw_info->text_antialias;
8566 }
8567 if (attribute_flag[19] != 0)
8568 (void) CloneString(&draw_info->family,
8569 argument_list[19].string_reference);
8570 if (attribute_flag[20] != 0)
8571 draw_info->style=(StyleType) argument_list[20].integer_reference;
8572 if (attribute_flag[21] != 0)
8573 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8574 if (attribute_flag[22] != 0)
8575 draw_info->weight=argument_list[22].integer_reference;
8576 if (attribute_flag[23] != 0)
8577 draw_info->align=(AlignType) argument_list[23].integer_reference;
8578 if (attribute_flag[24] != 0)
8579 (void) CloneString(&draw_info->encoding,
8580 argument_list[24].string_reference);
8581 if (attribute_flag[25] != 0)
8582 draw_info->fill_pattern=CloneImage(
8583 argument_list[25].image_reference,0,0,MagickTrue,exception);
8584 if (attribute_flag[26] != 0)
8585 draw_info->fill_pattern=CloneImage(
8586 argument_list[26].image_reference,0,0,MagickTrue,exception);
8587 if (attribute_flag[27] != 0)
8588 draw_info->stroke_pattern=CloneImage(
8589 argument_list[27].image_reference,0,0,MagickTrue,exception);
8590 if (attribute_flag[29] != 0)
8591 draw_info->kerning=argument_list[29].real_reference;
8592 if (attribute_flag[30] != 0)
8593 draw_info->interline_spacing=argument_list[30].real_reference;
8594 if (attribute_flag[31] != 0)
8595 draw_info->interword_spacing=argument_list[31].real_reference;
8596 if (attribute_flag[32] != 0)
8597 draw_info->direction=(DirectionType)
8598 argument_list[32].integer_reference;
8599 (void) AnnotateImage(image,draw_info,exception);
8600 draw_info=DestroyDrawInfo(draw_info);
8601 break;
8602 }
8603 case 34: /* ColorFloodfill */
8604 {
8605 DrawInfo
8606 *draw_info;
8607
8608 MagickBooleanType
8609 invert;
8610
8611 PixelInfo
8612 target;
8613
8614 draw_info=CloneDrawInfo(info ? info->image_info :
8615 (ImageInfo *) NULL,(DrawInfo *) NULL);
8616 if (attribute_flag[0] != 0)
8617 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8618 &geometry,exception);
8619 if (attribute_flag[1] != 0)
8620 geometry.x=argument_list[1].integer_reference;
8621 if (attribute_flag[2] != 0)
8622 geometry.y=argument_list[2].integer_reference;
8623 if (attribute_flag[3] != 0)
8624 (void) QueryColorCompliance(argument_list[3].string_reference,
8625 AllCompliance,&draw_info->fill,exception);
8626 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8627 geometry.x,geometry.y,&target,exception);
8628 invert=MagickFalse;
8629 if (attribute_flag[4] != 0)
8630 {
8631 QueryColorCompliance(argument_list[4].string_reference,
8632 AllCompliance,&target,exception);
8633 invert=MagickTrue;
8634 }
8635 if (attribute_flag[5] != 0)
8636 image->fuzz=StringToDoubleInterval(
8637 argument_list[5].string_reference,(double) QuantumRange+1.0);
8638 if (attribute_flag[6] != 0)
8639 invert=(MagickBooleanType) argument_list[6].integer_reference;
8640 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8641 geometry.y,invert,exception);
8642 draw_info=DestroyDrawInfo(draw_info);
8643 break;
8644 }
8645 case 35: /* Composite */
8646 {
8647 char
cristy151b66d2015-04-15 10:50:31 +00008648 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008649
8650 Image
8651 *composite_image,
8652 *rotate_image;
8653
8654 MagickBooleanType
8655 clip_to_self;
8656
8657 compose=OverCompositeOp;
8658 if (attribute_flag[0] != 0)
8659 composite_image=argument_list[0].image_reference;
8660 else
8661 {
8662 ThrowPerlException(exception,OptionError,
8663 "CompositeImageRequired",PackageName);
8664 goto PerlException;
8665 }
8666 /*
8667 Parameter Handling used for BOTH normal and tiled composition.
8668 */
8669 if (attribute_flag[1] != 0) /* compose */
8670 compose=(CompositeOperator) argument_list[1].integer_reference;
8671 if (attribute_flag[6] != 0) /* opacity */
8672 {
8673 if (compose != DissolveCompositeOp)
8674 (void) SetImageAlpha(composite_image,(Quantum)
8675 StringToDoubleInterval(argument_list[6].string_reference,
8676 (double) QuantumRange+1.0),exception);
8677 else
8678 {
8679 CacheView
8680 *composite_view;
8681
8682 double
8683 opacity;
8684
8685 MagickBooleanType
8686 sync;
8687
8688 register ssize_t
8689 x;
8690
8691 register Quantum
8692 *q;
8693
8694 ssize_t
8695 y;
8696
8697 /*
8698 Handle dissolve composite operator (patch by
8699 Kevin A. McGrail).
8700 */
8701 (void) CloneString(&image->geometry,
8702 argument_list[6].string_reference);
8703 opacity=(Quantum) StringToDoubleInterval(
8704 argument_list[6].string_reference,(double) QuantumRange+
8705 1.0);
cristy17f11b02014-12-20 19:37:04 +00008706 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008707 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8708 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8709 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8710 {
8711 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8712 composite_image->columns,1,exception);
8713 for (x=0; x < (ssize_t) composite_image->columns; x++)
8714 {
8715 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8716 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8717 q);
8718 q+=GetPixelChannels(composite_image);
8719 }
8720 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8721 if (sync == MagickFalse)
8722 break;
8723 }
8724 composite_view=DestroyCacheView(composite_view);
8725 }
8726 }
8727 if (attribute_flag[9] != 0) /* "color=>" */
8728 QueryColorCompliance(argument_list[9].string_reference,
8729 AllCompliance,&composite_image->background_color,exception);
8730 if (attribute_flag[12] != 0) /* "interpolate=>" */
8731 image->interpolate=(PixelInterpolateMethod)
8732 argument_list[12].integer_reference;
8733 if (attribute_flag[13] != 0) /* "args=>" */
8734 (void) SetImageArtifact(composite_image,"compose:args",
8735 argument_list[13].string_reference);
8736 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8737 (void) SetImageArtifact(composite_image,"compose:args",
8738 argument_list[14].string_reference);
8739 clip_to_self=MagickTrue;
8740 if (attribute_flag[15] != 0)
8741 clip_to_self=(MagickBooleanType)
8742 argument_list[15].integer_reference;
8743 /*
8744 Tiling Composition (with orthogonal rotate).
8745 */
8746 rotate_image=(Image *) NULL;
8747 if (attribute_flag[8] != 0) /* "rotate=>" */
8748 {
8749 /*
8750 Rotate image.
8751 */
8752 rotate_image=RotateImage(composite_image,
8753 argument_list[8].real_reference,exception);
8754 if (rotate_image == (Image *) NULL)
8755 break;
8756 }
8757 if ((attribute_flag[7] != 0) &&
8758 (argument_list[7].integer_reference != 0)) /* tile */
8759 {
8760 ssize_t
8761 x,
8762 y;
8763
8764 /*
8765 Tile the composite image.
8766 */
8767 if (attribute_flag[8] != 0) /* "tile=>" */
8768 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8769 "false");
8770 else
8771 (void) SetImageArtifact(composite_image,
8772 "compose:outside-overlay","false");
8773 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8774 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8775 {
8776 if (attribute_flag[8] != 0) /* rotate */
8777 (void) CompositeImage(image,rotate_image,compose,
8778 MagickTrue,x,y,exception);
8779 else
8780 (void) CompositeImage(image,composite_image,compose,
8781 MagickTrue,x,y,exception);
8782 }
8783 if (attribute_flag[8] != 0) /* rotate */
8784 rotate_image=DestroyImage(rotate_image);
8785 break;
8786 }
8787 /*
8788 Parameter Handling used used ONLY for normal composition.
8789 */
8790 if (attribute_flag[5] != 0) /* gravity */
8791 image->gravity=(GravityType) argument_list[5].integer_reference;
8792 if (attribute_flag[2] != 0) /* geometry offset */
8793 {
8794 SetGeometry(image,&geometry);
8795 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8796 &geometry);
8797 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8798 &geometry);
8799 }
8800 if (attribute_flag[3] != 0) /* x offset */
8801 geometry.x=argument_list[3].integer_reference;
8802 if (attribute_flag[4] != 0) /* y offset */
8803 geometry.y=argument_list[4].integer_reference;
8804 if (attribute_flag[10] != 0) /* mask */
8805 {
8806 if ((image->compose == DisplaceCompositeOp) ||
8807 (image->compose == DistortCompositeOp))
8808 {
8809 /*
8810 Merge Y displacement into X displacement image.
8811 */
8812 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8813 exception);
8814 (void) CompositeImage(composite_image,
8815 argument_list[10].image_reference,CopyGreenCompositeOp,
8816 MagickTrue,0,0,exception);
8817 }
8818 else
8819 {
8820 Image
8821 *mask_image;
8822
8823 /*
8824 Set a blending mask for the composition.
8825 */
8826 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8827 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008828 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008829 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008830 mask_image=DestroyImage(mask_image);
8831 }
8832 }
8833 if (attribute_flag[11] != 0) /* channel */
8834 channel=(ChannelType) argument_list[11].integer_reference;
8835 /*
8836 Composite two images (normal composition).
8837 */
cristy151b66d2015-04-15 10:50:31 +00008838 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008839 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8840 (double) composite_image->rows,(double) geometry.x,(double)
8841 geometry.y);
8842 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8843 exception);
8844 channel_mask=SetImageChannelMask(image,channel);
8845 if (attribute_flag[8] == 0) /* no rotate */
8846 CompositeImage(image,composite_image,compose,clip_to_self,
8847 geometry.x,geometry.y,exception);
8848 else
8849 {
8850 /*
8851 Position adjust rotated image then composite.
8852 */
8853 geometry.x-=(ssize_t) (rotate_image->columns-
8854 composite_image->columns)/2;
8855 geometry.y-=(ssize_t) (rotate_image->rows-
8856 composite_image->rows)/2;
8857 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8858 geometry.y,exception);
8859 rotate_image=DestroyImage(rotate_image);
8860 }
8861 if (attribute_flag[10] != 0) /* mask */
8862 {
8863 if ((image->compose == DisplaceCompositeOp) ||
8864 (image->compose == DistortCompositeOp))
8865 composite_image=DestroyImage(composite_image);
8866 else
cristy1f7ffb72015-07-29 11:07:03 +00008867 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008868 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008869 }
8870 (void) SetImageChannelMask(image,channel_mask);
8871 break;
8872 }
8873 case 36: /* Contrast */
8874 {
8875 if (attribute_flag[0] == 0)
8876 argument_list[0].integer_reference=0;
8877 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8878 MagickTrue : MagickFalse,exception);
8879 break;
8880 }
8881 case 37: /* CycleColormap */
8882 {
8883 if (attribute_flag[0] == 0)
8884 argument_list[0].integer_reference=6;
8885 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8886 exception);
8887 break;
8888 }
8889 case 38: /* Draw */
8890 {
8891 DrawInfo
8892 *draw_info;
8893
8894 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8895 (DrawInfo *) NULL);
8896 (void) CloneString(&draw_info->primitive,"point");
8897 if (attribute_flag[0] != 0)
8898 {
8899 if (argument_list[0].integer_reference < 0)
8900 (void) CloneString(&draw_info->primitive,
8901 argument_list[0].string_reference);
8902 else
8903 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8904 MagickPrimitiveOptions,argument_list[0].integer_reference));
8905 }
8906 if (attribute_flag[1] != 0)
8907 {
8908 if (LocaleCompare(draw_info->primitive,"path") == 0)
8909 {
8910 (void) ConcatenateString(&draw_info->primitive," '");
8911 ConcatenateString(&draw_info->primitive,
8912 argument_list[1].string_reference);
8913 (void) ConcatenateString(&draw_info->primitive,"'");
8914 }
8915 else
8916 {
8917 (void) ConcatenateString(&draw_info->primitive," ");
8918 ConcatenateString(&draw_info->primitive,
8919 argument_list[1].string_reference);
8920 }
8921 }
8922 if (attribute_flag[2] != 0)
8923 {
8924 (void) ConcatenateString(&draw_info->primitive," ");
8925 (void) ConcatenateString(&draw_info->primitive,
8926 CommandOptionToMnemonic(MagickMethodOptions,
8927 argument_list[2].integer_reference));
8928 }
8929 if (attribute_flag[3] != 0)
8930 {
8931 (void) QueryColorCompliance(argument_list[3].string_reference,
8932 AllCompliance,&draw_info->stroke,exception);
8933 if (argument_list[3].image_reference != (Image *) NULL)
8934 draw_info->stroke_pattern=CloneImage(
8935 argument_list[3].image_reference,0,0,MagickTrue,exception);
8936 }
8937 if (attribute_flag[4] != 0)
8938 {
8939 (void) QueryColorCompliance(argument_list[4].string_reference,
8940 AllCompliance,&draw_info->fill,exception);
8941 if (argument_list[4].image_reference != (Image *) NULL)
8942 draw_info->fill_pattern=CloneImage(
8943 argument_list[4].image_reference,0,0,MagickTrue,exception);
8944 }
8945 if (attribute_flag[5] != 0)
8946 draw_info->stroke_width=argument_list[5].real_reference;
8947 if (attribute_flag[6] != 0)
8948 (void) CloneString(&draw_info->font,
8949 argument_list[6].string_reference);
8950 if (attribute_flag[7] != 0)
8951 (void) QueryColorCompliance(argument_list[7].string_reference,
8952 AllCompliance,&draw_info->border_color,exception);
8953 if (attribute_flag[8] != 0)
8954 draw_info->affine.tx=argument_list[8].real_reference;
8955 if (attribute_flag[9] != 0)
8956 draw_info->affine.ty=argument_list[9].real_reference;
8957 if (attribute_flag[20] != 0)
8958 {
8959 AV
8960 *av;
8961
8962 av=(AV *) argument_list[20].array_reference;
8963 if ((av_len(av) != 3) && (av_len(av) != 5))
8964 {
8965 ThrowPerlException(exception,OptionError,
8966 "affine matrix must have 4 or 6 elements",PackageName);
8967 goto PerlException;
8968 }
8969 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8970 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8971 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8972 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8973 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8974 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8975 {
8976 ThrowPerlException(exception,OptionError,
8977 "affine matrix is singular",PackageName);
8978 goto PerlException;
8979 }
8980 if (av_len(av) == 5)
8981 {
8982 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8983 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8984 }
8985 }
8986 for (j=10; j < 15; j++)
8987 {
8988 if (attribute_flag[j] == 0)
8989 continue;
8990 value=argument_list[j].string_reference;
8991 angle=argument_list[j].real_reference;
8992 current=draw_info->affine;
8993 GetAffineMatrix(&affine);
8994 switch (j)
8995 {
8996 case 10:
8997 {
8998 /*
8999 Translate.
9000 */
9001 flags=ParseGeometry(value,&geometry_info);
9002 affine.tx=geometry_info.xi;
9003 affine.ty=geometry_info.psi;
9004 if ((flags & PsiValue) == 0)
9005 affine.ty=affine.tx;
9006 break;
9007 }
9008 case 11:
9009 {
9010 /*
9011 Scale.
9012 */
9013 flags=ParseGeometry(value,&geometry_info);
9014 affine.sx=geometry_info.rho;
9015 affine.sy=geometry_info.sigma;
9016 if ((flags & SigmaValue) == 0)
9017 affine.sy=affine.sx;
9018 break;
9019 }
9020 case 12:
9021 {
9022 /*
9023 Rotate.
9024 */
9025 if (angle == 0.0)
9026 break;
9027 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9028 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9029 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9030 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9031 break;
9032 }
9033 case 13:
9034 {
9035 /*
9036 SkewX.
9037 */
9038 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9039 break;
9040 }
9041 case 14:
9042 {
9043 /*
9044 SkewY.
9045 */
9046 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9047 break;
9048 }
9049 }
9050 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9051 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9052 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9053 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9054 draw_info->affine.tx=
9055 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9056 draw_info->affine.ty=
9057 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9058 }
9059 if (attribute_flag[15] != 0)
9060 draw_info->fill_pattern=CloneImage(
9061 argument_list[15].image_reference,0,0,MagickTrue,exception);
9062 if (attribute_flag[16] != 0)
9063 draw_info->pointsize=argument_list[16].real_reference;
9064 if (attribute_flag[17] != 0)
9065 {
9066 draw_info->stroke_antialias=argument_list[17].integer_reference != 0
9067 ? MagickTrue : MagickFalse;
9068 draw_info->text_antialias=draw_info->stroke_antialias;
9069 }
9070 if (attribute_flag[18] != 0)
9071 (void) CloneString(&draw_info->density,
9072 argument_list[18].string_reference);
9073 if (attribute_flag[19] != 0)
9074 draw_info->stroke_width=argument_list[19].real_reference;
9075 if (attribute_flag[21] != 0)
9076 draw_info->dash_offset=argument_list[21].real_reference;
9077 if (attribute_flag[22] != 0)
9078 {
9079 AV
9080 *av;
9081
9082 av=(AV *) argument_list[22].array_reference;
9083 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9084 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9085 if (draw_info->dash_pattern != (double *) NULL)
9086 {
9087 for (i=0; i <= av_len(av); i++)
9088 draw_info->dash_pattern[i]=(double)
9089 SvNV(*(av_fetch(av,i,0)));
9090 draw_info->dash_pattern[i]=0.0;
9091 }
9092 }
9093 if (attribute_flag[23] != 0)
9094 image->interpolate=(PixelInterpolateMethod)
9095 argument_list[23].integer_reference;
9096 if ((attribute_flag[24] != 0) &&
9097 (draw_info->fill_pattern != (Image *) NULL))
9098 flags=ParsePageGeometry(draw_info->fill_pattern,
9099 argument_list[24].string_reference,
9100 &draw_info->fill_pattern->tile_offset,exception);
9101 if (attribute_flag[25] != 0)
9102 {
9103 (void) ConcatenateString(&draw_info->primitive," '");
9104 (void) ConcatenateString(&draw_info->primitive,
9105 argument_list[25].string_reference);
9106 (void) ConcatenateString(&draw_info->primitive,"'");
9107 }
9108 if (attribute_flag[26] != 0)
9109 draw_info->fill_pattern=CloneImage(
9110 argument_list[26].image_reference,0,0,MagickTrue,exception);
9111 if (attribute_flag[27] != 0)
9112 draw_info->stroke_pattern=CloneImage(
9113 argument_list[27].image_reference,0,0,MagickTrue,exception);
9114 if (attribute_flag[28] != 0)
9115 (void) CloneString(&draw_info->primitive,
9116 argument_list[28].string_reference);
9117 if (attribute_flag[29] != 0)
9118 draw_info->kerning=argument_list[29].real_reference;
9119 if (attribute_flag[30] != 0)
9120 draw_info->interline_spacing=argument_list[30].real_reference;
9121 if (attribute_flag[31] != 0)
9122 draw_info->interword_spacing=argument_list[31].real_reference;
9123 if (attribute_flag[32] != 0)
9124 draw_info->direction=(DirectionType)
9125 argument_list[32].integer_reference;
9126 DrawImage(image,draw_info,exception);
9127 draw_info=DestroyDrawInfo(draw_info);
9128 break;
9129 }
9130 case 39: /* Equalize */
9131 {
9132 if (attribute_flag[0] != 0)
9133 channel=(ChannelType) argument_list[0].integer_reference;
9134 channel_mask=SetImageChannelMask(image,channel);
9135 EqualizeImage(image,exception);
9136 (void) SetImageChannelMask(image,channel_mask);
9137 break;
9138 }
9139 case 40: /* Gamma */
9140 {
9141 if (attribute_flag[1] != 0)
9142 channel=(ChannelType) argument_list[1].integer_reference;
9143 if (attribute_flag[2] == 0)
9144 argument_list[2].real_reference=1.0;
9145 if (attribute_flag[3] == 0)
9146 argument_list[3].real_reference=1.0;
9147 if (attribute_flag[4] == 0)
9148 argument_list[4].real_reference=1.0;
9149 if (attribute_flag[0] == 0)
9150 {
cristy151b66d2015-04-15 10:50:31 +00009151 (void) FormatLocaleString(message,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -05009152 "%.20g,%.20g,%.20g",(double) argument_list[2].real_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009153 (double) argument_list[3].real_reference,
9154 (double) argument_list[4].real_reference);
9155 argument_list[0].string_reference=message;
9156 }
9157 (void) GammaImage(image,StringToDouble(
9158 argument_list[0].string_reference,(char **) NULL),exception);
9159 break;
9160 }
9161 case 41: /* Map */
9162 {
9163 QuantizeInfo
9164 *quantize_info;
9165
9166 if (attribute_flag[0] == 0)
9167 {
9168 ThrowPerlException(exception,OptionError,"MapImageRequired",
9169 PackageName);
9170 goto PerlException;
9171 }
9172 quantize_info=AcquireQuantizeInfo(info->image_info);
9173 if (attribute_flag[1] != 0)
9174 quantize_info->dither_method=(DitherMethod)
9175 argument_list[1].integer_reference;
9176 (void) RemapImages(quantize_info,image,
9177 argument_list[0].image_reference,exception);
9178 quantize_info=DestroyQuantizeInfo(quantize_info);
9179 break;
9180 }
9181 case 42: /* MatteFloodfill */
9182 {
9183 DrawInfo
9184 *draw_info;
9185
9186 MagickBooleanType
9187 invert;
9188
9189 PixelInfo
9190 target;
9191
9192 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9193 (DrawInfo *) NULL);
9194 if (attribute_flag[0] != 0)
9195 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9196 &geometry,exception);
9197 if (attribute_flag[1] != 0)
9198 geometry.x=argument_list[1].integer_reference;
9199 if (attribute_flag[2] != 0)
9200 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009201 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009202 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9203 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9204 geometry.x,geometry.y,&target,exception);
9205 if (attribute_flag[4] != 0)
9206 QueryColorCompliance(argument_list[4].string_reference,
9207 AllCompliance,&target,exception);
9208 if (attribute_flag[3] != 0)
9209 target.alpha=StringToDoubleInterval(
9210 argument_list[3].string_reference,(double) (double) QuantumRange+
9211 1.0);
9212 if (attribute_flag[5] != 0)
9213 image->fuzz=StringToDoubleInterval(
9214 argument_list[5].string_reference,(double) QuantumRange+1.0);
9215 invert=MagickFalse;
9216 if (attribute_flag[6] != 0)
9217 invert=(MagickBooleanType) argument_list[6].integer_reference;
9218 channel_mask=SetImageChannelMask(image,AlphaChannel);
9219 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9220 geometry.y,invert,exception);
9221 (void) SetImageChannelMask(image,channel_mask);
9222 draw_info=DestroyDrawInfo(draw_info);
9223 break;
9224 }
9225 case 43: /* Modulate */
9226 {
9227 char
cristy151b66d2015-04-15 10:50:31 +00009228 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009229
9230 geometry_info.rho=100.0;
9231 geometry_info.sigma=100.0;
9232 geometry_info.xi=100.0;
9233 if (attribute_flag[0] != 0)
9234 (void)ParseGeometry(argument_list[0].string_reference,
9235 &geometry_info);
9236 if (attribute_flag[1] != 0)
9237 geometry_info.xi=argument_list[1].real_reference;
9238 if (attribute_flag[2] != 0)
9239 geometry_info.sigma=argument_list[2].real_reference;
9240 if (attribute_flag[3] != 0)
9241 {
9242 geometry_info.sigma=argument_list[3].real_reference;
9243 SetImageArtifact(image,"modulate:colorspace","HWB");
9244 }
9245 if (attribute_flag[4] != 0)
9246 {
9247 geometry_info.rho=argument_list[4].real_reference;
9248 SetImageArtifact(image,"modulate:colorspace","HSB");
9249 }
9250 if (attribute_flag[5] != 0)
9251 {
9252 geometry_info.sigma=argument_list[5].real_reference;
9253 SetImageArtifact(image,"modulate:colorspace","HSL");
9254 }
9255 if (attribute_flag[6] != 0)
9256 {
9257 geometry_info.rho=argument_list[6].real_reference;
9258 SetImageArtifact(image,"modulate:colorspace","HWB");
9259 }
Cristy935a4052017-03-31 17:45:37 -04009260 (void) FormatLocaleString(modulate,MagickPathExtent,"%.20g,%.20g,%.20g",
9261 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy4a3ce0a2013-08-03 20:06:59 +00009262 (void) ModulateImage(image,modulate,exception);
9263 break;
9264 }
9265 case 44: /* Negate */
9266 {
9267 if (attribute_flag[0] == 0)
9268 argument_list[0].integer_reference=0;
9269 if (attribute_flag[1] != 0)
9270 channel=(ChannelType) argument_list[1].integer_reference;
9271 channel_mask=SetImageChannelMask(image,channel);
9272 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9273 MagickTrue : MagickFalse,exception);
9274 (void) SetImageChannelMask(image,channel_mask);
9275 break;
9276 }
9277 case 45: /* Normalize */
9278 {
9279 if (attribute_flag[0] != 0)
9280 channel=(ChannelType) argument_list[0].integer_reference;
9281 channel_mask=SetImageChannelMask(image,channel);
9282 NormalizeImage(image,exception);
9283 (void) SetImageChannelMask(image,channel_mask);
9284 break;
9285 }
9286 case 46: /* NumberColors */
9287 break;
9288 case 47: /* Opaque */
9289 {
9290 MagickBooleanType
9291 invert;
9292
9293 PixelInfo
9294 fill_color,
9295 target;
9296
9297 (void) QueryColorCompliance("none",AllCompliance,&target,
9298 exception);
9299 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9300 exception);
9301 if (attribute_flag[0] != 0)
9302 (void) QueryColorCompliance(argument_list[0].string_reference,
9303 AllCompliance,&target,exception);
9304 if (attribute_flag[1] != 0)
9305 (void) QueryColorCompliance(argument_list[1].string_reference,
9306 AllCompliance,&fill_color,exception);
9307 if (attribute_flag[2] != 0)
9308 image->fuzz=StringToDoubleInterval(
9309 argument_list[2].string_reference,(double) QuantumRange+1.0);
9310 if (attribute_flag[3] != 0)
9311 channel=(ChannelType) argument_list[3].integer_reference;
9312 invert=MagickFalse;
9313 if (attribute_flag[4] != 0)
9314 invert=(MagickBooleanType) argument_list[4].integer_reference;
9315 channel_mask=SetImageChannelMask(image,channel);
9316 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9317 (void) SetImageChannelMask(image,channel_mask);
9318 break;
9319 }
9320 case 48: /* Quantize */
9321 {
9322 QuantizeInfo
9323 *quantize_info;
9324
9325 quantize_info=AcquireQuantizeInfo(info->image_info);
9326 if (attribute_flag[0] != 0)
9327 quantize_info->number_colors=(size_t)
9328 argument_list[0].integer_reference;
9329 if (attribute_flag[1] != 0)
9330 quantize_info->tree_depth=(size_t)
9331 argument_list[1].integer_reference;
9332 if (attribute_flag[2] != 0)
9333 quantize_info->colorspace=(ColorspaceType)
9334 argument_list[2].integer_reference;
9335 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009336 quantize_info->dither_method=(DitherMethod)
9337 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009338 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009339 quantize_info->measure_error=
9340 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009341 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009342 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009343 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009344 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009345 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009346 argument_list[7].integer_reference;
9347 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009348 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009349 else
cristyf7563392014-03-25 13:54:04 +00009350 if ((image->storage_class == DirectClass) ||
9351 (image->colors > quantize_info->number_colors) ||
9352 (quantize_info->colorspace == GRAYColorspace))
9353 (void) QuantizeImage(quantize_info,image,exception);
9354 else
9355 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009356 quantize_info=DestroyQuantizeInfo(quantize_info);
9357 break;
9358 }
9359 case 49: /* Raise */
9360 {
9361 if (attribute_flag[0] != 0)
9362 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9363 &geometry,exception);
9364 if (attribute_flag[1] != 0)
9365 geometry.width=argument_list[1].integer_reference;
9366 if (attribute_flag[2] != 0)
9367 geometry.height=argument_list[2].integer_reference;
9368 if (attribute_flag[3] == 0)
9369 argument_list[3].integer_reference=1;
9370 (void) RaiseImage(image,&geometry,
9371 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9372 exception);
9373 break;
9374 }
9375 case 50: /* Segment */
9376 {
9377 ColorspaceType
9378 colorspace;
9379
9380 double
9381 cluster_threshold,
9382 smoothing_threshold;
9383
9384 MagickBooleanType
9385 verbose;
9386
9387 cluster_threshold=1.0;
9388 smoothing_threshold=1.5;
9389 colorspace=sRGBColorspace;
9390 verbose=MagickFalse;
9391 if (attribute_flag[0] != 0)
9392 {
9393 flags=ParseGeometry(argument_list[0].string_reference,
9394 &geometry_info);
9395 cluster_threshold=geometry_info.rho;
9396 if (flags & SigmaValue)
9397 smoothing_threshold=geometry_info.sigma;
9398 }
9399 if (attribute_flag[1] != 0)
9400 cluster_threshold=argument_list[1].real_reference;
9401 if (attribute_flag[2] != 0)
9402 smoothing_threshold=argument_list[2].real_reference;
9403 if (attribute_flag[3] != 0)
9404 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9405 if (attribute_flag[4] != 0)
9406 verbose=argument_list[4].integer_reference != 0 ?
9407 MagickTrue : MagickFalse;
9408 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9409 smoothing_threshold,exception);
9410 break;
9411 }
9412 case 51: /* Signature */
9413 {
9414 (void) SignatureImage(image,exception);
9415 break;
9416 }
9417 case 52: /* Solarize */
9418 {
9419 geometry_info.rho=QuantumRange/2.0;
9420 if (attribute_flag[0] != 0)
9421 flags=ParseGeometry(argument_list[0].string_reference,
9422 &geometry_info);
9423 if (attribute_flag[1] != 0)
9424 geometry_info.rho=StringToDoubleInterval(
9425 argument_list[1].string_reference,(double) QuantumRange+1.0);
9426 (void) SolarizeImage(image,geometry_info.rho,exception);
9427 break;
9428 }
9429 case 53: /* Sync */
9430 {
9431 (void) SyncImage(image,exception);
9432 break;
9433 }
9434 case 54: /* Texture */
9435 {
9436 if (attribute_flag[0] == 0)
9437 break;
9438 TextureImage(image,argument_list[0].image_reference,exception);
9439 break;
9440 }
9441 case 55: /* Evalute */
9442 {
9443 MagickEvaluateOperator
9444 op;
9445
9446 op=SetEvaluateOperator;
9447 if (attribute_flag[0] == MagickFalse)
9448 argument_list[0].real_reference=0.0;
9449 if (attribute_flag[1] != MagickFalse)
9450 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9451 if (attribute_flag[2] != MagickFalse)
9452 channel=(ChannelType) argument_list[2].integer_reference;
9453 channel_mask=SetImageChannelMask(image,channel);
9454 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9455 exception);
9456 (void) SetImageChannelMask(image,channel_mask);
9457 break;
9458 }
9459 case 56: /* Transparent */
9460 {
9461 double
9462 opacity;
9463
9464 MagickBooleanType
9465 invert;
9466
9467 PixelInfo
9468 target;
9469
9470 (void) QueryColorCompliance("none",AllCompliance,&target,
9471 exception);
9472 if (attribute_flag[0] != 0)
9473 (void) QueryColorCompliance(argument_list[0].string_reference,
9474 AllCompliance,&target,exception);
9475 opacity=TransparentAlpha;
9476 if (attribute_flag[1] != 0)
9477 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9478 (double) QuantumRange+1.0);
9479 if (attribute_flag[2] != 0)
9480 image->fuzz=StringToDoubleInterval(
9481 argument_list[2].string_reference,(double) QuantumRange+1.0);
9482 if (attribute_flag[3] == 0)
9483 argument_list[3].integer_reference=0;
9484 invert=MagickFalse;
9485 if (attribute_flag[3] != 0)
9486 invert=(MagickBooleanType) argument_list[3].integer_reference;
9487 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9488 invert,exception);
9489 break;
9490 }
9491 case 57: /* Threshold */
9492 {
9493 double
9494 threshold;
9495
9496 if (attribute_flag[0] == 0)
9497 argument_list[0].string_reference="50%";
9498 if (attribute_flag[1] != 0)
9499 channel=(ChannelType) argument_list[1].integer_reference;
9500 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9501 (double) QuantumRange+1.0);
9502 channel_mask=SetImageChannelMask(image,channel);
9503 (void) BilevelImage(image,threshold,exception);
9504 (void) SetImageChannelMask(image,channel_mask);
9505 break;
9506 }
9507 case 58: /* Charcoal */
9508 {
9509 if (attribute_flag[0] != 0)
9510 {
9511 flags=ParseGeometry(argument_list[0].string_reference,
9512 &geometry_info);
9513 if ((flags & SigmaValue) == 0)
9514 geometry_info.sigma=1.0;
9515 }
9516 if (attribute_flag[1] != 0)
9517 geometry_info.rho=argument_list[1].real_reference;
9518 if (attribute_flag[2] != 0)
9519 geometry_info.sigma=argument_list[2].real_reference;
9520 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9521 exception);
9522 break;
9523 }
9524 case 59: /* Trim */
9525 {
9526 if (attribute_flag[0] != 0)
9527 image->fuzz=StringToDoubleInterval(
9528 argument_list[0].string_reference,(double) QuantumRange+1.0);
9529 image=TrimImage(image,exception);
9530 break;
9531 }
9532 case 60: /* Wave */
9533 {
9534 PixelInterpolateMethod
9535 method;
9536
9537 if (attribute_flag[0] != 0)
9538 {
9539 flags=ParseGeometry(argument_list[0].string_reference,
9540 &geometry_info);
9541 if ((flags & SigmaValue) == 0)
9542 geometry_info.sigma=1.0;
9543 }
9544 if (attribute_flag[1] != 0)
9545 geometry_info.rho=argument_list[1].real_reference;
9546 if (attribute_flag[2] != 0)
9547 geometry_info.sigma=argument_list[2].real_reference;
9548 method=UndefinedInterpolatePixel;
9549 if (attribute_flag[3] != 0)
9550 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9551 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9552 method,exception);
9553 break;
9554 }
9555 case 61: /* Separate */
9556 {
9557 if (attribute_flag[0] != 0)
9558 channel=(ChannelType) argument_list[0].integer_reference;
9559 image=SeparateImage(image,channel,exception);
9560 break;
9561 }
9562 case 63: /* Stereo */
9563 {
9564 if (attribute_flag[0] == 0)
9565 {
9566 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9567 PackageName);
9568 goto PerlException;
9569 }
9570 if (attribute_flag[1] != 0)
9571 geometry.x=argument_list[1].integer_reference;
9572 if (attribute_flag[2] != 0)
9573 geometry.y=argument_list[2].integer_reference;
9574 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9575 geometry.x,geometry.y,exception);
9576 break;
9577 }
9578 case 64: /* Stegano */
9579 {
9580 if (attribute_flag[0] == 0)
9581 {
9582 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9583 PackageName);
9584 goto PerlException;
9585 }
9586 if (attribute_flag[1] == 0)
9587 argument_list[1].integer_reference=0;
9588 image->offset=argument_list[1].integer_reference;
9589 image=SteganoImage(image,argument_list[0].image_reference,exception);
9590 break;
9591 }
9592 case 65: /* Deconstruct */
9593 {
9594 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9595 break;
9596 }
9597 case 66: /* GaussianBlur */
9598 {
9599 if (attribute_flag[0] != 0)
9600 {
9601 flags=ParseGeometry(argument_list[0].string_reference,
9602 &geometry_info);
9603 if ((flags & SigmaValue) == 0)
9604 geometry_info.sigma=1.0;
9605 }
9606 if (attribute_flag[1] != 0)
9607 geometry_info.rho=argument_list[1].real_reference;
9608 if (attribute_flag[2] != 0)
9609 geometry_info.sigma=argument_list[2].real_reference;
9610 if (attribute_flag[3] != 0)
9611 channel=(ChannelType) argument_list[3].integer_reference;
9612 channel_mask=SetImageChannelMask(image,channel);
9613 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9614 exception);
9615 if (image != (Image *) NULL)
9616 (void) SetImageChannelMask(image,channel_mask);
9617 break;
9618 }
9619 case 67: /* Convolve */
9620 {
9621 KernelInfo
9622 *kernel;
9623
9624 kernel=(KernelInfo *) NULL;
9625 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9626 break;
9627 if (attribute_flag[0] != 0)
9628 {
9629 AV
9630 *av;
9631
9632 size_t
9633 order;
9634
cristy2c57b742014-10-31 00:40:34 +00009635 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009636 if (kernel == (KernelInfo *) NULL)
9637 break;
9638 av=(AV *) argument_list[0].array_reference;
9639 order=(size_t) sqrt(av_len(av)+1);
9640 kernel->width=order;
9641 kernel->height=order;
9642 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9643 order*sizeof(*kernel->values));
9644 if (kernel->values == (MagickRealType *) NULL)
9645 {
9646 kernel=DestroyKernelInfo(kernel);
9647 ThrowPerlException(exception,ResourceLimitFatalError,
9648 "MemoryAllocationFailed",PackageName);
9649 goto PerlException;
9650 }
9651 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9652 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9653 for ( ; j < (ssize_t) (order*order); j++)
9654 kernel->values[j]=0.0;
9655 }
9656 if (attribute_flag[1] != 0)
9657 channel=(ChannelType) argument_list[1].integer_reference;
9658 if (attribute_flag[2] != 0)
9659 SetImageArtifact(image,"filter:blur",
9660 argument_list[2].string_reference);
9661 if (attribute_flag[3] != 0)
9662 {
cristy2c57b742014-10-31 00:40:34 +00009663 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9664 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009665 if (kernel == (KernelInfo *) NULL)
9666 break;
9667 }
9668 channel_mask=SetImageChannelMask(image,channel);
9669 image=ConvolveImage(image,kernel,exception);
9670 if (image != (Image *) NULL)
9671 (void) SetImageChannelMask(image,channel_mask);
9672 kernel=DestroyKernelInfo(kernel);
9673 break;
9674 }
9675 case 68: /* Profile */
9676 {
9677 const char
9678 *name;
9679
9680 Image
9681 *profile_image;
9682
9683 ImageInfo
9684 *profile_info;
9685
9686 StringInfo
9687 *profile;
9688
9689 name="*";
9690 if (attribute_flag[0] != 0)
9691 name=argument_list[0].string_reference;
9692 if (attribute_flag[2] != 0)
9693 image->rendering_intent=(RenderingIntent)
9694 argument_list[2].integer_reference;
9695 if (attribute_flag[3] != 0)
9696 image->black_point_compensation=
9697 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9698 if (attribute_flag[1] != 0)
9699 {
9700 if (argument_list[1].length == 0)
9701 {
9702 /*
9703 Remove a profile from the image.
9704 */
9705 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9706 exception);
9707 break;
9708 }
9709 /*
9710 Associate user supplied profile with the image.
9711 */
9712 profile=AcquireStringInfo(argument_list[1].length);
9713 SetStringInfoDatum(profile,(const unsigned char *)
9714 argument_list[1].string_reference);
9715 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9716 (size_t) GetStringInfoLength(profile),exception);
9717 profile=DestroyStringInfo(profile);
9718 break;
9719 }
9720 /*
9721 Associate a profile with the image.
9722 */
9723 profile_info=CloneImageInfo(info ? info->image_info :
9724 (ImageInfo *) NULL);
9725 profile_image=ReadImages(profile_info,name,exception);
9726 if (profile_image == (Image *) NULL)
9727 break;
9728 ResetImageProfileIterator(profile_image);
9729 name=GetNextImageProfile(profile_image);
9730 while (name != (const char *) NULL)
9731 {
9732 const StringInfo
9733 *profile;
9734
9735 profile=GetImageProfile(profile_image,name);
9736 if (profile != (const StringInfo *) NULL)
9737 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9738 (size_t) GetStringInfoLength(profile),exception);
9739 name=GetNextImageProfile(profile_image);
9740 }
9741 profile_image=DestroyImage(profile_image);
9742 profile_info=DestroyImageInfo(profile_info);
9743 break;
9744 }
9745 case 69: /* UnsharpMask */
9746 {
9747 if (attribute_flag[0] != 0)
9748 {
9749 flags=ParseGeometry(argument_list[0].string_reference,
9750 &geometry_info);
9751 if ((flags & SigmaValue) == 0)
9752 geometry_info.sigma=1.0;
9753 if ((flags & XiValue) == 0)
9754 geometry_info.xi=1.0;
9755 if ((flags & PsiValue) == 0)
9756 geometry_info.psi=0.5;
9757 }
9758 if (attribute_flag[1] != 0)
9759 geometry_info.rho=argument_list[1].real_reference;
9760 if (attribute_flag[2] != 0)
9761 geometry_info.sigma=argument_list[2].real_reference;
9762 if (attribute_flag[3] != 0)
9763 geometry_info.xi=argument_list[3].real_reference;
9764 if (attribute_flag[4] != 0)
9765 geometry_info.psi=argument_list[4].real_reference;
9766 if (attribute_flag[5] != 0)
9767 channel=(ChannelType) argument_list[5].integer_reference;
9768 channel_mask=SetImageChannelMask(image,channel);
9769 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9770 geometry_info.xi,geometry_info.psi,exception);
9771 if (image != (Image *) NULL)
9772 (void) SetImageChannelMask(image,channel_mask);
9773 break;
9774 }
9775 case 70: /* MotionBlur */
9776 {
9777 if (attribute_flag[0] != 0)
9778 {
9779 flags=ParseGeometry(argument_list[0].string_reference,
9780 &geometry_info);
9781 if ((flags & SigmaValue) == 0)
9782 geometry_info.sigma=1.0;
9783 if ((flags & XiValue) == 0)
9784 geometry_info.xi=1.0;
9785 }
9786 if (attribute_flag[1] != 0)
9787 geometry_info.rho=argument_list[1].real_reference;
9788 if (attribute_flag[2] != 0)
9789 geometry_info.sigma=argument_list[2].real_reference;
9790 if (attribute_flag[3] != 0)
9791 geometry_info.xi=argument_list[3].real_reference;
9792 if (attribute_flag[4] != 0)
9793 channel=(ChannelType) argument_list[4].integer_reference;
9794 channel_mask=SetImageChannelMask(image,channel);
9795 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9796 geometry_info.xi,exception);
9797 if (image != (Image *) NULL)
9798 (void) SetImageChannelMask(image,channel_mask);
9799 break;
9800 }
9801 case 71: /* OrderedDither */
9802 {
9803 if (attribute_flag[0] == 0)
9804 argument_list[0].string_reference="o8x8";
9805 if (attribute_flag[1] != 0)
9806 channel=(ChannelType) argument_list[1].integer_reference;
9807 channel_mask=SetImageChannelMask(image,channel);
Cristy6b93c072016-02-04 07:45:48 -05009808 (void) OrderedDitherImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009809 exception);
9810 (void) SetImageChannelMask(image,channel_mask);
9811 break;
9812 }
9813 case 72: /* Shave */
9814 {
9815 if (attribute_flag[0] != 0)
9816 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9817 &geometry,exception);
9818 if (attribute_flag[1] != 0)
9819 geometry.width=argument_list[1].integer_reference;
9820 if (attribute_flag[2] != 0)
9821 geometry.height=argument_list[2].integer_reference;
9822 image=ShaveImage(image,&geometry,exception);
9823 break;
9824 }
9825 case 73: /* Level */
9826 {
9827 double
9828 black_point,
9829 gamma,
9830 white_point;
9831
9832 black_point=0.0;
9833 white_point=(double) image->columns*image->rows;
9834 gamma=1.0;
9835 if (attribute_flag[0] != 0)
9836 {
9837 flags=ParseGeometry(argument_list[0].string_reference,
9838 &geometry_info);
9839 black_point=geometry_info.rho;
9840 if ((flags & SigmaValue) != 0)
9841 white_point=geometry_info.sigma;
9842 if ((flags & XiValue) != 0)
9843 gamma=geometry_info.xi;
9844 if ((flags & PercentValue) != 0)
9845 {
9846 black_point*=(double) (QuantumRange/100.0);
9847 white_point*=(double) (QuantumRange/100.0);
9848 }
9849 if ((flags & SigmaValue) == 0)
9850 white_point=(double) QuantumRange-black_point;
9851 }
9852 if (attribute_flag[1] != 0)
9853 black_point=argument_list[1].real_reference;
9854 if (attribute_flag[2] != 0)
9855 white_point=argument_list[2].real_reference;
9856 if (attribute_flag[3] != 0)
9857 gamma=argument_list[3].real_reference;
9858 if (attribute_flag[4] != 0)
9859 channel=(ChannelType) argument_list[4].integer_reference;
9860 if (attribute_flag[5] != 0)
9861 {
9862 argument_list[0].real_reference=argument_list[5].real_reference;
9863 attribute_flag[0]=attribute_flag[5];
9864 }
9865 channel_mask=SetImageChannelMask(image,channel);
9866 (void) LevelImage(image,black_point,white_point,gamma,exception);
9867 (void) SetImageChannelMask(image,channel_mask);
9868 break;
9869 }
9870 case 74: /* Clip */
9871 {
9872 if (attribute_flag[0] == 0)
9873 argument_list[0].string_reference="#1";
9874 if (attribute_flag[1] == 0)
9875 argument_list[1].integer_reference=MagickTrue;
9876 (void) ClipImagePath(image,argument_list[0].string_reference,
9877 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9878 exception);
9879 break;
9880 }
9881 case 75: /* AffineTransform */
9882 {
9883 DrawInfo
9884 *draw_info;
9885
9886 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9887 (DrawInfo *) NULL);
9888 if (attribute_flag[0] != 0)
9889 {
9890 AV
9891 *av;
9892
9893 av=(AV *) argument_list[0].array_reference;
9894 if ((av_len(av) != 3) && (av_len(av) != 5))
9895 {
9896 ThrowPerlException(exception,OptionError,
9897 "affine matrix must have 4 or 6 elements",PackageName);
9898 goto PerlException;
9899 }
9900 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9901 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9902 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9903 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9904 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9905 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9906 {
9907 ThrowPerlException(exception,OptionError,
9908 "affine matrix is singular",PackageName);
9909 goto PerlException;
9910 }
9911 if (av_len(av) == 5)
9912 {
9913 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9914 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9915 }
9916 }
9917 for (j=1; j < 6; j++)
9918 {
9919 if (attribute_flag[j] == 0)
9920 continue;
9921 value=argument_list[j].string_reference;
9922 angle=argument_list[j].real_reference;
9923 current=draw_info->affine;
9924 GetAffineMatrix(&affine);
9925 switch (j)
9926 {
9927 case 1:
9928 {
9929 /*
9930 Translate.
9931 */
9932 flags=ParseGeometry(value,&geometry_info);
9933 affine.tx=geometry_info.xi;
9934 affine.ty=geometry_info.psi;
9935 if ((flags & PsiValue) == 0)
9936 affine.ty=affine.tx;
9937 break;
9938 }
9939 case 2:
9940 {
9941 /*
9942 Scale.
9943 */
9944 flags=ParseGeometry(value,&geometry_info);
9945 affine.sx=geometry_info.rho;
9946 affine.sy=geometry_info.sigma;
9947 if ((flags & SigmaValue) == 0)
9948 affine.sy=affine.sx;
9949 break;
9950 }
9951 case 3:
9952 {
9953 /*
9954 Rotate.
9955 */
9956 if (angle == 0.0)
9957 break;
9958 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9959 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9960 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9961 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9962 break;
9963 }
9964 case 4:
9965 {
9966 /*
9967 SkewX.
9968 */
9969 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9970 break;
9971 }
9972 case 5:
9973 {
9974 /*
9975 SkewY.
9976 */
9977 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9978 break;
9979 }
9980 }
9981 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9982 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9983 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9984 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9985 draw_info->affine.tx=
9986 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9987 draw_info->affine.ty=
9988 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9989 }
9990 if (attribute_flag[6] != 0)
9991 image->interpolate=(PixelInterpolateMethod)
9992 argument_list[6].integer_reference;
9993 if (attribute_flag[7] != 0)
9994 QueryColorCompliance(argument_list[7].string_reference,
9995 AllCompliance,&image->background_color,exception);
9996 image=AffineTransformImage(image,&draw_info->affine,exception);
9997 draw_info=DestroyDrawInfo(draw_info);
9998 break;
9999 }
10000 case 76: /* Difference */
10001 {
10002 if (attribute_flag[0] == 0)
10003 {
10004 ThrowPerlException(exception,OptionError,
10005 "ReferenceImageRequired",PackageName);
10006 goto PerlException;
10007 }
10008 if (attribute_flag[1] != 0)
10009 image->fuzz=StringToDoubleInterval(
10010 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -050010011 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +000010012 exception);
10013 break;
10014 }
10015 case 77: /* AdaptiveThreshold */
10016 {
10017 if (attribute_flag[0] != 0)
10018 {
10019 flags=ParseGeometry(argument_list[0].string_reference,
10020 &geometry_info);
10021 if ((flags & PercentValue) != 0)
10022 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10023 }
10024 if (attribute_flag[1] != 0)
10025 geometry_info.rho=argument_list[1].integer_reference;
10026 if (attribute_flag[2] != 0)
10027 geometry_info.sigma=argument_list[2].integer_reference;
10028 if (attribute_flag[3] != 0)
10029 geometry_info.xi=argument_list[3].integer_reference;;
10030 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
10031 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
10032 break;
10033 }
10034 case 78: /* Resample */
10035 {
10036 size_t
10037 height,
10038 width;
10039
10040 if (attribute_flag[0] != 0)
10041 {
10042 flags=ParseGeometry(argument_list[0].string_reference,
10043 &geometry_info);
10044 if ((flags & SigmaValue) == 0)
10045 geometry_info.sigma=geometry_info.rho;
10046 }
10047 if (attribute_flag[1] != 0)
10048 geometry_info.rho=argument_list[1].real_reference;
10049 if (attribute_flag[2] != 0)
10050 geometry_info.sigma=argument_list[2].real_reference;
10051 if (attribute_flag[3] == 0)
10052 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10053 if (attribute_flag[4] == 0)
10054 SetImageArtifact(image,"filter:support",
10055 argument_list[4].string_reference);
10056 width=(size_t) (geometry_info.rho*image->columns/
10057 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10058 height=(size_t) (geometry_info.sigma*image->rows/
10059 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
Cristy8645e042016-02-03 16:35:29 -050010060 image=ResizeImage(image,width,height,(FilterType)
cristy4a3ce0a2013-08-03 20:06:59 +000010061 argument_list[3].integer_reference,exception);
10062 if (image != (Image *) NULL)
10063 {
10064 image->resolution.x=geometry_info.rho;
10065 image->resolution.y=geometry_info.sigma;
10066 }
10067 break;
10068 }
10069 case 79: /* Describe */
10070 {
10071 if (attribute_flag[0] == 0)
10072 argument_list[0].file_reference=(FILE *) NULL;
10073 if (attribute_flag[1] != 0)
10074 (void) SetImageArtifact(image,"identify:features",
10075 argument_list[1].string_reference);
10076 (void) IdentifyImage(image,argument_list[0].file_reference,
10077 MagickTrue,exception);
10078 break;
10079 }
10080 case 80: /* BlackThreshold */
10081 {
10082 if (attribute_flag[0] == 0)
10083 argument_list[0].string_reference="50%";
10084 if (attribute_flag[2] != 0)
10085 channel=(ChannelType) argument_list[2].integer_reference;
10086 channel_mask=SetImageChannelMask(image,channel);
10087 BlackThresholdImage(image,argument_list[0].string_reference,
10088 exception);
10089 (void) SetImageChannelMask(image,channel_mask);
10090 break;
10091 }
10092 case 81: /* WhiteThreshold */
10093 {
10094 if (attribute_flag[0] == 0)
10095 argument_list[0].string_reference="50%";
10096 if (attribute_flag[2] != 0)
10097 channel=(ChannelType) argument_list[2].integer_reference;
10098 channel_mask=SetImageChannelMask(image,channel);
10099 WhiteThresholdImage(image,argument_list[0].string_reference,
10100 exception);
10101 (void) SetImageChannelMask(image,channel_mask);
10102 break;
10103 }
cristy60c73c02014-03-25 12:09:58 +000010104 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010105 {
10106 if (attribute_flag[0] != 0)
10107 {
10108 flags=ParseGeometry(argument_list[0].string_reference,
10109 &geometry_info);
10110 }
10111 if (attribute_flag[1] != 0)
10112 geometry_info.rho=argument_list[1].real_reference;
10113 if (attribute_flag[2] != 0)
10114 channel=(ChannelType) argument_list[2].integer_reference;
10115 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010116 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010117 if (image != (Image *) NULL)
10118 (void) SetImageChannelMask(image,channel_mask);
10119 break;
10120 }
10121 case 83: /* Thumbnail */
10122 {
10123 if (attribute_flag[0] != 0)
10124 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10125 &geometry,exception);
10126 if (attribute_flag[1] != 0)
10127 geometry.width=argument_list[1].integer_reference;
10128 if (attribute_flag[2] != 0)
10129 geometry.height=argument_list[2].integer_reference;
10130 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10131 break;
10132 }
10133 case 84: /* Strip */
10134 {
10135 (void) StripImage(image,exception);
10136 break;
10137 }
10138 case 85: /* Tint */
10139 {
10140 PixelInfo
10141 tint;
10142
10143 GetPixelInfo(image,&tint);
10144 if (attribute_flag[0] != 0)
10145 (void) QueryColorCompliance(argument_list[0].string_reference,
10146 AllCompliance,&tint,exception);
10147 if (attribute_flag[1] == 0)
10148 argument_list[1].string_reference="100";
10149 image=TintImage(image,argument_list[1].string_reference,&tint,
10150 exception);
10151 break;
10152 }
10153 case 86: /* Channel */
10154 {
10155 if (attribute_flag[0] != 0)
10156 channel=(ChannelType) argument_list[0].integer_reference;
10157 image=SeparateImage(image,channel,exception);
10158 break;
10159 }
10160 case 87: /* Splice */
10161 {
cristy260bd762014-08-15 12:46:34 +000010162 if (attribute_flag[7] != 0)
10163 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010164 if (attribute_flag[0] != 0)
10165 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10166 &geometry,exception);
10167 if (attribute_flag[1] != 0)
10168 geometry.width=argument_list[1].integer_reference;
10169 if (attribute_flag[2] != 0)
10170 geometry.height=argument_list[2].integer_reference;
10171 if (attribute_flag[3] != 0)
10172 geometry.x=argument_list[3].integer_reference;
10173 if (attribute_flag[4] != 0)
10174 geometry.y=argument_list[4].integer_reference;
10175 if (attribute_flag[5] != 0)
10176 image->fuzz=StringToDoubleInterval(
10177 argument_list[5].string_reference,(double) QuantumRange+1.0);
10178 if (attribute_flag[6] != 0)
10179 (void) QueryColorCompliance(argument_list[6].string_reference,
10180 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010181 image=SpliceImage(image,&geometry,exception);
10182 break;
10183 }
10184 case 88: /* Posterize */
10185 {
10186 if (attribute_flag[0] == 0)
10187 argument_list[0].integer_reference=3;
10188 if (attribute_flag[1] == 0)
10189 argument_list[1].integer_reference=0;
10190 (void) PosterizeImage(image,argument_list[0].integer_reference,
10191 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10192 NoDitherMethod,exception);
10193 break;
10194 }
10195 case 89: /* Shadow */
10196 {
10197 if (attribute_flag[0] != 0)
10198 {
10199 flags=ParseGeometry(argument_list[0].string_reference,
10200 &geometry_info);
10201 if ((flags & SigmaValue) == 0)
10202 geometry_info.sigma=1.0;
10203 if ((flags & XiValue) == 0)
10204 geometry_info.xi=4.0;
10205 if ((flags & PsiValue) == 0)
10206 geometry_info.psi=4.0;
10207 }
10208 if (attribute_flag[1] != 0)
10209 geometry_info.rho=argument_list[1].real_reference;
10210 if (attribute_flag[2] != 0)
10211 geometry_info.sigma=argument_list[2].real_reference;
10212 if (attribute_flag[3] != 0)
10213 geometry_info.xi=argument_list[3].integer_reference;
10214 if (attribute_flag[4] != 0)
10215 geometry_info.psi=argument_list[4].integer_reference;
10216 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10217 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10218 ceil(geometry_info.psi-0.5),exception);
10219 break;
10220 }
10221 case 90: /* Identify */
10222 {
10223 if (attribute_flag[0] == 0)
10224 argument_list[0].file_reference=(FILE *) NULL;
10225 if (attribute_flag[1] != 0)
10226 (void) SetImageArtifact(image,"identify:features",
10227 argument_list[1].string_reference);
10228 if ((attribute_flag[2] != 0) &&
10229 (argument_list[2].integer_reference != 0))
10230 (void) SetImageArtifact(image,"identify:unique","true");
10231 (void) IdentifyImage(image,argument_list[0].file_reference,
10232 MagickTrue,exception);
10233 break;
10234 }
10235 case 91: /* SepiaTone */
10236 {
10237 if (attribute_flag[0] == 0)
10238 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10239 image=SepiaToneImage(image,argument_list[0].real_reference,
10240 exception);
10241 break;
10242 }
10243 case 92: /* SigmoidalContrast */
10244 {
10245 MagickBooleanType
10246 sharpen;
10247
10248 if (attribute_flag[0] != 0)
10249 {
10250 flags=ParseGeometry(argument_list[0].string_reference,
10251 &geometry_info);
10252 if ((flags & SigmaValue) == 0)
10253 geometry_info.sigma=QuantumRange/2.0;
10254 if ((flags & PercentValue) != 0)
10255 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10256 }
10257 if (attribute_flag[1] != 0)
10258 geometry_info.rho=argument_list[1].real_reference;
10259 if (attribute_flag[2] != 0)
10260 geometry_info.sigma=argument_list[2].real_reference;
10261 if (attribute_flag[3] != 0)
10262 channel=(ChannelType) argument_list[3].integer_reference;
10263 sharpen=MagickTrue;
10264 if (attribute_flag[4] != 0)
10265 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10266 MagickFalse;
10267 channel_mask=SetImageChannelMask(image,channel);
10268 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10269 geometry_info.sigma,exception);
10270 (void) SetImageChannelMask(image,channel_mask);
10271 break;
10272 }
10273 case 93: /* Extent */
10274 {
10275 if (attribute_flag[7] != 0)
10276 image->gravity=(GravityType) argument_list[7].integer_reference;
10277 if (attribute_flag[0] != 0)
10278 {
10279 int
10280 flags;
10281
10282 flags=ParseGravityGeometry(image,
10283 argument_list[0].string_reference,&geometry,exception);
10284 (void) flags;
10285 if (geometry.width == 0)
10286 geometry.width=image->columns;
10287 if (geometry.height == 0)
10288 geometry.height=image->rows;
10289 }
10290 if (attribute_flag[1] != 0)
10291 geometry.width=argument_list[1].integer_reference;
10292 if (attribute_flag[2] != 0)
10293 geometry.height=argument_list[2].integer_reference;
10294 if (attribute_flag[3] != 0)
10295 geometry.x=argument_list[3].integer_reference;
10296 if (attribute_flag[4] != 0)
10297 geometry.y=argument_list[4].integer_reference;
10298 if (attribute_flag[5] != 0)
10299 image->fuzz=StringToDoubleInterval(
10300 argument_list[5].string_reference,(double) QuantumRange+1.0);
10301 if (attribute_flag[6] != 0)
10302 (void) QueryColorCompliance(argument_list[6].string_reference,
10303 AllCompliance,&image->background_color,exception);
10304 image=ExtentImage(image,&geometry,exception);
10305 break;
10306 }
10307 case 94: /* Vignette */
10308 {
10309 if (attribute_flag[0] != 0)
10310 {
10311 flags=ParseGeometry(argument_list[0].string_reference,
10312 &geometry_info);
10313 if ((flags & SigmaValue) == 0)
10314 geometry_info.sigma=1.0;
10315 if ((flags & XiValue) == 0)
10316 geometry_info.xi=0.1*image->columns;
10317 if ((flags & PsiValue) == 0)
10318 geometry_info.psi=0.1*image->rows;
10319 }
10320 if (attribute_flag[1] != 0)
10321 geometry_info.rho=argument_list[1].real_reference;
10322 if (attribute_flag[2] != 0)
10323 geometry_info.sigma=argument_list[2].real_reference;
10324 if (attribute_flag[3] != 0)
10325 geometry_info.xi=argument_list[3].integer_reference;
10326 if (attribute_flag[4] != 0)
10327 geometry_info.psi=argument_list[4].integer_reference;
10328 if (attribute_flag[5] != 0)
10329 (void) QueryColorCompliance(argument_list[5].string_reference,
10330 AllCompliance,&image->background_color,exception);
10331 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10332 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10333 ceil(geometry_info.psi-0.5),exception);
10334 break;
10335 }
10336 case 95: /* ContrastStretch */
10337 {
10338 double
10339 black_point,
10340 white_point;
10341
10342 black_point=0.0;
10343 white_point=(double) image->columns*image->rows;
10344 if (attribute_flag[0] != 0)
10345 {
10346 flags=ParseGeometry(argument_list[0].string_reference,
10347 &geometry_info);
10348 black_point=geometry_info.rho;
10349 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10350 black_point;
10351 if ((flags & PercentValue) != 0)
10352 {
10353 black_point*=(double) image->columns*image->rows/100.0;
10354 white_point*=(double) image->columns*image->rows/100.0;
10355 }
10356 white_point=(double) image->columns*image->rows-
10357 white_point;
10358 }
10359 if (attribute_flag[1] != 0)
10360 black_point=argument_list[1].real_reference;
10361 if (attribute_flag[2] != 0)
10362 white_point=argument_list[2].real_reference;
10363 if (attribute_flag[4] != 0)
10364 channel=(ChannelType) argument_list[4].integer_reference;
10365 channel_mask=SetImageChannelMask(image,channel);
10366 (void) ContrastStretchImage(image,black_point,white_point,exception);
10367 (void) SetImageChannelMask(image,channel_mask);
10368 break;
10369 }
10370 case 96: /* Sans0 */
10371 {
10372 break;
10373 }
10374 case 97: /* Sans1 */
10375 {
10376 break;
10377 }
10378 case 98: /* AdaptiveSharpen */
10379 {
10380 if (attribute_flag[0] != 0)
10381 {
10382 flags=ParseGeometry(argument_list[0].string_reference,
10383 &geometry_info);
10384 if ((flags & SigmaValue) == 0)
10385 geometry_info.sigma=1.0;
10386 if ((flags & XiValue) == 0)
10387 geometry_info.xi=0.0;
10388 }
10389 if (attribute_flag[1] != 0)
10390 geometry_info.rho=argument_list[1].real_reference;
10391 if (attribute_flag[2] != 0)
10392 geometry_info.sigma=argument_list[2].real_reference;
10393 if (attribute_flag[3] != 0)
10394 geometry_info.xi=argument_list[3].real_reference;
10395 if (attribute_flag[4] != 0)
10396 channel=(ChannelType) argument_list[4].integer_reference;
10397 channel_mask=SetImageChannelMask(image,channel);
10398 image=AdaptiveSharpenImage(image,geometry_info.rho,
10399 geometry_info.sigma,exception);
10400 if (image != (Image *) NULL)
10401 (void) SetImageChannelMask(image,channel_mask);
10402 break;
10403 }
10404 case 99: /* Transpose */
10405 {
10406 image=TransposeImage(image,exception);
10407 break;
10408 }
10409 case 100: /* Tranverse */
10410 {
10411 image=TransverseImage(image,exception);
10412 break;
10413 }
10414 case 101: /* AutoOrient */
10415 {
10416 image=AutoOrientImage(image,image->orientation,exception);
10417 break;
10418 }
10419 case 102: /* AdaptiveBlur */
10420 {
10421 if (attribute_flag[0] != 0)
10422 {
10423 flags=ParseGeometry(argument_list[0].string_reference,
10424 &geometry_info);
10425 if ((flags & SigmaValue) == 0)
10426 geometry_info.sigma=1.0;
10427 if ((flags & XiValue) == 0)
10428 geometry_info.xi=0.0;
10429 }
10430 if (attribute_flag[1] != 0)
10431 geometry_info.rho=argument_list[1].real_reference;
10432 if (attribute_flag[2] != 0)
10433 geometry_info.sigma=argument_list[2].real_reference;
10434 if (attribute_flag[3] != 0)
10435 channel=(ChannelType) argument_list[3].integer_reference;
10436 channel_mask=SetImageChannelMask(image,channel);
10437 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10438 exception);
10439 if (image != (Image *) NULL)
10440 (void) SetImageChannelMask(image,channel_mask);
10441 break;
10442 }
10443 case 103: /* Sketch */
10444 {
10445 if (attribute_flag[0] != 0)
10446 {
10447 flags=ParseGeometry(argument_list[0].string_reference,
10448 &geometry_info);
10449 if ((flags & SigmaValue) == 0)
10450 geometry_info.sigma=1.0;
10451 if ((flags & XiValue) == 0)
10452 geometry_info.xi=1.0;
10453 }
10454 if (attribute_flag[1] != 0)
10455 geometry_info.rho=argument_list[1].real_reference;
10456 if (attribute_flag[2] != 0)
10457 geometry_info.sigma=argument_list[2].real_reference;
10458 if (attribute_flag[3] != 0)
10459 geometry_info.xi=argument_list[3].real_reference;
10460 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10461 geometry_info.xi,exception);
10462 break;
10463 }
10464 case 104: /* UniqueColors */
10465 {
10466 image=UniqueImageColors(image,exception);
10467 break;
10468 }
10469 case 105: /* AdaptiveResize */
10470 {
10471 if (attribute_flag[0] != 0)
10472 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10473 &geometry,exception);
10474 if (attribute_flag[1] != 0)
10475 geometry.width=argument_list[1].integer_reference;
10476 if (attribute_flag[2] != 0)
10477 geometry.height=argument_list[2].integer_reference;
10478 if (attribute_flag[3] != 0)
Cristy8645e042016-02-03 16:35:29 -050010479 image->filter=(FilterType) argument_list[4].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010480 if (attribute_flag[4] != 0)
10481 SetImageArtifact(image,"filter:support",
10482 argument_list[4].string_reference);
10483 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10484 exception);
10485 break;
10486 }
10487 case 106: /* ClipMask */
10488 {
10489 Image
10490 *mask_image;
10491
10492 if (attribute_flag[0] == 0)
10493 {
10494 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10495 PackageName);
10496 goto PerlException;
10497 }
10498 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10499 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010500 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010501 mask_image=DestroyImage(mask_image);
10502 break;
10503 }
10504 case 107: /* LinearStretch */
10505 {
10506 double
10507 black_point,
10508 white_point;
10509
10510 black_point=0.0;
10511 white_point=(double) image->columns*image->rows;
10512 if (attribute_flag[0] != 0)
10513 {
10514 flags=ParseGeometry(argument_list[0].string_reference,
10515 &geometry_info);
10516 if ((flags & SigmaValue) != 0)
10517 white_point=geometry_info.sigma;
10518 if ((flags & PercentValue) != 0)
10519 {
10520 black_point*=(double) image->columns*image->rows/100.0;
10521 white_point*=(double) image->columns*image->rows/100.0;
10522 }
10523 if ((flags & SigmaValue) == 0)
10524 white_point=(double) image->columns*image->rows-black_point;
10525 }
10526 if (attribute_flag[1] != 0)
10527 black_point=argument_list[1].real_reference;
10528 if (attribute_flag[2] != 0)
10529 white_point=argument_list[2].real_reference;
10530 (void) LinearStretchImage(image,black_point,white_point,exception);
10531 break;
10532 }
10533 case 108: /* ColorMatrix */
10534 {
10535 AV
10536 *av;
10537
10538 double
10539 *color_matrix;
10540
10541 KernelInfo
10542 *kernel_info;
10543
10544 size_t
10545 order;
10546
10547 if (attribute_flag[0] == 0)
10548 break;
10549 av=(AV *) argument_list[0].array_reference;
10550 order=(size_t) sqrt(av_len(av)+1);
10551 color_matrix=(double *) AcquireQuantumMemory(order,order*
10552 sizeof(*color_matrix));
10553 if (color_matrix == (double *) NULL)
10554 {
10555 ThrowPerlException(exception,ResourceLimitFatalError,
10556 "MemoryAllocationFailed",PackageName);
10557 goto PerlException;
10558 }
10559 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10560 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10561 for ( ; j < (ssize_t) (order*order); j++)
10562 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010563 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010564 if (kernel_info == (KernelInfo *) NULL)
10565 break;
10566 kernel_info->width=order;
10567 kernel_info->height=order;
10568 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10569 order*sizeof(*kernel_info->values));
10570 if (kernel_info->values != (MagickRealType *) NULL)
10571 {
10572 for (i=0; i < (ssize_t) (order*order); i++)
10573 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10574 image=ColorMatrixImage(image,kernel_info,exception);
10575 }
10576 kernel_info=DestroyKernelInfo(kernel_info);
10577 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10578 break;
10579 }
10580 case 109: /* Mask */
10581 {
10582 Image
10583 *mask_image;
10584
10585 if (attribute_flag[0] == 0)
10586 {
10587 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10588 PackageName);
10589 goto PerlException;
10590 }
10591 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10592 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010593 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010594 mask_image=DestroyImage(mask_image);
10595 break;
10596 }
10597 case 110: /* Polaroid */
10598 {
10599 char
10600 *caption;
10601
10602 DrawInfo
10603 *draw_info;
10604
10605 double
10606 angle;
10607
10608 PixelInterpolateMethod
10609 method;
10610
10611 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10612 (DrawInfo *) NULL);
10613 caption=(char *) NULL;
10614 if (attribute_flag[0] != 0)
10615 caption=InterpretImageProperties(info ? info->image_info :
10616 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10617 exception);
10618 angle=0.0;
10619 if (attribute_flag[1] != 0)
10620 angle=argument_list[1].real_reference;
10621 if (attribute_flag[2] != 0)
10622 (void) CloneString(&draw_info->font,
10623 argument_list[2].string_reference);
10624 if (attribute_flag[3] != 0)
10625 (void) QueryColorCompliance(argument_list[3].string_reference,
10626 AllCompliance,&draw_info->stroke,exception);
10627 if (attribute_flag[4] != 0)
10628 (void) QueryColorCompliance(argument_list[4].string_reference,
10629 AllCompliance,&draw_info->fill,exception);
10630 if (attribute_flag[5] != 0)
10631 draw_info->stroke_width=argument_list[5].real_reference;
10632 if (attribute_flag[6] != 0)
10633 draw_info->pointsize=argument_list[6].real_reference;
10634 if (attribute_flag[7] != 0)
10635 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10636 if (attribute_flag[8] != 0)
10637 (void) QueryColorCompliance(argument_list[8].string_reference,
10638 AllCompliance,&image->background_color,exception);
10639 method=UndefinedInterpolatePixel;
10640 if (attribute_flag[9] != 0)
10641 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10642 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10643 draw_info=DestroyDrawInfo(draw_info);
10644 if (caption != (char *) NULL)
10645 caption=DestroyString(caption);
10646 break;
10647 }
10648 case 111: /* FloodfillPaint */
10649 {
10650 DrawInfo
10651 *draw_info;
10652
10653 MagickBooleanType
10654 invert;
10655
10656 PixelInfo
10657 target;
10658
10659 draw_info=CloneDrawInfo(info ? info->image_info :
10660 (ImageInfo *) NULL,(DrawInfo *) NULL);
10661 if (attribute_flag[0] != 0)
10662 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10663 &geometry,exception);
10664 if (attribute_flag[1] != 0)
10665 geometry.x=argument_list[1].integer_reference;
10666 if (attribute_flag[2] != 0)
10667 geometry.y=argument_list[2].integer_reference;
10668 if (attribute_flag[3] != 0)
10669 (void) QueryColorCompliance(argument_list[3].string_reference,
10670 AllCompliance,&draw_info->fill,exception);
10671 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10672 geometry.x,geometry.y,&target,exception);
10673 if (attribute_flag[4] != 0)
10674 QueryColorCompliance(argument_list[4].string_reference,
10675 AllCompliance,&target,exception);
10676 if (attribute_flag[5] != 0)
10677 image->fuzz=StringToDoubleInterval(
10678 argument_list[5].string_reference,(double) QuantumRange+1.0);
10679 if (attribute_flag[6] != 0)
10680 channel=(ChannelType) argument_list[6].integer_reference;
10681 invert=MagickFalse;
10682 if (attribute_flag[7] != 0)
10683 invert=(MagickBooleanType) argument_list[7].integer_reference;
10684 channel_mask=SetImageChannelMask(image,channel);
10685 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10686 geometry.y,invert,exception);
10687 (void) SetImageChannelMask(image,channel_mask);
10688 draw_info=DestroyDrawInfo(draw_info);
10689 break;
10690 }
10691 case 112: /* Distort */
10692 {
10693 AV
10694 *av;
10695
10696 double
10697 *coordinates;
10698
Cristy8645e042016-02-03 16:35:29 -050010699 DistortMethod
cristy4a3ce0a2013-08-03 20:06:59 +000010700 method;
10701
10702 size_t
10703 number_coordinates;
10704
10705 VirtualPixelMethod
10706 virtual_pixel;
10707
10708 if (attribute_flag[0] == 0)
10709 break;
10710 method=UndefinedDistortion;
10711 if (attribute_flag[1] != 0)
Cristy8645e042016-02-03 16:35:29 -050010712 method=(DistortMethod) argument_list[1].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010713 av=(AV *) argument_list[0].array_reference;
10714 number_coordinates=(size_t) av_len(av)+1;
10715 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10716 sizeof(*coordinates));
10717 if (coordinates == (double *) NULL)
10718 {
10719 ThrowPerlException(exception,ResourceLimitFatalError,
10720 "MemoryAllocationFailed",PackageName);
10721 goto PerlException;
10722 }
10723 for (j=0; j < (ssize_t) number_coordinates; j++)
10724 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10725 virtual_pixel=UndefinedVirtualPixelMethod;
10726 if (attribute_flag[2] != 0)
10727 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10728 argument_list[2].integer_reference,exception);
10729 image=DistortImage(image,method,number_coordinates,coordinates,
10730 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10731 exception);
10732 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10733 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10734 exception);
10735 coordinates=(double *) RelinquishMagickMemory(coordinates);
10736 break;
10737 }
10738 case 113: /* Clut */
10739 {
10740 PixelInterpolateMethod
10741 method;
10742
10743 if (attribute_flag[0] == 0)
10744 {
10745 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10746 PackageName);
10747 goto PerlException;
10748 }
10749 method=UndefinedInterpolatePixel;
10750 if (attribute_flag[1] != 0)
10751 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10752 if (attribute_flag[2] != 0)
10753 channel=(ChannelType) argument_list[2].integer_reference;
10754 channel_mask=SetImageChannelMask(image,channel);
10755 (void) ClutImage(image,argument_list[0].image_reference,method,
10756 exception);
10757 (void) SetImageChannelMask(image,channel_mask);
10758 break;
10759 }
10760 case 114: /* LiquidRescale */
10761 {
10762 if (attribute_flag[0] != 0)
10763 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10764 &geometry,exception);
10765 if (attribute_flag[1] != 0)
10766 geometry.width=argument_list[1].integer_reference;
10767 if (attribute_flag[2] != 0)
10768 geometry.height=argument_list[2].integer_reference;
10769 if (attribute_flag[3] == 0)
10770 argument_list[3].real_reference=1.0;
10771 if (attribute_flag[4] == 0)
10772 argument_list[4].real_reference=0.0;
10773 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10774 argument_list[3].real_reference,argument_list[4].real_reference,
10775 exception);
10776 break;
10777 }
10778 case 115: /* EncipherImage */
10779 {
10780 (void) EncipherImage(image,argument_list[0].string_reference,
10781 exception);
10782 break;
10783 }
10784 case 116: /* DecipherImage */
10785 {
10786 (void) DecipherImage(image,argument_list[0].string_reference,
10787 exception);
10788 break;
10789 }
10790 case 117: /* Deskew */
10791 {
10792 geometry_info.rho=QuantumRange/2.0;
10793 if (attribute_flag[0] != 0)
10794 flags=ParseGeometry(argument_list[0].string_reference,
10795 &geometry_info);
10796 if (attribute_flag[1] != 0)
10797 geometry_info.rho=StringToDoubleInterval(
10798 argument_list[1].string_reference,(double) QuantumRange+1.0);
10799 image=DeskewImage(image,geometry_info.rho,exception);
10800 break;
10801 }
10802 case 118: /* Remap */
10803 {
10804 QuantizeInfo
10805 *quantize_info;
10806
10807 if (attribute_flag[0] == 0)
10808 {
10809 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10810 PackageName);
10811 goto PerlException;
10812 }
10813 quantize_info=AcquireQuantizeInfo(info->image_info);
10814 if (attribute_flag[1] != 0)
10815 quantize_info->dither_method=(DitherMethod)
10816 argument_list[1].integer_reference;
10817 (void) RemapImages(quantize_info,image,
10818 argument_list[0].image_reference,exception);
10819 quantize_info=DestroyQuantizeInfo(quantize_info);
10820 break;
10821 }
10822 case 119: /* SparseColor */
10823 {
10824 AV
10825 *av;
10826
10827 double
10828 *coordinates;
10829
10830 SparseColorMethod
10831 method;
10832
10833 size_t
10834 number_coordinates;
10835
10836 VirtualPixelMethod
10837 virtual_pixel;
10838
10839 if (attribute_flag[0] == 0)
10840 break;
10841 method=UndefinedColorInterpolate;
10842 if (attribute_flag[1] != 0)
10843 method=(SparseColorMethod) argument_list[1].integer_reference;
10844 av=(AV *) argument_list[0].array_reference;
10845 number_coordinates=(size_t) av_len(av)+1;
10846 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10847 sizeof(*coordinates));
10848 if (coordinates == (double *) NULL)
10849 {
10850 ThrowPerlException(exception,ResourceLimitFatalError,
10851 "MemoryAllocationFailed",PackageName);
10852 goto PerlException;
10853 }
10854 for (j=0; j < (ssize_t) number_coordinates; j++)
10855 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10856 virtual_pixel=UndefinedVirtualPixelMethod;
10857 if (attribute_flag[2] != 0)
10858 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10859 argument_list[2].integer_reference,exception);
10860 if (attribute_flag[3] != 0)
10861 channel=(ChannelType) argument_list[3].integer_reference;
10862 channel_mask=SetImageChannelMask(image,channel);
10863 image=SparseColorImage(image,method,number_coordinates,coordinates,
10864 exception);
10865 if (image != (Image *) NULL)
10866 (void) SetImageChannelMask(image,channel_mask);
10867 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10868 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10869 exception);
10870 coordinates=(double *) RelinquishMagickMemory(coordinates);
10871 break;
10872 }
10873 case 120: /* Function */
10874 {
10875 AV
10876 *av;
10877
10878 double
10879 *parameters;
10880
10881 MagickFunction
10882 function;
10883
10884 size_t
10885 number_parameters;
10886
10887 VirtualPixelMethod
10888 virtual_pixel;
10889
10890 if (attribute_flag[0] == 0)
10891 break;
10892 function=UndefinedFunction;
10893 if (attribute_flag[1] != 0)
10894 function=(MagickFunction) argument_list[1].integer_reference;
10895 av=(AV *) argument_list[0].array_reference;
10896 number_parameters=(size_t) av_len(av)+1;
10897 parameters=(double *) AcquireQuantumMemory(number_parameters,
10898 sizeof(*parameters));
10899 if (parameters == (double *) NULL)
10900 {
10901 ThrowPerlException(exception,ResourceLimitFatalError,
10902 "MemoryAllocationFailed",PackageName);
10903 goto PerlException;
10904 }
10905 for (j=0; j < (ssize_t) number_parameters; j++)
10906 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10907 virtual_pixel=UndefinedVirtualPixelMethod;
10908 if (attribute_flag[2] != 0)
10909 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10910 argument_list[2].integer_reference,exception);
10911 (void) FunctionImage(image,function,number_parameters,parameters,
10912 exception);
10913 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10914 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10915 exception);
10916 parameters=(double *) RelinquishMagickMemory(parameters);
10917 break;
10918 }
10919 case 121: /* SelectiveBlur */
10920 {
10921 if (attribute_flag[0] != 0)
10922 {
10923 flags=ParseGeometry(argument_list[0].string_reference,
10924 &geometry_info);
10925 if ((flags & SigmaValue) == 0)
10926 geometry_info.sigma=1.0;
10927 if ((flags & PercentValue) != 0)
10928 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10929 }
10930 if (attribute_flag[1] != 0)
10931 geometry_info.rho=argument_list[1].real_reference;
10932 if (attribute_flag[2] != 0)
10933 geometry_info.sigma=argument_list[2].real_reference;
10934 if (attribute_flag[3] != 0)
10935 geometry_info.xi=argument_list[3].integer_reference;;
10936 if (attribute_flag[5] != 0)
10937 channel=(ChannelType) argument_list[5].integer_reference;
10938 channel_mask=SetImageChannelMask(image,channel);
10939 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10940 geometry_info.xi,exception);
10941 if (image != (Image *) NULL)
10942 (void) SetImageChannelMask(image,channel_mask);
10943 break;
10944 }
10945 case 122: /* HaldClut */
10946 {
10947 if (attribute_flag[0] == 0)
10948 {
10949 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10950 PackageName);
10951 goto PerlException;
10952 }
10953 if (attribute_flag[1] != 0)
10954 channel=(ChannelType) argument_list[1].integer_reference;
10955 channel_mask=SetImageChannelMask(image,channel);
10956 (void) HaldClutImage(image,argument_list[0].image_reference,
10957 exception);
10958 (void) SetImageChannelMask(image,channel_mask);
10959 break;
10960 }
10961 case 123: /* BlueShift */
10962 {
10963 if (attribute_flag[0] != 0)
10964 (void) ParseGeometry(argument_list[0].string_reference,
10965 &geometry_info);
10966 image=BlueShiftImage(image,geometry_info.rho,exception);
10967 break;
10968 }
10969 case 124: /* ForwardFourierTransformImage */
10970 {
10971 image=ForwardFourierTransformImage(image,
10972 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10973 exception);
10974 break;
10975 }
10976 case 125: /* InverseFourierTransformImage */
10977 {
10978 image=InverseFourierTransformImage(image,image->next,
10979 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10980 exception);
10981 break;
10982 }
10983 case 126: /* ColorDecisionList */
10984 {
10985 if (attribute_flag[0] == 0)
10986 argument_list[0].string_reference=(char *) NULL;
10987 (void) ColorDecisionListImage(image,
10988 argument_list[0].string_reference,exception);
10989 break;
10990 }
10991 case 127: /* AutoGamma */
10992 {
10993 if (attribute_flag[0] != 0)
10994 channel=(ChannelType) argument_list[0].integer_reference;
10995 channel_mask=SetImageChannelMask(image,channel);
10996 (void) AutoGammaImage(image,exception);
10997 (void) SetImageChannelMask(image,channel_mask);
10998 break;
10999 }
11000 case 128: /* AutoLevel */
11001 {
11002 if (attribute_flag[0] != 0)
11003 channel=(ChannelType) argument_list[0].integer_reference;
11004 channel_mask=SetImageChannelMask(image,channel);
11005 (void) AutoLevelImage(image,exception);
11006 (void) SetImageChannelMask(image,channel_mask);
11007 break;
11008 }
11009 case 129: /* LevelColors */
11010 {
11011 PixelInfo
11012 black_point,
11013 white_point;
11014
11015 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
11016 exception);
11017 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
11018 exception);
11019 if (attribute_flag[1] != 0)
11020 (void) QueryColorCompliance(
11021 argument_list[1].string_reference,AllCompliance,&black_point,
11022 exception);
11023 if (attribute_flag[2] != 0)
11024 (void) QueryColorCompliance(
11025 argument_list[2].string_reference,AllCompliance,&white_point,
11026 exception);
11027 if (attribute_flag[3] != 0)
11028 channel=(ChannelType) argument_list[3].integer_reference;
11029 channel_mask=SetImageChannelMask(image,channel);
11030 (void) LevelImageColors(image,&black_point,&white_point,
11031 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11032 exception);
11033 (void) SetImageChannelMask(image,channel_mask);
11034 break;
11035 }
11036 case 130: /* Clamp */
11037 {
11038 if (attribute_flag[0] != 0)
11039 channel=(ChannelType) argument_list[0].integer_reference;
11040 channel_mask=SetImageChannelMask(image,channel);
11041 (void) ClampImage(image,exception);
11042 (void) SetImageChannelMask(image,channel_mask);
11043 break;
11044 }
11045 case 131: /* BrightnessContrast */
11046 {
11047 double
11048 brightness,
11049 contrast;
11050
11051 brightness=0.0;
11052 contrast=0.0;
11053 if (attribute_flag[0] != 0)
11054 {
11055 flags=ParseGeometry(argument_list[0].string_reference,
11056 &geometry_info);
11057 brightness=geometry_info.rho;
11058 if ((flags & SigmaValue) == 0)
11059 contrast=geometry_info.sigma;
11060 }
11061 if (attribute_flag[1] != 0)
11062 brightness=argument_list[1].real_reference;
11063 if (attribute_flag[2] != 0)
11064 contrast=argument_list[2].real_reference;
11065 if (attribute_flag[4] != 0)
11066 channel=(ChannelType) argument_list[4].integer_reference;
11067 channel_mask=SetImageChannelMask(image,channel);
11068 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11069 (void) SetImageChannelMask(image,channel_mask);
11070 break;
11071 }
11072 case 132: /* Morphology */
11073 {
11074 KernelInfo
11075 *kernel;
11076
11077 MorphologyMethod
11078 method;
11079
11080 ssize_t
11081 iterations;
11082
11083 if (attribute_flag[0] == 0)
11084 break;
cristy2c57b742014-10-31 00:40:34 +000011085 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011086 if (kernel == (KernelInfo *) NULL)
11087 break;
11088 if (attribute_flag[1] != 0)
11089 channel=(ChannelType) argument_list[1].integer_reference;
11090 method=UndefinedMorphology;
11091 if (attribute_flag[2] != 0)
11092 method=argument_list[2].integer_reference;
11093 iterations=1;
11094 if (attribute_flag[3] != 0)
11095 iterations=argument_list[3].integer_reference;
11096 channel_mask=SetImageChannelMask(image,channel);
11097 image=MorphologyImage(image,method,iterations,kernel,exception);
11098 if (image != (Image *) NULL)
11099 (void) SetImageChannelMask(image,channel_mask);
11100 kernel=DestroyKernelInfo(kernel);
11101 break;
11102 }
11103 case 133: /* Mode */
11104 {
11105 if (attribute_flag[0] != 0)
11106 {
11107 flags=ParseGeometry(argument_list[0].string_reference,
11108 &geometry_info);
11109 if ((flags & SigmaValue) == 0)
11110 geometry_info.sigma=1.0;
11111 }
11112 if (attribute_flag[1] != 0)
11113 geometry_info.rho=argument_list[1].real_reference;
11114 if (attribute_flag[2] != 0)
11115 geometry_info.sigma=argument_list[2].real_reference;
11116 if (attribute_flag[3] != 0)
11117 channel=(ChannelType) argument_list[3].integer_reference;
11118 channel_mask=SetImageChannelMask(image,channel);
11119 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11120 (size_t) geometry_info.sigma,exception);
11121 if (image != (Image *) NULL)
11122 (void) SetImageChannelMask(image,channel_mask);
11123 break;
11124 }
11125 case 134: /* Statistic */
11126 {
11127 StatisticType
11128 statistic;
11129
11130 statistic=UndefinedStatistic;
11131 if (attribute_flag[0] != 0)
11132 {
11133 flags=ParseGeometry(argument_list[0].string_reference,
11134 &geometry_info);
11135 if ((flags & SigmaValue) == 0)
11136 geometry_info.sigma=1.0;
11137 }
11138 if (attribute_flag[1] != 0)
11139 geometry_info.rho=argument_list[1].real_reference;
11140 if (attribute_flag[2] != 0)
11141 geometry_info.sigma=argument_list[2].real_reference;
11142 if (attribute_flag[3] != 0)
11143 channel=(ChannelType) argument_list[3].integer_reference;
11144 if (attribute_flag[4] != 0)
11145 statistic=(StatisticType) argument_list[4].integer_reference;
11146 channel_mask=SetImageChannelMask(image,channel);
11147 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11148 (size_t) geometry_info.sigma,exception);
11149 if (image != (Image *) NULL)
11150 (void) SetImageChannelMask(image,channel_mask);
11151 break;
11152 }
11153 case 135: /* Perceptible */
11154 {
11155 double
11156 epsilon;
11157
11158 epsilon=MagickEpsilon;
11159 if (attribute_flag[0] != 0)
11160 epsilon=argument_list[0].real_reference;
11161 if (attribute_flag[1] != 0)
11162 channel=(ChannelType) argument_list[1].integer_reference;
11163 channel_mask=SetImageChannelMask(image,channel);
11164 (void) PerceptibleImage(image,epsilon,exception);
11165 (void) SetImageChannelMask(image,channel_mask);
11166 break;
11167 }
11168 case 136: /* Poly */
11169 {
11170 AV
11171 *av;
11172
11173 double
11174 *terms;
11175
11176 size_t
11177 number_terms;
11178
11179 if (attribute_flag[0] == 0)
11180 break;
11181 if (attribute_flag[1] != 0)
11182 channel=(ChannelType) argument_list[1].integer_reference;
11183 av=(AV *) argument_list[0].array_reference;
11184 number_terms=(size_t) av_len(av);
11185 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11186 if (terms == (double *) NULL)
11187 {
11188 ThrowPerlException(exception,ResourceLimitFatalError,
11189 "MemoryAllocationFailed",PackageName);
11190 goto PerlException;
11191 }
11192 for (j=0; j < av_len(av); j++)
11193 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11194 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11195 terms=(double *) RelinquishMagickMemory(terms);
11196 break;
11197 }
11198 case 137: /* Grayscale */
11199 {
11200 PixelIntensityMethod
11201 method;
11202
11203 method=UndefinedPixelIntensityMethod;
11204 if (attribute_flag[0] != 0)
11205 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11206 (void) GrayscaleImage(image,method,exception);
11207 break;
11208 }
cristy4ceadb82014-03-29 15:30:43 +000011209 case 138: /* Canny */
11210 {
11211 if (attribute_flag[0] != 0)
11212 {
11213 flags=ParseGeometry(argument_list[0].string_reference,
11214 &geometry_info);
11215 if ((flags & SigmaValue) == 0)
11216 geometry_info.sigma=1.0;
11217 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011218 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011219 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011220 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011221 if ((flags & PercentValue) != 0)
11222 {
11223 geometry_info.xi/=100.0;
11224 geometry_info.psi/=100.0;
11225 }
cristy4ceadb82014-03-29 15:30:43 +000011226 }
11227 if (attribute_flag[1] != 0)
11228 geometry_info.rho=argument_list[1].real_reference;
11229 if (attribute_flag[2] != 0)
11230 geometry_info.sigma=argument_list[2].real_reference;
11231 if (attribute_flag[3] != 0)
11232 geometry_info.xi=argument_list[3].real_reference;
11233 if (attribute_flag[4] != 0)
11234 geometry_info.psi=argument_list[4].real_reference;
11235 if (attribute_flag[5] != 0)
11236 channel=(ChannelType) argument_list[5].integer_reference;
11237 channel_mask=SetImageChannelMask(image,channel);
11238 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11239 geometry_info.xi,geometry_info.psi,exception);
11240 if (image != (Image *) NULL)
11241 (void) SetImageChannelMask(image,channel_mask);
11242 break;
11243 }
cristy2fc10e52014-04-26 14:13:53 +000011244 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011245 {
11246 if (attribute_flag[0] != 0)
11247 {
11248 flags=ParseGeometry(argument_list[0].string_reference,
11249 &geometry_info);
11250 if ((flags & SigmaValue) == 0)
11251 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011252 if ((flags & XiValue) == 0)
11253 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011254 }
11255 if (attribute_flag[1] != 0)
11256 geometry_info.rho=(double) argument_list[1].integer_reference;
11257 if (attribute_flag[2] != 0)
11258 geometry_info.sigma=(double) argument_list[2].integer_reference;
11259 if (attribute_flag[3] != 0)
11260 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011261 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11262 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11263 break;
11264 }
11265 case 140: /* MeanShift */
11266 {
11267 if (attribute_flag[0] != 0)
11268 {
11269 flags=ParseGeometry(argument_list[0].string_reference,
11270 &geometry_info);
11271 if ((flags & SigmaValue) == 0)
11272 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011273 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011274 geometry_info.xi=0.10*QuantumRange;
11275 if ((flags & PercentValue) != 0)
11276 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011277 }
11278 if (attribute_flag[1] != 0)
11279 geometry_info.rho=(double) argument_list[1].integer_reference;
11280 if (attribute_flag[2] != 0)
11281 geometry_info.sigma=(double) argument_list[2].integer_reference;
11282 if (attribute_flag[3] != 0)
11283 geometry_info.xi=(double) argument_list[3].integer_reference;
11284 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011285 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011286 break;
11287 }
cristy3b207f82014-09-27 14:21:20 +000011288 case 141: /* Kuwahara */
11289 {
11290 if (attribute_flag[0] != 0)
11291 {
11292 flags=ParseGeometry(argument_list[0].string_reference,
11293 &geometry_info);
11294 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011295 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011296 }
11297 if (attribute_flag[1] != 0)
11298 geometry_info.rho=argument_list[1].real_reference;
11299 if (attribute_flag[2] != 0)
11300 geometry_info.sigma=argument_list[2].real_reference;
11301 if (attribute_flag[3] != 0)
11302 channel=(ChannelType) argument_list[3].integer_reference;
11303 channel_mask=SetImageChannelMask(image,channel);
11304 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11305 exception);
11306 if (image != (Image *) NULL)
11307 (void) SetImageChannelMask(image,channel_mask);
11308 break;
11309 }
cristy6e0b3bc2014-10-19 17:51:42 +000011310 case 142: /* ConnectedComponent */
11311 {
11312 size_t
11313 connectivity;
11314
11315 connectivity=4;
11316 if (attribute_flag[0] != 0)
11317 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011318 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011319 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011320 break;
11321 }
cristy0b94b392015-06-22 18:56:37 +000011322 case 143: /* Copy */
11323 {
11324 Image
11325 *source_image;
11326
11327 OffsetInfo
11328 offset;
11329
cristy2ffdb092015-06-25 14:31:20 +000011330 RectangleInfo
11331 offset_geometry;
11332
cristyf3a724a2015-06-25 13:02:53 +000011333 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011334 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011335 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011336 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011337 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011338 flags=ParseGravityGeometry(source_image,
11339 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011340 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011341 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011342 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011343 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011344 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011345 geometry.x=argument_list[4].integer_reference;
11346 if (attribute_flag[5] != 0)
11347 geometry.y=argument_list[5].integer_reference;
11348 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011349 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011350 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011351 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011352 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11353 &offset_geometry,exception);
11354 offset.x=offset_geometry.x;
11355 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011356 if (attribute_flag[8] != 0)
11357 offset.x=argument_list[8].integer_reference;
11358 if (attribute_flag[9] != 0)
11359 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011360 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11361 exception);
cristy0b94b392015-06-22 18:56:37 +000011362 break;
11363 }
Cristy5488c982016-02-13 14:07:50 -050011364 case 144: /* Color */
11365 {
11366 PixelInfo
11367 color;
11368
Cristyf20e3562016-02-14 09:08:15 -050011369 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011370 if (attribute_flag[0] != 0)
Cristyf20e3562016-02-14 09:08:15 -050011371 (void) QueryColorCompliance(argument_list[0].string_reference,
11372 AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011373 (void) SetImageColor(image,&color,exception);
11374 break;
11375 }
Cristy2d830ed2016-02-21 10:54:16 -050011376 case 145: /* WaveletDenoise */
11377 {
Cristyc1759412016-02-27 12:17:58 -050011378 if (attribute_flag[0] != 0)
Cristyee21f7f2016-02-27 15:56:49 -050011379 {
11380 flags=ParseGeometry(argument_list[0].string_reference,
11381 &geometry_info);
11382 if ((flags & PercentValue) != 0)
Cristy23446632016-02-29 09:36:34 -050011383 {
11384 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11385 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
11386 }
Cristyee21f7f2016-02-27 15:56:49 -050011387 if ((flags & SigmaValue) == 0)
11388 geometry_info.sigma=0.0;
11389 }
Cristyc1759412016-02-27 12:17:58 -050011390 if (attribute_flag[1] != 0)
11391 geometry_info.rho=argument_list[1].real_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011392 if (attribute_flag[2] != 0)
Cristyc1759412016-02-27 12:17:58 -050011393 geometry_info.sigma=argument_list[2].real_reference;
11394 if (attribute_flag[3] != 0)
11395 channel=(ChannelType) argument_list[3].integer_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011396 channel_mask=SetImageChannelMask(image,channel);
Cristyc1759412016-02-27 12:17:58 -050011397 image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11398 exception);
Cristy2d830ed2016-02-21 10:54:16 -050011399 if (image != (Image *) NULL)
11400 (void) SetImageChannelMask(image,channel_mask);
11401 break;
11402 }
Cristy99a57162016-12-05 11:47:57 -050011403 case 146: /* Colorspace */
11404 {
11405 ColorspaceType
11406 colorspace;
11407
11408 colorspace=sRGBColorspace;
11409 if (attribute_flag[0] != 0)
11410 colorspace=(ColorspaceType) argument_list[0].integer_reference;
11411 (void) TransformImageColorspace(image,colorspace,exception);
11412 break;
11413 }
Cristy53353872017-07-02 12:24:24 -040011414 case 147: /* AutoThreshold */
11415 {
11416 AutoThresholdMethod
11417 method;
11418
11419 method=UndefinedThresholdMethod;
11420 if (attribute_flag[0] != 0)
Cristyb63e7752017-07-02 13:22:01 -040011421 method=(AutoThresholdMethod) argument_list[0].integer_reference;
Cristy53353872017-07-02 12:24:24 -040011422 (void) AutoThresholdImage(image,method,exception);
11423 break;
11424 }
cristy4a3ce0a2013-08-03 20:06:59 +000011425 }
11426 if (next != (Image *) NULL)
11427 (void) CatchImageException(next);
11428 if (region_image != (Image *) NULL)
11429 {
11430 /*
11431 Composite region.
cristy83a28a02013-08-03 20:25:48 +000011432 */
cristy4a3ce0a2013-08-03 20:06:59 +000011433 status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11434 region_info.x,region_info.y,exception);
11435 (void) status;
11436 (void) CatchImageException(region_image);
11437 image=DestroyImage(image);
11438 image=region_image;
11439 }
11440 if (image != (Image *) NULL)
11441 {
11442 number_images++;
11443 if (next && (next != image))
11444 {
11445 image->next=next->next;
11446 if (image->next != (Image *) NULL)
11447 image->next->previous=image;
11448 DeleteImageFromRegistry(*pv,next);
11449 }
11450 sv_setiv(*pv,PTR2IV(image));
11451 next=image;
11452 }
11453 if (*pv)
11454 pv++;
11455 }
11456
11457 PerlException:
11458 if (reference_vector)
11459 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11460 InheritPerlException(exception,perl_exception);
11461 exception=DestroyExceptionInfo(exception);
11462 sv_setiv(perl_exception,(IV) number_images);
11463 SvPOK_on(perl_exception);
11464 ST(0)=sv_2mortal(perl_exception);
11465 XSRETURN(1);
11466 }
11467
11468#
11469###############################################################################
11470# #
11471# #
11472# #
11473# M o n t a g e #
11474# #
11475# #
11476# #
11477###############################################################################
11478#
11479#
11480void
11481Montage(ref,...)
11482 Image::Magick ref=NO_INIT
11483 ALIAS:
11484 MontageImage = 1
11485 montage = 2
11486 montageimage = 3
11487 PPCODE:
11488 {
11489 AV
11490 *av;
11491
11492 char
11493 *attribute;
11494
11495 ExceptionInfo
11496 *exception;
11497
11498 HV
11499 *hv;
11500
11501 Image
11502 *image,
11503 *next;
11504
11505 PixelInfo
11506 transparent_color;
11507
11508 MontageInfo
11509 *montage_info;
11510
11511 register ssize_t
11512 i;
11513
11514 ssize_t
11515 sp;
11516
11517 struct PackageInfo
11518 *info;
11519
11520 SV
11521 *av_reference,
11522 *perl_exception,
11523 *reference,
11524 *rv,
11525 *sv;
11526
11527 PERL_UNUSED_VAR(ref);
11528 PERL_UNUSED_VAR(ix);
11529 exception=AcquireExceptionInfo();
11530 perl_exception=newSVpv("",0);
11531 sv=NULL;
11532 attribute=NULL;
11533 if (sv_isobject(ST(0)) == 0)
11534 {
11535 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11536 PackageName);
11537 goto PerlException;
11538 }
11539 reference=SvRV(ST(0));
11540 hv=SvSTASH(reference);
11541 av=newAV();
11542 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11543 SvREFCNT_dec(av);
11544 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11545 if (image == (Image *) NULL)
11546 {
11547 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11548 PackageName);
11549 goto PerlException;
11550 }
11551 /*
11552 Get options.
11553 */
11554 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11555 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11556 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11557 exception);
11558 for (i=2; i < items; i+=2)
11559 {
11560 attribute=(char *) SvPV(ST(i-1),na);
11561 switch (*attribute)
11562 {
11563 case 'B':
11564 case 'b':
11565 {
11566 if (LocaleCompare(attribute,"background") == 0)
11567 {
11568 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11569 &montage_info->background_color,exception);
11570 for (next=image; next; next=next->next)
11571 next->background_color=montage_info->background_color;
11572 break;
11573 }
11574 if (LocaleCompare(attribute,"border") == 0)
11575 {
11576 montage_info->border_width=SvIV(ST(i));
11577 break;
11578 }
11579 if (LocaleCompare(attribute,"bordercolor") == 0)
11580 {
11581 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11582 &montage_info->border_color,exception);
11583 for (next=image; next; next=next->next)
11584 next->border_color=montage_info->border_color;
11585 break;
11586 }
11587 if (LocaleCompare(attribute,"borderwidth") == 0)
11588 {
11589 montage_info->border_width=SvIV(ST(i));
11590 break;
11591 }
11592 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11593 attribute);
11594 break;
11595 }
11596 case 'C':
11597 case 'c':
11598 {
11599 if (LocaleCompare(attribute,"compose") == 0)
11600 {
11601 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11602 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11603 if (sp < 0)
11604 {
11605 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11606 SvPV(ST(i),na));
11607 break;
11608 }
11609 for (next=image; next; next=next->next)
11610 next->compose=(CompositeOperator) sp;
11611 break;
11612 }
11613 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11614 attribute);
11615 break;
11616 }
11617 case 'F':
11618 case 'f':
11619 {
11620 if (LocaleCompare(attribute,"fill") == 0)
11621 {
11622 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11623 &montage_info->fill,exception);
11624 break;
11625 }
11626 if (LocaleCompare(attribute,"font") == 0)
11627 {
11628 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11629 break;
11630 }
11631 if (LocaleCompare(attribute,"frame") == 0)
11632 {
11633 char
11634 *p;
11635
11636 p=SvPV(ST(i),na);
11637 if (IsGeometry(p) == MagickFalse)
11638 {
11639 ThrowPerlException(exception,OptionError,"MissingGeometry",
11640 p);
11641 break;
11642 }
11643 (void) CloneString(&montage_info->frame,p);
11644 if (*p == '\0')
11645 montage_info->frame=(char *) NULL;
11646 break;
11647 }
11648 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11649 attribute);
11650 break;
11651 }
11652 case 'G':
11653 case 'g':
11654 {
11655 if (LocaleCompare(attribute,"geometry") == 0)
11656 {
11657 char
11658 *p;
11659
11660 p=SvPV(ST(i),na);
11661 if (IsGeometry(p) == MagickFalse)
11662 {
11663 ThrowPerlException(exception,OptionError,"MissingGeometry",
11664 p);
11665 break;
11666 }
11667 (void) CloneString(&montage_info->geometry,p);
11668 if (*p == '\0')
11669 montage_info->geometry=(char *) NULL;
11670 break;
11671 }
11672 if (LocaleCompare(attribute,"gravity") == 0)
11673 {
11674 ssize_t
11675 in;
11676
11677 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11678 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11679 if (in < 0)
11680 {
11681 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11682 SvPV(ST(i),na));
11683 return;
11684 }
11685 montage_info->gravity=(GravityType) in;
11686 for (next=image; next; next=next->next)
11687 next->gravity=(GravityType) in;
11688 break;
11689 }
11690 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11691 attribute);
11692 break;
11693 }
11694 case 'L':
11695 case 'l':
11696 {
11697 if (LocaleCompare(attribute,"label") == 0)
11698 {
11699 for (next=image; next; next=next->next)
Cristy935a4052017-03-31 17:45:37 -040011700 (void) SetImageProperty(next,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +000011701 info ? info->image_info : (ImageInfo *) NULL,next,
Cristy935a4052017-03-31 17:45:37 -040011702 SvPV(ST(i),na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011703 break;
11704 }
11705 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11706 attribute);
11707 break;
11708 }
11709 case 'M':
11710 case 'm':
11711 {
11712 if (LocaleCompare(attribute,"mattecolor") == 0)
11713 {
11714 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
Cristy8645e042016-02-03 16:35:29 -050011715 &montage_info->alpha_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011716 for (next=image; next; next=next->next)
Cristy8645e042016-02-03 16:35:29 -050011717 next->alpha_color=montage_info->alpha_color;
cristy4a3ce0a2013-08-03 20:06:59 +000011718 break;
11719 }
11720 if (LocaleCompare(attribute,"mode") == 0)
11721 {
11722 ssize_t
11723 in;
11724
11725 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11726 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11727 switch (in)
11728 {
11729 default:
11730 {
11731 ThrowPerlException(exception,OptionError,
11732 "UnrecognizedModeType",SvPV(ST(i),na));
11733 break;
11734 }
11735 case FrameMode:
11736 {
11737 (void) CloneString(&montage_info->frame,"15x15+3+3");
11738 montage_info->shadow=MagickTrue;
11739 break;
11740 }
11741 case UnframeMode:
11742 {
11743 montage_info->frame=(char *) NULL;
11744 montage_info->shadow=MagickFalse;
11745 montage_info->border_width=0;
11746 break;
11747 }
11748 case ConcatenateMode:
11749 {
11750 montage_info->frame=(char *) NULL;
11751 montage_info->shadow=MagickFalse;
11752 (void) CloneString(&montage_info->geometry,"+0+0");
11753 montage_info->border_width=0;
11754 }
11755 }
11756 break;
11757 }
11758 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11759 attribute);
11760 break;
11761 }
11762 case 'P':
11763 case 'p':
11764 {
11765 if (LocaleCompare(attribute,"pointsize") == 0)
11766 {
11767 montage_info->pointsize=SvIV(ST(i));
11768 break;
11769 }
11770 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11771 attribute);
11772 break;
11773 }
11774 case 'S':
11775 case 's':
11776 {
11777 if (LocaleCompare(attribute,"shadow") == 0)
11778 {
11779 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11780 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11781 if (sp < 0)
11782 {
11783 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11784 SvPV(ST(i),na));
11785 break;
11786 }
11787 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11788 break;
11789 }
11790 if (LocaleCompare(attribute,"stroke") == 0)
11791 {
11792 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11793 &montage_info->stroke,exception);
11794 break;
11795 }
11796 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11797 attribute);
11798 break;
11799 }
11800 case 'T':
11801 case 't':
11802 {
11803 if (LocaleCompare(attribute,"texture") == 0)
11804 {
11805 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11806 break;
11807 }
11808 if (LocaleCompare(attribute,"tile") == 0)
11809 {
11810 char *p=SvPV(ST(i),na);
11811 if (IsGeometry(p) == MagickFalse)
11812 {
11813 ThrowPerlException(exception,OptionError,"MissingGeometry",
11814 p);
11815 break;
11816 }
11817 (void) CloneString(&montage_info->tile,p);
11818 if (*p == '\0')
11819 montage_info->tile=(char *) NULL;
11820 break;
11821 }
11822 if (LocaleCompare(attribute,"title") == 0)
11823 {
11824 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11825 break;
11826 }
11827 if (LocaleCompare(attribute,"transparent") == 0)
11828 {
11829 PixelInfo
11830 transparent_color;
11831
11832 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11833 &transparent_color,exception);
11834 for (next=image; next; next=next->next)
11835 (void) TransparentPaintImage(next,&transparent_color,
11836 TransparentAlpha,MagickFalse,exception);
11837 break;
11838 }
11839 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11840 attribute);
11841 break;
11842 }
11843 default:
11844 {
11845 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11846 attribute);
11847 break;
11848 }
11849 }
11850 }
11851 image=MontageImageList(info->image_info,montage_info,image,exception);
11852 montage_info=DestroyMontageInfo(montage_info);
11853 if (image == (Image *) NULL)
11854 goto PerlException;
11855 if (transparent_color.alpha != TransparentAlpha)
11856 for (next=image; next; next=next->next)
11857 (void) TransparentPaintImage(next,&transparent_color,
11858 TransparentAlpha,MagickFalse,exception);
11859 for ( ; image; image=image->next)
11860 {
11861 AddImageToRegistry(sv,image);
11862 rv=newRV(sv);
11863 av_push(av,sv_bless(rv,hv));
11864 SvREFCNT_dec(sv);
11865 }
11866 exception=DestroyExceptionInfo(exception);
11867 ST(0)=av_reference;
11868 SvREFCNT_dec(perl_exception);
11869 XSRETURN(1);
11870
11871 PerlException:
11872 InheritPerlException(exception,perl_exception);
11873 exception=DestroyExceptionInfo(exception);
11874 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11875 SvPOK_on(perl_exception);
11876 ST(0)=sv_2mortal(perl_exception);
11877 XSRETURN(1);
11878 }
11879
11880#
11881###############################################################################
11882# #
11883# #
11884# #
11885# M o r p h #
11886# #
11887# #
11888# #
11889###############################################################################
11890#
11891#
11892void
11893Morph(ref,...)
11894 Image::Magick ref=NO_INIT
11895 ALIAS:
11896 MorphImage = 1
11897 morph = 2
11898 morphimage = 3
11899 PPCODE:
11900 {
11901 AV
11902 *av;
11903
11904 char
11905 *attribute;
11906
11907 ExceptionInfo
11908 *exception;
11909
11910 HV
11911 *hv;
11912
11913 Image
11914 *image;
11915
11916 register ssize_t
11917 i;
11918
11919 ssize_t
11920 number_frames;
11921
11922 struct PackageInfo
11923 *info;
11924
11925 SV
11926 *av_reference,
11927 *perl_exception,
11928 *reference,
11929 *rv,
11930 *sv;
11931
11932 PERL_UNUSED_VAR(ref);
11933 PERL_UNUSED_VAR(ix);
11934 exception=AcquireExceptionInfo();
11935 perl_exception=newSVpv("",0);
11936 sv=NULL;
11937 av=NULL;
11938 attribute=NULL;
11939 if (sv_isobject(ST(0)) == 0)
11940 {
11941 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11942 PackageName);
11943 goto PerlException;
11944 }
11945 reference=SvRV(ST(0));
11946 hv=SvSTASH(reference);
11947 av=newAV();
11948 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11949 SvREFCNT_dec(av);
11950 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11951 if (image == (Image *) NULL)
11952 {
11953 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11954 PackageName);
11955 goto PerlException;
11956 }
11957 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11958 /*
11959 Get attribute.
11960 */
11961 number_frames=30;
11962 for (i=2; i < items; i+=2)
11963 {
11964 attribute=(char *) SvPV(ST(i-1),na);
11965 switch (*attribute)
11966 {
11967 case 'F':
11968 case 'f':
11969 {
11970 if (LocaleCompare(attribute,"frames") == 0)
11971 {
11972 number_frames=SvIV(ST(i));
11973 break;
11974 }
11975 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11976 attribute);
11977 break;
11978 }
11979 default:
11980 {
11981 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11982 attribute);
11983 break;
11984 }
11985 }
11986 }
11987 image=MorphImages(image,number_frames,exception);
11988 if (image == (Image *) NULL)
11989 goto PerlException;
11990 for ( ; image; image=image->next)
11991 {
11992 AddImageToRegistry(sv,image);
11993 rv=newRV(sv);
11994 av_push(av,sv_bless(rv,hv));
11995 SvREFCNT_dec(sv);
11996 }
11997 exception=DestroyExceptionInfo(exception);
11998 ST(0)=av_reference;
11999 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12000 XSRETURN(1);
12001
12002 PerlException:
12003 InheritPerlException(exception,perl_exception);
12004 exception=DestroyExceptionInfo(exception);
12005 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12006 SvPOK_on(perl_exception);
12007 ST(0)=sv_2mortal(perl_exception);
12008 XSRETURN(1);
12009 }
12010
12011#
12012###############################################################################
12013# #
12014# #
12015# #
12016# M o s a i c #
12017# #
12018# #
12019# #
12020###############################################################################
12021#
12022#
12023void
12024Mosaic(ref)
12025 Image::Magick ref=NO_INIT
12026 ALIAS:
12027 MosaicImage = 1
12028 mosaic = 2
12029 mosaicimage = 3
12030 PPCODE:
12031 {
12032 AV
12033 *av;
12034
12035 ExceptionInfo
12036 *exception;
12037
12038 HV
12039 *hv;
12040
12041 Image
12042 *image;
12043
12044 struct PackageInfo
12045 *info;
12046
12047 SV
12048 *perl_exception,
12049 *reference,
12050 *rv,
12051 *sv;
12052
12053 PERL_UNUSED_VAR(ref);
12054 PERL_UNUSED_VAR(ix);
12055 exception=AcquireExceptionInfo();
12056 perl_exception=newSVpv("",0);
12057 sv=NULL;
12058 if (sv_isobject(ST(0)) == 0)
12059 {
12060 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12061 PackageName);
12062 goto PerlException;
12063 }
12064 reference=SvRV(ST(0));
12065 hv=SvSTASH(reference);
12066 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12067 if (image == (Image *) NULL)
12068 {
12069 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12070 PackageName);
12071 goto PerlException;
12072 }
12073 image=MergeImageLayers(image,MosaicLayer,exception);
12074 /*
12075 Create blessed Perl array for the returned image.
12076 */
12077 av=newAV();
12078 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12079 SvREFCNT_dec(av);
12080 AddImageToRegistry(sv,image);
12081 rv=newRV(sv);
12082 av_push(av,sv_bless(rv,hv));
12083 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000012084 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000012085 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012086 SetImageInfo(info->image_info,0,exception);
12087 exception=DestroyExceptionInfo(exception);
12088 SvREFCNT_dec(perl_exception);
12089 XSRETURN(1);
12090
12091 PerlException:
12092 InheritPerlException(exception,perl_exception);
12093 exception=DestroyExceptionInfo(exception);
12094 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12095 SvPOK_on(perl_exception); /* return messages in string context */
12096 ST(0)=sv_2mortal(perl_exception);
12097 XSRETURN(1);
12098 }
12099
12100#
12101###############################################################################
12102# #
12103# #
12104# #
12105# P i n g #
12106# #
12107# #
12108# #
12109###############################################################################
12110#
12111#
12112void
12113Ping(ref,...)
12114 Image::Magick ref=NO_INIT
12115 ALIAS:
12116 PingImage = 1
12117 ping = 2
12118 pingimage = 3
12119 PPCODE:
12120 {
12121 AV
12122 *av;
12123
12124 char
12125 **keep,
12126 **list;
12127
12128 ExceptionInfo
12129 *exception;
12130
12131 Image
12132 *image,
12133 *next;
12134
12135 int
12136 n;
12137
12138 MagickBooleanType
12139 status;
12140
12141 register char
12142 **p;
12143
12144 register ssize_t
12145 i;
12146
12147 ssize_t
12148 ac;
12149
12150 STRLEN
12151 *length;
12152
12153 struct PackageInfo
12154 *info,
12155 *package_info;
12156
12157 SV
12158 *perl_exception,
12159 *reference;
12160
12161 size_t
12162 count;
12163
12164 PERL_UNUSED_VAR(ref);
12165 PERL_UNUSED_VAR(ix);
12166 exception=AcquireExceptionInfo();
12167 perl_exception=newSVpv("",0);
12168 package_info=(struct PackageInfo *) NULL;
12169 ac=(items < 2) ? 1 : items-1;
12170 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12171 keep=list;
12172 length=(STRLEN *) NULL;
12173 if (list == (char **) NULL)
12174 {
12175 ThrowPerlException(exception,ResourceLimitError,
12176 "MemoryAllocationFailed",PackageName);
12177 goto PerlException;
12178 }
12179 keep=list;
12180 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12181 if (length == (STRLEN *) NULL)
12182 {
12183 ThrowPerlException(exception,ResourceLimitError,
12184 "MemoryAllocationFailed",PackageName);
12185 goto PerlException;
12186 }
12187 if (sv_isobject(ST(0)) == 0)
12188 {
12189 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12190 PackageName);
12191 goto PerlException;
12192 }
12193 reference=SvRV(ST(0));
12194 if (SvTYPE(reference) != SVt_PVAV)
12195 {
12196 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12197 PackageName);
12198 goto PerlException;
12199 }
12200 av=(AV *) reference;
12201 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12202 exception);
12203 package_info=ClonePackageInfo(info,exception);
12204 n=1;
12205 if (items <= 1)
12206 *list=(char *) (*package_info->image_info->filename ?
12207 package_info->image_info->filename : "XC:black");
12208 else
12209 for (n=0, i=0; i < ac; i++)
12210 {
12211 list[n]=(char *) SvPV(ST(i+1),length[n]);
12212 if ((items >= 3) && strEQcase(list[n],"blob"))
12213 {
12214 void
12215 *blob;
12216
12217 i++;
12218 blob=(void *) (SvPV(ST(i+1),length[n]));
12219 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12220 }
12221 if ((items >= 3) && strEQcase(list[n],"filename"))
12222 continue;
12223 if ((items >= 3) && strEQcase(list[n],"file"))
12224 {
12225 FILE
12226 *file;
12227
12228 PerlIO
12229 *io_info;
12230
12231 i++;
12232 io_info=IoIFP(sv_2io(ST(i+1)));
12233 if (io_info == (PerlIO *) NULL)
12234 {
12235 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12236 PackageName);
12237 continue;
12238 }
12239 file=PerlIO_findFILE(io_info);
12240 if (file == (FILE *) NULL)
12241 {
12242 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12243 PackageName);
12244 continue;
12245 }
12246 SetImageInfoFile(package_info->image_info,file);
12247 }
12248 if ((items >= 3) && strEQcase(list[n],"magick"))
12249 continue;
12250 n++;
12251 }
12252 list[n]=(char *) NULL;
12253 keep=list;
12254 status=ExpandFilenames(&n,&list);
12255 if (status == MagickFalse)
12256 {
12257 ThrowPerlException(exception,ResourceLimitError,
12258 "MemoryAllocationFailed",PackageName);
12259 goto PerlException;
12260 }
12261 count=0;
12262 for (i=0; i < n; i++)
12263 {
12264 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012265 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012266 image=PingImage(package_info->image_info,exception);
12267 if (image == (Image *) NULL)
12268 break;
12269 if ((package_info->image_info->file != (FILE *) NULL) ||
12270 (package_info->image_info->blob != (void *) NULL))
12271 DisassociateImageStream(image);
12272 count+=GetImageListLength(image);
12273 EXTEND(sp,4*count);
12274 for (next=image; next; next=next->next)
12275 {
12276 PUSHs(sv_2mortal(newSViv(next->columns)));
12277 PUSHs(sv_2mortal(newSViv(next->rows)));
12278 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12279 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12280 }
12281 image=DestroyImageList(image);
12282 }
12283 /*
12284 Free resources.
12285 */
12286 for (i=0; i < n; i++)
12287 if (list[i] != (char *) NULL)
12288 for (p=keep; list[i] != *p++; )
12289 if (*p == NULL)
12290 {
12291 list[i]=(char *) RelinquishMagickMemory(list[i]);
12292 break;
12293 }
12294
12295 PerlException:
12296 if (package_info != (struct PackageInfo *) NULL)
12297 DestroyPackageInfo(package_info);
12298 if (list && (list != keep))
12299 list=(char **) RelinquishMagickMemory(list);
12300 if (keep)
12301 keep=(char **) RelinquishMagickMemory(keep);
12302 if (length)
12303 length=(STRLEN *) RelinquishMagickMemory(length);
12304 InheritPerlException(exception,perl_exception);
12305 exception=DestroyExceptionInfo(exception);
12306 SvREFCNT_dec(perl_exception); /* throw away all errors */
12307 }
12308
12309#
12310###############################################################################
12311# #
12312# #
12313# #
12314# P r e v i e w #
12315# #
12316# #
12317# #
12318###############################################################################
12319#
12320#
12321void
12322Preview(ref,...)
12323 Image::Magick ref=NO_INIT
12324 ALIAS:
12325 PreviewImage = 1
12326 preview = 2
12327 previewimage = 3
12328 PPCODE:
12329 {
12330 AV
12331 *av;
12332
12333 ExceptionInfo
12334 *exception;
12335
12336 HV
12337 *hv;
12338
12339 Image
12340 *image,
12341 *preview_image;
12342
12343 PreviewType
12344 preview_type;
12345
12346 struct PackageInfo
12347 *info;
12348
12349 SV
12350 *av_reference,
12351 *perl_exception,
12352 *reference,
12353 *rv,
12354 *sv;
12355
12356 PERL_UNUSED_VAR(ref);
12357 PERL_UNUSED_VAR(ix);
12358 exception=AcquireExceptionInfo();
12359 perl_exception=newSVpv("",0);
12360 sv=NULL;
12361 av=NULL;
12362 if (sv_isobject(ST(0)) == 0)
12363 {
12364 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12365 PackageName);
12366 goto PerlException;
12367 }
12368 reference=SvRV(ST(0));
12369 hv=SvSTASH(reference);
12370 av=newAV();
12371 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12372 SvREFCNT_dec(av);
12373 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12374 if (image == (Image *) NULL)
12375 {
12376 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12377 PackageName);
12378 goto PerlException;
12379 }
12380 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12381 preview_type=GammaPreview;
12382 if (items > 1)
12383 preview_type=(PreviewType)
12384 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12385 for ( ; image; image=image->next)
12386 {
12387 preview_image=PreviewImage(image,preview_type,exception);
12388 if (preview_image == (Image *) NULL)
12389 goto PerlException;
12390 AddImageToRegistry(sv,preview_image);
12391 rv=newRV(sv);
12392 av_push(av,sv_bless(rv,hv));
12393 SvREFCNT_dec(sv);
12394 }
12395 exception=DestroyExceptionInfo(exception);
12396 ST(0)=av_reference;
12397 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12398 XSRETURN(1);
12399
12400 PerlException:
12401 InheritPerlException(exception,perl_exception);
12402 exception=DestroyExceptionInfo(exception);
12403 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12404 SvPOK_on(perl_exception);
12405 ST(0)=sv_2mortal(perl_exception);
12406 XSRETURN(1);
12407 }
12408
12409#
12410###############################################################################
12411# #
12412# #
12413# #
12414# Q u e r y C o l o r #
12415# #
12416# #
12417# #
12418###############################################################################
12419#
12420#
12421void
12422QueryColor(ref,...)
12423 Image::Magick ref=NO_INIT
12424 ALIAS:
12425 querycolor = 1
12426 PPCODE:
12427 {
12428 char
12429 *name;
12430
12431 ExceptionInfo
12432 *exception;
12433
12434 PixelInfo
12435 color;
12436
12437 register ssize_t
12438 i;
12439
12440 SV
12441 *perl_exception;
12442
12443 PERL_UNUSED_VAR(ref);
12444 PERL_UNUSED_VAR(ix);
12445 exception=AcquireExceptionInfo();
12446 perl_exception=newSVpv("",0);
12447 if (items == 1)
12448 {
12449 const ColorInfo
12450 **colorlist;
12451
12452 size_t
12453 colors;
12454
12455 colorlist=GetColorInfoList("*",&colors,exception);
12456 EXTEND(sp,colors);
12457 for (i=0; i < (ssize_t) colors; i++)
12458 {
12459 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12460 }
12461 colorlist=(const ColorInfo **)
12462 RelinquishMagickMemory((ColorInfo **) colorlist);
12463 goto PerlException;
12464 }
12465 EXTEND(sp,5*items);
12466 for (i=1; i < items; i++)
12467 {
12468 name=(char *) SvPV(ST(i),na);
12469 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12470 {
12471 PUSHs(&sv_undef);
12472 continue;
12473 }
12474 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12475 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12476 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12477 if (color.colorspace == CMYKColorspace)
12478 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012479 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012480 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12481 }
12482
12483 PerlException:
12484 InheritPerlException(exception,perl_exception);
12485 exception=DestroyExceptionInfo(exception);
12486 SvREFCNT_dec(perl_exception);
12487 }
12488
12489#
12490###############################################################################
12491# #
12492# #
12493# #
12494# Q u e r y C o l o r N a m e #
12495# #
12496# #
12497# #
12498###############################################################################
12499#
12500#
12501void
12502QueryColorname(ref,...)
12503 Image::Magick ref=NO_INIT
12504 ALIAS:
12505 querycolorname = 1
12506 PPCODE:
12507 {
12508 AV
12509 *av;
12510
12511 char
cristy151b66d2015-04-15 10:50:31 +000012512 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012513
12514 ExceptionInfo
12515 *exception;
12516
12517 Image
12518 *image;
12519
12520 PixelInfo
12521 target_color;
12522
12523 register ssize_t
12524 i;
12525
12526 struct PackageInfo
12527 *info;
12528
12529 SV
12530 *perl_exception,
12531 *reference; /* reference is the SV* of ref=SvIV(reference) */
12532
12533 PERL_UNUSED_VAR(ref);
12534 PERL_UNUSED_VAR(ix);
12535 exception=AcquireExceptionInfo();
12536 perl_exception=newSVpv("",0);
12537 reference=SvRV(ST(0));
12538 av=(AV *) reference;
12539 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12540 exception);
12541 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12542 if (image == (Image *) NULL)
12543 {
12544 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12545 PackageName);
12546 goto PerlException;
12547 }
12548 EXTEND(sp,items);
12549 for (i=1; i < items; i++)
12550 {
12551 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12552 exception);
12553 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12554 exception);
12555 PUSHs(sv_2mortal(newSVpv(message,0)));
12556 }
12557
12558 PerlException:
12559 InheritPerlException(exception,perl_exception);
12560 exception=DestroyExceptionInfo(exception);
12561 SvREFCNT_dec(perl_exception);
12562 }
12563
12564#
12565###############################################################################
12566# #
12567# #
12568# #
12569# Q u e r y F o n t #
12570# #
12571# #
12572# #
12573###############################################################################
12574#
12575#
12576void
12577QueryFont(ref,...)
12578 Image::Magick ref=NO_INIT
12579 ALIAS:
12580 queryfont = 1
12581 PPCODE:
12582 {
12583 char
12584 *name,
cristy151b66d2015-04-15 10:50:31 +000012585 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012586
12587 ExceptionInfo
12588 *exception;
12589
12590 register ssize_t
12591 i;
12592
12593 SV
12594 *perl_exception;
12595
12596 volatile const TypeInfo
12597 *type_info;
12598
12599 PERL_UNUSED_VAR(ref);
12600 PERL_UNUSED_VAR(ix);
12601 exception=AcquireExceptionInfo();
12602 perl_exception=newSVpv("",0);
12603 if (items == 1)
12604 {
12605 const TypeInfo
12606 **typelist;
12607
12608 size_t
12609 types;
12610
12611 typelist=GetTypeInfoList("*",&types,exception);
12612 EXTEND(sp,types);
12613 for (i=0; i < (ssize_t) types; i++)
12614 {
12615 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12616 }
12617 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12618 typelist);
12619 goto PerlException;
12620 }
12621 EXTEND(sp,10*items);
12622 for (i=1; i < items; i++)
12623 {
12624 name=(char *) SvPV(ST(i),na);
12625 type_info=GetTypeInfo(name,exception);
12626 if (type_info == (TypeInfo *) NULL)
12627 {
12628 PUSHs(&sv_undef);
12629 continue;
12630 }
12631 if (type_info->name == (char *) NULL)
12632 PUSHs(&sv_undef);
12633 else
12634 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12635 if (type_info->description == (char *) NULL)
12636 PUSHs(&sv_undef);
12637 else
12638 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12639 if (type_info->family == (char *) NULL)
12640 PUSHs(&sv_undef);
12641 else
12642 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12643 if (type_info->style == UndefinedStyle)
12644 PUSHs(&sv_undef);
12645 else
12646 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12647 type_info->style),0)));
12648 if (type_info->stretch == UndefinedStretch)
12649 PUSHs(&sv_undef);
12650 else
12651 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12652 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012653 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012654 type_info->weight);
12655 PUSHs(sv_2mortal(newSVpv(message,0)));
12656 if (type_info->encoding == (char *) NULL)
12657 PUSHs(&sv_undef);
12658 else
12659 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12660 if (type_info->foundry == (char *) NULL)
12661 PUSHs(&sv_undef);
12662 else
12663 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12664 if (type_info->format == (char *) NULL)
12665 PUSHs(&sv_undef);
12666 else
12667 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12668 if (type_info->metrics == (char *) NULL)
12669 PUSHs(&sv_undef);
12670 else
12671 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12672 if (type_info->glyphs == (char *) NULL)
12673 PUSHs(&sv_undef);
12674 else
12675 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12676 }
12677
12678 PerlException:
12679 InheritPerlException(exception,perl_exception);
12680 exception=DestroyExceptionInfo(exception);
12681 SvREFCNT_dec(perl_exception);
12682 }
12683
12684#
12685###############################################################################
12686# #
12687# #
12688# #
12689# Q u e r y F o n t M e t r i c s #
12690# #
12691# #
12692# #
12693###############################################################################
12694#
12695#
12696void
12697QueryFontMetrics(ref,...)
12698 Image::Magick ref=NO_INIT
12699 ALIAS:
12700 queryfontmetrics = 1
12701 PPCODE:
12702 {
12703 AffineMatrix
12704 affine,
12705 current;
12706
12707 AV
12708 *av;
12709
12710 char
12711 *attribute;
12712
12713 double
12714 x,
12715 y;
12716
12717 DrawInfo
12718 *draw_info;
12719
12720 ExceptionInfo
12721 *exception;
12722
12723 GeometryInfo
12724 geometry_info;
12725
12726 Image
12727 *image;
12728
12729 MagickBooleanType
12730 status;
12731
12732 MagickStatusType
12733 flags;
12734
12735 register ssize_t
12736 i;
12737
12738 ssize_t
12739 type;
12740
12741 struct PackageInfo
12742 *info,
12743 *package_info;
12744
12745 SV
12746 *perl_exception,
12747 *reference; /* reference is the SV* of ref=SvIV(reference) */
12748
12749 TypeMetric
12750 metrics;
12751
12752 PERL_UNUSED_VAR(ref);
12753 PERL_UNUSED_VAR(ix);
12754 exception=AcquireExceptionInfo();
12755 package_info=(struct PackageInfo *) NULL;
12756 perl_exception=newSVpv("",0);
12757 reference=SvRV(ST(0));
12758 av=(AV *) reference;
12759 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12760 exception);
12761 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12762 if (image == (Image *) NULL)
12763 {
12764 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12765 PackageName);
12766 goto PerlException;
12767 }
12768 package_info=ClonePackageInfo(info,exception);
12769 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12770 CloneString(&draw_info->text,"");
12771 current=draw_info->affine;
12772 GetAffineMatrix(&affine);
12773 x=0.0;
12774 y=0.0;
12775 EXTEND(sp,7*items);
12776 for (i=2; i < items; i+=2)
12777 {
12778 attribute=(char *) SvPV(ST(i-1),na);
12779 switch (*attribute)
12780 {
12781 case 'A':
12782 case 'a':
12783 {
12784 if (LocaleCompare(attribute,"antialias") == 0)
12785 {
12786 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12787 SvPV(ST(i),na));
12788 if (type < 0)
12789 {
12790 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12791 SvPV(ST(i),na));
12792 break;
12793 }
12794 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12795 break;
12796 }
12797 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12798 attribute);
12799 break;
12800 }
12801 case 'd':
12802 case 'D':
12803 {
12804 if (LocaleCompare(attribute,"density") == 0)
12805 {
12806 CloneString(&draw_info->density,SvPV(ST(i),na));
12807 break;
12808 }
12809 if (LocaleCompare(attribute,"direction") == 0)
12810 {
12811 draw_info->direction=(DirectionType) ParseCommandOption(
12812 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12813 break;
12814 }
12815 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12816 attribute);
12817 break;
12818 }
12819 case 'e':
12820 case 'E':
12821 {
12822 if (LocaleCompare(attribute,"encoding") == 0)
12823 {
12824 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12825 break;
12826 }
12827 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12828 attribute);
12829 break;
12830 }
12831 case 'f':
12832 case 'F':
12833 {
12834 if (LocaleCompare(attribute,"family") == 0)
12835 {
12836 CloneString(&draw_info->family,SvPV(ST(i),na));
12837 break;
12838 }
12839 if (LocaleCompare(attribute,"fill") == 0)
12840 {
12841 if (info)
12842 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12843 &draw_info->fill,exception);
12844 break;
12845 }
12846 if (LocaleCompare(attribute,"font") == 0)
12847 {
12848 CloneString(&draw_info->font,SvPV(ST(i),na));
12849 break;
12850 }
12851 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12852 attribute);
12853 break;
12854 }
12855 case 'g':
12856 case 'G':
12857 {
12858 if (LocaleCompare(attribute,"geometry") == 0)
12859 {
12860 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12861 break;
12862 }
12863 if (LocaleCompare(attribute,"gravity") == 0)
12864 {
12865 draw_info->gravity=(GravityType) ParseCommandOption(
12866 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12867 break;
12868 }
12869 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12870 attribute);
12871 break;
12872 }
12873 case 'i':
12874 case 'I':
12875 {
12876 if (LocaleCompare(attribute,"interline-spacing") == 0)
12877 {
12878 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12879 draw_info->interline_spacing=geometry_info.rho;
12880 break;
12881 }
12882 if (LocaleCompare(attribute,"interword-spacing") == 0)
12883 {
12884 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12885 draw_info->interword_spacing=geometry_info.rho;
12886 break;
12887 }
12888 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12889 attribute);
12890 break;
12891 }
12892 case 'k':
12893 case 'K':
12894 {
12895 if (LocaleCompare(attribute,"kerning") == 0)
12896 {
12897 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12898 draw_info->kerning=geometry_info.rho;
12899 break;
12900 }
12901 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12902 attribute);
12903 break;
12904 }
12905 case 'p':
12906 case 'P':
12907 {
12908 if (LocaleCompare(attribute,"pointsize") == 0)
12909 {
12910 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12911 draw_info->pointsize=geometry_info.rho;
12912 break;
12913 }
12914 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12915 attribute);
12916 break;
12917 }
12918 case 'r':
12919 case 'R':
12920 {
12921 if (LocaleCompare(attribute,"rotate") == 0)
12922 {
12923 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12924 affine.rx=geometry_info.rho;
12925 affine.ry=geometry_info.sigma;
12926 if ((flags & SigmaValue) == 0)
12927 affine.ry=affine.rx;
12928 break;
12929 }
12930 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12931 attribute);
12932 break;
12933 }
12934 case 's':
12935 case 'S':
12936 {
12937 if (LocaleCompare(attribute,"scale") == 0)
12938 {
12939 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12940 affine.sx=geometry_info.rho;
12941 affine.sy=geometry_info.sigma;
12942 if ((flags & SigmaValue) == 0)
12943 affine.sy=affine.sx;
12944 break;
12945 }
12946 if (LocaleCompare(attribute,"skew") == 0)
12947 {
12948 double
12949 x_angle,
12950 y_angle;
12951
12952 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12953 x_angle=geometry_info.rho;
12954 y_angle=geometry_info.sigma;
12955 if ((flags & SigmaValue) == 0)
12956 y_angle=x_angle;
12957 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12958 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12959 break;
12960 }
12961 if (LocaleCompare(attribute,"stroke") == 0)
12962 {
12963 if (info)
12964 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12965 &draw_info->stroke,exception);
12966 break;
12967 }
12968 if (LocaleCompare(attribute,"style") == 0)
12969 {
12970 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12971 SvPV(ST(i),na));
12972 if (type < 0)
12973 {
12974 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12975 SvPV(ST(i),na));
12976 break;
12977 }
12978 draw_info->style=(StyleType) type;
12979 break;
12980 }
12981 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12982 attribute);
12983 break;
12984 }
12985 case 't':
12986 case 'T':
12987 {
12988 if (LocaleCompare(attribute,"text") == 0)
12989 {
12990 CloneString(&draw_info->text,SvPV(ST(i),na));
12991 break;
12992 }
12993 if (LocaleCompare(attribute,"translate") == 0)
12994 {
12995 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12996 affine.tx=geometry_info.rho;
12997 affine.ty=geometry_info.sigma;
12998 if ((flags & SigmaValue) == 0)
12999 affine.ty=affine.tx;
13000 break;
13001 }
13002 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13003 attribute);
13004 break;
13005 }
13006 case 'w':
13007 case 'W':
13008 {
13009 if (LocaleCompare(attribute,"weight") == 0)
13010 {
13011 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13012 draw_info->weight=(size_t) geometry_info.rho;
13013 break;
13014 }
13015 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13016 attribute);
13017 break;
13018 }
13019 case 'x':
13020 case 'X':
13021 {
13022 if (LocaleCompare(attribute,"x") == 0)
13023 {
13024 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13025 x=geometry_info.rho;
13026 break;
13027 }
13028 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13029 attribute);
13030 break;
13031 }
13032 case 'y':
13033 case 'Y':
13034 {
13035 if (LocaleCompare(attribute,"y") == 0)
13036 {
13037 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13038 y=geometry_info.rho;
13039 break;
13040 }
13041 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13042 attribute);
13043 break;
13044 }
13045 default:
13046 {
13047 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13048 attribute);
13049 break;
13050 }
13051 }
13052 }
13053 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13054 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13055 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13056 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13057 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13058 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13059 if (draw_info->geometry == (char *) NULL)
13060 {
13061 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013062 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013063 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013064 }
13065 status=GetTypeMetrics(image,draw_info,&metrics,exception);
13066 (void) CatchImageException(image);
13067 if (status == MagickFalse)
13068 PUSHs(&sv_undef);
13069 else
13070 {
13071 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13072 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13073 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13074 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13075 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13076 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13077 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13078 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13079 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13080 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13081 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13082 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13083 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13084 }
13085 draw_info=DestroyDrawInfo(draw_info);
13086
13087 PerlException:
13088 if (package_info != (struct PackageInfo *) NULL)
13089 DestroyPackageInfo(package_info);
13090 InheritPerlException(exception,perl_exception);
13091 exception=DestroyExceptionInfo(exception);
13092 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13093 }
13094
13095#
13096###############################################################################
13097# #
13098# #
13099# #
13100# 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 #
13101# #
13102# #
13103# #
13104###############################################################################
13105#
13106#
13107void
13108QueryMultilineFontMetrics(ref,...)
13109 Image::Magick ref=NO_INIT
13110 ALIAS:
13111 querymultilinefontmetrics = 1
13112 PPCODE:
13113 {
13114 AffineMatrix
13115 affine,
13116 current;
13117
13118 AV
13119 *av;
13120
13121 char
13122 *attribute;
13123
13124 double
13125 x,
13126 y;
13127
13128 DrawInfo
13129 *draw_info;
13130
13131 ExceptionInfo
13132 *exception;
13133
13134 GeometryInfo
13135 geometry_info;
13136
13137 Image
13138 *image;
13139
13140 MagickBooleanType
13141 status;
13142
13143 MagickStatusType
13144 flags;
13145
13146 register ssize_t
13147 i;
13148
13149 ssize_t
13150 type;
13151
13152 struct PackageInfo
13153 *info,
13154 *package_info;
13155
13156 SV
13157 *perl_exception,
13158 *reference; /* reference is the SV* of ref=SvIV(reference) */
13159
13160 TypeMetric
13161 metrics;
13162
13163 PERL_UNUSED_VAR(ref);
13164 PERL_UNUSED_VAR(ix);
13165 exception=AcquireExceptionInfo();
13166 package_info=(struct PackageInfo *) NULL;
13167 perl_exception=newSVpv("",0);
13168 reference=SvRV(ST(0));
13169 av=(AV *) reference;
13170 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13171 exception);
13172 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13173 if (image == (Image *) NULL)
13174 {
13175 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13176 PackageName);
13177 goto PerlException;
13178 }
13179 package_info=ClonePackageInfo(info,exception);
13180 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13181 CloneString(&draw_info->text,"");
13182 current=draw_info->affine;
13183 GetAffineMatrix(&affine);
13184 x=0.0;
13185 y=0.0;
13186 EXTEND(sp,7*items);
13187 for (i=2; i < items; i+=2)
13188 {
13189 attribute=(char *) SvPV(ST(i-1),na);
13190 switch (*attribute)
13191 {
13192 case 'A':
13193 case 'a':
13194 {
13195 if (LocaleCompare(attribute,"antialias") == 0)
13196 {
13197 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13198 SvPV(ST(i),na));
13199 if (type < 0)
13200 {
13201 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13202 SvPV(ST(i),na));
13203 break;
13204 }
13205 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13206 break;
13207 }
13208 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13209 attribute);
13210 break;
13211 }
13212 case 'd':
13213 case 'D':
13214 {
13215 if (LocaleCompare(attribute,"density") == 0)
13216 {
13217 CloneString(&draw_info->density,SvPV(ST(i),na));
13218 break;
13219 }
13220 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13221 attribute);
13222 break;
13223 }
13224 case 'e':
13225 case 'E':
13226 {
13227 if (LocaleCompare(attribute,"encoding") == 0)
13228 {
13229 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13230 break;
13231 }
13232 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13233 attribute);
13234 break;
13235 }
13236 case 'f':
13237 case 'F':
13238 {
13239 if (LocaleCompare(attribute,"family") == 0)
13240 {
13241 CloneString(&draw_info->family,SvPV(ST(i),na));
13242 break;
13243 }
13244 if (LocaleCompare(attribute,"fill") == 0)
13245 {
13246 if (info)
13247 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13248 &draw_info->fill,exception);
13249 break;
13250 }
13251 if (LocaleCompare(attribute,"font") == 0)
13252 {
13253 CloneString(&draw_info->font,SvPV(ST(i),na));
13254 break;
13255 }
13256 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13257 attribute);
13258 break;
13259 }
13260 case 'g':
13261 case 'G':
13262 {
13263 if (LocaleCompare(attribute,"geometry") == 0)
13264 {
13265 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13266 break;
13267 }
13268 if (LocaleCompare(attribute,"gravity") == 0)
13269 {
13270 draw_info->gravity=(GravityType) ParseCommandOption(
13271 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13272 break;
13273 }
13274 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13275 attribute);
13276 break;
13277 }
13278 case 'p':
13279 case 'P':
13280 {
13281 if (LocaleCompare(attribute,"pointsize") == 0)
13282 {
13283 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13284 draw_info->pointsize=geometry_info.rho;
13285 break;
13286 }
13287 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13288 attribute);
13289 break;
13290 }
13291 case 'r':
13292 case 'R':
13293 {
13294 if (LocaleCompare(attribute,"rotate") == 0)
13295 {
13296 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13297 affine.rx=geometry_info.rho;
13298 affine.ry=geometry_info.sigma;
13299 if ((flags & SigmaValue) == 0)
13300 affine.ry=affine.rx;
13301 break;
13302 }
13303 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13304 attribute);
13305 break;
13306 }
13307 case 's':
13308 case 'S':
13309 {
13310 if (LocaleCompare(attribute,"scale") == 0)
13311 {
13312 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13313 affine.sx=geometry_info.rho;
13314 affine.sy=geometry_info.sigma;
13315 if ((flags & SigmaValue) == 0)
13316 affine.sy=affine.sx;
13317 break;
13318 }
13319 if (LocaleCompare(attribute,"skew") == 0)
13320 {
13321 double
13322 x_angle,
13323 y_angle;
13324
13325 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13326 x_angle=geometry_info.rho;
13327 y_angle=geometry_info.sigma;
13328 if ((flags & SigmaValue) == 0)
13329 y_angle=x_angle;
13330 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13331 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13332 break;
13333 }
13334 if (LocaleCompare(attribute,"stroke") == 0)
13335 {
13336 if (info)
13337 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13338 &draw_info->stroke,exception);
13339 break;
13340 }
13341 if (LocaleCompare(attribute,"style") == 0)
13342 {
13343 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13344 SvPV(ST(i),na));
13345 if (type < 0)
13346 {
13347 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13348 SvPV(ST(i),na));
13349 break;
13350 }
13351 draw_info->style=(StyleType) type;
13352 break;
13353 }
13354 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13355 attribute);
13356 break;
13357 }
13358 case 't':
13359 case 'T':
13360 {
13361 if (LocaleCompare(attribute,"text") == 0)
13362 {
13363 CloneString(&draw_info->text,SvPV(ST(i),na));
13364 break;
13365 }
13366 if (LocaleCompare(attribute,"translate") == 0)
13367 {
13368 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13369 affine.tx=geometry_info.rho;
13370 affine.ty=geometry_info.sigma;
13371 if ((flags & SigmaValue) == 0)
13372 affine.ty=affine.tx;
13373 break;
13374 }
13375 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13376 attribute);
13377 break;
13378 }
13379 case 'w':
13380 case 'W':
13381 {
13382 if (LocaleCompare(attribute,"weight") == 0)
13383 {
13384 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13385 draw_info->weight=(size_t) geometry_info.rho;
13386 break;
13387 }
13388 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13389 attribute);
13390 break;
13391 }
13392 case 'x':
13393 case 'X':
13394 {
13395 if (LocaleCompare(attribute,"x") == 0)
13396 {
13397 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13398 x=geometry_info.rho;
13399 break;
13400 }
13401 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13402 attribute);
13403 break;
13404 }
13405 case 'y':
13406 case 'Y':
13407 {
13408 if (LocaleCompare(attribute,"y") == 0)
13409 {
13410 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13411 y=geometry_info.rho;
13412 break;
13413 }
13414 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13415 attribute);
13416 break;
13417 }
13418 default:
13419 {
13420 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13421 attribute);
13422 break;
13423 }
13424 }
13425 }
13426 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13427 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13428 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13429 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13430 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13431 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13432 if (draw_info->geometry == (char *) NULL)
13433 {
13434 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013435 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013436 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013437 }
13438 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13439 (void) CatchException(exception);
13440 if (status == MagickFalse)
13441 PUSHs(&sv_undef);
13442 else
13443 {
13444 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13445 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13446 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13447 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13448 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13449 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13450 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13451 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13452 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13453 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13454 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13455 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13456 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13457 }
13458 draw_info=DestroyDrawInfo(draw_info);
13459
13460 PerlException:
13461 if (package_info != (struct PackageInfo *) NULL)
13462 DestroyPackageInfo(package_info);
13463 InheritPerlException(exception,perl_exception);
13464 exception=DestroyExceptionInfo(exception);
13465 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13466 }
13467
13468#
13469###############################################################################
13470# #
13471# #
13472# #
13473# Q u e r y F o r m a t #
13474# #
13475# #
13476# #
13477###############################################################################
13478#
13479#
13480void
13481QueryFormat(ref,...)
13482 Image::Magick ref=NO_INIT
13483 ALIAS:
13484 queryformat = 1
13485 PPCODE:
13486 {
13487 char
13488 *name;
13489
13490 ExceptionInfo
13491 *exception;
13492
13493 register ssize_t
13494 i;
13495
13496 SV
13497 *perl_exception;
13498
13499 volatile const MagickInfo
13500 *magick_info;
13501
13502 PERL_UNUSED_VAR(ref);
13503 PERL_UNUSED_VAR(ix);
13504 exception=AcquireExceptionInfo();
13505 perl_exception=newSVpv("",0);
13506 if (items == 1)
13507 {
13508 char
cristy151b66d2015-04-15 10:50:31 +000013509 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013510
13511 const MagickInfo
13512 **format_list;
13513
13514 size_t
13515 types;
13516
13517 format_list=GetMagickInfoList("*",&types,exception);
13518 EXTEND(sp,types);
13519 for (i=0; i < (ssize_t) types; i++)
13520 {
cristy151b66d2015-04-15 10:50:31 +000013521 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013522 LocaleLower(format);
13523 PUSHs(sv_2mortal(newSVpv(format,0)));
13524 }
13525 format_list=(const MagickInfo **)
13526 RelinquishMagickMemory((MagickInfo *) format_list);
13527 goto PerlException;
13528 }
13529 EXTEND(sp,8*items);
13530 for (i=1; i < items; i++)
13531 {
13532 name=(char *) SvPV(ST(i),na);
13533 magick_info=GetMagickInfo(name,exception);
13534 if (magick_info == (const MagickInfo *) NULL)
13535 {
13536 PUSHs(&sv_undef);
13537 continue;
13538 }
cristy4a3ce0a2013-08-03 20:06:59 +000013539 if (magick_info->description == (char *) NULL)
13540 PUSHs(&sv_undef);
13541 else
13542 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13543 if (magick_info->module == (char *) NULL)
13544 PUSHs(&sv_undef);
13545 else
13546 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13547 }
13548
13549 PerlException:
13550 InheritPerlException(exception,perl_exception);
13551 exception=DestroyExceptionInfo(exception);
13552 SvREFCNT_dec(perl_exception);
13553 }
13554
13555#
13556###############################################################################
13557# #
13558# #
13559# #
13560# Q u e r y O p t i o n #
13561# #
13562# #
13563# #
13564###############################################################################
13565#
13566#
13567void
13568QueryOption(ref,...)
13569 Image::Magick ref=NO_INIT
13570 ALIAS:
13571 queryoption = 1
13572 PPCODE:
13573 {
13574 char
13575 **options;
13576
13577 ExceptionInfo
13578 *exception;
13579
13580 register ssize_t
13581 i;
13582
13583 ssize_t
13584 j,
13585 option;
13586
13587 SV
13588 *perl_exception;
13589
13590 PERL_UNUSED_VAR(ref);
13591 PERL_UNUSED_VAR(ix);
13592 exception=AcquireExceptionInfo();
13593 perl_exception=newSVpv("",0);
13594 EXTEND(sp,8*items);
13595 for (i=1; i < items; i++)
13596 {
13597 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13598 SvPV(ST(i),na));
13599 options=GetCommandOptions((CommandOption) option);
13600 if (options == (char **) NULL)
13601 PUSHs(&sv_undef);
13602 else
13603 {
13604 for (j=0; options[j] != (char *) NULL; j++)
13605 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13606 options=DestroyStringList(options);
13607 }
13608 }
13609
13610 InheritPerlException(exception,perl_exception);
13611 exception=DestroyExceptionInfo(exception);
13612 SvREFCNT_dec(perl_exception);
13613 }
13614
13615#
13616###############################################################################
13617# #
13618# #
13619# #
13620# R e a d #
13621# #
13622# #
13623# #
13624###############################################################################
13625#
13626#
13627void
13628Read(ref,...)
13629 Image::Magick ref=NO_INIT
13630 ALIAS:
13631 ReadImage = 1
13632 read = 2
13633 readimage = 3
13634 PPCODE:
13635 {
13636 AV
13637 *av;
13638
13639 char
13640 **keep,
13641 **list;
13642
13643 ExceptionInfo
13644 *exception;
13645
13646 HV
13647 *hv;
13648
13649 Image
13650 *image;
13651
13652 int
13653 n;
13654
13655 MagickBooleanType
13656 status;
13657
13658 register char
13659 **p;
13660
13661 register ssize_t
13662 i;
13663
13664 ssize_t
13665 ac,
13666 number_images;
13667
13668 STRLEN
13669 *length;
13670
13671 struct PackageInfo
13672 *info,
13673 *package_info;
13674
13675 SV
13676 *perl_exception, /* Perl variable for storing messages */
13677 *reference,
13678 *rv,
13679 *sv;
13680
13681 PERL_UNUSED_VAR(ref);
13682 PERL_UNUSED_VAR(ix);
13683 exception=AcquireExceptionInfo();
13684 perl_exception=newSVpv("",0);
13685 sv=NULL;
13686 package_info=(struct PackageInfo *) NULL;
13687 number_images=0;
13688 ac=(items < 2) ? 1 : items-1;
13689 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13690 keep=list;
13691 length=(STRLEN *) NULL;
13692 if (list == (char **) NULL)
13693 {
13694 ThrowPerlException(exception,ResourceLimitError,
13695 "MemoryAllocationFailed",PackageName);
13696 goto PerlException;
13697 }
13698 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13699 if (length == (STRLEN *) NULL)
13700 {
13701 ThrowPerlException(exception,ResourceLimitError,
13702 "MemoryAllocationFailed",PackageName);
13703 goto PerlException;
13704 }
13705 if (sv_isobject(ST(0)) == 0)
13706 {
13707 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13708 PackageName);
13709 goto PerlException;
13710 }
13711 reference=SvRV(ST(0));
13712 hv=SvSTASH(reference);
13713 if (SvTYPE(reference) != SVt_PVAV)
13714 {
13715 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13716 PackageName);
13717 goto PerlException;
13718 }
13719 av=(AV *) reference;
13720 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13721 exception);
13722 package_info=ClonePackageInfo(info,exception);
13723 n=1;
13724 if (items <= 1)
13725 *list=(char *) (*package_info->image_info->filename ?
13726 package_info->image_info->filename : "XC:black");
13727 else
13728 for (n=0, i=0; i < ac; i++)
13729 {
13730 list[n]=(char *) SvPV(ST(i+1),length[n]);
13731 if ((items >= 3) && strEQcase(list[n],"blob"))
13732 {
13733 void
13734 *blob;
13735
13736 i++;
13737 blob=(void *) (SvPV(ST(i+1),length[n]));
13738 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13739 }
13740 if ((items >= 3) && strEQcase(list[n],"filename"))
13741 continue;
13742 if ((items >= 3) && strEQcase(list[n],"file"))
13743 {
13744 FILE
13745 *file;
13746
13747 PerlIO
13748 *io_info;
13749
13750 i++;
13751 io_info=IoIFP(sv_2io(ST(i+1)));
13752 if (io_info == (PerlIO *) NULL)
13753 {
13754 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13755 PackageName);
13756 continue;
13757 }
13758 file=PerlIO_findFILE(io_info);
13759 if (file == (FILE *) NULL)
13760 {
13761 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13762 PackageName);
13763 continue;
13764 }
13765 SetImageInfoFile(package_info->image_info,file);
13766 }
13767 if ((items >= 3) && strEQcase(list[n],"magick"))
13768 continue;
13769 n++;
13770 }
13771 list[n]=(char *) NULL;
13772 keep=list;
13773 status=ExpandFilenames(&n,&list);
13774 if (status == MagickFalse)
13775 {
13776 ThrowPerlException(exception,ResourceLimitError,
13777 "MemoryAllocationFailed",PackageName);
13778 goto PerlException;
13779 }
13780 number_images=0;
13781 for (i=0; i < n; i++)
13782 {
13783 if ((package_info->image_info->file == (FILE *) NULL) &&
13784 (package_info->image_info->blob == (void *) NULL))
13785 image=ReadImages(package_info->image_info,list[i],exception);
13786 else
13787 {
13788 image=ReadImages(package_info->image_info,
13789 package_info->image_info->filename,exception);
13790 if (image != (Image *) NULL)
13791 DisassociateImageStream(image);
13792 }
13793 if (image == (Image *) NULL)
13794 break;
13795 for ( ; image; image=image->next)
13796 {
13797 AddImageToRegistry(sv,image);
13798 rv=newRV(sv);
13799 av_push(av,sv_bless(rv,hv));
13800 SvREFCNT_dec(sv);
13801 number_images++;
13802 }
13803 }
13804 /*
13805 Free resources.
13806 */
13807 for (i=0; i < n; i++)
13808 if (list[i] != (char *) NULL)
13809 for (p=keep; list[i] != *p++; )
13810 if (*p == (char *) NULL)
13811 {
13812 list[i]=(char *) RelinquishMagickMemory(list[i]);
13813 break;
13814 }
13815
13816 PerlException:
13817 if (package_info != (struct PackageInfo *) NULL)
13818 DestroyPackageInfo(package_info);
13819 if (list && (list != keep))
13820 list=(char **) RelinquishMagickMemory(list);
13821 if (keep)
13822 keep=(char **) RelinquishMagickMemory(keep);
13823 if (length)
13824 length=(STRLEN *) RelinquishMagickMemory(length);
13825 InheritPerlException(exception,perl_exception);
13826 exception=DestroyExceptionInfo(exception);
13827 sv_setiv(perl_exception,(IV) number_images);
13828 SvPOK_on(perl_exception);
13829 ST(0)=sv_2mortal(perl_exception);
13830 XSRETURN(1);
13831 }
13832
13833#
13834###############################################################################
13835# #
13836# #
13837# #
13838# R e m o t e #
13839# #
13840# #
13841# #
13842###############################################################################
13843#
13844#
13845void
13846Remote(ref,...)
13847 Image::Magick ref=NO_INIT
13848 ALIAS:
13849 RemoteCommand = 1
13850 remote = 2
13851 remoteCommand = 3
13852 PPCODE:
13853 {
13854 AV
13855 *av;
13856
13857 ExceptionInfo
13858 *exception;
13859
13860 register ssize_t
13861 i;
13862
13863 SV
13864 *perl_exception,
13865 *reference;
13866
13867 struct PackageInfo
13868 *info;
13869
13870 PERL_UNUSED_VAR(ref);
13871 PERL_UNUSED_VAR(ix);
13872 exception=AcquireExceptionInfo();
13873 perl_exception=newSVpv("",0);
13874 reference=SvRV(ST(0));
13875 av=(AV *) reference;
13876 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13877 exception);
13878 for (i=1; i < items; i++)
13879 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13880 SvPV(ST(i),na),exception);
13881 InheritPerlException(exception,perl_exception);
13882 exception=DestroyExceptionInfo(exception);
13883 SvREFCNT_dec(perl_exception); /* throw away all errors */
13884 }
13885
13886#
13887###############################################################################
13888# #
13889# #
13890# #
13891# S e t #
13892# #
13893# #
13894# #
13895###############################################################################
13896#
13897#
13898void
13899Set(ref,...)
13900 Image::Magick ref=NO_INIT
13901 ALIAS:
13902 SetAttributes = 1
13903 SetAttribute = 2
13904 set = 3
13905 setattributes = 4
13906 setattribute = 5
13907 PPCODE:
13908 {
13909 ExceptionInfo
13910 *exception;
13911
13912 Image
13913 *image;
13914
13915 register ssize_t
13916 i;
13917
13918 struct PackageInfo
13919 *info;
13920
13921 SV
13922 *perl_exception,
13923 *reference; /* reference is the SV* of ref=SvIV(reference) */
13924
13925 PERL_UNUSED_VAR(ref);
13926 PERL_UNUSED_VAR(ix);
13927 exception=AcquireExceptionInfo();
13928 perl_exception=newSVpv("",0);
13929 if (sv_isobject(ST(0)) == 0)
13930 {
13931 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13932 PackageName);
13933 goto PerlException;
13934 }
13935 reference=SvRV(ST(0));
13936 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13937 if (items == 2)
13938 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13939 else
13940 for (i=2; i < items; i+=2)
13941 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13942
13943 PerlException:
13944 InheritPerlException(exception,perl_exception);
13945 exception=DestroyExceptionInfo(exception);
13946 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13947 SvPOK_on(perl_exception);
13948 ST(0)=sv_2mortal(perl_exception);
13949 XSRETURN(1);
13950 }
13951
13952#
13953###############################################################################
13954# #
13955# #
13956# #
13957# S e t P i x e l #
13958# #
13959# #
13960# #
13961###############################################################################
13962#
13963#
13964void
13965SetPixel(ref,...)
13966 Image::Magick ref=NO_INIT
13967 ALIAS:
13968 setpixel = 1
13969 setPixel = 2
13970 PPCODE:
13971 {
13972 AV
13973 *av;
13974
13975 char
13976 *attribute;
13977
13978 ChannelType
13979 channel,
13980 channel_mask;
13981
13982 ExceptionInfo
13983 *exception;
13984
13985 Image
13986 *image;
13987
13988 MagickBooleanType
13989 normalize;
13990
13991 RectangleInfo
13992 region;
13993
13994 register ssize_t
13995 i;
13996
13997 register Quantum
13998 *q;
13999
14000 ssize_t
14001 option;
14002
14003 struct PackageInfo
14004 *info;
14005
14006 SV
14007 *perl_exception,
14008 *reference; /* reference is the SV* of ref=SvIV(reference) */
14009
14010 PERL_UNUSED_VAR(ref);
14011 PERL_UNUSED_VAR(ix);
14012 exception=AcquireExceptionInfo();
14013 perl_exception=newSVpv("",0);
14014 reference=SvRV(ST(0));
14015 av=(AV *) reference;
14016 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14017 exception);
14018 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14019 if (image == (Image *) NULL)
14020 {
14021 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14022 PackageName);
14023 goto PerlException;
14024 }
14025 av=(AV *) NULL;
14026 normalize=MagickTrue;
14027 region.x=0;
14028 region.y=0;
14029 region.width=image->columns;
14030 region.height=1;
14031 if (items == 1)
14032 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
14033 channel=DefaultChannels;
14034 for (i=2; i < items; i+=2)
14035 {
14036 attribute=(char *) SvPV(ST(i-1),na);
14037 switch (*attribute)
14038 {
14039 case 'C':
14040 case 'c':
14041 {
14042 if (LocaleCompare(attribute,"channel") == 0)
14043 {
14044 ssize_t
14045 option;
14046
14047 option=ParseChannelOption(SvPV(ST(i),na));
14048 if (option < 0)
14049 {
14050 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14051 SvPV(ST(i),na));
14052 return;
14053 }
14054 channel=(ChannelType) option;
14055 break;
14056 }
14057 if (LocaleCompare(attribute,"color") == 0)
14058 {
14059 if (SvTYPE(ST(i)) != SVt_RV)
14060 {
14061 char
cristy151b66d2015-04-15 10:50:31 +000014062 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014063
cristy151b66d2015-04-15 10:50:31 +000014064 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000014065 "invalid %.60s value",attribute);
14066 ThrowPerlException(exception,OptionError,message,
14067 SvPV(ST(i),na));
14068 }
14069 av=(AV *) SvRV(ST(i));
14070 break;
14071 }
14072 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14073 attribute);
14074 break;
14075 }
14076 case 'g':
14077 case 'G':
14078 {
14079 if (LocaleCompare(attribute,"geometry") == 0)
14080 {
14081 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14082 break;
14083 }
14084 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14085 attribute);
14086 break;
14087 }
14088 case 'N':
14089 case 'n':
14090 {
14091 if (LocaleCompare(attribute,"normalize") == 0)
14092 {
14093 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14094 SvPV(ST(i),na));
14095 if (option < 0)
14096 {
14097 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14098 SvPV(ST(i),na));
14099 break;
14100 }
14101 normalize=option != 0 ? MagickTrue : MagickFalse;
14102 break;
14103 }
14104 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14105 attribute);
14106 break;
14107 }
14108 case 'x':
14109 case 'X':
14110 {
14111 if (LocaleCompare(attribute,"x") == 0)
14112 {
14113 region.x=SvIV(ST(i));
14114 break;
14115 }
14116 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14117 attribute);
14118 break;
14119 }
14120 case 'y':
14121 case 'Y':
14122 {
14123 if (LocaleCompare(attribute,"y") == 0)
14124 {
14125 region.y=SvIV(ST(i));
14126 break;
14127 }
14128 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14129 attribute);
14130 break;
14131 }
14132 default:
14133 {
14134 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14135 attribute);
14136 break;
14137 }
14138 }
14139 }
14140 (void) SetImageStorageClass(image,DirectClass,exception);
14141 channel_mask=SetImageChannelMask(image,channel);
14142 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14143 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14144 (SvTYPE(av) != SVt_PVAV))
14145 PUSHs(&sv_undef);
14146 else
14147 {
14148 double
14149 scale;
14150
14151 register ssize_t
14152 i;
14153
14154 i=0;
14155 scale=1.0;
14156 if (normalize != MagickFalse)
14157 scale=QuantumRange;
14158 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14159 (i <= av_len(av)))
14160 {
14161 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14162 av_fetch(av,i,0)))),q);
14163 i++;
14164 }
14165 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14166 (i <= av_len(av)))
14167 {
14168 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14169 av_fetch(av,i,0)))),q);
14170 i++;
14171 }
14172 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14173 (i <= av_len(av)))
14174 {
14175 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14176 av_fetch(av,i,0)))),q);
14177 i++;
14178 }
14179 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14180 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14181 {
14182 SetPixelBlack(image,ClampToQuantum(scale*
14183 SvNV(*(av_fetch(av,i,0)))),q);
14184 i++;
14185 }
14186 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14187 (i <= av_len(av)))
14188 {
14189 SetPixelAlpha(image,ClampToQuantum(scale*
14190 SvNV(*(av_fetch(av,i,0)))),q);
14191 i++;
14192 }
14193 (void) SyncAuthenticPixels(image,exception);
14194 }
14195 (void) SetImageChannelMask(image,channel_mask);
14196
14197 PerlException:
14198 InheritPerlException(exception,perl_exception);
14199 exception=DestroyExceptionInfo(exception);
14200 SvREFCNT_dec(perl_exception);
14201 }
14202
14203#
14204###############################################################################
14205# #
14206# #
14207# #
14208# S m u s h #
14209# #
14210# #
14211# #
14212###############################################################################
14213#
14214#
14215void
14216Smush(ref,...)
14217 Image::Magick ref=NO_INIT
14218 ALIAS:
14219 SmushImage = 1
14220 smush = 2
14221 smushimage = 3
14222 PPCODE:
14223 {
14224 AV
14225 *av;
14226
14227 char
14228 *attribute;
14229
14230 ExceptionInfo
14231 *exception;
14232
14233 HV
14234 *hv;
14235
14236 Image
14237 *image;
14238
14239 register ssize_t
14240 i;
14241
14242 ssize_t
14243 offset,
14244 stack;
14245
14246 struct PackageInfo
14247 *info;
14248
14249 SV
14250 *av_reference,
14251 *perl_exception,
14252 *reference,
14253 *rv,
14254 *sv;
14255
14256 PERL_UNUSED_VAR(ref);
14257 PERL_UNUSED_VAR(ix);
14258 exception=AcquireExceptionInfo();
14259 perl_exception=newSVpv("",0);
14260 sv=NULL;
14261 attribute=NULL;
14262 av=NULL;
14263 if (sv_isobject(ST(0)) == 0)
14264 {
14265 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14266 PackageName);
14267 goto PerlException;
14268 }
14269 reference=SvRV(ST(0));
14270 hv=SvSTASH(reference);
14271 av=newAV();
14272 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14273 SvREFCNT_dec(av);
14274 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14275 if (image == (Image *) NULL)
14276 {
14277 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14278 PackageName);
14279 goto PerlException;
14280 }
14281 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14282 /*
14283 Get options.
14284 */
14285 offset=0;
14286 stack=MagickTrue;
14287 for (i=2; i < items; i+=2)
14288 {
14289 attribute=(char *) SvPV(ST(i-1),na);
14290 switch (*attribute)
14291 {
14292 case 'O':
14293 case 'o':
14294 {
14295 if (LocaleCompare(attribute,"offset") == 0)
14296 {
14297 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14298 break;
14299 }
14300 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14301 attribute);
14302 break;
14303 }
14304 case 'S':
14305 case 's':
14306 {
14307 if (LocaleCompare(attribute,"stack") == 0)
14308 {
14309 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14310 SvPV(ST(i),na));
14311 if (stack < 0)
14312 {
14313 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14314 SvPV(ST(i),na));
14315 return;
14316 }
14317 break;
14318 }
14319 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14320 attribute);
14321 break;
14322 }
14323 default:
14324 {
14325 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14326 attribute);
14327 break;
14328 }
14329 }
14330 }
14331 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14332 exception);
14333 if (image == (Image *) NULL)
14334 goto PerlException;
14335 for ( ; image; image=image->next)
14336 {
14337 AddImageToRegistry(sv,image);
14338 rv=newRV(sv);
14339 av_push(av,sv_bless(rv,hv));
14340 SvREFCNT_dec(sv);
14341 }
14342 exception=DestroyExceptionInfo(exception);
14343 ST(0)=av_reference;
14344 SvREFCNT_dec(perl_exception);
14345 XSRETURN(1);
14346
14347 PerlException:
14348 InheritPerlException(exception,perl_exception);
14349 exception=DestroyExceptionInfo(exception);
14350 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14351 SvPOK_on(perl_exception);
14352 ST(0)=sv_2mortal(perl_exception);
14353 XSRETURN(1);
14354 }
14355
14356#
14357###############################################################################
14358# #
14359# #
14360# #
14361# S t a t i s t i c s #
14362# #
14363# #
14364# #
14365###############################################################################
14366#
14367#
14368void
14369Statistics(ref,...)
14370 Image::Magick ref=NO_INIT
14371 ALIAS:
14372 StatisticsImage = 1
14373 statistics = 2
14374 statisticsimage = 3
14375 PPCODE:
14376 {
14377#define ChannelStatistics(channel) \
14378{ \
cristy151b66d2015-04-15 10:50:31 +000014379 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014380 (double) channel_statistics[channel].depth); \
14381 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014382 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014383 channel_statistics[channel].minima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014384 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014385 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014386 channel_statistics[channel].maxima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014387 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014388 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014389 channel_statistics[channel].mean/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014390 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014391 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014392 channel_statistics[channel].standard_deviation/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014393 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014394 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014395 channel_statistics[channel].kurtosis); \
14396 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014397 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014398 channel_statistics[channel].skewness); \
14399 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014400 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy275bdd92014-11-08 23:45:03 +000014401 channel_statistics[channel].entropy); \
14402 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014403}
14404
14405 AV
14406 *av;
14407
14408 char
cristy151b66d2015-04-15 10:50:31 +000014409 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014410
14411 ChannelStatistics
14412 *channel_statistics;
14413
cristy4a3ce0a2013-08-03 20:06:59 +000014414 ExceptionInfo
14415 *exception;
14416
14417 Image
14418 *image;
14419
14420 ssize_t
14421 count;
14422
14423 struct PackageInfo
14424 *info;
14425
14426 SV
14427 *perl_exception,
14428 *reference;
14429
14430 PERL_UNUSED_VAR(ref);
14431 PERL_UNUSED_VAR(ix);
14432 exception=AcquireExceptionInfo();
14433 perl_exception=newSVpv("",0);
14434 av=NULL;
14435 if (sv_isobject(ST(0)) == 0)
14436 {
14437 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14438 PackageName);
14439 goto PerlException;
14440 }
14441 reference=SvRV(ST(0));
14442 av=newAV();
14443 SvREFCNT_dec(av);
14444 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14445 if (image == (Image *) NULL)
14446 {
14447 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14448 PackageName);
14449 goto PerlException;
14450 }
cristy4a3ce0a2013-08-03 20:06:59 +000014451 count=0;
14452 for ( ; image; image=image->next)
14453 {
Cristyb1710fe2017-02-11 13:51:48 -050014454 register size_t
14455 i;
14456
cristy4a3ce0a2013-08-03 20:06:59 +000014457 channel_statistics=GetImageStatistics(image,exception);
14458 if (channel_statistics == (ChannelStatistics *) NULL)
14459 continue;
14460 count++;
Cristyb1710fe2017-02-11 13:51:48 -050014461 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
14462 {
14463 PixelChannel channel=GetPixelChannelChannel(image,i);
14464 PixelTrait traits=GetPixelChannelTraits(image,channel);
Cristy5a854dc2017-02-11 15:43:46 -050014465 if (traits == UndefinedPixelTrait)
Cristyb1710fe2017-02-11 13:51:48 -050014466 continue;
Cristy5a854dc2017-02-11 15:43:46 -050014467 EXTEND(sp,8*(i+1)*count);
Cristyb1710fe2017-02-11 13:51:48 -050014468 ChannelStatistics(channel);
14469 }
Cristy25813902017-02-11 15:47:52 -050014470 EXTEND(sp,8*(i+1)*count);
14471 ChannelStatistics(CompositePixelChannel);
cristy4a3ce0a2013-08-03 20:06:59 +000014472 channel_statistics=(ChannelStatistics *)
14473 RelinquishMagickMemory(channel_statistics);
14474 }
14475
14476 PerlException:
14477 InheritPerlException(exception,perl_exception);
14478 exception=DestroyExceptionInfo(exception);
14479 SvREFCNT_dec(perl_exception);
14480 }
14481
14482#
14483###############################################################################
14484# #
14485# #
14486# #
14487# S y n c A u t h e n t i c P i x e l s #
14488# #
14489# #
14490# #
14491###############################################################################
14492#
14493#
14494void
14495SyncAuthenticPixels(ref,...)
14496 Image::Magick ref = NO_INIT
14497 ALIAS:
14498 Syncauthenticpixels = 1
14499 SyncImagePixels = 2
14500 syncimagepixels = 3
14501 CODE:
14502 {
14503 ExceptionInfo
14504 *exception;
14505
14506 Image
14507 *image;
14508
14509 MagickBooleanType
14510 status;
14511
14512 struct PackageInfo
14513 *info;
14514
14515 SV
14516 *perl_exception,
14517 *reference;
14518
14519 PERL_UNUSED_VAR(ref);
14520 PERL_UNUSED_VAR(ix);
14521 exception=AcquireExceptionInfo();
14522 perl_exception=newSVpv("",0);
14523 if (sv_isobject(ST(0)) == 0)
14524 {
14525 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14526 PackageName);
14527 goto PerlException;
14528 }
14529
14530 reference=SvRV(ST(0));
14531 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14532 if (image == (Image *) NULL)
14533 {
14534 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14535 PackageName);
14536 goto PerlException;
14537 }
14538
14539 status=SyncAuthenticPixels(image,exception);
14540 if (status != MagickFalse)
14541 return;
14542
14543 PerlException:
14544 InheritPerlException(exception,perl_exception);
14545 exception=DestroyExceptionInfo(exception);
14546 SvREFCNT_dec(perl_exception); /* throw away all errors */
14547 }
14548
14549#
14550###############################################################################
14551# #
14552# #
14553# #
cristy4a3ce0a2013-08-03 20:06:59 +000014554# W r i t e #
14555# #
14556# #
14557# #
14558###############################################################################
14559#
14560#
14561void
14562Write(ref,...)
14563 Image::Magick ref=NO_INIT
14564 ALIAS:
14565 WriteImage = 1
14566 write = 2
14567 writeimage = 3
14568 PPCODE:
14569 {
14570 char
cristy151b66d2015-04-15 10:50:31 +000014571 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014572
14573 ExceptionInfo
14574 *exception;
14575
14576 Image
14577 *image,
14578 *next;
14579
14580 register ssize_t
14581 i;
14582
14583 ssize_t
14584 number_images,
14585 scene;
14586
14587 struct PackageInfo
14588 *info,
14589 *package_info;
14590
14591 SV
14592 *perl_exception,
14593 *reference;
14594
14595 PERL_UNUSED_VAR(ref);
14596 PERL_UNUSED_VAR(ix);
14597 exception=AcquireExceptionInfo();
14598 perl_exception=newSVpv("",0);
14599 number_images=0;
14600 package_info=(struct PackageInfo *) NULL;
14601 if (sv_isobject(ST(0)) == 0)
14602 {
14603 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14604 PackageName);
14605 goto PerlException;
14606 }
14607 reference=SvRV(ST(0));
14608 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14609 if (image == (Image *) NULL)
14610 {
14611 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14612 PackageName);
14613 goto PerlException;
14614 }
14615 package_info=ClonePackageInfo(info,exception);
14616 if (items == 2)
14617 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14618 else
14619 if (items > 2)
14620 for (i=2; i < items; i+=2)
14621 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14622 exception);
14623 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014624 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014625 scene=0;
14626 for (next=image; next; next=next->next)
14627 {
cristy151b66d2015-04-15 10:50:31 +000014628 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014629 next->scene=scene++;
14630 }
cristy68bd79a2015-02-25 12:23:36 +000014631 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014632 SetImageInfo(package_info->image_info,(unsigned int)
14633 GetImageListLength(image),exception);
14634 for (next=image; next; next=next->next)
14635 {
14636 (void) WriteImage(package_info->image_info,next,exception);
14637 number_images++;
14638 if (package_info->image_info->adjoin)
14639 break;
14640 }
14641
14642 PerlException:
14643 if (package_info != (struct PackageInfo *) NULL)
14644 DestroyPackageInfo(package_info);
14645 InheritPerlException(exception,perl_exception);
14646 exception=DestroyExceptionInfo(exception);
14647 sv_setiv(perl_exception,(IV) number_images);
14648 SvPOK_on(perl_exception);
14649 ST(0)=sv_2mortal(perl_exception);
14650 XSRETURN(1);
14651 }