blob: f4e05cfb9c71515c57a8192b626b58d323feda61 [file] [log] [blame]
cristy4a3ce0a2013-08-03 20:06:59 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% PPPP EEEEE RRRR L %
6% P P E R R L %
7% PPPP EEE RRRR L %
8% P E R R L %
9% P EEEEE R R LLLLL %
10% %
11% M M AAA GGGG IIIII CCCC K K %
12% MM MM A A G I C K K %
13% M M M AAAAA G GGG I C KKK %
14% M M A A G G I C K K %
15% M M A A GGGG IIIII CCCC K K %
16% %
17% %
18% Object-oriented Perl interface to ImageMagick %
19% %
20% Software Design %
21% Kyle Shorter %
cristyde984cd2013-12-01 14:49:27 +000022% Cristy %
cristy4a3ce0a2013-08-03 20:06:59 +000023% February 1997 %
24% %
25% %
Cristyf6ff9ea2016-12-05 09:53:35 -050026% Copyright 1999-2017 ImageMagick Studio LLC, a non-profit organization %
cristy4a3ce0a2013-08-03 20:06:59 +000027% dedicated to making software imaging solutions freely available. %
28% %
29% You may not use this file except in compliance with the License. You may %
30% obtain a copy of the License at %
31% %
32% http://www.imagemagick.org/script/license.php %
33% %
34% Unless required by applicable law or agreed to in writing, software %
35% distributed under the License is distributed on an "AS IS" BASIS, %
36% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
37% See the License for the specific language governing permissions and %
38% limitations under the License. %
39% %
40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41%
42% PerlMagick is an objected-oriented Perl interface to ImageMagick. Use
43% the module to read, manipulate, or write an image or image sequence from
44% within a Perl script. This makes PerlMagick suitable for Web CGI scripts.
45%
46*/
47
48/*
49 Include declarations.
50*/
51#if defined(__cplusplus) || defined(c_plusplus)
52extern "C" {
53#endif
54
55#define PERL_NO_GET_CONTEXT
dirk190cc1c2015-06-16 11:48:37 +000056#include <MagickCore/MagickCore.h>
cristy4a3ce0a2013-08-03 20:06:59 +000057#include "EXTERN.h"
58#include "perl.h"
59#include "XSUB.h"
60#include <math.h>
cristy4a3ce0a2013-08-03 20:06:59 +000061#undef tainted
62
63#if defined(__cplusplus) || defined(c_plusplus)
64}
65#endif
66
67/*
68 Define declarations.
69*/
70#ifndef aTHX_
71#define aTHX_
72#define pTHX_
73#define dTHX
74#endif
75#define DegreesToRadians(x) (MagickPI*(x)/180.0)
76#define EndOf(array) (&array[NumberOf(array)])
cristy3249b7b2014-02-09 21:43:14 +000077#define MagickPI 3.14159265358979323846264338327950288419716939937510
cristy4a3ce0a2013-08-03 20:06:59 +000078#define MaxArguments 33
79#ifndef na
80#define na PL_na
81#endif
82#define NumberOf(array) (sizeof(array)/sizeof(*array))
83#define PackageName "Image::Magick"
84#if PERL_VERSION <= 6
85#define PerlIO FILE
86#define PerlIO_importFILE(f, fl) (f)
87#define PerlIO_findFILE(f) NULL
88#endif
89#ifndef sv_undef
90#define sv_undef PL_sv_undef
91#endif
92
93#define AddImageToRegistry(sv,image) \
94{ \
95 if (magick_registry != (SplayTreeInfo *) NULL) \
96 { \
97 (void) AddValueToSplayTree(magick_registry,image,image); \
98 (sv)=newSViv(PTR2IV(image)); \
99 } \
100}
101
102#define DeleteImageFromRegistry(reference,image) \
103{ \
104 if (magick_registry != (SplayTreeInfo *) NULL) \
105 { \
106 if (GetImageReferenceCount(image) == 1) \
107 (void) DeleteNodeByValueFromSplayTree(magick_registry,image); \
108 image=DestroyImage(image); \
109 sv_setiv(reference,0); \
110 } \
111}
112
113#define InheritPerlException(exception,perl_exception) \
114{ \
115 char \
cristy151b66d2015-04-15 10:50:31 +0000116 message[MagickPathExtent]; \
cristy4a3ce0a2013-08-03 20:06:59 +0000117 \
118 if ((exception)->severity != UndefinedException) \
119 { \
cristy151b66d2015-04-15 10:50:31 +0000120 (void) FormatLocaleString(message,MagickPathExtent,"Exception %d: %s%s%s%s",\
cristy4a3ce0a2013-08-03 20:06:59 +0000121 (exception)->severity, (exception)->reason ? \
122 GetLocaleExceptionMessage((exception)->severity,(exception)->reason) : \
123 "Unknown", (exception)->description ? " (" : "", \
124 (exception)->description ? GetLocaleExceptionMessage( \
125 (exception)->severity,(exception)->description) : "", \
126 (exception)->description ? ")" : ""); \
127 if ((perl_exception) != (SV *) NULL) \
128 { \
129 if (SvCUR(perl_exception)) \
130 sv_catpv(perl_exception,"\n"); \
131 sv_catpv(perl_exception,message); \
132 } \
133 } \
134}
135
136#define ThrowPerlException(exception,severity,tag,reason) \
137 (void) ThrowMagickException(exception,GetMagickModule(),severity, \
138 tag,"`%s'",reason); \
139
140/*
141 Typedef and structure declarations.
142*/
143typedef enum
144{
145 ArrayReference = (~0),
146 RealReference = (~0)-1,
147 FileReference = (~0)-2,
148 ImageReference = (~0)-3,
149 IntegerReference = (~0)-4,
150 StringReference = (~0)-5
151} MagickReference;
152
153typedef struct _Arguments
154{
155 const char
156 *method;
157
158 ssize_t
159 type;
160} Arguments;
161
162struct ArgumentList
163{
164 ssize_t
165 integer_reference;
166
167 double
168 real_reference;
169
170 const char
171 *string_reference;
172
173 Image
174 *image_reference;
175
176 SV
177 *array_reference;
178
179 FILE
180 *file_reference;
181
182 size_t
183 length;
184};
185
186struct PackageInfo
187{
188 ImageInfo
189 *image_info;
190};
191
192typedef void
193 *Image__Magick; /* data type for the Image::Magick package */
194
195/*
196 Static declarations.
197*/
198static struct
199 Methods
200 {
201 const char
202 *name;
203
204 Arguments
205 arguments[MaxArguments];
206 } Methods[] =
207 {
208 { "Comment", { {"comment", StringReference} } },
209 { "Label", { {"label", StringReference} } },
210 { "AddNoise", { {"noise", MagickNoiseOptions}, {"attenuate", RealReference},
211 {"channel", MagickChannelOptions} } },
212 { "Colorize", { {"fill", StringReference}, {"blend", StringReference} } },
213 { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
214 {"height", IntegerReference}, {"fill", StringReference},
215 {"bordercolor", StringReference}, {"color", StringReference},
216 {"compose", MagickComposeOptions} } },
217 { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
218 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
219 { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
220 {"height", IntegerReference}, {"x", IntegerReference},
cristy260bd762014-08-15 12:46:34 +0000221 {"y", IntegerReference}, {"gravity", MagickGravityOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000222 { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
223 {"height", IntegerReference}, {"x", IntegerReference},
224 {"y", IntegerReference}, {"fuzz", StringReference},
225 {"gravity", MagickGravityOptions} } },
226 { "Despeckle", },
227 { "Edge", { {"radius", RealReference} } },
228 { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
229 {"sigma", RealReference} } },
230 { "Enhance", },
231 { "Flip", },
232 { "Flop", },
233 { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
234 {"height", IntegerReference}, {"inner", IntegerReference},
235 {"outer", IntegerReference}, {"fill", StringReference},
236 {"color", StringReference}, {"compose", MagickComposeOptions} } },
237 { "Implode", { {"amount", RealReference},
238 {"interpolate", MagickInterpolateOptions} } },
239 { "Magnify", },
240 { "MedianFilter", { {"geometry", StringReference},
241 {"width", IntegerReference}, {"height", IntegerReference},
242 {"channel", MagickChannelOptions} } },
243 { "Minify", },
244 { "OilPaint", { {"radius", RealReference}, {"sigma", RealReference} } },
245 { "ReduceNoise", { {"geometry", StringReference},
246 {"width", IntegerReference},{"height", IntegerReference},
247 {"channel", MagickChannelOptions} } },
248 { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
249 {"y", IntegerReference} } },
cristy83a28a02013-08-03 20:25:48 +0000250 { "Rotate", { {"degrees", RealReference},
cristy4a3ce0a2013-08-03 20:06:59 +0000251 {"background", StringReference} } },
252 { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
253 {"height", IntegerReference} } },
254 { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
255 {"height", IntegerReference} } },
256 { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
257 {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
258 { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
259 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
260 { "Shear", { {"geometry", StringReference}, {"x", RealReference},
261 {"y", RealReference}, { "fill", StringReference},
262 {"color", StringReference} } },
Cristye3319c12015-08-24 07:11:48 -0400263 { "Spread", { {"radius", RealReference},
Cristy3ca633e2016-02-13 12:49:01 -0500264 {"interpolate", MagickInterpolateOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000265 { "Swirl", { {"degrees", RealReference},
266 {"interpolate", MagickInterpolateOptions} } },
267 { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
268 {"height", IntegerReference}, {"filter", MagickFilterOptions},
269 {"support", StringReference } } },
270 { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
271 {"height", IntegerReference}, {"filter", MagickFilterOptions},
272 {"support", RealReference } } },
273 { "Annotate", { {"text", StringReference}, {"font", StringReference},
274 {"pointsize", RealReference}, {"density", StringReference},
275 {"undercolor", StringReference}, {"stroke", StringReference},
276 {"fill", StringReference}, {"geometry", StringReference},
277 {"sans", StringReference}, {"x", RealReference},
278 {"y", RealReference}, {"gravity", MagickGravityOptions},
279 {"translate", StringReference}, {"scale", StringReference},
280 {"rotate", RealReference}, {"skewX", RealReference},
281 {"skewY", RealReference}, {"strokewidth", RealReference},
282 {"antialias", MagickBooleanOptions}, {"family", StringReference},
283 {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
284 {"weight", IntegerReference}, {"align", MagickAlignOptions},
285 {"encoding", StringReference}, {"affine", ArrayReference},
286 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
287 {"tile", ImageReference}, {"kerning", RealReference},
288 {"interline-spacing", RealReference},
289 {"interword-spacing", RealReference},
290 {"direction", MagickDirectionOptions} } },
291 { "ColorFloodfill", { {"geometry", StringReference},
292 {"x", IntegerReference}, {"y", IntegerReference},
293 {"fill", StringReference}, {"bordercolor", StringReference},
294 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
295 { "Composite", { {"image", ImageReference},
296 {"compose", MagickComposeOptions}, {"geometry", StringReference},
297 {"x", IntegerReference}, {"y", IntegerReference},
298 {"gravity", MagickGravityOptions}, {"opacity", StringReference},
299 {"tile", MagickBooleanOptions}, {"rotate", RealReference},
300 {"color", StringReference}, {"mask", ImageReference},
301 {"channel", MagickChannelOptions},
302 {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
303 {"blend", StringReference}, {"crop-to-self", MagickBooleanOptions} } },
304 { "Contrast", { {"sharpen", MagickBooleanOptions} } },
305 { "CycleColormap", { {"display", IntegerReference} } },
306 { "Draw", { {"primitive", MagickPrimitiveOptions},
307 {"points", StringReference}, {"method", MagickMethodOptions},
308 {"stroke", StringReference}, {"fill", StringReference},
309 {"strokewidth", RealReference}, {"font", StringReference},
310 {"bordercolor", StringReference}, {"x", RealReference},
311 {"y", RealReference}, {"translate", StringReference},
312 {"scale", StringReference}, {"rotate", RealReference},
313 {"skewX", RealReference}, {"skewY", RealReference},
314 {"tile", ImageReference}, {"pointsize", RealReference},
315 {"antialias", MagickBooleanOptions}, {"density", StringReference},
316 {"linewidth", RealReference}, {"affine", ArrayReference},
317 {"stroke-dashoffset", RealReference},
318 {"stroke-dasharray", ArrayReference},
319 {"interpolate", MagickInterpolateOptions},
320 {"origin", StringReference}, {"text", StringReference},
321 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
322 {"vector-graphics", StringReference}, {"kerning", RealReference},
323 {"interline-spacing", RealReference},
324 {"interword-spacing", RealReference},
325 {"direction", MagickDirectionOptions} } },
326 { "Equalize", { {"channel", MagickChannelOptions} } },
327 { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
328 {"red", RealReference}, {"green", RealReference},
329 {"blue", RealReference} } },
330 { "Map", { {"image", ImageReference},
331 {"dither-method", MagickDitherOptions} } },
332 { "MatteFloodfill", { {"geometry", StringReference},
333 {"x", IntegerReference}, {"y", IntegerReference},
334 {"opacity", StringReference}, {"bordercolor", StringReference},
335 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
336 { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
337 {"saturation", RealReference}, {"whiteness", RealReference},
338 {"brightness", RealReference}, {"lightness", RealReference},
339 {"blackness", RealReference} } },
340 { "Negate", { {"gray", MagickBooleanOptions},
341 {"channel", MagickChannelOptions} } },
342 { "Normalize", { {"channel", MagickChannelOptions} } },
343 { "NumberColors", },
344 { "Opaque", { {"color", StringReference}, {"fill", StringReference},
345 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
346 {"invert", MagickBooleanOptions} } },
347 { "Quantize", { {"colors", IntegerReference},
348 {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
349 {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
350 {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
351 {"dither-method", MagickDitherOptions} } },
352 { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
353 {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
354 { "Segment", { {"geometry", StringReference},
355 {"cluster-threshold", RealReference},
356 {"smoothing-threshold", RealReference},
357 {"colorspace", MagickColorspaceOptions},
358 {"verbose", MagickBooleanOptions} } },
359 { "Signature", },
360 { "Solarize", { {"geometry", StringReference},
361 {"threshold", StringReference} } },
362 { "Sync", },
363 { "Texture", { {"texture", ImageReference} } },
364 { "Evaluate", { {"value", RealReference},
365 {"operator", MagickEvaluateOptions},
366 {"channel", MagickChannelOptions} } },
367 { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
368 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
369 { "Threshold", { {"threshold", StringReference},
370 {"channel", MagickChannelOptions} } },
371 { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
372 {"sigma", RealReference} } },
373 { "Trim", { {"fuzz", StringReference} } },
374 { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
375 {"wavelength", RealReference},
376 {"interpolate", MagickInterpolateOptions} } },
377 { "Separate", { {"channel", MagickChannelOptions} } },
378 { "Condense", },
379 { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
380 {"y", IntegerReference} } },
381 { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
382 { "Deconstruct", },
383 { "GaussianBlur", { {"geometry", StringReference},
384 {"radius", RealReference}, {"sigma", RealReference},
385 {"channel", MagickChannelOptions} } },
386 { "Convolve", { {"coefficients", ArrayReference},
387 {"channel", MagickChannelOptions}, {"bias", StringReference},
388 {"kernel", StringReference} } },
389 { "Profile", { {"name", StringReference}, {"profile", StringReference},
390 { "rendering-intent", MagickIntentOptions},
391 { "black-point-compensation", MagickBooleanOptions} } },
392 { "UnsharpMask", { {"geometry", StringReference},
393 {"radius", RealReference}, {"sigma", RealReference},
394 {"gain", RealReference}, {"threshold", RealReference},
395 {"channel", MagickChannelOptions} } },
396 { "MotionBlur", { {"geometry", StringReference},
397 {"radius", RealReference}, {"sigma", RealReference},
398 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
399 { "OrderedDither", { {"threshold", StringReference},
400 {"channel", MagickChannelOptions} } },
401 { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
402 {"height", IntegerReference} } },
403 { "Level", { {"levels", StringReference}, {"black-point", RealReference},
404 {"white-point", RealReference}, {"gamma", RealReference},
405 {"channel", MagickChannelOptions}, {"level", StringReference} } },
406 { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
407 { "AffineTransform", { {"affine", ArrayReference},
408 {"translate", StringReference}, {"scale", StringReference},
409 {"rotate", RealReference}, {"skewX", RealReference},
410 {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
411 {"background", StringReference} } },
412 { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
413 { "AdaptiveThreshold", { {"geometry", StringReference},
414 {"width", IntegerReference}, {"height", IntegerReference} } },
415 { "Resample", { {"density", StringReference}, {"x", RealReference},
416 {"y", RealReference}, {"filter", MagickFilterOptions},
417 {"support", RealReference } } },
418 { "Describe", { {"file", FileReference} } },
419 { "BlackThreshold", { {"threshold", StringReference},
420 {"channel", MagickChannelOptions} } },
421 { "WhiteThreshold", { {"threshold", StringReference},
422 {"channel", MagickChannelOptions} } },
cristy60c73c02014-03-25 12:09:58 +0000423 { "RotationalBlur", { {"geometry", StringReference},
424 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000425 { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
426 {"height", IntegerReference} } },
427 { "Strip", },
428 { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
429 { "Channel", { {"channel", MagickChannelOptions} } },
430 { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
431 {"height", IntegerReference}, {"x", IntegerReference},
432 {"y", IntegerReference}, {"fuzz", StringReference},
433 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
434 { "Posterize", { {"levels", IntegerReference},
435 {"dither", MagickBooleanOptions} } },
436 { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
437 {"sigma", RealReference}, {"x", IntegerReference},
438 {"y", IntegerReference} } },
439 { "Identify", { {"file", FileReference}, {"features", StringReference},
440 {"unique", MagickBooleanOptions} } },
441 { "SepiaTone", { {"threshold", RealReference} } },
442 { "SigmoidalContrast", { {"geometry", StringReference},
443 {"contrast", RealReference}, {"mid-point", RealReference},
444 {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
445 { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
446 {"height", IntegerReference}, {"x", IntegerReference},
447 {"y", IntegerReference}, {"fuzz", StringReference},
448 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
449 { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
450 {"sigma", RealReference}, {"x", IntegerReference},
451 {"y", IntegerReference}, {"background", StringReference} } },
452 { "ContrastStretch", { {"levels", StringReference},
453 {"black-point", RealReference},{"white-point", RealReference},
454 {"channel", MagickChannelOptions} } },
455 { "Sans0", },
456 { "Sans1", },
457 { "AdaptiveSharpen", { {"geometry", StringReference},
458 {"radius", RealReference}, {"sigma", RealReference},
459 {"bias", RealReference}, {"channel", MagickChannelOptions} } },
460 { "Transpose", },
461 { "Transverse", },
462 { "AutoOrient", },
463 { "AdaptiveBlur", { {"geometry", StringReference},
464 {"radius", RealReference}, {"sigma", RealReference},
465 {"channel", MagickChannelOptions} } },
466 { "Sketch", { {"geometry", StringReference},
467 {"radius", RealReference}, {"sigma", RealReference},
468 {"angle", RealReference} } },
469 { "UniqueColors", },
470 { "AdaptiveResize", { {"geometry", StringReference},
471 {"width", IntegerReference}, {"height", IntegerReference},
472 {"filter", MagickFilterOptions}, {"support", StringReference },
473 {"blur", RealReference } } },
474 { "ClipMask", { {"mask", ImageReference} } },
475 { "LinearStretch", { {"levels", StringReference},
476 {"black-point", RealReference},{"white-point", RealReference} } },
477 { "ColorMatrix", { {"matrix", ArrayReference} } },
478 { "Mask", { {"mask", ImageReference} } },
479 { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
480 {"font", StringReference}, {"stroke", StringReference},
481 {"fill", StringReference}, {"strokewidth", RealReference},
482 {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
483 {"background", StringReference},
484 {"interpolate", MagickInterpolateOptions} } },
485 { "FloodfillPaint", { {"geometry", StringReference},
486 {"x", IntegerReference}, {"y", IntegerReference},
487 {"fill", StringReference}, {"bordercolor", StringReference},
488 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
489 {"invert", MagickBooleanOptions} } },
490 { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
491 {"virtual-pixel", MagickVirtualPixelOptions},
492 {"best-fit", MagickBooleanOptions} } },
493 { "Clut", { {"image", ImageReference},
494 {"interpolate", MagickInterpolateOptions},
495 {"channel", MagickChannelOptions} } },
496 { "LiquidRescale", { {"geometry", StringReference},
497 {"width", IntegerReference}, {"height", IntegerReference},
498 {"delta-x", RealReference}, {"rigidity", RealReference } } },
499 { "Encipher", { {"passphrase", StringReference} } },
500 { "Decipher", { {"passphrase", StringReference} } },
501 { "Deskew", { {"geometry", StringReference},
502 {"threshold", StringReference} } },
503 { "Remap", { {"image", ImageReference},
504 {"dither-method", MagickDitherOptions} } },
505 { "SparseColor", { {"points", ArrayReference},
506 {"method", MagickSparseColorOptions},
507 {"virtual-pixel", MagickVirtualPixelOptions},
508 {"channel", MagickChannelOptions} } },
509 { "Function", { {"parameters", ArrayReference},
510 {"function", MagickFunctionOptions},
511 {"virtual-pixel", MagickVirtualPixelOptions} } },
512 { "SelectiveBlur", { {"geometry", StringReference},
513 {"radius", RealReference}, {"sigma", RealReference},
514 {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
515 { "HaldClut", { {"image", ImageReference},
516 {"channel", MagickChannelOptions} } },
517 { "BlueShift", { {"factor", StringReference} } },
518 { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
519 { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
520 { "ColorDecisionList", {
521 {"color-correction-collection", StringReference} } },
522 { "AutoGamma", { {"channel", MagickChannelOptions} } },
523 { "AutoLevel", { {"channel", MagickChannelOptions} } },
524 { "LevelColors", { {"invert", MagickBooleanOptions},
525 {"black-point", StringReference}, {"white-point", StringReference},
526 {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
527 { "Clamp", { {"channel", MagickChannelOptions} } },
528 { "BrightnessContrast", { {"levels", StringReference},
529 {"brightness", RealReference},{"contrast", RealReference},
530 {"channel", MagickChannelOptions} } },
531 { "Morphology", { {"kernel", StringReference},
532 {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
533 {"iterations", IntegerReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000534 { "Mode", { {"geometry", StringReference},
535 {"width", IntegerReference},{"height", IntegerReference},
536 {"channel", MagickChannelOptions} } },
537 { "Statistic", { {"geometry", StringReference},
538 {"width", IntegerReference},{"height", IntegerReference},
539 {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
540 { "Perceptible", { {"epsilon", RealReference},
541 {"channel", MagickChannelOptions} } },
542 { "Poly", { {"terms", ArrayReference},
543 {"channel", MagickChannelOptions} } },
544 { "Grayscale", { {"method", MagickNoiseOptions} } },
cristy4ceadb82014-03-29 15:30:43 +0000545 { "CannyEdge", { {"geometry", StringReference},
546 {"radius", RealReference}, {"sigma", RealReference},
cristycfe7bf02014-04-04 15:31:52 +0000547 {"lower-percent", RealReference}, {"upper-percent", RealReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000548 { "HoughLine", { {"geometry", StringReference},
cristy4e215022014-04-19 18:02:35 +0000549 {"width", IntegerReference}, {"height", IntegerReference},
550 {"threshold", IntegerReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000551 { "MeanShift", { {"geometry", StringReference},
552 {"width", IntegerReference}, {"height", IntegerReference},
cristy1309fc32014-04-26 18:48:37 +0000553 {"distance", RealReference} } },
cristy3b207f82014-09-27 14:21:20 +0000554 { "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
555 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
Cristy2ca0e9a2016-01-01 08:36:14 -0500556 { "ConnectedComponents", { {"connectivity", IntegerReference} } },
cristyf3a724a2015-06-25 13:02:53 +0000557 { "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
558 {"width", IntegerReference}, {"height", IntegerReference},
559 {"x", IntegerReference}, {"y", IntegerReference},
560 {"gravity", MagickGravityOptions}, {"offset", StringReference},
561 {"dx", IntegerReference}, {"dy", IntegerReference} } },
Cristy5488c982016-02-13 14:07:50 -0500562 { "Color", { {"color", StringReference} } },
Cristyc1759412016-02-27 12:17:58 -0500563 { "WaveletDenoise", { {"geometry", StringReference},
564 {"threshold", RealReference}, {"softness", RealReference},
Cristy2d830ed2016-02-21 10:54:16 -0500565 {"channel", MagickChannelOptions} } },
Cristy99a57162016-12-05 11:47:57 -0500566 { "Colorspace", { {"colorspace", MagickColorspaceOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000567 };
568
569static SplayTreeInfo
570 *magick_registry = (SplayTreeInfo *) NULL;
571
572/*
573 Forward declarations.
574*/
575static Image
576 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
577
578static ssize_t
579 strEQcase(const char *,const char *);
580
581/*
582%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
583% %
584% %
585% %
586% C l o n e P a c k a g e I n f o %
587% %
588% %
589% %
590%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
591%
592% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
593% a new one.
594%
595% The format of the ClonePackageInfo routine is:
596%
597% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
598% exception)
599%
600% A description of each parameter follows:
601%
602% o info: a structure of type info.
603%
604% o exception: Return any errors or warnings in this structure.
605%
606*/
607static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
608 ExceptionInfo *exception)
609{
610 struct PackageInfo
611 *clone_info;
612
613 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
614 if (clone_info == (struct PackageInfo *) NULL)
615 {
616 ThrowPerlException(exception,ResourceLimitError,
617 "UnableToClonePackageInfo",PackageName);
618 return((struct PackageInfo *) NULL);
619 }
620 if (info == (struct PackageInfo *) NULL)
621 {
622 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
623 return(clone_info);
624 }
625 *clone_info=(*info);
626 clone_info->image_info=CloneImageInfo(info->image_info);
627 return(clone_info);
628}
629
630/*
631%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
632% %
633% %
634% %
635% c o n s t a n t %
636% %
637% %
638% %
639%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
640%
641% constant() returns a double value for the specified name.
642%
643% The format of the constant routine is:
644%
645% double constant(char *name,ssize_t sans)
646%
647% A description of each parameter follows:
648%
649% o value: Method constant returns a double value for the specified name.
650%
651% o name: The name of the constant.
652%
653% o sans: This integer value is not used.
654%
655*/
656static double constant(char *name,ssize_t sans)
657{
658 (void) sans;
659 errno=0;
660 switch (*name)
661 {
662 case 'B':
663 {
664 if (strEQ(name,"BlobError"))
665 return(BlobError);
666 if (strEQ(name,"BlobWarning"))
667 return(BlobWarning);
668 break;
669 }
670 case 'C':
671 {
672 if (strEQ(name,"CacheError"))
673 return(CacheError);
674 if (strEQ(name,"CacheWarning"))
675 return(CacheWarning);
676 if (strEQ(name,"CoderError"))
677 return(CoderError);
678 if (strEQ(name,"CoderWarning"))
679 return(CoderWarning);
680 if (strEQ(name,"ConfigureError"))
681 return(ConfigureError);
682 if (strEQ(name,"ConfigureWarning"))
683 return(ConfigureWarning);
684 if (strEQ(name,"CorruptImageError"))
685 return(CorruptImageError);
686 if (strEQ(name,"CorruptImageWarning"))
687 return(CorruptImageWarning);
688 break;
689 }
690 case 'D':
691 {
692 if (strEQ(name,"DelegateError"))
693 return(DelegateError);
694 if (strEQ(name,"DelegateWarning"))
695 return(DelegateWarning);
696 if (strEQ(name,"DrawError"))
697 return(DrawError);
698 if (strEQ(name,"DrawWarning"))
699 return(DrawWarning);
700 break;
701 }
702 case 'E':
703 {
704 if (strEQ(name,"ErrorException"))
705 return(ErrorException);
706 if (strEQ(name,"ExceptionError"))
707 return(CoderError);
708 if (strEQ(name,"ExceptionWarning"))
709 return(CoderWarning);
710 break;
711 }
712 case 'F':
713 {
714 if (strEQ(name,"FatalErrorException"))
715 return(FatalErrorException);
716 if (strEQ(name,"FileOpenError"))
717 return(FileOpenError);
718 if (strEQ(name,"FileOpenWarning"))
719 return(FileOpenWarning);
720 break;
721 }
722 case 'I':
723 {
724 if (strEQ(name,"ImageError"))
725 return(ImageError);
726 if (strEQ(name,"ImageWarning"))
727 return(ImageWarning);
728 break;
729 }
730 case 'M':
731 {
732 if (strEQ(name,"MaxRGB"))
733 return(QuantumRange);
734 if (strEQ(name,"MissingDelegateError"))
735 return(MissingDelegateError);
736 if (strEQ(name,"MissingDelegateWarning"))
737 return(MissingDelegateWarning);
738 if (strEQ(name,"ModuleError"))
739 return(ModuleError);
740 if (strEQ(name,"ModuleWarning"))
741 return(ModuleWarning);
742 break;
743 }
744 case 'O':
745 {
746 if (strEQ(name,"Opaque"))
747 return(OpaqueAlpha);
748 if (strEQ(name,"OptionError"))
749 return(OptionError);
750 if (strEQ(name,"OptionWarning"))
751 return(OptionWarning);
752 break;
753 }
754 case 'Q':
755 {
756 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
757 return(MAGICKCORE_QUANTUM_DEPTH);
758 if (strEQ(name,"QuantumDepth"))
759 return(MAGICKCORE_QUANTUM_DEPTH);
760 if (strEQ(name,"QuantumRange"))
761 return(QuantumRange);
762 break;
763 }
764 case 'R':
765 {
766 if (strEQ(name,"ResourceLimitError"))
767 return(ResourceLimitError);
768 if (strEQ(name,"ResourceLimitWarning"))
769 return(ResourceLimitWarning);
770 if (strEQ(name,"RegistryError"))
771 return(RegistryError);
772 if (strEQ(name,"RegistryWarning"))
773 return(RegistryWarning);
774 break;
775 }
776 case 'S':
777 {
778 if (strEQ(name,"StreamError"))
779 return(StreamError);
780 if (strEQ(name,"StreamWarning"))
781 return(StreamWarning);
782 if (strEQ(name,"Success"))
783 return(0);
784 break;
785 }
786 case 'T':
787 {
788 if (strEQ(name,"Transparent"))
789 return(TransparentAlpha);
790 if (strEQ(name,"TypeError"))
791 return(TypeError);
792 if (strEQ(name,"TypeWarning"))
793 return(TypeWarning);
794 break;
795 }
796 case 'W':
797 {
798 if (strEQ(name,"WarningException"))
799 return(WarningException);
800 break;
801 }
802 case 'X':
803 {
804 if (strEQ(name,"XServerError"))
805 return(XServerError);
806 if (strEQ(name,"XServerWarning"))
807 return(XServerWarning);
808 break;
809 }
810 }
811 errno=EINVAL;
812 return(0);
813}
814
815/*
816%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
817% %
818% %
819% %
820% D e s t r o y P a c k a g e I n f o %
821% %
822% %
823% %
824%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
825%
826% Method DestroyPackageInfo frees a previously created info structure.
827%
828% The format of the DestroyPackageInfo routine is:
829%
830% DestroyPackageInfo(struct PackageInfo *info)
831%
832% A description of each parameter follows:
833%
834% o info: a structure of type info.
835%
836*/
837static void DestroyPackageInfo(struct PackageInfo *info)
838{
839 info->image_info=DestroyImageInfo(info->image_info);
840 info=(struct PackageInfo *) RelinquishMagickMemory(info);
841}
842
843/*
844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
845% %
846% %
847% %
848% G e t L i s t %
849% %
850% %
851% %
852%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
853%
854% Method GetList is recursively called by SetupList to traverse the
855% Image__Magick reference. If building an reference_vector (see SetupList),
856% *current is the current position in *reference_vector and *last is the final
857% entry in *reference_vector.
858%
859% The format of the GetList routine is:
860%
861% GetList(info)
862%
863% A description of each parameter follows:
864%
865% o info: a structure of type info.
866%
867*/
868static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
869 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
870{
871 Image
872 *image;
873
874 if (reference == (SV *) NULL)
875 return(NULL);
876 switch (SvTYPE(reference))
877 {
878 case SVt_PVAV:
879 {
880 AV
881 *av;
882
883 Image
884 *head,
885 *previous;
886
887 register ssize_t
888 i;
889
890 ssize_t
891 n;
892
893 /*
894 Array of images.
895 */
896 previous=(Image *) NULL;
897 head=(Image *) NULL;
898 av=(AV *) reference;
899 n=av_len(av);
900 for (i=0; i <= n; i++)
901 {
902 SV
903 **rv;
904
905 rv=av_fetch(av,i,0);
906 if (rv && *rv && sv_isobject(*rv))
907 {
908 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
909 exception);
910 if (image == (Image *) NULL)
911 continue;
912 if (image == previous)
913 {
914 image=CloneImage(image,0,0,MagickTrue,exception);
915 if (image == (Image *) NULL)
916 return(NULL);
917 }
918 image->previous=previous;
919 *(previous ? &previous->next : &head)=image;
920 for (previous=image; previous->next; previous=previous->next) ;
921 }
922 }
923 return(head);
924 }
925 case SVt_PVMG:
926 {
927 /*
928 Blessed scalar, one image.
929 */
930 image=INT2PTR(Image *,SvIV(reference));
931 if (image == (Image *) NULL)
932 return(NULL);
933 image->previous=(Image *) NULL;
934 image->next=(Image *) NULL;
935 if (reference_vector)
936 {
937 if (*current == *last)
938 {
939 *last+=256;
940 if (*reference_vector == (SV **) NULL)
941 *reference_vector=(SV **) AcquireQuantumMemory(*last,
942 sizeof(*reference_vector));
943 else
944 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
945 *last,sizeof(*reference_vector));
946 }
947 if (*reference_vector == (SV **) NULL)
948 {
949 ThrowPerlException(exception,ResourceLimitError,
950 "MemoryAllocationFailed",PackageName);
951 return((Image *) NULL);
952 }
953 (*reference_vector)[*current]=reference;
954 (*reference_vector)[++(*current)]=NULL;
955 }
956 return(image);
957 }
958 default:
959 break;
960 }
961 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
962 (double) SvTYPE(reference));
963 return((Image *) NULL);
964}
965
966/*
967%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
968% %
969% %
970% %
971% G e t P a c k a g e I n f o %
972% %
973% %
974% %
975%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
976%
977% Method GetPackageInfo looks up or creates an info structure for the given
978% Image__Magick reference. If it does create a new one, the information in
979% package_info is used to initialize it.
980%
981% The format of the GetPackageInfo routine is:
982%
983% struct PackageInfo *GetPackageInfo(void *reference,
984% struct PackageInfo *package_info,ExceptionInfo *exception)
985%
986% A description of each parameter follows:
987%
988% o info: a structure of type info.
989%
990% o exception: Return any errors or warnings in this structure.
991%
992*/
993static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
994 struct PackageInfo *package_info,ExceptionInfo *exception)
995{
996 char
cristy151b66d2015-04-15 10:50:31 +0000997 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +0000998
999 struct PackageInfo
1000 *clone_info;
1001
1002 SV
1003 *sv;
1004
cristy151b66d2015-04-15 10:50:31 +00001005 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00001006 PackageName,XS_VERSION,reference);
1007 sv=perl_get_sv(message,(TRUE | 0x02));
1008 if (sv == (SV *) NULL)
1009 {
1010 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1011 message);
1012 return(package_info);
1013 }
1014 if (SvREFCNT(sv) == 0)
1015 (void) SvREFCNT_inc(sv);
1016 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1017 return(clone_info);
1018 clone_info=ClonePackageInfo(package_info,exception);
1019 sv_setiv(sv,PTR2IV(clone_info));
1020 return(clone_info);
1021}
1022
1023/*
1024%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1025% %
1026% %
1027% %
1028% S e t A t t r i b u t e %
1029% %
1030% %
1031% %
1032%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1033%
1034% SetAttribute() sets the attribute to the value in sval. This can change
1035% either or both of image or info.
1036%
1037% The format of the SetAttribute routine is:
1038%
1039% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1040% SV *sval,ExceptionInfo *exception)
1041%
1042% A description of each parameter follows:
1043%
1044% o list: a list of strings.
1045%
1046% o string: a character string.
1047%
1048*/
1049
1050static double SiPrefixToDoubleInterval(const char *string,const double interval)
1051{
1052 char
1053 *q;
1054
1055 double
1056 value;
1057
1058 value=InterpretSiPrefixValue(string,&q);
1059 if (*q == '%')
1060 value*=interval/100.0;
1061 return(value);
1062}
1063
1064static inline double StringToDouble(const char *string,char **sentinal)
1065{
1066 return(InterpretLocaleValue(string,sentinal));
1067}
1068
1069static double StringToDoubleInterval(const char *string,const double interval)
1070{
1071 char
1072 *q;
1073
1074 double
1075 value;
1076
1077 value=InterpretLocaleValue(string,&q);
1078 if (*q == '%')
1079 value*=interval/100.0;
1080 return(value);
1081}
1082
1083static inline ssize_t StringToLong(const char *value)
1084{
1085 return(strtol(value,(char **) NULL,10));
1086}
1087
1088static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1089 const char *attribute,SV *sval,ExceptionInfo *exception)
1090{
1091 GeometryInfo
1092 geometry_info;
1093
1094 long
1095 x,
1096 y;
1097
1098 PixelInfo
1099 pixel;
1100
1101 MagickStatusType
1102 flags;
1103
1104 PixelInfo
1105 *color,
1106 target_color;
1107
1108 ssize_t
1109 sp;
1110
1111 switch (*attribute)
1112 {
1113 case 'A':
1114 case 'a':
1115 {
1116 if (LocaleCompare(attribute,"adjoin") == 0)
1117 {
1118 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1119 SvPV(sval,na)) : SvIV(sval);
1120 if (sp < 0)
1121 {
1122 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1123 SvPV(sval,na));
1124 break;
1125 }
1126 if (info)
1127 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1128 break;
1129 }
1130 if (LocaleCompare(attribute,"alpha") == 0)
1131 {
1132 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1133 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1134 if (sp < 0)
1135 {
1136 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1137 SvPV(sval,na));
1138 break;
1139 }
1140 for ( ; image; image=image->next)
1141 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1142 exception);
1143 break;
1144 }
1145 if (LocaleCompare(attribute,"antialias") == 0)
1146 {
1147 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1148 SvPV(sval,na)) : SvIV(sval);
1149 if (sp < 0)
1150 {
1151 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1152 SvPV(sval,na));
1153 break;
1154 }
1155 if (info)
1156 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1157 break;
1158 }
1159 if (LocaleCompare(attribute,"area-limit") == 0)
1160 {
1161 MagickSizeType
1162 limit;
1163
1164 limit=MagickResourceInfinity;
1165 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1166 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1167 100.0);
1168 (void) SetMagickResourceLimit(AreaResource,limit);
1169 break;
1170 }
1171 if (LocaleCompare(attribute,"attenuate") == 0)
1172 {
1173 if (info)
1174 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1175 break;
1176 }
1177 if (LocaleCompare(attribute,"authenticate") == 0)
1178 {
1179 if (info)
1180 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1181 break;
1182 }
1183 if (info)
1184 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1185 for ( ; image; image=image->next)
1186 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1187 break;
1188 }
1189 case 'B':
1190 case 'b':
1191 {
1192 if (LocaleCompare(attribute,"background") == 0)
1193 {
1194 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1195 exception);
1196 if (info)
1197 info->image_info->background_color=target_color;
1198 for ( ; image; image=image->next)
1199 image->background_color=target_color;
1200 break;
1201 }
1202 if (LocaleCompare(attribute,"blue-primary") == 0)
1203 {
1204 for ( ; image; image=image->next)
1205 {
1206 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1207 image->chromaticity.blue_primary.x=geometry_info.rho;
1208 image->chromaticity.blue_primary.y=geometry_info.sigma;
1209 if ((flags & SigmaValue) == 0)
1210 image->chromaticity.blue_primary.y=
1211 image->chromaticity.blue_primary.x;
1212 }
1213 break;
1214 }
1215 if (LocaleCompare(attribute,"bordercolor") == 0)
1216 {
1217 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1218 exception);
1219 if (info)
1220 info->image_info->border_color=target_color;
1221 for ( ; image; image=image->next)
1222 image->border_color=target_color;
1223 break;
1224 }
1225 if (info)
1226 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1227 for ( ; image; image=image->next)
1228 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1229 break;
1230 }
1231 case 'C':
1232 case 'c':
1233 {
1234 if (LocaleCompare(attribute,"cache-threshold") == 0)
1235 {
1236 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1237 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1238 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1239 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1240 break;
1241 }
1242 if (LocaleCompare(attribute,"clip-mask") == 0)
1243 {
1244 Image
1245 *clip_mask;
1246
1247 clip_mask=(Image *) NULL;
1248 if (SvPOK(sval))
1249 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1250 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001251 SetImageMask(image,ReadPixelMask,clip_mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001252 break;
1253 }
1254 if (LocaleNCompare(attribute,"colormap",8) == 0)
1255 {
1256 for ( ; image; image=image->next)
1257 {
1258 int
1259 items;
1260
1261 long
1262 i;
1263
1264 if (image->storage_class == DirectClass)
1265 continue;
1266 i=0;
1267 items=sscanf(attribute,"%*[^[][%ld",&i);
1268 (void) items;
1269 if (i > (ssize_t) image->colors)
1270 i%=image->colors;
1271 if ((strchr(SvPV(sval,na),',') == 0) ||
1272 (strchr(SvPV(sval,na),')') != 0))
1273 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1274 image->colormap+i,exception);
1275 else
1276 {
1277 color=image->colormap+i;
1278 pixel.red=color->red;
1279 pixel.green=color->green;
1280 pixel.blue=color->blue;
1281 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1282 pixel.red=geometry_info.rho;
1283 pixel.green=geometry_info.sigma;
1284 pixel.blue=geometry_info.xi;
1285 color->red=ClampToQuantum(pixel.red);
1286 color->green=ClampToQuantum(pixel.green);
1287 color->blue=ClampToQuantum(pixel.blue);
1288 }
1289 }
1290 break;
1291 }
1292 if (LocaleCompare(attribute,"colorspace") == 0)
1293 {
1294 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1295 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1296 if (sp < 0)
1297 {
1298 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1299 SvPV(sval,na));
1300 break;
1301 }
1302 for ( ; image; image=image->next)
Cristy59262d92016-12-05 15:21:50 -05001303 (void) SetImageColorspace(image,(ColorspaceType) sp,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001304 break;
1305 }
1306 if (LocaleCompare(attribute,"comment") == 0)
1307 {
1308 for ( ; image; image=image->next)
1309 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1310 info ? info->image_info : (ImageInfo *) NULL,image,
1311 SvPV(sval,na),exception),exception);
1312 break;
1313 }
1314 if (LocaleCompare(attribute,"compression") == 0)
1315 {
1316 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1317 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1318 if (sp < 0)
1319 {
1320 ThrowPerlException(exception,OptionError,
1321 "UnrecognizedImageCompression",SvPV(sval,na));
1322 break;
1323 }
1324 if (info)
1325 info->image_info->compression=(CompressionType) sp;
1326 for ( ; image; image=image->next)
1327 image->compression=(CompressionType) sp;
1328 break;
1329 }
1330 if (info)
1331 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1332 for ( ; image; image=image->next)
1333 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1334 break;
1335 }
1336 case 'D':
1337 case 'd':
1338 {
1339 if (LocaleCompare(attribute,"debug") == 0)
1340 {
1341 SetLogEventMask(SvPV(sval,na));
1342 break;
1343 }
1344 if (LocaleCompare(attribute,"delay") == 0)
1345 {
1346 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1347 for ( ; image; image=image->next)
1348 {
1349 image->delay=(size_t) floor(geometry_info.rho+0.5);
1350 if ((flags & SigmaValue) != 0)
1351 image->ticks_per_second=(ssize_t)
1352 floor(geometry_info.sigma+0.5);
1353 }
1354 break;
1355 }
1356 if (LocaleCompare(attribute,"disk-limit") == 0)
1357 {
1358 MagickSizeType
1359 limit;
1360
1361 limit=MagickResourceInfinity;
1362 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1363 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1364 100.0);
1365 (void) SetMagickResourceLimit(DiskResource,limit);
1366 break;
1367 }
1368 if (LocaleCompare(attribute,"density") == 0)
1369 {
1370 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1371 {
1372 ThrowPerlException(exception,OptionError,"MissingGeometry",
1373 SvPV(sval,na));
1374 break;
1375 }
1376 if (info)
1377 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1378 for ( ; image; image=image->next)
1379 {
1380 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1381 image->resolution.x=geometry_info.rho;
1382 image->resolution.y=geometry_info.sigma;
1383 if ((flags & SigmaValue) == 0)
1384 image->resolution.y=image->resolution.x;
1385 }
1386 break;
1387 }
1388 if (LocaleCompare(attribute,"depth") == 0)
1389 {
1390 if (info)
1391 info->image_info->depth=SvIV(sval);
1392 for ( ; image; image=image->next)
1393 (void) SetImageDepth(image,SvIV(sval),exception);
1394 break;
1395 }
1396 if (LocaleCompare(attribute,"dispose") == 0)
1397 {
1398 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1399 SvPV(sval,na)) : SvIV(sval);
1400 if (sp < 0)
1401 {
1402 ThrowPerlException(exception,OptionError,
1403 "UnrecognizedDisposeMethod",SvPV(sval,na));
1404 break;
1405 }
1406 for ( ; image; image=image->next)
1407 image->dispose=(DisposeType) sp;
1408 break;
1409 }
1410 if (LocaleCompare(attribute,"dither") == 0)
1411 {
1412 if (info)
1413 {
1414 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1415 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1416 if (sp < 0)
1417 {
1418 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1419 SvPV(sval,na));
1420 break;
1421 }
1422 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1423 }
1424 break;
1425 }
1426 if (LocaleCompare(attribute,"display") == 0)
1427 {
1428 display:
1429 if (info)
1430 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1431 break;
1432 }
1433 if (info)
1434 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1435 for ( ; image; image=image->next)
1436 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1437 break;
1438 }
1439 case 'E':
1440 case 'e':
1441 {
1442 if (LocaleCompare(attribute,"endian") == 0)
1443 {
1444 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1445 SvPV(sval,na)) : SvIV(sval);
1446 if (sp < 0)
1447 {
1448 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1449 SvPV(sval,na));
1450 break;
1451 }
1452 if (info)
1453 info->image_info->endian=(EndianType) sp;
1454 for ( ; image; image=image->next)
1455 image->endian=(EndianType) sp;
1456 break;
1457 }
1458 if (LocaleCompare(attribute,"extract") == 0)
1459 {
1460 /*
1461 Set image extract geometry.
1462 */
1463 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1464 break;
1465 }
1466 if (info)
1467 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1468 for ( ; image; image=image->next)
1469 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1470 break;
1471 }
1472 case 'F':
1473 case 'f':
1474 {
1475 if (LocaleCompare(attribute,"filename") == 0)
1476 {
1477 if (info)
1478 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001479 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001480 for ( ; image; image=image->next)
1481 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001482 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001483 break;
1484 }
1485 if (LocaleCompare(attribute,"file") == 0)
1486 {
1487 FILE
1488 *file;
1489
1490 PerlIO
1491 *io_info;
1492
1493 if (info == (struct PackageInfo *) NULL)
1494 break;
1495 io_info=IoIFP(sv_2io(sval));
1496 if (io_info == (PerlIO *) NULL)
1497 {
1498 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1499 PackageName);
1500 break;
1501 }
1502 file=PerlIO_findFILE(io_info);
1503 if (file == (FILE *) NULL)
1504 {
1505 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1506 PackageName);
1507 break;
1508 }
1509 SetImageInfoFile(info->image_info,file);
1510 break;
1511 }
1512 if (LocaleCompare(attribute,"fill") == 0)
1513 {
1514 if (info)
1515 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1516 break;
1517 }
1518 if (LocaleCompare(attribute,"font") == 0)
1519 {
1520 if (info)
1521 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1522 break;
1523 }
1524 if (LocaleCompare(attribute,"foreground") == 0)
1525 break;
1526 if (LocaleCompare(attribute,"fuzz") == 0)
1527 {
1528 if (info)
1529 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1530 QuantumRange+1.0);
1531 for ( ; image; image=image->next)
1532 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1533 QuantumRange+1.0);
1534 break;
1535 }
1536 if (info)
1537 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1538 for ( ; image; image=image->next)
1539 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1540 break;
1541 }
1542 case 'G':
1543 case 'g':
1544 {
1545 if (LocaleCompare(attribute,"gamma") == 0)
1546 {
1547 for ( ; image; image=image->next)
1548 image->gamma=SvNV(sval);
1549 break;
1550 }
1551 if (LocaleCompare(attribute,"gravity") == 0)
1552 {
1553 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1554 SvPV(sval,na)) : SvIV(sval);
1555 if (sp < 0)
1556 {
1557 ThrowPerlException(exception,OptionError,
1558 "UnrecognizedGravityType",SvPV(sval,na));
1559 break;
1560 }
1561 if (info)
1562 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1563 for ( ; image; image=image->next)
1564 image->gravity=(GravityType) sp;
1565 break;
1566 }
1567 if (LocaleCompare(attribute,"green-primary") == 0)
1568 {
1569 for ( ; image; image=image->next)
1570 {
1571 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1572 image->chromaticity.green_primary.x=geometry_info.rho;
1573 image->chromaticity.green_primary.y=geometry_info.sigma;
1574 if ((flags & SigmaValue) == 0)
1575 image->chromaticity.green_primary.y=
1576 image->chromaticity.green_primary.x;
1577 }
1578 break;
1579 }
1580 if (info)
1581 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1582 for ( ; image; image=image->next)
1583 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1584 break;
1585 }
1586 case 'I':
1587 case 'i':
1588 {
1589 if (LocaleNCompare(attribute,"index",5) == 0)
1590 {
1591 int
1592 items;
1593
1594 long
1595 index;
1596
1597 register Quantum
1598 *q;
1599
1600 CacheView
1601 *image_view;
1602
1603 for ( ; image; image=image->next)
1604 {
1605 if (image->storage_class != PseudoClass)
1606 continue;
1607 x=0;
1608 y=0;
1609 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1610 (void) items;
1611 image_view=AcquireAuthenticCacheView(image,exception);
1612 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1613 if (q != (Quantum *) NULL)
1614 {
1615 items=sscanf(SvPV(sval,na),"%ld",&index);
1616 if ((index >= 0) && (index < (ssize_t) image->colors))
1617 SetPixelIndex(image,index,q);
1618 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1619 }
1620 image_view=DestroyCacheView(image_view);
1621 }
1622 break;
1623 }
1624 if (LocaleCompare(attribute,"iterations") == 0)
1625 {
1626 iterations:
1627 for ( ; image; image=image->next)
1628 image->iterations=SvIV(sval);
1629 break;
1630 }
1631 if (LocaleCompare(attribute,"interlace") == 0)
1632 {
1633 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1634 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1635 if (sp < 0)
1636 {
1637 ThrowPerlException(exception,OptionError,
1638 "UnrecognizedInterlaceType",SvPV(sval,na));
1639 break;
1640 }
1641 if (info)
1642 info->image_info->interlace=(InterlaceType) sp;
1643 for ( ; image; image=image->next)
1644 image->interlace=(InterlaceType) sp;
1645 break;
1646 }
1647 if (info)
1648 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1649 for ( ; image; image=image->next)
1650 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1651 break;
1652 }
1653 case 'L':
1654 case 'l':
1655 {
1656 if (LocaleCompare(attribute,"label") == 0)
1657 {
1658 for ( ; image; image=image->next)
1659 (void) SetImageProperty(image,"label",InterpretImageProperties(
1660 info ? info->image_info : (ImageInfo *) NULL,image,
1661 SvPV(sval,na),exception),exception);
1662 break;
1663 }
1664 if (LocaleCompare(attribute,"loop") == 0)
1665 goto iterations;
1666 if (info)
1667 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1668 for ( ; image; image=image->next)
1669 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1670 break;
1671 }
1672 case 'M':
1673 case 'm':
1674 {
1675 if (LocaleCompare(attribute,"magick") == 0)
1676 {
1677 if (info)
cristy151b66d2015-04-15 10:50:31 +00001678 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00001679 "%s:",SvPV(sval,na));
1680 for ( ; image; image=image->next)
cristy151b66d2015-04-15 10:50:31 +00001681 (void) CopyMagickString(image->magick,SvPV(sval,na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001682 break;
1683 }
1684 if (LocaleCompare(attribute,"map-limit") == 0)
1685 {
1686 MagickSizeType
1687 limit;
1688
1689 limit=MagickResourceInfinity;
1690 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1691 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1692 100.0);
1693 (void) SetMagickResourceLimit(MapResource,limit);
1694 break;
1695 }
1696 if (LocaleCompare(attribute,"mask") == 0)
1697 {
1698 Image
1699 *mask;
1700
1701 mask=(Image *) NULL;
1702 if (SvPOK(sval))
1703 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1704 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001705 SetImageMask(image,ReadPixelMask,mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001706 break;
1707 }
1708 if (LocaleCompare(attribute,"mattecolor") == 0)
1709 {
1710 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1711 exception);
1712 if (info)
Cristy8645e042016-02-03 16:35:29 -05001713 info->image_info->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001714 for ( ; image; image=image->next)
Cristy8645e042016-02-03 16:35:29 -05001715 image->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001716 break;
1717 }
1718 if (LocaleCompare(attribute,"matte") == 0)
1719 {
1720 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1721 SvPV(sval,na)) : SvIV(sval);
1722 if (sp < 0)
1723 {
1724 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1725 SvPV(sval,na));
1726 break;
1727 }
1728 for ( ; image; image=image->next)
1729 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1730 break;
1731 }
1732 if (LocaleCompare(attribute,"memory-limit") == 0)
1733 {
1734 MagickSizeType
1735 limit;
1736
1737 limit=MagickResourceInfinity;
1738 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1739 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1740 100.0);
1741 (void) SetMagickResourceLimit(MemoryResource,limit);
1742 break;
1743 }
1744 if (LocaleCompare(attribute,"monochrome") == 0)
1745 {
1746 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1747 SvPV(sval,na)) : SvIV(sval);
1748 if (sp < 0)
1749 {
1750 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1751 SvPV(sval,na));
1752 break;
1753 }
1754 if (info)
1755 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1756 for ( ; image; image=image->next)
1757 (void) SetImageType(image,BilevelType,exception);
1758 break;
1759 }
1760 if (info)
1761 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1762 for ( ; image; image=image->next)
1763 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1764 break;
1765 }
1766 case 'O':
1767 case 'o':
1768 {
1769 if (LocaleCompare(attribute,"option") == 0)
1770 {
1771 if (info)
1772 DefineImageOption(info->image_info,SvPV(sval,na));
1773 break;
1774 }
1775 if (LocaleCompare(attribute,"orientation") == 0)
1776 {
1777 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1778 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1779 if (sp < 0)
1780 {
1781 ThrowPerlException(exception,OptionError,
1782 "UnrecognizedOrientationType",SvPV(sval,na));
1783 break;
1784 }
1785 if (info)
1786 info->image_info->orientation=(OrientationType) sp;
1787 for ( ; image; image=image->next)
1788 image->orientation=(OrientationType) sp;
1789 break;
1790 }
1791 if (info)
1792 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1793 for ( ; image; image=image->next)
1794 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1795 break;
1796 }
1797 case 'P':
1798 case 'p':
1799 {
1800 if (LocaleCompare(attribute,"page") == 0)
1801 {
1802 char
1803 *geometry;
1804
1805 geometry=GetPageGeometry(SvPV(sval,na));
1806 if (info)
1807 (void) CloneString(&info->image_info->page,geometry);
1808 for ( ; image; image=image->next)
1809 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1810 geometry=(char *) RelinquishMagickMemory(geometry);
1811 break;
1812 }
1813 if (LocaleNCompare(attribute,"pixel",5) == 0)
1814 {
1815 int
1816 items;
1817
1818 PixelInfo
1819 pixel;
1820
1821 register Quantum
1822 *q;
1823
1824 CacheView
1825 *image_view;
1826
1827 for ( ; image; image=image->next)
1828 {
1829 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1830 break;
1831 x=0;
1832 y=0;
1833 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1834 (void) items;
1835 image_view=AcquireVirtualCacheView(image,exception);
1836 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1837 if (q != (Quantum *) NULL)
1838 {
1839 if ((strchr(SvPV(sval,na),',') == 0) ||
1840 (strchr(SvPV(sval,na),')') != 0))
1841 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1842 &pixel,exception);
1843 else
1844 {
1845 GetPixelInfo(image,&pixel);
1846 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1847 pixel.red=geometry_info.rho;
1848 if ((flags & SigmaValue) != 0)
1849 pixel.green=geometry_info.sigma;
1850 if ((flags & XiValue) != 0)
1851 pixel.blue=geometry_info.xi;
1852 if ((flags & PsiValue) != 0)
1853 pixel.alpha=geometry_info.psi;
1854 if ((flags & ChiValue) != 0)
1855 pixel.black=geometry_info.chi;
1856 }
1857 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1858 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1859 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1860 if (image->colorspace == CMYKColorspace)
1861 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1862 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1863 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1864 }
1865 image_view=DestroyCacheView(image_view);
1866 }
1867 break;
1868 }
1869 if (LocaleCompare(attribute,"pointsize") == 0)
1870 {
1871 if (info)
1872 {
1873 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1874 info->image_info->pointsize=geometry_info.rho;
1875 }
1876 break;
1877 }
cristy4a3ce0a2013-08-03 20:06:59 +00001878 if (info)
1879 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1880 for ( ; image; image=image->next)
1881 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1882 break;
1883 }
1884 case 'Q':
1885 case 'q':
1886 {
1887 if (LocaleCompare(attribute,"quality") == 0)
1888 {
1889 if (info)
1890 info->image_info->quality=SvIV(sval);
1891 for ( ; image; image=image->next)
1892 image->quality=SvIV(sval);
1893 break;
1894 }
1895 if (info)
1896 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1897 for ( ; image; image=image->next)
1898 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1899 break;
1900 }
1901 case 'R':
1902 case 'r':
1903 {
cristyc0fe4752015-07-27 18:02:39 +00001904 if (LocaleCompare(attribute,"read-mask") == 0)
1905 {
1906 Image
1907 *mask;
1908
1909 mask=(Image *) NULL;
1910 if (SvPOK(sval))
1911 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1912 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001913 SetImageMask(image,ReadPixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00001914 break;
1915 }
cristy4a3ce0a2013-08-03 20:06:59 +00001916 if (LocaleCompare(attribute,"red-primary") == 0)
1917 {
1918 for ( ; image; image=image->next)
1919 {
1920 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1921 image->chromaticity.red_primary.x=geometry_info.rho;
1922 image->chromaticity.red_primary.y=geometry_info.sigma;
1923 if ((flags & SigmaValue) == 0)
1924 image->chromaticity.red_primary.y=
1925 image->chromaticity.red_primary.x;
1926 }
1927 break;
1928 }
1929 if (LocaleCompare(attribute,"render") == 0)
1930 {
1931 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1932 SvPV(sval,na)) : SvIV(sval);
1933 if (sp < 0)
1934 {
1935 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1936 SvPV(sval,na));
1937 break;
1938 }
1939 for ( ; image; image=image->next)
1940 image->rendering_intent=(RenderingIntent) sp;
1941 break;
1942 }
1943 if (LocaleCompare(attribute,"repage") == 0)
1944 {
1945 RectangleInfo
1946 geometry;
1947
1948 for ( ; image; image=image->next)
1949 {
1950 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1951 if ((flags & WidthValue) != 0)
1952 {
1953 if ((flags & HeightValue) == 0)
1954 geometry.height=geometry.width;
1955 image->page.width=geometry.width;
1956 image->page.height=geometry.height;
1957 }
1958 if ((flags & AspectValue) != 0)
1959 {
1960 if ((flags & XValue) != 0)
1961 image->page.x+=geometry.x;
1962 if ((flags & YValue) != 0)
1963 image->page.y+=geometry.y;
1964 }
1965 else
1966 {
1967 if ((flags & XValue) != 0)
1968 {
1969 image->page.x=geometry.x;
1970 if (((flags & WidthValue) != 0) && (geometry.x > 0))
1971 image->page.width=image->columns+geometry.x;
1972 }
1973 if ((flags & YValue) != 0)
1974 {
1975 image->page.y=geometry.y;
1976 if (((flags & HeightValue) != 0) && (geometry.y > 0))
1977 image->page.height=image->rows+geometry.y;
1978 }
1979 }
1980 }
1981 break;
1982 }
1983 if (info)
1984 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1985 for ( ; image; image=image->next)
1986 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1987 break;
1988 }
1989 case 'S':
1990 case 's':
1991 {
1992 if (LocaleCompare(attribute,"sampling-factor") == 0)
1993 {
1994 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1995 {
1996 ThrowPerlException(exception,OptionError,"MissingGeometry",
1997 SvPV(sval,na));
1998 break;
1999 }
2000 if (info)
2001 (void) CloneString(&info->image_info->sampling_factor,
2002 SvPV(sval,na));
2003 break;
2004 }
2005 if (LocaleCompare(attribute,"scene") == 0)
2006 {
2007 for ( ; image; image=image->next)
2008 image->scene=SvIV(sval);
2009 break;
2010 }
2011 if (LocaleCompare(attribute,"server") == 0)
2012 goto display;
2013 if (LocaleCompare(attribute,"size") == 0)
2014 {
2015 if (info)
2016 {
2017 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2018 {
2019 ThrowPerlException(exception,OptionError,"MissingGeometry",
2020 SvPV(sval,na));
2021 break;
2022 }
2023 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2024 }
2025 break;
2026 }
2027 if (LocaleCompare(attribute,"stroke") == 0)
2028 {
2029 if (info)
2030 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2031 break;
2032 }
2033 if (info)
2034 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2035 for ( ; image; image=image->next)
2036 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2037 break;
2038 }
2039 case 'T':
2040 case 't':
2041 {
2042 if (LocaleCompare(attribute,"texture") == 0)
2043 {
2044 if (info)
2045 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2046 break;
2047 }
2048 if (LocaleCompare(attribute,"thread-limit") == 0)
2049 {
2050 MagickSizeType
2051 limit;
2052
2053 limit=MagickResourceInfinity;
2054 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2055 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2056 100.0);
2057 (void) SetMagickResourceLimit(ThreadResource,limit);
2058 break;
2059 }
2060 if (LocaleCompare(attribute,"tile-offset") == 0)
2061 {
2062 char
2063 *geometry;
2064
2065 geometry=GetPageGeometry(SvPV(sval,na));
2066 if (info)
2067 (void) CloneString(&info->image_info->page,geometry);
2068 for ( ; image; image=image->next)
2069 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2070 exception);
2071 geometry=(char *) RelinquishMagickMemory(geometry);
2072 break;
2073 }
2074 if (LocaleCompare(attribute,"time-limit") == 0)
2075 {
2076 MagickSizeType
2077 limit;
2078
2079 limit=MagickResourceInfinity;
2080 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2081 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2082 100.0);
2083 (void) SetMagickResourceLimit(TimeResource,limit);
2084 break;
2085 }
2086 if (LocaleCompare(attribute,"transparent-color") == 0)
2087 {
2088 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2089 exception);
2090 if (info)
2091 info->image_info->transparent_color=target_color;
2092 for ( ; image; image=image->next)
2093 image->transparent_color=target_color;
2094 break;
2095 }
2096 if (LocaleCompare(attribute,"type") == 0)
2097 {
2098 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2099 SvPV(sval,na)) : SvIV(sval);
2100 if (sp < 0)
2101 {
2102 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2103 SvPV(sval,na));
2104 break;
2105 }
2106 if (info)
2107 info->image_info->type=(ImageType) sp;
2108 for ( ; image; image=image->next)
2109 SetImageType(image,(ImageType) sp,exception);
2110 break;
2111 }
2112 if (info)
2113 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2114 for ( ; image; image=image->next)
2115 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2116 break;
2117 }
2118 case 'U':
2119 case 'u':
2120 {
2121 if (LocaleCompare(attribute,"units") == 0)
2122 {
2123 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2124 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2125 if (sp < 0)
2126 {
2127 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2128 SvPV(sval,na));
2129 break;
2130 }
2131 if (info)
2132 info->image_info->units=(ResolutionType) sp;
2133 for ( ; image; image=image->next)
2134 {
2135 ResolutionType
2136 units;
2137
2138 units=(ResolutionType) sp;
2139 if (image->units != units)
2140 switch (image->units)
2141 {
2142 case UndefinedResolution:
2143 case PixelsPerInchResolution:
2144 {
2145 if (units == PixelsPerCentimeterResolution)
2146 {
2147 image->resolution.x*=2.54;
2148 image->resolution.y*=2.54;
2149 }
2150 break;
2151 }
2152 case PixelsPerCentimeterResolution:
2153 {
2154 if (units == PixelsPerInchResolution)
2155 {
2156 image->resolution.x/=2.54;
2157 image->resolution.y/=2.54;
2158 }
2159 break;
2160 }
2161 }
2162 image->units=units;
2163 }
2164 break;
2165 }
2166 if (info)
2167 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2168 for ( ; image; image=image->next)
2169 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2170 break;
2171 }
2172 case 'V':
2173 case 'v':
2174 {
2175 if (LocaleCompare(attribute,"verbose") == 0)
2176 {
2177 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2178 SvPV(sval,na)) : SvIV(sval);
2179 if (sp < 0)
2180 {
2181 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2182 SvPV(sval,na));
2183 break;
2184 }
2185 if (info)
2186 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2187 break;
2188 }
cristy4a3ce0a2013-08-03 20:06:59 +00002189 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2190 {
2191 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2192 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2193 if (sp < 0)
2194 {
2195 ThrowPerlException(exception,OptionError,
2196 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2197 break;
2198 }
2199 for ( ; image; image=image->next)
2200 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2201 break;
2202 }
2203 if (info)
2204 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2205 for ( ; image; image=image->next)
2206 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2207 break;
2208 }
2209 case 'W':
2210 case 'w':
2211 {
2212 if (LocaleCompare(attribute,"white-point") == 0)
2213 {
2214 for ( ; image; image=image->next)
2215 {
2216 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2217 image->chromaticity.white_point.x=geometry_info.rho;
2218 image->chromaticity.white_point.y=geometry_info.sigma;
2219 if ((flags & SigmaValue) == 0)
2220 image->chromaticity.white_point.y=
2221 image->chromaticity.white_point.x;
2222 }
2223 break;
2224 }
cristyc0fe4752015-07-27 18:02:39 +00002225 if (LocaleCompare(attribute,"write-mask") == 0)
2226 {
2227 Image
2228 *mask;
2229
2230 mask=(Image *) NULL;
2231 if (SvPOK(sval))
2232 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2233 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002234 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002235 break;
2236 }
cristy4a3ce0a2013-08-03 20:06:59 +00002237 if (info)
2238 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2239 for ( ; image; image=image->next)
2240 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2241 break;
2242 }
2243 default:
2244 {
2245 if (info)
2246 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2247 for ( ; image; image=image->next)
2248 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2249 break;
2250 }
2251 }
2252}
2253
2254/*
2255%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2256% %
2257% %
2258% %
2259% S e t u p L i s t %
2260% %
2261% %
2262% %
2263%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2264%
2265% Method SetupList returns the list of all the images linked by their
2266% image->next and image->previous link lists for use with ImageMagick. If
2267% info is non-NULL, an info structure is returned in *info. If
2268% reference_vector is non-NULL,an array of SV* are returned in
2269% *reference_vector. Reference_vector is used when the images are going to be
2270% replaced with new Image*'s.
2271%
2272% The format of the SetupList routine is:
2273%
2274% Image *SetupList(SV *reference,struct PackageInfo **info,
2275% SV ***reference_vector,ExceptionInfo *exception)
2276%
2277% A description of each parameter follows:
2278%
2279% o list: a list of strings.
2280%
2281% o string: a character string.
2282%
2283% o exception: Return any errors or warnings in this structure.
2284%
2285*/
2286static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2287 SV ***reference_vector,ExceptionInfo *exception)
2288{
2289 Image
2290 *image;
2291
2292 ssize_t
2293 current,
2294 last;
2295
2296 if (reference_vector)
2297 *reference_vector=NULL;
2298 if (info)
2299 *info=NULL;
2300 current=0;
2301 last=0;
2302 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2303 if (info && (SvTYPE(reference) == SVt_PVAV))
2304 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2305 exception);
2306 return(image);
2307}
2308
2309/*
2310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2311% %
2312% %
2313% %
2314% s t r E Q c a s e %
2315% %
2316% %
2317% %
2318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2319%
2320% strEQcase() compares two strings and returns 0 if they are the
2321% same or if the second string runs out first. The comparison is case
2322% insensitive.
2323%
2324% The format of the strEQcase routine is:
2325%
2326% ssize_t strEQcase(const char *p,const char *q)
2327%
2328% A description of each parameter follows:
2329%
2330% o p: a character string.
2331%
2332% o q: a character string.
2333%
2334%
2335*/
2336static ssize_t strEQcase(const char *p,const char *q)
2337{
2338 char
2339 c;
2340
2341 register ssize_t
2342 i;
2343
2344 for (i=0 ; (c=(*q)) != 0; i++)
2345 {
2346 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2347 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2348 return(0);
2349 p++;
2350 q++;
2351 }
2352 return(((*q == 0) && (*p == 0)) ? i : 0);
2353}
2354
2355/*
2356%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2357% %
2358% %
2359% %
2360% I m a g e : : M a g i c k %
2361% %
2362% %
2363% %
2364%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2365%
2366%
2367*/
2368MODULE = Image::Magick PACKAGE = Image::Magick
2369
2370PROTOTYPES: ENABLE
2371
2372BOOT:
2373 MagickCoreGenesis("PerlMagick",MagickFalse);
2374 SetWarningHandler(NULL);
2375 SetErrorHandler(NULL);
2376 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2377 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2378
2379void
2380UNLOAD()
2381 PPCODE:
2382 {
2383 if (magick_registry != (SplayTreeInfo *) NULL)
2384 magick_registry=DestroySplayTree(magick_registry);
2385 MagickCoreTerminus();
2386 }
2387
2388double
2389constant(name,argument)
2390 char *name
2391 ssize_t argument
2392
2393#
2394###############################################################################
2395# #
2396# #
2397# #
2398# A n i m a t e #
2399# #
2400# #
2401# #
2402###############################################################################
2403#
2404#
2405void
2406Animate(ref,...)
2407 Image::Magick ref=NO_INIT
2408 ALIAS:
2409 AnimateImage = 1
2410 animate = 2
2411 animateimage = 3
2412 PPCODE:
2413 {
2414 ExceptionInfo
2415 *exception;
2416
2417 Image
2418 *image;
2419
2420 register ssize_t
2421 i;
2422
2423 struct PackageInfo
2424 *info,
2425 *package_info;
2426
2427 SV
2428 *perl_exception,
2429 *reference;
2430
2431 PERL_UNUSED_VAR(ref);
2432 PERL_UNUSED_VAR(ix);
2433 exception=AcquireExceptionInfo();
2434 perl_exception=newSVpv("",0);
2435 package_info=(struct PackageInfo *) NULL;
2436 if (sv_isobject(ST(0)) == 0)
2437 {
2438 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2439 PackageName);
2440 goto PerlException;
2441 }
2442 reference=SvRV(ST(0));
2443 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2444 if (image == (Image *) NULL)
2445 {
2446 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2447 PackageName);
2448 goto PerlException;
2449 }
2450 package_info=ClonePackageInfo(info,exception);
2451 if (items == 2)
2452 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2453 else
2454 if (items > 2)
2455 for (i=2; i < items; i+=2)
2456 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2457 exception);
2458 (void) AnimateImages(package_info->image_info,image,exception);
2459 (void) CatchImageException(image);
2460
2461 PerlException:
2462 if (package_info != (struct PackageInfo *) NULL)
2463 DestroyPackageInfo(package_info);
2464 InheritPerlException(exception,perl_exception);
2465 exception=DestroyExceptionInfo(exception);
2466 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2467 SvPOK_on(perl_exception);
2468 ST(0)=sv_2mortal(perl_exception);
2469 XSRETURN(1);
2470 }
2471
2472#
2473###############################################################################
2474# #
2475# #
2476# #
2477# A p p e n d #
2478# #
2479# #
2480# #
2481###############################################################################
2482#
2483#
2484void
2485Append(ref,...)
2486 Image::Magick ref=NO_INIT
2487 ALIAS:
2488 AppendImage = 1
2489 append = 2
2490 appendimage = 3
2491 PPCODE:
2492 {
2493 AV
2494 *av;
2495
2496 char
2497 *attribute;
2498
2499 ExceptionInfo
2500 *exception;
2501
2502 HV
2503 *hv;
2504
2505 Image
2506 *image;
2507
2508 register ssize_t
2509 i;
2510
2511 ssize_t
2512 stack;
2513
2514 struct PackageInfo
2515 *info;
2516
2517 SV
2518 *av_reference,
2519 *perl_exception,
2520 *reference,
2521 *rv,
2522 *sv;
2523
2524 PERL_UNUSED_VAR(ref);
2525 PERL_UNUSED_VAR(ix);
2526 exception=AcquireExceptionInfo();
2527 perl_exception=newSVpv("",0);
2528 sv=NULL;
2529 attribute=NULL;
2530 av=NULL;
2531 if (sv_isobject(ST(0)) == 0)
2532 {
2533 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2534 PackageName);
2535 goto PerlException;
2536 }
2537 reference=SvRV(ST(0));
2538 hv=SvSTASH(reference);
2539 av=newAV();
2540 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2541 SvREFCNT_dec(av);
2542 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2543 if (image == (Image *) NULL)
2544 {
2545 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2546 PackageName);
2547 goto PerlException;
2548 }
2549 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2550 /*
2551 Get options.
2552 */
2553 stack=MagickTrue;
2554 for (i=2; i < items; i+=2)
2555 {
2556 attribute=(char *) SvPV(ST(i-1),na);
2557 switch (*attribute)
2558 {
2559 case 'S':
2560 case 's':
2561 {
2562 if (LocaleCompare(attribute,"stack") == 0)
2563 {
2564 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2565 SvPV(ST(i),na));
2566 if (stack < 0)
2567 {
2568 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2569 SvPV(ST(i),na));
2570 return;
2571 }
2572 break;
2573 }
2574 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2575 attribute);
2576 break;
2577 }
2578 default:
2579 {
2580 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2581 attribute);
2582 break;
2583 }
2584 }
2585 }
2586 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2587 if (image == (Image *) NULL)
2588 goto PerlException;
2589 for ( ; image; image=image->next)
2590 {
2591 AddImageToRegistry(sv,image);
2592 rv=newRV(sv);
2593 av_push(av,sv_bless(rv,hv));
2594 SvREFCNT_dec(sv);
2595 }
2596 exception=DestroyExceptionInfo(exception);
2597 ST(0)=av_reference;
2598 SvREFCNT_dec(perl_exception);
2599 XSRETURN(1);
2600
2601 PerlException:
2602 InheritPerlException(exception,perl_exception);
2603 exception=DestroyExceptionInfo(exception);
2604 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2605 SvPOK_on(perl_exception);
2606 ST(0)=sv_2mortal(perl_exception);
2607 XSRETURN(1);
2608 }
2609
2610#
2611###############################################################################
2612# #
2613# #
2614# #
2615# A v e r a g e #
2616# #
2617# #
2618# #
2619###############################################################################
2620#
2621#
2622void
2623Average(ref)
2624 Image::Magick ref=NO_INIT
2625 ALIAS:
2626 AverageImage = 1
2627 average = 2
2628 averageimage = 3
2629 PPCODE:
2630 {
2631 AV
2632 *av;
2633
2634 char
2635 *p;
2636
2637 ExceptionInfo
2638 *exception;
2639
2640 HV
2641 *hv;
2642
2643 Image
2644 *image;
2645
2646 struct PackageInfo
2647 *info;
2648
2649 SV
2650 *perl_exception,
2651 *reference,
2652 *rv,
2653 *sv;
2654
2655 PERL_UNUSED_VAR(ref);
2656 PERL_UNUSED_VAR(ix);
2657 exception=AcquireExceptionInfo();
2658 perl_exception=newSVpv("",0);
2659 sv=NULL;
2660 if (sv_isobject(ST(0)) == 0)
2661 {
2662 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2663 PackageName);
2664 goto PerlException;
2665 }
2666 reference=SvRV(ST(0));
2667 hv=SvSTASH(reference);
2668 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2669 if (image == (Image *) NULL)
2670 {
2671 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2672 PackageName);
2673 goto PerlException;
2674 }
2675 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2676 if (image == (Image *) NULL)
2677 goto PerlException;
2678 /*
2679 Create blessed Perl array for the returned image.
2680 */
2681 av=newAV();
2682 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2683 SvREFCNT_dec(av);
2684 AddImageToRegistry(sv,image);
2685 rv=newRV(sv);
2686 av_push(av,sv_bless(rv,hv));
2687 SvREFCNT_dec(sv);
2688 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002689 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2690 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002691 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2692 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002693 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002694 SetImageInfo(info->image_info,0,exception);
2695 exception=DestroyExceptionInfo(exception);
2696 SvREFCNT_dec(perl_exception);
2697 XSRETURN(1);
2698
2699 PerlException:
2700 InheritPerlException(exception,perl_exception);
2701 exception=DestroyExceptionInfo(exception);
2702 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2703 SvPOK_on(perl_exception);
2704 ST(0)=sv_2mortal(perl_exception);
2705 XSRETURN(1);
2706 }
2707
2708#
2709###############################################################################
2710# #
2711# #
2712# #
2713# B l o b T o I m a g e #
2714# #
2715# #
2716# #
2717###############################################################################
2718#
2719#
2720void
2721BlobToImage(ref,...)
2722 Image::Magick ref=NO_INIT
2723 ALIAS:
2724 BlobToImage = 1
2725 blobtoimage = 2
2726 blobto = 3
2727 PPCODE:
2728 {
2729 AV
2730 *av;
2731
2732 char
2733 **keep,
2734 **list;
2735
2736 ExceptionInfo
2737 *exception;
2738
2739 HV
2740 *hv;
2741
2742 Image
2743 *image;
2744
2745 register char
2746 **p;
2747
2748 register ssize_t
2749 i;
2750
2751 ssize_t
2752 ac,
2753 n,
2754 number_images;
2755
2756 STRLEN
2757 *length;
2758
2759 struct PackageInfo
2760 *info;
2761
2762 SV
2763 *perl_exception,
2764 *reference,
2765 *rv,
2766 *sv;
2767
2768 PERL_UNUSED_VAR(ref);
2769 PERL_UNUSED_VAR(ix);
2770 exception=AcquireExceptionInfo();
2771 perl_exception=newSVpv("",0);
2772 sv=NULL;
2773 number_images=0;
2774 ac=(items < 2) ? 1 : items-1;
2775 length=(STRLEN *) NULL;
2776 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2777 if (list == (char **) NULL)
2778 {
2779 ThrowPerlException(exception,ResourceLimitError,
2780 "MemoryAllocationFailed",PackageName);
2781 goto PerlException;
2782 }
2783 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2784 if (length == (STRLEN *) NULL)
2785 {
2786 ThrowPerlException(exception,ResourceLimitError,
2787 "MemoryAllocationFailed",PackageName);
2788 goto PerlException;
2789 }
2790 if (sv_isobject(ST(0)) == 0)
2791 {
2792 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2793 PackageName);
2794 goto PerlException;
2795 }
2796 reference=SvRV(ST(0));
2797 hv=SvSTASH(reference);
2798 if (SvTYPE(reference) != SVt_PVAV)
2799 {
2800 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2801 PackageName);
2802 goto PerlException;
2803 }
2804 av=(AV *) reference;
2805 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2806 exception);
2807 n=1;
2808 if (items <= 1)
2809 {
2810 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2811 goto PerlException;
2812 }
2813 for (n=0, i=0; i < ac; i++)
2814 {
2815 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2816 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2817 {
2818 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2819 continue;
2820 }
2821 n++;
2822 }
2823 list[n]=(char *) NULL;
2824 keep=list;
2825 for (i=number_images=0; i < n; i++)
2826 {
2827 image=BlobToImage(info->image_info,list[i],length[i],exception);
2828 if (image == (Image *) NULL)
2829 break;
2830 for ( ; image; image=image->next)
2831 {
2832 AddImageToRegistry(sv,image);
2833 rv=newRV(sv);
2834 av_push(av,sv_bless(rv,hv));
2835 SvREFCNT_dec(sv);
2836 number_images++;
2837 }
2838 }
2839 /*
2840 Free resources.
2841 */
2842 for (i=0; i < n; i++)
2843 if (list[i] != (char *) NULL)
2844 for (p=keep; list[i] != *p++; )
2845 if (*p == (char *) NULL)
2846 {
2847 list[i]=(char *) RelinquishMagickMemory(list[i]);
2848 break;
2849 }
2850
2851 PerlException:
2852 if (list)
2853 list=(char **) RelinquishMagickMemory(list);
2854 if (length)
2855 length=(STRLEN *) RelinquishMagickMemory(length);
2856 InheritPerlException(exception,perl_exception);
2857 exception=DestroyExceptionInfo(exception);
2858 sv_setiv(perl_exception,(IV) number_images);
2859 SvPOK_on(perl_exception);
2860 ST(0)=sv_2mortal(perl_exception);
2861 XSRETURN(1);
2862 }
2863
2864#
2865###############################################################################
2866# #
2867# #
2868# #
2869# C h a n n e l F x #
2870# #
2871# #
2872# #
2873###############################################################################
2874#
2875#
2876void
2877ChannelFx(ref,...)
2878 Image::Magick ref=NO_INIT
2879 ALIAS:
2880 ChannelFxImage = 1
2881 channelfx = 2
2882 channelfximage = 3
2883 PPCODE:
2884 {
2885 AV
2886 *av;
2887
2888 char
2889 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002890 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002891
2892 ChannelType
2893 channel,
2894 channel_mask;
2895
2896 ExceptionInfo
2897 *exception;
2898
2899 HV
2900 *hv;
2901
2902 Image
2903 *image;
2904
2905 register ssize_t
2906 i;
2907
2908 struct PackageInfo
2909 *info;
2910
2911 SV
2912 *av_reference,
2913 *perl_exception,
2914 *reference,
2915 *rv,
2916 *sv;
2917
2918 PERL_UNUSED_VAR(ref);
2919 PERL_UNUSED_VAR(ix);
2920 exception=AcquireExceptionInfo();
2921 perl_exception=newSVpv("",0);
2922 sv=NULL;
2923 attribute=NULL;
2924 av=NULL;
2925 if (sv_isobject(ST(0)) == 0)
2926 {
2927 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2928 PackageName);
2929 goto PerlException;
2930 }
2931 reference=SvRV(ST(0));
2932 hv=SvSTASH(reference);
2933 av=newAV();
2934 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2935 SvREFCNT_dec(av);
2936 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2937 if (image == (Image *) NULL)
2938 {
2939 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2940 PackageName);
2941 goto PerlException;
2942 }
2943 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2944 /*
2945 Get options.
2946 */
2947 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00002948 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002949 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00002950 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002951 else
2952 for (i=2; i < items; i+=2)
2953 {
2954 attribute=(char *) SvPV(ST(i-1),na);
2955 switch (*attribute)
2956 {
2957 case 'C':
2958 case 'c':
2959 {
2960 if (LocaleCompare(attribute,"channel") == 0)
2961 {
2962 ssize_t
2963 option;
2964
2965 option=ParseChannelOption(SvPV(ST(i),na));
2966 if (option < 0)
2967 {
2968 ThrowPerlException(exception,OptionError,
2969 "UnrecognizedType",SvPV(ST(i),na));
2970 return;
2971 }
2972 channel=(ChannelType) option;
2973 break;
2974 }
2975 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2976 attribute);
2977 break;
2978 }
2979 case 'E':
2980 case 'e':
2981 {
2982 if (LocaleCompare(attribute,"expression") == 0)
2983 {
2984 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00002985 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002986 break;
2987 }
2988 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2989 attribute);
2990 break;
2991 }
2992 default:
2993 {
2994 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2995 attribute);
2996 break;
2997 }
2998 }
2999 }
3000 channel_mask=SetImageChannelMask(image,channel);
3001 image=ChannelFxImage(image,expression,exception);
3002 if (image != (Image *) NULL)
3003 (void) SetImageChannelMask(image,channel_mask);
3004 if (image == (Image *) NULL)
3005 goto PerlException;
3006 for ( ; image; image=image->next)
3007 {
3008 AddImageToRegistry(sv,image);
3009 rv=newRV(sv);
3010 av_push(av,sv_bless(rv,hv));
3011 SvREFCNT_dec(sv);
3012 }
3013 exception=DestroyExceptionInfo(exception);
3014 ST(0)=av_reference;
3015 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3016 XSRETURN(1);
3017
3018 PerlException:
3019 InheritPerlException(exception,perl_exception);
3020 exception=DestroyExceptionInfo(exception);
3021 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3022 SvPOK_on(perl_exception);
3023 ST(0)=sv_2mortal(perl_exception);
3024 XSRETURN(1);
3025 }
3026
3027#
3028###############################################################################
3029# #
3030# #
3031# #
3032# C l o n e #
3033# #
3034# #
3035# #
3036###############################################################################
3037#
3038#
3039void
3040Clone(ref)
3041 Image::Magick ref=NO_INIT
3042 ALIAS:
3043 CopyImage = 1
3044 copy = 2
3045 copyimage = 3
3046 CloneImage = 4
3047 clone = 5
3048 cloneimage = 6
3049 Clone = 7
3050 PPCODE:
3051 {
3052 AV
3053 *av;
3054
3055 ExceptionInfo
3056 *exception;
3057
3058 HV
3059 *hv;
3060
3061 Image
3062 *clone,
3063 *image;
3064
3065 struct PackageInfo
3066 *info;
3067
3068 SV
3069 *perl_exception,
3070 *reference,
3071 *rv,
3072 *sv;
3073
3074 PERL_UNUSED_VAR(ref);
3075 PERL_UNUSED_VAR(ix);
3076 exception=AcquireExceptionInfo();
3077 perl_exception=newSVpv("",0);
3078 sv=NULL;
3079 if (sv_isobject(ST(0)) == 0)
3080 {
3081 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3082 PackageName);
3083 goto PerlException;
3084 }
3085 reference=SvRV(ST(0));
3086 hv=SvSTASH(reference);
3087 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3088 if (image == (Image *) NULL)
3089 {
3090 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3091 PackageName);
3092 goto PerlException;
3093 }
3094 /*
3095 Create blessed Perl array for the returned image.
3096 */
3097 av=newAV();
3098 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3099 SvREFCNT_dec(av);
3100 for ( ; image; image=image->next)
3101 {
3102 clone=CloneImage(image,0,0,MagickTrue,exception);
3103 if (clone == (Image *) NULL)
3104 break;
3105 AddImageToRegistry(sv,clone);
3106 rv=newRV(sv);
3107 av_push(av,sv_bless(rv,hv));
3108 SvREFCNT_dec(sv);
3109 }
3110 exception=DestroyExceptionInfo(exception);
3111 SvREFCNT_dec(perl_exception);
3112 XSRETURN(1);
3113
3114 PerlException:
3115 InheritPerlException(exception,perl_exception);
3116 exception=DestroyExceptionInfo(exception);
3117 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3118 SvPOK_on(perl_exception);
3119 ST(0)=sv_2mortal(perl_exception);
3120 XSRETURN(1);
3121 }
3122
3123#
3124###############################################################################
3125# #
3126# #
3127# #
3128# C L O N E #
3129# #
3130# #
3131# #
3132###############################################################################
3133#
3134#
3135void
3136CLONE(ref,...)
3137 SV *ref;
3138 CODE:
3139 {
3140 PERL_UNUSED_VAR(ref);
3141 if (magick_registry != (SplayTreeInfo *) NULL)
3142 {
3143 register Image
3144 *p;
3145
3146 ResetSplayTreeIterator(magick_registry);
3147 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3148 while (p != (Image *) NULL)
3149 {
3150 ReferenceImage(p);
3151 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3152 }
3153 }
3154 }
3155
3156#
3157###############################################################################
3158# #
3159# #
3160# #
3161# C o a l e s c e #
3162# #
3163# #
3164# #
3165###############################################################################
3166#
3167#
3168void
3169Coalesce(ref)
3170 Image::Magick ref=NO_INIT
3171 ALIAS:
3172 CoalesceImage = 1
3173 coalesce = 2
3174 coalesceimage = 3
3175 PPCODE:
3176 {
3177 AV
3178 *av;
3179
3180 ExceptionInfo
3181 *exception;
3182
3183 HV
3184 *hv;
3185
3186 Image
3187 *image;
3188
3189 struct PackageInfo
3190 *info;
3191
3192 SV
3193 *av_reference,
3194 *perl_exception,
3195 *reference,
3196 *rv,
3197 *sv;
3198
3199 PERL_UNUSED_VAR(ref);
3200 PERL_UNUSED_VAR(ix);
3201 exception=AcquireExceptionInfo();
3202 perl_exception=newSVpv("",0);
3203 sv=NULL;
3204 if (sv_isobject(ST(0)) == 0)
3205 {
3206 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3207 PackageName);
3208 goto PerlException;
3209 }
3210 reference=SvRV(ST(0));
3211 hv=SvSTASH(reference);
3212 av=newAV();
3213 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3214 SvREFCNT_dec(av);
3215 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3216 if (image == (Image *) NULL)
3217 {
3218 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3219 PackageName);
3220 goto PerlException;
3221 }
3222 image=CoalesceImages(image,exception);
3223 if (image == (Image *) NULL)
3224 goto PerlException;
3225 for ( ; image; image=image->next)
3226 {
3227 AddImageToRegistry(sv,image);
3228 rv=newRV(sv);
3229 av_push(av,sv_bless(rv,hv));
3230 SvREFCNT_dec(sv);
3231 }
3232 exception=DestroyExceptionInfo(exception);
3233 ST(0)=av_reference;
3234 SvREFCNT_dec(perl_exception);
3235 XSRETURN(1);
3236
3237 PerlException:
3238 InheritPerlException(exception,perl_exception);
3239 exception=DestroyExceptionInfo(exception);
3240 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3241 SvPOK_on(perl_exception);
3242 ST(0)=sv_2mortal(perl_exception);
3243 XSRETURN(1);
3244 }
3245
3246#
3247###############################################################################
3248# #
3249# #
3250# #
3251# C o m p a r e #
3252# #
3253# #
3254# #
3255###############################################################################
3256#
3257#
3258void
3259Compare(ref,...)
3260 Image::Magick ref=NO_INIT
3261 ALIAS:
3262 CompareImages = 1
3263 compare = 2
3264 compareimage = 3
3265 PPCODE:
3266 {
3267 AV
3268 *av;
3269
3270 char
3271 *attribute;
3272
3273 double
3274 distortion;
3275
3276 ExceptionInfo
3277 *exception;
3278
3279 HV
3280 *hv;
3281
3282 Image
3283 *difference_image,
3284 *image,
3285 *reconstruct_image;
3286
3287 MetricType
3288 metric;
3289
3290 register ssize_t
3291 i;
3292
3293 ssize_t
3294 option;
3295
3296 struct PackageInfo
3297 *info;
3298
3299 SV
3300 *av_reference,
3301 *perl_exception,
3302 *reference,
3303 *rv,
3304 *sv;
3305
3306 PERL_UNUSED_VAR(ref);
3307 PERL_UNUSED_VAR(ix);
3308 exception=AcquireExceptionInfo();
3309 perl_exception=newSVpv("",0);
3310 sv=NULL;
3311 av=NULL;
3312 attribute=NULL;
3313 if (sv_isobject(ST(0)) == 0)
3314 {
3315 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3316 PackageName);
3317 goto PerlException;
3318 }
3319 reference=SvRV(ST(0));
3320 hv=SvSTASH(reference);
3321 av=newAV();
3322 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3323 SvREFCNT_dec(av);
3324 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3325 if (image == (Image *) NULL)
3326 {
3327 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3328 PackageName);
3329 goto PerlException;
3330 }
3331 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3332 /*
3333 Get attribute.
3334 */
3335 reconstruct_image=image;
3336 metric=RootMeanSquaredErrorMetric;
3337 for (i=2; i < items; i+=2)
3338 {
3339 attribute=(char *) SvPV(ST(i-1),na);
3340 switch (*attribute)
3341 {
3342 case 'C':
3343 case 'c':
3344 {
3345 if (LocaleCompare(attribute,"channel") == 0)
3346 {
3347 ssize_t
3348 option;
3349
3350 option=ParseChannelOption(SvPV(ST(i),na));
3351 if (option < 0)
3352 {
3353 ThrowPerlException(exception,OptionError,
3354 "UnrecognizedType",SvPV(ST(i),na));
3355 return;
3356 }
cristybcd59342015-06-07 14:07:19 +00003357 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003358 break;
3359 }
3360 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3361 attribute);
3362 break;
3363 }
3364 case 'F':
3365 case 'f':
3366 {
3367 if (LocaleCompare(attribute,"fuzz") == 0)
3368 {
3369 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3370 break;
3371 }
3372 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3373 attribute);
3374 break;
3375 }
3376 case 'I':
3377 case 'i':
3378 {
3379 if (LocaleCompare(attribute,"image") == 0)
3380 {
3381 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3382 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3383 break;
3384 }
3385 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3386 attribute);
3387 break;
3388 }
3389 case 'M':
3390 case 'm':
3391 {
3392 if (LocaleCompare(attribute,"metric") == 0)
3393 {
3394 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3395 SvPV(ST(i),na));
3396 if (option < 0)
3397 {
3398 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3399 SvPV(ST(i),na));
3400 break;
3401 }
3402 metric=(MetricType) option;
3403 break;
3404 }
3405 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3406 attribute);
3407 break;
3408 }
3409 default:
3410 {
3411 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3412 attribute);
3413 break;
3414 }
3415 }
3416 }
3417 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3418 exception);
3419 if (difference_image != (Image *) NULL)
3420 {
3421 difference_image->error.mean_error_per_pixel=distortion;
3422 AddImageToRegistry(sv,difference_image);
3423 rv=newRV(sv);
3424 av_push(av,sv_bless(rv,hv));
3425 SvREFCNT_dec(sv);
3426 }
3427 exception=DestroyExceptionInfo(exception);
3428 ST(0)=av_reference;
3429 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3430 XSRETURN(1);
3431
3432 PerlException:
3433 InheritPerlException(exception,perl_exception);
3434 exception=DestroyExceptionInfo(exception);
3435 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3436 SvPOK_on(perl_exception);
3437 ST(0)=sv_2mortal(perl_exception);
3438 XSRETURN(1);
3439 }
3440
3441#
3442###############################################################################
3443# #
3444# #
3445# #
cristy15655332013-10-06 00:27:33 +00003446# C o m p l e x I m a g e s #
3447# #
3448# #
3449# #
3450###############################################################################
3451#
3452#
3453void
3454ComplexImages(ref)
3455 Image::Magick ref=NO_INIT
3456 ALIAS:
3457 ComplexImages = 1
3458 compleximages = 2
3459 PPCODE:
3460 {
3461 AV
3462 *av;
3463
3464 char
3465 *attribute,
3466 *p;
3467
cristyfa21e9e2013-10-07 10:37:38 +00003468 ComplexOperator
3469 op;
3470
cristy15655332013-10-06 00:27:33 +00003471 ExceptionInfo
3472 *exception;
3473
3474 HV
3475 *hv;
3476
3477 Image
3478 *image;
3479
cristy15655332013-10-06 00:27:33 +00003480 register ssize_t
3481 i;
3482
3483 struct PackageInfo
3484 *info;
3485
3486 SV
3487 *perl_exception,
3488 *reference,
3489 *rv,
3490 *sv;
3491
3492 PERL_UNUSED_VAR(ref);
3493 PERL_UNUSED_VAR(ix);
3494 exception=AcquireExceptionInfo();
3495 perl_exception=newSVpv("",0);
3496 sv=NULL;
3497 if (sv_isobject(ST(0)) == 0)
3498 {
3499 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3500 PackageName);
3501 goto PerlException;
3502 }
3503 reference=SvRV(ST(0));
3504 hv=SvSTASH(reference);
3505 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3506 if (image == (Image *) NULL)
3507 {
3508 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3509 PackageName);
3510 goto PerlException;
3511 }
cristyfd168722013-10-07 15:59:31 +00003512 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003513 if (items == 2)
3514 {
3515 ssize_t
3516 in;
3517
3518 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3519 SvPV(ST(1),na));
3520 if (in < 0)
3521 {
3522 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3523 SvPV(ST(1),na));
3524 return;
3525 }
cristyfa21e9e2013-10-07 10:37:38 +00003526 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003527 }
3528 else
3529 for (i=2; i < items; i+=2)
3530 {
3531 attribute=(char *) SvPV(ST(i-1),na);
3532 switch (*attribute)
3533 {
3534 case 'O':
3535 case 'o':
3536 {
3537 if (LocaleCompare(attribute,"operator") == 0)
3538 {
3539 ssize_t
3540 in;
3541
3542 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3543 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3544 if (in < 0)
3545 {
3546 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3547 SvPV(ST(i),na));
3548 return;
3549 }
cristyfa21e9e2013-10-07 10:37:38 +00003550 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003551 break;
3552 }
3553 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3554 attribute);
3555 break;
3556 }
3557 default:
3558 {
3559 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3560 attribute);
3561 break;
3562 }
3563 }
3564 }
3565 image=ComplexImages(image,op,exception);
3566 if (image == (Image *) NULL)
3567 goto PerlException;
3568 /*
3569 Create blessed Perl array for the returned image.
3570 */
3571 av=newAV();
3572 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3573 SvREFCNT_dec(av);
3574 AddImageToRegistry(sv,image);
3575 rv=newRV(sv);
3576 av_push(av,sv_bless(rv,hv));
3577 SvREFCNT_dec(sv);
3578 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003579 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3580 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003581 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3582 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003583 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003584 SetImageInfo(info->image_info,0,exception);
3585 exception=DestroyExceptionInfo(exception);
3586 SvREFCNT_dec(perl_exception);
3587 XSRETURN(1);
3588
3589 PerlException:
3590 InheritPerlException(exception,perl_exception);
3591 exception=DestroyExceptionInfo(exception);
3592 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3593 SvPOK_on(perl_exception);
3594 ST(0)=sv_2mortal(perl_exception);
3595 XSRETURN(1);
3596 }
3597
3598#
3599###############################################################################
3600# #
3601# #
3602# #
cristy4a3ce0a2013-08-03 20:06:59 +00003603# C o m p a r e L a y e r s #
3604# #
3605# #
3606# #
3607###############################################################################
3608#
3609#
3610void
3611CompareLayers(ref)
3612 Image::Magick ref=NO_INIT
3613 ALIAS:
3614 CompareImagesLayers = 1
3615 comparelayers = 2
3616 compareimagelayers = 3
3617 PPCODE:
3618 {
3619 AV
3620 *av;
3621
3622 char
3623 *attribute;
3624
3625 ExceptionInfo
3626 *exception;
3627
3628 HV
3629 *hv;
3630
3631 Image
3632 *image;
3633
3634 LayerMethod
3635 method;
3636
3637 register ssize_t
3638 i;
3639
3640 ssize_t
3641 option;
3642
3643 struct PackageInfo
3644 *info;
3645
3646 SV
3647 *av_reference,
3648 *perl_exception,
3649 *reference,
3650 *rv,
3651 *sv;
3652
3653 PERL_UNUSED_VAR(ref);
3654 PERL_UNUSED_VAR(ix);
3655 exception=AcquireExceptionInfo();
3656 perl_exception=newSVpv("",0);
3657 sv=NULL;
3658 if (sv_isobject(ST(0)) == 0)
3659 {
3660 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3661 PackageName);
3662 goto PerlException;
3663 }
3664 reference=SvRV(ST(0));
3665 hv=SvSTASH(reference);
3666 av=newAV();
3667 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3668 SvREFCNT_dec(av);
3669 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3670 if (image == (Image *) NULL)
3671 {
3672 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3673 PackageName);
3674 goto PerlException;
3675 }
3676 method=CompareAnyLayer;
3677 for (i=2; i < items; i+=2)
3678 {
3679 attribute=(char *) SvPV(ST(i-1),na);
3680 switch (*attribute)
3681 {
3682 case 'M':
3683 case 'm':
3684 {
3685 if (LocaleCompare(attribute,"method") == 0)
3686 {
3687 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3688 SvPV(ST(i),na));
3689 if (option < 0)
3690 {
3691 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3692 SvPV(ST(i),na));
3693 break;
3694 }
3695 method=(LayerMethod) option;
3696 break;
3697 }
3698 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3699 attribute);
3700 break;
3701 }
3702 default:
3703 {
3704 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3705 attribute);
3706 break;
3707 }
3708 }
3709 }
3710 image=CompareImagesLayers(image,method,exception);
3711 if (image == (Image *) NULL)
3712 goto PerlException;
3713 for ( ; image; image=image->next)
3714 {
3715 AddImageToRegistry(sv,image);
3716 rv=newRV(sv);
3717 av_push(av,sv_bless(rv,hv));
3718 SvREFCNT_dec(sv);
3719 }
3720 exception=DestroyExceptionInfo(exception);
3721 ST(0)=av_reference;
3722 SvREFCNT_dec(perl_exception);
3723 XSRETURN(1);
3724
3725 PerlException:
3726 InheritPerlException(exception,perl_exception);
3727 exception=DestroyExceptionInfo(exception);
3728 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3729 SvPOK_on(perl_exception);
3730 ST(0)=sv_2mortal(perl_exception);
3731 XSRETURN(1);
3732 }
3733
3734#
3735###############################################################################
3736# #
3737# #
3738# #
3739# D e s t r o y #
3740# #
3741# #
3742# #
3743###############################################################################
3744#
3745#
3746void
3747DESTROY(ref)
3748 Image::Magick ref=NO_INIT
3749 PPCODE:
3750 {
3751 SV
3752 *reference;
3753
3754 PERL_UNUSED_VAR(ref);
3755 if (sv_isobject(ST(0)) == 0)
3756 croak("ReferenceIsNotMyType");
3757 reference=SvRV(ST(0));
3758 switch (SvTYPE(reference))
3759 {
3760 case SVt_PVAV:
3761 {
3762 char
cristy151b66d2015-04-15 10:50:31 +00003763 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003764
3765 const SV
3766 *key;
3767
3768 HV
3769 *hv;
3770
3771 GV
3772 **gvp;
3773
3774 struct PackageInfo
3775 *info;
3776
3777 SV
3778 *sv;
3779
3780 /*
3781 Array (AV *) reference
3782 */
cristy151b66d2015-04-15 10:50:31 +00003783 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003784 XS_VERSION,reference);
3785 hv=gv_stashpv(PackageName, FALSE);
3786 if (!hv)
3787 break;
3788 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3789 if (!gvp)
3790 break;
3791 sv=GvSV(*gvp);
3792 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3793 {
3794 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3795 DestroyPackageInfo(info);
3796 }
3797 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3798 (void) key;
3799 break;
3800 }
3801 case SVt_PVMG:
3802 {
3803 Image
3804 *image;
3805
3806 /*
3807 Blessed scalar = (Image *) SvIV(reference)
3808 */
3809 image=INT2PTR(Image *,SvIV(reference));
3810 if (image != (Image *) NULL)
3811 DeleteImageFromRegistry(reference,image);
3812 break;
3813 }
3814 default:
3815 break;
3816 }
3817 }
3818
3819#
3820###############################################################################
3821# #
3822# #
3823# #
3824# D i s p l a y #
3825# #
3826# #
3827# #
3828###############################################################################
3829#
3830#
3831void
3832Display(ref,...)
3833 Image::Magick ref=NO_INIT
3834 ALIAS:
3835 DisplayImage = 1
3836 display = 2
3837 displayimage = 3
3838 PPCODE:
3839 {
3840 ExceptionInfo
3841 *exception;
3842
3843 Image
3844 *image;
3845
3846 register ssize_t
3847 i;
3848
3849 struct PackageInfo
3850 *info,
3851 *package_info;
3852
3853 SV
3854 *perl_exception,
3855 *reference;
3856
3857 PERL_UNUSED_VAR(ref);
3858 PERL_UNUSED_VAR(ix);
3859 exception=AcquireExceptionInfo();
3860 perl_exception=newSVpv("",0);
3861 package_info=(struct PackageInfo *) NULL;
3862 if (sv_isobject(ST(0)) == 0)
3863 {
3864 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3865 PackageName);
3866 goto PerlException;
3867 }
3868 reference=SvRV(ST(0));
3869 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3870 if (image == (Image *) NULL)
3871 {
3872 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3873 PackageName);
3874 goto PerlException;
3875 }
3876 package_info=ClonePackageInfo(info,exception);
3877 if (items == 2)
3878 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3879 else
3880 if (items > 2)
3881 for (i=2; i < items; i+=2)
3882 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3883 exception);
3884 (void) DisplayImages(package_info->image_info,image,exception);
3885 (void) CatchImageException(image);
3886
3887 PerlException:
3888 if (package_info != (struct PackageInfo *) NULL)
3889 DestroyPackageInfo(package_info);
3890 InheritPerlException(exception,perl_exception);
3891 exception=DestroyExceptionInfo(exception);
3892 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3893 SvPOK_on(perl_exception);
3894 ST(0)=sv_2mortal(perl_exception);
3895 XSRETURN(1);
3896 }
3897
3898#
3899###############################################################################
3900# #
3901# #
3902# #
3903# E v a l u a t e I m a g e s #
3904# #
3905# #
3906# #
3907###############################################################################
3908#
3909#
3910void
3911EvaluateImages(ref)
3912 Image::Magick ref=NO_INIT
3913 ALIAS:
3914 EvaluateImages = 1
3915 evaluateimages = 2
3916 PPCODE:
3917 {
3918 AV
3919 *av;
3920
3921 char
3922 *attribute,
3923 *p;
3924
3925 ExceptionInfo
3926 *exception;
3927
3928 HV
3929 *hv;
3930
3931 Image
3932 *image;
3933
3934 MagickEvaluateOperator
3935 op;
3936
3937 register ssize_t
3938 i;
3939
3940 struct PackageInfo
3941 *info;
3942
3943 SV
3944 *perl_exception,
3945 *reference,
3946 *rv,
3947 *sv;
3948
3949 PERL_UNUSED_VAR(ref);
3950 PERL_UNUSED_VAR(ix);
3951 exception=AcquireExceptionInfo();
3952 perl_exception=newSVpv("",0);
3953 sv=NULL;
3954 if (sv_isobject(ST(0)) == 0)
3955 {
3956 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3957 PackageName);
3958 goto PerlException;
3959 }
3960 reference=SvRV(ST(0));
3961 hv=SvSTASH(reference);
3962 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3963 if (image == (Image *) NULL)
3964 {
3965 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3966 PackageName);
3967 goto PerlException;
3968 }
3969 op=MeanEvaluateOperator;
3970 if (items == 2)
3971 {
3972 ssize_t
3973 in;
3974
3975 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
3976 SvPV(ST(1),na));
3977 if (in < 0)
3978 {
3979 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3980 SvPV(ST(1),na));
3981 return;
3982 }
3983 op=(MagickEvaluateOperator) in;
3984 }
3985 else
3986 for (i=2; i < items; i+=2)
3987 {
3988 attribute=(char *) SvPV(ST(i-1),na);
3989 switch (*attribute)
3990 {
3991 case 'O':
3992 case 'o':
3993 {
3994 if (LocaleCompare(attribute,"operator") == 0)
3995 {
3996 ssize_t
3997 in;
3998
3999 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4000 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4001 if (in < 0)
4002 {
4003 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4004 SvPV(ST(i),na));
4005 return;
4006 }
4007 op=(MagickEvaluateOperator) in;
4008 break;
4009 }
4010 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4011 attribute);
4012 break;
4013 }
4014 default:
4015 {
4016 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4017 attribute);
4018 break;
4019 }
4020 }
4021 }
4022 image=EvaluateImages(image,op,exception);
4023 if (image == (Image *) NULL)
4024 goto PerlException;
4025 /*
4026 Create blessed Perl array for the returned image.
4027 */
4028 av=newAV();
4029 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4030 SvREFCNT_dec(av);
4031 AddImageToRegistry(sv,image);
4032 rv=newRV(sv);
4033 av_push(av,sv_bless(rv,hv));
4034 SvREFCNT_dec(sv);
4035 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004036 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4037 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004038 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4039 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004040 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004041 SetImageInfo(info->image_info,0,exception);
4042 exception=DestroyExceptionInfo(exception);
4043 SvREFCNT_dec(perl_exception);
4044 XSRETURN(1);
4045
4046 PerlException:
4047 InheritPerlException(exception,perl_exception);
4048 exception=DestroyExceptionInfo(exception);
4049 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4050 SvPOK_on(perl_exception);
4051 ST(0)=sv_2mortal(perl_exception);
4052 XSRETURN(1);
4053 }
4054
4055#
4056###############################################################################
4057# #
4058# #
4059# #
4060# F e a t u r e s #
4061# #
4062# #
4063# #
4064###############################################################################
4065#
4066#
4067void
4068Features(ref,...)
4069 Image::Magick ref=NO_INIT
4070 ALIAS:
4071 FeaturesImage = 1
4072 features = 2
4073 featuresimage = 3
4074 PPCODE:
4075 {
4076#define ChannelFeatures(channel,direction) \
4077{ \
Cristyb1710fe2017-02-11 13:51:48 -05004078 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004079 channel_features[channel].angular_second_moment[direction]); \
4080 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004081 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004082 channel_features[channel].contrast[direction]); \
4083 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004084 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004085 channel_features[channel].contrast[direction]); \
4086 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004087 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004088 channel_features[channel].variance_sum_of_squares[direction]); \
4089 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004090 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004091 channel_features[channel].inverse_difference_moment[direction]); \
4092 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004093 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004094 channel_features[channel].sum_average[direction]); \
4095 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004096 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004097 channel_features[channel].sum_variance[direction]); \
4098 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004099 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004100 channel_features[channel].sum_entropy[direction]); \
4101 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004102 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004103 channel_features[channel].entropy[direction]); \
4104 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004105 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004106 channel_features[channel].difference_variance[direction]); \
4107 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004108 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004109 channel_features[channel].difference_entropy[direction]); \
4110 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004111 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004112 channel_features[channel].measure_of_correlation_1[direction]); \
4113 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004114 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004115 channel_features[channel].measure_of_correlation_2[direction]); \
4116 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004117 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004118 channel_features[channel].maximum_correlation_coefficient[direction]); \
4119 PUSHs(sv_2mortal(newSVpv(message,0))); \
4120}
4121
4122 AV
4123 *av;
4124
4125 char
4126 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004127 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004128
4129 ChannelFeatures
4130 *channel_features;
4131
4132 double
4133 distance;
4134
4135 ExceptionInfo
4136 *exception;
4137
4138 Image
4139 *image;
4140
4141 register ssize_t
4142 i;
4143
4144 ssize_t
4145 count;
4146
4147 struct PackageInfo
4148 *info;
4149
4150 SV
4151 *perl_exception,
4152 *reference;
4153
4154 PERL_UNUSED_VAR(ref);
4155 PERL_UNUSED_VAR(ix);
4156 exception=AcquireExceptionInfo();
4157 perl_exception=newSVpv("",0);
4158 av=NULL;
4159 if (sv_isobject(ST(0)) == 0)
4160 {
4161 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4162 PackageName);
4163 goto PerlException;
4164 }
4165 reference=SvRV(ST(0));
4166 av=newAV();
4167 SvREFCNT_dec(av);
4168 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4169 if (image == (Image *) NULL)
4170 {
4171 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4172 PackageName);
4173 goto PerlException;
4174 }
cristy7dbd9262014-07-02 17:53:42 +00004175 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004176 for (i=2; i < items; i+=2)
4177 {
4178 attribute=(char *) SvPV(ST(i-1),na);
4179 switch (*attribute)
4180 {
4181 case 'D':
4182 case 'd':
4183 {
4184 if (LocaleCompare(attribute,"distance") == 0)
4185 {
4186 distance=StringToLong((char *) SvPV(ST(1),na));
4187 break;
4188 }
4189 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4190 attribute);
4191 break;
4192 }
4193 default:
4194 {
4195 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4196 attribute);
4197 break;
4198 }
4199 }
4200 }
4201 count=0;
4202 for ( ; image; image=image->next)
4203 {
Cristy5a854dc2017-02-11 15:43:46 -05004204 register ssize_t
4205 j;
4206
cristy4a3ce0a2013-08-03 20:06:59 +00004207 channel_features=GetImageFeatures(image,distance,exception);
4208 if (channel_features == (ChannelFeatures *) NULL)
4209 continue;
4210 count++;
Cristy5a854dc2017-02-11 15:43:46 -05004211 for (j=0; j < 4; j++)
cristy4a3ce0a2013-08-03 20:06:59 +00004212 {
Cristy5a854dc2017-02-11 15:43:46 -05004213 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
4214 {
4215 PixelChannel channel=GetPixelChannelChannel(image,i);
4216 PixelTrait traits=GetPixelChannelTraits(image,channel);
4217 if (traits == UndefinedPixelTrait)
4218 continue;
4219 EXTEND(sp,14*(i+1)*count);
4220 ChannelFeatures(channel,j);
4221 }
cristy4a3ce0a2013-08-03 20:06:59 +00004222 }
4223 channel_features=(ChannelFeatures *)
4224 RelinquishMagickMemory(channel_features);
4225 }
4226
4227 PerlException:
4228 InheritPerlException(exception,perl_exception);
4229 exception=DestroyExceptionInfo(exception);
4230 SvREFCNT_dec(perl_exception);
4231 }
4232
4233#
4234###############################################################################
4235# #
4236# #
4237# #
4238# F l a t t e n #
4239# #
4240# #
4241# #
4242###############################################################################
4243#
4244#
4245void
4246Flatten(ref)
4247 Image::Magick ref=NO_INIT
4248 ALIAS:
4249 FlattenImage = 1
4250 flatten = 2
4251 flattenimage = 3
4252 PPCODE:
4253 {
4254 AV
4255 *av;
4256
4257 char
4258 *attribute,
4259 *p;
4260
4261 ExceptionInfo
4262 *exception;
4263
4264 HV
4265 *hv;
4266
4267 Image
4268 *image;
4269
4270 PixelInfo
4271 background_color;
4272
4273 register ssize_t
4274 i;
4275
4276 struct PackageInfo
4277 *info;
4278
4279 SV
4280 *perl_exception,
4281 *reference,
4282 *rv,
4283 *sv;
4284
4285 PERL_UNUSED_VAR(ref);
4286 PERL_UNUSED_VAR(ix);
4287 exception=AcquireExceptionInfo();
4288 perl_exception=newSVpv("",0);
4289 sv=NULL;
4290 if (sv_isobject(ST(0)) == 0)
4291 {
4292 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4293 PackageName);
4294 goto PerlException;
4295 }
4296 reference=SvRV(ST(0));
4297 hv=SvSTASH(reference);
4298 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4299 if (image == (Image *) NULL)
4300 {
4301 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4302 PackageName);
4303 goto PerlException;
4304 }
4305 background_color=image->background_color;
4306 if (items == 2)
4307 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4308 &background_color,exception);
4309 else
4310 for (i=2; i < items; i+=2)
4311 {
4312 attribute=(char *) SvPV(ST(i-1),na);
4313 switch (*attribute)
4314 {
4315 case 'B':
4316 case 'b':
4317 {
4318 if (LocaleCompare(attribute,"background") == 0)
4319 {
4320 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4321 AllCompliance,&background_color,exception);
4322 break;
4323 }
4324 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4325 attribute);
4326 break;
4327 }
4328 default:
4329 {
4330 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4331 attribute);
4332 break;
4333 }
4334 }
4335 }
4336 image->background_color=background_color;
4337 image=MergeImageLayers(image,FlattenLayer,exception);
4338 if (image == (Image *) NULL)
4339 goto PerlException;
4340 /*
4341 Create blessed Perl array for the returned image.
4342 */
4343 av=newAV();
4344 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4345 SvREFCNT_dec(av);
4346 AddImageToRegistry(sv,image);
4347 rv=newRV(sv);
4348 av_push(av,sv_bless(rv,hv));
4349 SvREFCNT_dec(sv);
4350 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004351 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4352 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004353 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4354 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004355 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004356 SetImageInfo(info->image_info,0,exception);
4357 exception=DestroyExceptionInfo(exception);
4358 SvREFCNT_dec(perl_exception);
4359 XSRETURN(1);
4360
4361 PerlException:
4362 InheritPerlException(exception,perl_exception);
4363 exception=DestroyExceptionInfo(exception);
4364 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4365 SvPOK_on(perl_exception); /* return messages in string context */
4366 ST(0)=sv_2mortal(perl_exception);
4367 XSRETURN(1);
4368 }
4369
4370#
4371###############################################################################
4372# #
4373# #
4374# #
4375# F x #
4376# #
4377# #
4378# #
4379###############################################################################
4380#
4381#
4382void
4383Fx(ref,...)
4384 Image::Magick ref=NO_INIT
4385 ALIAS:
4386 FxImage = 1
4387 fx = 2
4388 fximage = 3
4389 PPCODE:
4390 {
4391 AV
4392 *av;
4393
4394 char
4395 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004396 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004397
4398 ChannelType
4399 channel,
4400 channel_mask;
4401
4402 ExceptionInfo
4403 *exception;
4404
4405 HV
4406 *hv;
4407
4408 Image
4409 *image;
4410
4411 register ssize_t
4412 i;
4413
4414 struct PackageInfo
4415 *info;
4416
4417 SV
4418 *av_reference,
4419 *perl_exception,
4420 *reference,
4421 *rv,
4422 *sv;
4423
4424 PERL_UNUSED_VAR(ref);
4425 PERL_UNUSED_VAR(ix);
4426 exception=AcquireExceptionInfo();
4427 perl_exception=newSVpv("",0);
4428 sv=NULL;
4429 attribute=NULL;
4430 av=NULL;
4431 if (sv_isobject(ST(0)) == 0)
4432 {
4433 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4434 PackageName);
4435 goto PerlException;
4436 }
4437 reference=SvRV(ST(0));
4438 hv=SvSTASH(reference);
4439 av=newAV();
4440 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4441 SvREFCNT_dec(av);
4442 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4443 if (image == (Image *) NULL)
4444 {
4445 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4446 PackageName);
4447 goto PerlException;
4448 }
4449 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4450 /*
4451 Get options.
4452 */
4453 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004454 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004455 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004456 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004457 else
4458 for (i=2; i < items; i+=2)
4459 {
4460 attribute=(char *) SvPV(ST(i-1),na);
4461 switch (*attribute)
4462 {
4463 case 'C':
4464 case 'c':
4465 {
4466 if (LocaleCompare(attribute,"channel") == 0)
4467 {
4468 ssize_t
4469 option;
4470
4471 option=ParseChannelOption(SvPV(ST(i),na));
4472 if (option < 0)
4473 {
4474 ThrowPerlException(exception,OptionError,
4475 "UnrecognizedType",SvPV(ST(i),na));
4476 return;
4477 }
4478 channel=(ChannelType) option;
4479 break;
4480 }
4481 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4482 attribute);
4483 break;
4484 }
4485 case 'E':
4486 case 'e':
4487 {
4488 if (LocaleCompare(attribute,"expression") == 0)
4489 {
4490 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004491 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004492 break;
4493 }
4494 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4495 attribute);
4496 break;
4497 }
4498 default:
4499 {
4500 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4501 attribute);
4502 break;
4503 }
4504 }
4505 }
4506 channel_mask=SetImageChannelMask(image,channel);
4507 image=FxImage(image,expression,exception);
4508 if (image != (Image *) NULL)
4509 (void) SetImageChannelMask(image,channel_mask);
4510 if (image == (Image *) NULL)
4511 goto PerlException;
4512 for ( ; image; image=image->next)
4513 {
4514 AddImageToRegistry(sv,image);
4515 rv=newRV(sv);
4516 av_push(av,sv_bless(rv,hv));
4517 SvREFCNT_dec(sv);
4518 }
4519 exception=DestroyExceptionInfo(exception);
4520 ST(0)=av_reference;
4521 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4522 XSRETURN(1);
4523
4524 PerlException:
4525 InheritPerlException(exception,perl_exception);
4526 exception=DestroyExceptionInfo(exception);
4527 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4528 SvPOK_on(perl_exception);
4529 ST(0)=sv_2mortal(perl_exception);
4530 XSRETURN(1);
4531 }
4532
4533#
4534###############################################################################
4535# #
4536# #
4537# #
4538# G e t #
4539# #
4540# #
4541# #
4542###############################################################################
4543#
4544#
4545void
4546Get(ref,...)
4547 Image::Magick ref=NO_INIT
4548 ALIAS:
4549 GetAttributes = 1
4550 GetAttribute = 2
4551 get = 3
4552 getattributes = 4
4553 getattribute = 5
4554 PPCODE:
4555 {
4556 char
4557 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004558 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004559
4560 const char
4561 *value;
4562
4563 ExceptionInfo
4564 *exception;
4565
4566 Image
4567 *image;
4568
4569 long
4570 j;
4571
4572 register ssize_t
4573 i;
4574
4575 struct PackageInfo
4576 *info;
4577
4578 SV
4579 *perl_exception,
4580 *reference,
4581 *s;
4582
4583 PERL_UNUSED_VAR(ref);
4584 PERL_UNUSED_VAR(ix);
4585 exception=AcquireExceptionInfo();
4586 perl_exception=newSVpv("",0);
4587 if (sv_isobject(ST(0)) == 0)
4588 {
4589 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4590 PackageName);
4591 XSRETURN_EMPTY;
4592 }
4593 reference=SvRV(ST(0));
4594 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4595 if (image == (Image *) NULL && !info)
4596 XSRETURN_EMPTY;
4597 EXTEND(sp,items);
4598 for (i=1; i < items; i++)
4599 {
4600 attribute=(char *) SvPV(ST(i),na);
4601 s=NULL;
4602 switch (*attribute)
4603 {
4604 case 'A':
4605 case 'a':
4606 {
4607 if (LocaleCompare(attribute,"adjoin") == 0)
4608 {
4609 if (info)
4610 s=newSViv((ssize_t) info->image_info->adjoin);
4611 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4612 continue;
4613 }
4614 if (LocaleCompare(attribute,"antialias") == 0)
4615 {
4616 if (info)
4617 s=newSViv((ssize_t) info->image_info->antialias);
4618 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4619 continue;
4620 }
4621 if (LocaleCompare(attribute,"area") == 0)
4622 {
4623 s=newSViv(GetMagickResource(AreaResource));
4624 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4625 continue;
4626 }
4627 if (LocaleCompare(attribute,"attenuate") == 0)
4628 {
4629 const char
4630 *value;
4631
4632 value=GetImageProperty(image,attribute,exception);
4633 if (value != (const char *) NULL)
4634 s=newSVpv(value,0);
4635 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4636 continue;
4637 }
4638 if (LocaleCompare(attribute,"authenticate") == 0)
4639 {
4640 if (info)
4641 {
4642 const char
4643 *option;
4644
4645 option=GetImageOption(info->image_info,attribute);
4646 if (option != (const char *) NULL)
4647 s=newSVpv(option,0);
4648 }
4649 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4650 continue;
4651 }
4652 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4653 attribute);
4654 break;
4655 }
4656 case 'B':
4657 case 'b':
4658 {
4659 if (LocaleCompare(attribute,"background") == 0)
4660 {
4661 if (image == (Image *) NULL)
4662 break;
cristy151b66d2015-04-15 10:50:31 +00004663 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004664 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4665 (double) image->background_color.green,
4666 (double) image->background_color.blue,
4667 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004668 s=newSVpv(color,0);
4669 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4670 continue;
4671 }
4672 if (LocaleCompare(attribute,"base-columns") == 0)
4673 {
4674 if (image != (Image *) NULL)
4675 s=newSViv((ssize_t) image->magick_columns);
4676 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4677 continue;
4678 }
4679 if (LocaleCompare(attribute,"base-filename") == 0)
4680 {
4681 if (image != (Image *) NULL)
4682 s=newSVpv(image->magick_filename,0);
4683 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4684 continue;
4685 }
4686 if (LocaleCompare(attribute,"base-height") == 0)
4687 {
4688 if (image != (Image *) NULL)
4689 s=newSViv((ssize_t) image->magick_rows);
4690 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4691 continue;
4692 }
4693 if (LocaleCompare(attribute,"base-rows") == 0)
4694 {
4695 if (image != (Image *) NULL)
4696 s=newSViv((ssize_t) image->magick_rows);
4697 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4698 continue;
4699 }
4700 if (LocaleCompare(attribute,"base-width") == 0)
4701 {
4702 if (image != (Image *) NULL)
4703 s=newSViv((ssize_t) image->magick_columns);
4704 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4705 continue;
4706 }
4707 if (LocaleCompare(attribute,"blue-primary") == 0)
4708 {
4709 if (image == (Image *) NULL)
4710 break;
Cristyb1710fe2017-02-11 13:51:48 -05004711 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004712 image->chromaticity.blue_primary.x,
4713 image->chromaticity.blue_primary.y);
4714 s=newSVpv(color,0);
4715 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4716 continue;
4717 }
4718 if (LocaleCompare(attribute,"bordercolor") == 0)
4719 {
4720 if (image == (Image *) NULL)
4721 break;
cristy151b66d2015-04-15 10:50:31 +00004722 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004723 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4724 (double) image->border_color.green,
4725 (double) image->border_color.blue,
4726 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004727 s=newSVpv(color,0);
4728 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4729 continue;
4730 }
4731 if (LocaleCompare(attribute,"bounding-box") == 0)
4732 {
4733 char
cristy151b66d2015-04-15 10:50:31 +00004734 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004735
4736 RectangleInfo
4737 page;
4738
4739 if (image == (Image *) NULL)
4740 break;
4741 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004742 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004743 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4744 page.height,(double) page.x,(double) page.y);
4745 s=newSVpv(geometry,0);
4746 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4747 continue;
4748 }
4749 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4750 attribute);
4751 break;
4752 }
4753 case 'C':
4754 case 'c':
4755 {
4756 if (LocaleCompare(attribute,"class") == 0)
4757 {
4758 if (image == (Image *) NULL)
4759 break;
4760 s=newSViv(image->storage_class);
4761 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4762 image->storage_class));
4763 SvIOK_on(s);
4764 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4765 continue;
4766 }
4767 if (LocaleCompare(attribute,"clip-mask") == 0)
4768 {
4769 if (image != (Image *) NULL)
4770 {
4771 Image
4772 *mask_image;
4773
4774 SV
4775 *sv;
4776
4777 sv=NULL;
4778 if (image->read_mask == MagickFalse)
4779 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004780 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004781 if (mask_image != (Image *) NULL)
4782 {
4783 AddImageToRegistry(sv,mask_image);
4784 s=sv_bless(newRV(sv),SvSTASH(reference));
4785 }
4786 }
4787 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4788 continue;
4789 }
4790 if (LocaleCompare(attribute,"clip-path") == 0)
4791 {
4792 if (image != (Image *) NULL)
4793 {
4794 Image
4795 *mask_image;
4796
4797 SV
4798 *sv;
4799
4800 sv=NULL;
4801 if (image->read_mask != MagickFalse)
4802 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004803 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004804 if (mask_image != (Image *) NULL)
4805 {
4806 AddImageToRegistry(sv,mask_image);
4807 s=sv_bless(newRV(sv),SvSTASH(reference));
4808 }
4809 }
4810 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4811 continue;
4812 }
4813 if (LocaleCompare(attribute,"compression") == 0)
4814 {
4815 j=info ? info->image_info->compression : image ?
4816 image->compression : UndefinedCompression;
4817 if (info)
4818 if (info->image_info->compression == UndefinedCompression)
4819 j=image->compression;
4820 s=newSViv(j);
4821 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4822 j));
4823 SvIOK_on(s);
4824 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4825 continue;
4826 }
4827 if (LocaleCompare(attribute,"colorspace") == 0)
4828 {
4829 j=image ? image->colorspace : RGBColorspace;
4830 s=newSViv(j);
4831 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4832 j));
4833 SvIOK_on(s);
4834 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4835 continue;
4836 }
4837 if (LocaleCompare(attribute,"colors") == 0)
4838 {
4839 if (image != (Image *) NULL)
4840 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4841 exception));
4842 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4843 continue;
4844 }
4845 if (LocaleNCompare(attribute,"colormap",8) == 0)
4846 {
4847 int
4848 items;
4849
4850 if (image == (Image *) NULL || !image->colormap)
4851 break;
4852 j=0;
4853 items=sscanf(attribute,"%*[^[][%ld",&j);
4854 (void) items;
4855 if (j > (ssize_t) image->colors)
4856 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004857 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004858 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4859 (double) image->colormap[j].green,
4860 (double) image->colormap[j].blue,
4861 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004862 s=newSVpv(color,0);
4863 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4864 continue;
4865 }
4866 if (LocaleCompare(attribute,"columns") == 0)
4867 {
4868 if (image != (Image *) NULL)
4869 s=newSViv((ssize_t) image->columns);
4870 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4871 continue;
4872 }
4873 if (LocaleCompare(attribute,"comment") == 0)
4874 {
4875 const char
4876 *value;
4877
4878 value=GetImageProperty(image,attribute,exception);
4879 if (value != (const char *) NULL)
4880 s=newSVpv(value,0);
4881 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4882 continue;
4883 }
4884 if (LocaleCompare(attribute,"copyright") == 0)
4885 {
4886 s=newSVpv(GetMagickCopyright(),0);
4887 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4888 continue;
4889 }
4890 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4891 attribute);
4892 break;
4893 }
4894 case 'D':
4895 case 'd':
4896 {
4897 if (LocaleCompare(attribute,"density") == 0)
4898 {
4899 char
cristy151b66d2015-04-15 10:50:31 +00004900 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004901
4902 if (image == (Image *) NULL)
4903 break;
Cristyb1710fe2017-02-11 13:51:48 -05004904 (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004905 image->resolution.x,image->resolution.y);
4906 s=newSVpv(geometry,0);
4907 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4908 continue;
4909 }
4910 if (LocaleCompare(attribute,"delay") == 0)
4911 {
4912 if (image != (Image *) NULL)
4913 s=newSViv((ssize_t) image->delay);
4914 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4915 continue;
4916 }
4917 if (LocaleCompare(attribute,"depth") == 0)
4918 {
4919 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4920 if (image != (Image *) NULL)
4921 s=newSViv((ssize_t) GetImageDepth(image,exception));
4922 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4923 continue;
4924 }
4925 if (LocaleCompare(attribute,"directory") == 0)
4926 {
4927 if (image && image->directory)
4928 s=newSVpv(image->directory,0);
4929 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4930 continue;
4931 }
4932 if (LocaleCompare(attribute,"dispose") == 0)
4933 {
4934 if (image == (Image *) NULL)
4935 break;
4936
4937 s=newSViv(image->dispose);
4938 (void) sv_setpv(s,
4939 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
4940 SvIOK_on(s);
4941 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4942 continue;
4943 }
4944 if (LocaleCompare(attribute,"disk") == 0)
4945 {
4946 s=newSViv(GetMagickResource(DiskResource));
4947 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4948 continue;
4949 }
4950 if (LocaleCompare(attribute,"dither") == 0)
4951 {
4952 if (info)
4953 s=newSViv((ssize_t) info->image_info->dither);
4954 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4955 continue;
4956 }
4957 if (LocaleCompare(attribute,"display") == 0) /* same as server */
4958 {
4959 if (info && info->image_info->server_name)
4960 s=newSVpv(info->image_info->server_name,0);
4961 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4962 continue;
4963 }
4964 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4965 attribute);
4966 break;
4967 }
4968 case 'E':
4969 case 'e':
4970 {
4971 if (LocaleCompare(attribute,"elapsed-time") == 0)
4972 {
4973 if (image != (Image *) NULL)
4974 s=newSVnv(GetElapsedTime(&image->timer));
4975 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4976 continue;
4977 }
4978 if (LocaleCompare(attribute,"endian") == 0)
4979 {
4980 j=info ? info->image_info->endian : image ? image->endian :
4981 UndefinedEndian;
4982 s=newSViv(j);
4983 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
4984 SvIOK_on(s);
4985 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4986 continue;
4987 }
4988 if (LocaleCompare(attribute,"error") == 0)
4989 {
4990 if (image != (Image *) NULL)
4991 s=newSVnv(image->error.mean_error_per_pixel);
4992 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4993 continue;
4994 }
4995 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4996 attribute);
4997 break;
4998 }
4999 case 'F':
5000 case 'f':
5001 {
5002 if (LocaleCompare(attribute,"filesize") == 0)
5003 {
5004 if (image != (Image *) NULL)
5005 s=newSViv((ssize_t) GetBlobSize(image));
5006 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5007 continue;
5008 }
5009 if (LocaleCompare(attribute,"filename") == 0)
5010 {
5011 if (info && info->image_info->filename &&
5012 *info->image_info->filename)
5013 s=newSVpv(info->image_info->filename,0);
5014 if (image != (Image *) NULL)
5015 s=newSVpv(image->filename,0);
5016 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5017 continue;
5018 }
5019 if (LocaleCompare(attribute,"filter") == 0)
5020 {
5021 s=image ? newSViv(image->filter) : newSViv(0);
5022 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5023 image->filter));
5024 SvIOK_on(s);
5025 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5026 continue;
5027 }
5028 if (LocaleCompare(attribute,"font") == 0)
5029 {
5030 if (info && info->image_info->font)
5031 s=newSVpv(info->image_info->font,0);
5032 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5033 continue;
5034 }
5035 if (LocaleCompare(attribute,"foreground") == 0)
5036 continue;
5037 if (LocaleCompare(attribute,"format") == 0)
5038 {
5039 const MagickInfo
5040 *magick_info;
5041
5042 magick_info=(const MagickInfo *) NULL;
5043 if (info && (*info->image_info->magick != '\0'))
5044 magick_info=GetMagickInfo(info->image_info->magick,exception);
5045 if (image != (Image *) NULL)
5046 magick_info=GetMagickInfo(image->magick,exception);
5047 if ((magick_info != (const MagickInfo *) NULL) &&
5048 (*magick_info->description != '\0'))
5049 s=newSVpv((char *) magick_info->description,0);
5050 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5051 continue;
5052 }
5053 if (LocaleCompare(attribute,"fuzz") == 0)
5054 {
5055 if (info)
5056 s=newSVnv(info->image_info->fuzz);
5057 if (image != (Image *) NULL)
5058 s=newSVnv(image->fuzz);
5059 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5060 continue;
5061 }
5062 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5063 attribute);
5064 break;
5065 }
5066 case 'G':
5067 case 'g':
5068 {
5069 if (LocaleCompare(attribute,"gamma") == 0)
5070 {
5071 if (image != (Image *) NULL)
5072 s=newSVnv(image->gamma);
5073 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5074 continue;
5075 }
5076 if (LocaleCompare(attribute,"geometry") == 0)
5077 {
5078 if (image && image->geometry)
5079 s=newSVpv(image->geometry,0);
5080 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5081 continue;
5082 }
5083 if (LocaleCompare(attribute,"gravity") == 0)
5084 {
5085 s=image ? newSViv(image->gravity) : newSViv(0);
5086 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5087 image->gravity));
5088 SvIOK_on(s);
5089 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5090 continue;
5091 }
5092 if (LocaleCompare(attribute,"green-primary") == 0)
5093 {
5094 if (image == (Image *) NULL)
5095 break;
Cristyb1710fe2017-02-11 13:51:48 -05005096 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005097 image->chromaticity.green_primary.x,
5098 image->chromaticity.green_primary.y);
5099 s=newSVpv(color,0);
5100 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5101 continue;
5102 }
5103 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5104 attribute);
5105 break;
5106 }
5107 case 'H':
5108 case 'h':
5109 {
5110 if (LocaleCompare(attribute,"height") == 0)
5111 {
5112 if (image != (Image *) NULL)
5113 s=newSViv((ssize_t) image->rows);
5114 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5115 continue;
5116 }
5117 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5118 attribute);
5119 break;
5120 }
5121 case 'I':
5122 case 'i':
5123 {
5124 if (LocaleCompare(attribute,"icc") == 0)
5125 {
5126 if (image != (Image *) NULL)
5127 {
5128 const StringInfo
5129 *profile;
5130
5131 profile=GetImageProfile(image,"icc");
5132 if (profile != (StringInfo *) NULL)
5133 s=newSVpv((const char *) GetStringInfoDatum(profile),
5134 GetStringInfoLength(profile));
5135 }
5136 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5137 continue;
5138 }
5139 if (LocaleCompare(attribute,"icm") == 0)
5140 {
5141 if (image != (Image *) NULL)
5142 {
5143 const StringInfo
5144 *profile;
5145
5146 profile=GetImageProfile(image,"icm");
5147 if (profile != (const StringInfo *) NULL)
5148 s=newSVpv((const char *) GetStringInfoDatum(profile),
5149 GetStringInfoLength(profile));
5150 }
5151 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5152 continue;
5153 }
5154 if (LocaleCompare(attribute,"id") == 0)
5155 {
5156 if (image != (Image *) NULL)
5157 {
5158 char
cristy151b66d2015-04-15 10:50:31 +00005159 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005160
5161 MagickBooleanType
5162 status;
5163
5164 static ssize_t
5165 id = 0;
5166
cristy151b66d2015-04-15 10:50:31 +00005167 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005168 id);
5169 status=SetImageRegistry(ImageRegistryType,key,image,
5170 exception);
5171 (void) status;
5172 s=newSViv(id++);
5173 }
5174 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5175 continue;
5176 }
5177 if (LocaleNCompare(attribute,"index",5) == 0)
5178 {
5179 char
cristy151b66d2015-04-15 10:50:31 +00005180 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005181
5182 int
5183 items;
5184
5185 long
5186 x,
5187 y;
5188
5189 register const Quantum
5190 *p;
5191
5192 CacheView
5193 *image_view;
5194
5195 if (image == (Image *) NULL)
5196 break;
5197 if (image->storage_class != PseudoClass)
5198 break;
5199 x=0;
5200 y=0;
5201 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5202 (void) items;
5203 image_view=AcquireVirtualCacheView(image,exception);
5204 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5205 if (p != (const Quantum *) NULL)
5206 {
cristy151b66d2015-04-15 10:50:31 +00005207 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005208 GetPixelIndex(image,p));
5209 s=newSVpv(name,0);
5210 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5211 }
5212 image_view=DestroyCacheView(image_view);
5213 continue;
5214 }
5215 if (LocaleCompare(attribute,"iptc") == 0)
5216 {
5217 if (image != (Image *) NULL)
5218 {
5219 const StringInfo
5220 *profile;
5221
5222 profile=GetImageProfile(image,"iptc");
5223 if (profile != (const StringInfo *) NULL)
5224 s=newSVpv((const char *) GetStringInfoDatum(profile),
5225 GetStringInfoLength(profile));
5226 }
5227 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5228 continue;
5229 }
5230 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5231 {
5232 if (image != (Image *) NULL)
5233 s=newSViv((ssize_t) image->iterations);
5234 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5235 continue;
5236 }
5237 if (LocaleCompare(attribute,"interlace") == 0)
5238 {
5239 j=info ? info->image_info->interlace : image ? image->interlace :
5240 UndefinedInterlace;
5241 s=newSViv(j);
5242 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5243 j));
5244 SvIOK_on(s);
5245 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5246 continue;
5247 }
5248 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5249 attribute);
5250 break;
5251 }
5252 case 'L':
5253 case 'l':
5254 {
5255 if (LocaleCompare(attribute,"label") == 0)
5256 {
5257 const char
5258 *value;
5259
5260 if (image == (Image *) NULL)
5261 break;
5262 value=GetImageProperty(image,"Label",exception);
5263 if (value != (const char *) NULL)
5264 s=newSVpv(value,0);
5265 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5266 continue;
5267 }
5268 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5269 {
5270 if (image != (Image *) NULL)
5271 s=newSViv((ssize_t) image->iterations);
5272 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5273 continue;
5274 }
5275 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5276 attribute);
5277 break;
5278 }
5279 case 'M':
5280 case 'm':
5281 {
5282 if (LocaleCompare(attribute,"magick") == 0)
5283 {
5284 if (info && *info->image_info->magick)
5285 s=newSVpv(info->image_info->magick,0);
5286 if (image != (Image *) NULL)
5287 s=newSVpv(image->magick,0);
5288 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5289 continue;
5290 }
5291 if (LocaleCompare(attribute,"map") == 0)
5292 {
5293 s=newSViv(GetMagickResource(MapResource));
5294 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5295 continue;
5296 }
5297 if (LocaleCompare(attribute,"maximum-error") == 0)
5298 {
5299 if (image != (Image *) NULL)
5300 s=newSVnv(image->error.normalized_maximum_error);
5301 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5302 continue;
5303 }
5304 if (LocaleCompare(attribute,"memory") == 0)
5305 {
5306 s=newSViv(GetMagickResource(MemoryResource));
5307 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5308 continue;
5309 }
5310 if (LocaleCompare(attribute,"mean-error") == 0)
5311 {
5312 if (image != (Image *) NULL)
5313 s=newSVnv(image->error.normalized_mean_error);
5314 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5315 continue;
5316 }
5317 if (LocaleCompare(attribute,"mime") == 0)
5318 {
5319 if (info && *info->image_info->magick)
5320 s=newSVpv(MagickToMime(info->image_info->magick),0);
5321 if (image != (Image *) NULL)
5322 s=newSVpv(MagickToMime(image->magick),0);
5323 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5324 continue;
5325 }
5326 if (LocaleCompare(attribute,"mattecolor") == 0)
5327 {
5328 if (image == (Image *) NULL)
5329 break;
cristy151b66d2015-04-15 10:50:31 +00005330 (void) FormatLocaleString(color,MagickPathExtent,
Cristy8645e042016-02-03 16:35:29 -05005331 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5332 (double) image->alpha_color.green,
5333 (double) image->alpha_color.blue,
5334 (double) image->alpha_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005335 s=newSVpv(color,0);
5336 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5337 continue;
5338 }
5339 if (LocaleCompare(attribute,"matte") == 0)
5340 {
5341 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005342 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005343 1 : 0);
5344 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5345 continue;
5346 }
5347 if (LocaleCompare(attribute,"mime") == 0)
5348 {
5349 const char
5350 *magick;
5351
5352 magick=NULL;
5353 if (info && *info->image_info->magick)
5354 magick=info->image_info->magick;
5355 if (image != (Image *) NULL)
5356 magick=image->magick;
5357 if (magick)
5358 {
5359 char
5360 *mime;
5361
5362 mime=MagickToMime(magick);
5363 s=newSVpv(mime,0);
5364 mime=(char *) RelinquishMagickMemory(mime);
5365 }
5366 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5367 continue;
5368 }
5369 if (LocaleCompare(attribute,"monochrome") == 0)
5370 {
5371 if (image == (Image *) NULL)
5372 continue;
5373 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005374 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005375 s=newSViv(j);
5376 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5377 continue;
5378 }
5379 if (LocaleCompare(attribute,"montage") == 0)
5380 {
5381 if (image && image->montage)
5382 s=newSVpv(image->montage,0);
5383 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5384 continue;
5385 }
5386 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5387 attribute);
5388 break;
5389 }
5390 case 'O':
5391 case 'o':
5392 {
5393 if (LocaleCompare(attribute,"orientation") == 0)
5394 {
5395 j=info ? info->image_info->orientation : image ?
5396 image->orientation : UndefinedOrientation;
5397 s=newSViv(j);
5398 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5399 j));
5400 SvIOK_on(s);
5401 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5402 continue;
5403 }
5404 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5405 attribute);
5406 break;
5407 }
5408 case 'P':
5409 case 'p':
5410 {
5411 if (LocaleCompare(attribute,"page") == 0)
5412 {
5413 if (info && info->image_info->page)
5414 s=newSVpv(info->image_info->page,0);
5415 if (image != (Image *) NULL)
5416 {
5417 char
cristy151b66d2015-04-15 10:50:31 +00005418 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005419
cristy151b66d2015-04-15 10:50:31 +00005420 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005421 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5422 (double) image->page.height,(double) image->page.x,(double)
5423 image->page.y);
5424 s=newSVpv(geometry,0);
5425 }
5426 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5427 continue;
5428 }
5429 if (LocaleCompare(attribute,"page.x") == 0)
5430 {
5431 if (image != (Image *) NULL)
5432 s=newSViv((ssize_t) image->page.x);
5433 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5434 continue;
5435 }
5436 if (LocaleCompare(attribute,"page.y") == 0)
5437 {
5438 if (image != (Image *) NULL)
5439 s=newSViv((ssize_t) image->page.y);
5440 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5441 continue;
5442 }
5443 if (LocaleNCompare(attribute,"pixel",5) == 0)
5444 {
5445 char
cristy151b66d2015-04-15 10:50:31 +00005446 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005447
5448 int
5449 items;
5450
5451 long
5452 x,
5453 y;
5454
5455 register const Quantum
5456 *p;
5457
5458 if (image == (Image *) NULL)
5459 break;
5460 x=0;
5461 y=0;
5462 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5463 (void) items;
5464 p=GetVirtualPixels(image,x,y,1,1,exception);
5465 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005466 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005467 QuantumFormat "," QuantumFormat "," QuantumFormat,
5468 GetPixelRed(image,p),GetPixelGreen(image,p),
5469 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5470 else
cristy151b66d2015-04-15 10:50:31 +00005471 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005472 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5473 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5474 GetPixelBlue(image,p),GetPixelBlack(image,p),
5475 GetPixelAlpha(image,p));
5476 s=newSVpv(tuple,0);
5477 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5478 continue;
5479 }
5480 if (LocaleCompare(attribute,"pointsize") == 0)
5481 {
5482 if (info)
5483 s=newSViv((ssize_t) info->image_info->pointsize);
5484 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5485 continue;
5486 }
cristy4a3ce0a2013-08-03 20:06:59 +00005487 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5488 attribute);
5489 break;
5490 }
5491 case 'Q':
5492 case 'q':
5493 {
5494 if (LocaleCompare(attribute,"quality") == 0)
5495 {
5496 if (info)
5497 s=newSViv((ssize_t) info->image_info->quality);
5498 if (image != (Image *) NULL)
5499 s=newSViv((ssize_t) image->quality);
5500 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5501 continue;
5502 }
5503 if (LocaleCompare(attribute,"quantum") == 0)
5504 {
5505 if (info)
5506 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5507 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5508 continue;
5509 }
5510 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5511 attribute);
5512 break;
5513 }
5514 case 'R':
5515 case 'r':
5516 {
5517 if (LocaleCompare(attribute,"rendering-intent") == 0)
5518 {
5519 s=newSViv(image->rendering_intent);
5520 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5521 image->rendering_intent));
5522 SvIOK_on(s);
5523 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5524 continue;
5525 }
5526 if (LocaleCompare(attribute,"red-primary") == 0)
5527 {
5528 if (image == (Image *) NULL)
5529 break;
Cristyb1710fe2017-02-11 13:51:48 -05005530 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005531 image->chromaticity.red_primary.x,
5532 image->chromaticity.red_primary.y);
5533 s=newSVpv(color,0);
5534 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5535 continue;
5536 }
5537 if (LocaleCompare(attribute,"rows") == 0)
5538 {
5539 if (image != (Image *) NULL)
5540 s=newSViv((ssize_t) image->rows);
5541 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5542 continue;
5543 }
5544 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5545 attribute);
5546 break;
5547 }
5548 case 'S':
5549 case 's':
5550 {
5551 if (LocaleCompare(attribute,"sampling-factor") == 0)
5552 {
5553 if (info && info->image_info->sampling_factor)
5554 s=newSVpv(info->image_info->sampling_factor,0);
5555 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5556 continue;
5557 }
5558 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5559 {
5560 if (info && info->image_info->server_name)
5561 s=newSVpv(info->image_info->server_name,0);
5562 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5563 continue;
5564 }
5565 if (LocaleCompare(attribute,"size") == 0)
5566 {
5567 if (info && info->image_info->size)
5568 s=newSVpv(info->image_info->size,0);
5569 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5570 continue;
5571 }
5572 if (LocaleCompare(attribute,"scene") == 0)
5573 {
5574 if (image != (Image *) NULL)
5575 s=newSViv((ssize_t) image->scene);
5576 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5577 continue;
5578 }
5579 if (LocaleCompare(attribute,"scenes") == 0)
5580 {
5581 if (image != (Image *) NULL)
5582 s=newSViv((ssize_t) info->image_info->number_scenes);
5583 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5584 continue;
5585 }
5586 if (LocaleCompare(attribute,"signature") == 0)
5587 {
5588 const char
5589 *value;
5590
5591 if (image == (Image *) NULL)
5592 break;
5593 (void) SignatureImage(image,exception);
5594 value=GetImageProperty(image,"Signature",exception);
5595 if (value != (const char *) NULL)
5596 s=newSVpv(value,0);
5597 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5598 continue;
5599 }
5600 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5601 attribute);
5602 break;
5603 }
5604 case 'T':
5605 case 't':
5606 {
5607 if (LocaleCompare(attribute,"taint") == 0)
5608 {
5609 if (image != (Image *) NULL)
5610 s=newSViv((ssize_t) IsTaintImage(image));
5611 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5612 continue;
5613 }
5614 if (LocaleCompare(attribute,"texture") == 0)
5615 {
5616 if (info && info->image_info->texture)
5617 s=newSVpv(info->image_info->texture,0);
5618 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5619 continue;
5620 }
5621 if (LocaleCompare(attribute,"total-ink-density") == 0)
5622 {
5623 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5624 if (image != (Image *) NULL)
5625 s=newSVnv(GetImageTotalInkDensity(image,exception));
5626 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5627 continue;
5628 }
5629 if (LocaleCompare(attribute,"transparent-color") == 0)
5630 {
5631 if (image == (Image *) NULL)
5632 break;
cristy151b66d2015-04-15 10:50:31 +00005633 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005634 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5635 (double) image->transparent_color.green,
5636 (double) image->transparent_color.blue,
5637 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005638 s=newSVpv(color,0);
5639 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5640 continue;
5641 }
5642 if (LocaleCompare(attribute,"type") == 0)
5643 {
5644 if (image == (Image *) NULL)
5645 break;
cristya26f54c2015-07-29 12:26:12 +00005646 j=(ssize_t) GetImageType(image);
cristy4a3ce0a2013-08-03 20:06:59 +00005647 s=newSViv(j);
5648 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5649 SvIOK_on(s);
5650 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5651 continue;
5652 }
5653 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5654 attribute);
5655 break;
5656 }
5657 case 'U':
5658 case 'u':
5659 {
5660 if (LocaleCompare(attribute,"units") == 0)
5661 {
5662 j=info ? info->image_info->units : image ? image->units :
5663 UndefinedResolution;
5664 if (info && (info->image_info->units == UndefinedResolution))
5665 if (image)
5666 j=image->units;
5667 if (j == UndefinedResolution)
5668 s=newSVpv("undefined units",0);
5669 else
5670 if (j == PixelsPerInchResolution)
5671 s=newSVpv("pixels / inch",0);
5672 else
5673 s=newSVpv("pixels / centimeter",0);
5674 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5675 continue;
5676 }
5677 if (LocaleCompare(attribute,"user-time") == 0)
5678 {
5679 if (image != (Image *) NULL)
5680 s=newSVnv(GetUserTime(&image->timer));
5681 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5682 continue;
5683 }
5684 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5685 attribute);
5686 break;
5687 }
5688 case 'V':
5689 case 'v':
5690 {
5691 if (LocaleCompare(attribute,"verbose") == 0)
5692 {
5693 if (info)
5694 s=newSViv((ssize_t) info->image_info->verbose);
5695 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5696 continue;
5697 }
5698 if (LocaleCompare(attribute,"version") == 0)
5699 {
5700 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5701 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5702 continue;
5703 }
cristy4a3ce0a2013-08-03 20:06:59 +00005704 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5705 {
5706 if (image == (Image *) NULL)
5707 break;
5708 j=(ssize_t) GetImageVirtualPixelMethod(image);
5709 s=newSViv(j);
5710 (void) sv_setpv(s,CommandOptionToMnemonic(
5711 MagickVirtualPixelOptions,j));
5712 SvIOK_on(s);
5713 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5714 continue;
5715 }
5716 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5717 attribute);
5718 break;
5719 }
5720 case 'W':
5721 case 'w':
5722 {
5723 if (LocaleCompare(attribute,"white-point") == 0)
5724 {
5725 if (image == (Image *) NULL)
5726 break;
Cristyb1710fe2017-02-11 13:51:48 -05005727 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005728 image->chromaticity.white_point.x,
5729 image->chromaticity.white_point.y);
5730 s=newSVpv(color,0);
5731 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5732 continue;
5733 }
5734 if (LocaleCompare(attribute,"width") == 0)
5735 {
5736 if (image != (Image *) NULL)
5737 s=newSViv((ssize_t) image->columns);
5738 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5739 continue;
5740 }
5741 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5742 attribute);
5743 break;
5744 }
5745 case 'X':
5746 case 'x':
5747 {
Cristyc1f9f9f2016-01-05 08:19:28 -05005748 if (LocaleCompare(attribute,"xmp") == 0)
5749 {
5750 if (image != (Image *) NULL)
5751 {
5752 const StringInfo
5753 *profile;
5754
5755 profile=GetImageProfile(image,"xmp");
5756 if (profile != (StringInfo *) NULL)
5757 s=newSVpv((const char *) GetStringInfoDatum(profile),
5758 GetStringInfoLength(profile));
5759 }
5760 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5761 continue;
5762 }
cristy4a3ce0a2013-08-03 20:06:59 +00005763 if (LocaleCompare(attribute,"x-resolution") == 0)
5764 {
5765 if (image != (Image *) NULL)
5766 s=newSVnv(image->resolution.x);
5767 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5768 continue;
5769 }
5770 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5771 attribute);
5772 break;
5773 }
5774 case 'Y':
5775 case 'y':
5776 {
5777 if (LocaleCompare(attribute,"y-resolution") == 0)
5778 {
5779 if (image != (Image *) NULL)
5780 s=newSVnv(image->resolution.y);
5781 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5782 continue;
5783 }
5784 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5785 attribute);
5786 break;
5787 }
5788 default:
5789 break;
5790 }
5791 if (image == (Image *) NULL)
5792 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5793 attribute)
5794 else
5795 {
5796 value=GetImageProperty(image,attribute,exception);
5797 if (value != (const char *) NULL)
5798 {
5799 s=newSVpv(value,0);
5800 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5801 }
5802 else
5803 if (*attribute != '%')
5804 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5805 attribute)
5806 else
5807 {
5808 char
5809 *meta;
5810
5811 meta=InterpretImageProperties(info ? info->image_info :
5812 (ImageInfo *) NULL,image,attribute,exception);
5813 s=newSVpv(meta,0);
5814 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5815 meta=(char *) RelinquishMagickMemory(meta);
5816 }
5817 }
5818 }
5819 exception=DestroyExceptionInfo(exception);
5820 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5821 }
5822
5823#
5824###############################################################################
5825# #
5826# #
5827# #
5828# G e t A u t h e n t i c P i x e l s #
5829# #
5830# #
5831# #
5832###############################################################################
5833#
5834#
5835void *
5836GetAuthenticPixels(ref,...)
5837 Image::Magick ref = NO_INIT
5838 ALIAS:
5839 getauthenticpixels = 1
5840 GetImagePixels = 2
5841 getimagepixels = 3
5842 CODE:
5843 {
5844 char
5845 *attribute;
5846
5847 ExceptionInfo
5848 *exception;
5849
5850 Image
5851 *image;
5852
5853 RectangleInfo
5854 region;
5855
5856 ssize_t
5857 i;
5858
5859 struct PackageInfo
5860 *info;
5861
5862 SV
5863 *perl_exception,
5864 *reference;
5865
5866 void
5867 *blob = NULL;
5868
5869 PERL_UNUSED_VAR(ref);
5870 PERL_UNUSED_VAR(ix);
5871 exception=AcquireExceptionInfo();
5872 perl_exception=newSVpv("",0);
5873 if (sv_isobject(ST(0)) == 0)
5874 {
5875 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5876 PackageName);
5877 goto PerlException;
5878 }
5879 reference=SvRV(ST(0));
5880
5881 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5882 if (image == (Image *) NULL)
5883 {
5884 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5885 PackageName);
5886 goto PerlException;
5887 }
5888
5889 region.x=0;
5890 region.y=0;
5891 region.width=image->columns;
5892 region.height=1;
5893 if (items == 1)
5894 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5895 for (i=2; i < items; i+=2)
5896 {
5897 attribute=(char *) SvPV(ST(i-1),na);
5898 switch (*attribute)
5899 {
5900 case 'g':
5901 case 'G':
5902 {
5903 if (LocaleCompare(attribute,"geometry") == 0)
5904 {
5905 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5906 break;
5907 }
5908 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5909 attribute);
5910 break;
5911 }
5912 case 'H':
5913 case 'h':
5914 {
5915 if (LocaleCompare(attribute,"height") == 0)
5916 {
5917 region.height=SvIV(ST(i));
5918 continue;
5919 }
5920 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5921 attribute);
5922 break;
5923 }
5924 case 'X':
5925 case 'x':
5926 {
5927 if (LocaleCompare(attribute,"x") == 0)
5928 {
5929 region.x=SvIV(ST(i));
5930 continue;
5931 }
5932 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5933 attribute);
5934 break;
5935 }
5936 case 'Y':
5937 case 'y':
5938 {
5939 if (LocaleCompare(attribute,"y") == 0)
5940 {
5941 region.y=SvIV(ST(i));
5942 continue;
5943 }
5944 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5945 attribute);
5946 break;
5947 }
5948 case 'W':
5949 case 'w':
5950 {
5951 if (LocaleCompare(attribute,"width") == 0)
5952 {
5953 region.width=SvIV(ST(i));
5954 continue;
5955 }
5956 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5957 attribute);
5958 break;
5959 }
5960 }
5961 }
5962 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5963 region.height,exception);
5964 if (blob != (void *) NULL)
5965 goto PerlEnd;
5966
5967 PerlException:
5968 InheritPerlException(exception,perl_exception);
5969 exception=DestroyExceptionInfo(exception);
5970 SvREFCNT_dec(perl_exception); /* throw away all errors */
5971
5972 PerlEnd:
5973 RETVAL = blob;
5974 }
5975 OUTPUT:
5976 RETVAL
5977
5978#
5979###############################################################################
5980# #
5981# #
5982# #
5983# G e t V i r t u a l P i x e l s #
5984# #
5985# #
5986# #
5987###############################################################################
5988#
5989#
5990void *
5991GetVirtualPixels(ref,...)
5992 Image::Magick ref = NO_INIT
5993 ALIAS:
5994 getvirtualpixels = 1
5995 AcquireImagePixels = 2
5996 acquireimagepixels = 3
5997 CODE:
5998 {
5999 char
6000 *attribute;
6001
6002 const void
6003 *blob = NULL;
6004
6005 ExceptionInfo
6006 *exception;
6007
6008 Image
6009 *image;
6010
6011 RectangleInfo
6012 region;
6013
6014 ssize_t
6015 i;
6016
6017 struct PackageInfo
6018 *info;
6019
6020 SV
6021 *perl_exception,
6022 *reference;
6023
6024 PERL_UNUSED_VAR(ref);
6025 PERL_UNUSED_VAR(ix);
6026 exception=AcquireExceptionInfo();
6027 perl_exception=newSVpv("",0);
6028 if (sv_isobject(ST(0)) == 0)
6029 {
6030 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6031 PackageName);
6032 goto PerlException;
6033 }
6034 reference=SvRV(ST(0));
6035
6036 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6037 if (image == (Image *) NULL)
6038 {
6039 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6040 PackageName);
6041 goto PerlException;
6042 }
6043
6044 region.x=0;
6045 region.y=0;
6046 region.width=image->columns;
6047 region.height=1;
6048 if (items == 1)
6049 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6050 for (i=2; i < items; i+=2)
6051 {
6052 attribute=(char *) SvPV(ST(i-1),na);
6053 switch (*attribute)
6054 {
6055 case 'g':
6056 case 'G':
6057 {
6058 if (LocaleCompare(attribute,"geometry") == 0)
6059 {
6060 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6061 break;
6062 }
6063 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6064 attribute);
6065 break;
6066 }
6067 case 'H':
6068 case 'h':
6069 {
6070 if (LocaleCompare(attribute,"height") == 0)
6071 {
6072 region.height=SvIV(ST(i));
6073 continue;
6074 }
6075 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6076 attribute);
6077 break;
6078 }
6079 case 'X':
6080 case 'x':
6081 {
6082 if (LocaleCompare(attribute,"x") == 0)
6083 {
6084 region.x=SvIV(ST(i));
6085 continue;
6086 }
6087 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6088 attribute);
6089 break;
6090 }
6091 case 'Y':
6092 case 'y':
6093 {
6094 if (LocaleCompare(attribute,"y") == 0)
6095 {
6096 region.y=SvIV(ST(i));
6097 continue;
6098 }
6099 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6100 attribute);
6101 break;
6102 }
6103 case 'W':
6104 case 'w':
6105 {
6106 if (LocaleCompare(attribute,"width") == 0)
6107 {
6108 region.width=SvIV(ST(i));
6109 continue;
6110 }
6111 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6112 attribute);
6113 break;
6114 }
6115 }
6116 }
6117 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6118 region.height,exception);
6119 if (blob != (void *) NULL)
6120 goto PerlEnd;
6121
6122 PerlException:
6123 InheritPerlException(exception,perl_exception);
6124 exception=DestroyExceptionInfo(exception);
6125 SvREFCNT_dec(perl_exception); /* throw away all errors */
6126
6127 PerlEnd:
6128 RETVAL = (void *) blob;
6129 }
6130 OUTPUT:
6131 RETVAL
6132
6133#
6134###############################################################################
6135# #
6136# #
6137# #
6138# G e t A u t h e n t i c M e t a c o n t e n t #
6139# #
6140# #
6141# #
6142###############################################################################
6143#
6144#
6145void *
6146GetAuthenticMetacontent(ref,...)
6147 Image::Magick ref = NO_INIT
6148 ALIAS:
6149 getauthenticmetacontent = 1
6150 GetMetacontent = 2
6151 getmetacontent = 3
6152 CODE:
6153 {
6154 ExceptionInfo
6155 *exception;
6156
6157 Image
6158 *image;
6159
6160 struct PackageInfo
6161 *info;
6162
6163 SV
6164 *perl_exception,
6165 *reference;
6166
6167 void
6168 *blob = NULL;
6169
6170 PERL_UNUSED_VAR(ref);
6171 PERL_UNUSED_VAR(ix);
6172 exception=AcquireExceptionInfo();
6173 perl_exception=newSVpv("",0);
6174 if (sv_isobject(ST(0)) == 0)
6175 {
6176 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6177 PackageName);
6178 goto PerlException;
6179 }
6180 reference=SvRV(ST(0));
6181
6182 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6183 if (image == (Image *) NULL)
6184 {
6185 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6186 PackageName);
6187 goto PerlException;
6188 }
6189
6190 blob=(void *) GetAuthenticMetacontent(image);
6191 if (blob != (void *) NULL)
6192 goto PerlEnd;
6193
6194 PerlException:
6195 InheritPerlException(exception,perl_exception);
6196 exception=DestroyExceptionInfo(exception);
6197 SvREFCNT_dec(perl_exception); /* throw away all errors */
6198
6199 PerlEnd:
6200 RETVAL = blob;
6201 }
6202 OUTPUT:
6203 RETVAL
6204
6205#
6206###############################################################################
6207# #
6208# #
6209# #
6210# G e t V i r t u a l M e t a c o n t e n t #
6211# #
6212# #
6213# #
6214###############################################################################
6215#
6216#
6217void *
6218GetVirtualMetacontent(ref,...)
6219 Image::Magick ref = NO_INIT
6220 ALIAS:
6221 getvirtualmetacontent = 1
6222 CODE:
6223 {
6224 ExceptionInfo
6225 *exception;
6226
6227 Image
6228 *image;
6229
6230 struct PackageInfo
6231 *info;
6232
6233 SV
6234 *perl_exception,
6235 *reference;
6236
6237 void
6238 *blob = NULL;
6239
6240 PERL_UNUSED_VAR(ref);
6241 PERL_UNUSED_VAR(ix);
6242 exception=AcquireExceptionInfo();
6243 perl_exception=newSVpv("",0);
6244 if (sv_isobject(ST(0)) == 0)
6245 {
6246 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6247 PackageName);
6248 goto PerlException;
6249 }
6250 reference=SvRV(ST(0));
6251
6252 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6253 if (image == (Image *) NULL)
6254 {
6255 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6256 PackageName);
6257 goto PerlException;
6258 }
6259
6260 blob=(void *) GetVirtualMetacontent(image);
6261 if (blob != (void *) NULL)
6262 goto PerlEnd;
6263
6264 PerlException:
6265 InheritPerlException(exception,perl_exception);
6266 exception=DestroyExceptionInfo(exception);
6267 SvREFCNT_dec(perl_exception); /* throw away all errors */
6268
6269 PerlEnd:
6270 RETVAL = blob;
6271 }
6272 OUTPUT:
6273 RETVAL
6274
6275#
6276###############################################################################
6277# #
6278# #
6279# #
6280# H i s t o g r a m #
6281# #
6282# #
6283# #
6284###############################################################################
6285#
6286#
6287void
6288Histogram(ref,...)
6289 Image::Magick ref=NO_INIT
6290 ALIAS:
6291 HistogramImage = 1
6292 histogram = 2
6293 histogramimage = 3
6294 PPCODE:
6295 {
6296 AV
6297 *av;
6298
6299 char
cristy151b66d2015-04-15 10:50:31 +00006300 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006301
6302 PixelInfo
6303 *histogram;
6304
6305 ExceptionInfo
6306 *exception;
6307
6308 Image
6309 *image;
6310
6311 register ssize_t
6312 i;
6313
6314 ssize_t
6315 count;
6316
6317 struct PackageInfo
6318 *info;
6319
6320 SV
6321 *perl_exception,
6322 *reference;
6323
6324 size_t
6325 number_colors;
6326
6327 PERL_UNUSED_VAR(ref);
6328 PERL_UNUSED_VAR(ix);
6329 exception=AcquireExceptionInfo();
6330 perl_exception=newSVpv("",0);
6331 av=NULL;
6332 if (sv_isobject(ST(0)) == 0)
6333 {
6334 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6335 PackageName);
6336 goto PerlException;
6337 }
6338 reference=SvRV(ST(0));
6339 av=newAV();
6340 SvREFCNT_dec(av);
6341 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6342 if (image == (Image *) NULL)
6343 {
6344 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6345 PackageName);
6346 goto PerlException;
6347 }
cristy4a3ce0a2013-08-03 20:06:59 +00006348 count=0;
6349 for ( ; image; image=image->next)
6350 {
6351 histogram=GetImageHistogram(image,&number_colors,exception);
6352 if (histogram == (PixelInfo *) NULL)
6353 continue;
6354 count+=(ssize_t) number_colors;
6355 EXTEND(sp,6*count);
6356 for (i=0; i < (ssize_t) number_colors; i++)
6357 {
cristy151b66d2015-04-15 10:50:31 +00006358 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006359 histogram[i].red);
6360 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006361 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006362 histogram[i].green);
6363 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006364 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006365 histogram[i].blue);
6366 PUSHs(sv_2mortal(newSVpv(message,0)));
6367 if (image->colorspace == CMYKColorspace)
6368 {
cristy151b66d2015-04-15 10:50:31 +00006369 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006370 histogram[i].black);
6371 PUSHs(sv_2mortal(newSVpv(message,0)));
6372 }
cristy151b66d2015-04-15 10:50:31 +00006373 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006374 histogram[i].alpha);
6375 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006376 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006377 histogram[i].count);
6378 PUSHs(sv_2mortal(newSVpv(message,0)));
6379 }
6380 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6381 }
6382
6383 PerlException:
6384 InheritPerlException(exception,perl_exception);
6385 exception=DestroyExceptionInfo(exception);
6386 SvREFCNT_dec(perl_exception);
6387 }
6388
6389#
6390###############################################################################
6391# #
6392# #
6393# #
6394# G e t P i x e l #
6395# #
6396# #
6397# #
6398###############################################################################
6399#
6400#
6401void
6402GetPixel(ref,...)
6403 Image::Magick ref=NO_INIT
6404 ALIAS:
6405 getpixel = 1
6406 getPixel = 2
6407 PPCODE:
6408 {
6409 AV
6410 *av;
6411
6412 char
6413 *attribute;
6414
6415 ExceptionInfo
6416 *exception;
6417
6418 Image
6419 *image;
6420
6421 MagickBooleanType
6422 normalize;
6423
6424 RectangleInfo
6425 region;
6426
6427 register const Quantum
6428 *p;
6429
6430 register ssize_t
6431 i;
6432
6433 ssize_t
6434 option;
6435
6436 struct PackageInfo
6437 *info;
6438
6439 SV
6440 *perl_exception,
6441 *reference; /* reference is the SV* of ref=SvIV(reference) */
6442
6443 PERL_UNUSED_VAR(ref);
6444 PERL_UNUSED_VAR(ix);
6445 exception=AcquireExceptionInfo();
6446 perl_exception=newSVpv("",0);
6447 reference=SvRV(ST(0));
6448 av=(AV *) reference;
6449 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6450 exception);
6451 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6452 if (image == (Image *) NULL)
6453 {
6454 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6455 PackageName);
6456 goto PerlException;
6457 }
6458 normalize=MagickTrue;
6459 region.x=0;
6460 region.y=0;
6461 region.width=image->columns;
6462 region.height=1;
6463 if (items == 1)
6464 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6465 for (i=2; i < items; i+=2)
6466 {
6467 attribute=(char *) SvPV(ST(i-1),na);
6468 switch (*attribute)
6469 {
6470 case 'C':
6471 case 'c':
6472 {
6473 if (LocaleCompare(attribute,"channel") == 0)
6474 {
6475 ssize_t
6476 option;
6477
6478 option=ParseChannelOption(SvPV(ST(i),na));
6479 if (option < 0)
6480 {
6481 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6482 SvPV(ST(i),na));
6483 return;
6484 }
cristybcd59342015-06-07 14:07:19 +00006485 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00006486 break;
6487 }
6488 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6489 attribute);
6490 break;
6491 }
6492 case 'g':
6493 case 'G':
6494 {
6495 if (LocaleCompare(attribute,"geometry") == 0)
6496 {
6497 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6498 break;
6499 }
6500 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6501 attribute);
6502 break;
6503 }
6504 case 'N':
6505 case 'n':
6506 {
6507 if (LocaleCompare(attribute,"normalize") == 0)
6508 {
6509 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6510 SvPV(ST(i),na));
6511 if (option < 0)
6512 {
6513 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6514 SvPV(ST(i),na));
6515 break;
6516 }
6517 normalize=option != 0 ? MagickTrue : MagickFalse;
6518 break;
6519 }
6520 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6521 attribute);
6522 break;
6523 }
6524 case 'x':
6525 case 'X':
6526 {
6527 if (LocaleCompare(attribute,"x") == 0)
6528 {
6529 region.x=SvIV(ST(i));
6530 break;
6531 }
6532 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6533 attribute);
6534 break;
6535 }
6536 case 'y':
6537 case 'Y':
6538 {
6539 if (LocaleCompare(attribute,"y") == 0)
6540 {
6541 region.y=SvIV(ST(i));
6542 break;
6543 }
6544 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6545 attribute);
6546 break;
6547 }
6548 default:
6549 {
6550 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6551 attribute);
6552 break;
6553 }
6554 }
6555 }
6556 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6557 if (p == (const Quantum *) NULL)
6558 PUSHs(&sv_undef);
6559 else
6560 {
6561 double
6562 scale;
6563
6564 scale=1.0;
6565 if (normalize != MagickFalse)
6566 scale=1.0/QuantumRange;
6567 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6568 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6569 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6570 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6571 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6572 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6573 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6574 (image->colorspace == CMYKColorspace))
6575 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6576 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6577 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6578 }
6579
6580 PerlException:
6581 InheritPerlException(exception,perl_exception);
6582 exception=DestroyExceptionInfo(exception);
6583 SvREFCNT_dec(perl_exception);
6584 }
6585
6586#
6587###############################################################################
6588# #
6589# #
6590# #
6591# G e t P i x e l s #
6592# #
6593# #
6594# #
6595###############################################################################
6596#
6597#
6598void
6599GetPixels(ref,...)
6600 Image::Magick ref=NO_INIT
6601 ALIAS:
6602 getpixels = 1
6603 getPixels = 2
6604 PPCODE:
6605 {
6606 AV
6607 *av;
6608
6609 char
6610 *attribute;
6611
6612 const char
6613 *map;
6614
6615 ExceptionInfo
6616 *exception;
6617
6618 Image
6619 *image;
6620
6621 MagickBooleanType
6622 normalize,
6623 status;
6624
6625 RectangleInfo
6626 region;
6627
6628 register ssize_t
6629 i;
6630
6631 ssize_t
6632 option;
6633
6634 struct PackageInfo
6635 *info;
6636
6637 SV
6638 *perl_exception,
6639 *reference; /* reference is the SV* of ref=SvIV(reference) */
6640
6641 PERL_UNUSED_VAR(ref);
6642 PERL_UNUSED_VAR(ix);
6643 exception=AcquireExceptionInfo();
6644 perl_exception=newSVpv("",0);
6645 reference=SvRV(ST(0));
6646 av=(AV *) reference;
6647 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6648 exception);
6649 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6650 if (image == (Image *) NULL)
6651 {
6652 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6653 PackageName);
6654 goto PerlException;
6655 }
6656 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006657 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006658 map="RGBA";
6659 if (image->colorspace == CMYKColorspace)
6660 {
6661 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006662 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006663 map="CMYKA";
6664 }
6665 normalize=MagickFalse;
6666 region.x=0;
6667 region.y=0;
6668 region.width=image->columns;
6669 region.height=1;
6670 if (items == 1)
6671 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6672 for (i=2; i < items; i+=2)
6673 {
6674 attribute=(char *) SvPV(ST(i-1),na);
6675 switch (*attribute)
6676 {
6677 case 'g':
6678 case 'G':
6679 {
6680 if (LocaleCompare(attribute,"geometry") == 0)
6681 {
6682 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6683 break;
6684 }
6685 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6686 attribute);
6687 break;
6688 }
6689 case 'H':
6690 case 'h':
6691 {
6692 if (LocaleCompare(attribute,"height") == 0)
6693 {
6694 region.height=SvIV(ST(i));
6695 break;
6696 }
6697 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6698 attribute);
6699 break;
6700 }
6701 case 'M':
6702 case 'm':
6703 {
6704 if (LocaleCompare(attribute,"map") == 0)
6705 {
6706 map=SvPV(ST(i),na);
6707 break;
6708 }
6709 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6710 attribute);
6711 break;
6712 }
6713 case 'N':
6714 case 'n':
6715 {
6716 if (LocaleCompare(attribute,"normalize") == 0)
6717 {
6718 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6719 SvPV(ST(i),na));
6720 if (option < 0)
6721 {
6722 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6723 SvPV(ST(i),na));
6724 break;
6725 }
6726 normalize=option != 0 ? MagickTrue : MagickFalse;
6727 break;
6728 }
6729 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6730 attribute);
6731 break;
6732 }
6733 case 'W':
6734 case 'w':
6735 {
6736 if (LocaleCompare(attribute,"width") == 0)
6737 {
6738 region.width=SvIV(ST(i));
6739 break;
6740 }
6741 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6742 attribute);
6743 break;
6744 }
6745 case 'x':
6746 case 'X':
6747 {
6748 if (LocaleCompare(attribute,"x") == 0)
6749 {
6750 region.x=SvIV(ST(i));
6751 break;
6752 }
6753 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6754 attribute);
6755 break;
6756 }
6757 case 'y':
6758 case 'Y':
6759 {
6760 if (LocaleCompare(attribute,"y") == 0)
6761 {
6762 region.y=SvIV(ST(i));
6763 break;
6764 }
6765 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6766 attribute);
6767 break;
6768 }
6769 default:
6770 {
6771 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6772 attribute);
6773 break;
6774 }
6775 }
6776 }
6777 if (normalize != MagickFalse)
6778 {
6779 float
6780 *pixels;
6781
6782 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6783 region.height*sizeof(*pixels));
6784 if (pixels == (float *) NULL)
6785 {
6786 ThrowPerlException(exception,ResourceLimitError,
6787 "MemoryAllocationFailed",PackageName);
6788 goto PerlException;
6789 }
6790 status=ExportImagePixels(image,region.x,region.y,region.width,
6791 region.height,map,FloatPixel,pixels,exception);
6792 if (status == MagickFalse)
6793 PUSHs(&sv_undef);
6794 else
6795 {
6796 EXTEND(sp,strlen(map)*region.width*region.height);
6797 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6798 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6799 }
6800 pixels=(float *) RelinquishMagickMemory(pixels);
6801 }
6802 else
6803 {
6804 Quantum
6805 *pixels;
6806
6807 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6808 region.height*sizeof(*pixels));
6809 if (pixels == (Quantum *) NULL)
6810 {
6811 ThrowPerlException(exception,ResourceLimitError,
6812 "MemoryAllocationFailed",PackageName);
6813 goto PerlException;
6814 }
6815 status=ExportImagePixels(image,region.x,region.y,region.width,
6816 region.height,map,QuantumPixel,pixels,exception);
6817 if (status == MagickFalse)
6818 PUSHs(&sv_undef);
6819 else
6820 {
6821 EXTEND(sp,strlen(map)*region.width*region.height);
6822 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6823 PUSHs(sv_2mortal(newSViv(pixels[i])));
6824 }
6825 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6826 }
6827
6828 PerlException:
6829 InheritPerlException(exception,perl_exception);
6830 exception=DestroyExceptionInfo(exception);
6831 SvREFCNT_dec(perl_exception);
6832 }
6833
6834#
6835###############################################################################
6836# #
6837# #
6838# #
6839# I m a g e T o B l o b #
6840# #
6841# #
6842# #
6843###############################################################################
6844#
6845#
6846void
6847ImageToBlob(ref,...)
6848 Image::Magick ref=NO_INIT
6849 ALIAS:
6850 ImageToBlob = 1
6851 imagetoblob = 2
6852 toblob = 3
6853 blob = 4
6854 PPCODE:
6855 {
6856 char
cristy151b66d2015-04-15 10:50:31 +00006857 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006858
6859 ExceptionInfo
6860 *exception;
6861
6862 Image
6863 *image,
6864 *next;
6865
6866 register ssize_t
6867 i;
6868
6869 struct PackageInfo
6870 *info,
6871 *package_info;
6872
6873 size_t
6874 length;
6875
6876 ssize_t
6877 scene;
6878
6879 SV
6880 *perl_exception,
6881 *reference;
6882
6883 void
6884 *blob;
6885
6886 PERL_UNUSED_VAR(ref);
6887 PERL_UNUSED_VAR(ix);
6888 exception=AcquireExceptionInfo();
6889 perl_exception=newSVpv("",0);
6890 package_info=(struct PackageInfo *) NULL;
6891 if (sv_isobject(ST(0)) == 0)
6892 {
6893 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6894 PackageName);
6895 goto PerlException;
6896 }
6897 reference=SvRV(ST(0));
6898 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6899 if (image == (Image *) NULL)
6900 {
6901 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6902 PackageName);
6903 goto PerlException;
6904 }
6905 package_info=ClonePackageInfo(info,exception);
6906 for (i=2; i < items; i+=2)
6907 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6908 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006909 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006910 scene=0;
6911 for (next=image; next; next=next->next)
6912 {
cristy151b66d2015-04-15 10:50:31 +00006913 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006914 next->scene=scene++;
6915 }
6916 SetImageInfo(package_info->image_info,(unsigned int)
6917 GetImageListLength(image),exception);
6918 EXTEND(sp,(ssize_t) GetImageListLength(image));
6919 for ( ; image; image=image->next)
6920 {
6921 length=0;
6922 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6923 if (blob != (char *) NULL)
6924 {
6925 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6926 blob=(unsigned char *) RelinquishMagickMemory(blob);
6927 }
6928 if (package_info->image_info->adjoin)
6929 break;
6930 }
6931
6932 PerlException:
6933 if (package_info != (struct PackageInfo *) NULL)
6934 DestroyPackageInfo(package_info);
6935 InheritPerlException(exception,perl_exception);
6936 exception=DestroyExceptionInfo(exception);
6937 SvREFCNT_dec(perl_exception); /* throw away all errors */
6938 }
6939
6940#
6941###############################################################################
6942# #
6943# #
6944# #
6945# L a y e r s #
6946# #
6947# #
6948# #
6949###############################################################################
6950#
6951#
6952void
6953Layers(ref,...)
6954 Image::Magick ref=NO_INIT
6955 ALIAS:
6956 Layers = 1
6957 layers = 2
6958 OptimizeImageLayers = 3
6959 optimizelayers = 4
6960 optimizeimagelayers = 5
6961 PPCODE:
6962 {
6963 AV
6964 *av;
6965
6966 char
6967 *attribute;
6968
6969 CompositeOperator
6970 compose;
6971
6972 ExceptionInfo
6973 *exception;
6974
6975 HV
6976 *hv;
6977
6978 Image
6979 *image,
6980 *layers;
6981
6982 LayerMethod
6983 method;
6984
6985 register ssize_t
6986 i;
6987
6988 ssize_t
6989 option,
6990 sp;
6991
6992 struct PackageInfo
6993 *info;
6994
6995 SV
6996 *av_reference,
6997 *perl_exception,
6998 *reference,
6999 *rv,
7000 *sv;
7001
7002 PERL_UNUSED_VAR(ref);
7003 PERL_UNUSED_VAR(ix);
7004 exception=AcquireExceptionInfo();
7005 perl_exception=newSVpv("",0);
7006 sv=NULL;
7007 if (sv_isobject(ST(0)) == 0)
7008 {
7009 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7010 PackageName);
7011 goto PerlException;
7012 }
7013 reference=SvRV(ST(0));
7014 hv=SvSTASH(reference);
7015 av=newAV();
7016 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7017 SvREFCNT_dec(av);
7018 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7019 if (image == (Image *) NULL)
7020 {
7021 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7022 PackageName);
7023 goto PerlException;
7024 }
7025 compose=image->compose;
7026 method=OptimizeLayer;
7027 for (i=2; i < items; i+=2)
7028 {
7029 attribute=(char *) SvPV(ST(i-1),na);
7030 switch (*attribute)
7031 {
7032 case 'C':
7033 case 'c':
7034 {
7035 if (LocaleCompare(attribute,"compose") == 0)
7036 {
7037 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7038 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7039 if (sp < 0)
7040 {
7041 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7042 SvPV(ST(i),na));
7043 break;
7044 }
7045 compose=(CompositeOperator) sp;
7046 break;
7047 }
7048 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7049 attribute);
7050 break;
7051 }
7052 case 'M':
7053 case 'm':
7054 {
7055 if (LocaleCompare(attribute,"method") == 0)
7056 {
7057 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7058 SvPV(ST(i),na));
7059 if (option < 0)
7060 {
7061 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7062 SvPV(ST(i),na));
7063 break;
7064 }
7065 method=(LayerMethod) option;
7066 break;
7067 }
7068 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7069 attribute);
7070 break;
7071 }
7072 default:
7073 {
7074 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7075 attribute);
7076 break;
7077 }
7078 }
7079 }
7080 layers=(Image *) NULL;
7081 switch (method)
7082 {
7083 case CompareAnyLayer:
7084 case CompareClearLayer:
7085 case CompareOverlayLayer:
7086 default:
7087 {
7088 layers=CompareImagesLayers(image,method,exception);
7089 break;
7090 }
7091 case MergeLayer:
7092 case FlattenLayer:
7093 case MosaicLayer:
7094 {
7095 layers=MergeImageLayers(image,method,exception);
7096 break;
7097 }
7098 case DisposeLayer:
7099 {
7100 layers=DisposeImages(image,exception);
7101 break;
7102 }
7103 case OptimizeImageLayer:
7104 {
7105 layers=OptimizeImageLayers(image,exception);
7106 break;
7107 }
7108 case OptimizePlusLayer:
7109 {
7110 layers=OptimizePlusImageLayers(image,exception);
7111 break;
7112 }
7113 case OptimizeTransLayer:
7114 {
7115 OptimizeImageTransparency(image,exception);
7116 break;
7117 }
7118 case RemoveDupsLayer:
7119 {
7120 RemoveDuplicateLayers(&image,exception);
7121 break;
7122 }
7123 case RemoveZeroLayer:
7124 {
7125 RemoveZeroDelayLayers(&image,exception);
7126 break;
7127 }
7128 case OptimizeLayer:
7129 {
7130 QuantizeInfo
7131 *quantize_info;
7132
7133 /*
7134 General Purpose, GIF Animation Optimizer.
7135 */
7136 layers=CoalesceImages(image,exception);
7137 if (layers == (Image *) NULL)
7138 break;
7139 image=layers;
7140 layers=OptimizeImageLayers(image,exception);
7141 if (layers == (Image *) NULL)
7142 break;
7143 image=DestroyImageList(image);
7144 image=layers;
7145 layers=(Image *) NULL;
7146 OptimizeImageTransparency(image,exception);
7147 quantize_info=AcquireQuantizeInfo(info->image_info);
7148 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7149 quantize_info=DestroyQuantizeInfo(quantize_info);
7150 break;
7151 }
7152 case CompositeLayer:
7153 {
7154 Image
7155 *source;
7156
7157 RectangleInfo
7158 geometry;
7159
7160 /*
7161 Split image sequence at the first 'NULL:' image.
7162 */
7163 source=image;
7164 while (source != (Image *) NULL)
7165 {
7166 source=GetNextImageInList(source);
7167 if ((source != (Image *) NULL) &&
7168 (LocaleCompare(source->magick,"NULL") == 0))
7169 break;
7170 }
7171 if (source != (Image *) NULL)
7172 {
7173 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7174 (GetNextImageInList(source) == (Image *) NULL))
7175 source=(Image *) NULL;
7176 else
7177 {
7178 /*
7179 Separate the two lists, junk the null: image.
7180 */
7181 source=SplitImageList(source->previous);
7182 DeleteImageFromList(&source);
7183 }
7184 }
7185 if (source == (Image *) NULL)
7186 {
7187 (void) ThrowMagickException(exception,GetMagickModule(),
7188 OptionError,"MissingNullSeparator","layers Composite");
7189 break;
7190 }
7191 /*
7192 Adjust offset with gravity and virtual canvas.
7193 */
7194 SetGeometry(image,&geometry);
7195 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7196 geometry.width=source->page.width != 0 ? source->page.width :
7197 source->columns;
7198 geometry.height=source->page.height != 0 ? source->page.height :
7199 source->rows;
7200 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7201 image->columns,image->page.height != 0 ? image->page.height :
7202 image->rows,image->gravity,&geometry);
7203 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7204 source=DestroyImageList(source);
7205 break;
7206 }
7207 }
7208 if (layers != (Image *) NULL)
7209 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007210 else
7211 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007212 if (image == (Image *) NULL)
7213 goto PerlException;
7214 for ( ; image; image=image->next)
7215 {
7216 AddImageToRegistry(sv,image);
7217 rv=newRV(sv);
7218 av_push(av,sv_bless(rv,hv));
7219 SvREFCNT_dec(sv);
7220 }
7221 exception=DestroyExceptionInfo(exception);
7222 ST(0)=av_reference;
7223 SvREFCNT_dec(perl_exception);
7224 XSRETURN(1);
7225
7226 PerlException:
7227 InheritPerlException(exception,perl_exception);
7228 exception=DestroyExceptionInfo(exception);
7229 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7230 SvPOK_on(perl_exception);
7231 ST(0)=sv_2mortal(perl_exception);
7232 XSRETURN(1);
7233 }
7234
7235#
7236###############################################################################
7237# #
7238# #
7239# #
7240# M a g i c k T o M i m e #
7241# #
7242# #
7243# #
7244###############################################################################
7245#
7246#
7247SV *
7248MagickToMime(ref,name)
7249 Image::Magick ref=NO_INIT
7250 char *name
7251 ALIAS:
7252 magicktomime = 1
7253 CODE:
7254 {
7255 char
7256 *mime;
7257
7258 PERL_UNUSED_VAR(ref);
7259 PERL_UNUSED_VAR(ix);
7260 mime=MagickToMime(name);
7261 RETVAL=newSVpv(mime,0);
7262 mime=(char *) RelinquishMagickMemory(mime);
7263 }
7264 OUTPUT:
7265 RETVAL
7266
7267#
7268###############################################################################
7269# #
7270# #
7271# #
7272# M o g r i f y #
7273# #
7274# #
7275# #
7276###############################################################################
7277#
7278#
7279void
7280Mogrify(ref,...)
7281 Image::Magick ref=NO_INIT
7282 ALIAS:
7283 Comment = 1
7284 CommentImage = 2
7285 Label = 3
7286 LabelImage = 4
7287 AddNoise = 5
7288 AddNoiseImage = 6
7289 Colorize = 7
7290 ColorizeImage = 8
7291 Border = 9
7292 BorderImage = 10
7293 Blur = 11
7294 BlurImage = 12
7295 Chop = 13
7296 ChopImage = 14
7297 Crop = 15
7298 CropImage = 16
7299 Despeckle = 17
7300 DespeckleImage = 18
7301 Edge = 19
7302 EdgeImage = 20
7303 Emboss = 21
7304 EmbossImage = 22
7305 Enhance = 23
7306 EnhanceImage = 24
7307 Flip = 25
7308 FlipImage = 26
7309 Flop = 27
7310 FlopImage = 28
7311 Frame = 29
7312 FrameImage = 30
7313 Implode = 31
7314 ImplodeImage = 32
7315 Magnify = 33
7316 MagnifyImage = 34
7317 MedianFilter = 35
7318 MedianConvolveImage = 36
7319 Minify = 37
7320 MinifyImage = 38
7321 OilPaint = 39
7322 OilPaintImage = 40
7323 ReduceNoise = 41
7324 ReduceNoiseImage = 42
7325 Roll = 43
7326 RollImage = 44
7327 Rotate = 45
7328 RotateImage = 46
7329 Sample = 47
7330 SampleImage = 48
7331 Scale = 49
7332 ScaleImage = 50
7333 Shade = 51
7334 ShadeImage = 52
7335 Sharpen = 53
7336 SharpenImage = 54
7337 Shear = 55
7338 ShearImage = 56
7339 Spread = 57
7340 SpreadImage = 58
7341 Swirl = 59
7342 SwirlImage = 60
7343 Resize = 61
7344 ResizeImage = 62
7345 Zoom = 63
7346 ZoomImage = 64
7347 Annotate = 65
7348 AnnotateImage = 66
7349 ColorFloodfill = 67
7350 ColorFloodfillImage= 68
7351 Composite = 69
7352 CompositeImage = 70
7353 Contrast = 71
7354 ContrastImage = 72
7355 CycleColormap = 73
7356 CycleColormapImage = 74
7357 Draw = 75
7358 DrawImage = 76
7359 Equalize = 77
7360 EqualizeImage = 78
7361 Gamma = 79
7362 GammaImage = 80
7363 Map = 81
7364 MapImage = 82
7365 MatteFloodfill = 83
7366 MatteFloodfillImage= 84
7367 Modulate = 85
7368 ModulateImage = 86
7369 Negate = 87
7370 NegateImage = 88
7371 Normalize = 89
7372 NormalizeImage = 90
7373 NumberColors = 91
7374 NumberColorsImage = 92
7375 Opaque = 93
7376 OpaqueImage = 94
7377 Quantize = 95
7378 QuantizeImage = 96
7379 Raise = 97
7380 RaiseImage = 98
7381 Segment = 99
7382 SegmentImage = 100
7383 Signature = 101
7384 SignatureImage = 102
7385 Solarize = 103
7386 SolarizeImage = 104
7387 Sync = 105
7388 SyncImage = 106
7389 Texture = 107
7390 TextureImage = 108
7391 Evaluate = 109
7392 EvaluateImage = 110
7393 Transparent = 111
7394 TransparentImage = 112
7395 Threshold = 113
7396 ThresholdImage = 114
7397 Charcoal = 115
7398 CharcoalImage = 116
7399 Trim = 117
7400 TrimImage = 118
7401 Wave = 119
7402 WaveImage = 120
7403 Separate = 121
7404 SeparateImage = 122
7405 Stereo = 125
7406 StereoImage = 126
7407 Stegano = 127
7408 SteganoImage = 128
7409 Deconstruct = 129
7410 DeconstructImage = 130
7411 GaussianBlur = 131
7412 GaussianBlurImage = 132
7413 Convolve = 133
7414 ConvolveImage = 134
7415 Profile = 135
7416 ProfileImage = 136
7417 UnsharpMask = 137
7418 UnsharpMaskImage = 138
7419 MotionBlur = 139
7420 MotionBlurImage = 140
7421 OrderedDither = 141
7422 OrderedDitherImage = 142
7423 Shave = 143
7424 ShaveImage = 144
7425 Level = 145
7426 LevelImage = 146
7427 Clip = 147
7428 ClipImage = 148
7429 AffineTransform = 149
7430 AffineTransformImage = 150
7431 Difference = 151
7432 DifferenceImage = 152
7433 AdaptiveThreshold = 153
7434 AdaptiveThresholdImage = 154
7435 Resample = 155
7436 ResampleImage = 156
7437 Describe = 157
7438 DescribeImage = 158
7439 BlackThreshold = 159
7440 BlackThresholdImage= 160
7441 WhiteThreshold = 161
7442 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007443 RotationalBlur = 163
7444 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007445 Thumbnail = 165
7446 ThumbnailImage = 166
7447 Strip = 167
7448 StripImage = 168
7449 Tint = 169
7450 TintImage = 170
7451 Channel = 171
7452 ChannelImage = 172
7453 Splice = 173
7454 SpliceImage = 174
7455 Posterize = 175
7456 PosterizeImage = 176
7457 Shadow = 177
7458 ShadowImage = 178
7459 Identify = 179
7460 IdentifyImage = 180
7461 SepiaTone = 181
7462 SepiaToneImage = 182
7463 SigmoidalContrast = 183
7464 SigmoidalContrastImage = 184
7465 Extent = 185
7466 ExtentImage = 186
7467 Vignette = 187
7468 VignetteImage = 188
7469 ContrastStretch = 189
7470 ContrastStretchImage = 190
7471 Sans0 = 191
7472 Sans0Image = 192
7473 Sans1 = 193
7474 Sans1Image = 194
7475 AdaptiveSharpen = 195
7476 AdaptiveSharpenImage = 196
7477 Transpose = 197
7478 TransposeImage = 198
7479 Transverse = 199
7480 TransverseImage = 200
7481 AutoOrient = 201
7482 AutoOrientImage = 202
7483 AdaptiveBlur = 203
7484 AdaptiveBlurImage = 204
7485 Sketch = 205
7486 SketchImage = 206
7487 UniqueColors = 207
7488 UniqueColorsImage = 208
7489 AdaptiveResize = 209
7490 AdaptiveResizeImage= 210
7491 ClipMask = 211
7492 ClipMaskImage = 212
7493 LinearStretch = 213
7494 LinearStretchImage = 214
7495 ColorMatrix = 215
7496 ColorMatrixImage = 216
7497 Mask = 217
7498 MaskImage = 218
7499 Polaroid = 219
7500 PolaroidImage = 220
7501 FloodfillPaint = 221
7502 FloodfillPaintImage= 222
7503 Distort = 223
7504 DistortImage = 224
7505 Clut = 225
7506 ClutImage = 226
7507 LiquidRescale = 227
7508 LiquidRescaleImage = 228
7509 Encipher = 229
7510 EncipherImage = 230
7511 Decipher = 231
7512 DecipherImage = 232
7513 Deskew = 233
7514 DeskewImage = 234
7515 Remap = 235
7516 RemapImage = 236
7517 SparseColor = 237
7518 SparseColorImage = 238
7519 Function = 239
7520 FunctionImage = 240
7521 SelectiveBlur = 241
7522 SelectiveBlurImage = 242
7523 HaldClut = 243
7524 HaldClutImage = 244
7525 BlueShift = 245
7526 BlueShiftImage = 246
7527 ForwardFourierTransform = 247
7528 ForwardFourierTransformImage = 248
7529 InverseFourierTransform = 249
7530 InverseFourierTransformImage = 250
7531 ColorDecisionList = 251
7532 ColorDecisionListImage = 252
7533 AutoGamma = 253
7534 AutoGammaImage = 254
7535 AutoLevel = 255
7536 AutoLevelImage = 256
7537 LevelColors = 257
7538 LevelImageColors = 258
7539 Clamp = 259
7540 ClampImage = 260
7541 BrightnessContrast = 261
7542 BrightnessContrastImage = 262
7543 Morphology = 263
7544 MorphologyImage = 264
Cristy3ca633e2016-02-13 12:49:01 -05007545 Mode = 265
7546 ModeImage = 266
7547 Statistic = 267
7548 StatisticImage = 268
7549 Perceptible = 269
7550 PerceptibleImage = 270
7551 Poly = 271
7552 PolyImage = 272
7553 Grayscale = 273
7554 GrayscaleImage = 274
7555 CannyEdge = 275
7556 CannyEdgeImage = 276
7557 HoughLine = 277
7558 HoughLineImage = 278
7559 MeanShift = 279
7560 MeanShiftImage = 280
7561 Kuwahara = 281
7562 KuwaharaImage = 282
7563 ConnectedComponent = 283
7564 ConnectedComponentImage = 284
7565 CopyPixels = 285
7566 CopyImagePixels = 286
Cristy5488c982016-02-13 14:07:50 -05007567 Color = 287
7568 ColorImage = 288
Cristy2d830ed2016-02-21 10:54:16 -05007569 WaveletDenoise = 289
7570 WaveletDenoiseImage= 290
Cristy99a57162016-12-05 11:47:57 -05007571 Colorspace = 291
7572 ColorspaceImage = 292
cristy4a3ce0a2013-08-03 20:06:59 +00007573 MogrifyRegion = 666
7574 PPCODE:
7575 {
7576 AffineMatrix
7577 affine,
7578 current;
7579
7580 char
7581 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007582 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007583
7584 ChannelType
7585 channel,
7586 channel_mask;
7587
7588 CompositeOperator
7589 compose;
7590
7591 const char
7592 *attribute,
7593 *value;
7594
7595 double
7596 angle;
7597
7598 ExceptionInfo
7599 *exception;
7600
7601 GeometryInfo
7602 geometry_info;
7603
7604 Image
7605 *image,
7606 *next,
7607 *region_image;
7608
7609 MagickBooleanType
7610 status;
7611
7612 MagickStatusType
7613 flags;
7614
7615 PixelInfo
7616 fill_color;
7617
7618 RectangleInfo
7619 geometry,
7620 region_info;
7621
7622 register ssize_t
7623 i;
7624
7625 ssize_t
7626 base,
7627 j,
7628 number_images;
7629
7630 struct Methods
7631 *rp;
7632
7633 struct PackageInfo
7634 *info;
7635
7636 SV
7637 *perl_exception,
7638 **pv,
7639 *reference,
7640 **reference_vector;
7641
7642 struct ArgumentList
7643 argument_list[MaxArguments];
7644
7645 PERL_UNUSED_VAR(ref);
7646 PERL_UNUSED_VAR(ix);
7647 exception=AcquireExceptionInfo();
7648 perl_exception=newSVpv("",0);
7649 reference_vector=NULL;
7650 region_image=NULL;
7651 number_images=0;
7652 base=2;
7653 if (sv_isobject(ST(0)) == 0)
7654 {
7655 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7656 PackageName);
7657 goto PerlException;
7658 }
7659 reference=SvRV(ST(0));
7660 region_info.width=0;
7661 region_info.height=0;
7662 region_info.x=0;
7663 region_info.y=0;
7664 region_image=(Image *) NULL;
7665 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7666 if (ix && (ix != 666))
7667 {
7668 /*
7669 Called as Method(...)
7670 */
7671 ix=(ix+1)/2;
7672 rp=(&Methods[ix-1]);
7673 attribute=rp->name;
7674 }
7675 else
7676 {
7677 /*
7678 Called as Mogrify("Method",...)
7679 */
7680 attribute=(char *) SvPV(ST(1),na);
7681 if (ix)
7682 {
7683 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7684 attribute=(char *) SvPV(ST(2),na);
7685 base++;
7686 }
7687 for (rp=Methods; ; rp++)
7688 {
7689 if (rp >= EndOf(Methods))
7690 {
7691 ThrowPerlException(exception,OptionError,
7692 "UnrecognizedPerlMagickMethod",attribute);
7693 goto PerlException;
7694 }
7695 if (strEQcase(attribute,rp->name))
7696 break;
7697 }
7698 ix=rp-Methods+1;
7699 base++;
7700 }
7701 if (image == (Image *) NULL)
7702 {
7703 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7704 goto PerlException;
7705 }
7706 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7707 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7708 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7709 {
7710 Arguments
7711 *pp,
7712 *qq;
7713
7714 ssize_t
7715 ssize_test;
7716
7717 struct ArgumentList
7718 *al;
7719
7720 SV
7721 *sv;
7722
7723 sv=NULL;
7724 ssize_test=0;
7725 pp=(Arguments *) NULL;
7726 qq=rp->arguments;
7727 if (i == items)
7728 {
7729 pp=rp->arguments,
7730 sv=ST(i-1);
7731 }
7732 else
7733 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7734 {
7735 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7736 break;
7737 if (strEQcase(attribute,qq->method) > ssize_test)
7738 {
7739 pp=qq;
7740 ssize_test=strEQcase(attribute,qq->method);
7741 }
7742 }
7743 if (pp == (Arguments *) NULL)
7744 {
7745 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7746 attribute);
7747 goto continue_outer_loop;
7748 }
7749 al=(&argument_list[pp-rp->arguments]);
7750 switch (pp->type)
7751 {
7752 case ArrayReference:
7753 {
7754 if (SvTYPE(sv) != SVt_RV)
7755 {
cristy151b66d2015-04-15 10:50:31 +00007756 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007757 "invalid %.60s value",pp->method);
7758 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7759 goto continue_outer_loop;
7760 }
7761 al->array_reference=SvRV(sv);
7762 break;
7763 }
7764 case RealReference:
7765 {
7766 al->real_reference=SvNV(sv);
7767 break;
7768 }
7769 case FileReference:
7770 {
7771 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7772 break;
7773 }
7774 case ImageReference:
7775 {
7776 if (!sv_isobject(sv) ||
7777 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7778 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7779 {
7780 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7781 PackageName);
7782 goto PerlException;
7783 }
7784 break;
7785 }
7786 case IntegerReference:
7787 {
7788 al->integer_reference=SvIV(sv);
7789 break;
7790 }
7791 case StringReference:
7792 {
7793 al->string_reference=(char *) SvPV(sv,al->length);
7794 if (sv_isobject(sv))
7795 al->image_reference=SetupList(aTHX_ SvRV(sv),
7796 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7797 break;
7798 }
7799 default:
7800 {
7801 /*
7802 Is a string; look up name.
7803 */
7804 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7805 {
7806 al->string_reference=(char *) SvPV(sv,al->length);
7807 al->integer_reference=(-1);
7808 break;
7809 }
7810 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7811 MagickFalse,SvPV(sv,na));
7812 if (pp->type == MagickChannelOptions)
7813 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7814 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7815 {
cristy151b66d2015-04-15 10:50:31 +00007816 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007817 "invalid %.60s value",pp->method);
7818 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7819 goto continue_outer_loop;
7820 }
7821 break;
7822 }
7823 }
7824 attribute_flag[pp-rp->arguments]++;
7825 continue_outer_loop: ;
7826 }
7827 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7828 pv=reference_vector;
7829 SetGeometryInfo(&geometry_info);
7830 channel=DefaultChannels;
7831 for (next=image; next; next=next->next)
7832 {
7833 image=next;
7834 SetGeometry(image,&geometry);
7835 if ((region_info.width*region_info.height) != 0)
7836 {
7837 region_image=image;
7838 image=CropImage(image,&region_info,exception);
7839 }
7840 switch (ix)
7841 {
7842 default:
7843 {
cristy151b66d2015-04-15 10:50:31 +00007844 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007845 ThrowPerlException(exception,OptionError,
7846 "UnrecognizedPerlMagickMethod",message);
7847 goto PerlException;
7848 }
7849 case 1: /* Comment */
7850 {
7851 if (attribute_flag[0] == 0)
7852 argument_list[0].string_reference=(char *) NULL;
7853 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7854 info ? info->image_info : (ImageInfo *) NULL,image,
7855 argument_list[0].string_reference,exception),exception);
7856 break;
7857 }
7858 case 2: /* Label */
7859 {
7860 if (attribute_flag[0] == 0)
7861 argument_list[0].string_reference=(char *) NULL;
7862 (void) SetImageProperty(image,"label",InterpretImageProperties(
7863 info ? info->image_info : (ImageInfo *) NULL,image,
7864 argument_list[0].string_reference,exception),exception);
7865 break;
7866 }
7867 case 3: /* AddNoise */
7868 {
7869 double
7870 attenuate;
7871
7872 if (attribute_flag[0] == 0)
7873 argument_list[0].integer_reference=UniformNoise;
7874 attenuate=1.0;
7875 if (attribute_flag[1] != 0)
7876 attenuate=argument_list[1].real_reference;
7877 if (attribute_flag[2] != 0)
7878 channel=(ChannelType) argument_list[2].integer_reference;
7879 channel_mask=SetImageChannelMask(image,channel);
7880 image=AddNoiseImage(image,(NoiseType)
7881 argument_list[0].integer_reference,attenuate,exception);
7882 if (image != (Image *) NULL)
7883 (void) SetImageChannelMask(image,channel_mask);
7884 break;
7885 }
7886 case 4: /* Colorize */
7887 {
7888 PixelInfo
7889 target;
7890
7891 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7892 0,0,&target,exception);
7893 if (attribute_flag[0] != 0)
7894 (void) QueryColorCompliance(argument_list[0].string_reference,
7895 AllCompliance,&target,exception);
7896 if (attribute_flag[1] == 0)
7897 argument_list[1].string_reference="100%";
7898 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7899 exception);
7900 break;
7901 }
7902 case 5: /* Border */
7903 {
7904 CompositeOperator
7905 compose;
7906
7907 geometry.width=0;
7908 geometry.height=0;
7909 if (attribute_flag[0] != 0)
7910 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7911 &geometry,exception);
7912 if (attribute_flag[1] != 0)
7913 geometry.width=argument_list[1].integer_reference;
7914 if (attribute_flag[2] != 0)
7915 geometry.height=argument_list[2].integer_reference;
7916 if (attribute_flag[3] != 0)
7917 QueryColorCompliance(argument_list[3].string_reference,
7918 AllCompliance,&image->border_color,exception);
7919 if (attribute_flag[4] != 0)
7920 QueryColorCompliance(argument_list[4].string_reference,
7921 AllCompliance,&image->border_color,exception);
7922 if (attribute_flag[5] != 0)
7923 QueryColorCompliance(argument_list[5].string_reference,
7924 AllCompliance,&image->border_color,exception);
7925 compose=image->compose;
7926 if (attribute_flag[6] != 0)
7927 compose=(CompositeOperator) argument_list[6].integer_reference;
7928 image=BorderImage(image,&geometry,compose,exception);
7929 break;
7930 }
7931 case 6: /* Blur */
7932 {
7933 if (attribute_flag[0] != 0)
7934 {
7935 flags=ParseGeometry(argument_list[0].string_reference,
7936 &geometry_info);
7937 if ((flags & SigmaValue) == 0)
7938 geometry_info.sigma=1.0;
7939 }
7940 if (attribute_flag[1] != 0)
7941 geometry_info.rho=argument_list[1].real_reference;
7942 if (attribute_flag[2] != 0)
7943 geometry_info.sigma=argument_list[2].real_reference;
7944 if (attribute_flag[3] != 0)
7945 channel=(ChannelType) argument_list[3].integer_reference;
7946 channel_mask=SetImageChannelMask(image,channel);
7947 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
7948 exception);
7949 if (image != (Image *) NULL)
7950 (void) SetImageChannelMask(image,channel_mask);
7951 break;
7952 }
7953 case 7: /* Chop */
7954 {
cristy260bd762014-08-15 12:46:34 +00007955 if (attribute_flag[5] != 0)
7956 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00007957 if (attribute_flag[0] != 0)
7958 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7959 &geometry,exception);
7960 if (attribute_flag[1] != 0)
7961 geometry.width=argument_list[1].integer_reference;
7962 if (attribute_flag[2] != 0)
7963 geometry.height=argument_list[2].integer_reference;
7964 if (attribute_flag[3] != 0)
7965 geometry.x=argument_list[3].integer_reference;
7966 if (attribute_flag[4] != 0)
7967 geometry.y=argument_list[4].integer_reference;
7968 image=ChopImage(image,&geometry,exception);
7969 break;
7970 }
7971 case 8: /* Crop */
7972 {
7973 if (attribute_flag[6] != 0)
7974 image->gravity=(GravityType) argument_list[6].integer_reference;
7975 if (attribute_flag[0] != 0)
7976 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7977 &geometry,exception);
7978 if (attribute_flag[1] != 0)
7979 geometry.width=argument_list[1].integer_reference;
7980 if (attribute_flag[2] != 0)
7981 geometry.height=argument_list[2].integer_reference;
7982 if (attribute_flag[3] != 0)
7983 geometry.x=argument_list[3].integer_reference;
7984 if (attribute_flag[4] != 0)
7985 geometry.y=argument_list[4].integer_reference;
7986 if (attribute_flag[5] != 0)
7987 image->fuzz=StringToDoubleInterval(
7988 argument_list[5].string_reference,(double) QuantumRange+1.0);
7989 image=CropImage(image,&geometry,exception);
7990 break;
7991 }
7992 case 9: /* Despeckle */
7993 {
7994 image=DespeckleImage(image,exception);
7995 break;
7996 }
7997 case 10: /* Edge */
7998 {
7999 if (attribute_flag[0] != 0)
8000 geometry_info.rho=argument_list[0].real_reference;
8001 image=EdgeImage(image,geometry_info.rho,exception);
8002 break;
8003 }
8004 case 11: /* Emboss */
8005 {
8006 if (attribute_flag[0] != 0)
8007 {
8008 flags=ParseGeometry(argument_list[0].string_reference,
8009 &geometry_info);
8010 if ((flags & SigmaValue) == 0)
8011 geometry_info.sigma=1.0;
8012 }
8013 if (attribute_flag[1] != 0)
8014 geometry_info.rho=argument_list[1].real_reference;
8015 if (attribute_flag[2] != 0)
8016 geometry_info.sigma=argument_list[2].real_reference;
8017 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8018 exception);
8019 break;
8020 }
8021 case 12: /* Enhance */
8022 {
8023 image=EnhanceImage(image,exception);
8024 break;
8025 }
8026 case 13: /* Flip */
8027 {
8028 image=FlipImage(image,exception);
8029 break;
8030 }
8031 case 14: /* Flop */
8032 {
8033 image=FlopImage(image,exception);
8034 break;
8035 }
8036 case 15: /* Frame */
8037 {
8038 CompositeOperator
8039 compose;
8040
8041 FrameInfo
8042 frame_info;
8043
8044 if (attribute_flag[0] != 0)
8045 {
8046 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8047 &geometry,exception);
8048 frame_info.width=geometry.width;
8049 frame_info.height=geometry.height;
8050 frame_info.outer_bevel=geometry.x;
8051 frame_info.inner_bevel=geometry.y;
8052 }
8053 if (attribute_flag[1] != 0)
8054 frame_info.width=argument_list[1].integer_reference;
8055 if (attribute_flag[2] != 0)
8056 frame_info.height=argument_list[2].integer_reference;
8057 if (attribute_flag[3] != 0)
8058 frame_info.inner_bevel=argument_list[3].integer_reference;
8059 if (attribute_flag[4] != 0)
8060 frame_info.outer_bevel=argument_list[4].integer_reference;
8061 if (attribute_flag[5] != 0)
8062 QueryColorCompliance(argument_list[5].string_reference,
8063 AllCompliance,&fill_color,exception);
8064 if (attribute_flag[6] != 0)
8065 QueryColorCompliance(argument_list[6].string_reference,
8066 AllCompliance,&fill_color,exception);
8067 frame_info.x=(ssize_t) frame_info.width;
8068 frame_info.y=(ssize_t) frame_info.height;
8069 frame_info.width=image->columns+2*frame_info.x;
8070 frame_info.height=image->rows+2*frame_info.y;
8071 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
Cristy8645e042016-02-03 16:35:29 -05008072 image->alpha_color=fill_color;
cristy4a3ce0a2013-08-03 20:06:59 +00008073 compose=image->compose;
8074 if (attribute_flag[7] != 0)
8075 compose=(CompositeOperator) argument_list[7].integer_reference;
8076 image=FrameImage(image,&frame_info,compose,exception);
8077 break;
8078 }
8079 case 16: /* Implode */
8080 {
8081 PixelInterpolateMethod
8082 method;
8083
8084 if (attribute_flag[0] == 0)
8085 argument_list[0].real_reference=0.5;
8086 method=UndefinedInterpolatePixel;
8087 if (attribute_flag[1] != 0)
8088 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8089 image=ImplodeImage(image,argument_list[0].real_reference,
8090 method,exception);
8091 break;
8092 }
8093 case 17: /* Magnify */
8094 {
8095 image=MagnifyImage(image,exception);
8096 break;
8097 }
8098 case 18: /* MedianFilter */
8099 {
8100 if (attribute_flag[0] != 0)
8101 {
8102 flags=ParseGeometry(argument_list[0].string_reference,
8103 &geometry_info);
8104 if ((flags & SigmaValue) == 0)
8105 geometry_info.sigma=geometry_info.rho;
8106 }
8107 if (attribute_flag[1] != 0)
8108 geometry_info.rho=argument_list[1].real_reference;
8109 if (attribute_flag[2] != 0)
8110 geometry_info.sigma=argument_list[2].real_reference;
8111 if (attribute_flag[3] != 0)
8112 channel=(ChannelType) argument_list[3].integer_reference;
8113 channel_mask=SetImageChannelMask(image,channel);
8114 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8115 (size_t) geometry_info.sigma,exception);
8116 if (image != (Image *) NULL)
8117 (void) SetImageChannelMask(image,channel_mask);
8118 break;
8119 }
8120 case 19: /* Minify */
8121 {
8122 image=MinifyImage(image,exception);
8123 break;
8124 }
8125 case 20: /* OilPaint */
8126 {
8127 if (attribute_flag[0] == 0)
8128 argument_list[0].real_reference=0.0;
8129 if (attribute_flag[1] == 0)
8130 argument_list[1].real_reference=1.0;
8131 image=OilPaintImage(image,argument_list[0].real_reference,
8132 argument_list[1].real_reference,exception);
8133 break;
8134 }
8135 case 21: /* ReduceNoise */
8136 {
8137 if (attribute_flag[0] != 0)
8138 {
8139 flags=ParseGeometry(argument_list[0].string_reference,
8140 &geometry_info);
8141 if ((flags & SigmaValue) == 0)
8142 geometry_info.sigma=1.0;
8143 }
8144 if (attribute_flag[1] != 0)
8145 geometry_info.rho=argument_list[1].real_reference;
8146 if (attribute_flag[2] != 0)
8147 geometry_info.sigma=argument_list[2].real_reference;
8148 if (attribute_flag[3] != 0)
8149 channel=(ChannelType) argument_list[3].integer_reference;
8150 channel_mask=SetImageChannelMask(image,channel);
8151 image=StatisticImage(image,NonpeakStatistic,(size_t)
8152 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8153 if (image != (Image *) NULL)
8154 (void) SetImageChannelMask(image,channel_mask);
8155 break;
8156 }
8157 case 22: /* Roll */
8158 {
8159 if (attribute_flag[0] != 0)
8160 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8161 &geometry,exception);
8162 if (attribute_flag[1] != 0)
8163 geometry.x=argument_list[1].integer_reference;
8164 if (attribute_flag[2] != 0)
8165 geometry.y=argument_list[2].integer_reference;
8166 image=RollImage(image,geometry.x,geometry.y,exception);
8167 break;
8168 }
8169 case 23: /* Rotate */
8170 {
8171 if (attribute_flag[0] == 0)
8172 argument_list[0].real_reference=90.0;
8173 if (attribute_flag[1] != 0)
8174 {
8175 QueryColorCompliance(argument_list[1].string_reference,
8176 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008177 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8178 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008179 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8180 }
8181 image=RotateImage(image,argument_list[0].real_reference,exception);
8182 break;
8183 }
8184 case 24: /* Sample */
8185 {
8186 if (attribute_flag[0] != 0)
8187 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8188 &geometry,exception);
8189 if (attribute_flag[1] != 0)
8190 geometry.width=argument_list[1].integer_reference;
8191 if (attribute_flag[2] != 0)
8192 geometry.height=argument_list[2].integer_reference;
8193 image=SampleImage(image,geometry.width,geometry.height,exception);
8194 break;
8195 }
8196 case 25: /* Scale */
8197 {
8198 if (attribute_flag[0] != 0)
8199 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8200 &geometry,exception);
8201 if (attribute_flag[1] != 0)
8202 geometry.width=argument_list[1].integer_reference;
8203 if (attribute_flag[2] != 0)
8204 geometry.height=argument_list[2].integer_reference;
8205 image=ScaleImage(image,geometry.width,geometry.height,exception);
8206 break;
8207 }
8208 case 26: /* Shade */
8209 {
8210 if (attribute_flag[0] != 0)
8211 {
8212 flags=ParseGeometry(argument_list[0].string_reference,
8213 &geometry_info);
8214 if ((flags & SigmaValue) == 0)
8215 geometry_info.sigma=0.0;
8216 }
8217 if (attribute_flag[1] != 0)
8218 geometry_info.rho=argument_list[1].real_reference;
8219 if (attribute_flag[2] != 0)
8220 geometry_info.sigma=argument_list[2].real_reference;
8221 image=ShadeImage(image,
8222 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8223 geometry_info.rho,geometry_info.sigma,exception);
8224 break;
8225 }
8226 case 27: /* Sharpen */
8227 {
8228 if (attribute_flag[0] != 0)
8229 {
8230 flags=ParseGeometry(argument_list[0].string_reference,
8231 &geometry_info);
8232 if ((flags & SigmaValue) == 0)
8233 geometry_info.sigma=1.0;
8234 }
8235 if (attribute_flag[1] != 0)
8236 geometry_info.rho=argument_list[1].real_reference;
8237 if (attribute_flag[2] != 0)
8238 geometry_info.sigma=argument_list[2].real_reference;
8239 if (attribute_flag[3] != 0)
8240 channel=(ChannelType) argument_list[3].integer_reference;
8241 channel_mask=SetImageChannelMask(image,channel);
8242 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8243 exception);
8244 if (image != (Image *) NULL)
8245 (void) SetImageChannelMask(image,channel_mask);
8246 break;
8247 }
8248 case 28: /* Shear */
8249 {
8250 if (attribute_flag[0] != 0)
8251 {
8252 flags=ParseGeometry(argument_list[0].string_reference,
8253 &geometry_info);
8254 if ((flags & SigmaValue) == 0)
8255 geometry_info.sigma=geometry_info.rho;
8256 }
8257 if (attribute_flag[1] != 0)
8258 geometry_info.rho=argument_list[1].real_reference;
8259 if (attribute_flag[2] != 0)
8260 geometry_info.sigma=argument_list[2].real_reference;
8261 if (attribute_flag[3] != 0)
8262 QueryColorCompliance(argument_list[3].string_reference,
8263 AllCompliance,&image->background_color,exception);
8264 if (attribute_flag[4] != 0)
8265 QueryColorCompliance(argument_list[4].string_reference,
8266 AllCompliance,&image->background_color,exception);
8267 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8268 exception);
8269 break;
8270 }
8271 case 29: /* Spread */
8272 {
Cristye3319c12015-08-24 07:11:48 -04008273 PixelInterpolateMethod
8274 method;
8275
cristy4a3ce0a2013-08-03 20:06:59 +00008276 if (attribute_flag[0] == 0)
8277 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008278 method=UndefinedInterpolatePixel;
8279 if (attribute_flag[1] != 0)
8280 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8281 image=SpreadImage(image,method,argument_list[0].real_reference,
8282 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008283 break;
8284 }
8285 case 30: /* Swirl */
8286 {
8287 PixelInterpolateMethod
8288 method;
8289
8290 if (attribute_flag[0] == 0)
8291 argument_list[0].real_reference=50.0;
8292 method=UndefinedInterpolatePixel;
8293 if (attribute_flag[1] != 0)
8294 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8295 image=SwirlImage(image,argument_list[0].real_reference,
8296 method,exception);
8297 break;
8298 }
8299 case 31: /* Resize */
8300 case 32: /* Zoom */
8301 {
8302 if (attribute_flag[0] != 0)
8303 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8304 &geometry,exception);
8305 if (attribute_flag[1] != 0)
8306 geometry.width=argument_list[1].integer_reference;
8307 if (attribute_flag[2] != 0)
8308 geometry.height=argument_list[2].integer_reference;
8309 if (attribute_flag[3] == 0)
8310 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8311 if (attribute_flag[4] != 0)
8312 SetImageArtifact(image,"filter:support",
8313 argument_list[4].string_reference);
8314 image=ResizeImage(image,geometry.width,geometry.height,
Cristy8645e042016-02-03 16:35:29 -05008315 (FilterType) argument_list[3].integer_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00008316 exception);
8317 break;
8318 }
8319 case 33: /* Annotate */
8320 {
8321 DrawInfo
8322 *draw_info;
8323
8324 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8325 (DrawInfo *) NULL);
8326 if (attribute_flag[0] != 0)
8327 {
8328 char
8329 *text;
8330
8331 text=InterpretImageProperties(info ? info->image_info :
8332 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8333 exception);
8334 (void) CloneString(&draw_info->text,text);
8335 text=DestroyString(text);
8336 }
8337 if (attribute_flag[1] != 0)
8338 (void) CloneString(&draw_info->font,
8339 argument_list[1].string_reference);
8340 if (attribute_flag[2] != 0)
8341 draw_info->pointsize=argument_list[2].real_reference;
8342 if (attribute_flag[3] != 0)
8343 (void) CloneString(&draw_info->density,
8344 argument_list[3].string_reference);
8345 if (attribute_flag[4] != 0)
8346 (void) QueryColorCompliance(argument_list[4].string_reference,
8347 AllCompliance,&draw_info->undercolor,exception);
8348 if (attribute_flag[5] != 0)
8349 {
8350 (void) QueryColorCompliance(argument_list[5].string_reference,
8351 AllCompliance,&draw_info->stroke,exception);
8352 if (argument_list[5].image_reference != (Image *) NULL)
8353 draw_info->stroke_pattern=CloneImage(
8354 argument_list[5].image_reference,0,0,MagickTrue,exception);
8355 }
8356 if (attribute_flag[6] != 0)
8357 {
8358 (void) QueryColorCompliance(argument_list[6].string_reference,
8359 AllCompliance,&draw_info->fill,exception);
8360 if (argument_list[6].image_reference != (Image *) NULL)
8361 draw_info->fill_pattern=CloneImage(
8362 argument_list[6].image_reference,0,0,MagickTrue,exception);
8363 }
8364 if (attribute_flag[7] != 0)
8365 {
8366 (void) CloneString(&draw_info->geometry,
8367 argument_list[7].string_reference);
8368 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8369 &geometry,exception);
8370 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8371 geometry_info.sigma=geometry_info.xi;
8372 }
8373 if (attribute_flag[8] != 0)
8374 (void) QueryColorCompliance(argument_list[8].string_reference,
8375 AllCompliance,&draw_info->fill,exception);
8376 if (attribute_flag[11] != 0)
8377 draw_info->gravity=(GravityType)
8378 argument_list[11].integer_reference;
8379 if (attribute_flag[25] != 0)
8380 {
8381 AV
8382 *av;
8383
8384 av=(AV *) argument_list[25].array_reference;
8385 if ((av_len(av) != 3) && (av_len(av) != 5))
8386 {
8387 ThrowPerlException(exception,OptionError,
8388 "affine matrix must have 4 or 6 elements",PackageName);
8389 goto PerlException;
8390 }
8391 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8392 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8393 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8394 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8395 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8396 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8397 {
8398 ThrowPerlException(exception,OptionError,
8399 "affine matrix is singular",PackageName);
8400 goto PerlException;
8401 }
8402 if (av_len(av) == 5)
8403 {
8404 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8405 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8406 }
8407 }
8408 for (j=12; j < 17; j++)
8409 {
8410 if (attribute_flag[j] == 0)
8411 continue;
8412 value=argument_list[j].string_reference;
8413 angle=argument_list[j].real_reference;
8414 current=draw_info->affine;
8415 GetAffineMatrix(&affine);
8416 switch (j)
8417 {
8418 case 12:
8419 {
8420 /*
8421 Translate.
8422 */
8423 flags=ParseGeometry(value,&geometry_info);
8424 affine.tx=geometry_info.xi;
8425 affine.ty=geometry_info.psi;
8426 if ((flags & PsiValue) == 0)
8427 affine.ty=affine.tx;
8428 break;
8429 }
8430 case 13:
8431 {
8432 /*
8433 Scale.
8434 */
8435 flags=ParseGeometry(value,&geometry_info);
8436 affine.sx=geometry_info.rho;
8437 affine.sy=geometry_info.sigma;
8438 if ((flags & SigmaValue) == 0)
8439 affine.sy=affine.sx;
8440 break;
8441 }
8442 case 14:
8443 {
8444 /*
8445 Rotate.
8446 */
8447 if (angle == 0.0)
8448 break;
8449 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8450 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8451 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8452 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8453 break;
8454 }
8455 case 15:
8456 {
8457 /*
8458 SkewX.
8459 */
8460 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8461 break;
8462 }
8463 case 16:
8464 {
8465 /*
8466 SkewY.
8467 */
8468 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8469 break;
8470 }
8471 }
8472 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8473 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8474 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8475 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8476 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8477 current.tx;
8478 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8479 current.ty;
8480 }
8481 if (attribute_flag[9] == 0)
8482 argument_list[9].real_reference=0.0;
8483 if (attribute_flag[10] == 0)
8484 argument_list[10].real_reference=0.0;
8485 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8486 {
8487 char
cristy151b66d2015-04-15 10:50:31 +00008488 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008489
cristy151b66d2015-04-15 10:50:31 +00008490 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008491 (double) argument_list[9].real_reference+draw_info->affine.tx,
8492 (double) argument_list[10].real_reference+draw_info->affine.ty);
8493 (void) CloneString(&draw_info->geometry,geometry);
8494 }
8495 if (attribute_flag[17] != 0)
8496 draw_info->stroke_width=argument_list[17].real_reference;
8497 if (attribute_flag[18] != 0)
8498 {
8499 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8500 MagickTrue : MagickFalse;
8501 draw_info->stroke_antialias=draw_info->text_antialias;
8502 }
8503 if (attribute_flag[19] != 0)
8504 (void) CloneString(&draw_info->family,
8505 argument_list[19].string_reference);
8506 if (attribute_flag[20] != 0)
8507 draw_info->style=(StyleType) argument_list[20].integer_reference;
8508 if (attribute_flag[21] != 0)
8509 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8510 if (attribute_flag[22] != 0)
8511 draw_info->weight=argument_list[22].integer_reference;
8512 if (attribute_flag[23] != 0)
8513 draw_info->align=(AlignType) argument_list[23].integer_reference;
8514 if (attribute_flag[24] != 0)
8515 (void) CloneString(&draw_info->encoding,
8516 argument_list[24].string_reference);
8517 if (attribute_flag[25] != 0)
8518 draw_info->fill_pattern=CloneImage(
8519 argument_list[25].image_reference,0,0,MagickTrue,exception);
8520 if (attribute_flag[26] != 0)
8521 draw_info->fill_pattern=CloneImage(
8522 argument_list[26].image_reference,0,0,MagickTrue,exception);
8523 if (attribute_flag[27] != 0)
8524 draw_info->stroke_pattern=CloneImage(
8525 argument_list[27].image_reference,0,0,MagickTrue,exception);
8526 if (attribute_flag[29] != 0)
8527 draw_info->kerning=argument_list[29].real_reference;
8528 if (attribute_flag[30] != 0)
8529 draw_info->interline_spacing=argument_list[30].real_reference;
8530 if (attribute_flag[31] != 0)
8531 draw_info->interword_spacing=argument_list[31].real_reference;
8532 if (attribute_flag[32] != 0)
8533 draw_info->direction=(DirectionType)
8534 argument_list[32].integer_reference;
8535 (void) AnnotateImage(image,draw_info,exception);
8536 draw_info=DestroyDrawInfo(draw_info);
8537 break;
8538 }
8539 case 34: /* ColorFloodfill */
8540 {
8541 DrawInfo
8542 *draw_info;
8543
8544 MagickBooleanType
8545 invert;
8546
8547 PixelInfo
8548 target;
8549
8550 draw_info=CloneDrawInfo(info ? info->image_info :
8551 (ImageInfo *) NULL,(DrawInfo *) NULL);
8552 if (attribute_flag[0] != 0)
8553 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8554 &geometry,exception);
8555 if (attribute_flag[1] != 0)
8556 geometry.x=argument_list[1].integer_reference;
8557 if (attribute_flag[2] != 0)
8558 geometry.y=argument_list[2].integer_reference;
8559 if (attribute_flag[3] != 0)
8560 (void) QueryColorCompliance(argument_list[3].string_reference,
8561 AllCompliance,&draw_info->fill,exception);
8562 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8563 geometry.x,geometry.y,&target,exception);
8564 invert=MagickFalse;
8565 if (attribute_flag[4] != 0)
8566 {
8567 QueryColorCompliance(argument_list[4].string_reference,
8568 AllCompliance,&target,exception);
8569 invert=MagickTrue;
8570 }
8571 if (attribute_flag[5] != 0)
8572 image->fuzz=StringToDoubleInterval(
8573 argument_list[5].string_reference,(double) QuantumRange+1.0);
8574 if (attribute_flag[6] != 0)
8575 invert=(MagickBooleanType) argument_list[6].integer_reference;
8576 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8577 geometry.y,invert,exception);
8578 draw_info=DestroyDrawInfo(draw_info);
8579 break;
8580 }
8581 case 35: /* Composite */
8582 {
8583 char
cristy151b66d2015-04-15 10:50:31 +00008584 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008585
8586 Image
8587 *composite_image,
8588 *rotate_image;
8589
8590 MagickBooleanType
8591 clip_to_self;
8592
8593 compose=OverCompositeOp;
8594 if (attribute_flag[0] != 0)
8595 composite_image=argument_list[0].image_reference;
8596 else
8597 {
8598 ThrowPerlException(exception,OptionError,
8599 "CompositeImageRequired",PackageName);
8600 goto PerlException;
8601 }
8602 /*
8603 Parameter Handling used for BOTH normal and tiled composition.
8604 */
8605 if (attribute_flag[1] != 0) /* compose */
8606 compose=(CompositeOperator) argument_list[1].integer_reference;
8607 if (attribute_flag[6] != 0) /* opacity */
8608 {
8609 if (compose != DissolveCompositeOp)
8610 (void) SetImageAlpha(composite_image,(Quantum)
8611 StringToDoubleInterval(argument_list[6].string_reference,
8612 (double) QuantumRange+1.0),exception);
8613 else
8614 {
8615 CacheView
8616 *composite_view;
8617
8618 double
8619 opacity;
8620
8621 MagickBooleanType
8622 sync;
8623
8624 register ssize_t
8625 x;
8626
8627 register Quantum
8628 *q;
8629
8630 ssize_t
8631 y;
8632
8633 /*
8634 Handle dissolve composite operator (patch by
8635 Kevin A. McGrail).
8636 */
8637 (void) CloneString(&image->geometry,
8638 argument_list[6].string_reference);
8639 opacity=(Quantum) StringToDoubleInterval(
8640 argument_list[6].string_reference,(double) QuantumRange+
8641 1.0);
cristy17f11b02014-12-20 19:37:04 +00008642 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008643 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8644 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8645 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8646 {
8647 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8648 composite_image->columns,1,exception);
8649 for (x=0; x < (ssize_t) composite_image->columns; x++)
8650 {
8651 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8652 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8653 q);
8654 q+=GetPixelChannels(composite_image);
8655 }
8656 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8657 if (sync == MagickFalse)
8658 break;
8659 }
8660 composite_view=DestroyCacheView(composite_view);
8661 }
8662 }
8663 if (attribute_flag[9] != 0) /* "color=>" */
8664 QueryColorCompliance(argument_list[9].string_reference,
8665 AllCompliance,&composite_image->background_color,exception);
8666 if (attribute_flag[12] != 0) /* "interpolate=>" */
8667 image->interpolate=(PixelInterpolateMethod)
8668 argument_list[12].integer_reference;
8669 if (attribute_flag[13] != 0) /* "args=>" */
8670 (void) SetImageArtifact(composite_image,"compose:args",
8671 argument_list[13].string_reference);
8672 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8673 (void) SetImageArtifact(composite_image,"compose:args",
8674 argument_list[14].string_reference);
8675 clip_to_self=MagickTrue;
8676 if (attribute_flag[15] != 0)
8677 clip_to_self=(MagickBooleanType)
8678 argument_list[15].integer_reference;
8679 /*
8680 Tiling Composition (with orthogonal rotate).
8681 */
8682 rotate_image=(Image *) NULL;
8683 if (attribute_flag[8] != 0) /* "rotate=>" */
8684 {
8685 /*
8686 Rotate image.
8687 */
8688 rotate_image=RotateImage(composite_image,
8689 argument_list[8].real_reference,exception);
8690 if (rotate_image == (Image *) NULL)
8691 break;
8692 }
8693 if ((attribute_flag[7] != 0) &&
8694 (argument_list[7].integer_reference != 0)) /* tile */
8695 {
8696 ssize_t
8697 x,
8698 y;
8699
8700 /*
8701 Tile the composite image.
8702 */
8703 if (attribute_flag[8] != 0) /* "tile=>" */
8704 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8705 "false");
8706 else
8707 (void) SetImageArtifact(composite_image,
8708 "compose:outside-overlay","false");
8709 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8710 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8711 {
8712 if (attribute_flag[8] != 0) /* rotate */
8713 (void) CompositeImage(image,rotate_image,compose,
8714 MagickTrue,x,y,exception);
8715 else
8716 (void) CompositeImage(image,composite_image,compose,
8717 MagickTrue,x,y,exception);
8718 }
8719 if (attribute_flag[8] != 0) /* rotate */
8720 rotate_image=DestroyImage(rotate_image);
8721 break;
8722 }
8723 /*
8724 Parameter Handling used used ONLY for normal composition.
8725 */
8726 if (attribute_flag[5] != 0) /* gravity */
8727 image->gravity=(GravityType) argument_list[5].integer_reference;
8728 if (attribute_flag[2] != 0) /* geometry offset */
8729 {
8730 SetGeometry(image,&geometry);
8731 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8732 &geometry);
8733 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8734 &geometry);
8735 }
8736 if (attribute_flag[3] != 0) /* x offset */
8737 geometry.x=argument_list[3].integer_reference;
8738 if (attribute_flag[4] != 0) /* y offset */
8739 geometry.y=argument_list[4].integer_reference;
8740 if (attribute_flag[10] != 0) /* mask */
8741 {
8742 if ((image->compose == DisplaceCompositeOp) ||
8743 (image->compose == DistortCompositeOp))
8744 {
8745 /*
8746 Merge Y displacement into X displacement image.
8747 */
8748 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8749 exception);
8750 (void) CompositeImage(composite_image,
8751 argument_list[10].image_reference,CopyGreenCompositeOp,
8752 MagickTrue,0,0,exception);
8753 }
8754 else
8755 {
8756 Image
8757 *mask_image;
8758
8759 /*
8760 Set a blending mask for the composition.
8761 */
8762 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8763 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008764 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008765 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008766 mask_image=DestroyImage(mask_image);
8767 }
8768 }
8769 if (attribute_flag[11] != 0) /* channel */
8770 channel=(ChannelType) argument_list[11].integer_reference;
8771 /*
8772 Composite two images (normal composition).
8773 */
cristy151b66d2015-04-15 10:50:31 +00008774 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008775 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8776 (double) composite_image->rows,(double) geometry.x,(double)
8777 geometry.y);
8778 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8779 exception);
8780 channel_mask=SetImageChannelMask(image,channel);
8781 if (attribute_flag[8] == 0) /* no rotate */
8782 CompositeImage(image,composite_image,compose,clip_to_self,
8783 geometry.x,geometry.y,exception);
8784 else
8785 {
8786 /*
8787 Position adjust rotated image then composite.
8788 */
8789 geometry.x-=(ssize_t) (rotate_image->columns-
8790 composite_image->columns)/2;
8791 geometry.y-=(ssize_t) (rotate_image->rows-
8792 composite_image->rows)/2;
8793 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8794 geometry.y,exception);
8795 rotate_image=DestroyImage(rotate_image);
8796 }
8797 if (attribute_flag[10] != 0) /* mask */
8798 {
8799 if ((image->compose == DisplaceCompositeOp) ||
8800 (image->compose == DistortCompositeOp))
8801 composite_image=DestroyImage(composite_image);
8802 else
cristy1f7ffb72015-07-29 11:07:03 +00008803 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008804 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008805 }
8806 (void) SetImageChannelMask(image,channel_mask);
8807 break;
8808 }
8809 case 36: /* Contrast */
8810 {
8811 if (attribute_flag[0] == 0)
8812 argument_list[0].integer_reference=0;
8813 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8814 MagickTrue : MagickFalse,exception);
8815 break;
8816 }
8817 case 37: /* CycleColormap */
8818 {
8819 if (attribute_flag[0] == 0)
8820 argument_list[0].integer_reference=6;
8821 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8822 exception);
8823 break;
8824 }
8825 case 38: /* Draw */
8826 {
8827 DrawInfo
8828 *draw_info;
8829
8830 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8831 (DrawInfo *) NULL);
8832 (void) CloneString(&draw_info->primitive,"point");
8833 if (attribute_flag[0] != 0)
8834 {
8835 if (argument_list[0].integer_reference < 0)
8836 (void) CloneString(&draw_info->primitive,
8837 argument_list[0].string_reference);
8838 else
8839 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8840 MagickPrimitiveOptions,argument_list[0].integer_reference));
8841 }
8842 if (attribute_flag[1] != 0)
8843 {
8844 if (LocaleCompare(draw_info->primitive,"path") == 0)
8845 {
8846 (void) ConcatenateString(&draw_info->primitive," '");
8847 ConcatenateString(&draw_info->primitive,
8848 argument_list[1].string_reference);
8849 (void) ConcatenateString(&draw_info->primitive,"'");
8850 }
8851 else
8852 {
8853 (void) ConcatenateString(&draw_info->primitive," ");
8854 ConcatenateString(&draw_info->primitive,
8855 argument_list[1].string_reference);
8856 }
8857 }
8858 if (attribute_flag[2] != 0)
8859 {
8860 (void) ConcatenateString(&draw_info->primitive," ");
8861 (void) ConcatenateString(&draw_info->primitive,
8862 CommandOptionToMnemonic(MagickMethodOptions,
8863 argument_list[2].integer_reference));
8864 }
8865 if (attribute_flag[3] != 0)
8866 {
8867 (void) QueryColorCompliance(argument_list[3].string_reference,
8868 AllCompliance,&draw_info->stroke,exception);
8869 if (argument_list[3].image_reference != (Image *) NULL)
8870 draw_info->stroke_pattern=CloneImage(
8871 argument_list[3].image_reference,0,0,MagickTrue,exception);
8872 }
8873 if (attribute_flag[4] != 0)
8874 {
8875 (void) QueryColorCompliance(argument_list[4].string_reference,
8876 AllCompliance,&draw_info->fill,exception);
8877 if (argument_list[4].image_reference != (Image *) NULL)
8878 draw_info->fill_pattern=CloneImage(
8879 argument_list[4].image_reference,0,0,MagickTrue,exception);
8880 }
8881 if (attribute_flag[5] != 0)
8882 draw_info->stroke_width=argument_list[5].real_reference;
8883 if (attribute_flag[6] != 0)
8884 (void) CloneString(&draw_info->font,
8885 argument_list[6].string_reference);
8886 if (attribute_flag[7] != 0)
8887 (void) QueryColorCompliance(argument_list[7].string_reference,
8888 AllCompliance,&draw_info->border_color,exception);
8889 if (attribute_flag[8] != 0)
8890 draw_info->affine.tx=argument_list[8].real_reference;
8891 if (attribute_flag[9] != 0)
8892 draw_info->affine.ty=argument_list[9].real_reference;
8893 if (attribute_flag[20] != 0)
8894 {
8895 AV
8896 *av;
8897
8898 av=(AV *) argument_list[20].array_reference;
8899 if ((av_len(av) != 3) && (av_len(av) != 5))
8900 {
8901 ThrowPerlException(exception,OptionError,
8902 "affine matrix must have 4 or 6 elements",PackageName);
8903 goto PerlException;
8904 }
8905 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8906 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8907 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8908 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8909 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8910 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8911 {
8912 ThrowPerlException(exception,OptionError,
8913 "affine matrix is singular",PackageName);
8914 goto PerlException;
8915 }
8916 if (av_len(av) == 5)
8917 {
8918 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8919 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8920 }
8921 }
8922 for (j=10; j < 15; j++)
8923 {
8924 if (attribute_flag[j] == 0)
8925 continue;
8926 value=argument_list[j].string_reference;
8927 angle=argument_list[j].real_reference;
8928 current=draw_info->affine;
8929 GetAffineMatrix(&affine);
8930 switch (j)
8931 {
8932 case 10:
8933 {
8934 /*
8935 Translate.
8936 */
8937 flags=ParseGeometry(value,&geometry_info);
8938 affine.tx=geometry_info.xi;
8939 affine.ty=geometry_info.psi;
8940 if ((flags & PsiValue) == 0)
8941 affine.ty=affine.tx;
8942 break;
8943 }
8944 case 11:
8945 {
8946 /*
8947 Scale.
8948 */
8949 flags=ParseGeometry(value,&geometry_info);
8950 affine.sx=geometry_info.rho;
8951 affine.sy=geometry_info.sigma;
8952 if ((flags & SigmaValue) == 0)
8953 affine.sy=affine.sx;
8954 break;
8955 }
8956 case 12:
8957 {
8958 /*
8959 Rotate.
8960 */
8961 if (angle == 0.0)
8962 break;
8963 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8964 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8965 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8966 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8967 break;
8968 }
8969 case 13:
8970 {
8971 /*
8972 SkewX.
8973 */
8974 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8975 break;
8976 }
8977 case 14:
8978 {
8979 /*
8980 SkewY.
8981 */
8982 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8983 break;
8984 }
8985 }
8986 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8987 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8988 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8989 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8990 draw_info->affine.tx=
8991 current.sx*affine.tx+current.ry*affine.ty+current.tx;
8992 draw_info->affine.ty=
8993 current.rx*affine.tx+current.sy*affine.ty+current.ty;
8994 }
8995 if (attribute_flag[15] != 0)
8996 draw_info->fill_pattern=CloneImage(
8997 argument_list[15].image_reference,0,0,MagickTrue,exception);
8998 if (attribute_flag[16] != 0)
8999 draw_info->pointsize=argument_list[16].real_reference;
9000 if (attribute_flag[17] != 0)
9001 {
9002 draw_info->stroke_antialias=argument_list[17].integer_reference != 0
9003 ? MagickTrue : MagickFalse;
9004 draw_info->text_antialias=draw_info->stroke_antialias;
9005 }
9006 if (attribute_flag[18] != 0)
9007 (void) CloneString(&draw_info->density,
9008 argument_list[18].string_reference);
9009 if (attribute_flag[19] != 0)
9010 draw_info->stroke_width=argument_list[19].real_reference;
9011 if (attribute_flag[21] != 0)
9012 draw_info->dash_offset=argument_list[21].real_reference;
9013 if (attribute_flag[22] != 0)
9014 {
9015 AV
9016 *av;
9017
9018 av=(AV *) argument_list[22].array_reference;
9019 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9020 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9021 if (draw_info->dash_pattern != (double *) NULL)
9022 {
9023 for (i=0; i <= av_len(av); i++)
9024 draw_info->dash_pattern[i]=(double)
9025 SvNV(*(av_fetch(av,i,0)));
9026 draw_info->dash_pattern[i]=0.0;
9027 }
9028 }
9029 if (attribute_flag[23] != 0)
9030 image->interpolate=(PixelInterpolateMethod)
9031 argument_list[23].integer_reference;
9032 if ((attribute_flag[24] != 0) &&
9033 (draw_info->fill_pattern != (Image *) NULL))
9034 flags=ParsePageGeometry(draw_info->fill_pattern,
9035 argument_list[24].string_reference,
9036 &draw_info->fill_pattern->tile_offset,exception);
9037 if (attribute_flag[25] != 0)
9038 {
9039 (void) ConcatenateString(&draw_info->primitive," '");
9040 (void) ConcatenateString(&draw_info->primitive,
9041 argument_list[25].string_reference);
9042 (void) ConcatenateString(&draw_info->primitive,"'");
9043 }
9044 if (attribute_flag[26] != 0)
9045 draw_info->fill_pattern=CloneImage(
9046 argument_list[26].image_reference,0,0,MagickTrue,exception);
9047 if (attribute_flag[27] != 0)
9048 draw_info->stroke_pattern=CloneImage(
9049 argument_list[27].image_reference,0,0,MagickTrue,exception);
9050 if (attribute_flag[28] != 0)
9051 (void) CloneString(&draw_info->primitive,
9052 argument_list[28].string_reference);
9053 if (attribute_flag[29] != 0)
9054 draw_info->kerning=argument_list[29].real_reference;
9055 if (attribute_flag[30] != 0)
9056 draw_info->interline_spacing=argument_list[30].real_reference;
9057 if (attribute_flag[31] != 0)
9058 draw_info->interword_spacing=argument_list[31].real_reference;
9059 if (attribute_flag[32] != 0)
9060 draw_info->direction=(DirectionType)
9061 argument_list[32].integer_reference;
9062 DrawImage(image,draw_info,exception);
9063 draw_info=DestroyDrawInfo(draw_info);
9064 break;
9065 }
9066 case 39: /* Equalize */
9067 {
9068 if (attribute_flag[0] != 0)
9069 channel=(ChannelType) argument_list[0].integer_reference;
9070 channel_mask=SetImageChannelMask(image,channel);
9071 EqualizeImage(image,exception);
9072 (void) SetImageChannelMask(image,channel_mask);
9073 break;
9074 }
9075 case 40: /* Gamma */
9076 {
9077 if (attribute_flag[1] != 0)
9078 channel=(ChannelType) argument_list[1].integer_reference;
9079 if (attribute_flag[2] == 0)
9080 argument_list[2].real_reference=1.0;
9081 if (attribute_flag[3] == 0)
9082 argument_list[3].real_reference=1.0;
9083 if (attribute_flag[4] == 0)
9084 argument_list[4].real_reference=1.0;
9085 if (attribute_flag[0] == 0)
9086 {
cristy151b66d2015-04-15 10:50:31 +00009087 (void) FormatLocaleString(message,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -05009088 "%.20g,%.20g,%.20g",(double) argument_list[2].real_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009089 (double) argument_list[3].real_reference,
9090 (double) argument_list[4].real_reference);
9091 argument_list[0].string_reference=message;
9092 }
9093 (void) GammaImage(image,StringToDouble(
9094 argument_list[0].string_reference,(char **) NULL),exception);
9095 break;
9096 }
9097 case 41: /* Map */
9098 {
9099 QuantizeInfo
9100 *quantize_info;
9101
9102 if (attribute_flag[0] == 0)
9103 {
9104 ThrowPerlException(exception,OptionError,"MapImageRequired",
9105 PackageName);
9106 goto PerlException;
9107 }
9108 quantize_info=AcquireQuantizeInfo(info->image_info);
9109 if (attribute_flag[1] != 0)
9110 quantize_info->dither_method=(DitherMethod)
9111 argument_list[1].integer_reference;
9112 (void) RemapImages(quantize_info,image,
9113 argument_list[0].image_reference,exception);
9114 quantize_info=DestroyQuantizeInfo(quantize_info);
9115 break;
9116 }
9117 case 42: /* MatteFloodfill */
9118 {
9119 DrawInfo
9120 *draw_info;
9121
9122 MagickBooleanType
9123 invert;
9124
9125 PixelInfo
9126 target;
9127
9128 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9129 (DrawInfo *) NULL);
9130 if (attribute_flag[0] != 0)
9131 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9132 &geometry,exception);
9133 if (attribute_flag[1] != 0)
9134 geometry.x=argument_list[1].integer_reference;
9135 if (attribute_flag[2] != 0)
9136 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009137 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009138 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9139 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9140 geometry.x,geometry.y,&target,exception);
9141 if (attribute_flag[4] != 0)
9142 QueryColorCompliance(argument_list[4].string_reference,
9143 AllCompliance,&target,exception);
9144 if (attribute_flag[3] != 0)
9145 target.alpha=StringToDoubleInterval(
9146 argument_list[3].string_reference,(double) (double) QuantumRange+
9147 1.0);
9148 if (attribute_flag[5] != 0)
9149 image->fuzz=StringToDoubleInterval(
9150 argument_list[5].string_reference,(double) QuantumRange+1.0);
9151 invert=MagickFalse;
9152 if (attribute_flag[6] != 0)
9153 invert=(MagickBooleanType) argument_list[6].integer_reference;
9154 channel_mask=SetImageChannelMask(image,AlphaChannel);
9155 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9156 geometry.y,invert,exception);
9157 (void) SetImageChannelMask(image,channel_mask);
9158 draw_info=DestroyDrawInfo(draw_info);
9159 break;
9160 }
9161 case 43: /* Modulate */
9162 {
9163 char
cristy151b66d2015-04-15 10:50:31 +00009164 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009165
9166 geometry_info.rho=100.0;
9167 geometry_info.sigma=100.0;
9168 geometry_info.xi=100.0;
9169 if (attribute_flag[0] != 0)
9170 (void)ParseGeometry(argument_list[0].string_reference,
9171 &geometry_info);
9172 if (attribute_flag[1] != 0)
9173 geometry_info.xi=argument_list[1].real_reference;
9174 if (attribute_flag[2] != 0)
9175 geometry_info.sigma=argument_list[2].real_reference;
9176 if (attribute_flag[3] != 0)
9177 {
9178 geometry_info.sigma=argument_list[3].real_reference;
9179 SetImageArtifact(image,"modulate:colorspace","HWB");
9180 }
9181 if (attribute_flag[4] != 0)
9182 {
9183 geometry_info.rho=argument_list[4].real_reference;
9184 SetImageArtifact(image,"modulate:colorspace","HSB");
9185 }
9186 if (attribute_flag[5] != 0)
9187 {
9188 geometry_info.sigma=argument_list[5].real_reference;
9189 SetImageArtifact(image,"modulate:colorspace","HSL");
9190 }
9191 if (attribute_flag[6] != 0)
9192 {
9193 geometry_info.rho=argument_list[6].real_reference;
9194 SetImageArtifact(image,"modulate:colorspace","HWB");
9195 }
Cristyb1710fe2017-02-11 13:51:48 -05009196 (void) FormatLocaleString(modulate,MagickPathExtent,"%.20g,%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00009197 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
9198 (void) ModulateImage(image,modulate,exception);
9199 break;
9200 }
9201 case 44: /* Negate */
9202 {
9203 if (attribute_flag[0] == 0)
9204 argument_list[0].integer_reference=0;
9205 if (attribute_flag[1] != 0)
9206 channel=(ChannelType) argument_list[1].integer_reference;
9207 channel_mask=SetImageChannelMask(image,channel);
9208 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9209 MagickTrue : MagickFalse,exception);
9210 (void) SetImageChannelMask(image,channel_mask);
9211 break;
9212 }
9213 case 45: /* Normalize */
9214 {
9215 if (attribute_flag[0] != 0)
9216 channel=(ChannelType) argument_list[0].integer_reference;
9217 channel_mask=SetImageChannelMask(image,channel);
9218 NormalizeImage(image,exception);
9219 (void) SetImageChannelMask(image,channel_mask);
9220 break;
9221 }
9222 case 46: /* NumberColors */
9223 break;
9224 case 47: /* Opaque */
9225 {
9226 MagickBooleanType
9227 invert;
9228
9229 PixelInfo
9230 fill_color,
9231 target;
9232
9233 (void) QueryColorCompliance("none",AllCompliance,&target,
9234 exception);
9235 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9236 exception);
9237 if (attribute_flag[0] != 0)
9238 (void) QueryColorCompliance(argument_list[0].string_reference,
9239 AllCompliance,&target,exception);
9240 if (attribute_flag[1] != 0)
9241 (void) QueryColorCompliance(argument_list[1].string_reference,
9242 AllCompliance,&fill_color,exception);
9243 if (attribute_flag[2] != 0)
9244 image->fuzz=StringToDoubleInterval(
9245 argument_list[2].string_reference,(double) QuantumRange+1.0);
9246 if (attribute_flag[3] != 0)
9247 channel=(ChannelType) argument_list[3].integer_reference;
9248 invert=MagickFalse;
9249 if (attribute_flag[4] != 0)
9250 invert=(MagickBooleanType) argument_list[4].integer_reference;
9251 channel_mask=SetImageChannelMask(image,channel);
9252 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9253 (void) SetImageChannelMask(image,channel_mask);
9254 break;
9255 }
9256 case 48: /* Quantize */
9257 {
9258 QuantizeInfo
9259 *quantize_info;
9260
9261 quantize_info=AcquireQuantizeInfo(info->image_info);
9262 if (attribute_flag[0] != 0)
9263 quantize_info->number_colors=(size_t)
9264 argument_list[0].integer_reference;
9265 if (attribute_flag[1] != 0)
9266 quantize_info->tree_depth=(size_t)
9267 argument_list[1].integer_reference;
9268 if (attribute_flag[2] != 0)
9269 quantize_info->colorspace=(ColorspaceType)
9270 argument_list[2].integer_reference;
9271 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009272 quantize_info->dither_method=(DitherMethod)
9273 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009274 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009275 quantize_info->measure_error=
9276 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009277 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009278 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009279 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009280 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009281 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009282 argument_list[7].integer_reference;
9283 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009284 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009285 else
cristyf7563392014-03-25 13:54:04 +00009286 if ((image->storage_class == DirectClass) ||
9287 (image->colors > quantize_info->number_colors) ||
9288 (quantize_info->colorspace == GRAYColorspace))
9289 (void) QuantizeImage(quantize_info,image,exception);
9290 else
9291 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009292 quantize_info=DestroyQuantizeInfo(quantize_info);
9293 break;
9294 }
9295 case 49: /* Raise */
9296 {
9297 if (attribute_flag[0] != 0)
9298 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9299 &geometry,exception);
9300 if (attribute_flag[1] != 0)
9301 geometry.width=argument_list[1].integer_reference;
9302 if (attribute_flag[2] != 0)
9303 geometry.height=argument_list[2].integer_reference;
9304 if (attribute_flag[3] == 0)
9305 argument_list[3].integer_reference=1;
9306 (void) RaiseImage(image,&geometry,
9307 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9308 exception);
9309 break;
9310 }
9311 case 50: /* Segment */
9312 {
9313 ColorspaceType
9314 colorspace;
9315
9316 double
9317 cluster_threshold,
9318 smoothing_threshold;
9319
9320 MagickBooleanType
9321 verbose;
9322
9323 cluster_threshold=1.0;
9324 smoothing_threshold=1.5;
9325 colorspace=sRGBColorspace;
9326 verbose=MagickFalse;
9327 if (attribute_flag[0] != 0)
9328 {
9329 flags=ParseGeometry(argument_list[0].string_reference,
9330 &geometry_info);
9331 cluster_threshold=geometry_info.rho;
9332 if (flags & SigmaValue)
9333 smoothing_threshold=geometry_info.sigma;
9334 }
9335 if (attribute_flag[1] != 0)
9336 cluster_threshold=argument_list[1].real_reference;
9337 if (attribute_flag[2] != 0)
9338 smoothing_threshold=argument_list[2].real_reference;
9339 if (attribute_flag[3] != 0)
9340 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9341 if (attribute_flag[4] != 0)
9342 verbose=argument_list[4].integer_reference != 0 ?
9343 MagickTrue : MagickFalse;
9344 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9345 smoothing_threshold,exception);
9346 break;
9347 }
9348 case 51: /* Signature */
9349 {
9350 (void) SignatureImage(image,exception);
9351 break;
9352 }
9353 case 52: /* Solarize */
9354 {
9355 geometry_info.rho=QuantumRange/2.0;
9356 if (attribute_flag[0] != 0)
9357 flags=ParseGeometry(argument_list[0].string_reference,
9358 &geometry_info);
9359 if (attribute_flag[1] != 0)
9360 geometry_info.rho=StringToDoubleInterval(
9361 argument_list[1].string_reference,(double) QuantumRange+1.0);
9362 (void) SolarizeImage(image,geometry_info.rho,exception);
9363 break;
9364 }
9365 case 53: /* Sync */
9366 {
9367 (void) SyncImage(image,exception);
9368 break;
9369 }
9370 case 54: /* Texture */
9371 {
9372 if (attribute_flag[0] == 0)
9373 break;
9374 TextureImage(image,argument_list[0].image_reference,exception);
9375 break;
9376 }
9377 case 55: /* Evalute */
9378 {
9379 MagickEvaluateOperator
9380 op;
9381
9382 op=SetEvaluateOperator;
9383 if (attribute_flag[0] == MagickFalse)
9384 argument_list[0].real_reference=0.0;
9385 if (attribute_flag[1] != MagickFalse)
9386 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9387 if (attribute_flag[2] != MagickFalse)
9388 channel=(ChannelType) argument_list[2].integer_reference;
9389 channel_mask=SetImageChannelMask(image,channel);
9390 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9391 exception);
9392 (void) SetImageChannelMask(image,channel_mask);
9393 break;
9394 }
9395 case 56: /* Transparent */
9396 {
9397 double
9398 opacity;
9399
9400 MagickBooleanType
9401 invert;
9402
9403 PixelInfo
9404 target;
9405
9406 (void) QueryColorCompliance("none",AllCompliance,&target,
9407 exception);
9408 if (attribute_flag[0] != 0)
9409 (void) QueryColorCompliance(argument_list[0].string_reference,
9410 AllCompliance,&target,exception);
9411 opacity=TransparentAlpha;
9412 if (attribute_flag[1] != 0)
9413 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9414 (double) QuantumRange+1.0);
9415 if (attribute_flag[2] != 0)
9416 image->fuzz=StringToDoubleInterval(
9417 argument_list[2].string_reference,(double) QuantumRange+1.0);
9418 if (attribute_flag[3] == 0)
9419 argument_list[3].integer_reference=0;
9420 invert=MagickFalse;
9421 if (attribute_flag[3] != 0)
9422 invert=(MagickBooleanType) argument_list[3].integer_reference;
9423 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9424 invert,exception);
9425 break;
9426 }
9427 case 57: /* Threshold */
9428 {
9429 double
9430 threshold;
9431
9432 if (attribute_flag[0] == 0)
9433 argument_list[0].string_reference="50%";
9434 if (attribute_flag[1] != 0)
9435 channel=(ChannelType) argument_list[1].integer_reference;
9436 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9437 (double) QuantumRange+1.0);
9438 channel_mask=SetImageChannelMask(image,channel);
9439 (void) BilevelImage(image,threshold,exception);
9440 (void) SetImageChannelMask(image,channel_mask);
9441 break;
9442 }
9443 case 58: /* Charcoal */
9444 {
9445 if (attribute_flag[0] != 0)
9446 {
9447 flags=ParseGeometry(argument_list[0].string_reference,
9448 &geometry_info);
9449 if ((flags & SigmaValue) == 0)
9450 geometry_info.sigma=1.0;
9451 }
9452 if (attribute_flag[1] != 0)
9453 geometry_info.rho=argument_list[1].real_reference;
9454 if (attribute_flag[2] != 0)
9455 geometry_info.sigma=argument_list[2].real_reference;
9456 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9457 exception);
9458 break;
9459 }
9460 case 59: /* Trim */
9461 {
9462 if (attribute_flag[0] != 0)
9463 image->fuzz=StringToDoubleInterval(
9464 argument_list[0].string_reference,(double) QuantumRange+1.0);
9465 image=TrimImage(image,exception);
9466 break;
9467 }
9468 case 60: /* Wave */
9469 {
9470 PixelInterpolateMethod
9471 method;
9472
9473 if (attribute_flag[0] != 0)
9474 {
9475 flags=ParseGeometry(argument_list[0].string_reference,
9476 &geometry_info);
9477 if ((flags & SigmaValue) == 0)
9478 geometry_info.sigma=1.0;
9479 }
9480 if (attribute_flag[1] != 0)
9481 geometry_info.rho=argument_list[1].real_reference;
9482 if (attribute_flag[2] != 0)
9483 geometry_info.sigma=argument_list[2].real_reference;
9484 method=UndefinedInterpolatePixel;
9485 if (attribute_flag[3] != 0)
9486 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9487 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9488 method,exception);
9489 break;
9490 }
9491 case 61: /* Separate */
9492 {
9493 if (attribute_flag[0] != 0)
9494 channel=(ChannelType) argument_list[0].integer_reference;
9495 image=SeparateImage(image,channel,exception);
9496 break;
9497 }
9498 case 63: /* Stereo */
9499 {
9500 if (attribute_flag[0] == 0)
9501 {
9502 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9503 PackageName);
9504 goto PerlException;
9505 }
9506 if (attribute_flag[1] != 0)
9507 geometry.x=argument_list[1].integer_reference;
9508 if (attribute_flag[2] != 0)
9509 geometry.y=argument_list[2].integer_reference;
9510 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9511 geometry.x,geometry.y,exception);
9512 break;
9513 }
9514 case 64: /* Stegano */
9515 {
9516 if (attribute_flag[0] == 0)
9517 {
9518 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9519 PackageName);
9520 goto PerlException;
9521 }
9522 if (attribute_flag[1] == 0)
9523 argument_list[1].integer_reference=0;
9524 image->offset=argument_list[1].integer_reference;
9525 image=SteganoImage(image,argument_list[0].image_reference,exception);
9526 break;
9527 }
9528 case 65: /* Deconstruct */
9529 {
9530 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9531 break;
9532 }
9533 case 66: /* GaussianBlur */
9534 {
9535 if (attribute_flag[0] != 0)
9536 {
9537 flags=ParseGeometry(argument_list[0].string_reference,
9538 &geometry_info);
9539 if ((flags & SigmaValue) == 0)
9540 geometry_info.sigma=1.0;
9541 }
9542 if (attribute_flag[1] != 0)
9543 geometry_info.rho=argument_list[1].real_reference;
9544 if (attribute_flag[2] != 0)
9545 geometry_info.sigma=argument_list[2].real_reference;
9546 if (attribute_flag[3] != 0)
9547 channel=(ChannelType) argument_list[3].integer_reference;
9548 channel_mask=SetImageChannelMask(image,channel);
9549 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9550 exception);
9551 if (image != (Image *) NULL)
9552 (void) SetImageChannelMask(image,channel_mask);
9553 break;
9554 }
9555 case 67: /* Convolve */
9556 {
9557 KernelInfo
9558 *kernel;
9559
9560 kernel=(KernelInfo *) NULL;
9561 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9562 break;
9563 if (attribute_flag[0] != 0)
9564 {
9565 AV
9566 *av;
9567
9568 size_t
9569 order;
9570
cristy2c57b742014-10-31 00:40:34 +00009571 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009572 if (kernel == (KernelInfo *) NULL)
9573 break;
9574 av=(AV *) argument_list[0].array_reference;
9575 order=(size_t) sqrt(av_len(av)+1);
9576 kernel->width=order;
9577 kernel->height=order;
9578 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9579 order*sizeof(*kernel->values));
9580 if (kernel->values == (MagickRealType *) NULL)
9581 {
9582 kernel=DestroyKernelInfo(kernel);
9583 ThrowPerlException(exception,ResourceLimitFatalError,
9584 "MemoryAllocationFailed",PackageName);
9585 goto PerlException;
9586 }
9587 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9588 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9589 for ( ; j < (ssize_t) (order*order); j++)
9590 kernel->values[j]=0.0;
9591 }
9592 if (attribute_flag[1] != 0)
9593 channel=(ChannelType) argument_list[1].integer_reference;
9594 if (attribute_flag[2] != 0)
9595 SetImageArtifact(image,"filter:blur",
9596 argument_list[2].string_reference);
9597 if (attribute_flag[3] != 0)
9598 {
cristy2c57b742014-10-31 00:40:34 +00009599 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9600 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009601 if (kernel == (KernelInfo *) NULL)
9602 break;
9603 }
9604 channel_mask=SetImageChannelMask(image,channel);
9605 image=ConvolveImage(image,kernel,exception);
9606 if (image != (Image *) NULL)
9607 (void) SetImageChannelMask(image,channel_mask);
9608 kernel=DestroyKernelInfo(kernel);
9609 break;
9610 }
9611 case 68: /* Profile */
9612 {
9613 const char
9614 *name;
9615
9616 Image
9617 *profile_image;
9618
9619 ImageInfo
9620 *profile_info;
9621
9622 StringInfo
9623 *profile;
9624
9625 name="*";
9626 if (attribute_flag[0] != 0)
9627 name=argument_list[0].string_reference;
9628 if (attribute_flag[2] != 0)
9629 image->rendering_intent=(RenderingIntent)
9630 argument_list[2].integer_reference;
9631 if (attribute_flag[3] != 0)
9632 image->black_point_compensation=
9633 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9634 if (attribute_flag[1] != 0)
9635 {
9636 if (argument_list[1].length == 0)
9637 {
9638 /*
9639 Remove a profile from the image.
9640 */
9641 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9642 exception);
9643 break;
9644 }
9645 /*
9646 Associate user supplied profile with the image.
9647 */
9648 profile=AcquireStringInfo(argument_list[1].length);
9649 SetStringInfoDatum(profile,(const unsigned char *)
9650 argument_list[1].string_reference);
9651 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9652 (size_t) GetStringInfoLength(profile),exception);
9653 profile=DestroyStringInfo(profile);
9654 break;
9655 }
9656 /*
9657 Associate a profile with the image.
9658 */
9659 profile_info=CloneImageInfo(info ? info->image_info :
9660 (ImageInfo *) NULL);
9661 profile_image=ReadImages(profile_info,name,exception);
9662 if (profile_image == (Image *) NULL)
9663 break;
9664 ResetImageProfileIterator(profile_image);
9665 name=GetNextImageProfile(profile_image);
9666 while (name != (const char *) NULL)
9667 {
9668 const StringInfo
9669 *profile;
9670
9671 profile=GetImageProfile(profile_image,name);
9672 if (profile != (const StringInfo *) NULL)
9673 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9674 (size_t) GetStringInfoLength(profile),exception);
9675 name=GetNextImageProfile(profile_image);
9676 }
9677 profile_image=DestroyImage(profile_image);
9678 profile_info=DestroyImageInfo(profile_info);
9679 break;
9680 }
9681 case 69: /* UnsharpMask */
9682 {
9683 if (attribute_flag[0] != 0)
9684 {
9685 flags=ParseGeometry(argument_list[0].string_reference,
9686 &geometry_info);
9687 if ((flags & SigmaValue) == 0)
9688 geometry_info.sigma=1.0;
9689 if ((flags & XiValue) == 0)
9690 geometry_info.xi=1.0;
9691 if ((flags & PsiValue) == 0)
9692 geometry_info.psi=0.5;
9693 }
9694 if (attribute_flag[1] != 0)
9695 geometry_info.rho=argument_list[1].real_reference;
9696 if (attribute_flag[2] != 0)
9697 geometry_info.sigma=argument_list[2].real_reference;
9698 if (attribute_flag[3] != 0)
9699 geometry_info.xi=argument_list[3].real_reference;
9700 if (attribute_flag[4] != 0)
9701 geometry_info.psi=argument_list[4].real_reference;
9702 if (attribute_flag[5] != 0)
9703 channel=(ChannelType) argument_list[5].integer_reference;
9704 channel_mask=SetImageChannelMask(image,channel);
9705 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9706 geometry_info.xi,geometry_info.psi,exception);
9707 if (image != (Image *) NULL)
9708 (void) SetImageChannelMask(image,channel_mask);
9709 break;
9710 }
9711 case 70: /* MotionBlur */
9712 {
9713 if (attribute_flag[0] != 0)
9714 {
9715 flags=ParseGeometry(argument_list[0].string_reference,
9716 &geometry_info);
9717 if ((flags & SigmaValue) == 0)
9718 geometry_info.sigma=1.0;
9719 if ((flags & XiValue) == 0)
9720 geometry_info.xi=1.0;
9721 }
9722 if (attribute_flag[1] != 0)
9723 geometry_info.rho=argument_list[1].real_reference;
9724 if (attribute_flag[2] != 0)
9725 geometry_info.sigma=argument_list[2].real_reference;
9726 if (attribute_flag[3] != 0)
9727 geometry_info.xi=argument_list[3].real_reference;
9728 if (attribute_flag[4] != 0)
9729 channel=(ChannelType) argument_list[4].integer_reference;
9730 channel_mask=SetImageChannelMask(image,channel);
9731 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9732 geometry_info.xi,exception);
9733 if (image != (Image *) NULL)
9734 (void) SetImageChannelMask(image,channel_mask);
9735 break;
9736 }
9737 case 71: /* OrderedDither */
9738 {
9739 if (attribute_flag[0] == 0)
9740 argument_list[0].string_reference="o8x8";
9741 if (attribute_flag[1] != 0)
9742 channel=(ChannelType) argument_list[1].integer_reference;
9743 channel_mask=SetImageChannelMask(image,channel);
Cristy6b93c072016-02-04 07:45:48 -05009744 (void) OrderedDitherImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009745 exception);
9746 (void) SetImageChannelMask(image,channel_mask);
9747 break;
9748 }
9749 case 72: /* Shave */
9750 {
9751 if (attribute_flag[0] != 0)
9752 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9753 &geometry,exception);
9754 if (attribute_flag[1] != 0)
9755 geometry.width=argument_list[1].integer_reference;
9756 if (attribute_flag[2] != 0)
9757 geometry.height=argument_list[2].integer_reference;
9758 image=ShaveImage(image,&geometry,exception);
9759 break;
9760 }
9761 case 73: /* Level */
9762 {
9763 double
9764 black_point,
9765 gamma,
9766 white_point;
9767
9768 black_point=0.0;
9769 white_point=(double) image->columns*image->rows;
9770 gamma=1.0;
9771 if (attribute_flag[0] != 0)
9772 {
9773 flags=ParseGeometry(argument_list[0].string_reference,
9774 &geometry_info);
9775 black_point=geometry_info.rho;
9776 if ((flags & SigmaValue) != 0)
9777 white_point=geometry_info.sigma;
9778 if ((flags & XiValue) != 0)
9779 gamma=geometry_info.xi;
9780 if ((flags & PercentValue) != 0)
9781 {
9782 black_point*=(double) (QuantumRange/100.0);
9783 white_point*=(double) (QuantumRange/100.0);
9784 }
9785 if ((flags & SigmaValue) == 0)
9786 white_point=(double) QuantumRange-black_point;
9787 }
9788 if (attribute_flag[1] != 0)
9789 black_point=argument_list[1].real_reference;
9790 if (attribute_flag[2] != 0)
9791 white_point=argument_list[2].real_reference;
9792 if (attribute_flag[3] != 0)
9793 gamma=argument_list[3].real_reference;
9794 if (attribute_flag[4] != 0)
9795 channel=(ChannelType) argument_list[4].integer_reference;
9796 if (attribute_flag[5] != 0)
9797 {
9798 argument_list[0].real_reference=argument_list[5].real_reference;
9799 attribute_flag[0]=attribute_flag[5];
9800 }
9801 channel_mask=SetImageChannelMask(image,channel);
9802 (void) LevelImage(image,black_point,white_point,gamma,exception);
9803 (void) SetImageChannelMask(image,channel_mask);
9804 break;
9805 }
9806 case 74: /* Clip */
9807 {
9808 if (attribute_flag[0] == 0)
9809 argument_list[0].string_reference="#1";
9810 if (attribute_flag[1] == 0)
9811 argument_list[1].integer_reference=MagickTrue;
9812 (void) ClipImagePath(image,argument_list[0].string_reference,
9813 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9814 exception);
9815 break;
9816 }
9817 case 75: /* AffineTransform */
9818 {
9819 DrawInfo
9820 *draw_info;
9821
9822 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9823 (DrawInfo *) NULL);
9824 if (attribute_flag[0] != 0)
9825 {
9826 AV
9827 *av;
9828
9829 av=(AV *) argument_list[0].array_reference;
9830 if ((av_len(av) != 3) && (av_len(av) != 5))
9831 {
9832 ThrowPerlException(exception,OptionError,
9833 "affine matrix must have 4 or 6 elements",PackageName);
9834 goto PerlException;
9835 }
9836 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9837 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9838 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9839 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9840 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9841 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9842 {
9843 ThrowPerlException(exception,OptionError,
9844 "affine matrix is singular",PackageName);
9845 goto PerlException;
9846 }
9847 if (av_len(av) == 5)
9848 {
9849 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9850 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9851 }
9852 }
9853 for (j=1; j < 6; j++)
9854 {
9855 if (attribute_flag[j] == 0)
9856 continue;
9857 value=argument_list[j].string_reference;
9858 angle=argument_list[j].real_reference;
9859 current=draw_info->affine;
9860 GetAffineMatrix(&affine);
9861 switch (j)
9862 {
9863 case 1:
9864 {
9865 /*
9866 Translate.
9867 */
9868 flags=ParseGeometry(value,&geometry_info);
9869 affine.tx=geometry_info.xi;
9870 affine.ty=geometry_info.psi;
9871 if ((flags & PsiValue) == 0)
9872 affine.ty=affine.tx;
9873 break;
9874 }
9875 case 2:
9876 {
9877 /*
9878 Scale.
9879 */
9880 flags=ParseGeometry(value,&geometry_info);
9881 affine.sx=geometry_info.rho;
9882 affine.sy=geometry_info.sigma;
9883 if ((flags & SigmaValue) == 0)
9884 affine.sy=affine.sx;
9885 break;
9886 }
9887 case 3:
9888 {
9889 /*
9890 Rotate.
9891 */
9892 if (angle == 0.0)
9893 break;
9894 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9895 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9896 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9897 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9898 break;
9899 }
9900 case 4:
9901 {
9902 /*
9903 SkewX.
9904 */
9905 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9906 break;
9907 }
9908 case 5:
9909 {
9910 /*
9911 SkewY.
9912 */
9913 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9914 break;
9915 }
9916 }
9917 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9918 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9919 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9920 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9921 draw_info->affine.tx=
9922 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9923 draw_info->affine.ty=
9924 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9925 }
9926 if (attribute_flag[6] != 0)
9927 image->interpolate=(PixelInterpolateMethod)
9928 argument_list[6].integer_reference;
9929 if (attribute_flag[7] != 0)
9930 QueryColorCompliance(argument_list[7].string_reference,
9931 AllCompliance,&image->background_color,exception);
9932 image=AffineTransformImage(image,&draw_info->affine,exception);
9933 draw_info=DestroyDrawInfo(draw_info);
9934 break;
9935 }
9936 case 76: /* Difference */
9937 {
9938 if (attribute_flag[0] == 0)
9939 {
9940 ThrowPerlException(exception,OptionError,
9941 "ReferenceImageRequired",PackageName);
9942 goto PerlException;
9943 }
9944 if (attribute_flag[1] != 0)
9945 image->fuzz=StringToDoubleInterval(
9946 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -05009947 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009948 exception);
9949 break;
9950 }
9951 case 77: /* AdaptiveThreshold */
9952 {
9953 if (attribute_flag[0] != 0)
9954 {
9955 flags=ParseGeometry(argument_list[0].string_reference,
9956 &geometry_info);
9957 if ((flags & PercentValue) != 0)
9958 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9959 }
9960 if (attribute_flag[1] != 0)
9961 geometry_info.rho=argument_list[1].integer_reference;
9962 if (attribute_flag[2] != 0)
9963 geometry_info.sigma=argument_list[2].integer_reference;
9964 if (attribute_flag[3] != 0)
9965 geometry_info.xi=argument_list[3].integer_reference;;
9966 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9967 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9968 break;
9969 }
9970 case 78: /* Resample */
9971 {
9972 size_t
9973 height,
9974 width;
9975
9976 if (attribute_flag[0] != 0)
9977 {
9978 flags=ParseGeometry(argument_list[0].string_reference,
9979 &geometry_info);
9980 if ((flags & SigmaValue) == 0)
9981 geometry_info.sigma=geometry_info.rho;
9982 }
9983 if (attribute_flag[1] != 0)
9984 geometry_info.rho=argument_list[1].real_reference;
9985 if (attribute_flag[2] != 0)
9986 geometry_info.sigma=argument_list[2].real_reference;
9987 if (attribute_flag[3] == 0)
9988 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
9989 if (attribute_flag[4] == 0)
9990 SetImageArtifact(image,"filter:support",
9991 argument_list[4].string_reference);
9992 width=(size_t) (geometry_info.rho*image->columns/
9993 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
9994 height=(size_t) (geometry_info.sigma*image->rows/
9995 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
Cristy8645e042016-02-03 16:35:29 -05009996 image=ResizeImage(image,width,height,(FilterType)
cristy4a3ce0a2013-08-03 20:06:59 +00009997 argument_list[3].integer_reference,exception);
9998 if (image != (Image *) NULL)
9999 {
10000 image->resolution.x=geometry_info.rho;
10001 image->resolution.y=geometry_info.sigma;
10002 }
10003 break;
10004 }
10005 case 79: /* Describe */
10006 {
10007 if (attribute_flag[0] == 0)
10008 argument_list[0].file_reference=(FILE *) NULL;
10009 if (attribute_flag[1] != 0)
10010 (void) SetImageArtifact(image,"identify:features",
10011 argument_list[1].string_reference);
10012 (void) IdentifyImage(image,argument_list[0].file_reference,
10013 MagickTrue,exception);
10014 break;
10015 }
10016 case 80: /* BlackThreshold */
10017 {
10018 if (attribute_flag[0] == 0)
10019 argument_list[0].string_reference="50%";
10020 if (attribute_flag[2] != 0)
10021 channel=(ChannelType) argument_list[2].integer_reference;
10022 channel_mask=SetImageChannelMask(image,channel);
10023 BlackThresholdImage(image,argument_list[0].string_reference,
10024 exception);
10025 (void) SetImageChannelMask(image,channel_mask);
10026 break;
10027 }
10028 case 81: /* WhiteThreshold */
10029 {
10030 if (attribute_flag[0] == 0)
10031 argument_list[0].string_reference="50%";
10032 if (attribute_flag[2] != 0)
10033 channel=(ChannelType) argument_list[2].integer_reference;
10034 channel_mask=SetImageChannelMask(image,channel);
10035 WhiteThresholdImage(image,argument_list[0].string_reference,
10036 exception);
10037 (void) SetImageChannelMask(image,channel_mask);
10038 break;
10039 }
cristy60c73c02014-03-25 12:09:58 +000010040 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010041 {
10042 if (attribute_flag[0] != 0)
10043 {
10044 flags=ParseGeometry(argument_list[0].string_reference,
10045 &geometry_info);
10046 }
10047 if (attribute_flag[1] != 0)
10048 geometry_info.rho=argument_list[1].real_reference;
10049 if (attribute_flag[2] != 0)
10050 channel=(ChannelType) argument_list[2].integer_reference;
10051 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010052 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010053 if (image != (Image *) NULL)
10054 (void) SetImageChannelMask(image,channel_mask);
10055 break;
10056 }
10057 case 83: /* Thumbnail */
10058 {
10059 if (attribute_flag[0] != 0)
10060 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10061 &geometry,exception);
10062 if (attribute_flag[1] != 0)
10063 geometry.width=argument_list[1].integer_reference;
10064 if (attribute_flag[2] != 0)
10065 geometry.height=argument_list[2].integer_reference;
10066 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10067 break;
10068 }
10069 case 84: /* Strip */
10070 {
10071 (void) StripImage(image,exception);
10072 break;
10073 }
10074 case 85: /* Tint */
10075 {
10076 PixelInfo
10077 tint;
10078
10079 GetPixelInfo(image,&tint);
10080 if (attribute_flag[0] != 0)
10081 (void) QueryColorCompliance(argument_list[0].string_reference,
10082 AllCompliance,&tint,exception);
10083 if (attribute_flag[1] == 0)
10084 argument_list[1].string_reference="100";
10085 image=TintImage(image,argument_list[1].string_reference,&tint,
10086 exception);
10087 break;
10088 }
10089 case 86: /* Channel */
10090 {
10091 if (attribute_flag[0] != 0)
10092 channel=(ChannelType) argument_list[0].integer_reference;
10093 image=SeparateImage(image,channel,exception);
10094 break;
10095 }
10096 case 87: /* Splice */
10097 {
cristy260bd762014-08-15 12:46:34 +000010098 if (attribute_flag[7] != 0)
10099 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010100 if (attribute_flag[0] != 0)
10101 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10102 &geometry,exception);
10103 if (attribute_flag[1] != 0)
10104 geometry.width=argument_list[1].integer_reference;
10105 if (attribute_flag[2] != 0)
10106 geometry.height=argument_list[2].integer_reference;
10107 if (attribute_flag[3] != 0)
10108 geometry.x=argument_list[3].integer_reference;
10109 if (attribute_flag[4] != 0)
10110 geometry.y=argument_list[4].integer_reference;
10111 if (attribute_flag[5] != 0)
10112 image->fuzz=StringToDoubleInterval(
10113 argument_list[5].string_reference,(double) QuantumRange+1.0);
10114 if (attribute_flag[6] != 0)
10115 (void) QueryColorCompliance(argument_list[6].string_reference,
10116 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010117 image=SpliceImage(image,&geometry,exception);
10118 break;
10119 }
10120 case 88: /* Posterize */
10121 {
10122 if (attribute_flag[0] == 0)
10123 argument_list[0].integer_reference=3;
10124 if (attribute_flag[1] == 0)
10125 argument_list[1].integer_reference=0;
10126 (void) PosterizeImage(image,argument_list[0].integer_reference,
10127 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10128 NoDitherMethod,exception);
10129 break;
10130 }
10131 case 89: /* Shadow */
10132 {
10133 if (attribute_flag[0] != 0)
10134 {
10135 flags=ParseGeometry(argument_list[0].string_reference,
10136 &geometry_info);
10137 if ((flags & SigmaValue) == 0)
10138 geometry_info.sigma=1.0;
10139 if ((flags & XiValue) == 0)
10140 geometry_info.xi=4.0;
10141 if ((flags & PsiValue) == 0)
10142 geometry_info.psi=4.0;
10143 }
10144 if (attribute_flag[1] != 0)
10145 geometry_info.rho=argument_list[1].real_reference;
10146 if (attribute_flag[2] != 0)
10147 geometry_info.sigma=argument_list[2].real_reference;
10148 if (attribute_flag[3] != 0)
10149 geometry_info.xi=argument_list[3].integer_reference;
10150 if (attribute_flag[4] != 0)
10151 geometry_info.psi=argument_list[4].integer_reference;
10152 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10153 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10154 ceil(geometry_info.psi-0.5),exception);
10155 break;
10156 }
10157 case 90: /* Identify */
10158 {
10159 if (attribute_flag[0] == 0)
10160 argument_list[0].file_reference=(FILE *) NULL;
10161 if (attribute_flag[1] != 0)
10162 (void) SetImageArtifact(image,"identify:features",
10163 argument_list[1].string_reference);
10164 if ((attribute_flag[2] != 0) &&
10165 (argument_list[2].integer_reference != 0))
10166 (void) SetImageArtifact(image,"identify:unique","true");
10167 (void) IdentifyImage(image,argument_list[0].file_reference,
10168 MagickTrue,exception);
10169 break;
10170 }
10171 case 91: /* SepiaTone */
10172 {
10173 if (attribute_flag[0] == 0)
10174 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10175 image=SepiaToneImage(image,argument_list[0].real_reference,
10176 exception);
10177 break;
10178 }
10179 case 92: /* SigmoidalContrast */
10180 {
10181 MagickBooleanType
10182 sharpen;
10183
10184 if (attribute_flag[0] != 0)
10185 {
10186 flags=ParseGeometry(argument_list[0].string_reference,
10187 &geometry_info);
10188 if ((flags & SigmaValue) == 0)
10189 geometry_info.sigma=QuantumRange/2.0;
10190 if ((flags & PercentValue) != 0)
10191 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10192 }
10193 if (attribute_flag[1] != 0)
10194 geometry_info.rho=argument_list[1].real_reference;
10195 if (attribute_flag[2] != 0)
10196 geometry_info.sigma=argument_list[2].real_reference;
10197 if (attribute_flag[3] != 0)
10198 channel=(ChannelType) argument_list[3].integer_reference;
10199 sharpen=MagickTrue;
10200 if (attribute_flag[4] != 0)
10201 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10202 MagickFalse;
10203 channel_mask=SetImageChannelMask(image,channel);
10204 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10205 geometry_info.sigma,exception);
10206 (void) SetImageChannelMask(image,channel_mask);
10207 break;
10208 }
10209 case 93: /* Extent */
10210 {
10211 if (attribute_flag[7] != 0)
10212 image->gravity=(GravityType) argument_list[7].integer_reference;
10213 if (attribute_flag[0] != 0)
10214 {
10215 int
10216 flags;
10217
10218 flags=ParseGravityGeometry(image,
10219 argument_list[0].string_reference,&geometry,exception);
10220 (void) flags;
10221 if (geometry.width == 0)
10222 geometry.width=image->columns;
10223 if (geometry.height == 0)
10224 geometry.height=image->rows;
10225 }
10226 if (attribute_flag[1] != 0)
10227 geometry.width=argument_list[1].integer_reference;
10228 if (attribute_flag[2] != 0)
10229 geometry.height=argument_list[2].integer_reference;
10230 if (attribute_flag[3] != 0)
10231 geometry.x=argument_list[3].integer_reference;
10232 if (attribute_flag[4] != 0)
10233 geometry.y=argument_list[4].integer_reference;
10234 if (attribute_flag[5] != 0)
10235 image->fuzz=StringToDoubleInterval(
10236 argument_list[5].string_reference,(double) QuantumRange+1.0);
10237 if (attribute_flag[6] != 0)
10238 (void) QueryColorCompliance(argument_list[6].string_reference,
10239 AllCompliance,&image->background_color,exception);
10240 image=ExtentImage(image,&geometry,exception);
10241 break;
10242 }
10243 case 94: /* Vignette */
10244 {
10245 if (attribute_flag[0] != 0)
10246 {
10247 flags=ParseGeometry(argument_list[0].string_reference,
10248 &geometry_info);
10249 if ((flags & SigmaValue) == 0)
10250 geometry_info.sigma=1.0;
10251 if ((flags & XiValue) == 0)
10252 geometry_info.xi=0.1*image->columns;
10253 if ((flags & PsiValue) == 0)
10254 geometry_info.psi=0.1*image->rows;
10255 }
10256 if (attribute_flag[1] != 0)
10257 geometry_info.rho=argument_list[1].real_reference;
10258 if (attribute_flag[2] != 0)
10259 geometry_info.sigma=argument_list[2].real_reference;
10260 if (attribute_flag[3] != 0)
10261 geometry_info.xi=argument_list[3].integer_reference;
10262 if (attribute_flag[4] != 0)
10263 geometry_info.psi=argument_list[4].integer_reference;
10264 if (attribute_flag[5] != 0)
10265 (void) QueryColorCompliance(argument_list[5].string_reference,
10266 AllCompliance,&image->background_color,exception);
10267 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10268 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10269 ceil(geometry_info.psi-0.5),exception);
10270 break;
10271 }
10272 case 95: /* ContrastStretch */
10273 {
10274 double
10275 black_point,
10276 white_point;
10277
10278 black_point=0.0;
10279 white_point=(double) image->columns*image->rows;
10280 if (attribute_flag[0] != 0)
10281 {
10282 flags=ParseGeometry(argument_list[0].string_reference,
10283 &geometry_info);
10284 black_point=geometry_info.rho;
10285 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10286 black_point;
10287 if ((flags & PercentValue) != 0)
10288 {
10289 black_point*=(double) image->columns*image->rows/100.0;
10290 white_point*=(double) image->columns*image->rows/100.0;
10291 }
10292 white_point=(double) image->columns*image->rows-
10293 white_point;
10294 }
10295 if (attribute_flag[1] != 0)
10296 black_point=argument_list[1].real_reference;
10297 if (attribute_flag[2] != 0)
10298 white_point=argument_list[2].real_reference;
10299 if (attribute_flag[4] != 0)
10300 channel=(ChannelType) argument_list[4].integer_reference;
10301 channel_mask=SetImageChannelMask(image,channel);
10302 (void) ContrastStretchImage(image,black_point,white_point,exception);
10303 (void) SetImageChannelMask(image,channel_mask);
10304 break;
10305 }
10306 case 96: /* Sans0 */
10307 {
10308 break;
10309 }
10310 case 97: /* Sans1 */
10311 {
10312 break;
10313 }
10314 case 98: /* AdaptiveSharpen */
10315 {
10316 if (attribute_flag[0] != 0)
10317 {
10318 flags=ParseGeometry(argument_list[0].string_reference,
10319 &geometry_info);
10320 if ((flags & SigmaValue) == 0)
10321 geometry_info.sigma=1.0;
10322 if ((flags & XiValue) == 0)
10323 geometry_info.xi=0.0;
10324 }
10325 if (attribute_flag[1] != 0)
10326 geometry_info.rho=argument_list[1].real_reference;
10327 if (attribute_flag[2] != 0)
10328 geometry_info.sigma=argument_list[2].real_reference;
10329 if (attribute_flag[3] != 0)
10330 geometry_info.xi=argument_list[3].real_reference;
10331 if (attribute_flag[4] != 0)
10332 channel=(ChannelType) argument_list[4].integer_reference;
10333 channel_mask=SetImageChannelMask(image,channel);
10334 image=AdaptiveSharpenImage(image,geometry_info.rho,
10335 geometry_info.sigma,exception);
10336 if (image != (Image *) NULL)
10337 (void) SetImageChannelMask(image,channel_mask);
10338 break;
10339 }
10340 case 99: /* Transpose */
10341 {
10342 image=TransposeImage(image,exception);
10343 break;
10344 }
10345 case 100: /* Tranverse */
10346 {
10347 image=TransverseImage(image,exception);
10348 break;
10349 }
10350 case 101: /* AutoOrient */
10351 {
10352 image=AutoOrientImage(image,image->orientation,exception);
10353 break;
10354 }
10355 case 102: /* AdaptiveBlur */
10356 {
10357 if (attribute_flag[0] != 0)
10358 {
10359 flags=ParseGeometry(argument_list[0].string_reference,
10360 &geometry_info);
10361 if ((flags & SigmaValue) == 0)
10362 geometry_info.sigma=1.0;
10363 if ((flags & XiValue) == 0)
10364 geometry_info.xi=0.0;
10365 }
10366 if (attribute_flag[1] != 0)
10367 geometry_info.rho=argument_list[1].real_reference;
10368 if (attribute_flag[2] != 0)
10369 geometry_info.sigma=argument_list[2].real_reference;
10370 if (attribute_flag[3] != 0)
10371 channel=(ChannelType) argument_list[3].integer_reference;
10372 channel_mask=SetImageChannelMask(image,channel);
10373 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10374 exception);
10375 if (image != (Image *) NULL)
10376 (void) SetImageChannelMask(image,channel_mask);
10377 break;
10378 }
10379 case 103: /* Sketch */
10380 {
10381 if (attribute_flag[0] != 0)
10382 {
10383 flags=ParseGeometry(argument_list[0].string_reference,
10384 &geometry_info);
10385 if ((flags & SigmaValue) == 0)
10386 geometry_info.sigma=1.0;
10387 if ((flags & XiValue) == 0)
10388 geometry_info.xi=1.0;
10389 }
10390 if (attribute_flag[1] != 0)
10391 geometry_info.rho=argument_list[1].real_reference;
10392 if (attribute_flag[2] != 0)
10393 geometry_info.sigma=argument_list[2].real_reference;
10394 if (attribute_flag[3] != 0)
10395 geometry_info.xi=argument_list[3].real_reference;
10396 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10397 geometry_info.xi,exception);
10398 break;
10399 }
10400 case 104: /* UniqueColors */
10401 {
10402 image=UniqueImageColors(image,exception);
10403 break;
10404 }
10405 case 105: /* AdaptiveResize */
10406 {
10407 if (attribute_flag[0] != 0)
10408 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10409 &geometry,exception);
10410 if (attribute_flag[1] != 0)
10411 geometry.width=argument_list[1].integer_reference;
10412 if (attribute_flag[2] != 0)
10413 geometry.height=argument_list[2].integer_reference;
10414 if (attribute_flag[3] != 0)
Cristy8645e042016-02-03 16:35:29 -050010415 image->filter=(FilterType) argument_list[4].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010416 if (attribute_flag[4] != 0)
10417 SetImageArtifact(image,"filter:support",
10418 argument_list[4].string_reference);
10419 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10420 exception);
10421 break;
10422 }
10423 case 106: /* ClipMask */
10424 {
10425 Image
10426 *mask_image;
10427
10428 if (attribute_flag[0] == 0)
10429 {
10430 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10431 PackageName);
10432 goto PerlException;
10433 }
10434 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10435 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010436 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010437 mask_image=DestroyImage(mask_image);
10438 break;
10439 }
10440 case 107: /* LinearStretch */
10441 {
10442 double
10443 black_point,
10444 white_point;
10445
10446 black_point=0.0;
10447 white_point=(double) image->columns*image->rows;
10448 if (attribute_flag[0] != 0)
10449 {
10450 flags=ParseGeometry(argument_list[0].string_reference,
10451 &geometry_info);
10452 if ((flags & SigmaValue) != 0)
10453 white_point=geometry_info.sigma;
10454 if ((flags & PercentValue) != 0)
10455 {
10456 black_point*=(double) image->columns*image->rows/100.0;
10457 white_point*=(double) image->columns*image->rows/100.0;
10458 }
10459 if ((flags & SigmaValue) == 0)
10460 white_point=(double) image->columns*image->rows-black_point;
10461 }
10462 if (attribute_flag[1] != 0)
10463 black_point=argument_list[1].real_reference;
10464 if (attribute_flag[2] != 0)
10465 white_point=argument_list[2].real_reference;
10466 (void) LinearStretchImage(image,black_point,white_point,exception);
10467 break;
10468 }
10469 case 108: /* ColorMatrix */
10470 {
10471 AV
10472 *av;
10473
10474 double
10475 *color_matrix;
10476
10477 KernelInfo
10478 *kernel_info;
10479
10480 size_t
10481 order;
10482
10483 if (attribute_flag[0] == 0)
10484 break;
10485 av=(AV *) argument_list[0].array_reference;
10486 order=(size_t) sqrt(av_len(av)+1);
10487 color_matrix=(double *) AcquireQuantumMemory(order,order*
10488 sizeof(*color_matrix));
10489 if (color_matrix == (double *) NULL)
10490 {
10491 ThrowPerlException(exception,ResourceLimitFatalError,
10492 "MemoryAllocationFailed",PackageName);
10493 goto PerlException;
10494 }
10495 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10496 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10497 for ( ; j < (ssize_t) (order*order); j++)
10498 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010499 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010500 if (kernel_info == (KernelInfo *) NULL)
10501 break;
10502 kernel_info->width=order;
10503 kernel_info->height=order;
10504 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10505 order*sizeof(*kernel_info->values));
10506 if (kernel_info->values != (MagickRealType *) NULL)
10507 {
10508 for (i=0; i < (ssize_t) (order*order); i++)
10509 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10510 image=ColorMatrixImage(image,kernel_info,exception);
10511 }
10512 kernel_info=DestroyKernelInfo(kernel_info);
10513 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10514 break;
10515 }
10516 case 109: /* Mask */
10517 {
10518 Image
10519 *mask_image;
10520
10521 if (attribute_flag[0] == 0)
10522 {
10523 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10524 PackageName);
10525 goto PerlException;
10526 }
10527 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10528 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010529 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010530 mask_image=DestroyImage(mask_image);
10531 break;
10532 }
10533 case 110: /* Polaroid */
10534 {
10535 char
10536 *caption;
10537
10538 DrawInfo
10539 *draw_info;
10540
10541 double
10542 angle;
10543
10544 PixelInterpolateMethod
10545 method;
10546
10547 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10548 (DrawInfo *) NULL);
10549 caption=(char *) NULL;
10550 if (attribute_flag[0] != 0)
10551 caption=InterpretImageProperties(info ? info->image_info :
10552 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10553 exception);
10554 angle=0.0;
10555 if (attribute_flag[1] != 0)
10556 angle=argument_list[1].real_reference;
10557 if (attribute_flag[2] != 0)
10558 (void) CloneString(&draw_info->font,
10559 argument_list[2].string_reference);
10560 if (attribute_flag[3] != 0)
10561 (void) QueryColorCompliance(argument_list[3].string_reference,
10562 AllCompliance,&draw_info->stroke,exception);
10563 if (attribute_flag[4] != 0)
10564 (void) QueryColorCompliance(argument_list[4].string_reference,
10565 AllCompliance,&draw_info->fill,exception);
10566 if (attribute_flag[5] != 0)
10567 draw_info->stroke_width=argument_list[5].real_reference;
10568 if (attribute_flag[6] != 0)
10569 draw_info->pointsize=argument_list[6].real_reference;
10570 if (attribute_flag[7] != 0)
10571 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10572 if (attribute_flag[8] != 0)
10573 (void) QueryColorCompliance(argument_list[8].string_reference,
10574 AllCompliance,&image->background_color,exception);
10575 method=UndefinedInterpolatePixel;
10576 if (attribute_flag[9] != 0)
10577 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10578 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10579 draw_info=DestroyDrawInfo(draw_info);
10580 if (caption != (char *) NULL)
10581 caption=DestroyString(caption);
10582 break;
10583 }
10584 case 111: /* FloodfillPaint */
10585 {
10586 DrawInfo
10587 *draw_info;
10588
10589 MagickBooleanType
10590 invert;
10591
10592 PixelInfo
10593 target;
10594
10595 draw_info=CloneDrawInfo(info ? info->image_info :
10596 (ImageInfo *) NULL,(DrawInfo *) NULL);
10597 if (attribute_flag[0] != 0)
10598 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10599 &geometry,exception);
10600 if (attribute_flag[1] != 0)
10601 geometry.x=argument_list[1].integer_reference;
10602 if (attribute_flag[2] != 0)
10603 geometry.y=argument_list[2].integer_reference;
10604 if (attribute_flag[3] != 0)
10605 (void) QueryColorCompliance(argument_list[3].string_reference,
10606 AllCompliance,&draw_info->fill,exception);
10607 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10608 geometry.x,geometry.y,&target,exception);
10609 if (attribute_flag[4] != 0)
10610 QueryColorCompliance(argument_list[4].string_reference,
10611 AllCompliance,&target,exception);
10612 if (attribute_flag[5] != 0)
10613 image->fuzz=StringToDoubleInterval(
10614 argument_list[5].string_reference,(double) QuantumRange+1.0);
10615 if (attribute_flag[6] != 0)
10616 channel=(ChannelType) argument_list[6].integer_reference;
10617 invert=MagickFalse;
10618 if (attribute_flag[7] != 0)
10619 invert=(MagickBooleanType) argument_list[7].integer_reference;
10620 channel_mask=SetImageChannelMask(image,channel);
10621 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10622 geometry.y,invert,exception);
10623 (void) SetImageChannelMask(image,channel_mask);
10624 draw_info=DestroyDrawInfo(draw_info);
10625 break;
10626 }
10627 case 112: /* Distort */
10628 {
10629 AV
10630 *av;
10631
10632 double
10633 *coordinates;
10634
Cristy8645e042016-02-03 16:35:29 -050010635 DistortMethod
cristy4a3ce0a2013-08-03 20:06:59 +000010636 method;
10637
10638 size_t
10639 number_coordinates;
10640
10641 VirtualPixelMethod
10642 virtual_pixel;
10643
10644 if (attribute_flag[0] == 0)
10645 break;
10646 method=UndefinedDistortion;
10647 if (attribute_flag[1] != 0)
Cristy8645e042016-02-03 16:35:29 -050010648 method=(DistortMethod) argument_list[1].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010649 av=(AV *) argument_list[0].array_reference;
10650 number_coordinates=(size_t) av_len(av)+1;
10651 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10652 sizeof(*coordinates));
10653 if (coordinates == (double *) NULL)
10654 {
10655 ThrowPerlException(exception,ResourceLimitFatalError,
10656 "MemoryAllocationFailed",PackageName);
10657 goto PerlException;
10658 }
10659 for (j=0; j < (ssize_t) number_coordinates; j++)
10660 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10661 virtual_pixel=UndefinedVirtualPixelMethod;
10662 if (attribute_flag[2] != 0)
10663 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10664 argument_list[2].integer_reference,exception);
10665 image=DistortImage(image,method,number_coordinates,coordinates,
10666 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10667 exception);
10668 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10669 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10670 exception);
10671 coordinates=(double *) RelinquishMagickMemory(coordinates);
10672 break;
10673 }
10674 case 113: /* Clut */
10675 {
10676 PixelInterpolateMethod
10677 method;
10678
10679 if (attribute_flag[0] == 0)
10680 {
10681 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10682 PackageName);
10683 goto PerlException;
10684 }
10685 method=UndefinedInterpolatePixel;
10686 if (attribute_flag[1] != 0)
10687 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10688 if (attribute_flag[2] != 0)
10689 channel=(ChannelType) argument_list[2].integer_reference;
10690 channel_mask=SetImageChannelMask(image,channel);
10691 (void) ClutImage(image,argument_list[0].image_reference,method,
10692 exception);
10693 (void) SetImageChannelMask(image,channel_mask);
10694 break;
10695 }
10696 case 114: /* LiquidRescale */
10697 {
10698 if (attribute_flag[0] != 0)
10699 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10700 &geometry,exception);
10701 if (attribute_flag[1] != 0)
10702 geometry.width=argument_list[1].integer_reference;
10703 if (attribute_flag[2] != 0)
10704 geometry.height=argument_list[2].integer_reference;
10705 if (attribute_flag[3] == 0)
10706 argument_list[3].real_reference=1.0;
10707 if (attribute_flag[4] == 0)
10708 argument_list[4].real_reference=0.0;
10709 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10710 argument_list[3].real_reference,argument_list[4].real_reference,
10711 exception);
10712 break;
10713 }
10714 case 115: /* EncipherImage */
10715 {
10716 (void) EncipherImage(image,argument_list[0].string_reference,
10717 exception);
10718 break;
10719 }
10720 case 116: /* DecipherImage */
10721 {
10722 (void) DecipherImage(image,argument_list[0].string_reference,
10723 exception);
10724 break;
10725 }
10726 case 117: /* Deskew */
10727 {
10728 geometry_info.rho=QuantumRange/2.0;
10729 if (attribute_flag[0] != 0)
10730 flags=ParseGeometry(argument_list[0].string_reference,
10731 &geometry_info);
10732 if (attribute_flag[1] != 0)
10733 geometry_info.rho=StringToDoubleInterval(
10734 argument_list[1].string_reference,(double) QuantumRange+1.0);
10735 image=DeskewImage(image,geometry_info.rho,exception);
10736 break;
10737 }
10738 case 118: /* Remap */
10739 {
10740 QuantizeInfo
10741 *quantize_info;
10742
10743 if (attribute_flag[0] == 0)
10744 {
10745 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10746 PackageName);
10747 goto PerlException;
10748 }
10749 quantize_info=AcquireQuantizeInfo(info->image_info);
10750 if (attribute_flag[1] != 0)
10751 quantize_info->dither_method=(DitherMethod)
10752 argument_list[1].integer_reference;
10753 (void) RemapImages(quantize_info,image,
10754 argument_list[0].image_reference,exception);
10755 quantize_info=DestroyQuantizeInfo(quantize_info);
10756 break;
10757 }
10758 case 119: /* SparseColor */
10759 {
10760 AV
10761 *av;
10762
10763 double
10764 *coordinates;
10765
10766 SparseColorMethod
10767 method;
10768
10769 size_t
10770 number_coordinates;
10771
10772 VirtualPixelMethod
10773 virtual_pixel;
10774
10775 if (attribute_flag[0] == 0)
10776 break;
10777 method=UndefinedColorInterpolate;
10778 if (attribute_flag[1] != 0)
10779 method=(SparseColorMethod) argument_list[1].integer_reference;
10780 av=(AV *) argument_list[0].array_reference;
10781 number_coordinates=(size_t) av_len(av)+1;
10782 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10783 sizeof(*coordinates));
10784 if (coordinates == (double *) NULL)
10785 {
10786 ThrowPerlException(exception,ResourceLimitFatalError,
10787 "MemoryAllocationFailed",PackageName);
10788 goto PerlException;
10789 }
10790 for (j=0; j < (ssize_t) number_coordinates; j++)
10791 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10792 virtual_pixel=UndefinedVirtualPixelMethod;
10793 if (attribute_flag[2] != 0)
10794 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10795 argument_list[2].integer_reference,exception);
10796 if (attribute_flag[3] != 0)
10797 channel=(ChannelType) argument_list[3].integer_reference;
10798 channel_mask=SetImageChannelMask(image,channel);
10799 image=SparseColorImage(image,method,number_coordinates,coordinates,
10800 exception);
10801 if (image != (Image *) NULL)
10802 (void) SetImageChannelMask(image,channel_mask);
10803 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10804 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10805 exception);
10806 coordinates=(double *) RelinquishMagickMemory(coordinates);
10807 break;
10808 }
10809 case 120: /* Function */
10810 {
10811 AV
10812 *av;
10813
10814 double
10815 *parameters;
10816
10817 MagickFunction
10818 function;
10819
10820 size_t
10821 number_parameters;
10822
10823 VirtualPixelMethod
10824 virtual_pixel;
10825
10826 if (attribute_flag[0] == 0)
10827 break;
10828 function=UndefinedFunction;
10829 if (attribute_flag[1] != 0)
10830 function=(MagickFunction) argument_list[1].integer_reference;
10831 av=(AV *) argument_list[0].array_reference;
10832 number_parameters=(size_t) av_len(av)+1;
10833 parameters=(double *) AcquireQuantumMemory(number_parameters,
10834 sizeof(*parameters));
10835 if (parameters == (double *) NULL)
10836 {
10837 ThrowPerlException(exception,ResourceLimitFatalError,
10838 "MemoryAllocationFailed",PackageName);
10839 goto PerlException;
10840 }
10841 for (j=0; j < (ssize_t) number_parameters; j++)
10842 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10843 virtual_pixel=UndefinedVirtualPixelMethod;
10844 if (attribute_flag[2] != 0)
10845 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10846 argument_list[2].integer_reference,exception);
10847 (void) FunctionImage(image,function,number_parameters,parameters,
10848 exception);
10849 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10850 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10851 exception);
10852 parameters=(double *) RelinquishMagickMemory(parameters);
10853 break;
10854 }
10855 case 121: /* SelectiveBlur */
10856 {
10857 if (attribute_flag[0] != 0)
10858 {
10859 flags=ParseGeometry(argument_list[0].string_reference,
10860 &geometry_info);
10861 if ((flags & SigmaValue) == 0)
10862 geometry_info.sigma=1.0;
10863 if ((flags & PercentValue) != 0)
10864 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10865 }
10866 if (attribute_flag[1] != 0)
10867 geometry_info.rho=argument_list[1].real_reference;
10868 if (attribute_flag[2] != 0)
10869 geometry_info.sigma=argument_list[2].real_reference;
10870 if (attribute_flag[3] != 0)
10871 geometry_info.xi=argument_list[3].integer_reference;;
10872 if (attribute_flag[5] != 0)
10873 channel=(ChannelType) argument_list[5].integer_reference;
10874 channel_mask=SetImageChannelMask(image,channel);
10875 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10876 geometry_info.xi,exception);
10877 if (image != (Image *) NULL)
10878 (void) SetImageChannelMask(image,channel_mask);
10879 break;
10880 }
10881 case 122: /* HaldClut */
10882 {
10883 if (attribute_flag[0] == 0)
10884 {
10885 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10886 PackageName);
10887 goto PerlException;
10888 }
10889 if (attribute_flag[1] != 0)
10890 channel=(ChannelType) argument_list[1].integer_reference;
10891 channel_mask=SetImageChannelMask(image,channel);
10892 (void) HaldClutImage(image,argument_list[0].image_reference,
10893 exception);
10894 (void) SetImageChannelMask(image,channel_mask);
10895 break;
10896 }
10897 case 123: /* BlueShift */
10898 {
10899 if (attribute_flag[0] != 0)
10900 (void) ParseGeometry(argument_list[0].string_reference,
10901 &geometry_info);
10902 image=BlueShiftImage(image,geometry_info.rho,exception);
10903 break;
10904 }
10905 case 124: /* ForwardFourierTransformImage */
10906 {
10907 image=ForwardFourierTransformImage(image,
10908 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10909 exception);
10910 break;
10911 }
10912 case 125: /* InverseFourierTransformImage */
10913 {
10914 image=InverseFourierTransformImage(image,image->next,
10915 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10916 exception);
10917 break;
10918 }
10919 case 126: /* ColorDecisionList */
10920 {
10921 if (attribute_flag[0] == 0)
10922 argument_list[0].string_reference=(char *) NULL;
10923 (void) ColorDecisionListImage(image,
10924 argument_list[0].string_reference,exception);
10925 break;
10926 }
10927 case 127: /* AutoGamma */
10928 {
10929 if (attribute_flag[0] != 0)
10930 channel=(ChannelType) argument_list[0].integer_reference;
10931 channel_mask=SetImageChannelMask(image,channel);
10932 (void) AutoGammaImage(image,exception);
10933 (void) SetImageChannelMask(image,channel_mask);
10934 break;
10935 }
10936 case 128: /* AutoLevel */
10937 {
10938 if (attribute_flag[0] != 0)
10939 channel=(ChannelType) argument_list[0].integer_reference;
10940 channel_mask=SetImageChannelMask(image,channel);
10941 (void) AutoLevelImage(image,exception);
10942 (void) SetImageChannelMask(image,channel_mask);
10943 break;
10944 }
10945 case 129: /* LevelColors */
10946 {
10947 PixelInfo
10948 black_point,
10949 white_point;
10950
10951 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10952 exception);
10953 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10954 exception);
10955 if (attribute_flag[1] != 0)
10956 (void) QueryColorCompliance(
10957 argument_list[1].string_reference,AllCompliance,&black_point,
10958 exception);
10959 if (attribute_flag[2] != 0)
10960 (void) QueryColorCompliance(
10961 argument_list[2].string_reference,AllCompliance,&white_point,
10962 exception);
10963 if (attribute_flag[3] != 0)
10964 channel=(ChannelType) argument_list[3].integer_reference;
10965 channel_mask=SetImageChannelMask(image,channel);
10966 (void) LevelImageColors(image,&black_point,&white_point,
10967 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10968 exception);
10969 (void) SetImageChannelMask(image,channel_mask);
10970 break;
10971 }
10972 case 130: /* Clamp */
10973 {
10974 if (attribute_flag[0] != 0)
10975 channel=(ChannelType) argument_list[0].integer_reference;
10976 channel_mask=SetImageChannelMask(image,channel);
10977 (void) ClampImage(image,exception);
10978 (void) SetImageChannelMask(image,channel_mask);
10979 break;
10980 }
10981 case 131: /* BrightnessContrast */
10982 {
10983 double
10984 brightness,
10985 contrast;
10986
10987 brightness=0.0;
10988 contrast=0.0;
10989 if (attribute_flag[0] != 0)
10990 {
10991 flags=ParseGeometry(argument_list[0].string_reference,
10992 &geometry_info);
10993 brightness=geometry_info.rho;
10994 if ((flags & SigmaValue) == 0)
10995 contrast=geometry_info.sigma;
10996 }
10997 if (attribute_flag[1] != 0)
10998 brightness=argument_list[1].real_reference;
10999 if (attribute_flag[2] != 0)
11000 contrast=argument_list[2].real_reference;
11001 if (attribute_flag[4] != 0)
11002 channel=(ChannelType) argument_list[4].integer_reference;
11003 channel_mask=SetImageChannelMask(image,channel);
11004 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11005 (void) SetImageChannelMask(image,channel_mask);
11006 break;
11007 }
11008 case 132: /* Morphology */
11009 {
11010 KernelInfo
11011 *kernel;
11012
11013 MorphologyMethod
11014 method;
11015
11016 ssize_t
11017 iterations;
11018
11019 if (attribute_flag[0] == 0)
11020 break;
cristy2c57b742014-10-31 00:40:34 +000011021 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011022 if (kernel == (KernelInfo *) NULL)
11023 break;
11024 if (attribute_flag[1] != 0)
11025 channel=(ChannelType) argument_list[1].integer_reference;
11026 method=UndefinedMorphology;
11027 if (attribute_flag[2] != 0)
11028 method=argument_list[2].integer_reference;
11029 iterations=1;
11030 if (attribute_flag[3] != 0)
11031 iterations=argument_list[3].integer_reference;
11032 channel_mask=SetImageChannelMask(image,channel);
11033 image=MorphologyImage(image,method,iterations,kernel,exception);
11034 if (image != (Image *) NULL)
11035 (void) SetImageChannelMask(image,channel_mask);
11036 kernel=DestroyKernelInfo(kernel);
11037 break;
11038 }
11039 case 133: /* Mode */
11040 {
11041 if (attribute_flag[0] != 0)
11042 {
11043 flags=ParseGeometry(argument_list[0].string_reference,
11044 &geometry_info);
11045 if ((flags & SigmaValue) == 0)
11046 geometry_info.sigma=1.0;
11047 }
11048 if (attribute_flag[1] != 0)
11049 geometry_info.rho=argument_list[1].real_reference;
11050 if (attribute_flag[2] != 0)
11051 geometry_info.sigma=argument_list[2].real_reference;
11052 if (attribute_flag[3] != 0)
11053 channel=(ChannelType) argument_list[3].integer_reference;
11054 channel_mask=SetImageChannelMask(image,channel);
11055 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11056 (size_t) geometry_info.sigma,exception);
11057 if (image != (Image *) NULL)
11058 (void) SetImageChannelMask(image,channel_mask);
11059 break;
11060 }
11061 case 134: /* Statistic */
11062 {
11063 StatisticType
11064 statistic;
11065
11066 statistic=UndefinedStatistic;
11067 if (attribute_flag[0] != 0)
11068 {
11069 flags=ParseGeometry(argument_list[0].string_reference,
11070 &geometry_info);
11071 if ((flags & SigmaValue) == 0)
11072 geometry_info.sigma=1.0;
11073 }
11074 if (attribute_flag[1] != 0)
11075 geometry_info.rho=argument_list[1].real_reference;
11076 if (attribute_flag[2] != 0)
11077 geometry_info.sigma=argument_list[2].real_reference;
11078 if (attribute_flag[3] != 0)
11079 channel=(ChannelType) argument_list[3].integer_reference;
11080 if (attribute_flag[4] != 0)
11081 statistic=(StatisticType) argument_list[4].integer_reference;
11082 channel_mask=SetImageChannelMask(image,channel);
11083 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11084 (size_t) geometry_info.sigma,exception);
11085 if (image != (Image *) NULL)
11086 (void) SetImageChannelMask(image,channel_mask);
11087 break;
11088 }
11089 case 135: /* Perceptible */
11090 {
11091 double
11092 epsilon;
11093
11094 epsilon=MagickEpsilon;
11095 if (attribute_flag[0] != 0)
11096 epsilon=argument_list[0].real_reference;
11097 if (attribute_flag[1] != 0)
11098 channel=(ChannelType) argument_list[1].integer_reference;
11099 channel_mask=SetImageChannelMask(image,channel);
11100 (void) PerceptibleImage(image,epsilon,exception);
11101 (void) SetImageChannelMask(image,channel_mask);
11102 break;
11103 }
11104 case 136: /* Poly */
11105 {
11106 AV
11107 *av;
11108
11109 double
11110 *terms;
11111
11112 size_t
11113 number_terms;
11114
11115 if (attribute_flag[0] == 0)
11116 break;
11117 if (attribute_flag[1] != 0)
11118 channel=(ChannelType) argument_list[1].integer_reference;
11119 av=(AV *) argument_list[0].array_reference;
11120 number_terms=(size_t) av_len(av);
11121 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11122 if (terms == (double *) NULL)
11123 {
11124 ThrowPerlException(exception,ResourceLimitFatalError,
11125 "MemoryAllocationFailed",PackageName);
11126 goto PerlException;
11127 }
11128 for (j=0; j < av_len(av); j++)
11129 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11130 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11131 terms=(double *) RelinquishMagickMemory(terms);
11132 break;
11133 }
11134 case 137: /* Grayscale */
11135 {
11136 PixelIntensityMethod
11137 method;
11138
11139 method=UndefinedPixelIntensityMethod;
11140 if (attribute_flag[0] != 0)
11141 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11142 (void) GrayscaleImage(image,method,exception);
11143 break;
11144 }
cristy4ceadb82014-03-29 15:30:43 +000011145 case 138: /* Canny */
11146 {
11147 if (attribute_flag[0] != 0)
11148 {
11149 flags=ParseGeometry(argument_list[0].string_reference,
11150 &geometry_info);
11151 if ((flags & SigmaValue) == 0)
11152 geometry_info.sigma=1.0;
11153 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011154 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011155 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011156 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011157 if ((flags & PercentValue) != 0)
11158 {
11159 geometry_info.xi/=100.0;
11160 geometry_info.psi/=100.0;
11161 }
cristy4ceadb82014-03-29 15:30:43 +000011162 }
11163 if (attribute_flag[1] != 0)
11164 geometry_info.rho=argument_list[1].real_reference;
11165 if (attribute_flag[2] != 0)
11166 geometry_info.sigma=argument_list[2].real_reference;
11167 if (attribute_flag[3] != 0)
11168 geometry_info.xi=argument_list[3].real_reference;
11169 if (attribute_flag[4] != 0)
11170 geometry_info.psi=argument_list[4].real_reference;
11171 if (attribute_flag[5] != 0)
11172 channel=(ChannelType) argument_list[5].integer_reference;
11173 channel_mask=SetImageChannelMask(image,channel);
11174 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11175 geometry_info.xi,geometry_info.psi,exception);
11176 if (image != (Image *) NULL)
11177 (void) SetImageChannelMask(image,channel_mask);
11178 break;
11179 }
cristy2fc10e52014-04-26 14:13:53 +000011180 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011181 {
11182 if (attribute_flag[0] != 0)
11183 {
11184 flags=ParseGeometry(argument_list[0].string_reference,
11185 &geometry_info);
11186 if ((flags & SigmaValue) == 0)
11187 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011188 if ((flags & XiValue) == 0)
11189 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011190 }
11191 if (attribute_flag[1] != 0)
11192 geometry_info.rho=(double) argument_list[1].integer_reference;
11193 if (attribute_flag[2] != 0)
11194 geometry_info.sigma=(double) argument_list[2].integer_reference;
11195 if (attribute_flag[3] != 0)
11196 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011197 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11198 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11199 break;
11200 }
11201 case 140: /* MeanShift */
11202 {
11203 if (attribute_flag[0] != 0)
11204 {
11205 flags=ParseGeometry(argument_list[0].string_reference,
11206 &geometry_info);
11207 if ((flags & SigmaValue) == 0)
11208 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011209 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011210 geometry_info.xi=0.10*QuantumRange;
11211 if ((flags & PercentValue) != 0)
11212 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011213 }
11214 if (attribute_flag[1] != 0)
11215 geometry_info.rho=(double) argument_list[1].integer_reference;
11216 if (attribute_flag[2] != 0)
11217 geometry_info.sigma=(double) argument_list[2].integer_reference;
11218 if (attribute_flag[3] != 0)
11219 geometry_info.xi=(double) argument_list[3].integer_reference;
11220 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011221 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011222 break;
11223 }
cristy3b207f82014-09-27 14:21:20 +000011224 case 141: /* Kuwahara */
11225 {
11226 if (attribute_flag[0] != 0)
11227 {
11228 flags=ParseGeometry(argument_list[0].string_reference,
11229 &geometry_info);
11230 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011231 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011232 }
11233 if (attribute_flag[1] != 0)
11234 geometry_info.rho=argument_list[1].real_reference;
11235 if (attribute_flag[2] != 0)
11236 geometry_info.sigma=argument_list[2].real_reference;
11237 if (attribute_flag[3] != 0)
11238 channel=(ChannelType) argument_list[3].integer_reference;
11239 channel_mask=SetImageChannelMask(image,channel);
11240 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11241 exception);
11242 if (image != (Image *) NULL)
11243 (void) SetImageChannelMask(image,channel_mask);
11244 break;
11245 }
cristy6e0b3bc2014-10-19 17:51:42 +000011246 case 142: /* ConnectedComponent */
11247 {
11248 size_t
11249 connectivity;
11250
11251 connectivity=4;
11252 if (attribute_flag[0] != 0)
11253 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011254 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011255 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011256 break;
11257 }
cristy0b94b392015-06-22 18:56:37 +000011258 case 143: /* Copy */
11259 {
11260 Image
11261 *source_image;
11262
11263 OffsetInfo
11264 offset;
11265
cristy2ffdb092015-06-25 14:31:20 +000011266 RectangleInfo
11267 offset_geometry;
11268
cristyf3a724a2015-06-25 13:02:53 +000011269 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011270 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011271 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011272 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011273 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011274 flags=ParseGravityGeometry(source_image,
11275 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011276 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011277 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011278 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011279 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011280 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011281 geometry.x=argument_list[4].integer_reference;
11282 if (attribute_flag[5] != 0)
11283 geometry.y=argument_list[5].integer_reference;
11284 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011285 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011286 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011287 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011288 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11289 &offset_geometry,exception);
11290 offset.x=offset_geometry.x;
11291 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011292 if (attribute_flag[8] != 0)
11293 offset.x=argument_list[8].integer_reference;
11294 if (attribute_flag[9] != 0)
11295 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011296 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11297 exception);
cristy0b94b392015-06-22 18:56:37 +000011298 break;
11299 }
Cristy5488c982016-02-13 14:07:50 -050011300 case 144: /* Color */
11301 {
11302 PixelInfo
11303 color;
11304
Cristyf20e3562016-02-14 09:08:15 -050011305 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011306 if (attribute_flag[0] != 0)
Cristyf20e3562016-02-14 09:08:15 -050011307 (void) QueryColorCompliance(argument_list[0].string_reference,
11308 AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011309 (void) SetImageColor(image,&color,exception);
11310 break;
11311 }
Cristy2d830ed2016-02-21 10:54:16 -050011312 case 145: /* WaveletDenoise */
11313 {
Cristyc1759412016-02-27 12:17:58 -050011314 if (attribute_flag[0] != 0)
Cristyee21f7f2016-02-27 15:56:49 -050011315 {
11316 flags=ParseGeometry(argument_list[0].string_reference,
11317 &geometry_info);
11318 if ((flags & PercentValue) != 0)
Cristy23446632016-02-29 09:36:34 -050011319 {
11320 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11321 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
11322 }
Cristyee21f7f2016-02-27 15:56:49 -050011323 if ((flags & SigmaValue) == 0)
11324 geometry_info.sigma=0.0;
11325 }
Cristyc1759412016-02-27 12:17:58 -050011326 if (attribute_flag[1] != 0)
11327 geometry_info.rho=argument_list[1].real_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011328 if (attribute_flag[2] != 0)
Cristyc1759412016-02-27 12:17:58 -050011329 geometry_info.sigma=argument_list[2].real_reference;
11330 if (attribute_flag[3] != 0)
11331 channel=(ChannelType) argument_list[3].integer_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011332 channel_mask=SetImageChannelMask(image,channel);
Cristyc1759412016-02-27 12:17:58 -050011333 image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11334 exception);
Cristy2d830ed2016-02-21 10:54:16 -050011335 if (image != (Image *) NULL)
11336 (void) SetImageChannelMask(image,channel_mask);
11337 break;
11338 }
Cristy99a57162016-12-05 11:47:57 -050011339 case 146: /* Colorspace */
11340 {
11341 ColorspaceType
11342 colorspace;
11343
11344 colorspace=sRGBColorspace;
11345 if (attribute_flag[0] != 0)
11346 colorspace=(ColorspaceType) argument_list[0].integer_reference;
11347 (void) TransformImageColorspace(image,colorspace,exception);
11348 break;
11349 }
cristy4a3ce0a2013-08-03 20:06:59 +000011350 }
11351 if (next != (Image *) NULL)
11352 (void) CatchImageException(next);
11353 if (region_image != (Image *) NULL)
11354 {
11355 /*
11356 Composite region.
cristy83a28a02013-08-03 20:25:48 +000011357 */
cristy4a3ce0a2013-08-03 20:06:59 +000011358 status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11359 region_info.x,region_info.y,exception);
11360 (void) status;
11361 (void) CatchImageException(region_image);
11362 image=DestroyImage(image);
11363 image=region_image;
11364 }
11365 if (image != (Image *) NULL)
11366 {
11367 number_images++;
11368 if (next && (next != image))
11369 {
11370 image->next=next->next;
11371 if (image->next != (Image *) NULL)
11372 image->next->previous=image;
11373 DeleteImageFromRegistry(*pv,next);
11374 }
11375 sv_setiv(*pv,PTR2IV(image));
11376 next=image;
11377 }
11378 if (*pv)
11379 pv++;
11380 }
11381
11382 PerlException:
11383 if (reference_vector)
11384 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11385 InheritPerlException(exception,perl_exception);
11386 exception=DestroyExceptionInfo(exception);
11387 sv_setiv(perl_exception,(IV) number_images);
11388 SvPOK_on(perl_exception);
11389 ST(0)=sv_2mortal(perl_exception);
11390 XSRETURN(1);
11391 }
11392
11393#
11394###############################################################################
11395# #
11396# #
11397# #
11398# M o n t a g e #
11399# #
11400# #
11401# #
11402###############################################################################
11403#
11404#
11405void
11406Montage(ref,...)
11407 Image::Magick ref=NO_INIT
11408 ALIAS:
11409 MontageImage = 1
11410 montage = 2
11411 montageimage = 3
11412 PPCODE:
11413 {
11414 AV
11415 *av;
11416
11417 char
11418 *attribute;
11419
11420 ExceptionInfo
11421 *exception;
11422
11423 HV
11424 *hv;
11425
11426 Image
11427 *image,
11428 *next;
11429
11430 PixelInfo
11431 transparent_color;
11432
11433 MontageInfo
11434 *montage_info;
11435
11436 register ssize_t
11437 i;
11438
11439 ssize_t
11440 sp;
11441
11442 struct PackageInfo
11443 *info;
11444
11445 SV
11446 *av_reference,
11447 *perl_exception,
11448 *reference,
11449 *rv,
11450 *sv;
11451
11452 PERL_UNUSED_VAR(ref);
11453 PERL_UNUSED_VAR(ix);
11454 exception=AcquireExceptionInfo();
11455 perl_exception=newSVpv("",0);
11456 sv=NULL;
11457 attribute=NULL;
11458 if (sv_isobject(ST(0)) == 0)
11459 {
11460 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11461 PackageName);
11462 goto PerlException;
11463 }
11464 reference=SvRV(ST(0));
11465 hv=SvSTASH(reference);
11466 av=newAV();
11467 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11468 SvREFCNT_dec(av);
11469 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11470 if (image == (Image *) NULL)
11471 {
11472 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11473 PackageName);
11474 goto PerlException;
11475 }
11476 /*
11477 Get options.
11478 */
11479 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11480 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11481 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11482 exception);
11483 for (i=2; i < items; i+=2)
11484 {
11485 attribute=(char *) SvPV(ST(i-1),na);
11486 switch (*attribute)
11487 {
11488 case 'B':
11489 case 'b':
11490 {
11491 if (LocaleCompare(attribute,"background") == 0)
11492 {
11493 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11494 &montage_info->background_color,exception);
11495 for (next=image; next; next=next->next)
11496 next->background_color=montage_info->background_color;
11497 break;
11498 }
11499 if (LocaleCompare(attribute,"border") == 0)
11500 {
11501 montage_info->border_width=SvIV(ST(i));
11502 break;
11503 }
11504 if (LocaleCompare(attribute,"bordercolor") == 0)
11505 {
11506 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11507 &montage_info->border_color,exception);
11508 for (next=image; next; next=next->next)
11509 next->border_color=montage_info->border_color;
11510 break;
11511 }
11512 if (LocaleCompare(attribute,"borderwidth") == 0)
11513 {
11514 montage_info->border_width=SvIV(ST(i));
11515 break;
11516 }
11517 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11518 attribute);
11519 break;
11520 }
11521 case 'C':
11522 case 'c':
11523 {
11524 if (LocaleCompare(attribute,"compose") == 0)
11525 {
11526 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11527 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11528 if (sp < 0)
11529 {
11530 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11531 SvPV(ST(i),na));
11532 break;
11533 }
11534 for (next=image; next; next=next->next)
11535 next->compose=(CompositeOperator) sp;
11536 break;
11537 }
11538 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11539 attribute);
11540 break;
11541 }
11542 case 'F':
11543 case 'f':
11544 {
11545 if (LocaleCompare(attribute,"fill") == 0)
11546 {
11547 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11548 &montage_info->fill,exception);
11549 break;
11550 }
11551 if (LocaleCompare(attribute,"font") == 0)
11552 {
11553 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11554 break;
11555 }
11556 if (LocaleCompare(attribute,"frame") == 0)
11557 {
11558 char
11559 *p;
11560
11561 p=SvPV(ST(i),na);
11562 if (IsGeometry(p) == MagickFalse)
11563 {
11564 ThrowPerlException(exception,OptionError,"MissingGeometry",
11565 p);
11566 break;
11567 }
11568 (void) CloneString(&montage_info->frame,p);
11569 if (*p == '\0')
11570 montage_info->frame=(char *) NULL;
11571 break;
11572 }
11573 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11574 attribute);
11575 break;
11576 }
11577 case 'G':
11578 case 'g':
11579 {
11580 if (LocaleCompare(attribute,"geometry") == 0)
11581 {
11582 char
11583 *p;
11584
11585 p=SvPV(ST(i),na);
11586 if (IsGeometry(p) == MagickFalse)
11587 {
11588 ThrowPerlException(exception,OptionError,"MissingGeometry",
11589 p);
11590 break;
11591 }
11592 (void) CloneString(&montage_info->geometry,p);
11593 if (*p == '\0')
11594 montage_info->geometry=(char *) NULL;
11595 break;
11596 }
11597 if (LocaleCompare(attribute,"gravity") == 0)
11598 {
11599 ssize_t
11600 in;
11601
11602 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11603 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11604 if (in < 0)
11605 {
11606 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11607 SvPV(ST(i),na));
11608 return;
11609 }
11610 montage_info->gravity=(GravityType) in;
11611 for (next=image; next; next=next->next)
11612 next->gravity=(GravityType) in;
11613 break;
11614 }
11615 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11616 attribute);
11617 break;
11618 }
11619 case 'L':
11620 case 'l':
11621 {
11622 if (LocaleCompare(attribute,"label") == 0)
11623 {
11624 for (next=image; next; next=next->next)
11625 (void) SetImageProperty(next,"label",InterpretImageProperties(
11626 info ? info->image_info : (ImageInfo *) NULL,next,
11627 SvPV(ST(i),na),exception),exception);
11628 break;
11629 }
11630 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11631 attribute);
11632 break;
11633 }
11634 case 'M':
11635 case 'm':
11636 {
11637 if (LocaleCompare(attribute,"mattecolor") == 0)
11638 {
11639 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
Cristy8645e042016-02-03 16:35:29 -050011640 &montage_info->alpha_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011641 for (next=image; next; next=next->next)
Cristy8645e042016-02-03 16:35:29 -050011642 next->alpha_color=montage_info->alpha_color;
cristy4a3ce0a2013-08-03 20:06:59 +000011643 break;
11644 }
11645 if (LocaleCompare(attribute,"mode") == 0)
11646 {
11647 ssize_t
11648 in;
11649
11650 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11651 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11652 switch (in)
11653 {
11654 default:
11655 {
11656 ThrowPerlException(exception,OptionError,
11657 "UnrecognizedModeType",SvPV(ST(i),na));
11658 break;
11659 }
11660 case FrameMode:
11661 {
11662 (void) CloneString(&montage_info->frame,"15x15+3+3");
11663 montage_info->shadow=MagickTrue;
11664 break;
11665 }
11666 case UnframeMode:
11667 {
11668 montage_info->frame=(char *) NULL;
11669 montage_info->shadow=MagickFalse;
11670 montage_info->border_width=0;
11671 break;
11672 }
11673 case ConcatenateMode:
11674 {
11675 montage_info->frame=(char *) NULL;
11676 montage_info->shadow=MagickFalse;
11677 (void) CloneString(&montage_info->geometry,"+0+0");
11678 montage_info->border_width=0;
11679 }
11680 }
11681 break;
11682 }
11683 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11684 attribute);
11685 break;
11686 }
11687 case 'P':
11688 case 'p':
11689 {
11690 if (LocaleCompare(attribute,"pointsize") == 0)
11691 {
11692 montage_info->pointsize=SvIV(ST(i));
11693 break;
11694 }
11695 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11696 attribute);
11697 break;
11698 }
11699 case 'S':
11700 case 's':
11701 {
11702 if (LocaleCompare(attribute,"shadow") == 0)
11703 {
11704 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11705 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11706 if (sp < 0)
11707 {
11708 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11709 SvPV(ST(i),na));
11710 break;
11711 }
11712 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11713 break;
11714 }
11715 if (LocaleCompare(attribute,"stroke") == 0)
11716 {
11717 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11718 &montage_info->stroke,exception);
11719 break;
11720 }
11721 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11722 attribute);
11723 break;
11724 }
11725 case 'T':
11726 case 't':
11727 {
11728 if (LocaleCompare(attribute,"texture") == 0)
11729 {
11730 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11731 break;
11732 }
11733 if (LocaleCompare(attribute,"tile") == 0)
11734 {
11735 char *p=SvPV(ST(i),na);
11736 if (IsGeometry(p) == MagickFalse)
11737 {
11738 ThrowPerlException(exception,OptionError,"MissingGeometry",
11739 p);
11740 break;
11741 }
11742 (void) CloneString(&montage_info->tile,p);
11743 if (*p == '\0')
11744 montage_info->tile=(char *) NULL;
11745 break;
11746 }
11747 if (LocaleCompare(attribute,"title") == 0)
11748 {
11749 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11750 break;
11751 }
11752 if (LocaleCompare(attribute,"transparent") == 0)
11753 {
11754 PixelInfo
11755 transparent_color;
11756
11757 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11758 &transparent_color,exception);
11759 for (next=image; next; next=next->next)
11760 (void) TransparentPaintImage(next,&transparent_color,
11761 TransparentAlpha,MagickFalse,exception);
11762 break;
11763 }
11764 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11765 attribute);
11766 break;
11767 }
11768 default:
11769 {
11770 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11771 attribute);
11772 break;
11773 }
11774 }
11775 }
11776 image=MontageImageList(info->image_info,montage_info,image,exception);
11777 montage_info=DestroyMontageInfo(montage_info);
11778 if (image == (Image *) NULL)
11779 goto PerlException;
11780 if (transparent_color.alpha != TransparentAlpha)
11781 for (next=image; next; next=next->next)
11782 (void) TransparentPaintImage(next,&transparent_color,
11783 TransparentAlpha,MagickFalse,exception);
11784 for ( ; image; image=image->next)
11785 {
11786 AddImageToRegistry(sv,image);
11787 rv=newRV(sv);
11788 av_push(av,sv_bless(rv,hv));
11789 SvREFCNT_dec(sv);
11790 }
11791 exception=DestroyExceptionInfo(exception);
11792 ST(0)=av_reference;
11793 SvREFCNT_dec(perl_exception);
11794 XSRETURN(1);
11795
11796 PerlException:
11797 InheritPerlException(exception,perl_exception);
11798 exception=DestroyExceptionInfo(exception);
11799 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11800 SvPOK_on(perl_exception);
11801 ST(0)=sv_2mortal(perl_exception);
11802 XSRETURN(1);
11803 }
11804
11805#
11806###############################################################################
11807# #
11808# #
11809# #
11810# M o r p h #
11811# #
11812# #
11813# #
11814###############################################################################
11815#
11816#
11817void
11818Morph(ref,...)
11819 Image::Magick ref=NO_INIT
11820 ALIAS:
11821 MorphImage = 1
11822 morph = 2
11823 morphimage = 3
11824 PPCODE:
11825 {
11826 AV
11827 *av;
11828
11829 char
11830 *attribute;
11831
11832 ExceptionInfo
11833 *exception;
11834
11835 HV
11836 *hv;
11837
11838 Image
11839 *image;
11840
11841 register ssize_t
11842 i;
11843
11844 ssize_t
11845 number_frames;
11846
11847 struct PackageInfo
11848 *info;
11849
11850 SV
11851 *av_reference,
11852 *perl_exception,
11853 *reference,
11854 *rv,
11855 *sv;
11856
11857 PERL_UNUSED_VAR(ref);
11858 PERL_UNUSED_VAR(ix);
11859 exception=AcquireExceptionInfo();
11860 perl_exception=newSVpv("",0);
11861 sv=NULL;
11862 av=NULL;
11863 attribute=NULL;
11864 if (sv_isobject(ST(0)) == 0)
11865 {
11866 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11867 PackageName);
11868 goto PerlException;
11869 }
11870 reference=SvRV(ST(0));
11871 hv=SvSTASH(reference);
11872 av=newAV();
11873 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11874 SvREFCNT_dec(av);
11875 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11876 if (image == (Image *) NULL)
11877 {
11878 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11879 PackageName);
11880 goto PerlException;
11881 }
11882 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11883 /*
11884 Get attribute.
11885 */
11886 number_frames=30;
11887 for (i=2; i < items; i+=2)
11888 {
11889 attribute=(char *) SvPV(ST(i-1),na);
11890 switch (*attribute)
11891 {
11892 case 'F':
11893 case 'f':
11894 {
11895 if (LocaleCompare(attribute,"frames") == 0)
11896 {
11897 number_frames=SvIV(ST(i));
11898 break;
11899 }
11900 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11901 attribute);
11902 break;
11903 }
11904 default:
11905 {
11906 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11907 attribute);
11908 break;
11909 }
11910 }
11911 }
11912 image=MorphImages(image,number_frames,exception);
11913 if (image == (Image *) NULL)
11914 goto PerlException;
11915 for ( ; image; image=image->next)
11916 {
11917 AddImageToRegistry(sv,image);
11918 rv=newRV(sv);
11919 av_push(av,sv_bless(rv,hv));
11920 SvREFCNT_dec(sv);
11921 }
11922 exception=DestroyExceptionInfo(exception);
11923 ST(0)=av_reference;
11924 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11925 XSRETURN(1);
11926
11927 PerlException:
11928 InheritPerlException(exception,perl_exception);
11929 exception=DestroyExceptionInfo(exception);
11930 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11931 SvPOK_on(perl_exception);
11932 ST(0)=sv_2mortal(perl_exception);
11933 XSRETURN(1);
11934 }
11935
11936#
11937###############################################################################
11938# #
11939# #
11940# #
11941# M o s a i c #
11942# #
11943# #
11944# #
11945###############################################################################
11946#
11947#
11948void
11949Mosaic(ref)
11950 Image::Magick ref=NO_INIT
11951 ALIAS:
11952 MosaicImage = 1
11953 mosaic = 2
11954 mosaicimage = 3
11955 PPCODE:
11956 {
11957 AV
11958 *av;
11959
11960 ExceptionInfo
11961 *exception;
11962
11963 HV
11964 *hv;
11965
11966 Image
11967 *image;
11968
11969 struct PackageInfo
11970 *info;
11971
11972 SV
11973 *perl_exception,
11974 *reference,
11975 *rv,
11976 *sv;
11977
11978 PERL_UNUSED_VAR(ref);
11979 PERL_UNUSED_VAR(ix);
11980 exception=AcquireExceptionInfo();
11981 perl_exception=newSVpv("",0);
11982 sv=NULL;
11983 if (sv_isobject(ST(0)) == 0)
11984 {
11985 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11986 PackageName);
11987 goto PerlException;
11988 }
11989 reference=SvRV(ST(0));
11990 hv=SvSTASH(reference);
11991 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11992 if (image == (Image *) NULL)
11993 {
11994 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11995 PackageName);
11996 goto PerlException;
11997 }
11998 image=MergeImageLayers(image,MosaicLayer,exception);
11999 /*
12000 Create blessed Perl array for the returned image.
12001 */
12002 av=newAV();
12003 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12004 SvREFCNT_dec(av);
12005 AddImageToRegistry(sv,image);
12006 rv=newRV(sv);
12007 av_push(av,sv_bless(rv,hv));
12008 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000012009 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000012010 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012011 SetImageInfo(info->image_info,0,exception);
12012 exception=DestroyExceptionInfo(exception);
12013 SvREFCNT_dec(perl_exception);
12014 XSRETURN(1);
12015
12016 PerlException:
12017 InheritPerlException(exception,perl_exception);
12018 exception=DestroyExceptionInfo(exception);
12019 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12020 SvPOK_on(perl_exception); /* return messages in string context */
12021 ST(0)=sv_2mortal(perl_exception);
12022 XSRETURN(1);
12023 }
12024
12025#
12026###############################################################################
12027# #
12028# #
12029# #
12030# P i n g #
12031# #
12032# #
12033# #
12034###############################################################################
12035#
12036#
12037void
12038Ping(ref,...)
12039 Image::Magick ref=NO_INIT
12040 ALIAS:
12041 PingImage = 1
12042 ping = 2
12043 pingimage = 3
12044 PPCODE:
12045 {
12046 AV
12047 *av;
12048
12049 char
12050 **keep,
12051 **list;
12052
12053 ExceptionInfo
12054 *exception;
12055
12056 Image
12057 *image,
12058 *next;
12059
12060 int
12061 n;
12062
12063 MagickBooleanType
12064 status;
12065
12066 register char
12067 **p;
12068
12069 register ssize_t
12070 i;
12071
12072 ssize_t
12073 ac;
12074
12075 STRLEN
12076 *length;
12077
12078 struct PackageInfo
12079 *info,
12080 *package_info;
12081
12082 SV
12083 *perl_exception,
12084 *reference;
12085
12086 size_t
12087 count;
12088
12089 PERL_UNUSED_VAR(ref);
12090 PERL_UNUSED_VAR(ix);
12091 exception=AcquireExceptionInfo();
12092 perl_exception=newSVpv("",0);
12093 package_info=(struct PackageInfo *) NULL;
12094 ac=(items < 2) ? 1 : items-1;
12095 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12096 keep=list;
12097 length=(STRLEN *) NULL;
12098 if (list == (char **) NULL)
12099 {
12100 ThrowPerlException(exception,ResourceLimitError,
12101 "MemoryAllocationFailed",PackageName);
12102 goto PerlException;
12103 }
12104 keep=list;
12105 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12106 if (length == (STRLEN *) NULL)
12107 {
12108 ThrowPerlException(exception,ResourceLimitError,
12109 "MemoryAllocationFailed",PackageName);
12110 goto PerlException;
12111 }
12112 if (sv_isobject(ST(0)) == 0)
12113 {
12114 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12115 PackageName);
12116 goto PerlException;
12117 }
12118 reference=SvRV(ST(0));
12119 if (SvTYPE(reference) != SVt_PVAV)
12120 {
12121 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12122 PackageName);
12123 goto PerlException;
12124 }
12125 av=(AV *) reference;
12126 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12127 exception);
12128 package_info=ClonePackageInfo(info,exception);
12129 n=1;
12130 if (items <= 1)
12131 *list=(char *) (*package_info->image_info->filename ?
12132 package_info->image_info->filename : "XC:black");
12133 else
12134 for (n=0, i=0; i < ac; i++)
12135 {
12136 list[n]=(char *) SvPV(ST(i+1),length[n]);
12137 if ((items >= 3) && strEQcase(list[n],"blob"))
12138 {
12139 void
12140 *blob;
12141
12142 i++;
12143 blob=(void *) (SvPV(ST(i+1),length[n]));
12144 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12145 }
12146 if ((items >= 3) && strEQcase(list[n],"filename"))
12147 continue;
12148 if ((items >= 3) && strEQcase(list[n],"file"))
12149 {
12150 FILE
12151 *file;
12152
12153 PerlIO
12154 *io_info;
12155
12156 i++;
12157 io_info=IoIFP(sv_2io(ST(i+1)));
12158 if (io_info == (PerlIO *) NULL)
12159 {
12160 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12161 PackageName);
12162 continue;
12163 }
12164 file=PerlIO_findFILE(io_info);
12165 if (file == (FILE *) NULL)
12166 {
12167 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12168 PackageName);
12169 continue;
12170 }
12171 SetImageInfoFile(package_info->image_info,file);
12172 }
12173 if ((items >= 3) && strEQcase(list[n],"magick"))
12174 continue;
12175 n++;
12176 }
12177 list[n]=(char *) NULL;
12178 keep=list;
12179 status=ExpandFilenames(&n,&list);
12180 if (status == MagickFalse)
12181 {
12182 ThrowPerlException(exception,ResourceLimitError,
12183 "MemoryAllocationFailed",PackageName);
12184 goto PerlException;
12185 }
12186 count=0;
12187 for (i=0; i < n; i++)
12188 {
12189 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012190 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012191 image=PingImage(package_info->image_info,exception);
12192 if (image == (Image *) NULL)
12193 break;
12194 if ((package_info->image_info->file != (FILE *) NULL) ||
12195 (package_info->image_info->blob != (void *) NULL))
12196 DisassociateImageStream(image);
12197 count+=GetImageListLength(image);
12198 EXTEND(sp,4*count);
12199 for (next=image; next; next=next->next)
12200 {
12201 PUSHs(sv_2mortal(newSViv(next->columns)));
12202 PUSHs(sv_2mortal(newSViv(next->rows)));
12203 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12204 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12205 }
12206 image=DestroyImageList(image);
12207 }
12208 /*
12209 Free resources.
12210 */
12211 for (i=0; i < n; i++)
12212 if (list[i] != (char *) NULL)
12213 for (p=keep; list[i] != *p++; )
12214 if (*p == NULL)
12215 {
12216 list[i]=(char *) RelinquishMagickMemory(list[i]);
12217 break;
12218 }
12219
12220 PerlException:
12221 if (package_info != (struct PackageInfo *) NULL)
12222 DestroyPackageInfo(package_info);
12223 if (list && (list != keep))
12224 list=(char **) RelinquishMagickMemory(list);
12225 if (keep)
12226 keep=(char **) RelinquishMagickMemory(keep);
12227 if (length)
12228 length=(STRLEN *) RelinquishMagickMemory(length);
12229 InheritPerlException(exception,perl_exception);
12230 exception=DestroyExceptionInfo(exception);
12231 SvREFCNT_dec(perl_exception); /* throw away all errors */
12232 }
12233
12234#
12235###############################################################################
12236# #
12237# #
12238# #
12239# P r e v i e w #
12240# #
12241# #
12242# #
12243###############################################################################
12244#
12245#
12246void
12247Preview(ref,...)
12248 Image::Magick ref=NO_INIT
12249 ALIAS:
12250 PreviewImage = 1
12251 preview = 2
12252 previewimage = 3
12253 PPCODE:
12254 {
12255 AV
12256 *av;
12257
12258 ExceptionInfo
12259 *exception;
12260
12261 HV
12262 *hv;
12263
12264 Image
12265 *image,
12266 *preview_image;
12267
12268 PreviewType
12269 preview_type;
12270
12271 struct PackageInfo
12272 *info;
12273
12274 SV
12275 *av_reference,
12276 *perl_exception,
12277 *reference,
12278 *rv,
12279 *sv;
12280
12281 PERL_UNUSED_VAR(ref);
12282 PERL_UNUSED_VAR(ix);
12283 exception=AcquireExceptionInfo();
12284 perl_exception=newSVpv("",0);
12285 sv=NULL;
12286 av=NULL;
12287 if (sv_isobject(ST(0)) == 0)
12288 {
12289 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12290 PackageName);
12291 goto PerlException;
12292 }
12293 reference=SvRV(ST(0));
12294 hv=SvSTASH(reference);
12295 av=newAV();
12296 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12297 SvREFCNT_dec(av);
12298 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12299 if (image == (Image *) NULL)
12300 {
12301 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12302 PackageName);
12303 goto PerlException;
12304 }
12305 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12306 preview_type=GammaPreview;
12307 if (items > 1)
12308 preview_type=(PreviewType)
12309 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12310 for ( ; image; image=image->next)
12311 {
12312 preview_image=PreviewImage(image,preview_type,exception);
12313 if (preview_image == (Image *) NULL)
12314 goto PerlException;
12315 AddImageToRegistry(sv,preview_image);
12316 rv=newRV(sv);
12317 av_push(av,sv_bless(rv,hv));
12318 SvREFCNT_dec(sv);
12319 }
12320 exception=DestroyExceptionInfo(exception);
12321 ST(0)=av_reference;
12322 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12323 XSRETURN(1);
12324
12325 PerlException:
12326 InheritPerlException(exception,perl_exception);
12327 exception=DestroyExceptionInfo(exception);
12328 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12329 SvPOK_on(perl_exception);
12330 ST(0)=sv_2mortal(perl_exception);
12331 XSRETURN(1);
12332 }
12333
12334#
12335###############################################################################
12336# #
12337# #
12338# #
12339# Q u e r y C o l o r #
12340# #
12341# #
12342# #
12343###############################################################################
12344#
12345#
12346void
12347QueryColor(ref,...)
12348 Image::Magick ref=NO_INIT
12349 ALIAS:
12350 querycolor = 1
12351 PPCODE:
12352 {
12353 char
12354 *name;
12355
12356 ExceptionInfo
12357 *exception;
12358
12359 PixelInfo
12360 color;
12361
12362 register ssize_t
12363 i;
12364
12365 SV
12366 *perl_exception;
12367
12368 PERL_UNUSED_VAR(ref);
12369 PERL_UNUSED_VAR(ix);
12370 exception=AcquireExceptionInfo();
12371 perl_exception=newSVpv("",0);
12372 if (items == 1)
12373 {
12374 const ColorInfo
12375 **colorlist;
12376
12377 size_t
12378 colors;
12379
12380 colorlist=GetColorInfoList("*",&colors,exception);
12381 EXTEND(sp,colors);
12382 for (i=0; i < (ssize_t) colors; i++)
12383 {
12384 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12385 }
12386 colorlist=(const ColorInfo **)
12387 RelinquishMagickMemory((ColorInfo **) colorlist);
12388 goto PerlException;
12389 }
12390 EXTEND(sp,5*items);
12391 for (i=1; i < items; i++)
12392 {
12393 name=(char *) SvPV(ST(i),na);
12394 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12395 {
12396 PUSHs(&sv_undef);
12397 continue;
12398 }
12399 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12400 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12401 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12402 if (color.colorspace == CMYKColorspace)
12403 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012404 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012405 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12406 }
12407
12408 PerlException:
12409 InheritPerlException(exception,perl_exception);
12410 exception=DestroyExceptionInfo(exception);
12411 SvREFCNT_dec(perl_exception);
12412 }
12413
12414#
12415###############################################################################
12416# #
12417# #
12418# #
12419# Q u e r y C o l o r N a m e #
12420# #
12421# #
12422# #
12423###############################################################################
12424#
12425#
12426void
12427QueryColorname(ref,...)
12428 Image::Magick ref=NO_INIT
12429 ALIAS:
12430 querycolorname = 1
12431 PPCODE:
12432 {
12433 AV
12434 *av;
12435
12436 char
cristy151b66d2015-04-15 10:50:31 +000012437 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012438
12439 ExceptionInfo
12440 *exception;
12441
12442 Image
12443 *image;
12444
12445 PixelInfo
12446 target_color;
12447
12448 register ssize_t
12449 i;
12450
12451 struct PackageInfo
12452 *info;
12453
12454 SV
12455 *perl_exception,
12456 *reference; /* reference is the SV* of ref=SvIV(reference) */
12457
12458 PERL_UNUSED_VAR(ref);
12459 PERL_UNUSED_VAR(ix);
12460 exception=AcquireExceptionInfo();
12461 perl_exception=newSVpv("",0);
12462 reference=SvRV(ST(0));
12463 av=(AV *) reference;
12464 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12465 exception);
12466 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12467 if (image == (Image *) NULL)
12468 {
12469 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12470 PackageName);
12471 goto PerlException;
12472 }
12473 EXTEND(sp,items);
12474 for (i=1; i < items; i++)
12475 {
12476 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12477 exception);
12478 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12479 exception);
12480 PUSHs(sv_2mortal(newSVpv(message,0)));
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 F o n t #
12495# #
12496# #
12497# #
12498###############################################################################
12499#
12500#
12501void
12502QueryFont(ref,...)
12503 Image::Magick ref=NO_INIT
12504 ALIAS:
12505 queryfont = 1
12506 PPCODE:
12507 {
12508 char
12509 *name,
cristy151b66d2015-04-15 10:50:31 +000012510 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012511
12512 ExceptionInfo
12513 *exception;
12514
12515 register ssize_t
12516 i;
12517
12518 SV
12519 *perl_exception;
12520
12521 volatile const TypeInfo
12522 *type_info;
12523
12524 PERL_UNUSED_VAR(ref);
12525 PERL_UNUSED_VAR(ix);
12526 exception=AcquireExceptionInfo();
12527 perl_exception=newSVpv("",0);
12528 if (items == 1)
12529 {
12530 const TypeInfo
12531 **typelist;
12532
12533 size_t
12534 types;
12535
12536 typelist=GetTypeInfoList("*",&types,exception);
12537 EXTEND(sp,types);
12538 for (i=0; i < (ssize_t) types; i++)
12539 {
12540 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12541 }
12542 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12543 typelist);
12544 goto PerlException;
12545 }
12546 EXTEND(sp,10*items);
12547 for (i=1; i < items; i++)
12548 {
12549 name=(char *) SvPV(ST(i),na);
12550 type_info=GetTypeInfo(name,exception);
12551 if (type_info == (TypeInfo *) NULL)
12552 {
12553 PUSHs(&sv_undef);
12554 continue;
12555 }
12556 if (type_info->name == (char *) NULL)
12557 PUSHs(&sv_undef);
12558 else
12559 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12560 if (type_info->description == (char *) NULL)
12561 PUSHs(&sv_undef);
12562 else
12563 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12564 if (type_info->family == (char *) NULL)
12565 PUSHs(&sv_undef);
12566 else
12567 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12568 if (type_info->style == UndefinedStyle)
12569 PUSHs(&sv_undef);
12570 else
12571 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12572 type_info->style),0)));
12573 if (type_info->stretch == UndefinedStretch)
12574 PUSHs(&sv_undef);
12575 else
12576 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12577 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012578 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012579 type_info->weight);
12580 PUSHs(sv_2mortal(newSVpv(message,0)));
12581 if (type_info->encoding == (char *) NULL)
12582 PUSHs(&sv_undef);
12583 else
12584 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12585 if (type_info->foundry == (char *) NULL)
12586 PUSHs(&sv_undef);
12587 else
12588 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12589 if (type_info->format == (char *) NULL)
12590 PUSHs(&sv_undef);
12591 else
12592 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12593 if (type_info->metrics == (char *) NULL)
12594 PUSHs(&sv_undef);
12595 else
12596 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12597 if (type_info->glyphs == (char *) NULL)
12598 PUSHs(&sv_undef);
12599 else
12600 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12601 }
12602
12603 PerlException:
12604 InheritPerlException(exception,perl_exception);
12605 exception=DestroyExceptionInfo(exception);
12606 SvREFCNT_dec(perl_exception);
12607 }
12608
12609#
12610###############################################################################
12611# #
12612# #
12613# #
12614# Q u e r y F o n t M e t r i c s #
12615# #
12616# #
12617# #
12618###############################################################################
12619#
12620#
12621void
12622QueryFontMetrics(ref,...)
12623 Image::Magick ref=NO_INIT
12624 ALIAS:
12625 queryfontmetrics = 1
12626 PPCODE:
12627 {
12628 AffineMatrix
12629 affine,
12630 current;
12631
12632 AV
12633 *av;
12634
12635 char
12636 *attribute;
12637
12638 double
12639 x,
12640 y;
12641
12642 DrawInfo
12643 *draw_info;
12644
12645 ExceptionInfo
12646 *exception;
12647
12648 GeometryInfo
12649 geometry_info;
12650
12651 Image
12652 *image;
12653
12654 MagickBooleanType
12655 status;
12656
12657 MagickStatusType
12658 flags;
12659
12660 register ssize_t
12661 i;
12662
12663 ssize_t
12664 type;
12665
12666 struct PackageInfo
12667 *info,
12668 *package_info;
12669
12670 SV
12671 *perl_exception,
12672 *reference; /* reference is the SV* of ref=SvIV(reference) */
12673
12674 TypeMetric
12675 metrics;
12676
12677 PERL_UNUSED_VAR(ref);
12678 PERL_UNUSED_VAR(ix);
12679 exception=AcquireExceptionInfo();
12680 package_info=(struct PackageInfo *) NULL;
12681 perl_exception=newSVpv("",0);
12682 reference=SvRV(ST(0));
12683 av=(AV *) reference;
12684 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12685 exception);
12686 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12687 if (image == (Image *) NULL)
12688 {
12689 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12690 PackageName);
12691 goto PerlException;
12692 }
12693 package_info=ClonePackageInfo(info,exception);
12694 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12695 CloneString(&draw_info->text,"");
12696 current=draw_info->affine;
12697 GetAffineMatrix(&affine);
12698 x=0.0;
12699 y=0.0;
12700 EXTEND(sp,7*items);
12701 for (i=2; i < items; i+=2)
12702 {
12703 attribute=(char *) SvPV(ST(i-1),na);
12704 switch (*attribute)
12705 {
12706 case 'A':
12707 case 'a':
12708 {
12709 if (LocaleCompare(attribute,"antialias") == 0)
12710 {
12711 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12712 SvPV(ST(i),na));
12713 if (type < 0)
12714 {
12715 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12716 SvPV(ST(i),na));
12717 break;
12718 }
12719 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12720 break;
12721 }
12722 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12723 attribute);
12724 break;
12725 }
12726 case 'd':
12727 case 'D':
12728 {
12729 if (LocaleCompare(attribute,"density") == 0)
12730 {
12731 CloneString(&draw_info->density,SvPV(ST(i),na));
12732 break;
12733 }
12734 if (LocaleCompare(attribute,"direction") == 0)
12735 {
12736 draw_info->direction=(DirectionType) ParseCommandOption(
12737 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12738 break;
12739 }
12740 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12741 attribute);
12742 break;
12743 }
12744 case 'e':
12745 case 'E':
12746 {
12747 if (LocaleCompare(attribute,"encoding") == 0)
12748 {
12749 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12750 break;
12751 }
12752 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12753 attribute);
12754 break;
12755 }
12756 case 'f':
12757 case 'F':
12758 {
12759 if (LocaleCompare(attribute,"family") == 0)
12760 {
12761 CloneString(&draw_info->family,SvPV(ST(i),na));
12762 break;
12763 }
12764 if (LocaleCompare(attribute,"fill") == 0)
12765 {
12766 if (info)
12767 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12768 &draw_info->fill,exception);
12769 break;
12770 }
12771 if (LocaleCompare(attribute,"font") == 0)
12772 {
12773 CloneString(&draw_info->font,SvPV(ST(i),na));
12774 break;
12775 }
12776 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12777 attribute);
12778 break;
12779 }
12780 case 'g':
12781 case 'G':
12782 {
12783 if (LocaleCompare(attribute,"geometry") == 0)
12784 {
12785 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12786 break;
12787 }
12788 if (LocaleCompare(attribute,"gravity") == 0)
12789 {
12790 draw_info->gravity=(GravityType) ParseCommandOption(
12791 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12792 break;
12793 }
12794 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12795 attribute);
12796 break;
12797 }
12798 case 'i':
12799 case 'I':
12800 {
12801 if (LocaleCompare(attribute,"interline-spacing") == 0)
12802 {
12803 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12804 draw_info->interline_spacing=geometry_info.rho;
12805 break;
12806 }
12807 if (LocaleCompare(attribute,"interword-spacing") == 0)
12808 {
12809 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12810 draw_info->interword_spacing=geometry_info.rho;
12811 break;
12812 }
12813 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12814 attribute);
12815 break;
12816 }
12817 case 'k':
12818 case 'K':
12819 {
12820 if (LocaleCompare(attribute,"kerning") == 0)
12821 {
12822 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12823 draw_info->kerning=geometry_info.rho;
12824 break;
12825 }
12826 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12827 attribute);
12828 break;
12829 }
12830 case 'p':
12831 case 'P':
12832 {
12833 if (LocaleCompare(attribute,"pointsize") == 0)
12834 {
12835 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12836 draw_info->pointsize=geometry_info.rho;
12837 break;
12838 }
12839 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12840 attribute);
12841 break;
12842 }
12843 case 'r':
12844 case 'R':
12845 {
12846 if (LocaleCompare(attribute,"rotate") == 0)
12847 {
12848 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12849 affine.rx=geometry_info.rho;
12850 affine.ry=geometry_info.sigma;
12851 if ((flags & SigmaValue) == 0)
12852 affine.ry=affine.rx;
12853 break;
12854 }
12855 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12856 attribute);
12857 break;
12858 }
12859 case 's':
12860 case 'S':
12861 {
12862 if (LocaleCompare(attribute,"scale") == 0)
12863 {
12864 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12865 affine.sx=geometry_info.rho;
12866 affine.sy=geometry_info.sigma;
12867 if ((flags & SigmaValue) == 0)
12868 affine.sy=affine.sx;
12869 break;
12870 }
12871 if (LocaleCompare(attribute,"skew") == 0)
12872 {
12873 double
12874 x_angle,
12875 y_angle;
12876
12877 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12878 x_angle=geometry_info.rho;
12879 y_angle=geometry_info.sigma;
12880 if ((flags & SigmaValue) == 0)
12881 y_angle=x_angle;
12882 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12883 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12884 break;
12885 }
12886 if (LocaleCompare(attribute,"stroke") == 0)
12887 {
12888 if (info)
12889 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12890 &draw_info->stroke,exception);
12891 break;
12892 }
12893 if (LocaleCompare(attribute,"style") == 0)
12894 {
12895 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12896 SvPV(ST(i),na));
12897 if (type < 0)
12898 {
12899 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12900 SvPV(ST(i),na));
12901 break;
12902 }
12903 draw_info->style=(StyleType) type;
12904 break;
12905 }
12906 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12907 attribute);
12908 break;
12909 }
12910 case 't':
12911 case 'T':
12912 {
12913 if (LocaleCompare(attribute,"text") == 0)
12914 {
12915 CloneString(&draw_info->text,SvPV(ST(i),na));
12916 break;
12917 }
12918 if (LocaleCompare(attribute,"translate") == 0)
12919 {
12920 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12921 affine.tx=geometry_info.rho;
12922 affine.ty=geometry_info.sigma;
12923 if ((flags & SigmaValue) == 0)
12924 affine.ty=affine.tx;
12925 break;
12926 }
12927 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12928 attribute);
12929 break;
12930 }
12931 case 'w':
12932 case 'W':
12933 {
12934 if (LocaleCompare(attribute,"weight") == 0)
12935 {
12936 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12937 draw_info->weight=(size_t) geometry_info.rho;
12938 break;
12939 }
12940 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12941 attribute);
12942 break;
12943 }
12944 case 'x':
12945 case 'X':
12946 {
12947 if (LocaleCompare(attribute,"x") == 0)
12948 {
12949 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12950 x=geometry_info.rho;
12951 break;
12952 }
12953 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12954 attribute);
12955 break;
12956 }
12957 case 'y':
12958 case 'Y':
12959 {
12960 if (LocaleCompare(attribute,"y") == 0)
12961 {
12962 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12963 y=geometry_info.rho;
12964 break;
12965 }
12966 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12967 attribute);
12968 break;
12969 }
12970 default:
12971 {
12972 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12973 attribute);
12974 break;
12975 }
12976 }
12977 }
12978 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12979 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12980 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12981 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12982 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12983 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12984 if (draw_info->geometry == (char *) NULL)
12985 {
12986 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000012987 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050012988 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000012989 }
12990 status=GetTypeMetrics(image,draw_info,&metrics,exception);
12991 (void) CatchImageException(image);
12992 if (status == MagickFalse)
12993 PUSHs(&sv_undef);
12994 else
12995 {
12996 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12997 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12998 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12999 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13000 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13001 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13002 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13003 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13004 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13005 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13006 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13007 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13008 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13009 }
13010 draw_info=DestroyDrawInfo(draw_info);
13011
13012 PerlException:
13013 if (package_info != (struct PackageInfo *) NULL)
13014 DestroyPackageInfo(package_info);
13015 InheritPerlException(exception,perl_exception);
13016 exception=DestroyExceptionInfo(exception);
13017 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13018 }
13019
13020#
13021###############################################################################
13022# #
13023# #
13024# #
13025# 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 #
13026# #
13027# #
13028# #
13029###############################################################################
13030#
13031#
13032void
13033QueryMultilineFontMetrics(ref,...)
13034 Image::Magick ref=NO_INIT
13035 ALIAS:
13036 querymultilinefontmetrics = 1
13037 PPCODE:
13038 {
13039 AffineMatrix
13040 affine,
13041 current;
13042
13043 AV
13044 *av;
13045
13046 char
13047 *attribute;
13048
13049 double
13050 x,
13051 y;
13052
13053 DrawInfo
13054 *draw_info;
13055
13056 ExceptionInfo
13057 *exception;
13058
13059 GeometryInfo
13060 geometry_info;
13061
13062 Image
13063 *image;
13064
13065 MagickBooleanType
13066 status;
13067
13068 MagickStatusType
13069 flags;
13070
13071 register ssize_t
13072 i;
13073
13074 ssize_t
13075 type;
13076
13077 struct PackageInfo
13078 *info,
13079 *package_info;
13080
13081 SV
13082 *perl_exception,
13083 *reference; /* reference is the SV* of ref=SvIV(reference) */
13084
13085 TypeMetric
13086 metrics;
13087
13088 PERL_UNUSED_VAR(ref);
13089 PERL_UNUSED_VAR(ix);
13090 exception=AcquireExceptionInfo();
13091 package_info=(struct PackageInfo *) NULL;
13092 perl_exception=newSVpv("",0);
13093 reference=SvRV(ST(0));
13094 av=(AV *) reference;
13095 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13096 exception);
13097 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13098 if (image == (Image *) NULL)
13099 {
13100 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13101 PackageName);
13102 goto PerlException;
13103 }
13104 package_info=ClonePackageInfo(info,exception);
13105 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13106 CloneString(&draw_info->text,"");
13107 current=draw_info->affine;
13108 GetAffineMatrix(&affine);
13109 x=0.0;
13110 y=0.0;
13111 EXTEND(sp,7*items);
13112 for (i=2; i < items; i+=2)
13113 {
13114 attribute=(char *) SvPV(ST(i-1),na);
13115 switch (*attribute)
13116 {
13117 case 'A':
13118 case 'a':
13119 {
13120 if (LocaleCompare(attribute,"antialias") == 0)
13121 {
13122 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13123 SvPV(ST(i),na));
13124 if (type < 0)
13125 {
13126 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13127 SvPV(ST(i),na));
13128 break;
13129 }
13130 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13131 break;
13132 }
13133 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13134 attribute);
13135 break;
13136 }
13137 case 'd':
13138 case 'D':
13139 {
13140 if (LocaleCompare(attribute,"density") == 0)
13141 {
13142 CloneString(&draw_info->density,SvPV(ST(i),na));
13143 break;
13144 }
13145 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13146 attribute);
13147 break;
13148 }
13149 case 'e':
13150 case 'E':
13151 {
13152 if (LocaleCompare(attribute,"encoding") == 0)
13153 {
13154 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13155 break;
13156 }
13157 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13158 attribute);
13159 break;
13160 }
13161 case 'f':
13162 case 'F':
13163 {
13164 if (LocaleCompare(attribute,"family") == 0)
13165 {
13166 CloneString(&draw_info->family,SvPV(ST(i),na));
13167 break;
13168 }
13169 if (LocaleCompare(attribute,"fill") == 0)
13170 {
13171 if (info)
13172 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13173 &draw_info->fill,exception);
13174 break;
13175 }
13176 if (LocaleCompare(attribute,"font") == 0)
13177 {
13178 CloneString(&draw_info->font,SvPV(ST(i),na));
13179 break;
13180 }
13181 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13182 attribute);
13183 break;
13184 }
13185 case 'g':
13186 case 'G':
13187 {
13188 if (LocaleCompare(attribute,"geometry") == 0)
13189 {
13190 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13191 break;
13192 }
13193 if (LocaleCompare(attribute,"gravity") == 0)
13194 {
13195 draw_info->gravity=(GravityType) ParseCommandOption(
13196 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13197 break;
13198 }
13199 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13200 attribute);
13201 break;
13202 }
13203 case 'p':
13204 case 'P':
13205 {
13206 if (LocaleCompare(attribute,"pointsize") == 0)
13207 {
13208 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13209 draw_info->pointsize=geometry_info.rho;
13210 break;
13211 }
13212 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13213 attribute);
13214 break;
13215 }
13216 case 'r':
13217 case 'R':
13218 {
13219 if (LocaleCompare(attribute,"rotate") == 0)
13220 {
13221 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13222 affine.rx=geometry_info.rho;
13223 affine.ry=geometry_info.sigma;
13224 if ((flags & SigmaValue) == 0)
13225 affine.ry=affine.rx;
13226 break;
13227 }
13228 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13229 attribute);
13230 break;
13231 }
13232 case 's':
13233 case 'S':
13234 {
13235 if (LocaleCompare(attribute,"scale") == 0)
13236 {
13237 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13238 affine.sx=geometry_info.rho;
13239 affine.sy=geometry_info.sigma;
13240 if ((flags & SigmaValue) == 0)
13241 affine.sy=affine.sx;
13242 break;
13243 }
13244 if (LocaleCompare(attribute,"skew") == 0)
13245 {
13246 double
13247 x_angle,
13248 y_angle;
13249
13250 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13251 x_angle=geometry_info.rho;
13252 y_angle=geometry_info.sigma;
13253 if ((flags & SigmaValue) == 0)
13254 y_angle=x_angle;
13255 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13256 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13257 break;
13258 }
13259 if (LocaleCompare(attribute,"stroke") == 0)
13260 {
13261 if (info)
13262 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13263 &draw_info->stroke,exception);
13264 break;
13265 }
13266 if (LocaleCompare(attribute,"style") == 0)
13267 {
13268 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13269 SvPV(ST(i),na));
13270 if (type < 0)
13271 {
13272 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13273 SvPV(ST(i),na));
13274 break;
13275 }
13276 draw_info->style=(StyleType) type;
13277 break;
13278 }
13279 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13280 attribute);
13281 break;
13282 }
13283 case 't':
13284 case 'T':
13285 {
13286 if (LocaleCompare(attribute,"text") == 0)
13287 {
13288 CloneString(&draw_info->text,SvPV(ST(i),na));
13289 break;
13290 }
13291 if (LocaleCompare(attribute,"translate") == 0)
13292 {
13293 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13294 affine.tx=geometry_info.rho;
13295 affine.ty=geometry_info.sigma;
13296 if ((flags & SigmaValue) == 0)
13297 affine.ty=affine.tx;
13298 break;
13299 }
13300 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13301 attribute);
13302 break;
13303 }
13304 case 'w':
13305 case 'W':
13306 {
13307 if (LocaleCompare(attribute,"weight") == 0)
13308 {
13309 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13310 draw_info->weight=(size_t) geometry_info.rho;
13311 break;
13312 }
13313 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13314 attribute);
13315 break;
13316 }
13317 case 'x':
13318 case 'X':
13319 {
13320 if (LocaleCompare(attribute,"x") == 0)
13321 {
13322 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13323 x=geometry_info.rho;
13324 break;
13325 }
13326 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13327 attribute);
13328 break;
13329 }
13330 case 'y':
13331 case 'Y':
13332 {
13333 if (LocaleCompare(attribute,"y") == 0)
13334 {
13335 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13336 y=geometry_info.rho;
13337 break;
13338 }
13339 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13340 attribute);
13341 break;
13342 }
13343 default:
13344 {
13345 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13346 attribute);
13347 break;
13348 }
13349 }
13350 }
13351 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13352 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13353 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13354 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13355 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13356 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13357 if (draw_info->geometry == (char *) NULL)
13358 {
13359 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013360 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013361 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013362 }
13363 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13364 (void) CatchException(exception);
13365 if (status == MagickFalse)
13366 PUSHs(&sv_undef);
13367 else
13368 {
13369 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13370 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13371 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13372 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13373 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13374 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13375 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13376 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13377 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13378 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13379 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13380 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13381 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13382 }
13383 draw_info=DestroyDrawInfo(draw_info);
13384
13385 PerlException:
13386 if (package_info != (struct PackageInfo *) NULL)
13387 DestroyPackageInfo(package_info);
13388 InheritPerlException(exception,perl_exception);
13389 exception=DestroyExceptionInfo(exception);
13390 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13391 }
13392
13393#
13394###############################################################################
13395# #
13396# #
13397# #
13398# Q u e r y F o r m a t #
13399# #
13400# #
13401# #
13402###############################################################################
13403#
13404#
13405void
13406QueryFormat(ref,...)
13407 Image::Magick ref=NO_INIT
13408 ALIAS:
13409 queryformat = 1
13410 PPCODE:
13411 {
13412 char
13413 *name;
13414
13415 ExceptionInfo
13416 *exception;
13417
13418 register ssize_t
13419 i;
13420
13421 SV
13422 *perl_exception;
13423
13424 volatile const MagickInfo
13425 *magick_info;
13426
13427 PERL_UNUSED_VAR(ref);
13428 PERL_UNUSED_VAR(ix);
13429 exception=AcquireExceptionInfo();
13430 perl_exception=newSVpv("",0);
13431 if (items == 1)
13432 {
13433 char
cristy151b66d2015-04-15 10:50:31 +000013434 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013435
13436 const MagickInfo
13437 **format_list;
13438
13439 size_t
13440 types;
13441
13442 format_list=GetMagickInfoList("*",&types,exception);
13443 EXTEND(sp,types);
13444 for (i=0; i < (ssize_t) types; i++)
13445 {
cristy151b66d2015-04-15 10:50:31 +000013446 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013447 LocaleLower(format);
13448 PUSHs(sv_2mortal(newSVpv(format,0)));
13449 }
13450 format_list=(const MagickInfo **)
13451 RelinquishMagickMemory((MagickInfo *) format_list);
13452 goto PerlException;
13453 }
13454 EXTEND(sp,8*items);
13455 for (i=1; i < items; i++)
13456 {
13457 name=(char *) SvPV(ST(i),na);
13458 magick_info=GetMagickInfo(name,exception);
13459 if (magick_info == (const MagickInfo *) NULL)
13460 {
13461 PUSHs(&sv_undef);
13462 continue;
13463 }
cristy4a3ce0a2013-08-03 20:06:59 +000013464 if (magick_info->description == (char *) NULL)
13465 PUSHs(&sv_undef);
13466 else
13467 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13468 if (magick_info->module == (char *) NULL)
13469 PUSHs(&sv_undef);
13470 else
13471 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13472 }
13473
13474 PerlException:
13475 InheritPerlException(exception,perl_exception);
13476 exception=DestroyExceptionInfo(exception);
13477 SvREFCNT_dec(perl_exception);
13478 }
13479
13480#
13481###############################################################################
13482# #
13483# #
13484# #
13485# Q u e r y O p t i o n #
13486# #
13487# #
13488# #
13489###############################################################################
13490#
13491#
13492void
13493QueryOption(ref,...)
13494 Image::Magick ref=NO_INIT
13495 ALIAS:
13496 queryoption = 1
13497 PPCODE:
13498 {
13499 char
13500 **options;
13501
13502 ExceptionInfo
13503 *exception;
13504
13505 register ssize_t
13506 i;
13507
13508 ssize_t
13509 j,
13510 option;
13511
13512 SV
13513 *perl_exception;
13514
13515 PERL_UNUSED_VAR(ref);
13516 PERL_UNUSED_VAR(ix);
13517 exception=AcquireExceptionInfo();
13518 perl_exception=newSVpv("",0);
13519 EXTEND(sp,8*items);
13520 for (i=1; i < items; i++)
13521 {
13522 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13523 SvPV(ST(i),na));
13524 options=GetCommandOptions((CommandOption) option);
13525 if (options == (char **) NULL)
13526 PUSHs(&sv_undef);
13527 else
13528 {
13529 for (j=0; options[j] != (char *) NULL; j++)
13530 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13531 options=DestroyStringList(options);
13532 }
13533 }
13534
13535 InheritPerlException(exception,perl_exception);
13536 exception=DestroyExceptionInfo(exception);
13537 SvREFCNT_dec(perl_exception);
13538 }
13539
13540#
13541###############################################################################
13542# #
13543# #
13544# #
13545# R e a d #
13546# #
13547# #
13548# #
13549###############################################################################
13550#
13551#
13552void
13553Read(ref,...)
13554 Image::Magick ref=NO_INIT
13555 ALIAS:
13556 ReadImage = 1
13557 read = 2
13558 readimage = 3
13559 PPCODE:
13560 {
13561 AV
13562 *av;
13563
13564 char
13565 **keep,
13566 **list;
13567
13568 ExceptionInfo
13569 *exception;
13570
13571 HV
13572 *hv;
13573
13574 Image
13575 *image;
13576
13577 int
13578 n;
13579
13580 MagickBooleanType
13581 status;
13582
13583 register char
13584 **p;
13585
13586 register ssize_t
13587 i;
13588
13589 ssize_t
13590 ac,
13591 number_images;
13592
13593 STRLEN
13594 *length;
13595
13596 struct PackageInfo
13597 *info,
13598 *package_info;
13599
13600 SV
13601 *perl_exception, /* Perl variable for storing messages */
13602 *reference,
13603 *rv,
13604 *sv;
13605
13606 PERL_UNUSED_VAR(ref);
13607 PERL_UNUSED_VAR(ix);
13608 exception=AcquireExceptionInfo();
13609 perl_exception=newSVpv("",0);
13610 sv=NULL;
13611 package_info=(struct PackageInfo *) NULL;
13612 number_images=0;
13613 ac=(items < 2) ? 1 : items-1;
13614 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13615 keep=list;
13616 length=(STRLEN *) NULL;
13617 if (list == (char **) NULL)
13618 {
13619 ThrowPerlException(exception,ResourceLimitError,
13620 "MemoryAllocationFailed",PackageName);
13621 goto PerlException;
13622 }
13623 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13624 if (length == (STRLEN *) NULL)
13625 {
13626 ThrowPerlException(exception,ResourceLimitError,
13627 "MemoryAllocationFailed",PackageName);
13628 goto PerlException;
13629 }
13630 if (sv_isobject(ST(0)) == 0)
13631 {
13632 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13633 PackageName);
13634 goto PerlException;
13635 }
13636 reference=SvRV(ST(0));
13637 hv=SvSTASH(reference);
13638 if (SvTYPE(reference) != SVt_PVAV)
13639 {
13640 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13641 PackageName);
13642 goto PerlException;
13643 }
13644 av=(AV *) reference;
13645 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13646 exception);
13647 package_info=ClonePackageInfo(info,exception);
13648 n=1;
13649 if (items <= 1)
13650 *list=(char *) (*package_info->image_info->filename ?
13651 package_info->image_info->filename : "XC:black");
13652 else
13653 for (n=0, i=0; i < ac; i++)
13654 {
13655 list[n]=(char *) SvPV(ST(i+1),length[n]);
13656 if ((items >= 3) && strEQcase(list[n],"blob"))
13657 {
13658 void
13659 *blob;
13660
13661 i++;
13662 blob=(void *) (SvPV(ST(i+1),length[n]));
13663 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13664 }
13665 if ((items >= 3) && strEQcase(list[n],"filename"))
13666 continue;
13667 if ((items >= 3) && strEQcase(list[n],"file"))
13668 {
13669 FILE
13670 *file;
13671
13672 PerlIO
13673 *io_info;
13674
13675 i++;
13676 io_info=IoIFP(sv_2io(ST(i+1)));
13677 if (io_info == (PerlIO *) NULL)
13678 {
13679 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13680 PackageName);
13681 continue;
13682 }
13683 file=PerlIO_findFILE(io_info);
13684 if (file == (FILE *) NULL)
13685 {
13686 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13687 PackageName);
13688 continue;
13689 }
13690 SetImageInfoFile(package_info->image_info,file);
13691 }
13692 if ((items >= 3) && strEQcase(list[n],"magick"))
13693 continue;
13694 n++;
13695 }
13696 list[n]=(char *) NULL;
13697 keep=list;
13698 status=ExpandFilenames(&n,&list);
13699 if (status == MagickFalse)
13700 {
13701 ThrowPerlException(exception,ResourceLimitError,
13702 "MemoryAllocationFailed",PackageName);
13703 goto PerlException;
13704 }
13705 number_images=0;
13706 for (i=0; i < n; i++)
13707 {
13708 if ((package_info->image_info->file == (FILE *) NULL) &&
13709 (package_info->image_info->blob == (void *) NULL))
13710 image=ReadImages(package_info->image_info,list[i],exception);
13711 else
13712 {
13713 image=ReadImages(package_info->image_info,
13714 package_info->image_info->filename,exception);
13715 if (image != (Image *) NULL)
13716 DisassociateImageStream(image);
13717 }
13718 if (image == (Image *) NULL)
13719 break;
13720 for ( ; image; image=image->next)
13721 {
13722 AddImageToRegistry(sv,image);
13723 rv=newRV(sv);
13724 av_push(av,sv_bless(rv,hv));
13725 SvREFCNT_dec(sv);
13726 number_images++;
13727 }
13728 }
13729 /*
13730 Free resources.
13731 */
13732 for (i=0; i < n; i++)
13733 if (list[i] != (char *) NULL)
13734 for (p=keep; list[i] != *p++; )
13735 if (*p == (char *) NULL)
13736 {
13737 list[i]=(char *) RelinquishMagickMemory(list[i]);
13738 break;
13739 }
13740
13741 PerlException:
13742 if (package_info != (struct PackageInfo *) NULL)
13743 DestroyPackageInfo(package_info);
13744 if (list && (list != keep))
13745 list=(char **) RelinquishMagickMemory(list);
13746 if (keep)
13747 keep=(char **) RelinquishMagickMemory(keep);
13748 if (length)
13749 length=(STRLEN *) RelinquishMagickMemory(length);
13750 InheritPerlException(exception,perl_exception);
13751 exception=DestroyExceptionInfo(exception);
13752 sv_setiv(perl_exception,(IV) number_images);
13753 SvPOK_on(perl_exception);
13754 ST(0)=sv_2mortal(perl_exception);
13755 XSRETURN(1);
13756 }
13757
13758#
13759###############################################################################
13760# #
13761# #
13762# #
13763# R e m o t e #
13764# #
13765# #
13766# #
13767###############################################################################
13768#
13769#
13770void
13771Remote(ref,...)
13772 Image::Magick ref=NO_INIT
13773 ALIAS:
13774 RemoteCommand = 1
13775 remote = 2
13776 remoteCommand = 3
13777 PPCODE:
13778 {
13779 AV
13780 *av;
13781
13782 ExceptionInfo
13783 *exception;
13784
13785 register ssize_t
13786 i;
13787
13788 SV
13789 *perl_exception,
13790 *reference;
13791
13792 struct PackageInfo
13793 *info;
13794
13795 PERL_UNUSED_VAR(ref);
13796 PERL_UNUSED_VAR(ix);
13797 exception=AcquireExceptionInfo();
13798 perl_exception=newSVpv("",0);
13799 reference=SvRV(ST(0));
13800 av=(AV *) reference;
13801 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13802 exception);
13803 for (i=1; i < items; i++)
13804 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13805 SvPV(ST(i),na),exception);
13806 InheritPerlException(exception,perl_exception);
13807 exception=DestroyExceptionInfo(exception);
13808 SvREFCNT_dec(perl_exception); /* throw away all errors */
13809 }
13810
13811#
13812###############################################################################
13813# #
13814# #
13815# #
13816# S e t #
13817# #
13818# #
13819# #
13820###############################################################################
13821#
13822#
13823void
13824Set(ref,...)
13825 Image::Magick ref=NO_INIT
13826 ALIAS:
13827 SetAttributes = 1
13828 SetAttribute = 2
13829 set = 3
13830 setattributes = 4
13831 setattribute = 5
13832 PPCODE:
13833 {
13834 ExceptionInfo
13835 *exception;
13836
13837 Image
13838 *image;
13839
13840 register ssize_t
13841 i;
13842
13843 struct PackageInfo
13844 *info;
13845
13846 SV
13847 *perl_exception,
13848 *reference; /* reference is the SV* of ref=SvIV(reference) */
13849
13850 PERL_UNUSED_VAR(ref);
13851 PERL_UNUSED_VAR(ix);
13852 exception=AcquireExceptionInfo();
13853 perl_exception=newSVpv("",0);
13854 if (sv_isobject(ST(0)) == 0)
13855 {
13856 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13857 PackageName);
13858 goto PerlException;
13859 }
13860 reference=SvRV(ST(0));
13861 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13862 if (items == 2)
13863 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13864 else
13865 for (i=2; i < items; i+=2)
13866 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13867
13868 PerlException:
13869 InheritPerlException(exception,perl_exception);
13870 exception=DestroyExceptionInfo(exception);
13871 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13872 SvPOK_on(perl_exception);
13873 ST(0)=sv_2mortal(perl_exception);
13874 XSRETURN(1);
13875 }
13876
13877#
13878###############################################################################
13879# #
13880# #
13881# #
13882# S e t P i x e l #
13883# #
13884# #
13885# #
13886###############################################################################
13887#
13888#
13889void
13890SetPixel(ref,...)
13891 Image::Magick ref=NO_INIT
13892 ALIAS:
13893 setpixel = 1
13894 setPixel = 2
13895 PPCODE:
13896 {
13897 AV
13898 *av;
13899
13900 char
13901 *attribute;
13902
13903 ChannelType
13904 channel,
13905 channel_mask;
13906
13907 ExceptionInfo
13908 *exception;
13909
13910 Image
13911 *image;
13912
13913 MagickBooleanType
13914 normalize;
13915
13916 RectangleInfo
13917 region;
13918
13919 register ssize_t
13920 i;
13921
13922 register Quantum
13923 *q;
13924
13925 ssize_t
13926 option;
13927
13928 struct PackageInfo
13929 *info;
13930
13931 SV
13932 *perl_exception,
13933 *reference; /* reference is the SV* of ref=SvIV(reference) */
13934
13935 PERL_UNUSED_VAR(ref);
13936 PERL_UNUSED_VAR(ix);
13937 exception=AcquireExceptionInfo();
13938 perl_exception=newSVpv("",0);
13939 reference=SvRV(ST(0));
13940 av=(AV *) reference;
13941 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13942 exception);
13943 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13944 if (image == (Image *) NULL)
13945 {
13946 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13947 PackageName);
13948 goto PerlException;
13949 }
13950 av=(AV *) NULL;
13951 normalize=MagickTrue;
13952 region.x=0;
13953 region.y=0;
13954 region.width=image->columns;
13955 region.height=1;
13956 if (items == 1)
13957 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
13958 channel=DefaultChannels;
13959 for (i=2; i < items; i+=2)
13960 {
13961 attribute=(char *) SvPV(ST(i-1),na);
13962 switch (*attribute)
13963 {
13964 case 'C':
13965 case 'c':
13966 {
13967 if (LocaleCompare(attribute,"channel") == 0)
13968 {
13969 ssize_t
13970 option;
13971
13972 option=ParseChannelOption(SvPV(ST(i),na));
13973 if (option < 0)
13974 {
13975 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13976 SvPV(ST(i),na));
13977 return;
13978 }
13979 channel=(ChannelType) option;
13980 break;
13981 }
13982 if (LocaleCompare(attribute,"color") == 0)
13983 {
13984 if (SvTYPE(ST(i)) != SVt_RV)
13985 {
13986 char
cristy151b66d2015-04-15 10:50:31 +000013987 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013988
cristy151b66d2015-04-15 10:50:31 +000013989 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013990 "invalid %.60s value",attribute);
13991 ThrowPerlException(exception,OptionError,message,
13992 SvPV(ST(i),na));
13993 }
13994 av=(AV *) SvRV(ST(i));
13995 break;
13996 }
13997 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13998 attribute);
13999 break;
14000 }
14001 case 'g':
14002 case 'G':
14003 {
14004 if (LocaleCompare(attribute,"geometry") == 0)
14005 {
14006 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14007 break;
14008 }
14009 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14010 attribute);
14011 break;
14012 }
14013 case 'N':
14014 case 'n':
14015 {
14016 if (LocaleCompare(attribute,"normalize") == 0)
14017 {
14018 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14019 SvPV(ST(i),na));
14020 if (option < 0)
14021 {
14022 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14023 SvPV(ST(i),na));
14024 break;
14025 }
14026 normalize=option != 0 ? MagickTrue : MagickFalse;
14027 break;
14028 }
14029 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14030 attribute);
14031 break;
14032 }
14033 case 'x':
14034 case 'X':
14035 {
14036 if (LocaleCompare(attribute,"x") == 0)
14037 {
14038 region.x=SvIV(ST(i));
14039 break;
14040 }
14041 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14042 attribute);
14043 break;
14044 }
14045 case 'y':
14046 case 'Y':
14047 {
14048 if (LocaleCompare(attribute,"y") == 0)
14049 {
14050 region.y=SvIV(ST(i));
14051 break;
14052 }
14053 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14054 attribute);
14055 break;
14056 }
14057 default:
14058 {
14059 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14060 attribute);
14061 break;
14062 }
14063 }
14064 }
14065 (void) SetImageStorageClass(image,DirectClass,exception);
14066 channel_mask=SetImageChannelMask(image,channel);
14067 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14068 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14069 (SvTYPE(av) != SVt_PVAV))
14070 PUSHs(&sv_undef);
14071 else
14072 {
14073 double
14074 scale;
14075
14076 register ssize_t
14077 i;
14078
14079 i=0;
14080 scale=1.0;
14081 if (normalize != MagickFalse)
14082 scale=QuantumRange;
14083 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14084 (i <= av_len(av)))
14085 {
14086 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14087 av_fetch(av,i,0)))),q);
14088 i++;
14089 }
14090 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14091 (i <= av_len(av)))
14092 {
14093 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14094 av_fetch(av,i,0)))),q);
14095 i++;
14096 }
14097 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14098 (i <= av_len(av)))
14099 {
14100 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14101 av_fetch(av,i,0)))),q);
14102 i++;
14103 }
14104 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14105 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14106 {
14107 SetPixelBlack(image,ClampToQuantum(scale*
14108 SvNV(*(av_fetch(av,i,0)))),q);
14109 i++;
14110 }
14111 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14112 (i <= av_len(av)))
14113 {
14114 SetPixelAlpha(image,ClampToQuantum(scale*
14115 SvNV(*(av_fetch(av,i,0)))),q);
14116 i++;
14117 }
14118 (void) SyncAuthenticPixels(image,exception);
14119 }
14120 (void) SetImageChannelMask(image,channel_mask);
14121
14122 PerlException:
14123 InheritPerlException(exception,perl_exception);
14124 exception=DestroyExceptionInfo(exception);
14125 SvREFCNT_dec(perl_exception);
14126 }
14127
14128#
14129###############################################################################
14130# #
14131# #
14132# #
14133# S m u s h #
14134# #
14135# #
14136# #
14137###############################################################################
14138#
14139#
14140void
14141Smush(ref,...)
14142 Image::Magick ref=NO_INIT
14143 ALIAS:
14144 SmushImage = 1
14145 smush = 2
14146 smushimage = 3
14147 PPCODE:
14148 {
14149 AV
14150 *av;
14151
14152 char
14153 *attribute;
14154
14155 ExceptionInfo
14156 *exception;
14157
14158 HV
14159 *hv;
14160
14161 Image
14162 *image;
14163
14164 register ssize_t
14165 i;
14166
14167 ssize_t
14168 offset,
14169 stack;
14170
14171 struct PackageInfo
14172 *info;
14173
14174 SV
14175 *av_reference,
14176 *perl_exception,
14177 *reference,
14178 *rv,
14179 *sv;
14180
14181 PERL_UNUSED_VAR(ref);
14182 PERL_UNUSED_VAR(ix);
14183 exception=AcquireExceptionInfo();
14184 perl_exception=newSVpv("",0);
14185 sv=NULL;
14186 attribute=NULL;
14187 av=NULL;
14188 if (sv_isobject(ST(0)) == 0)
14189 {
14190 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14191 PackageName);
14192 goto PerlException;
14193 }
14194 reference=SvRV(ST(0));
14195 hv=SvSTASH(reference);
14196 av=newAV();
14197 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14198 SvREFCNT_dec(av);
14199 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14200 if (image == (Image *) NULL)
14201 {
14202 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14203 PackageName);
14204 goto PerlException;
14205 }
14206 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14207 /*
14208 Get options.
14209 */
14210 offset=0;
14211 stack=MagickTrue;
14212 for (i=2; i < items; i+=2)
14213 {
14214 attribute=(char *) SvPV(ST(i-1),na);
14215 switch (*attribute)
14216 {
14217 case 'O':
14218 case 'o':
14219 {
14220 if (LocaleCompare(attribute,"offset") == 0)
14221 {
14222 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14223 break;
14224 }
14225 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14226 attribute);
14227 break;
14228 }
14229 case 'S':
14230 case 's':
14231 {
14232 if (LocaleCompare(attribute,"stack") == 0)
14233 {
14234 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14235 SvPV(ST(i),na));
14236 if (stack < 0)
14237 {
14238 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14239 SvPV(ST(i),na));
14240 return;
14241 }
14242 break;
14243 }
14244 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14245 attribute);
14246 break;
14247 }
14248 default:
14249 {
14250 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14251 attribute);
14252 break;
14253 }
14254 }
14255 }
14256 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14257 exception);
14258 if (image == (Image *) NULL)
14259 goto PerlException;
14260 for ( ; image; image=image->next)
14261 {
14262 AddImageToRegistry(sv,image);
14263 rv=newRV(sv);
14264 av_push(av,sv_bless(rv,hv));
14265 SvREFCNT_dec(sv);
14266 }
14267 exception=DestroyExceptionInfo(exception);
14268 ST(0)=av_reference;
14269 SvREFCNT_dec(perl_exception);
14270 XSRETURN(1);
14271
14272 PerlException:
14273 InheritPerlException(exception,perl_exception);
14274 exception=DestroyExceptionInfo(exception);
14275 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14276 SvPOK_on(perl_exception);
14277 ST(0)=sv_2mortal(perl_exception);
14278 XSRETURN(1);
14279 }
14280
14281#
14282###############################################################################
14283# #
14284# #
14285# #
14286# S t a t i s t i c s #
14287# #
14288# #
14289# #
14290###############################################################################
14291#
14292#
14293void
14294Statistics(ref,...)
14295 Image::Magick ref=NO_INIT
14296 ALIAS:
14297 StatisticsImage = 1
14298 statistics = 2
14299 statisticsimage = 3
14300 PPCODE:
14301 {
14302#define ChannelStatistics(channel) \
14303{ \
cristy151b66d2015-04-15 10:50:31 +000014304 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014305 (double) channel_statistics[channel].depth); \
14306 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014307 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014308 channel_statistics[channel].minima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014309 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014310 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014311 channel_statistics[channel].maxima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014312 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014313 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014314 channel_statistics[channel].mean/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014315 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014316 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014317 channel_statistics[channel].standard_deviation/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014318 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014319 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014320 channel_statistics[channel].kurtosis); \
14321 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014322 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014323 channel_statistics[channel].skewness); \
14324 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014325 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy275bdd92014-11-08 23:45:03 +000014326 channel_statistics[channel].entropy); \
14327 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014328}
14329
14330 AV
14331 *av;
14332
14333 char
cristy151b66d2015-04-15 10:50:31 +000014334 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014335
14336 ChannelStatistics
14337 *channel_statistics;
14338
cristy4a3ce0a2013-08-03 20:06:59 +000014339 ExceptionInfo
14340 *exception;
14341
14342 Image
14343 *image;
14344
14345 ssize_t
14346 count;
14347
14348 struct PackageInfo
14349 *info;
14350
14351 SV
14352 *perl_exception,
14353 *reference;
14354
14355 PERL_UNUSED_VAR(ref);
14356 PERL_UNUSED_VAR(ix);
14357 exception=AcquireExceptionInfo();
14358 perl_exception=newSVpv("",0);
14359 av=NULL;
14360 if (sv_isobject(ST(0)) == 0)
14361 {
14362 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14363 PackageName);
14364 goto PerlException;
14365 }
14366 reference=SvRV(ST(0));
14367 av=newAV();
14368 SvREFCNT_dec(av);
14369 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14370 if (image == (Image *) NULL)
14371 {
14372 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14373 PackageName);
14374 goto PerlException;
14375 }
cristy4a3ce0a2013-08-03 20:06:59 +000014376 count=0;
14377 for ( ; image; image=image->next)
14378 {
Cristyb1710fe2017-02-11 13:51:48 -050014379 register size_t
14380 i;
14381
cristy4a3ce0a2013-08-03 20:06:59 +000014382 channel_statistics=GetImageStatistics(image,exception);
14383 if (channel_statistics == (ChannelStatistics *) NULL)
14384 continue;
14385 count++;
Cristyb1710fe2017-02-11 13:51:48 -050014386 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
14387 {
14388 PixelChannel channel=GetPixelChannelChannel(image,i);
14389 PixelTrait traits=GetPixelChannelTraits(image,channel);
Cristy5a854dc2017-02-11 15:43:46 -050014390 if (traits == UndefinedPixelTrait)
Cristyb1710fe2017-02-11 13:51:48 -050014391 continue;
Cristy5a854dc2017-02-11 15:43:46 -050014392 EXTEND(sp,8*(i+1)*count);
Cristyb1710fe2017-02-11 13:51:48 -050014393 ChannelStatistics(channel);
14394 }
cristy4a3ce0a2013-08-03 20:06:59 +000014395 channel_statistics=(ChannelStatistics *)
14396 RelinquishMagickMemory(channel_statistics);
14397 }
14398
14399 PerlException:
14400 InheritPerlException(exception,perl_exception);
14401 exception=DestroyExceptionInfo(exception);
14402 SvREFCNT_dec(perl_exception);
14403 }
14404
14405#
14406###############################################################################
14407# #
14408# #
14409# #
14410# S y n c A u t h e n t i c P i x e l s #
14411# #
14412# #
14413# #
14414###############################################################################
14415#
14416#
14417void
14418SyncAuthenticPixels(ref,...)
14419 Image::Magick ref = NO_INIT
14420 ALIAS:
14421 Syncauthenticpixels = 1
14422 SyncImagePixels = 2
14423 syncimagepixels = 3
14424 CODE:
14425 {
14426 ExceptionInfo
14427 *exception;
14428
14429 Image
14430 *image;
14431
14432 MagickBooleanType
14433 status;
14434
14435 struct PackageInfo
14436 *info;
14437
14438 SV
14439 *perl_exception,
14440 *reference;
14441
14442 PERL_UNUSED_VAR(ref);
14443 PERL_UNUSED_VAR(ix);
14444 exception=AcquireExceptionInfo();
14445 perl_exception=newSVpv("",0);
14446 if (sv_isobject(ST(0)) == 0)
14447 {
14448 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14449 PackageName);
14450 goto PerlException;
14451 }
14452
14453 reference=SvRV(ST(0));
14454 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14455 if (image == (Image *) NULL)
14456 {
14457 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14458 PackageName);
14459 goto PerlException;
14460 }
14461
14462 status=SyncAuthenticPixels(image,exception);
14463 if (status != MagickFalse)
14464 return;
14465
14466 PerlException:
14467 InheritPerlException(exception,perl_exception);
14468 exception=DestroyExceptionInfo(exception);
14469 SvREFCNT_dec(perl_exception); /* throw away all errors */
14470 }
14471
14472#
14473###############################################################################
14474# #
14475# #
14476# #
cristy4a3ce0a2013-08-03 20:06:59 +000014477# W r i t e #
14478# #
14479# #
14480# #
14481###############################################################################
14482#
14483#
14484void
14485Write(ref,...)
14486 Image::Magick ref=NO_INIT
14487 ALIAS:
14488 WriteImage = 1
14489 write = 2
14490 writeimage = 3
14491 PPCODE:
14492 {
14493 char
cristy151b66d2015-04-15 10:50:31 +000014494 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014495
14496 ExceptionInfo
14497 *exception;
14498
14499 Image
14500 *image,
14501 *next;
14502
14503 register ssize_t
14504 i;
14505
14506 ssize_t
14507 number_images,
14508 scene;
14509
14510 struct PackageInfo
14511 *info,
14512 *package_info;
14513
14514 SV
14515 *perl_exception,
14516 *reference;
14517
14518 PERL_UNUSED_VAR(ref);
14519 PERL_UNUSED_VAR(ix);
14520 exception=AcquireExceptionInfo();
14521 perl_exception=newSVpv("",0);
14522 number_images=0;
14523 package_info=(struct PackageInfo *) NULL;
14524 if (sv_isobject(ST(0)) == 0)
14525 {
14526 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14527 PackageName);
14528 goto PerlException;
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 package_info=ClonePackageInfo(info,exception);
14539 if (items == 2)
14540 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14541 else
14542 if (items > 2)
14543 for (i=2; i < items; i+=2)
14544 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14545 exception);
14546 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014547 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014548 scene=0;
14549 for (next=image; next; next=next->next)
14550 {
cristy151b66d2015-04-15 10:50:31 +000014551 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014552 next->scene=scene++;
14553 }
cristy68bd79a2015-02-25 12:23:36 +000014554 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014555 SetImageInfo(package_info->image_info,(unsigned int)
14556 GetImageListLength(image),exception);
14557 for (next=image; next; next=next->next)
14558 {
14559 (void) WriteImage(package_info->image_info,next,exception);
14560 number_images++;
14561 if (package_info->image_info->adjoin)
14562 break;
14563 }
14564
14565 PerlException:
14566 if (package_info != (struct PackageInfo *) NULL)
14567 DestroyPackageInfo(package_info);
14568 InheritPerlException(exception,perl_exception);
14569 exception=DestroyExceptionInfo(exception);
14570 sv_setiv(perl_exception,(IV) number_images);
14571 SvPOK_on(perl_exception);
14572 ST(0)=sv_2mortal(perl_exception);
14573 XSRETURN(1);
14574 }