blob: a70b4c45e203704c1b2c3dbd81a4a22c0527bd13 [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)
Cristyb5b1f5d2017-03-31 16:42:35 -04001186 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001187 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04001228 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001229 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04001309 (void) SetImageOption(image,"Comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001310 info ? info->image_info : (ImageInfo *) NULL,image,
Cristyb5b1f5d2017-03-31 16:42:35 -04001311 SvPV(sval,na),exception));
cristy4a3ce0a2013-08-03 20:06:59 +00001312 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04001333 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001334 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04001436 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001437 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04001469 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001470 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04001539 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001540 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04001583 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001584 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04001650 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001651 break;
1652 }
1653 case 'L':
1654 case 'l':
1655 {
1656 if (LocaleCompare(attribute,"label") == 0)
1657 {
1658 for ( ; image; image=image->next)
Cristyb5b1f5d2017-03-31 16:42:35 -04001659 (void) SetImageOption(image,attribute,InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001660 info ? info->image_info : (ImageInfo *) NULL,image,
Cristyb5b1f5d2017-03-31 16:42:35 -04001661 SvPV(sval,na),exception));
cristy4a3ce0a2013-08-03 20:06:59 +00001662 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04001669 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001670 break;
1671 }
1672 case 'M':
1673 case 'm':
1674 {
1675 if (LocaleCompare(attribute,"magick") == 0)
1676 {
1677 if (info)
Cristyb5b1f5d2017-03-31 16:42:35 -04001678 (void) FormatLocaleString(info->image_info->filename,
1679 MagickPathExtent,"%s:",SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001680 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04001763 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001764 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04001794 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001795 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04001881 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001882 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04001898 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001899 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04001986 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001987 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04002036 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00002037 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04002115 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00002116 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04002169 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00002170 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04002206 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00002207 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)
Cristyb5b1f5d2017-03-31 16:42:35 -04002240 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00002241 break;
2242 }
2243 default:
2244 {
2245 if (info)
2246 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2247 for ( ; image; image=image->next)
Cristyb5b1f5d2017-03-31 16:42:35 -04002248 SetImageArtifact(image,attribute,SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00002249 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
Cristyb5b1f5d2017-03-31 16:42:35 -04004878 value=GetImageOption(image,attribute);
cristy4a3ce0a2013-08-03 20:06:59 +00004879 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;
Cristyb5b1f5d2017-03-31 16:42:35 -04005262 value=GetImageOption(image,"label");
cristy4a3ce0a2013-08-03 20:06:59 +00005263 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;
Cristyb5b1f5d2017-03-31 16:42:35 -04007853 (void) SetImageOption(image,"comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007854 info ? info->image_info : (ImageInfo *) NULL,image,
Cristyb5b1f5d2017-03-31 16:42:35 -04007855 argument_list[0].string_reference,exception));
cristy4a3ce0a2013-08-03 20:06:59 +00007856 break;
7857 }
7858 case 2: /* Label */
7859 {
7860 if (attribute_flag[0] == 0)
7861 argument_list[0].string_reference=(char *) NULL;
Cristyb5b1f5d2017-03-31 16:42:35 -04007862 (void) SetImageOption(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007863 info ? info->image_info : (ImageInfo *) NULL,image,
Cristyb5b1f5d2017-03-31 16:42:35 -04007864 argument_list[0].string_reference,exception));
cristy4a3ce0a2013-08-03 20:06:59 +00007865 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 }
Cristyb5b1f5d2017-03-31 16:42:35 -04009196 (void) FormatLocaleString(modulate,MagickPathExtent,
9197 "%.20g,%.20g,%.20g",geometry_info.rho,geometry_info.sigma,
9198 geometry_info.xi);
cristy4a3ce0a2013-08-03 20:06:59 +00009199 (void) ModulateImage(image,modulate,exception);
9200 break;
9201 }
9202 case 44: /* Negate */
9203 {
9204 if (attribute_flag[0] == 0)
9205 argument_list[0].integer_reference=0;
9206 if (attribute_flag[1] != 0)
9207 channel=(ChannelType) argument_list[1].integer_reference;
9208 channel_mask=SetImageChannelMask(image,channel);
9209 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9210 MagickTrue : MagickFalse,exception);
9211 (void) SetImageChannelMask(image,channel_mask);
9212 break;
9213 }
9214 case 45: /* Normalize */
9215 {
9216 if (attribute_flag[0] != 0)
9217 channel=(ChannelType) argument_list[0].integer_reference;
9218 channel_mask=SetImageChannelMask(image,channel);
9219 NormalizeImage(image,exception);
9220 (void) SetImageChannelMask(image,channel_mask);
9221 break;
9222 }
9223 case 46: /* NumberColors */
9224 break;
9225 case 47: /* Opaque */
9226 {
9227 MagickBooleanType
9228 invert;
9229
9230 PixelInfo
9231 fill_color,
9232 target;
9233
9234 (void) QueryColorCompliance("none",AllCompliance,&target,
9235 exception);
9236 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9237 exception);
9238 if (attribute_flag[0] != 0)
9239 (void) QueryColorCompliance(argument_list[0].string_reference,
9240 AllCompliance,&target,exception);
9241 if (attribute_flag[1] != 0)
9242 (void) QueryColorCompliance(argument_list[1].string_reference,
9243 AllCompliance,&fill_color,exception);
9244 if (attribute_flag[2] != 0)
9245 image->fuzz=StringToDoubleInterval(
9246 argument_list[2].string_reference,(double) QuantumRange+1.0);
9247 if (attribute_flag[3] != 0)
9248 channel=(ChannelType) argument_list[3].integer_reference;
9249 invert=MagickFalse;
9250 if (attribute_flag[4] != 0)
9251 invert=(MagickBooleanType) argument_list[4].integer_reference;
9252 channel_mask=SetImageChannelMask(image,channel);
9253 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9254 (void) SetImageChannelMask(image,channel_mask);
9255 break;
9256 }
9257 case 48: /* Quantize */
9258 {
9259 QuantizeInfo
9260 *quantize_info;
9261
9262 quantize_info=AcquireQuantizeInfo(info->image_info);
9263 if (attribute_flag[0] != 0)
9264 quantize_info->number_colors=(size_t)
9265 argument_list[0].integer_reference;
9266 if (attribute_flag[1] != 0)
9267 quantize_info->tree_depth=(size_t)
9268 argument_list[1].integer_reference;
9269 if (attribute_flag[2] != 0)
9270 quantize_info->colorspace=(ColorspaceType)
9271 argument_list[2].integer_reference;
9272 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009273 quantize_info->dither_method=(DitherMethod)
9274 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009275 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009276 quantize_info->measure_error=
9277 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009278 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009279 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009280 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009281 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009282 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009283 argument_list[7].integer_reference;
9284 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009285 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009286 else
cristyf7563392014-03-25 13:54:04 +00009287 if ((image->storage_class == DirectClass) ||
9288 (image->colors > quantize_info->number_colors) ||
9289 (quantize_info->colorspace == GRAYColorspace))
9290 (void) QuantizeImage(quantize_info,image,exception);
9291 else
9292 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009293 quantize_info=DestroyQuantizeInfo(quantize_info);
9294 break;
9295 }
9296 case 49: /* Raise */
9297 {
9298 if (attribute_flag[0] != 0)
9299 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9300 &geometry,exception);
9301 if (attribute_flag[1] != 0)
9302 geometry.width=argument_list[1].integer_reference;
9303 if (attribute_flag[2] != 0)
9304 geometry.height=argument_list[2].integer_reference;
9305 if (attribute_flag[3] == 0)
9306 argument_list[3].integer_reference=1;
9307 (void) RaiseImage(image,&geometry,
9308 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9309 exception);
9310 break;
9311 }
9312 case 50: /* Segment */
9313 {
9314 ColorspaceType
9315 colorspace;
9316
9317 double
9318 cluster_threshold,
9319 smoothing_threshold;
9320
9321 MagickBooleanType
9322 verbose;
9323
9324 cluster_threshold=1.0;
9325 smoothing_threshold=1.5;
9326 colorspace=sRGBColorspace;
9327 verbose=MagickFalse;
9328 if (attribute_flag[0] != 0)
9329 {
9330 flags=ParseGeometry(argument_list[0].string_reference,
9331 &geometry_info);
9332 cluster_threshold=geometry_info.rho;
9333 if (flags & SigmaValue)
9334 smoothing_threshold=geometry_info.sigma;
9335 }
9336 if (attribute_flag[1] != 0)
9337 cluster_threshold=argument_list[1].real_reference;
9338 if (attribute_flag[2] != 0)
9339 smoothing_threshold=argument_list[2].real_reference;
9340 if (attribute_flag[3] != 0)
9341 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9342 if (attribute_flag[4] != 0)
9343 verbose=argument_list[4].integer_reference != 0 ?
9344 MagickTrue : MagickFalse;
9345 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9346 smoothing_threshold,exception);
9347 break;
9348 }
9349 case 51: /* Signature */
9350 {
9351 (void) SignatureImage(image,exception);
9352 break;
9353 }
9354 case 52: /* Solarize */
9355 {
9356 geometry_info.rho=QuantumRange/2.0;
9357 if (attribute_flag[0] != 0)
9358 flags=ParseGeometry(argument_list[0].string_reference,
9359 &geometry_info);
9360 if (attribute_flag[1] != 0)
9361 geometry_info.rho=StringToDoubleInterval(
9362 argument_list[1].string_reference,(double) QuantumRange+1.0);
9363 (void) SolarizeImage(image,geometry_info.rho,exception);
9364 break;
9365 }
9366 case 53: /* Sync */
9367 {
9368 (void) SyncImage(image,exception);
9369 break;
9370 }
9371 case 54: /* Texture */
9372 {
9373 if (attribute_flag[0] == 0)
9374 break;
9375 TextureImage(image,argument_list[0].image_reference,exception);
9376 break;
9377 }
9378 case 55: /* Evalute */
9379 {
9380 MagickEvaluateOperator
9381 op;
9382
9383 op=SetEvaluateOperator;
9384 if (attribute_flag[0] == MagickFalse)
9385 argument_list[0].real_reference=0.0;
9386 if (attribute_flag[1] != MagickFalse)
9387 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9388 if (attribute_flag[2] != MagickFalse)
9389 channel=(ChannelType) argument_list[2].integer_reference;
9390 channel_mask=SetImageChannelMask(image,channel);
9391 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9392 exception);
9393 (void) SetImageChannelMask(image,channel_mask);
9394 break;
9395 }
9396 case 56: /* Transparent */
9397 {
9398 double
9399 opacity;
9400
9401 MagickBooleanType
9402 invert;
9403
9404 PixelInfo
9405 target;
9406
9407 (void) QueryColorCompliance("none",AllCompliance,&target,
9408 exception);
9409 if (attribute_flag[0] != 0)
9410 (void) QueryColorCompliance(argument_list[0].string_reference,
9411 AllCompliance,&target,exception);
9412 opacity=TransparentAlpha;
9413 if (attribute_flag[1] != 0)
9414 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9415 (double) QuantumRange+1.0);
9416 if (attribute_flag[2] != 0)
9417 image->fuzz=StringToDoubleInterval(
9418 argument_list[2].string_reference,(double) QuantumRange+1.0);
9419 if (attribute_flag[3] == 0)
9420 argument_list[3].integer_reference=0;
9421 invert=MagickFalse;
9422 if (attribute_flag[3] != 0)
9423 invert=(MagickBooleanType) argument_list[3].integer_reference;
9424 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9425 invert,exception);
9426 break;
9427 }
9428 case 57: /* Threshold */
9429 {
9430 double
9431 threshold;
9432
9433 if (attribute_flag[0] == 0)
9434 argument_list[0].string_reference="50%";
9435 if (attribute_flag[1] != 0)
9436 channel=(ChannelType) argument_list[1].integer_reference;
9437 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9438 (double) QuantumRange+1.0);
9439 channel_mask=SetImageChannelMask(image,channel);
9440 (void) BilevelImage(image,threshold,exception);
9441 (void) SetImageChannelMask(image,channel_mask);
9442 break;
9443 }
9444 case 58: /* Charcoal */
9445 {
9446 if (attribute_flag[0] != 0)
9447 {
9448 flags=ParseGeometry(argument_list[0].string_reference,
9449 &geometry_info);
9450 if ((flags & SigmaValue) == 0)
9451 geometry_info.sigma=1.0;
9452 }
9453 if (attribute_flag[1] != 0)
9454 geometry_info.rho=argument_list[1].real_reference;
9455 if (attribute_flag[2] != 0)
9456 geometry_info.sigma=argument_list[2].real_reference;
9457 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9458 exception);
9459 break;
9460 }
9461 case 59: /* Trim */
9462 {
9463 if (attribute_flag[0] != 0)
9464 image->fuzz=StringToDoubleInterval(
9465 argument_list[0].string_reference,(double) QuantumRange+1.0);
9466 image=TrimImage(image,exception);
9467 break;
9468 }
9469 case 60: /* Wave */
9470 {
9471 PixelInterpolateMethod
9472 method;
9473
9474 if (attribute_flag[0] != 0)
9475 {
9476 flags=ParseGeometry(argument_list[0].string_reference,
9477 &geometry_info);
9478 if ((flags & SigmaValue) == 0)
9479 geometry_info.sigma=1.0;
9480 }
9481 if (attribute_flag[1] != 0)
9482 geometry_info.rho=argument_list[1].real_reference;
9483 if (attribute_flag[2] != 0)
9484 geometry_info.sigma=argument_list[2].real_reference;
9485 method=UndefinedInterpolatePixel;
9486 if (attribute_flag[3] != 0)
9487 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9488 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9489 method,exception);
9490 break;
9491 }
9492 case 61: /* Separate */
9493 {
9494 if (attribute_flag[0] != 0)
9495 channel=(ChannelType) argument_list[0].integer_reference;
9496 image=SeparateImage(image,channel,exception);
9497 break;
9498 }
9499 case 63: /* Stereo */
9500 {
9501 if (attribute_flag[0] == 0)
9502 {
9503 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9504 PackageName);
9505 goto PerlException;
9506 }
9507 if (attribute_flag[1] != 0)
9508 geometry.x=argument_list[1].integer_reference;
9509 if (attribute_flag[2] != 0)
9510 geometry.y=argument_list[2].integer_reference;
9511 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9512 geometry.x,geometry.y,exception);
9513 break;
9514 }
9515 case 64: /* Stegano */
9516 {
9517 if (attribute_flag[0] == 0)
9518 {
9519 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9520 PackageName);
9521 goto PerlException;
9522 }
9523 if (attribute_flag[1] == 0)
9524 argument_list[1].integer_reference=0;
9525 image->offset=argument_list[1].integer_reference;
9526 image=SteganoImage(image,argument_list[0].image_reference,exception);
9527 break;
9528 }
9529 case 65: /* Deconstruct */
9530 {
9531 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9532 break;
9533 }
9534 case 66: /* GaussianBlur */
9535 {
9536 if (attribute_flag[0] != 0)
9537 {
9538 flags=ParseGeometry(argument_list[0].string_reference,
9539 &geometry_info);
9540 if ((flags & SigmaValue) == 0)
9541 geometry_info.sigma=1.0;
9542 }
9543 if (attribute_flag[1] != 0)
9544 geometry_info.rho=argument_list[1].real_reference;
9545 if (attribute_flag[2] != 0)
9546 geometry_info.sigma=argument_list[2].real_reference;
9547 if (attribute_flag[3] != 0)
9548 channel=(ChannelType) argument_list[3].integer_reference;
9549 channel_mask=SetImageChannelMask(image,channel);
9550 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9551 exception);
9552 if (image != (Image *) NULL)
9553 (void) SetImageChannelMask(image,channel_mask);
9554 break;
9555 }
9556 case 67: /* Convolve */
9557 {
9558 KernelInfo
9559 *kernel;
9560
9561 kernel=(KernelInfo *) NULL;
9562 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9563 break;
9564 if (attribute_flag[0] != 0)
9565 {
9566 AV
9567 *av;
9568
9569 size_t
9570 order;
9571
cristy2c57b742014-10-31 00:40:34 +00009572 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009573 if (kernel == (KernelInfo *) NULL)
9574 break;
9575 av=(AV *) argument_list[0].array_reference;
9576 order=(size_t) sqrt(av_len(av)+1);
9577 kernel->width=order;
9578 kernel->height=order;
9579 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9580 order*sizeof(*kernel->values));
9581 if (kernel->values == (MagickRealType *) NULL)
9582 {
9583 kernel=DestroyKernelInfo(kernel);
9584 ThrowPerlException(exception,ResourceLimitFatalError,
9585 "MemoryAllocationFailed",PackageName);
9586 goto PerlException;
9587 }
9588 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9589 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9590 for ( ; j < (ssize_t) (order*order); j++)
9591 kernel->values[j]=0.0;
9592 }
9593 if (attribute_flag[1] != 0)
9594 channel=(ChannelType) argument_list[1].integer_reference;
9595 if (attribute_flag[2] != 0)
9596 SetImageArtifact(image,"filter:blur",
9597 argument_list[2].string_reference);
9598 if (attribute_flag[3] != 0)
9599 {
cristy2c57b742014-10-31 00:40:34 +00009600 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9601 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009602 if (kernel == (KernelInfo *) NULL)
9603 break;
9604 }
9605 channel_mask=SetImageChannelMask(image,channel);
9606 image=ConvolveImage(image,kernel,exception);
9607 if (image != (Image *) NULL)
9608 (void) SetImageChannelMask(image,channel_mask);
9609 kernel=DestroyKernelInfo(kernel);
9610 break;
9611 }
9612 case 68: /* Profile */
9613 {
9614 const char
9615 *name;
9616
9617 Image
9618 *profile_image;
9619
9620 ImageInfo
9621 *profile_info;
9622
9623 StringInfo
9624 *profile;
9625
9626 name="*";
9627 if (attribute_flag[0] != 0)
9628 name=argument_list[0].string_reference;
9629 if (attribute_flag[2] != 0)
9630 image->rendering_intent=(RenderingIntent)
9631 argument_list[2].integer_reference;
9632 if (attribute_flag[3] != 0)
9633 image->black_point_compensation=
9634 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9635 if (attribute_flag[1] != 0)
9636 {
9637 if (argument_list[1].length == 0)
9638 {
9639 /*
9640 Remove a profile from the image.
9641 */
9642 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9643 exception);
9644 break;
9645 }
9646 /*
9647 Associate user supplied profile with the image.
9648 */
9649 profile=AcquireStringInfo(argument_list[1].length);
9650 SetStringInfoDatum(profile,(const unsigned char *)
9651 argument_list[1].string_reference);
9652 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9653 (size_t) GetStringInfoLength(profile),exception);
9654 profile=DestroyStringInfo(profile);
9655 break;
9656 }
9657 /*
9658 Associate a profile with the image.
9659 */
9660 profile_info=CloneImageInfo(info ? info->image_info :
9661 (ImageInfo *) NULL);
9662 profile_image=ReadImages(profile_info,name,exception);
9663 if (profile_image == (Image *) NULL)
9664 break;
9665 ResetImageProfileIterator(profile_image);
9666 name=GetNextImageProfile(profile_image);
9667 while (name != (const char *) NULL)
9668 {
9669 const StringInfo
9670 *profile;
9671
9672 profile=GetImageProfile(profile_image,name);
9673 if (profile != (const StringInfo *) NULL)
9674 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9675 (size_t) GetStringInfoLength(profile),exception);
9676 name=GetNextImageProfile(profile_image);
9677 }
9678 profile_image=DestroyImage(profile_image);
9679 profile_info=DestroyImageInfo(profile_info);
9680 break;
9681 }
9682 case 69: /* UnsharpMask */
9683 {
9684 if (attribute_flag[0] != 0)
9685 {
9686 flags=ParseGeometry(argument_list[0].string_reference,
9687 &geometry_info);
9688 if ((flags & SigmaValue) == 0)
9689 geometry_info.sigma=1.0;
9690 if ((flags & XiValue) == 0)
9691 geometry_info.xi=1.0;
9692 if ((flags & PsiValue) == 0)
9693 geometry_info.psi=0.5;
9694 }
9695 if (attribute_flag[1] != 0)
9696 geometry_info.rho=argument_list[1].real_reference;
9697 if (attribute_flag[2] != 0)
9698 geometry_info.sigma=argument_list[2].real_reference;
9699 if (attribute_flag[3] != 0)
9700 geometry_info.xi=argument_list[3].real_reference;
9701 if (attribute_flag[4] != 0)
9702 geometry_info.psi=argument_list[4].real_reference;
9703 if (attribute_flag[5] != 0)
9704 channel=(ChannelType) argument_list[5].integer_reference;
9705 channel_mask=SetImageChannelMask(image,channel);
9706 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9707 geometry_info.xi,geometry_info.psi,exception);
9708 if (image != (Image *) NULL)
9709 (void) SetImageChannelMask(image,channel_mask);
9710 break;
9711 }
9712 case 70: /* MotionBlur */
9713 {
9714 if (attribute_flag[0] != 0)
9715 {
9716 flags=ParseGeometry(argument_list[0].string_reference,
9717 &geometry_info);
9718 if ((flags & SigmaValue) == 0)
9719 geometry_info.sigma=1.0;
9720 if ((flags & XiValue) == 0)
9721 geometry_info.xi=1.0;
9722 }
9723 if (attribute_flag[1] != 0)
9724 geometry_info.rho=argument_list[1].real_reference;
9725 if (attribute_flag[2] != 0)
9726 geometry_info.sigma=argument_list[2].real_reference;
9727 if (attribute_flag[3] != 0)
9728 geometry_info.xi=argument_list[3].real_reference;
9729 if (attribute_flag[4] != 0)
9730 channel=(ChannelType) argument_list[4].integer_reference;
9731 channel_mask=SetImageChannelMask(image,channel);
9732 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9733 geometry_info.xi,exception);
9734 if (image != (Image *) NULL)
9735 (void) SetImageChannelMask(image,channel_mask);
9736 break;
9737 }
9738 case 71: /* OrderedDither */
9739 {
9740 if (attribute_flag[0] == 0)
9741 argument_list[0].string_reference="o8x8";
9742 if (attribute_flag[1] != 0)
9743 channel=(ChannelType) argument_list[1].integer_reference;
9744 channel_mask=SetImageChannelMask(image,channel);
Cristy6b93c072016-02-04 07:45:48 -05009745 (void) OrderedDitherImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009746 exception);
9747 (void) SetImageChannelMask(image,channel_mask);
9748 break;
9749 }
9750 case 72: /* Shave */
9751 {
9752 if (attribute_flag[0] != 0)
9753 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9754 &geometry,exception);
9755 if (attribute_flag[1] != 0)
9756 geometry.width=argument_list[1].integer_reference;
9757 if (attribute_flag[2] != 0)
9758 geometry.height=argument_list[2].integer_reference;
9759 image=ShaveImage(image,&geometry,exception);
9760 break;
9761 }
9762 case 73: /* Level */
9763 {
9764 double
9765 black_point,
9766 gamma,
9767 white_point;
9768
9769 black_point=0.0;
9770 white_point=(double) image->columns*image->rows;
9771 gamma=1.0;
9772 if (attribute_flag[0] != 0)
9773 {
9774 flags=ParseGeometry(argument_list[0].string_reference,
9775 &geometry_info);
9776 black_point=geometry_info.rho;
9777 if ((flags & SigmaValue) != 0)
9778 white_point=geometry_info.sigma;
9779 if ((flags & XiValue) != 0)
9780 gamma=geometry_info.xi;
9781 if ((flags & PercentValue) != 0)
9782 {
9783 black_point*=(double) (QuantumRange/100.0);
9784 white_point*=(double) (QuantumRange/100.0);
9785 }
9786 if ((flags & SigmaValue) == 0)
9787 white_point=(double) QuantumRange-black_point;
9788 }
9789 if (attribute_flag[1] != 0)
9790 black_point=argument_list[1].real_reference;
9791 if (attribute_flag[2] != 0)
9792 white_point=argument_list[2].real_reference;
9793 if (attribute_flag[3] != 0)
9794 gamma=argument_list[3].real_reference;
9795 if (attribute_flag[4] != 0)
9796 channel=(ChannelType) argument_list[4].integer_reference;
9797 if (attribute_flag[5] != 0)
9798 {
9799 argument_list[0].real_reference=argument_list[5].real_reference;
9800 attribute_flag[0]=attribute_flag[5];
9801 }
9802 channel_mask=SetImageChannelMask(image,channel);
9803 (void) LevelImage(image,black_point,white_point,gamma,exception);
9804 (void) SetImageChannelMask(image,channel_mask);
9805 break;
9806 }
9807 case 74: /* Clip */
9808 {
9809 if (attribute_flag[0] == 0)
9810 argument_list[0].string_reference="#1";
9811 if (attribute_flag[1] == 0)
9812 argument_list[1].integer_reference=MagickTrue;
9813 (void) ClipImagePath(image,argument_list[0].string_reference,
9814 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9815 exception);
9816 break;
9817 }
9818 case 75: /* AffineTransform */
9819 {
9820 DrawInfo
9821 *draw_info;
9822
9823 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9824 (DrawInfo *) NULL);
9825 if (attribute_flag[0] != 0)
9826 {
9827 AV
9828 *av;
9829
9830 av=(AV *) argument_list[0].array_reference;
9831 if ((av_len(av) != 3) && (av_len(av) != 5))
9832 {
9833 ThrowPerlException(exception,OptionError,
9834 "affine matrix must have 4 or 6 elements",PackageName);
9835 goto PerlException;
9836 }
9837 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9838 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9839 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9840 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9841 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9842 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9843 {
9844 ThrowPerlException(exception,OptionError,
9845 "affine matrix is singular",PackageName);
9846 goto PerlException;
9847 }
9848 if (av_len(av) == 5)
9849 {
9850 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9851 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9852 }
9853 }
9854 for (j=1; j < 6; j++)
9855 {
9856 if (attribute_flag[j] == 0)
9857 continue;
9858 value=argument_list[j].string_reference;
9859 angle=argument_list[j].real_reference;
9860 current=draw_info->affine;
9861 GetAffineMatrix(&affine);
9862 switch (j)
9863 {
9864 case 1:
9865 {
9866 /*
9867 Translate.
9868 */
9869 flags=ParseGeometry(value,&geometry_info);
9870 affine.tx=geometry_info.xi;
9871 affine.ty=geometry_info.psi;
9872 if ((flags & PsiValue) == 0)
9873 affine.ty=affine.tx;
9874 break;
9875 }
9876 case 2:
9877 {
9878 /*
9879 Scale.
9880 */
9881 flags=ParseGeometry(value,&geometry_info);
9882 affine.sx=geometry_info.rho;
9883 affine.sy=geometry_info.sigma;
9884 if ((flags & SigmaValue) == 0)
9885 affine.sy=affine.sx;
9886 break;
9887 }
9888 case 3:
9889 {
9890 /*
9891 Rotate.
9892 */
9893 if (angle == 0.0)
9894 break;
9895 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9896 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9897 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9898 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9899 break;
9900 }
9901 case 4:
9902 {
9903 /*
9904 SkewX.
9905 */
9906 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9907 break;
9908 }
9909 case 5:
9910 {
9911 /*
9912 SkewY.
9913 */
9914 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9915 break;
9916 }
9917 }
9918 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9919 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9920 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9921 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9922 draw_info->affine.tx=
9923 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9924 draw_info->affine.ty=
9925 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9926 }
9927 if (attribute_flag[6] != 0)
9928 image->interpolate=(PixelInterpolateMethod)
9929 argument_list[6].integer_reference;
9930 if (attribute_flag[7] != 0)
9931 QueryColorCompliance(argument_list[7].string_reference,
9932 AllCompliance,&image->background_color,exception);
9933 image=AffineTransformImage(image,&draw_info->affine,exception);
9934 draw_info=DestroyDrawInfo(draw_info);
9935 break;
9936 }
9937 case 76: /* Difference */
9938 {
9939 if (attribute_flag[0] == 0)
9940 {
9941 ThrowPerlException(exception,OptionError,
9942 "ReferenceImageRequired",PackageName);
9943 goto PerlException;
9944 }
9945 if (attribute_flag[1] != 0)
9946 image->fuzz=StringToDoubleInterval(
9947 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -05009948 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009949 exception);
9950 break;
9951 }
9952 case 77: /* AdaptiveThreshold */
9953 {
9954 if (attribute_flag[0] != 0)
9955 {
9956 flags=ParseGeometry(argument_list[0].string_reference,
9957 &geometry_info);
9958 if ((flags & PercentValue) != 0)
9959 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9960 }
9961 if (attribute_flag[1] != 0)
9962 geometry_info.rho=argument_list[1].integer_reference;
9963 if (attribute_flag[2] != 0)
9964 geometry_info.sigma=argument_list[2].integer_reference;
9965 if (attribute_flag[3] != 0)
9966 geometry_info.xi=argument_list[3].integer_reference;;
9967 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9968 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9969 break;
9970 }
9971 case 78: /* Resample */
9972 {
9973 size_t
9974 height,
9975 width;
9976
9977 if (attribute_flag[0] != 0)
9978 {
9979 flags=ParseGeometry(argument_list[0].string_reference,
9980 &geometry_info);
9981 if ((flags & SigmaValue) == 0)
9982 geometry_info.sigma=geometry_info.rho;
9983 }
9984 if (attribute_flag[1] != 0)
9985 geometry_info.rho=argument_list[1].real_reference;
9986 if (attribute_flag[2] != 0)
9987 geometry_info.sigma=argument_list[2].real_reference;
9988 if (attribute_flag[3] == 0)
9989 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
9990 if (attribute_flag[4] == 0)
9991 SetImageArtifact(image,"filter:support",
9992 argument_list[4].string_reference);
9993 width=(size_t) (geometry_info.rho*image->columns/
9994 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
9995 height=(size_t) (geometry_info.sigma*image->rows/
9996 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
Cristy8645e042016-02-03 16:35:29 -05009997 image=ResizeImage(image,width,height,(FilterType)
cristy4a3ce0a2013-08-03 20:06:59 +00009998 argument_list[3].integer_reference,exception);
9999 if (image != (Image *) NULL)
10000 {
10001 image->resolution.x=geometry_info.rho;
10002 image->resolution.y=geometry_info.sigma;
10003 }
10004 break;
10005 }
10006 case 79: /* Describe */
10007 {
10008 if (attribute_flag[0] == 0)
10009 argument_list[0].file_reference=(FILE *) NULL;
10010 if (attribute_flag[1] != 0)
10011 (void) SetImageArtifact(image,"identify:features",
10012 argument_list[1].string_reference);
10013 (void) IdentifyImage(image,argument_list[0].file_reference,
10014 MagickTrue,exception);
10015 break;
10016 }
10017 case 80: /* BlackThreshold */
10018 {
10019 if (attribute_flag[0] == 0)
10020 argument_list[0].string_reference="50%";
10021 if (attribute_flag[2] != 0)
10022 channel=(ChannelType) argument_list[2].integer_reference;
10023 channel_mask=SetImageChannelMask(image,channel);
10024 BlackThresholdImage(image,argument_list[0].string_reference,
10025 exception);
10026 (void) SetImageChannelMask(image,channel_mask);
10027 break;
10028 }
10029 case 81: /* WhiteThreshold */
10030 {
10031 if (attribute_flag[0] == 0)
10032 argument_list[0].string_reference="50%";
10033 if (attribute_flag[2] != 0)
10034 channel=(ChannelType) argument_list[2].integer_reference;
10035 channel_mask=SetImageChannelMask(image,channel);
10036 WhiteThresholdImage(image,argument_list[0].string_reference,
10037 exception);
10038 (void) SetImageChannelMask(image,channel_mask);
10039 break;
10040 }
cristy60c73c02014-03-25 12:09:58 +000010041 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010042 {
10043 if (attribute_flag[0] != 0)
10044 {
10045 flags=ParseGeometry(argument_list[0].string_reference,
10046 &geometry_info);
10047 }
10048 if (attribute_flag[1] != 0)
10049 geometry_info.rho=argument_list[1].real_reference;
10050 if (attribute_flag[2] != 0)
10051 channel=(ChannelType) argument_list[2].integer_reference;
10052 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010053 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010054 if (image != (Image *) NULL)
10055 (void) SetImageChannelMask(image,channel_mask);
10056 break;
10057 }
10058 case 83: /* Thumbnail */
10059 {
10060 if (attribute_flag[0] != 0)
10061 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10062 &geometry,exception);
10063 if (attribute_flag[1] != 0)
10064 geometry.width=argument_list[1].integer_reference;
10065 if (attribute_flag[2] != 0)
10066 geometry.height=argument_list[2].integer_reference;
10067 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10068 break;
10069 }
10070 case 84: /* Strip */
10071 {
10072 (void) StripImage(image,exception);
10073 break;
10074 }
10075 case 85: /* Tint */
10076 {
10077 PixelInfo
10078 tint;
10079
10080 GetPixelInfo(image,&tint);
10081 if (attribute_flag[0] != 0)
10082 (void) QueryColorCompliance(argument_list[0].string_reference,
10083 AllCompliance,&tint,exception);
10084 if (attribute_flag[1] == 0)
10085 argument_list[1].string_reference="100";
10086 image=TintImage(image,argument_list[1].string_reference,&tint,
10087 exception);
10088 break;
10089 }
10090 case 86: /* Channel */
10091 {
10092 if (attribute_flag[0] != 0)
10093 channel=(ChannelType) argument_list[0].integer_reference;
10094 image=SeparateImage(image,channel,exception);
10095 break;
10096 }
10097 case 87: /* Splice */
10098 {
cristy260bd762014-08-15 12:46:34 +000010099 if (attribute_flag[7] != 0)
10100 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010101 if (attribute_flag[0] != 0)
10102 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10103 &geometry,exception);
10104 if (attribute_flag[1] != 0)
10105 geometry.width=argument_list[1].integer_reference;
10106 if (attribute_flag[2] != 0)
10107 geometry.height=argument_list[2].integer_reference;
10108 if (attribute_flag[3] != 0)
10109 geometry.x=argument_list[3].integer_reference;
10110 if (attribute_flag[4] != 0)
10111 geometry.y=argument_list[4].integer_reference;
10112 if (attribute_flag[5] != 0)
10113 image->fuzz=StringToDoubleInterval(
10114 argument_list[5].string_reference,(double) QuantumRange+1.0);
10115 if (attribute_flag[6] != 0)
10116 (void) QueryColorCompliance(argument_list[6].string_reference,
10117 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010118 image=SpliceImage(image,&geometry,exception);
10119 break;
10120 }
10121 case 88: /* Posterize */
10122 {
10123 if (attribute_flag[0] == 0)
10124 argument_list[0].integer_reference=3;
10125 if (attribute_flag[1] == 0)
10126 argument_list[1].integer_reference=0;
10127 (void) PosterizeImage(image,argument_list[0].integer_reference,
10128 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10129 NoDitherMethod,exception);
10130 break;
10131 }
10132 case 89: /* Shadow */
10133 {
10134 if (attribute_flag[0] != 0)
10135 {
10136 flags=ParseGeometry(argument_list[0].string_reference,
10137 &geometry_info);
10138 if ((flags & SigmaValue) == 0)
10139 geometry_info.sigma=1.0;
10140 if ((flags & XiValue) == 0)
10141 geometry_info.xi=4.0;
10142 if ((flags & PsiValue) == 0)
10143 geometry_info.psi=4.0;
10144 }
10145 if (attribute_flag[1] != 0)
10146 geometry_info.rho=argument_list[1].real_reference;
10147 if (attribute_flag[2] != 0)
10148 geometry_info.sigma=argument_list[2].real_reference;
10149 if (attribute_flag[3] != 0)
10150 geometry_info.xi=argument_list[3].integer_reference;
10151 if (attribute_flag[4] != 0)
10152 geometry_info.psi=argument_list[4].integer_reference;
10153 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10154 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10155 ceil(geometry_info.psi-0.5),exception);
10156 break;
10157 }
10158 case 90: /* Identify */
10159 {
10160 if (attribute_flag[0] == 0)
10161 argument_list[0].file_reference=(FILE *) NULL;
10162 if (attribute_flag[1] != 0)
10163 (void) SetImageArtifact(image,"identify:features",
10164 argument_list[1].string_reference);
10165 if ((attribute_flag[2] != 0) &&
10166 (argument_list[2].integer_reference != 0))
10167 (void) SetImageArtifact(image,"identify:unique","true");
10168 (void) IdentifyImage(image,argument_list[0].file_reference,
10169 MagickTrue,exception);
10170 break;
10171 }
10172 case 91: /* SepiaTone */
10173 {
10174 if (attribute_flag[0] == 0)
10175 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10176 image=SepiaToneImage(image,argument_list[0].real_reference,
10177 exception);
10178 break;
10179 }
10180 case 92: /* SigmoidalContrast */
10181 {
10182 MagickBooleanType
10183 sharpen;
10184
10185 if (attribute_flag[0] != 0)
10186 {
10187 flags=ParseGeometry(argument_list[0].string_reference,
10188 &geometry_info);
10189 if ((flags & SigmaValue) == 0)
10190 geometry_info.sigma=QuantumRange/2.0;
10191 if ((flags & PercentValue) != 0)
10192 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10193 }
10194 if (attribute_flag[1] != 0)
10195 geometry_info.rho=argument_list[1].real_reference;
10196 if (attribute_flag[2] != 0)
10197 geometry_info.sigma=argument_list[2].real_reference;
10198 if (attribute_flag[3] != 0)
10199 channel=(ChannelType) argument_list[3].integer_reference;
10200 sharpen=MagickTrue;
10201 if (attribute_flag[4] != 0)
10202 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10203 MagickFalse;
10204 channel_mask=SetImageChannelMask(image,channel);
10205 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10206 geometry_info.sigma,exception);
10207 (void) SetImageChannelMask(image,channel_mask);
10208 break;
10209 }
10210 case 93: /* Extent */
10211 {
10212 if (attribute_flag[7] != 0)
10213 image->gravity=(GravityType) argument_list[7].integer_reference;
10214 if (attribute_flag[0] != 0)
10215 {
10216 int
10217 flags;
10218
10219 flags=ParseGravityGeometry(image,
10220 argument_list[0].string_reference,&geometry,exception);
10221 (void) flags;
10222 if (geometry.width == 0)
10223 geometry.width=image->columns;
10224 if (geometry.height == 0)
10225 geometry.height=image->rows;
10226 }
10227 if (attribute_flag[1] != 0)
10228 geometry.width=argument_list[1].integer_reference;
10229 if (attribute_flag[2] != 0)
10230 geometry.height=argument_list[2].integer_reference;
10231 if (attribute_flag[3] != 0)
10232 geometry.x=argument_list[3].integer_reference;
10233 if (attribute_flag[4] != 0)
10234 geometry.y=argument_list[4].integer_reference;
10235 if (attribute_flag[5] != 0)
10236 image->fuzz=StringToDoubleInterval(
10237 argument_list[5].string_reference,(double) QuantumRange+1.0);
10238 if (attribute_flag[6] != 0)
10239 (void) QueryColorCompliance(argument_list[6].string_reference,
10240 AllCompliance,&image->background_color,exception);
10241 image=ExtentImage(image,&geometry,exception);
10242 break;
10243 }
10244 case 94: /* Vignette */
10245 {
10246 if (attribute_flag[0] != 0)
10247 {
10248 flags=ParseGeometry(argument_list[0].string_reference,
10249 &geometry_info);
10250 if ((flags & SigmaValue) == 0)
10251 geometry_info.sigma=1.0;
10252 if ((flags & XiValue) == 0)
10253 geometry_info.xi=0.1*image->columns;
10254 if ((flags & PsiValue) == 0)
10255 geometry_info.psi=0.1*image->rows;
10256 }
10257 if (attribute_flag[1] != 0)
10258 geometry_info.rho=argument_list[1].real_reference;
10259 if (attribute_flag[2] != 0)
10260 geometry_info.sigma=argument_list[2].real_reference;
10261 if (attribute_flag[3] != 0)
10262 geometry_info.xi=argument_list[3].integer_reference;
10263 if (attribute_flag[4] != 0)
10264 geometry_info.psi=argument_list[4].integer_reference;
10265 if (attribute_flag[5] != 0)
10266 (void) QueryColorCompliance(argument_list[5].string_reference,
10267 AllCompliance,&image->background_color,exception);
10268 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10269 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10270 ceil(geometry_info.psi-0.5),exception);
10271 break;
10272 }
10273 case 95: /* ContrastStretch */
10274 {
10275 double
10276 black_point,
10277 white_point;
10278
10279 black_point=0.0;
10280 white_point=(double) image->columns*image->rows;
10281 if (attribute_flag[0] != 0)
10282 {
10283 flags=ParseGeometry(argument_list[0].string_reference,
10284 &geometry_info);
10285 black_point=geometry_info.rho;
10286 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10287 black_point;
10288 if ((flags & PercentValue) != 0)
10289 {
10290 black_point*=(double) image->columns*image->rows/100.0;
10291 white_point*=(double) image->columns*image->rows/100.0;
10292 }
10293 white_point=(double) image->columns*image->rows-
10294 white_point;
10295 }
10296 if (attribute_flag[1] != 0)
10297 black_point=argument_list[1].real_reference;
10298 if (attribute_flag[2] != 0)
10299 white_point=argument_list[2].real_reference;
10300 if (attribute_flag[4] != 0)
10301 channel=(ChannelType) argument_list[4].integer_reference;
10302 channel_mask=SetImageChannelMask(image,channel);
10303 (void) ContrastStretchImage(image,black_point,white_point,exception);
10304 (void) SetImageChannelMask(image,channel_mask);
10305 break;
10306 }
10307 case 96: /* Sans0 */
10308 {
10309 break;
10310 }
10311 case 97: /* Sans1 */
10312 {
10313 break;
10314 }
10315 case 98: /* AdaptiveSharpen */
10316 {
10317 if (attribute_flag[0] != 0)
10318 {
10319 flags=ParseGeometry(argument_list[0].string_reference,
10320 &geometry_info);
10321 if ((flags & SigmaValue) == 0)
10322 geometry_info.sigma=1.0;
10323 if ((flags & XiValue) == 0)
10324 geometry_info.xi=0.0;
10325 }
10326 if (attribute_flag[1] != 0)
10327 geometry_info.rho=argument_list[1].real_reference;
10328 if (attribute_flag[2] != 0)
10329 geometry_info.sigma=argument_list[2].real_reference;
10330 if (attribute_flag[3] != 0)
10331 geometry_info.xi=argument_list[3].real_reference;
10332 if (attribute_flag[4] != 0)
10333 channel=(ChannelType) argument_list[4].integer_reference;
10334 channel_mask=SetImageChannelMask(image,channel);
10335 image=AdaptiveSharpenImage(image,geometry_info.rho,
10336 geometry_info.sigma,exception);
10337 if (image != (Image *) NULL)
10338 (void) SetImageChannelMask(image,channel_mask);
10339 break;
10340 }
10341 case 99: /* Transpose */
10342 {
10343 image=TransposeImage(image,exception);
10344 break;
10345 }
10346 case 100: /* Tranverse */
10347 {
10348 image=TransverseImage(image,exception);
10349 break;
10350 }
10351 case 101: /* AutoOrient */
10352 {
10353 image=AutoOrientImage(image,image->orientation,exception);
10354 break;
10355 }
10356 case 102: /* AdaptiveBlur */
10357 {
10358 if (attribute_flag[0] != 0)
10359 {
10360 flags=ParseGeometry(argument_list[0].string_reference,
10361 &geometry_info);
10362 if ((flags & SigmaValue) == 0)
10363 geometry_info.sigma=1.0;
10364 if ((flags & XiValue) == 0)
10365 geometry_info.xi=0.0;
10366 }
10367 if (attribute_flag[1] != 0)
10368 geometry_info.rho=argument_list[1].real_reference;
10369 if (attribute_flag[2] != 0)
10370 geometry_info.sigma=argument_list[2].real_reference;
10371 if (attribute_flag[3] != 0)
10372 channel=(ChannelType) argument_list[3].integer_reference;
10373 channel_mask=SetImageChannelMask(image,channel);
10374 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10375 exception);
10376 if (image != (Image *) NULL)
10377 (void) SetImageChannelMask(image,channel_mask);
10378 break;
10379 }
10380 case 103: /* Sketch */
10381 {
10382 if (attribute_flag[0] != 0)
10383 {
10384 flags=ParseGeometry(argument_list[0].string_reference,
10385 &geometry_info);
10386 if ((flags & SigmaValue) == 0)
10387 geometry_info.sigma=1.0;
10388 if ((flags & XiValue) == 0)
10389 geometry_info.xi=1.0;
10390 }
10391 if (attribute_flag[1] != 0)
10392 geometry_info.rho=argument_list[1].real_reference;
10393 if (attribute_flag[2] != 0)
10394 geometry_info.sigma=argument_list[2].real_reference;
10395 if (attribute_flag[3] != 0)
10396 geometry_info.xi=argument_list[3].real_reference;
10397 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10398 geometry_info.xi,exception);
10399 break;
10400 }
10401 case 104: /* UniqueColors */
10402 {
10403 image=UniqueImageColors(image,exception);
10404 break;
10405 }
10406 case 105: /* AdaptiveResize */
10407 {
10408 if (attribute_flag[0] != 0)
10409 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10410 &geometry,exception);
10411 if (attribute_flag[1] != 0)
10412 geometry.width=argument_list[1].integer_reference;
10413 if (attribute_flag[2] != 0)
10414 geometry.height=argument_list[2].integer_reference;
10415 if (attribute_flag[3] != 0)
Cristy8645e042016-02-03 16:35:29 -050010416 image->filter=(FilterType) argument_list[4].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010417 if (attribute_flag[4] != 0)
10418 SetImageArtifact(image,"filter:support",
10419 argument_list[4].string_reference);
10420 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10421 exception);
10422 break;
10423 }
10424 case 106: /* ClipMask */
10425 {
10426 Image
10427 *mask_image;
10428
10429 if (attribute_flag[0] == 0)
10430 {
10431 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10432 PackageName);
10433 goto PerlException;
10434 }
10435 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10436 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010437 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010438 mask_image=DestroyImage(mask_image);
10439 break;
10440 }
10441 case 107: /* LinearStretch */
10442 {
10443 double
10444 black_point,
10445 white_point;
10446
10447 black_point=0.0;
10448 white_point=(double) image->columns*image->rows;
10449 if (attribute_flag[0] != 0)
10450 {
10451 flags=ParseGeometry(argument_list[0].string_reference,
10452 &geometry_info);
10453 if ((flags & SigmaValue) != 0)
10454 white_point=geometry_info.sigma;
10455 if ((flags & PercentValue) != 0)
10456 {
10457 black_point*=(double) image->columns*image->rows/100.0;
10458 white_point*=(double) image->columns*image->rows/100.0;
10459 }
10460 if ((flags & SigmaValue) == 0)
10461 white_point=(double) image->columns*image->rows-black_point;
10462 }
10463 if (attribute_flag[1] != 0)
10464 black_point=argument_list[1].real_reference;
10465 if (attribute_flag[2] != 0)
10466 white_point=argument_list[2].real_reference;
10467 (void) LinearStretchImage(image,black_point,white_point,exception);
10468 break;
10469 }
10470 case 108: /* ColorMatrix */
10471 {
10472 AV
10473 *av;
10474
10475 double
10476 *color_matrix;
10477
10478 KernelInfo
10479 *kernel_info;
10480
10481 size_t
10482 order;
10483
10484 if (attribute_flag[0] == 0)
10485 break;
10486 av=(AV *) argument_list[0].array_reference;
10487 order=(size_t) sqrt(av_len(av)+1);
10488 color_matrix=(double *) AcquireQuantumMemory(order,order*
10489 sizeof(*color_matrix));
10490 if (color_matrix == (double *) NULL)
10491 {
10492 ThrowPerlException(exception,ResourceLimitFatalError,
10493 "MemoryAllocationFailed",PackageName);
10494 goto PerlException;
10495 }
10496 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10497 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10498 for ( ; j < (ssize_t) (order*order); j++)
10499 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010500 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010501 if (kernel_info == (KernelInfo *) NULL)
10502 break;
10503 kernel_info->width=order;
10504 kernel_info->height=order;
10505 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10506 order*sizeof(*kernel_info->values));
10507 if (kernel_info->values != (MagickRealType *) NULL)
10508 {
10509 for (i=0; i < (ssize_t) (order*order); i++)
10510 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10511 image=ColorMatrixImage(image,kernel_info,exception);
10512 }
10513 kernel_info=DestroyKernelInfo(kernel_info);
10514 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10515 break;
10516 }
10517 case 109: /* Mask */
10518 {
10519 Image
10520 *mask_image;
10521
10522 if (attribute_flag[0] == 0)
10523 {
10524 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10525 PackageName);
10526 goto PerlException;
10527 }
10528 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10529 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010530 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010531 mask_image=DestroyImage(mask_image);
10532 break;
10533 }
10534 case 110: /* Polaroid */
10535 {
10536 char
10537 *caption;
10538
10539 DrawInfo
10540 *draw_info;
10541
10542 double
10543 angle;
10544
10545 PixelInterpolateMethod
10546 method;
10547
10548 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10549 (DrawInfo *) NULL);
10550 caption=(char *) NULL;
10551 if (attribute_flag[0] != 0)
10552 caption=InterpretImageProperties(info ? info->image_info :
10553 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10554 exception);
10555 angle=0.0;
10556 if (attribute_flag[1] != 0)
10557 angle=argument_list[1].real_reference;
10558 if (attribute_flag[2] != 0)
10559 (void) CloneString(&draw_info->font,
10560 argument_list[2].string_reference);
10561 if (attribute_flag[3] != 0)
10562 (void) QueryColorCompliance(argument_list[3].string_reference,
10563 AllCompliance,&draw_info->stroke,exception);
10564 if (attribute_flag[4] != 0)
10565 (void) QueryColorCompliance(argument_list[4].string_reference,
10566 AllCompliance,&draw_info->fill,exception);
10567 if (attribute_flag[5] != 0)
10568 draw_info->stroke_width=argument_list[5].real_reference;
10569 if (attribute_flag[6] != 0)
10570 draw_info->pointsize=argument_list[6].real_reference;
10571 if (attribute_flag[7] != 0)
10572 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10573 if (attribute_flag[8] != 0)
10574 (void) QueryColorCompliance(argument_list[8].string_reference,
10575 AllCompliance,&image->background_color,exception);
10576 method=UndefinedInterpolatePixel;
10577 if (attribute_flag[9] != 0)
10578 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10579 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10580 draw_info=DestroyDrawInfo(draw_info);
10581 if (caption != (char *) NULL)
10582 caption=DestroyString(caption);
10583 break;
10584 }
10585 case 111: /* FloodfillPaint */
10586 {
10587 DrawInfo
10588 *draw_info;
10589
10590 MagickBooleanType
10591 invert;
10592
10593 PixelInfo
10594 target;
10595
10596 draw_info=CloneDrawInfo(info ? info->image_info :
10597 (ImageInfo *) NULL,(DrawInfo *) NULL);
10598 if (attribute_flag[0] != 0)
10599 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10600 &geometry,exception);
10601 if (attribute_flag[1] != 0)
10602 geometry.x=argument_list[1].integer_reference;
10603 if (attribute_flag[2] != 0)
10604 geometry.y=argument_list[2].integer_reference;
10605 if (attribute_flag[3] != 0)
10606 (void) QueryColorCompliance(argument_list[3].string_reference,
10607 AllCompliance,&draw_info->fill,exception);
10608 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10609 geometry.x,geometry.y,&target,exception);
10610 if (attribute_flag[4] != 0)
10611 QueryColorCompliance(argument_list[4].string_reference,
10612 AllCompliance,&target,exception);
10613 if (attribute_flag[5] != 0)
10614 image->fuzz=StringToDoubleInterval(
10615 argument_list[5].string_reference,(double) QuantumRange+1.0);
10616 if (attribute_flag[6] != 0)
10617 channel=(ChannelType) argument_list[6].integer_reference;
10618 invert=MagickFalse;
10619 if (attribute_flag[7] != 0)
10620 invert=(MagickBooleanType) argument_list[7].integer_reference;
10621 channel_mask=SetImageChannelMask(image,channel);
10622 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10623 geometry.y,invert,exception);
10624 (void) SetImageChannelMask(image,channel_mask);
10625 draw_info=DestroyDrawInfo(draw_info);
10626 break;
10627 }
10628 case 112: /* Distort */
10629 {
10630 AV
10631 *av;
10632
10633 double
10634 *coordinates;
10635
Cristy8645e042016-02-03 16:35:29 -050010636 DistortMethod
cristy4a3ce0a2013-08-03 20:06:59 +000010637 method;
10638
10639 size_t
10640 number_coordinates;
10641
10642 VirtualPixelMethod
10643 virtual_pixel;
10644
10645 if (attribute_flag[0] == 0)
10646 break;
10647 method=UndefinedDistortion;
10648 if (attribute_flag[1] != 0)
Cristy8645e042016-02-03 16:35:29 -050010649 method=(DistortMethod) argument_list[1].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010650 av=(AV *) argument_list[0].array_reference;
10651 number_coordinates=(size_t) av_len(av)+1;
10652 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10653 sizeof(*coordinates));
10654 if (coordinates == (double *) NULL)
10655 {
10656 ThrowPerlException(exception,ResourceLimitFatalError,
10657 "MemoryAllocationFailed",PackageName);
10658 goto PerlException;
10659 }
10660 for (j=0; j < (ssize_t) number_coordinates; j++)
10661 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10662 virtual_pixel=UndefinedVirtualPixelMethod;
10663 if (attribute_flag[2] != 0)
10664 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10665 argument_list[2].integer_reference,exception);
10666 image=DistortImage(image,method,number_coordinates,coordinates,
10667 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10668 exception);
10669 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10670 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10671 exception);
10672 coordinates=(double *) RelinquishMagickMemory(coordinates);
10673 break;
10674 }
10675 case 113: /* Clut */
10676 {
10677 PixelInterpolateMethod
10678 method;
10679
10680 if (attribute_flag[0] == 0)
10681 {
10682 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10683 PackageName);
10684 goto PerlException;
10685 }
10686 method=UndefinedInterpolatePixel;
10687 if (attribute_flag[1] != 0)
10688 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10689 if (attribute_flag[2] != 0)
10690 channel=(ChannelType) argument_list[2].integer_reference;
10691 channel_mask=SetImageChannelMask(image,channel);
10692 (void) ClutImage(image,argument_list[0].image_reference,method,
10693 exception);
10694 (void) SetImageChannelMask(image,channel_mask);
10695 break;
10696 }
10697 case 114: /* LiquidRescale */
10698 {
10699 if (attribute_flag[0] != 0)
10700 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10701 &geometry,exception);
10702 if (attribute_flag[1] != 0)
10703 geometry.width=argument_list[1].integer_reference;
10704 if (attribute_flag[2] != 0)
10705 geometry.height=argument_list[2].integer_reference;
10706 if (attribute_flag[3] == 0)
10707 argument_list[3].real_reference=1.0;
10708 if (attribute_flag[4] == 0)
10709 argument_list[4].real_reference=0.0;
10710 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10711 argument_list[3].real_reference,argument_list[4].real_reference,
10712 exception);
10713 break;
10714 }
10715 case 115: /* EncipherImage */
10716 {
10717 (void) EncipherImage(image,argument_list[0].string_reference,
10718 exception);
10719 break;
10720 }
10721 case 116: /* DecipherImage */
10722 {
10723 (void) DecipherImage(image,argument_list[0].string_reference,
10724 exception);
10725 break;
10726 }
10727 case 117: /* Deskew */
10728 {
10729 geometry_info.rho=QuantumRange/2.0;
10730 if (attribute_flag[0] != 0)
10731 flags=ParseGeometry(argument_list[0].string_reference,
10732 &geometry_info);
10733 if (attribute_flag[1] != 0)
10734 geometry_info.rho=StringToDoubleInterval(
10735 argument_list[1].string_reference,(double) QuantumRange+1.0);
10736 image=DeskewImage(image,geometry_info.rho,exception);
10737 break;
10738 }
10739 case 118: /* Remap */
10740 {
10741 QuantizeInfo
10742 *quantize_info;
10743
10744 if (attribute_flag[0] == 0)
10745 {
10746 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10747 PackageName);
10748 goto PerlException;
10749 }
10750 quantize_info=AcquireQuantizeInfo(info->image_info);
10751 if (attribute_flag[1] != 0)
10752 quantize_info->dither_method=(DitherMethod)
10753 argument_list[1].integer_reference;
10754 (void) RemapImages(quantize_info,image,
10755 argument_list[0].image_reference,exception);
10756 quantize_info=DestroyQuantizeInfo(quantize_info);
10757 break;
10758 }
10759 case 119: /* SparseColor */
10760 {
10761 AV
10762 *av;
10763
10764 double
10765 *coordinates;
10766
10767 SparseColorMethod
10768 method;
10769
10770 size_t
10771 number_coordinates;
10772
10773 VirtualPixelMethod
10774 virtual_pixel;
10775
10776 if (attribute_flag[0] == 0)
10777 break;
10778 method=UndefinedColorInterpolate;
10779 if (attribute_flag[1] != 0)
10780 method=(SparseColorMethod) argument_list[1].integer_reference;
10781 av=(AV *) argument_list[0].array_reference;
10782 number_coordinates=(size_t) av_len(av)+1;
10783 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10784 sizeof(*coordinates));
10785 if (coordinates == (double *) NULL)
10786 {
10787 ThrowPerlException(exception,ResourceLimitFatalError,
10788 "MemoryAllocationFailed",PackageName);
10789 goto PerlException;
10790 }
10791 for (j=0; j < (ssize_t) number_coordinates; j++)
10792 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10793 virtual_pixel=UndefinedVirtualPixelMethod;
10794 if (attribute_flag[2] != 0)
10795 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10796 argument_list[2].integer_reference,exception);
10797 if (attribute_flag[3] != 0)
10798 channel=(ChannelType) argument_list[3].integer_reference;
10799 channel_mask=SetImageChannelMask(image,channel);
10800 image=SparseColorImage(image,method,number_coordinates,coordinates,
10801 exception);
10802 if (image != (Image *) NULL)
10803 (void) SetImageChannelMask(image,channel_mask);
10804 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10805 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10806 exception);
10807 coordinates=(double *) RelinquishMagickMemory(coordinates);
10808 break;
10809 }
10810 case 120: /* Function */
10811 {
10812 AV
10813 *av;
10814
10815 double
10816 *parameters;
10817
10818 MagickFunction
10819 function;
10820
10821 size_t
10822 number_parameters;
10823
10824 VirtualPixelMethod
10825 virtual_pixel;
10826
10827 if (attribute_flag[0] == 0)
10828 break;
10829 function=UndefinedFunction;
10830 if (attribute_flag[1] != 0)
10831 function=(MagickFunction) argument_list[1].integer_reference;
10832 av=(AV *) argument_list[0].array_reference;
10833 number_parameters=(size_t) av_len(av)+1;
10834 parameters=(double *) AcquireQuantumMemory(number_parameters,
10835 sizeof(*parameters));
10836 if (parameters == (double *) NULL)
10837 {
10838 ThrowPerlException(exception,ResourceLimitFatalError,
10839 "MemoryAllocationFailed",PackageName);
10840 goto PerlException;
10841 }
10842 for (j=0; j < (ssize_t) number_parameters; j++)
10843 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10844 virtual_pixel=UndefinedVirtualPixelMethod;
10845 if (attribute_flag[2] != 0)
10846 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10847 argument_list[2].integer_reference,exception);
10848 (void) FunctionImage(image,function,number_parameters,parameters,
10849 exception);
10850 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10851 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10852 exception);
10853 parameters=(double *) RelinquishMagickMemory(parameters);
10854 break;
10855 }
10856 case 121: /* SelectiveBlur */
10857 {
10858 if (attribute_flag[0] != 0)
10859 {
10860 flags=ParseGeometry(argument_list[0].string_reference,
10861 &geometry_info);
10862 if ((flags & SigmaValue) == 0)
10863 geometry_info.sigma=1.0;
10864 if ((flags & PercentValue) != 0)
10865 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10866 }
10867 if (attribute_flag[1] != 0)
10868 geometry_info.rho=argument_list[1].real_reference;
10869 if (attribute_flag[2] != 0)
10870 geometry_info.sigma=argument_list[2].real_reference;
10871 if (attribute_flag[3] != 0)
10872 geometry_info.xi=argument_list[3].integer_reference;;
10873 if (attribute_flag[5] != 0)
10874 channel=(ChannelType) argument_list[5].integer_reference;
10875 channel_mask=SetImageChannelMask(image,channel);
10876 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10877 geometry_info.xi,exception);
10878 if (image != (Image *) NULL)
10879 (void) SetImageChannelMask(image,channel_mask);
10880 break;
10881 }
10882 case 122: /* HaldClut */
10883 {
10884 if (attribute_flag[0] == 0)
10885 {
10886 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10887 PackageName);
10888 goto PerlException;
10889 }
10890 if (attribute_flag[1] != 0)
10891 channel=(ChannelType) argument_list[1].integer_reference;
10892 channel_mask=SetImageChannelMask(image,channel);
10893 (void) HaldClutImage(image,argument_list[0].image_reference,
10894 exception);
10895 (void) SetImageChannelMask(image,channel_mask);
10896 break;
10897 }
10898 case 123: /* BlueShift */
10899 {
10900 if (attribute_flag[0] != 0)
10901 (void) ParseGeometry(argument_list[0].string_reference,
10902 &geometry_info);
10903 image=BlueShiftImage(image,geometry_info.rho,exception);
10904 break;
10905 }
10906 case 124: /* ForwardFourierTransformImage */
10907 {
10908 image=ForwardFourierTransformImage(image,
10909 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10910 exception);
10911 break;
10912 }
10913 case 125: /* InverseFourierTransformImage */
10914 {
10915 image=InverseFourierTransformImage(image,image->next,
10916 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10917 exception);
10918 break;
10919 }
10920 case 126: /* ColorDecisionList */
10921 {
10922 if (attribute_flag[0] == 0)
10923 argument_list[0].string_reference=(char *) NULL;
10924 (void) ColorDecisionListImage(image,
10925 argument_list[0].string_reference,exception);
10926 break;
10927 }
10928 case 127: /* AutoGamma */
10929 {
10930 if (attribute_flag[0] != 0)
10931 channel=(ChannelType) argument_list[0].integer_reference;
10932 channel_mask=SetImageChannelMask(image,channel);
10933 (void) AutoGammaImage(image,exception);
10934 (void) SetImageChannelMask(image,channel_mask);
10935 break;
10936 }
10937 case 128: /* AutoLevel */
10938 {
10939 if (attribute_flag[0] != 0)
10940 channel=(ChannelType) argument_list[0].integer_reference;
10941 channel_mask=SetImageChannelMask(image,channel);
10942 (void) AutoLevelImage(image,exception);
10943 (void) SetImageChannelMask(image,channel_mask);
10944 break;
10945 }
10946 case 129: /* LevelColors */
10947 {
10948 PixelInfo
10949 black_point,
10950 white_point;
10951
10952 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10953 exception);
10954 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10955 exception);
10956 if (attribute_flag[1] != 0)
10957 (void) QueryColorCompliance(
10958 argument_list[1].string_reference,AllCompliance,&black_point,
10959 exception);
10960 if (attribute_flag[2] != 0)
10961 (void) QueryColorCompliance(
10962 argument_list[2].string_reference,AllCompliance,&white_point,
10963 exception);
10964 if (attribute_flag[3] != 0)
10965 channel=(ChannelType) argument_list[3].integer_reference;
10966 channel_mask=SetImageChannelMask(image,channel);
10967 (void) LevelImageColors(image,&black_point,&white_point,
10968 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10969 exception);
10970 (void) SetImageChannelMask(image,channel_mask);
10971 break;
10972 }
10973 case 130: /* Clamp */
10974 {
10975 if (attribute_flag[0] != 0)
10976 channel=(ChannelType) argument_list[0].integer_reference;
10977 channel_mask=SetImageChannelMask(image,channel);
10978 (void) ClampImage(image,exception);
10979 (void) SetImageChannelMask(image,channel_mask);
10980 break;
10981 }
10982 case 131: /* BrightnessContrast */
10983 {
10984 double
10985 brightness,
10986 contrast;
10987
10988 brightness=0.0;
10989 contrast=0.0;
10990 if (attribute_flag[0] != 0)
10991 {
10992 flags=ParseGeometry(argument_list[0].string_reference,
10993 &geometry_info);
10994 brightness=geometry_info.rho;
10995 if ((flags & SigmaValue) == 0)
10996 contrast=geometry_info.sigma;
10997 }
10998 if (attribute_flag[1] != 0)
10999 brightness=argument_list[1].real_reference;
11000 if (attribute_flag[2] != 0)
11001 contrast=argument_list[2].real_reference;
11002 if (attribute_flag[4] != 0)
11003 channel=(ChannelType) argument_list[4].integer_reference;
11004 channel_mask=SetImageChannelMask(image,channel);
11005 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11006 (void) SetImageChannelMask(image,channel_mask);
11007 break;
11008 }
11009 case 132: /* Morphology */
11010 {
11011 KernelInfo
11012 *kernel;
11013
11014 MorphologyMethod
11015 method;
11016
11017 ssize_t
11018 iterations;
11019
11020 if (attribute_flag[0] == 0)
11021 break;
cristy2c57b742014-10-31 00:40:34 +000011022 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011023 if (kernel == (KernelInfo *) NULL)
11024 break;
11025 if (attribute_flag[1] != 0)
11026 channel=(ChannelType) argument_list[1].integer_reference;
11027 method=UndefinedMorphology;
11028 if (attribute_flag[2] != 0)
11029 method=argument_list[2].integer_reference;
11030 iterations=1;
11031 if (attribute_flag[3] != 0)
11032 iterations=argument_list[3].integer_reference;
11033 channel_mask=SetImageChannelMask(image,channel);
11034 image=MorphologyImage(image,method,iterations,kernel,exception);
11035 if (image != (Image *) NULL)
11036 (void) SetImageChannelMask(image,channel_mask);
11037 kernel=DestroyKernelInfo(kernel);
11038 break;
11039 }
11040 case 133: /* Mode */
11041 {
11042 if (attribute_flag[0] != 0)
11043 {
11044 flags=ParseGeometry(argument_list[0].string_reference,
11045 &geometry_info);
11046 if ((flags & SigmaValue) == 0)
11047 geometry_info.sigma=1.0;
11048 }
11049 if (attribute_flag[1] != 0)
11050 geometry_info.rho=argument_list[1].real_reference;
11051 if (attribute_flag[2] != 0)
11052 geometry_info.sigma=argument_list[2].real_reference;
11053 if (attribute_flag[3] != 0)
11054 channel=(ChannelType) argument_list[3].integer_reference;
11055 channel_mask=SetImageChannelMask(image,channel);
11056 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11057 (size_t) geometry_info.sigma,exception);
11058 if (image != (Image *) NULL)
11059 (void) SetImageChannelMask(image,channel_mask);
11060 break;
11061 }
11062 case 134: /* Statistic */
11063 {
11064 StatisticType
11065 statistic;
11066
11067 statistic=UndefinedStatistic;
11068 if (attribute_flag[0] != 0)
11069 {
11070 flags=ParseGeometry(argument_list[0].string_reference,
11071 &geometry_info);
11072 if ((flags & SigmaValue) == 0)
11073 geometry_info.sigma=1.0;
11074 }
11075 if (attribute_flag[1] != 0)
11076 geometry_info.rho=argument_list[1].real_reference;
11077 if (attribute_flag[2] != 0)
11078 geometry_info.sigma=argument_list[2].real_reference;
11079 if (attribute_flag[3] != 0)
11080 channel=(ChannelType) argument_list[3].integer_reference;
11081 if (attribute_flag[4] != 0)
11082 statistic=(StatisticType) argument_list[4].integer_reference;
11083 channel_mask=SetImageChannelMask(image,channel);
11084 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11085 (size_t) geometry_info.sigma,exception);
11086 if (image != (Image *) NULL)
11087 (void) SetImageChannelMask(image,channel_mask);
11088 break;
11089 }
11090 case 135: /* Perceptible */
11091 {
11092 double
11093 epsilon;
11094
11095 epsilon=MagickEpsilon;
11096 if (attribute_flag[0] != 0)
11097 epsilon=argument_list[0].real_reference;
11098 if (attribute_flag[1] != 0)
11099 channel=(ChannelType) argument_list[1].integer_reference;
11100 channel_mask=SetImageChannelMask(image,channel);
11101 (void) PerceptibleImage(image,epsilon,exception);
11102 (void) SetImageChannelMask(image,channel_mask);
11103 break;
11104 }
11105 case 136: /* Poly */
11106 {
11107 AV
11108 *av;
11109
11110 double
11111 *terms;
11112
11113 size_t
11114 number_terms;
11115
11116 if (attribute_flag[0] == 0)
11117 break;
11118 if (attribute_flag[1] != 0)
11119 channel=(ChannelType) argument_list[1].integer_reference;
11120 av=(AV *) argument_list[0].array_reference;
11121 number_terms=(size_t) av_len(av);
11122 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11123 if (terms == (double *) NULL)
11124 {
11125 ThrowPerlException(exception,ResourceLimitFatalError,
11126 "MemoryAllocationFailed",PackageName);
11127 goto PerlException;
11128 }
11129 for (j=0; j < av_len(av); j++)
11130 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11131 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11132 terms=(double *) RelinquishMagickMemory(terms);
11133 break;
11134 }
11135 case 137: /* Grayscale */
11136 {
11137 PixelIntensityMethod
11138 method;
11139
11140 method=UndefinedPixelIntensityMethod;
11141 if (attribute_flag[0] != 0)
11142 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11143 (void) GrayscaleImage(image,method,exception);
11144 break;
11145 }
cristy4ceadb82014-03-29 15:30:43 +000011146 case 138: /* Canny */
11147 {
11148 if (attribute_flag[0] != 0)
11149 {
11150 flags=ParseGeometry(argument_list[0].string_reference,
11151 &geometry_info);
11152 if ((flags & SigmaValue) == 0)
11153 geometry_info.sigma=1.0;
11154 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011155 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011156 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011157 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011158 if ((flags & PercentValue) != 0)
11159 {
11160 geometry_info.xi/=100.0;
11161 geometry_info.psi/=100.0;
11162 }
cristy4ceadb82014-03-29 15:30:43 +000011163 }
11164 if (attribute_flag[1] != 0)
11165 geometry_info.rho=argument_list[1].real_reference;
11166 if (attribute_flag[2] != 0)
11167 geometry_info.sigma=argument_list[2].real_reference;
11168 if (attribute_flag[3] != 0)
11169 geometry_info.xi=argument_list[3].real_reference;
11170 if (attribute_flag[4] != 0)
11171 geometry_info.psi=argument_list[4].real_reference;
11172 if (attribute_flag[5] != 0)
11173 channel=(ChannelType) argument_list[5].integer_reference;
11174 channel_mask=SetImageChannelMask(image,channel);
11175 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11176 geometry_info.xi,geometry_info.psi,exception);
11177 if (image != (Image *) NULL)
11178 (void) SetImageChannelMask(image,channel_mask);
11179 break;
11180 }
cristy2fc10e52014-04-26 14:13:53 +000011181 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011182 {
11183 if (attribute_flag[0] != 0)
11184 {
11185 flags=ParseGeometry(argument_list[0].string_reference,
11186 &geometry_info);
11187 if ((flags & SigmaValue) == 0)
11188 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011189 if ((flags & XiValue) == 0)
11190 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011191 }
11192 if (attribute_flag[1] != 0)
11193 geometry_info.rho=(double) argument_list[1].integer_reference;
11194 if (attribute_flag[2] != 0)
11195 geometry_info.sigma=(double) argument_list[2].integer_reference;
11196 if (attribute_flag[3] != 0)
11197 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011198 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11199 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11200 break;
11201 }
11202 case 140: /* MeanShift */
11203 {
11204 if (attribute_flag[0] != 0)
11205 {
11206 flags=ParseGeometry(argument_list[0].string_reference,
11207 &geometry_info);
11208 if ((flags & SigmaValue) == 0)
11209 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011210 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011211 geometry_info.xi=0.10*QuantumRange;
11212 if ((flags & PercentValue) != 0)
11213 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011214 }
11215 if (attribute_flag[1] != 0)
11216 geometry_info.rho=(double) argument_list[1].integer_reference;
11217 if (attribute_flag[2] != 0)
11218 geometry_info.sigma=(double) argument_list[2].integer_reference;
11219 if (attribute_flag[3] != 0)
11220 geometry_info.xi=(double) argument_list[3].integer_reference;
11221 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011222 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011223 break;
11224 }
cristy3b207f82014-09-27 14:21:20 +000011225 case 141: /* Kuwahara */
11226 {
11227 if (attribute_flag[0] != 0)
11228 {
11229 flags=ParseGeometry(argument_list[0].string_reference,
11230 &geometry_info);
11231 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011232 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011233 }
11234 if (attribute_flag[1] != 0)
11235 geometry_info.rho=argument_list[1].real_reference;
11236 if (attribute_flag[2] != 0)
11237 geometry_info.sigma=argument_list[2].real_reference;
11238 if (attribute_flag[3] != 0)
11239 channel=(ChannelType) argument_list[3].integer_reference;
11240 channel_mask=SetImageChannelMask(image,channel);
11241 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11242 exception);
11243 if (image != (Image *) NULL)
11244 (void) SetImageChannelMask(image,channel_mask);
11245 break;
11246 }
cristy6e0b3bc2014-10-19 17:51:42 +000011247 case 142: /* ConnectedComponent */
11248 {
11249 size_t
11250 connectivity;
11251
11252 connectivity=4;
11253 if (attribute_flag[0] != 0)
11254 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011255 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011256 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011257 break;
11258 }
cristy0b94b392015-06-22 18:56:37 +000011259 case 143: /* Copy */
11260 {
11261 Image
11262 *source_image;
11263
11264 OffsetInfo
11265 offset;
11266
cristy2ffdb092015-06-25 14:31:20 +000011267 RectangleInfo
11268 offset_geometry;
11269
cristyf3a724a2015-06-25 13:02:53 +000011270 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011271 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011272 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011273 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011274 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011275 flags=ParseGravityGeometry(source_image,
11276 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011277 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011278 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011279 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011280 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011281 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011282 geometry.x=argument_list[4].integer_reference;
11283 if (attribute_flag[5] != 0)
11284 geometry.y=argument_list[5].integer_reference;
11285 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011286 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011287 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011288 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011289 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11290 &offset_geometry,exception);
11291 offset.x=offset_geometry.x;
11292 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011293 if (attribute_flag[8] != 0)
11294 offset.x=argument_list[8].integer_reference;
11295 if (attribute_flag[9] != 0)
11296 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011297 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11298 exception);
cristy0b94b392015-06-22 18:56:37 +000011299 break;
11300 }
Cristy5488c982016-02-13 14:07:50 -050011301 case 144: /* Color */
11302 {
11303 PixelInfo
11304 color;
11305
Cristyf20e3562016-02-14 09:08:15 -050011306 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011307 if (attribute_flag[0] != 0)
Cristyf20e3562016-02-14 09:08:15 -050011308 (void) QueryColorCompliance(argument_list[0].string_reference,
11309 AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011310 (void) SetImageColor(image,&color,exception);
11311 break;
11312 }
Cristy2d830ed2016-02-21 10:54:16 -050011313 case 145: /* WaveletDenoise */
11314 {
Cristyc1759412016-02-27 12:17:58 -050011315 if (attribute_flag[0] != 0)
Cristyee21f7f2016-02-27 15:56:49 -050011316 {
11317 flags=ParseGeometry(argument_list[0].string_reference,
11318 &geometry_info);
11319 if ((flags & PercentValue) != 0)
Cristy23446632016-02-29 09:36:34 -050011320 {
11321 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11322 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
11323 }
Cristyee21f7f2016-02-27 15:56:49 -050011324 if ((flags & SigmaValue) == 0)
11325 geometry_info.sigma=0.0;
11326 }
Cristyc1759412016-02-27 12:17:58 -050011327 if (attribute_flag[1] != 0)
11328 geometry_info.rho=argument_list[1].real_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011329 if (attribute_flag[2] != 0)
Cristyc1759412016-02-27 12:17:58 -050011330 geometry_info.sigma=argument_list[2].real_reference;
11331 if (attribute_flag[3] != 0)
11332 channel=(ChannelType) argument_list[3].integer_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011333 channel_mask=SetImageChannelMask(image,channel);
Cristyc1759412016-02-27 12:17:58 -050011334 image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11335 exception);
Cristy2d830ed2016-02-21 10:54:16 -050011336 if (image != (Image *) NULL)
11337 (void) SetImageChannelMask(image,channel_mask);
11338 break;
11339 }
Cristy99a57162016-12-05 11:47:57 -050011340 case 146: /* Colorspace */
11341 {
11342 ColorspaceType
11343 colorspace;
11344
11345 colorspace=sRGBColorspace;
11346 if (attribute_flag[0] != 0)
11347 colorspace=(ColorspaceType) argument_list[0].integer_reference;
11348 (void) TransformImageColorspace(image,colorspace,exception);
11349 break;
11350 }
cristy4a3ce0a2013-08-03 20:06:59 +000011351 }
11352 if (next != (Image *) NULL)
11353 (void) CatchImageException(next);
11354 if (region_image != (Image *) NULL)
11355 {
11356 /*
11357 Composite region.
cristy83a28a02013-08-03 20:25:48 +000011358 */
cristy4a3ce0a2013-08-03 20:06:59 +000011359 status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11360 region_info.x,region_info.y,exception);
11361 (void) status;
11362 (void) CatchImageException(region_image);
11363 image=DestroyImage(image);
11364 image=region_image;
11365 }
11366 if (image != (Image *) NULL)
11367 {
11368 number_images++;
11369 if (next && (next != image))
11370 {
11371 image->next=next->next;
11372 if (image->next != (Image *) NULL)
11373 image->next->previous=image;
11374 DeleteImageFromRegistry(*pv,next);
11375 }
11376 sv_setiv(*pv,PTR2IV(image));
11377 next=image;
11378 }
11379 if (*pv)
11380 pv++;
11381 }
11382
11383 PerlException:
11384 if (reference_vector)
11385 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11386 InheritPerlException(exception,perl_exception);
11387 exception=DestroyExceptionInfo(exception);
11388 sv_setiv(perl_exception,(IV) number_images);
11389 SvPOK_on(perl_exception);
11390 ST(0)=sv_2mortal(perl_exception);
11391 XSRETURN(1);
11392 }
11393
11394#
11395###############################################################################
11396# #
11397# #
11398# #
11399# M o n t a g e #
11400# #
11401# #
11402# #
11403###############################################################################
11404#
11405#
11406void
11407Montage(ref,...)
11408 Image::Magick ref=NO_INIT
11409 ALIAS:
11410 MontageImage = 1
11411 montage = 2
11412 montageimage = 3
11413 PPCODE:
11414 {
11415 AV
11416 *av;
11417
11418 char
11419 *attribute;
11420
11421 ExceptionInfo
11422 *exception;
11423
11424 HV
11425 *hv;
11426
11427 Image
11428 *image,
11429 *next;
11430
11431 PixelInfo
11432 transparent_color;
11433
11434 MontageInfo
11435 *montage_info;
11436
11437 register ssize_t
11438 i;
11439
11440 ssize_t
11441 sp;
11442
11443 struct PackageInfo
11444 *info;
11445
11446 SV
11447 *av_reference,
11448 *perl_exception,
11449 *reference,
11450 *rv,
11451 *sv;
11452
11453 PERL_UNUSED_VAR(ref);
11454 PERL_UNUSED_VAR(ix);
11455 exception=AcquireExceptionInfo();
11456 perl_exception=newSVpv("",0);
11457 sv=NULL;
11458 attribute=NULL;
11459 if (sv_isobject(ST(0)) == 0)
11460 {
11461 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11462 PackageName);
11463 goto PerlException;
11464 }
11465 reference=SvRV(ST(0));
11466 hv=SvSTASH(reference);
11467 av=newAV();
11468 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11469 SvREFCNT_dec(av);
11470 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11471 if (image == (Image *) NULL)
11472 {
11473 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11474 PackageName);
11475 goto PerlException;
11476 }
11477 /*
11478 Get options.
11479 */
11480 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11481 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11482 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11483 exception);
11484 for (i=2; i < items; i+=2)
11485 {
11486 attribute=(char *) SvPV(ST(i-1),na);
11487 switch (*attribute)
11488 {
11489 case 'B':
11490 case 'b':
11491 {
11492 if (LocaleCompare(attribute,"background") == 0)
11493 {
11494 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11495 &montage_info->background_color,exception);
11496 for (next=image; next; next=next->next)
11497 next->background_color=montage_info->background_color;
11498 break;
11499 }
11500 if (LocaleCompare(attribute,"border") == 0)
11501 {
11502 montage_info->border_width=SvIV(ST(i));
11503 break;
11504 }
11505 if (LocaleCompare(attribute,"bordercolor") == 0)
11506 {
11507 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11508 &montage_info->border_color,exception);
11509 for (next=image; next; next=next->next)
11510 next->border_color=montage_info->border_color;
11511 break;
11512 }
11513 if (LocaleCompare(attribute,"borderwidth") == 0)
11514 {
11515 montage_info->border_width=SvIV(ST(i));
11516 break;
11517 }
11518 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11519 attribute);
11520 break;
11521 }
11522 case 'C':
11523 case 'c':
11524 {
11525 if (LocaleCompare(attribute,"compose") == 0)
11526 {
11527 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11528 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11529 if (sp < 0)
11530 {
11531 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11532 SvPV(ST(i),na));
11533 break;
11534 }
11535 for (next=image; next; next=next->next)
11536 next->compose=(CompositeOperator) sp;
11537 break;
11538 }
11539 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11540 attribute);
11541 break;
11542 }
11543 case 'F':
11544 case 'f':
11545 {
11546 if (LocaleCompare(attribute,"fill") == 0)
11547 {
11548 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11549 &montage_info->fill,exception);
11550 break;
11551 }
11552 if (LocaleCompare(attribute,"font") == 0)
11553 {
11554 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11555 break;
11556 }
11557 if (LocaleCompare(attribute,"frame") == 0)
11558 {
11559 char
11560 *p;
11561
11562 p=SvPV(ST(i),na);
11563 if (IsGeometry(p) == MagickFalse)
11564 {
11565 ThrowPerlException(exception,OptionError,"MissingGeometry",
11566 p);
11567 break;
11568 }
11569 (void) CloneString(&montage_info->frame,p);
11570 if (*p == '\0')
11571 montage_info->frame=(char *) NULL;
11572 break;
11573 }
11574 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11575 attribute);
11576 break;
11577 }
11578 case 'G':
11579 case 'g':
11580 {
11581 if (LocaleCompare(attribute,"geometry") == 0)
11582 {
11583 char
11584 *p;
11585
11586 p=SvPV(ST(i),na);
11587 if (IsGeometry(p) == MagickFalse)
11588 {
11589 ThrowPerlException(exception,OptionError,"MissingGeometry",
11590 p);
11591 break;
11592 }
11593 (void) CloneString(&montage_info->geometry,p);
11594 if (*p == '\0')
11595 montage_info->geometry=(char *) NULL;
11596 break;
11597 }
11598 if (LocaleCompare(attribute,"gravity") == 0)
11599 {
11600 ssize_t
11601 in;
11602
11603 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11604 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11605 if (in < 0)
11606 {
11607 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11608 SvPV(ST(i),na));
11609 return;
11610 }
11611 montage_info->gravity=(GravityType) in;
11612 for (next=image; next; next=next->next)
11613 next->gravity=(GravityType) in;
11614 break;
11615 }
11616 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11617 attribute);
11618 break;
11619 }
11620 case 'L':
11621 case 'l':
11622 {
11623 if (LocaleCompare(attribute,"label") == 0)
11624 {
11625 for (next=image; next; next=next->next)
Cristyb5b1f5d2017-03-31 16:42:35 -040011626 (void) SetImageOption(next,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +000011627 info ? info->image_info : (ImageInfo *) NULL,next,
Cristyb5b1f5d2017-03-31 16:42:35 -040011628 SvPV(ST(i),na),exception));
cristy4a3ce0a2013-08-03 20:06:59 +000011629 break;
11630 }
11631 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11632 attribute);
11633 break;
11634 }
11635 case 'M':
11636 case 'm':
11637 {
11638 if (LocaleCompare(attribute,"mattecolor") == 0)
11639 {
11640 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
Cristy8645e042016-02-03 16:35:29 -050011641 &montage_info->alpha_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011642 for (next=image; next; next=next->next)
Cristy8645e042016-02-03 16:35:29 -050011643 next->alpha_color=montage_info->alpha_color;
cristy4a3ce0a2013-08-03 20:06:59 +000011644 break;
11645 }
11646 if (LocaleCompare(attribute,"mode") == 0)
11647 {
11648 ssize_t
11649 in;
11650
11651 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11652 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11653 switch (in)
11654 {
11655 default:
11656 {
11657 ThrowPerlException(exception,OptionError,
11658 "UnrecognizedModeType",SvPV(ST(i),na));
11659 break;
11660 }
11661 case FrameMode:
11662 {
11663 (void) CloneString(&montage_info->frame,"15x15+3+3");
11664 montage_info->shadow=MagickTrue;
11665 break;
11666 }
11667 case UnframeMode:
11668 {
11669 montage_info->frame=(char *) NULL;
11670 montage_info->shadow=MagickFalse;
11671 montage_info->border_width=0;
11672 break;
11673 }
11674 case ConcatenateMode:
11675 {
11676 montage_info->frame=(char *) NULL;
11677 montage_info->shadow=MagickFalse;
11678 (void) CloneString(&montage_info->geometry,"+0+0");
11679 montage_info->border_width=0;
11680 }
11681 }
11682 break;
11683 }
11684 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11685 attribute);
11686 break;
11687 }
11688 case 'P':
11689 case 'p':
11690 {
11691 if (LocaleCompare(attribute,"pointsize") == 0)
11692 {
11693 montage_info->pointsize=SvIV(ST(i));
11694 break;
11695 }
11696 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11697 attribute);
11698 break;
11699 }
11700 case 'S':
11701 case 's':
11702 {
11703 if (LocaleCompare(attribute,"shadow") == 0)
11704 {
11705 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11706 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11707 if (sp < 0)
11708 {
11709 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11710 SvPV(ST(i),na));
11711 break;
11712 }
11713 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11714 break;
11715 }
11716 if (LocaleCompare(attribute,"stroke") == 0)
11717 {
11718 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11719 &montage_info->stroke,exception);
11720 break;
11721 }
11722 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11723 attribute);
11724 break;
11725 }
11726 case 'T':
11727 case 't':
11728 {
11729 if (LocaleCompare(attribute,"texture") == 0)
11730 {
11731 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11732 break;
11733 }
11734 if (LocaleCompare(attribute,"tile") == 0)
11735 {
11736 char *p=SvPV(ST(i),na);
11737 if (IsGeometry(p) == MagickFalse)
11738 {
11739 ThrowPerlException(exception,OptionError,"MissingGeometry",
11740 p);
11741 break;
11742 }
11743 (void) CloneString(&montage_info->tile,p);
11744 if (*p == '\0')
11745 montage_info->tile=(char *) NULL;
11746 break;
11747 }
11748 if (LocaleCompare(attribute,"title") == 0)
11749 {
11750 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11751 break;
11752 }
11753 if (LocaleCompare(attribute,"transparent") == 0)
11754 {
11755 PixelInfo
11756 transparent_color;
11757
11758 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11759 &transparent_color,exception);
11760 for (next=image; next; next=next->next)
11761 (void) TransparentPaintImage(next,&transparent_color,
11762 TransparentAlpha,MagickFalse,exception);
11763 break;
11764 }
11765 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11766 attribute);
11767 break;
11768 }
11769 default:
11770 {
11771 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11772 attribute);
11773 break;
11774 }
11775 }
11776 }
11777 image=MontageImageList(info->image_info,montage_info,image,exception);
11778 montage_info=DestroyMontageInfo(montage_info);
11779 if (image == (Image *) NULL)
11780 goto PerlException;
11781 if (transparent_color.alpha != TransparentAlpha)
11782 for (next=image; next; next=next->next)
11783 (void) TransparentPaintImage(next,&transparent_color,
11784 TransparentAlpha,MagickFalse,exception);
11785 for ( ; image; image=image->next)
11786 {
11787 AddImageToRegistry(sv,image);
11788 rv=newRV(sv);
11789 av_push(av,sv_bless(rv,hv));
11790 SvREFCNT_dec(sv);
11791 }
11792 exception=DestroyExceptionInfo(exception);
11793 ST(0)=av_reference;
11794 SvREFCNT_dec(perl_exception);
11795 XSRETURN(1);
11796
11797 PerlException:
11798 InheritPerlException(exception,perl_exception);
11799 exception=DestroyExceptionInfo(exception);
11800 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11801 SvPOK_on(perl_exception);
11802 ST(0)=sv_2mortal(perl_exception);
11803 XSRETURN(1);
11804 }
11805
11806#
11807###############################################################################
11808# #
11809# #
11810# #
11811# M o r p h #
11812# #
11813# #
11814# #
11815###############################################################################
11816#
11817#
11818void
11819Morph(ref,...)
11820 Image::Magick ref=NO_INIT
11821 ALIAS:
11822 MorphImage = 1
11823 morph = 2
11824 morphimage = 3
11825 PPCODE:
11826 {
11827 AV
11828 *av;
11829
11830 char
11831 *attribute;
11832
11833 ExceptionInfo
11834 *exception;
11835
11836 HV
11837 *hv;
11838
11839 Image
11840 *image;
11841
11842 register ssize_t
11843 i;
11844
11845 ssize_t
11846 number_frames;
11847
11848 struct PackageInfo
11849 *info;
11850
11851 SV
11852 *av_reference,
11853 *perl_exception,
11854 *reference,
11855 *rv,
11856 *sv;
11857
11858 PERL_UNUSED_VAR(ref);
11859 PERL_UNUSED_VAR(ix);
11860 exception=AcquireExceptionInfo();
11861 perl_exception=newSVpv("",0);
11862 sv=NULL;
11863 av=NULL;
11864 attribute=NULL;
11865 if (sv_isobject(ST(0)) == 0)
11866 {
11867 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11868 PackageName);
11869 goto PerlException;
11870 }
11871 reference=SvRV(ST(0));
11872 hv=SvSTASH(reference);
11873 av=newAV();
11874 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11875 SvREFCNT_dec(av);
11876 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11877 if (image == (Image *) NULL)
11878 {
11879 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11880 PackageName);
11881 goto PerlException;
11882 }
11883 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11884 /*
11885 Get attribute.
11886 */
11887 number_frames=30;
11888 for (i=2; i < items; i+=2)
11889 {
11890 attribute=(char *) SvPV(ST(i-1),na);
11891 switch (*attribute)
11892 {
11893 case 'F':
11894 case 'f':
11895 {
11896 if (LocaleCompare(attribute,"frames") == 0)
11897 {
11898 number_frames=SvIV(ST(i));
11899 break;
11900 }
11901 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11902 attribute);
11903 break;
11904 }
11905 default:
11906 {
11907 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11908 attribute);
11909 break;
11910 }
11911 }
11912 }
11913 image=MorphImages(image,number_frames,exception);
11914 if (image == (Image *) NULL)
11915 goto PerlException;
11916 for ( ; image; image=image->next)
11917 {
11918 AddImageToRegistry(sv,image);
11919 rv=newRV(sv);
11920 av_push(av,sv_bless(rv,hv));
11921 SvREFCNT_dec(sv);
11922 }
11923 exception=DestroyExceptionInfo(exception);
11924 ST(0)=av_reference;
11925 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11926 XSRETURN(1);
11927
11928 PerlException:
11929 InheritPerlException(exception,perl_exception);
11930 exception=DestroyExceptionInfo(exception);
11931 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11932 SvPOK_on(perl_exception);
11933 ST(0)=sv_2mortal(perl_exception);
11934 XSRETURN(1);
11935 }
11936
11937#
11938###############################################################################
11939# #
11940# #
11941# #
11942# M o s a i c #
11943# #
11944# #
11945# #
11946###############################################################################
11947#
11948#
11949void
11950Mosaic(ref)
11951 Image::Magick ref=NO_INIT
11952 ALIAS:
11953 MosaicImage = 1
11954 mosaic = 2
11955 mosaicimage = 3
11956 PPCODE:
11957 {
11958 AV
11959 *av;
11960
11961 ExceptionInfo
11962 *exception;
11963
11964 HV
11965 *hv;
11966
11967 Image
11968 *image;
11969
11970 struct PackageInfo
11971 *info;
11972
11973 SV
11974 *perl_exception,
11975 *reference,
11976 *rv,
11977 *sv;
11978
11979 PERL_UNUSED_VAR(ref);
11980 PERL_UNUSED_VAR(ix);
11981 exception=AcquireExceptionInfo();
11982 perl_exception=newSVpv("",0);
11983 sv=NULL;
11984 if (sv_isobject(ST(0)) == 0)
11985 {
11986 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11987 PackageName);
11988 goto PerlException;
11989 }
11990 reference=SvRV(ST(0));
11991 hv=SvSTASH(reference);
11992 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11993 if (image == (Image *) NULL)
11994 {
11995 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11996 PackageName);
11997 goto PerlException;
11998 }
11999 image=MergeImageLayers(image,MosaicLayer,exception);
12000 /*
12001 Create blessed Perl array for the returned image.
12002 */
12003 av=newAV();
12004 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12005 SvREFCNT_dec(av);
12006 AddImageToRegistry(sv,image);
12007 rv=newRV(sv);
12008 av_push(av,sv_bless(rv,hv));
12009 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000012010 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000012011 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012012 SetImageInfo(info->image_info,0,exception);
12013 exception=DestroyExceptionInfo(exception);
12014 SvREFCNT_dec(perl_exception);
12015 XSRETURN(1);
12016
12017 PerlException:
12018 InheritPerlException(exception,perl_exception);
12019 exception=DestroyExceptionInfo(exception);
12020 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12021 SvPOK_on(perl_exception); /* return messages in string context */
12022 ST(0)=sv_2mortal(perl_exception);
12023 XSRETURN(1);
12024 }
12025
12026#
12027###############################################################################
12028# #
12029# #
12030# #
12031# P i n g #
12032# #
12033# #
12034# #
12035###############################################################################
12036#
12037#
12038void
12039Ping(ref,...)
12040 Image::Magick ref=NO_INIT
12041 ALIAS:
12042 PingImage = 1
12043 ping = 2
12044 pingimage = 3
12045 PPCODE:
12046 {
12047 AV
12048 *av;
12049
12050 char
12051 **keep,
12052 **list;
12053
12054 ExceptionInfo
12055 *exception;
12056
12057 Image
12058 *image,
12059 *next;
12060
12061 int
12062 n;
12063
12064 MagickBooleanType
12065 status;
12066
12067 register char
12068 **p;
12069
12070 register ssize_t
12071 i;
12072
12073 ssize_t
12074 ac;
12075
12076 STRLEN
12077 *length;
12078
12079 struct PackageInfo
12080 *info,
12081 *package_info;
12082
12083 SV
12084 *perl_exception,
12085 *reference;
12086
12087 size_t
12088 count;
12089
12090 PERL_UNUSED_VAR(ref);
12091 PERL_UNUSED_VAR(ix);
12092 exception=AcquireExceptionInfo();
12093 perl_exception=newSVpv("",0);
12094 package_info=(struct PackageInfo *) NULL;
12095 ac=(items < 2) ? 1 : items-1;
12096 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12097 keep=list;
12098 length=(STRLEN *) NULL;
12099 if (list == (char **) NULL)
12100 {
12101 ThrowPerlException(exception,ResourceLimitError,
12102 "MemoryAllocationFailed",PackageName);
12103 goto PerlException;
12104 }
12105 keep=list;
12106 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12107 if (length == (STRLEN *) NULL)
12108 {
12109 ThrowPerlException(exception,ResourceLimitError,
12110 "MemoryAllocationFailed",PackageName);
12111 goto PerlException;
12112 }
12113 if (sv_isobject(ST(0)) == 0)
12114 {
12115 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12116 PackageName);
12117 goto PerlException;
12118 }
12119 reference=SvRV(ST(0));
12120 if (SvTYPE(reference) != SVt_PVAV)
12121 {
12122 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12123 PackageName);
12124 goto PerlException;
12125 }
12126 av=(AV *) reference;
12127 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12128 exception);
12129 package_info=ClonePackageInfo(info,exception);
12130 n=1;
12131 if (items <= 1)
12132 *list=(char *) (*package_info->image_info->filename ?
12133 package_info->image_info->filename : "XC:black");
12134 else
12135 for (n=0, i=0; i < ac; i++)
12136 {
12137 list[n]=(char *) SvPV(ST(i+1),length[n]);
12138 if ((items >= 3) && strEQcase(list[n],"blob"))
12139 {
12140 void
12141 *blob;
12142
12143 i++;
12144 blob=(void *) (SvPV(ST(i+1),length[n]));
12145 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12146 }
12147 if ((items >= 3) && strEQcase(list[n],"filename"))
12148 continue;
12149 if ((items >= 3) && strEQcase(list[n],"file"))
12150 {
12151 FILE
12152 *file;
12153
12154 PerlIO
12155 *io_info;
12156
12157 i++;
12158 io_info=IoIFP(sv_2io(ST(i+1)));
12159 if (io_info == (PerlIO *) NULL)
12160 {
12161 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12162 PackageName);
12163 continue;
12164 }
12165 file=PerlIO_findFILE(io_info);
12166 if (file == (FILE *) NULL)
12167 {
12168 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12169 PackageName);
12170 continue;
12171 }
12172 SetImageInfoFile(package_info->image_info,file);
12173 }
12174 if ((items >= 3) && strEQcase(list[n],"magick"))
12175 continue;
12176 n++;
12177 }
12178 list[n]=(char *) NULL;
12179 keep=list;
12180 status=ExpandFilenames(&n,&list);
12181 if (status == MagickFalse)
12182 {
12183 ThrowPerlException(exception,ResourceLimitError,
12184 "MemoryAllocationFailed",PackageName);
12185 goto PerlException;
12186 }
12187 count=0;
12188 for (i=0; i < n; i++)
12189 {
12190 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012191 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012192 image=PingImage(package_info->image_info,exception);
12193 if (image == (Image *) NULL)
12194 break;
12195 if ((package_info->image_info->file != (FILE *) NULL) ||
12196 (package_info->image_info->blob != (void *) NULL))
12197 DisassociateImageStream(image);
12198 count+=GetImageListLength(image);
12199 EXTEND(sp,4*count);
12200 for (next=image; next; next=next->next)
12201 {
12202 PUSHs(sv_2mortal(newSViv(next->columns)));
12203 PUSHs(sv_2mortal(newSViv(next->rows)));
12204 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12205 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12206 }
12207 image=DestroyImageList(image);
12208 }
12209 /*
12210 Free resources.
12211 */
12212 for (i=0; i < n; i++)
12213 if (list[i] != (char *) NULL)
12214 for (p=keep; list[i] != *p++; )
12215 if (*p == NULL)
12216 {
12217 list[i]=(char *) RelinquishMagickMemory(list[i]);
12218 break;
12219 }
12220
12221 PerlException:
12222 if (package_info != (struct PackageInfo *) NULL)
12223 DestroyPackageInfo(package_info);
12224 if (list && (list != keep))
12225 list=(char **) RelinquishMagickMemory(list);
12226 if (keep)
12227 keep=(char **) RelinquishMagickMemory(keep);
12228 if (length)
12229 length=(STRLEN *) RelinquishMagickMemory(length);
12230 InheritPerlException(exception,perl_exception);
12231 exception=DestroyExceptionInfo(exception);
12232 SvREFCNT_dec(perl_exception); /* throw away all errors */
12233 }
12234
12235#
12236###############################################################################
12237# #
12238# #
12239# #
12240# P r e v i e w #
12241# #
12242# #
12243# #
12244###############################################################################
12245#
12246#
12247void
12248Preview(ref,...)
12249 Image::Magick ref=NO_INIT
12250 ALIAS:
12251 PreviewImage = 1
12252 preview = 2
12253 previewimage = 3
12254 PPCODE:
12255 {
12256 AV
12257 *av;
12258
12259 ExceptionInfo
12260 *exception;
12261
12262 HV
12263 *hv;
12264
12265 Image
12266 *image,
12267 *preview_image;
12268
12269 PreviewType
12270 preview_type;
12271
12272 struct PackageInfo
12273 *info;
12274
12275 SV
12276 *av_reference,
12277 *perl_exception,
12278 *reference,
12279 *rv,
12280 *sv;
12281
12282 PERL_UNUSED_VAR(ref);
12283 PERL_UNUSED_VAR(ix);
12284 exception=AcquireExceptionInfo();
12285 perl_exception=newSVpv("",0);
12286 sv=NULL;
12287 av=NULL;
12288 if (sv_isobject(ST(0)) == 0)
12289 {
12290 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12291 PackageName);
12292 goto PerlException;
12293 }
12294 reference=SvRV(ST(0));
12295 hv=SvSTASH(reference);
12296 av=newAV();
12297 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12298 SvREFCNT_dec(av);
12299 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12300 if (image == (Image *) NULL)
12301 {
12302 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12303 PackageName);
12304 goto PerlException;
12305 }
12306 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12307 preview_type=GammaPreview;
12308 if (items > 1)
12309 preview_type=(PreviewType)
12310 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12311 for ( ; image; image=image->next)
12312 {
12313 preview_image=PreviewImage(image,preview_type,exception);
12314 if (preview_image == (Image *) NULL)
12315 goto PerlException;
12316 AddImageToRegistry(sv,preview_image);
12317 rv=newRV(sv);
12318 av_push(av,sv_bless(rv,hv));
12319 SvREFCNT_dec(sv);
12320 }
12321 exception=DestroyExceptionInfo(exception);
12322 ST(0)=av_reference;
12323 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12324 XSRETURN(1);
12325
12326 PerlException:
12327 InheritPerlException(exception,perl_exception);
12328 exception=DestroyExceptionInfo(exception);
12329 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12330 SvPOK_on(perl_exception);
12331 ST(0)=sv_2mortal(perl_exception);
12332 XSRETURN(1);
12333 }
12334
12335#
12336###############################################################################
12337# #
12338# #
12339# #
12340# Q u e r y C o l o r #
12341# #
12342# #
12343# #
12344###############################################################################
12345#
12346#
12347void
12348QueryColor(ref,...)
12349 Image::Magick ref=NO_INIT
12350 ALIAS:
12351 querycolor = 1
12352 PPCODE:
12353 {
12354 char
12355 *name;
12356
12357 ExceptionInfo
12358 *exception;
12359
12360 PixelInfo
12361 color;
12362
12363 register ssize_t
12364 i;
12365
12366 SV
12367 *perl_exception;
12368
12369 PERL_UNUSED_VAR(ref);
12370 PERL_UNUSED_VAR(ix);
12371 exception=AcquireExceptionInfo();
12372 perl_exception=newSVpv("",0);
12373 if (items == 1)
12374 {
12375 const ColorInfo
12376 **colorlist;
12377
12378 size_t
12379 colors;
12380
12381 colorlist=GetColorInfoList("*",&colors,exception);
12382 EXTEND(sp,colors);
12383 for (i=0; i < (ssize_t) colors; i++)
12384 {
12385 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12386 }
12387 colorlist=(const ColorInfo **)
12388 RelinquishMagickMemory((ColorInfo **) colorlist);
12389 goto PerlException;
12390 }
12391 EXTEND(sp,5*items);
12392 for (i=1; i < items; i++)
12393 {
12394 name=(char *) SvPV(ST(i),na);
12395 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12396 {
12397 PUSHs(&sv_undef);
12398 continue;
12399 }
12400 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12401 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12402 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12403 if (color.colorspace == CMYKColorspace)
12404 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012405 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012406 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12407 }
12408
12409 PerlException:
12410 InheritPerlException(exception,perl_exception);
12411 exception=DestroyExceptionInfo(exception);
12412 SvREFCNT_dec(perl_exception);
12413 }
12414
12415#
12416###############################################################################
12417# #
12418# #
12419# #
12420# Q u e r y C o l o r N a m e #
12421# #
12422# #
12423# #
12424###############################################################################
12425#
12426#
12427void
12428QueryColorname(ref,...)
12429 Image::Magick ref=NO_INIT
12430 ALIAS:
12431 querycolorname = 1
12432 PPCODE:
12433 {
12434 AV
12435 *av;
12436
12437 char
cristy151b66d2015-04-15 10:50:31 +000012438 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012439
12440 ExceptionInfo
12441 *exception;
12442
12443 Image
12444 *image;
12445
12446 PixelInfo
12447 target_color;
12448
12449 register ssize_t
12450 i;
12451
12452 struct PackageInfo
12453 *info;
12454
12455 SV
12456 *perl_exception,
12457 *reference; /* reference is the SV* of ref=SvIV(reference) */
12458
12459 PERL_UNUSED_VAR(ref);
12460 PERL_UNUSED_VAR(ix);
12461 exception=AcquireExceptionInfo();
12462 perl_exception=newSVpv("",0);
12463 reference=SvRV(ST(0));
12464 av=(AV *) reference;
12465 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12466 exception);
12467 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12468 if (image == (Image *) NULL)
12469 {
12470 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12471 PackageName);
12472 goto PerlException;
12473 }
12474 EXTEND(sp,items);
12475 for (i=1; i < items; i++)
12476 {
12477 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12478 exception);
12479 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12480 exception);
12481 PUSHs(sv_2mortal(newSVpv(message,0)));
12482 }
12483
12484 PerlException:
12485 InheritPerlException(exception,perl_exception);
12486 exception=DestroyExceptionInfo(exception);
12487 SvREFCNT_dec(perl_exception);
12488 }
12489
12490#
12491###############################################################################
12492# #
12493# #
12494# #
12495# Q u e r y F o n t #
12496# #
12497# #
12498# #
12499###############################################################################
12500#
12501#
12502void
12503QueryFont(ref,...)
12504 Image::Magick ref=NO_INIT
12505 ALIAS:
12506 queryfont = 1
12507 PPCODE:
12508 {
12509 char
12510 *name,
cristy151b66d2015-04-15 10:50:31 +000012511 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012512
12513 ExceptionInfo
12514 *exception;
12515
12516 register ssize_t
12517 i;
12518
12519 SV
12520 *perl_exception;
12521
12522 volatile const TypeInfo
12523 *type_info;
12524
12525 PERL_UNUSED_VAR(ref);
12526 PERL_UNUSED_VAR(ix);
12527 exception=AcquireExceptionInfo();
12528 perl_exception=newSVpv("",0);
12529 if (items == 1)
12530 {
12531 const TypeInfo
12532 **typelist;
12533
12534 size_t
12535 types;
12536
12537 typelist=GetTypeInfoList("*",&types,exception);
12538 EXTEND(sp,types);
12539 for (i=0; i < (ssize_t) types; i++)
12540 {
12541 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12542 }
12543 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12544 typelist);
12545 goto PerlException;
12546 }
12547 EXTEND(sp,10*items);
12548 for (i=1; i < items; i++)
12549 {
12550 name=(char *) SvPV(ST(i),na);
12551 type_info=GetTypeInfo(name,exception);
12552 if (type_info == (TypeInfo *) NULL)
12553 {
12554 PUSHs(&sv_undef);
12555 continue;
12556 }
12557 if (type_info->name == (char *) NULL)
12558 PUSHs(&sv_undef);
12559 else
12560 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12561 if (type_info->description == (char *) NULL)
12562 PUSHs(&sv_undef);
12563 else
12564 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12565 if (type_info->family == (char *) NULL)
12566 PUSHs(&sv_undef);
12567 else
12568 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12569 if (type_info->style == UndefinedStyle)
12570 PUSHs(&sv_undef);
12571 else
12572 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12573 type_info->style),0)));
12574 if (type_info->stretch == UndefinedStretch)
12575 PUSHs(&sv_undef);
12576 else
12577 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12578 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012579 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012580 type_info->weight);
12581 PUSHs(sv_2mortal(newSVpv(message,0)));
12582 if (type_info->encoding == (char *) NULL)
12583 PUSHs(&sv_undef);
12584 else
12585 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12586 if (type_info->foundry == (char *) NULL)
12587 PUSHs(&sv_undef);
12588 else
12589 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12590 if (type_info->format == (char *) NULL)
12591 PUSHs(&sv_undef);
12592 else
12593 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12594 if (type_info->metrics == (char *) NULL)
12595 PUSHs(&sv_undef);
12596 else
12597 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12598 if (type_info->glyphs == (char *) NULL)
12599 PUSHs(&sv_undef);
12600 else
12601 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12602 }
12603
12604 PerlException:
12605 InheritPerlException(exception,perl_exception);
12606 exception=DestroyExceptionInfo(exception);
12607 SvREFCNT_dec(perl_exception);
12608 }
12609
12610#
12611###############################################################################
12612# #
12613# #
12614# #
12615# Q u e r y F o n t M e t r i c s #
12616# #
12617# #
12618# #
12619###############################################################################
12620#
12621#
12622void
12623QueryFontMetrics(ref,...)
12624 Image::Magick ref=NO_INIT
12625 ALIAS:
12626 queryfontmetrics = 1
12627 PPCODE:
12628 {
12629 AffineMatrix
12630 affine,
12631 current;
12632
12633 AV
12634 *av;
12635
12636 char
12637 *attribute;
12638
12639 double
12640 x,
12641 y;
12642
12643 DrawInfo
12644 *draw_info;
12645
12646 ExceptionInfo
12647 *exception;
12648
12649 GeometryInfo
12650 geometry_info;
12651
12652 Image
12653 *image;
12654
12655 MagickBooleanType
12656 status;
12657
12658 MagickStatusType
12659 flags;
12660
12661 register ssize_t
12662 i;
12663
12664 ssize_t
12665 type;
12666
12667 struct PackageInfo
12668 *info,
12669 *package_info;
12670
12671 SV
12672 *perl_exception,
12673 *reference; /* reference is the SV* of ref=SvIV(reference) */
12674
12675 TypeMetric
12676 metrics;
12677
12678 PERL_UNUSED_VAR(ref);
12679 PERL_UNUSED_VAR(ix);
12680 exception=AcquireExceptionInfo();
12681 package_info=(struct PackageInfo *) NULL;
12682 perl_exception=newSVpv("",0);
12683 reference=SvRV(ST(0));
12684 av=(AV *) reference;
12685 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12686 exception);
12687 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12688 if (image == (Image *) NULL)
12689 {
12690 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12691 PackageName);
12692 goto PerlException;
12693 }
12694 package_info=ClonePackageInfo(info,exception);
12695 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12696 CloneString(&draw_info->text,"");
12697 current=draw_info->affine;
12698 GetAffineMatrix(&affine);
12699 x=0.0;
12700 y=0.0;
12701 EXTEND(sp,7*items);
12702 for (i=2; i < items; i+=2)
12703 {
12704 attribute=(char *) SvPV(ST(i-1),na);
12705 switch (*attribute)
12706 {
12707 case 'A':
12708 case 'a':
12709 {
12710 if (LocaleCompare(attribute,"antialias") == 0)
12711 {
12712 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12713 SvPV(ST(i),na));
12714 if (type < 0)
12715 {
12716 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12717 SvPV(ST(i),na));
12718 break;
12719 }
12720 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12721 break;
12722 }
12723 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12724 attribute);
12725 break;
12726 }
12727 case 'd':
12728 case 'D':
12729 {
12730 if (LocaleCompare(attribute,"density") == 0)
12731 {
12732 CloneString(&draw_info->density,SvPV(ST(i),na));
12733 break;
12734 }
12735 if (LocaleCompare(attribute,"direction") == 0)
12736 {
12737 draw_info->direction=(DirectionType) ParseCommandOption(
12738 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12739 break;
12740 }
12741 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12742 attribute);
12743 break;
12744 }
12745 case 'e':
12746 case 'E':
12747 {
12748 if (LocaleCompare(attribute,"encoding") == 0)
12749 {
12750 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12751 break;
12752 }
12753 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12754 attribute);
12755 break;
12756 }
12757 case 'f':
12758 case 'F':
12759 {
12760 if (LocaleCompare(attribute,"family") == 0)
12761 {
12762 CloneString(&draw_info->family,SvPV(ST(i),na));
12763 break;
12764 }
12765 if (LocaleCompare(attribute,"fill") == 0)
12766 {
12767 if (info)
12768 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12769 &draw_info->fill,exception);
12770 break;
12771 }
12772 if (LocaleCompare(attribute,"font") == 0)
12773 {
12774 CloneString(&draw_info->font,SvPV(ST(i),na));
12775 break;
12776 }
12777 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12778 attribute);
12779 break;
12780 }
12781 case 'g':
12782 case 'G':
12783 {
12784 if (LocaleCompare(attribute,"geometry") == 0)
12785 {
12786 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12787 break;
12788 }
12789 if (LocaleCompare(attribute,"gravity") == 0)
12790 {
12791 draw_info->gravity=(GravityType) ParseCommandOption(
12792 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12793 break;
12794 }
12795 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12796 attribute);
12797 break;
12798 }
12799 case 'i':
12800 case 'I':
12801 {
12802 if (LocaleCompare(attribute,"interline-spacing") == 0)
12803 {
12804 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12805 draw_info->interline_spacing=geometry_info.rho;
12806 break;
12807 }
12808 if (LocaleCompare(attribute,"interword-spacing") == 0)
12809 {
12810 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12811 draw_info->interword_spacing=geometry_info.rho;
12812 break;
12813 }
12814 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12815 attribute);
12816 break;
12817 }
12818 case 'k':
12819 case 'K':
12820 {
12821 if (LocaleCompare(attribute,"kerning") == 0)
12822 {
12823 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12824 draw_info->kerning=geometry_info.rho;
12825 break;
12826 }
12827 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12828 attribute);
12829 break;
12830 }
12831 case 'p':
12832 case 'P':
12833 {
12834 if (LocaleCompare(attribute,"pointsize") == 0)
12835 {
12836 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12837 draw_info->pointsize=geometry_info.rho;
12838 break;
12839 }
12840 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12841 attribute);
12842 break;
12843 }
12844 case 'r':
12845 case 'R':
12846 {
12847 if (LocaleCompare(attribute,"rotate") == 0)
12848 {
12849 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12850 affine.rx=geometry_info.rho;
12851 affine.ry=geometry_info.sigma;
12852 if ((flags & SigmaValue) == 0)
12853 affine.ry=affine.rx;
12854 break;
12855 }
12856 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12857 attribute);
12858 break;
12859 }
12860 case 's':
12861 case 'S':
12862 {
12863 if (LocaleCompare(attribute,"scale") == 0)
12864 {
12865 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12866 affine.sx=geometry_info.rho;
12867 affine.sy=geometry_info.sigma;
12868 if ((flags & SigmaValue) == 0)
12869 affine.sy=affine.sx;
12870 break;
12871 }
12872 if (LocaleCompare(attribute,"skew") == 0)
12873 {
12874 double
12875 x_angle,
12876 y_angle;
12877
12878 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12879 x_angle=geometry_info.rho;
12880 y_angle=geometry_info.sigma;
12881 if ((flags & SigmaValue) == 0)
12882 y_angle=x_angle;
12883 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12884 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12885 break;
12886 }
12887 if (LocaleCompare(attribute,"stroke") == 0)
12888 {
12889 if (info)
12890 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12891 &draw_info->stroke,exception);
12892 break;
12893 }
12894 if (LocaleCompare(attribute,"style") == 0)
12895 {
12896 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12897 SvPV(ST(i),na));
12898 if (type < 0)
12899 {
12900 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12901 SvPV(ST(i),na));
12902 break;
12903 }
12904 draw_info->style=(StyleType) type;
12905 break;
12906 }
12907 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12908 attribute);
12909 break;
12910 }
12911 case 't':
12912 case 'T':
12913 {
12914 if (LocaleCompare(attribute,"text") == 0)
12915 {
12916 CloneString(&draw_info->text,SvPV(ST(i),na));
12917 break;
12918 }
12919 if (LocaleCompare(attribute,"translate") == 0)
12920 {
12921 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12922 affine.tx=geometry_info.rho;
12923 affine.ty=geometry_info.sigma;
12924 if ((flags & SigmaValue) == 0)
12925 affine.ty=affine.tx;
12926 break;
12927 }
12928 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12929 attribute);
12930 break;
12931 }
12932 case 'w':
12933 case 'W':
12934 {
12935 if (LocaleCompare(attribute,"weight") == 0)
12936 {
12937 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12938 draw_info->weight=(size_t) geometry_info.rho;
12939 break;
12940 }
12941 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12942 attribute);
12943 break;
12944 }
12945 case 'x':
12946 case 'X':
12947 {
12948 if (LocaleCompare(attribute,"x") == 0)
12949 {
12950 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12951 x=geometry_info.rho;
12952 break;
12953 }
12954 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12955 attribute);
12956 break;
12957 }
12958 case 'y':
12959 case 'Y':
12960 {
12961 if (LocaleCompare(attribute,"y") == 0)
12962 {
12963 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12964 y=geometry_info.rho;
12965 break;
12966 }
12967 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12968 attribute);
12969 break;
12970 }
12971 default:
12972 {
12973 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12974 attribute);
12975 break;
12976 }
12977 }
12978 }
12979 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12980 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12981 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12982 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12983 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12984 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12985 if (draw_info->geometry == (char *) NULL)
12986 {
12987 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000012988 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050012989 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000012990 }
12991 status=GetTypeMetrics(image,draw_info,&metrics,exception);
12992 (void) CatchImageException(image);
12993 if (status == MagickFalse)
12994 PUSHs(&sv_undef);
12995 else
12996 {
12997 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12998 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12999 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13000 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13001 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13002 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13003 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13004 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13005 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13006 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13007 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13008 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13009 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13010 }
13011 draw_info=DestroyDrawInfo(draw_info);
13012
13013 PerlException:
13014 if (package_info != (struct PackageInfo *) NULL)
13015 DestroyPackageInfo(package_info);
13016 InheritPerlException(exception,perl_exception);
13017 exception=DestroyExceptionInfo(exception);
13018 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13019 }
13020
13021#
13022###############################################################################
13023# #
13024# #
13025# #
13026# 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 #
13027# #
13028# #
13029# #
13030###############################################################################
13031#
13032#
13033void
13034QueryMultilineFontMetrics(ref,...)
13035 Image::Magick ref=NO_INIT
13036 ALIAS:
13037 querymultilinefontmetrics = 1
13038 PPCODE:
13039 {
13040 AffineMatrix
13041 affine,
13042 current;
13043
13044 AV
13045 *av;
13046
13047 char
13048 *attribute;
13049
13050 double
13051 x,
13052 y;
13053
13054 DrawInfo
13055 *draw_info;
13056
13057 ExceptionInfo
13058 *exception;
13059
13060 GeometryInfo
13061 geometry_info;
13062
13063 Image
13064 *image;
13065
13066 MagickBooleanType
13067 status;
13068
13069 MagickStatusType
13070 flags;
13071
13072 register ssize_t
13073 i;
13074
13075 ssize_t
13076 type;
13077
13078 struct PackageInfo
13079 *info,
13080 *package_info;
13081
13082 SV
13083 *perl_exception,
13084 *reference; /* reference is the SV* of ref=SvIV(reference) */
13085
13086 TypeMetric
13087 metrics;
13088
13089 PERL_UNUSED_VAR(ref);
13090 PERL_UNUSED_VAR(ix);
13091 exception=AcquireExceptionInfo();
13092 package_info=(struct PackageInfo *) NULL;
13093 perl_exception=newSVpv("",0);
13094 reference=SvRV(ST(0));
13095 av=(AV *) reference;
13096 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13097 exception);
13098 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13099 if (image == (Image *) NULL)
13100 {
13101 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13102 PackageName);
13103 goto PerlException;
13104 }
13105 package_info=ClonePackageInfo(info,exception);
13106 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13107 CloneString(&draw_info->text,"");
13108 current=draw_info->affine;
13109 GetAffineMatrix(&affine);
13110 x=0.0;
13111 y=0.0;
13112 EXTEND(sp,7*items);
13113 for (i=2; i < items; i+=2)
13114 {
13115 attribute=(char *) SvPV(ST(i-1),na);
13116 switch (*attribute)
13117 {
13118 case 'A':
13119 case 'a':
13120 {
13121 if (LocaleCompare(attribute,"antialias") == 0)
13122 {
13123 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13124 SvPV(ST(i),na));
13125 if (type < 0)
13126 {
13127 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13128 SvPV(ST(i),na));
13129 break;
13130 }
13131 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13132 break;
13133 }
13134 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13135 attribute);
13136 break;
13137 }
13138 case 'd':
13139 case 'D':
13140 {
13141 if (LocaleCompare(attribute,"density") == 0)
13142 {
13143 CloneString(&draw_info->density,SvPV(ST(i),na));
13144 break;
13145 }
13146 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13147 attribute);
13148 break;
13149 }
13150 case 'e':
13151 case 'E':
13152 {
13153 if (LocaleCompare(attribute,"encoding") == 0)
13154 {
13155 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13156 break;
13157 }
13158 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13159 attribute);
13160 break;
13161 }
13162 case 'f':
13163 case 'F':
13164 {
13165 if (LocaleCompare(attribute,"family") == 0)
13166 {
13167 CloneString(&draw_info->family,SvPV(ST(i),na));
13168 break;
13169 }
13170 if (LocaleCompare(attribute,"fill") == 0)
13171 {
13172 if (info)
13173 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13174 &draw_info->fill,exception);
13175 break;
13176 }
13177 if (LocaleCompare(attribute,"font") == 0)
13178 {
13179 CloneString(&draw_info->font,SvPV(ST(i),na));
13180 break;
13181 }
13182 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13183 attribute);
13184 break;
13185 }
13186 case 'g':
13187 case 'G':
13188 {
13189 if (LocaleCompare(attribute,"geometry") == 0)
13190 {
13191 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13192 break;
13193 }
13194 if (LocaleCompare(attribute,"gravity") == 0)
13195 {
13196 draw_info->gravity=(GravityType) ParseCommandOption(
13197 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13198 break;
13199 }
13200 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13201 attribute);
13202 break;
13203 }
13204 case 'p':
13205 case 'P':
13206 {
13207 if (LocaleCompare(attribute,"pointsize") == 0)
13208 {
13209 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13210 draw_info->pointsize=geometry_info.rho;
13211 break;
13212 }
13213 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13214 attribute);
13215 break;
13216 }
13217 case 'r':
13218 case 'R':
13219 {
13220 if (LocaleCompare(attribute,"rotate") == 0)
13221 {
13222 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13223 affine.rx=geometry_info.rho;
13224 affine.ry=geometry_info.sigma;
13225 if ((flags & SigmaValue) == 0)
13226 affine.ry=affine.rx;
13227 break;
13228 }
13229 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13230 attribute);
13231 break;
13232 }
13233 case 's':
13234 case 'S':
13235 {
13236 if (LocaleCompare(attribute,"scale") == 0)
13237 {
13238 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13239 affine.sx=geometry_info.rho;
13240 affine.sy=geometry_info.sigma;
13241 if ((flags & SigmaValue) == 0)
13242 affine.sy=affine.sx;
13243 break;
13244 }
13245 if (LocaleCompare(attribute,"skew") == 0)
13246 {
13247 double
13248 x_angle,
13249 y_angle;
13250
13251 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13252 x_angle=geometry_info.rho;
13253 y_angle=geometry_info.sigma;
13254 if ((flags & SigmaValue) == 0)
13255 y_angle=x_angle;
13256 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13257 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13258 break;
13259 }
13260 if (LocaleCompare(attribute,"stroke") == 0)
13261 {
13262 if (info)
13263 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13264 &draw_info->stroke,exception);
13265 break;
13266 }
13267 if (LocaleCompare(attribute,"style") == 0)
13268 {
13269 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13270 SvPV(ST(i),na));
13271 if (type < 0)
13272 {
13273 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13274 SvPV(ST(i),na));
13275 break;
13276 }
13277 draw_info->style=(StyleType) type;
13278 break;
13279 }
13280 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13281 attribute);
13282 break;
13283 }
13284 case 't':
13285 case 'T':
13286 {
13287 if (LocaleCompare(attribute,"text") == 0)
13288 {
13289 CloneString(&draw_info->text,SvPV(ST(i),na));
13290 break;
13291 }
13292 if (LocaleCompare(attribute,"translate") == 0)
13293 {
13294 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13295 affine.tx=geometry_info.rho;
13296 affine.ty=geometry_info.sigma;
13297 if ((flags & SigmaValue) == 0)
13298 affine.ty=affine.tx;
13299 break;
13300 }
13301 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13302 attribute);
13303 break;
13304 }
13305 case 'w':
13306 case 'W':
13307 {
13308 if (LocaleCompare(attribute,"weight") == 0)
13309 {
13310 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13311 draw_info->weight=(size_t) geometry_info.rho;
13312 break;
13313 }
13314 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13315 attribute);
13316 break;
13317 }
13318 case 'x':
13319 case 'X':
13320 {
13321 if (LocaleCompare(attribute,"x") == 0)
13322 {
13323 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13324 x=geometry_info.rho;
13325 break;
13326 }
13327 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13328 attribute);
13329 break;
13330 }
13331 case 'y':
13332 case 'Y':
13333 {
13334 if (LocaleCompare(attribute,"y") == 0)
13335 {
13336 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13337 y=geometry_info.rho;
13338 break;
13339 }
13340 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13341 attribute);
13342 break;
13343 }
13344 default:
13345 {
13346 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13347 attribute);
13348 break;
13349 }
13350 }
13351 }
13352 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13353 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13354 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13355 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13356 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13357 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13358 if (draw_info->geometry == (char *) NULL)
13359 {
13360 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013361 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013362 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013363 }
13364 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13365 (void) CatchException(exception);
13366 if (status == MagickFalse)
13367 PUSHs(&sv_undef);
13368 else
13369 {
13370 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13371 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13372 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13373 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13374 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13375 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13376 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13377 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13378 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13379 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13380 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13381 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13382 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13383 }
13384 draw_info=DestroyDrawInfo(draw_info);
13385
13386 PerlException:
13387 if (package_info != (struct PackageInfo *) NULL)
13388 DestroyPackageInfo(package_info);
13389 InheritPerlException(exception,perl_exception);
13390 exception=DestroyExceptionInfo(exception);
13391 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13392 }
13393
13394#
13395###############################################################################
13396# #
13397# #
13398# #
13399# Q u e r y F o r m a t #
13400# #
13401# #
13402# #
13403###############################################################################
13404#
13405#
13406void
13407QueryFormat(ref,...)
13408 Image::Magick ref=NO_INIT
13409 ALIAS:
13410 queryformat = 1
13411 PPCODE:
13412 {
13413 char
13414 *name;
13415
13416 ExceptionInfo
13417 *exception;
13418
13419 register ssize_t
13420 i;
13421
13422 SV
13423 *perl_exception;
13424
13425 volatile const MagickInfo
13426 *magick_info;
13427
13428 PERL_UNUSED_VAR(ref);
13429 PERL_UNUSED_VAR(ix);
13430 exception=AcquireExceptionInfo();
13431 perl_exception=newSVpv("",0);
13432 if (items == 1)
13433 {
13434 char
cristy151b66d2015-04-15 10:50:31 +000013435 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013436
13437 const MagickInfo
13438 **format_list;
13439
13440 size_t
13441 types;
13442
13443 format_list=GetMagickInfoList("*",&types,exception);
13444 EXTEND(sp,types);
13445 for (i=0; i < (ssize_t) types; i++)
13446 {
cristy151b66d2015-04-15 10:50:31 +000013447 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013448 LocaleLower(format);
13449 PUSHs(sv_2mortal(newSVpv(format,0)));
13450 }
13451 format_list=(const MagickInfo **)
13452 RelinquishMagickMemory((MagickInfo *) format_list);
13453 goto PerlException;
13454 }
13455 EXTEND(sp,8*items);
13456 for (i=1; i < items; i++)
13457 {
13458 name=(char *) SvPV(ST(i),na);
13459 magick_info=GetMagickInfo(name,exception);
13460 if (magick_info == (const MagickInfo *) NULL)
13461 {
13462 PUSHs(&sv_undef);
13463 continue;
13464 }
cristy4a3ce0a2013-08-03 20:06:59 +000013465 if (magick_info->description == (char *) NULL)
13466 PUSHs(&sv_undef);
13467 else
13468 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13469 if (magick_info->module == (char *) NULL)
13470 PUSHs(&sv_undef);
13471 else
13472 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13473 }
13474
13475 PerlException:
13476 InheritPerlException(exception,perl_exception);
13477 exception=DestroyExceptionInfo(exception);
13478 SvREFCNT_dec(perl_exception);
13479 }
13480
13481#
13482###############################################################################
13483# #
13484# #
13485# #
13486# Q u e r y O p t i o n #
13487# #
13488# #
13489# #
13490###############################################################################
13491#
13492#
13493void
13494QueryOption(ref,...)
13495 Image::Magick ref=NO_INIT
13496 ALIAS:
13497 queryoption = 1
13498 PPCODE:
13499 {
13500 char
13501 **options;
13502
13503 ExceptionInfo
13504 *exception;
13505
13506 register ssize_t
13507 i;
13508
13509 ssize_t
13510 j,
13511 option;
13512
13513 SV
13514 *perl_exception;
13515
13516 PERL_UNUSED_VAR(ref);
13517 PERL_UNUSED_VAR(ix);
13518 exception=AcquireExceptionInfo();
13519 perl_exception=newSVpv("",0);
13520 EXTEND(sp,8*items);
13521 for (i=1; i < items; i++)
13522 {
13523 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13524 SvPV(ST(i),na));
13525 options=GetCommandOptions((CommandOption) option);
13526 if (options == (char **) NULL)
13527 PUSHs(&sv_undef);
13528 else
13529 {
13530 for (j=0; options[j] != (char *) NULL; j++)
13531 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13532 options=DestroyStringList(options);
13533 }
13534 }
13535
13536 InheritPerlException(exception,perl_exception);
13537 exception=DestroyExceptionInfo(exception);
13538 SvREFCNT_dec(perl_exception);
13539 }
13540
13541#
13542###############################################################################
13543# #
13544# #
13545# #
13546# R e a d #
13547# #
13548# #
13549# #
13550###############################################################################
13551#
13552#
13553void
13554Read(ref,...)
13555 Image::Magick ref=NO_INIT
13556 ALIAS:
13557 ReadImage = 1
13558 read = 2
13559 readimage = 3
13560 PPCODE:
13561 {
13562 AV
13563 *av;
13564
13565 char
13566 **keep,
13567 **list;
13568
13569 ExceptionInfo
13570 *exception;
13571
13572 HV
13573 *hv;
13574
13575 Image
13576 *image;
13577
13578 int
13579 n;
13580
13581 MagickBooleanType
13582 status;
13583
13584 register char
13585 **p;
13586
13587 register ssize_t
13588 i;
13589
13590 ssize_t
13591 ac,
13592 number_images;
13593
13594 STRLEN
13595 *length;
13596
13597 struct PackageInfo
13598 *info,
13599 *package_info;
13600
13601 SV
13602 *perl_exception, /* Perl variable for storing messages */
13603 *reference,
13604 *rv,
13605 *sv;
13606
13607 PERL_UNUSED_VAR(ref);
13608 PERL_UNUSED_VAR(ix);
13609 exception=AcquireExceptionInfo();
13610 perl_exception=newSVpv("",0);
13611 sv=NULL;
13612 package_info=(struct PackageInfo *) NULL;
13613 number_images=0;
13614 ac=(items < 2) ? 1 : items-1;
13615 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13616 keep=list;
13617 length=(STRLEN *) NULL;
13618 if (list == (char **) NULL)
13619 {
13620 ThrowPerlException(exception,ResourceLimitError,
13621 "MemoryAllocationFailed",PackageName);
13622 goto PerlException;
13623 }
13624 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13625 if (length == (STRLEN *) NULL)
13626 {
13627 ThrowPerlException(exception,ResourceLimitError,
13628 "MemoryAllocationFailed",PackageName);
13629 goto PerlException;
13630 }
13631 if (sv_isobject(ST(0)) == 0)
13632 {
13633 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13634 PackageName);
13635 goto PerlException;
13636 }
13637 reference=SvRV(ST(0));
13638 hv=SvSTASH(reference);
13639 if (SvTYPE(reference) != SVt_PVAV)
13640 {
13641 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13642 PackageName);
13643 goto PerlException;
13644 }
13645 av=(AV *) reference;
13646 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13647 exception);
13648 package_info=ClonePackageInfo(info,exception);
13649 n=1;
13650 if (items <= 1)
13651 *list=(char *) (*package_info->image_info->filename ?
13652 package_info->image_info->filename : "XC:black");
13653 else
13654 for (n=0, i=0; i < ac; i++)
13655 {
13656 list[n]=(char *) SvPV(ST(i+1),length[n]);
13657 if ((items >= 3) && strEQcase(list[n],"blob"))
13658 {
13659 void
13660 *blob;
13661
13662 i++;
13663 blob=(void *) (SvPV(ST(i+1),length[n]));
13664 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13665 }
13666 if ((items >= 3) && strEQcase(list[n],"filename"))
13667 continue;
13668 if ((items >= 3) && strEQcase(list[n],"file"))
13669 {
13670 FILE
13671 *file;
13672
13673 PerlIO
13674 *io_info;
13675
13676 i++;
13677 io_info=IoIFP(sv_2io(ST(i+1)));
13678 if (io_info == (PerlIO *) NULL)
13679 {
13680 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13681 PackageName);
13682 continue;
13683 }
13684 file=PerlIO_findFILE(io_info);
13685 if (file == (FILE *) NULL)
13686 {
13687 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13688 PackageName);
13689 continue;
13690 }
13691 SetImageInfoFile(package_info->image_info,file);
13692 }
13693 if ((items >= 3) && strEQcase(list[n],"magick"))
13694 continue;
13695 n++;
13696 }
13697 list[n]=(char *) NULL;
13698 keep=list;
13699 status=ExpandFilenames(&n,&list);
13700 if (status == MagickFalse)
13701 {
13702 ThrowPerlException(exception,ResourceLimitError,
13703 "MemoryAllocationFailed",PackageName);
13704 goto PerlException;
13705 }
13706 number_images=0;
13707 for (i=0; i < n; i++)
13708 {
13709 if ((package_info->image_info->file == (FILE *) NULL) &&
13710 (package_info->image_info->blob == (void *) NULL))
13711 image=ReadImages(package_info->image_info,list[i],exception);
13712 else
13713 {
13714 image=ReadImages(package_info->image_info,
13715 package_info->image_info->filename,exception);
13716 if (image != (Image *) NULL)
13717 DisassociateImageStream(image);
13718 }
13719 if (image == (Image *) NULL)
13720 break;
13721 for ( ; image; image=image->next)
13722 {
13723 AddImageToRegistry(sv,image);
13724 rv=newRV(sv);
13725 av_push(av,sv_bless(rv,hv));
13726 SvREFCNT_dec(sv);
13727 number_images++;
13728 }
13729 }
13730 /*
13731 Free resources.
13732 */
13733 for (i=0; i < n; i++)
13734 if (list[i] != (char *) NULL)
13735 for (p=keep; list[i] != *p++; )
13736 if (*p == (char *) NULL)
13737 {
13738 list[i]=(char *) RelinquishMagickMemory(list[i]);
13739 break;
13740 }
13741
13742 PerlException:
13743 if (package_info != (struct PackageInfo *) NULL)
13744 DestroyPackageInfo(package_info);
13745 if (list && (list != keep))
13746 list=(char **) RelinquishMagickMemory(list);
13747 if (keep)
13748 keep=(char **) RelinquishMagickMemory(keep);
13749 if (length)
13750 length=(STRLEN *) RelinquishMagickMemory(length);
13751 InheritPerlException(exception,perl_exception);
13752 exception=DestroyExceptionInfo(exception);
13753 sv_setiv(perl_exception,(IV) number_images);
13754 SvPOK_on(perl_exception);
13755 ST(0)=sv_2mortal(perl_exception);
13756 XSRETURN(1);
13757 }
13758
13759#
13760###############################################################################
13761# #
13762# #
13763# #
13764# R e m o t e #
13765# #
13766# #
13767# #
13768###############################################################################
13769#
13770#
13771void
13772Remote(ref,...)
13773 Image::Magick ref=NO_INIT
13774 ALIAS:
13775 RemoteCommand = 1
13776 remote = 2
13777 remoteCommand = 3
13778 PPCODE:
13779 {
13780 AV
13781 *av;
13782
13783 ExceptionInfo
13784 *exception;
13785
13786 register ssize_t
13787 i;
13788
13789 SV
13790 *perl_exception,
13791 *reference;
13792
13793 struct PackageInfo
13794 *info;
13795
13796 PERL_UNUSED_VAR(ref);
13797 PERL_UNUSED_VAR(ix);
13798 exception=AcquireExceptionInfo();
13799 perl_exception=newSVpv("",0);
13800 reference=SvRV(ST(0));
13801 av=(AV *) reference;
13802 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13803 exception);
13804 for (i=1; i < items; i++)
13805 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13806 SvPV(ST(i),na),exception);
13807 InheritPerlException(exception,perl_exception);
13808 exception=DestroyExceptionInfo(exception);
13809 SvREFCNT_dec(perl_exception); /* throw away all errors */
13810 }
13811
13812#
13813###############################################################################
13814# #
13815# #
13816# #
13817# S e t #
13818# #
13819# #
13820# #
13821###############################################################################
13822#
13823#
13824void
13825Set(ref,...)
13826 Image::Magick ref=NO_INIT
13827 ALIAS:
13828 SetAttributes = 1
13829 SetAttribute = 2
13830 set = 3
13831 setattributes = 4
13832 setattribute = 5
13833 PPCODE:
13834 {
13835 ExceptionInfo
13836 *exception;
13837
13838 Image
13839 *image;
13840
13841 register ssize_t
13842 i;
13843
13844 struct PackageInfo
13845 *info;
13846
13847 SV
13848 *perl_exception,
13849 *reference; /* reference is the SV* of ref=SvIV(reference) */
13850
13851 PERL_UNUSED_VAR(ref);
13852 PERL_UNUSED_VAR(ix);
13853 exception=AcquireExceptionInfo();
13854 perl_exception=newSVpv("",0);
13855 if (sv_isobject(ST(0)) == 0)
13856 {
13857 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13858 PackageName);
13859 goto PerlException;
13860 }
13861 reference=SvRV(ST(0));
13862 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13863 if (items == 2)
13864 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13865 else
13866 for (i=2; i < items; i+=2)
13867 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13868
13869 PerlException:
13870 InheritPerlException(exception,perl_exception);
13871 exception=DestroyExceptionInfo(exception);
13872 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13873 SvPOK_on(perl_exception);
13874 ST(0)=sv_2mortal(perl_exception);
13875 XSRETURN(1);
13876 }
13877
13878#
13879###############################################################################
13880# #
13881# #
13882# #
13883# S e t P i x e l #
13884# #
13885# #
13886# #
13887###############################################################################
13888#
13889#
13890void
13891SetPixel(ref,...)
13892 Image::Magick ref=NO_INIT
13893 ALIAS:
13894 setpixel = 1
13895 setPixel = 2
13896 PPCODE:
13897 {
13898 AV
13899 *av;
13900
13901 char
13902 *attribute;
13903
13904 ChannelType
13905 channel,
13906 channel_mask;
13907
13908 ExceptionInfo
13909 *exception;
13910
13911 Image
13912 *image;
13913
13914 MagickBooleanType
13915 normalize;
13916
13917 RectangleInfo
13918 region;
13919
13920 register ssize_t
13921 i;
13922
13923 register Quantum
13924 *q;
13925
13926 ssize_t
13927 option;
13928
13929 struct PackageInfo
13930 *info;
13931
13932 SV
13933 *perl_exception,
13934 *reference; /* reference is the SV* of ref=SvIV(reference) */
13935
13936 PERL_UNUSED_VAR(ref);
13937 PERL_UNUSED_VAR(ix);
13938 exception=AcquireExceptionInfo();
13939 perl_exception=newSVpv("",0);
13940 reference=SvRV(ST(0));
13941 av=(AV *) reference;
13942 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13943 exception);
13944 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13945 if (image == (Image *) NULL)
13946 {
13947 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13948 PackageName);
13949 goto PerlException;
13950 }
13951 av=(AV *) NULL;
13952 normalize=MagickTrue;
13953 region.x=0;
13954 region.y=0;
13955 region.width=image->columns;
13956 region.height=1;
13957 if (items == 1)
13958 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
13959 channel=DefaultChannels;
13960 for (i=2; i < items; i+=2)
13961 {
13962 attribute=(char *) SvPV(ST(i-1),na);
13963 switch (*attribute)
13964 {
13965 case 'C':
13966 case 'c':
13967 {
13968 if (LocaleCompare(attribute,"channel") == 0)
13969 {
13970 ssize_t
13971 option;
13972
13973 option=ParseChannelOption(SvPV(ST(i),na));
13974 if (option < 0)
13975 {
13976 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13977 SvPV(ST(i),na));
13978 return;
13979 }
13980 channel=(ChannelType) option;
13981 break;
13982 }
13983 if (LocaleCompare(attribute,"color") == 0)
13984 {
13985 if (SvTYPE(ST(i)) != SVt_RV)
13986 {
13987 char
cristy151b66d2015-04-15 10:50:31 +000013988 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013989
cristy151b66d2015-04-15 10:50:31 +000013990 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013991 "invalid %.60s value",attribute);
13992 ThrowPerlException(exception,OptionError,message,
13993 SvPV(ST(i),na));
13994 }
13995 av=(AV *) SvRV(ST(i));
13996 break;
13997 }
13998 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13999 attribute);
14000 break;
14001 }
14002 case 'g':
14003 case 'G':
14004 {
14005 if (LocaleCompare(attribute,"geometry") == 0)
14006 {
14007 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14008 break;
14009 }
14010 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14011 attribute);
14012 break;
14013 }
14014 case 'N':
14015 case 'n':
14016 {
14017 if (LocaleCompare(attribute,"normalize") == 0)
14018 {
14019 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14020 SvPV(ST(i),na));
14021 if (option < 0)
14022 {
14023 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14024 SvPV(ST(i),na));
14025 break;
14026 }
14027 normalize=option != 0 ? MagickTrue : MagickFalse;
14028 break;
14029 }
14030 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14031 attribute);
14032 break;
14033 }
14034 case 'x':
14035 case 'X':
14036 {
14037 if (LocaleCompare(attribute,"x") == 0)
14038 {
14039 region.x=SvIV(ST(i));
14040 break;
14041 }
14042 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14043 attribute);
14044 break;
14045 }
14046 case 'y':
14047 case 'Y':
14048 {
14049 if (LocaleCompare(attribute,"y") == 0)
14050 {
14051 region.y=SvIV(ST(i));
14052 break;
14053 }
14054 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14055 attribute);
14056 break;
14057 }
14058 default:
14059 {
14060 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14061 attribute);
14062 break;
14063 }
14064 }
14065 }
14066 (void) SetImageStorageClass(image,DirectClass,exception);
14067 channel_mask=SetImageChannelMask(image,channel);
14068 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14069 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14070 (SvTYPE(av) != SVt_PVAV))
14071 PUSHs(&sv_undef);
14072 else
14073 {
14074 double
14075 scale;
14076
14077 register ssize_t
14078 i;
14079
14080 i=0;
14081 scale=1.0;
14082 if (normalize != MagickFalse)
14083 scale=QuantumRange;
14084 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14085 (i <= av_len(av)))
14086 {
14087 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14088 av_fetch(av,i,0)))),q);
14089 i++;
14090 }
14091 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14092 (i <= av_len(av)))
14093 {
14094 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14095 av_fetch(av,i,0)))),q);
14096 i++;
14097 }
14098 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14099 (i <= av_len(av)))
14100 {
14101 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14102 av_fetch(av,i,0)))),q);
14103 i++;
14104 }
14105 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14106 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14107 {
14108 SetPixelBlack(image,ClampToQuantum(scale*
14109 SvNV(*(av_fetch(av,i,0)))),q);
14110 i++;
14111 }
14112 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14113 (i <= av_len(av)))
14114 {
14115 SetPixelAlpha(image,ClampToQuantum(scale*
14116 SvNV(*(av_fetch(av,i,0)))),q);
14117 i++;
14118 }
14119 (void) SyncAuthenticPixels(image,exception);
14120 }
14121 (void) SetImageChannelMask(image,channel_mask);
14122
14123 PerlException:
14124 InheritPerlException(exception,perl_exception);
14125 exception=DestroyExceptionInfo(exception);
14126 SvREFCNT_dec(perl_exception);
14127 }
14128
14129#
14130###############################################################################
14131# #
14132# #
14133# #
14134# S m u s h #
14135# #
14136# #
14137# #
14138###############################################################################
14139#
14140#
14141void
14142Smush(ref,...)
14143 Image::Magick ref=NO_INIT
14144 ALIAS:
14145 SmushImage = 1
14146 smush = 2
14147 smushimage = 3
14148 PPCODE:
14149 {
14150 AV
14151 *av;
14152
14153 char
14154 *attribute;
14155
14156 ExceptionInfo
14157 *exception;
14158
14159 HV
14160 *hv;
14161
14162 Image
14163 *image;
14164
14165 register ssize_t
14166 i;
14167
14168 ssize_t
14169 offset,
14170 stack;
14171
14172 struct PackageInfo
14173 *info;
14174
14175 SV
14176 *av_reference,
14177 *perl_exception,
14178 *reference,
14179 *rv,
14180 *sv;
14181
14182 PERL_UNUSED_VAR(ref);
14183 PERL_UNUSED_VAR(ix);
14184 exception=AcquireExceptionInfo();
14185 perl_exception=newSVpv("",0);
14186 sv=NULL;
14187 attribute=NULL;
14188 av=NULL;
14189 if (sv_isobject(ST(0)) == 0)
14190 {
14191 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14192 PackageName);
14193 goto PerlException;
14194 }
14195 reference=SvRV(ST(0));
14196 hv=SvSTASH(reference);
14197 av=newAV();
14198 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14199 SvREFCNT_dec(av);
14200 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14201 if (image == (Image *) NULL)
14202 {
14203 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14204 PackageName);
14205 goto PerlException;
14206 }
14207 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14208 /*
14209 Get options.
14210 */
14211 offset=0;
14212 stack=MagickTrue;
14213 for (i=2; i < items; i+=2)
14214 {
14215 attribute=(char *) SvPV(ST(i-1),na);
14216 switch (*attribute)
14217 {
14218 case 'O':
14219 case 'o':
14220 {
14221 if (LocaleCompare(attribute,"offset") == 0)
14222 {
14223 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14224 break;
14225 }
14226 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14227 attribute);
14228 break;
14229 }
14230 case 'S':
14231 case 's':
14232 {
14233 if (LocaleCompare(attribute,"stack") == 0)
14234 {
14235 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14236 SvPV(ST(i),na));
14237 if (stack < 0)
14238 {
14239 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14240 SvPV(ST(i),na));
14241 return;
14242 }
14243 break;
14244 }
14245 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14246 attribute);
14247 break;
14248 }
14249 default:
14250 {
14251 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14252 attribute);
14253 break;
14254 }
14255 }
14256 }
14257 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14258 exception);
14259 if (image == (Image *) NULL)
14260 goto PerlException;
14261 for ( ; image; image=image->next)
14262 {
14263 AddImageToRegistry(sv,image);
14264 rv=newRV(sv);
14265 av_push(av,sv_bless(rv,hv));
14266 SvREFCNT_dec(sv);
14267 }
14268 exception=DestroyExceptionInfo(exception);
14269 ST(0)=av_reference;
14270 SvREFCNT_dec(perl_exception);
14271 XSRETURN(1);
14272
14273 PerlException:
14274 InheritPerlException(exception,perl_exception);
14275 exception=DestroyExceptionInfo(exception);
14276 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14277 SvPOK_on(perl_exception);
14278 ST(0)=sv_2mortal(perl_exception);
14279 XSRETURN(1);
14280 }
14281
14282#
14283###############################################################################
14284# #
14285# #
14286# #
14287# S t a t i s t i c s #
14288# #
14289# #
14290# #
14291###############################################################################
14292#
14293#
14294void
14295Statistics(ref,...)
14296 Image::Magick ref=NO_INIT
14297 ALIAS:
14298 StatisticsImage = 1
14299 statistics = 2
14300 statisticsimage = 3
14301 PPCODE:
14302 {
14303#define ChannelStatistics(channel) \
14304{ \
cristy151b66d2015-04-15 10:50:31 +000014305 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014306 (double) channel_statistics[channel].depth); \
14307 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014308 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014309 channel_statistics[channel].minima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014310 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014311 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014312 channel_statistics[channel].maxima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014313 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014314 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014315 channel_statistics[channel].mean/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014316 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014317 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014318 channel_statistics[channel].standard_deviation/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014319 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014320 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014321 channel_statistics[channel].kurtosis); \
14322 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014323 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014324 channel_statistics[channel].skewness); \
14325 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014326 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy275bdd92014-11-08 23:45:03 +000014327 channel_statistics[channel].entropy); \
14328 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014329}
14330
14331 AV
14332 *av;
14333
14334 char
cristy151b66d2015-04-15 10:50:31 +000014335 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014336
14337 ChannelStatistics
14338 *channel_statistics;
14339
cristy4a3ce0a2013-08-03 20:06:59 +000014340 ExceptionInfo
14341 *exception;
14342
14343 Image
14344 *image;
14345
14346 ssize_t
14347 count;
14348
14349 struct PackageInfo
14350 *info;
14351
14352 SV
14353 *perl_exception,
14354 *reference;
14355
14356 PERL_UNUSED_VAR(ref);
14357 PERL_UNUSED_VAR(ix);
14358 exception=AcquireExceptionInfo();
14359 perl_exception=newSVpv("",0);
14360 av=NULL;
14361 if (sv_isobject(ST(0)) == 0)
14362 {
14363 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14364 PackageName);
14365 goto PerlException;
14366 }
14367 reference=SvRV(ST(0));
14368 av=newAV();
14369 SvREFCNT_dec(av);
14370 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14371 if (image == (Image *) NULL)
14372 {
14373 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14374 PackageName);
14375 goto PerlException;
14376 }
cristy4a3ce0a2013-08-03 20:06:59 +000014377 count=0;
14378 for ( ; image; image=image->next)
14379 {
Cristyb1710fe2017-02-11 13:51:48 -050014380 register size_t
14381 i;
14382
cristy4a3ce0a2013-08-03 20:06:59 +000014383 channel_statistics=GetImageStatistics(image,exception);
14384 if (channel_statistics == (ChannelStatistics *) NULL)
14385 continue;
14386 count++;
Cristyb1710fe2017-02-11 13:51:48 -050014387 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
14388 {
14389 PixelChannel channel=GetPixelChannelChannel(image,i);
14390 PixelTrait traits=GetPixelChannelTraits(image,channel);
Cristy5a854dc2017-02-11 15:43:46 -050014391 if (traits == UndefinedPixelTrait)
Cristyb1710fe2017-02-11 13:51:48 -050014392 continue;
Cristy5a854dc2017-02-11 15:43:46 -050014393 EXTEND(sp,8*(i+1)*count);
Cristyb1710fe2017-02-11 13:51:48 -050014394 ChannelStatistics(channel);
14395 }
Cristy25813902017-02-11 15:47:52 -050014396 EXTEND(sp,8*(i+1)*count);
14397 ChannelStatistics(CompositePixelChannel);
cristy4a3ce0a2013-08-03 20:06:59 +000014398 channel_statistics=(ChannelStatistics *)
14399 RelinquishMagickMemory(channel_statistics);
14400 }
14401
14402 PerlException:
14403 InheritPerlException(exception,perl_exception);
14404 exception=DestroyExceptionInfo(exception);
14405 SvREFCNT_dec(perl_exception);
14406 }
14407
14408#
14409###############################################################################
14410# #
14411# #
14412# #
14413# S y n c A u t h e n t i c P i x e l s #
14414# #
14415# #
14416# #
14417###############################################################################
14418#
14419#
14420void
14421SyncAuthenticPixels(ref,...)
14422 Image::Magick ref = NO_INIT
14423 ALIAS:
14424 Syncauthenticpixels = 1
14425 SyncImagePixels = 2
14426 syncimagepixels = 3
14427 CODE:
14428 {
14429 ExceptionInfo
14430 *exception;
14431
14432 Image
14433 *image;
14434
14435 MagickBooleanType
14436 status;
14437
14438 struct PackageInfo
14439 *info;
14440
14441 SV
14442 *perl_exception,
14443 *reference;
14444
14445 PERL_UNUSED_VAR(ref);
14446 PERL_UNUSED_VAR(ix);
14447 exception=AcquireExceptionInfo();
14448 perl_exception=newSVpv("",0);
14449 if (sv_isobject(ST(0)) == 0)
14450 {
14451 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14452 PackageName);
14453 goto PerlException;
14454 }
14455
14456 reference=SvRV(ST(0));
14457 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14458 if (image == (Image *) NULL)
14459 {
14460 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14461 PackageName);
14462 goto PerlException;
14463 }
14464
14465 status=SyncAuthenticPixels(image,exception);
14466 if (status != MagickFalse)
14467 return;
14468
14469 PerlException:
14470 InheritPerlException(exception,perl_exception);
14471 exception=DestroyExceptionInfo(exception);
14472 SvREFCNT_dec(perl_exception); /* throw away all errors */
14473 }
14474
14475#
14476###############################################################################
14477# #
14478# #
14479# #
cristy4a3ce0a2013-08-03 20:06:59 +000014480# W r i t e #
14481# #
14482# #
14483# #
14484###############################################################################
14485#
14486#
14487void
14488Write(ref,...)
14489 Image::Magick ref=NO_INIT
14490 ALIAS:
14491 WriteImage = 1
14492 write = 2
14493 writeimage = 3
14494 PPCODE:
14495 {
14496 char
cristy151b66d2015-04-15 10:50:31 +000014497 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014498
14499 ExceptionInfo
14500 *exception;
14501
14502 Image
14503 *image,
14504 *next;
14505
14506 register ssize_t
14507 i;
14508
14509 ssize_t
14510 number_images,
14511 scene;
14512
14513 struct PackageInfo
14514 *info,
14515 *package_info;
14516
14517 SV
14518 *perl_exception,
14519 *reference;
14520
14521 PERL_UNUSED_VAR(ref);
14522 PERL_UNUSED_VAR(ix);
14523 exception=AcquireExceptionInfo();
14524 perl_exception=newSVpv("",0);
14525 number_images=0;
14526 package_info=(struct PackageInfo *) NULL;
14527 if (sv_isobject(ST(0)) == 0)
14528 {
14529 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14530 PackageName);
14531 goto PerlException;
14532 }
14533 reference=SvRV(ST(0));
14534 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14535 if (image == (Image *) NULL)
14536 {
14537 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14538 PackageName);
14539 goto PerlException;
14540 }
14541 package_info=ClonePackageInfo(info,exception);
14542 if (items == 2)
14543 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14544 else
14545 if (items > 2)
14546 for (i=2; i < items; i+=2)
14547 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14548 exception);
14549 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014550 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014551 scene=0;
14552 for (next=image; next; next=next->next)
14553 {
cristy151b66d2015-04-15 10:50:31 +000014554 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014555 next->scene=scene++;
14556 }
cristy68bd79a2015-02-25 12:23:36 +000014557 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014558 SetImageInfo(package_info->image_info,(unsigned int)
14559 GetImageListLength(image),exception);
14560 for (next=image; next; next=next->next)
14561 {
14562 (void) WriteImage(package_info->image_info,next,exception);
14563 number_images++;
14564 if (package_info->image_info->adjoin)
14565 break;
14566 }
14567
14568 PerlException:
14569 if (package_info != (struct PackageInfo *) NULL)
14570 DestroyPackageInfo(package_info);
14571 InheritPerlException(exception,perl_exception);
14572 exception=DestroyExceptionInfo(exception);
14573 sv_setiv(perl_exception,(IV) number_images);
14574 SvPOK_on(perl_exception);
14575 ST(0)=sv_2mortal(perl_exception);
14576 XSRETURN(1);
14577 }