blob: 7cabd5fb29a160dd8b97116365b5070d3754ba2a [file] [log] [blame]
cristy4a3ce0a2013-08-03 20:06:59 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% PPPP EEEEE RRRR L %
6% P P E R R L %
7% PPPP EEE RRRR L %
8% P E R R L %
9% P EEEEE R R LLLLL %
10% %
11% M M AAA GGGG IIIII CCCC K K %
12% MM MM A A G I C K K %
13% M M M AAAAA G GGG I C KKK %
14% M M A A G G I C K K %
15% M M A A GGGG IIIII CCCC K K %
16% %
17% %
18% Object-oriented Perl interface to ImageMagick %
19% %
20% Software Design %
21% Kyle Shorter %
cristyde984cd2013-12-01 14:49:27 +000022% Cristy %
cristy4a3ce0a2013-08-03 20:06:59 +000023% February 1997 %
24% %
25% %
Cristyf6ff9ea2016-12-05 09:53:35 -050026% Copyright 1999-2017 ImageMagick Studio LLC, a non-profit organization %
cristy4a3ce0a2013-08-03 20:06:59 +000027% dedicated to making software imaging solutions freely available. %
28% %
29% You may not use this file except in compliance with the License. You may %
30% obtain a copy of the License at %
31% %
32% http://www.imagemagick.org/script/license.php %
33% %
34% Unless required by applicable law or agreed to in writing, software %
35% distributed under the License is distributed on an "AS IS" BASIS, %
36% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
37% See the License for the specific language governing permissions and %
38% limitations under the License. %
39% %
40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41%
42% PerlMagick is an objected-oriented Perl interface to ImageMagick. Use
43% the module to read, manipulate, or write an image or image sequence from
44% within a Perl script. This makes PerlMagick suitable for Web CGI scripts.
45%
46*/
47
48/*
49 Include declarations.
50*/
51#if defined(__cplusplus) || defined(c_plusplus)
52extern "C" {
53#endif
54
55#define PERL_NO_GET_CONTEXT
dirk190cc1c2015-06-16 11:48:37 +000056#include <MagickCore/MagickCore.h>
cristy4a3ce0a2013-08-03 20:06:59 +000057#include "EXTERN.h"
58#include "perl.h"
59#include "XSUB.h"
60#include <math.h>
cristy4a3ce0a2013-08-03 20:06:59 +000061#undef tainted
62
63#if defined(__cplusplus) || defined(c_plusplus)
64}
65#endif
66
67/*
68 Define declarations.
69*/
70#ifndef aTHX_
71#define aTHX_
72#define pTHX_
73#define dTHX
74#endif
75#define DegreesToRadians(x) (MagickPI*(x)/180.0)
76#define EndOf(array) (&array[NumberOf(array)])
cristy3249b7b2014-02-09 21:43:14 +000077#define MagickPI 3.14159265358979323846264338327950288419716939937510
cristy4a3ce0a2013-08-03 20:06:59 +000078#define MaxArguments 33
79#ifndef na
80#define na PL_na
81#endif
82#define NumberOf(array) (sizeof(array)/sizeof(*array))
83#define PackageName "Image::Magick"
84#if PERL_VERSION <= 6
85#define PerlIO FILE
86#define PerlIO_importFILE(f, fl) (f)
87#define PerlIO_findFILE(f) NULL
88#endif
89#ifndef sv_undef
90#define sv_undef PL_sv_undef
91#endif
92
93#define AddImageToRegistry(sv,image) \
94{ \
95 if (magick_registry != (SplayTreeInfo *) NULL) \
96 { \
97 (void) AddValueToSplayTree(magick_registry,image,image); \
98 (sv)=newSViv(PTR2IV(image)); \
99 } \
100}
101
102#define DeleteImageFromRegistry(reference,image) \
103{ \
104 if (magick_registry != (SplayTreeInfo *) NULL) \
105 { \
106 if (GetImageReferenceCount(image) == 1) \
107 (void) DeleteNodeByValueFromSplayTree(magick_registry,image); \
108 image=DestroyImage(image); \
109 sv_setiv(reference,0); \
110 } \
111}
112
113#define InheritPerlException(exception,perl_exception) \
114{ \
115 char \
cristy151b66d2015-04-15 10:50:31 +0000116 message[MagickPathExtent]; \
cristy4a3ce0a2013-08-03 20:06:59 +0000117 \
118 if ((exception)->severity != UndefinedException) \
119 { \
cristy151b66d2015-04-15 10:50:31 +0000120 (void) FormatLocaleString(message,MagickPathExtent,"Exception %d: %s%s%s%s",\
cristy4a3ce0a2013-08-03 20:06:59 +0000121 (exception)->severity, (exception)->reason ? \
122 GetLocaleExceptionMessage((exception)->severity,(exception)->reason) : \
123 "Unknown", (exception)->description ? " (" : "", \
124 (exception)->description ? GetLocaleExceptionMessage( \
125 (exception)->severity,(exception)->description) : "", \
126 (exception)->description ? ")" : ""); \
127 if ((perl_exception) != (SV *) NULL) \
128 { \
129 if (SvCUR(perl_exception)) \
130 sv_catpv(perl_exception,"\n"); \
131 sv_catpv(perl_exception,message); \
132 } \
133 } \
134}
135
136#define ThrowPerlException(exception,severity,tag,reason) \
137 (void) ThrowMagickException(exception,GetMagickModule(),severity, \
138 tag,"`%s'",reason); \
139
140/*
141 Typedef and structure declarations.
142*/
143typedef enum
144{
145 ArrayReference = (~0),
146 RealReference = (~0)-1,
147 FileReference = (~0)-2,
148 ImageReference = (~0)-3,
149 IntegerReference = (~0)-4,
150 StringReference = (~0)-5
151} MagickReference;
152
153typedef struct _Arguments
154{
155 const char
156 *method;
157
158 ssize_t
159 type;
160} Arguments;
161
162struct ArgumentList
163{
164 ssize_t
165 integer_reference;
166
167 double
168 real_reference;
169
170 const char
171 *string_reference;
172
173 Image
174 *image_reference;
175
176 SV
177 *array_reference;
178
179 FILE
180 *file_reference;
181
182 size_t
183 length;
184};
185
186struct PackageInfo
187{
188 ImageInfo
189 *image_info;
190};
191
192typedef void
193 *Image__Magick; /* data type for the Image::Magick package */
194
195/*
196 Static declarations.
197*/
198static struct
199 Methods
200 {
201 const char
202 *name;
203
204 Arguments
205 arguments[MaxArguments];
206 } Methods[] =
207 {
208 { "Comment", { {"comment", StringReference} } },
209 { "Label", { {"label", StringReference} } },
210 { "AddNoise", { {"noise", MagickNoiseOptions}, {"attenuate", RealReference},
211 {"channel", MagickChannelOptions} } },
212 { "Colorize", { {"fill", StringReference}, {"blend", StringReference} } },
213 { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
214 {"height", IntegerReference}, {"fill", StringReference},
215 {"bordercolor", StringReference}, {"color", StringReference},
216 {"compose", MagickComposeOptions} } },
217 { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
218 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
219 { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
220 {"height", IntegerReference}, {"x", IntegerReference},
cristy260bd762014-08-15 12:46:34 +0000221 {"y", IntegerReference}, {"gravity", MagickGravityOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000222 { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
223 {"height", IntegerReference}, {"x", IntegerReference},
224 {"y", IntegerReference}, {"fuzz", StringReference},
225 {"gravity", MagickGravityOptions} } },
226 { "Despeckle", },
227 { "Edge", { {"radius", RealReference} } },
228 { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
229 {"sigma", RealReference} } },
230 { "Enhance", },
231 { "Flip", },
232 { "Flop", },
233 { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
234 {"height", IntegerReference}, {"inner", IntegerReference},
235 {"outer", IntegerReference}, {"fill", StringReference},
236 {"color", StringReference}, {"compose", MagickComposeOptions} } },
237 { "Implode", { {"amount", RealReference},
238 {"interpolate", MagickInterpolateOptions} } },
239 { "Magnify", },
240 { "MedianFilter", { {"geometry", StringReference},
241 {"width", IntegerReference}, {"height", IntegerReference},
242 {"channel", MagickChannelOptions} } },
243 { "Minify", },
244 { "OilPaint", { {"radius", RealReference}, {"sigma", RealReference} } },
245 { "ReduceNoise", { {"geometry", StringReference},
246 {"width", IntegerReference},{"height", IntegerReference},
247 {"channel", MagickChannelOptions} } },
248 { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
249 {"y", IntegerReference} } },
cristy83a28a02013-08-03 20:25:48 +0000250 { "Rotate", { {"degrees", RealReference},
cristy4a3ce0a2013-08-03 20:06:59 +0000251 {"background", StringReference} } },
252 { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
253 {"height", IntegerReference} } },
254 { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
255 {"height", IntegerReference} } },
256 { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
257 {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
258 { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
259 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
260 { "Shear", { {"geometry", StringReference}, {"x", RealReference},
261 {"y", RealReference}, { "fill", StringReference},
262 {"color", StringReference} } },
Cristye3319c12015-08-24 07:11:48 -0400263 { "Spread", { {"radius", RealReference},
Cristy3ca633e2016-02-13 12:49:01 -0500264 {"interpolate", MagickInterpolateOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000265 { "Swirl", { {"degrees", RealReference},
266 {"interpolate", MagickInterpolateOptions} } },
267 { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
268 {"height", IntegerReference}, {"filter", MagickFilterOptions},
269 {"support", StringReference } } },
270 { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
271 {"height", IntegerReference}, {"filter", MagickFilterOptions},
272 {"support", RealReference } } },
273 { "Annotate", { {"text", StringReference}, {"font", StringReference},
274 {"pointsize", RealReference}, {"density", StringReference},
275 {"undercolor", StringReference}, {"stroke", StringReference},
276 {"fill", StringReference}, {"geometry", StringReference},
277 {"sans", StringReference}, {"x", RealReference},
278 {"y", RealReference}, {"gravity", MagickGravityOptions},
279 {"translate", StringReference}, {"scale", StringReference},
280 {"rotate", RealReference}, {"skewX", RealReference},
281 {"skewY", RealReference}, {"strokewidth", RealReference},
282 {"antialias", MagickBooleanOptions}, {"family", StringReference},
283 {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
284 {"weight", IntegerReference}, {"align", MagickAlignOptions},
285 {"encoding", StringReference}, {"affine", ArrayReference},
286 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
287 {"tile", ImageReference}, {"kerning", RealReference},
288 {"interline-spacing", RealReference},
289 {"interword-spacing", RealReference},
290 {"direction", MagickDirectionOptions} } },
291 { "ColorFloodfill", { {"geometry", StringReference},
292 {"x", IntegerReference}, {"y", IntegerReference},
293 {"fill", StringReference}, {"bordercolor", StringReference},
294 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
295 { "Composite", { {"image", ImageReference},
296 {"compose", MagickComposeOptions}, {"geometry", StringReference},
297 {"x", IntegerReference}, {"y", IntegerReference},
298 {"gravity", MagickGravityOptions}, {"opacity", StringReference},
299 {"tile", MagickBooleanOptions}, {"rotate", RealReference},
300 {"color", StringReference}, {"mask", ImageReference},
301 {"channel", MagickChannelOptions},
302 {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
303 {"blend", StringReference}, {"crop-to-self", MagickBooleanOptions} } },
304 { "Contrast", { {"sharpen", MagickBooleanOptions} } },
305 { "CycleColormap", { {"display", IntegerReference} } },
306 { "Draw", { {"primitive", MagickPrimitiveOptions},
307 {"points", StringReference}, {"method", MagickMethodOptions},
308 {"stroke", StringReference}, {"fill", StringReference},
309 {"strokewidth", RealReference}, {"font", StringReference},
310 {"bordercolor", StringReference}, {"x", RealReference},
311 {"y", RealReference}, {"translate", StringReference},
312 {"scale", StringReference}, {"rotate", RealReference},
313 {"skewX", RealReference}, {"skewY", RealReference},
314 {"tile", ImageReference}, {"pointsize", RealReference},
315 {"antialias", MagickBooleanOptions}, {"density", StringReference},
316 {"linewidth", RealReference}, {"affine", ArrayReference},
317 {"stroke-dashoffset", RealReference},
318 {"stroke-dasharray", ArrayReference},
319 {"interpolate", MagickInterpolateOptions},
320 {"origin", StringReference}, {"text", StringReference},
321 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
322 {"vector-graphics", StringReference}, {"kerning", RealReference},
323 {"interline-spacing", RealReference},
324 {"interword-spacing", RealReference},
325 {"direction", MagickDirectionOptions} } },
326 { "Equalize", { {"channel", MagickChannelOptions} } },
327 { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
328 {"red", RealReference}, {"green", RealReference},
329 {"blue", RealReference} } },
330 { "Map", { {"image", ImageReference},
331 {"dither-method", MagickDitherOptions} } },
332 { "MatteFloodfill", { {"geometry", StringReference},
333 {"x", IntegerReference}, {"y", IntegerReference},
334 {"opacity", StringReference}, {"bordercolor", StringReference},
335 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
336 { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
337 {"saturation", RealReference}, {"whiteness", RealReference},
338 {"brightness", RealReference}, {"lightness", RealReference},
339 {"blackness", RealReference} } },
340 { "Negate", { {"gray", MagickBooleanOptions},
341 {"channel", MagickChannelOptions} } },
342 { "Normalize", { {"channel", MagickChannelOptions} } },
343 { "NumberColors", },
344 { "Opaque", { {"color", StringReference}, {"fill", StringReference},
345 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
346 {"invert", MagickBooleanOptions} } },
347 { "Quantize", { {"colors", IntegerReference},
348 {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
349 {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
350 {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
351 {"dither-method", MagickDitherOptions} } },
352 { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
353 {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
354 { "Segment", { {"geometry", StringReference},
355 {"cluster-threshold", RealReference},
356 {"smoothing-threshold", RealReference},
357 {"colorspace", MagickColorspaceOptions},
358 {"verbose", MagickBooleanOptions} } },
359 { "Signature", },
360 { "Solarize", { {"geometry", StringReference},
361 {"threshold", StringReference} } },
362 { "Sync", },
363 { "Texture", { {"texture", ImageReference} } },
364 { "Evaluate", { {"value", RealReference},
365 {"operator", MagickEvaluateOptions},
366 {"channel", MagickChannelOptions} } },
367 { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
368 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
369 { "Threshold", { {"threshold", StringReference},
370 {"channel", MagickChannelOptions} } },
371 { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
372 {"sigma", RealReference} } },
373 { "Trim", { {"fuzz", StringReference} } },
374 { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
375 {"wavelength", RealReference},
376 {"interpolate", MagickInterpolateOptions} } },
377 { "Separate", { {"channel", MagickChannelOptions} } },
378 { "Condense", },
379 { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
380 {"y", IntegerReference} } },
381 { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
382 { "Deconstruct", },
383 { "GaussianBlur", { {"geometry", StringReference},
384 {"radius", RealReference}, {"sigma", RealReference},
385 {"channel", MagickChannelOptions} } },
386 { "Convolve", { {"coefficients", ArrayReference},
387 {"channel", MagickChannelOptions}, {"bias", StringReference},
388 {"kernel", StringReference} } },
389 { "Profile", { {"name", StringReference}, {"profile", StringReference},
390 { "rendering-intent", MagickIntentOptions},
391 { "black-point-compensation", MagickBooleanOptions} } },
392 { "UnsharpMask", { {"geometry", StringReference},
393 {"radius", RealReference}, {"sigma", RealReference},
394 {"gain", RealReference}, {"threshold", RealReference},
395 {"channel", MagickChannelOptions} } },
396 { "MotionBlur", { {"geometry", StringReference},
397 {"radius", RealReference}, {"sigma", RealReference},
398 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
399 { "OrderedDither", { {"threshold", StringReference},
400 {"channel", MagickChannelOptions} } },
401 { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
402 {"height", IntegerReference} } },
403 { "Level", { {"levels", StringReference}, {"black-point", RealReference},
404 {"white-point", RealReference}, {"gamma", RealReference},
405 {"channel", MagickChannelOptions}, {"level", StringReference} } },
406 { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
407 { "AffineTransform", { {"affine", ArrayReference},
408 {"translate", StringReference}, {"scale", StringReference},
409 {"rotate", RealReference}, {"skewX", RealReference},
410 {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
411 {"background", StringReference} } },
412 { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
413 { "AdaptiveThreshold", { {"geometry", StringReference},
414 {"width", IntegerReference}, {"height", IntegerReference} } },
415 { "Resample", { {"density", StringReference}, {"x", RealReference},
416 {"y", RealReference}, {"filter", MagickFilterOptions},
417 {"support", RealReference } } },
418 { "Describe", { {"file", FileReference} } },
419 { "BlackThreshold", { {"threshold", StringReference},
420 {"channel", MagickChannelOptions} } },
421 { "WhiteThreshold", { {"threshold", StringReference},
422 {"channel", MagickChannelOptions} } },
cristy60c73c02014-03-25 12:09:58 +0000423 { "RotationalBlur", { {"geometry", StringReference},
424 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000425 { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
426 {"height", IntegerReference} } },
427 { "Strip", },
428 { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
429 { "Channel", { {"channel", MagickChannelOptions} } },
430 { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
431 {"height", IntegerReference}, {"x", IntegerReference},
432 {"y", IntegerReference}, {"fuzz", StringReference},
433 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
434 { "Posterize", { {"levels", IntegerReference},
435 {"dither", MagickBooleanOptions} } },
436 { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
437 {"sigma", RealReference}, {"x", IntegerReference},
438 {"y", IntegerReference} } },
439 { "Identify", { {"file", FileReference}, {"features", StringReference},
440 {"unique", MagickBooleanOptions} } },
441 { "SepiaTone", { {"threshold", RealReference} } },
442 { "SigmoidalContrast", { {"geometry", StringReference},
443 {"contrast", RealReference}, {"mid-point", RealReference},
444 {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
445 { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
446 {"height", IntegerReference}, {"x", IntegerReference},
447 {"y", IntegerReference}, {"fuzz", StringReference},
448 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
449 { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
450 {"sigma", RealReference}, {"x", IntegerReference},
451 {"y", IntegerReference}, {"background", StringReference} } },
452 { "ContrastStretch", { {"levels", StringReference},
453 {"black-point", RealReference},{"white-point", RealReference},
454 {"channel", MagickChannelOptions} } },
455 { "Sans0", },
456 { "Sans1", },
457 { "AdaptiveSharpen", { {"geometry", StringReference},
458 {"radius", RealReference}, {"sigma", RealReference},
459 {"bias", RealReference}, {"channel", MagickChannelOptions} } },
460 { "Transpose", },
461 { "Transverse", },
462 { "AutoOrient", },
463 { "AdaptiveBlur", { {"geometry", StringReference},
464 {"radius", RealReference}, {"sigma", RealReference},
465 {"channel", MagickChannelOptions} } },
466 { "Sketch", { {"geometry", StringReference},
467 {"radius", RealReference}, {"sigma", RealReference},
468 {"angle", RealReference} } },
469 { "UniqueColors", },
470 { "AdaptiveResize", { {"geometry", StringReference},
471 {"width", IntegerReference}, {"height", IntegerReference},
472 {"filter", MagickFilterOptions}, {"support", StringReference },
473 {"blur", RealReference } } },
474 { "ClipMask", { {"mask", ImageReference} } },
475 { "LinearStretch", { {"levels", StringReference},
476 {"black-point", RealReference},{"white-point", RealReference} } },
477 { "ColorMatrix", { {"matrix", ArrayReference} } },
478 { "Mask", { {"mask", ImageReference} } },
479 { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
480 {"font", StringReference}, {"stroke", StringReference},
481 {"fill", StringReference}, {"strokewidth", RealReference},
482 {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
483 {"background", StringReference},
484 {"interpolate", MagickInterpolateOptions} } },
485 { "FloodfillPaint", { {"geometry", StringReference},
486 {"x", IntegerReference}, {"y", IntegerReference},
487 {"fill", StringReference}, {"bordercolor", StringReference},
488 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
489 {"invert", MagickBooleanOptions} } },
490 { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
491 {"virtual-pixel", MagickVirtualPixelOptions},
492 {"best-fit", MagickBooleanOptions} } },
493 { "Clut", { {"image", ImageReference},
494 {"interpolate", MagickInterpolateOptions},
495 {"channel", MagickChannelOptions} } },
496 { "LiquidRescale", { {"geometry", StringReference},
497 {"width", IntegerReference}, {"height", IntegerReference},
498 {"delta-x", RealReference}, {"rigidity", RealReference } } },
499 { "Encipher", { {"passphrase", StringReference} } },
500 { "Decipher", { {"passphrase", StringReference} } },
501 { "Deskew", { {"geometry", StringReference},
502 {"threshold", StringReference} } },
503 { "Remap", { {"image", ImageReference},
504 {"dither-method", MagickDitherOptions} } },
505 { "SparseColor", { {"points", ArrayReference},
506 {"method", MagickSparseColorOptions},
507 {"virtual-pixel", MagickVirtualPixelOptions},
508 {"channel", MagickChannelOptions} } },
509 { "Function", { {"parameters", ArrayReference},
510 {"function", MagickFunctionOptions},
511 {"virtual-pixel", MagickVirtualPixelOptions} } },
512 { "SelectiveBlur", { {"geometry", StringReference},
513 {"radius", RealReference}, {"sigma", RealReference},
514 {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
515 { "HaldClut", { {"image", ImageReference},
516 {"channel", MagickChannelOptions} } },
517 { "BlueShift", { {"factor", StringReference} } },
518 { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
519 { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
520 { "ColorDecisionList", {
521 {"color-correction-collection", StringReference} } },
522 { "AutoGamma", { {"channel", MagickChannelOptions} } },
523 { "AutoLevel", { {"channel", MagickChannelOptions} } },
524 { "LevelColors", { {"invert", MagickBooleanOptions},
525 {"black-point", StringReference}, {"white-point", StringReference},
526 {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
527 { "Clamp", { {"channel", MagickChannelOptions} } },
528 { "BrightnessContrast", { {"levels", StringReference},
529 {"brightness", RealReference},{"contrast", RealReference},
530 {"channel", MagickChannelOptions} } },
531 { "Morphology", { {"kernel", StringReference},
532 {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
533 {"iterations", IntegerReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000534 { "Mode", { {"geometry", StringReference},
535 {"width", IntegerReference},{"height", IntegerReference},
536 {"channel", MagickChannelOptions} } },
537 { "Statistic", { {"geometry", StringReference},
538 {"width", IntegerReference},{"height", IntegerReference},
539 {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
540 { "Perceptible", { {"epsilon", RealReference},
541 {"channel", MagickChannelOptions} } },
542 { "Poly", { {"terms", ArrayReference},
543 {"channel", MagickChannelOptions} } },
544 { "Grayscale", { {"method", MagickNoiseOptions} } },
cristy4ceadb82014-03-29 15:30:43 +0000545 { "CannyEdge", { {"geometry", StringReference},
546 {"radius", RealReference}, {"sigma", RealReference},
cristycfe7bf02014-04-04 15:31:52 +0000547 {"lower-percent", RealReference}, {"upper-percent", RealReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000548 { "HoughLine", { {"geometry", StringReference},
cristy4e215022014-04-19 18:02:35 +0000549 {"width", IntegerReference}, {"height", IntegerReference},
550 {"threshold", IntegerReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000551 { "MeanShift", { {"geometry", StringReference},
552 {"width", IntegerReference}, {"height", IntegerReference},
cristy1309fc32014-04-26 18:48:37 +0000553 {"distance", RealReference} } },
cristy3b207f82014-09-27 14:21:20 +0000554 { "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
555 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
Cristy2ca0e9a2016-01-01 08:36:14 -0500556 { "ConnectedComponents", { {"connectivity", IntegerReference} } },
cristyf3a724a2015-06-25 13:02:53 +0000557 { "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
558 {"width", IntegerReference}, {"height", IntegerReference},
559 {"x", IntegerReference}, {"y", IntegerReference},
560 {"gravity", MagickGravityOptions}, {"offset", StringReference},
561 {"dx", IntegerReference}, {"dy", IntegerReference} } },
Cristy5488c982016-02-13 14:07:50 -0500562 { "Color", { {"color", StringReference} } },
Cristyc1759412016-02-27 12:17:58 -0500563 { "WaveletDenoise", { {"geometry", StringReference},
564 {"threshold", RealReference}, {"softness", RealReference},
Cristy2d830ed2016-02-21 10:54:16 -0500565 {"channel", MagickChannelOptions} } },
Cristy99a57162016-12-05 11:47:57 -0500566 { "Colorspace", { {"colorspace", MagickColorspaceOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000567 };
568
569static SplayTreeInfo
570 *magick_registry = (SplayTreeInfo *) NULL;
571
572/*
573 Forward declarations.
574*/
575static Image
576 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
577
578static ssize_t
579 strEQcase(const char *,const char *);
580
581/*
582%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
583% %
584% %
585% %
586% C l o n e P a c k a g e I n f o %
587% %
588% %
589% %
590%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
591%
592% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
593% a new one.
594%
595% The format of the ClonePackageInfo routine is:
596%
597% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
598% exception)
599%
600% A description of each parameter follows:
601%
602% o info: a structure of type info.
603%
604% o exception: Return any errors or warnings in this structure.
605%
606*/
607static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
608 ExceptionInfo *exception)
609{
610 struct PackageInfo
611 *clone_info;
612
613 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
614 if (clone_info == (struct PackageInfo *) NULL)
615 {
616 ThrowPerlException(exception,ResourceLimitError,
617 "UnableToClonePackageInfo",PackageName);
618 return((struct PackageInfo *) NULL);
619 }
620 if (info == (struct PackageInfo *) NULL)
621 {
622 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
623 return(clone_info);
624 }
625 *clone_info=(*info);
626 clone_info->image_info=CloneImageInfo(info->image_info);
627 return(clone_info);
628}
629
630/*
631%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
632% %
633% %
634% %
635% c o n s t a n t %
636% %
637% %
638% %
639%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
640%
641% constant() returns a double value for the specified name.
642%
643% The format of the constant routine is:
644%
645% double constant(char *name,ssize_t sans)
646%
647% A description of each parameter follows:
648%
649% o value: Method constant returns a double value for the specified name.
650%
651% o name: The name of the constant.
652%
653% o sans: This integer value is not used.
654%
655*/
656static double constant(char *name,ssize_t sans)
657{
658 (void) sans;
659 errno=0;
660 switch (*name)
661 {
662 case 'B':
663 {
664 if (strEQ(name,"BlobError"))
665 return(BlobError);
666 if (strEQ(name,"BlobWarning"))
667 return(BlobWarning);
668 break;
669 }
670 case 'C':
671 {
672 if (strEQ(name,"CacheError"))
673 return(CacheError);
674 if (strEQ(name,"CacheWarning"))
675 return(CacheWarning);
676 if (strEQ(name,"CoderError"))
677 return(CoderError);
678 if (strEQ(name,"CoderWarning"))
679 return(CoderWarning);
680 if (strEQ(name,"ConfigureError"))
681 return(ConfigureError);
682 if (strEQ(name,"ConfigureWarning"))
683 return(ConfigureWarning);
684 if (strEQ(name,"CorruptImageError"))
685 return(CorruptImageError);
686 if (strEQ(name,"CorruptImageWarning"))
687 return(CorruptImageWarning);
688 break;
689 }
690 case 'D':
691 {
692 if (strEQ(name,"DelegateError"))
693 return(DelegateError);
694 if (strEQ(name,"DelegateWarning"))
695 return(DelegateWarning);
696 if (strEQ(name,"DrawError"))
697 return(DrawError);
698 if (strEQ(name,"DrawWarning"))
699 return(DrawWarning);
700 break;
701 }
702 case 'E':
703 {
704 if (strEQ(name,"ErrorException"))
705 return(ErrorException);
706 if (strEQ(name,"ExceptionError"))
707 return(CoderError);
708 if (strEQ(name,"ExceptionWarning"))
709 return(CoderWarning);
710 break;
711 }
712 case 'F':
713 {
714 if (strEQ(name,"FatalErrorException"))
715 return(FatalErrorException);
716 if (strEQ(name,"FileOpenError"))
717 return(FileOpenError);
718 if (strEQ(name,"FileOpenWarning"))
719 return(FileOpenWarning);
720 break;
721 }
722 case 'I':
723 {
724 if (strEQ(name,"ImageError"))
725 return(ImageError);
726 if (strEQ(name,"ImageWarning"))
727 return(ImageWarning);
728 break;
729 }
730 case 'M':
731 {
732 if (strEQ(name,"MaxRGB"))
733 return(QuantumRange);
734 if (strEQ(name,"MissingDelegateError"))
735 return(MissingDelegateError);
736 if (strEQ(name,"MissingDelegateWarning"))
737 return(MissingDelegateWarning);
738 if (strEQ(name,"ModuleError"))
739 return(ModuleError);
740 if (strEQ(name,"ModuleWarning"))
741 return(ModuleWarning);
742 break;
743 }
744 case 'O':
745 {
746 if (strEQ(name,"Opaque"))
747 return(OpaqueAlpha);
748 if (strEQ(name,"OptionError"))
749 return(OptionError);
750 if (strEQ(name,"OptionWarning"))
751 return(OptionWarning);
752 break;
753 }
754 case 'Q':
755 {
756 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
757 return(MAGICKCORE_QUANTUM_DEPTH);
758 if (strEQ(name,"QuantumDepth"))
759 return(MAGICKCORE_QUANTUM_DEPTH);
760 if (strEQ(name,"QuantumRange"))
761 return(QuantumRange);
762 break;
763 }
764 case 'R':
765 {
766 if (strEQ(name,"ResourceLimitError"))
767 return(ResourceLimitError);
768 if (strEQ(name,"ResourceLimitWarning"))
769 return(ResourceLimitWarning);
770 if (strEQ(name,"RegistryError"))
771 return(RegistryError);
772 if (strEQ(name,"RegistryWarning"))
773 return(RegistryWarning);
774 break;
775 }
776 case 'S':
777 {
778 if (strEQ(name,"StreamError"))
779 return(StreamError);
780 if (strEQ(name,"StreamWarning"))
781 return(StreamWarning);
782 if (strEQ(name,"Success"))
783 return(0);
784 break;
785 }
786 case 'T':
787 {
788 if (strEQ(name,"Transparent"))
789 return(TransparentAlpha);
790 if (strEQ(name,"TypeError"))
791 return(TypeError);
792 if (strEQ(name,"TypeWarning"))
793 return(TypeWarning);
794 break;
795 }
796 case 'W':
797 {
798 if (strEQ(name,"WarningException"))
799 return(WarningException);
800 break;
801 }
802 case 'X':
803 {
804 if (strEQ(name,"XServerError"))
805 return(XServerError);
806 if (strEQ(name,"XServerWarning"))
807 return(XServerWarning);
808 break;
809 }
810 }
811 errno=EINVAL;
812 return(0);
813}
814
815/*
816%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
817% %
818% %
819% %
820% D e s t r o y P a c k a g e I n f o %
821% %
822% %
823% %
824%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
825%
826% Method DestroyPackageInfo frees a previously created info structure.
827%
828% The format of the DestroyPackageInfo routine is:
829%
830% DestroyPackageInfo(struct PackageInfo *info)
831%
832% A description of each parameter follows:
833%
834% o info: a structure of type info.
835%
836*/
837static void DestroyPackageInfo(struct PackageInfo *info)
838{
839 info->image_info=DestroyImageInfo(info->image_info);
840 info=(struct PackageInfo *) RelinquishMagickMemory(info);
841}
842
843/*
844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
845% %
846% %
847% %
848% G e t L i s t %
849% %
850% %
851% %
852%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
853%
854% Method GetList is recursively called by SetupList to traverse the
855% Image__Magick reference. If building an reference_vector (see SetupList),
856% *current is the current position in *reference_vector and *last is the final
857% entry in *reference_vector.
858%
859% The format of the GetList routine is:
860%
861% GetList(info)
862%
863% A description of each parameter follows:
864%
865% o info: a structure of type info.
866%
867*/
868static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
869 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
870{
871 Image
872 *image;
873
874 if (reference == (SV *) NULL)
875 return(NULL);
876 switch (SvTYPE(reference))
877 {
878 case SVt_PVAV:
879 {
880 AV
881 *av;
882
883 Image
884 *head,
885 *previous;
886
887 register ssize_t
888 i;
889
890 ssize_t
891 n;
892
893 /*
894 Array of images.
895 */
896 previous=(Image *) NULL;
897 head=(Image *) NULL;
898 av=(AV *) reference;
899 n=av_len(av);
900 for (i=0; i <= n; i++)
901 {
902 SV
903 **rv;
904
905 rv=av_fetch(av,i,0);
906 if (rv && *rv && sv_isobject(*rv))
907 {
908 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
909 exception);
910 if (image == (Image *) NULL)
911 continue;
912 if (image == previous)
913 {
914 image=CloneImage(image,0,0,MagickTrue,exception);
915 if (image == (Image *) NULL)
916 return(NULL);
917 }
918 image->previous=previous;
919 *(previous ? &previous->next : &head)=image;
920 for (previous=image; previous->next; previous=previous->next) ;
921 }
922 }
923 return(head);
924 }
925 case SVt_PVMG:
926 {
927 /*
928 Blessed scalar, one image.
929 */
930 image=INT2PTR(Image *,SvIV(reference));
931 if (image == (Image *) NULL)
932 return(NULL);
933 image->previous=(Image *) NULL;
934 image->next=(Image *) NULL;
935 if (reference_vector)
936 {
937 if (*current == *last)
938 {
939 *last+=256;
940 if (*reference_vector == (SV **) NULL)
941 *reference_vector=(SV **) AcquireQuantumMemory(*last,
942 sizeof(*reference_vector));
943 else
944 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
945 *last,sizeof(*reference_vector));
946 }
947 if (*reference_vector == (SV **) NULL)
948 {
949 ThrowPerlException(exception,ResourceLimitError,
950 "MemoryAllocationFailed",PackageName);
951 return((Image *) NULL);
952 }
953 (*reference_vector)[*current]=reference;
954 (*reference_vector)[++(*current)]=NULL;
955 }
956 return(image);
957 }
958 default:
959 break;
960 }
961 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
962 (double) SvTYPE(reference));
963 return((Image *) NULL);
964}
965
966/*
967%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
968% %
969% %
970% %
971% G e t P a c k a g e I n f o %
972% %
973% %
974% %
975%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
976%
977% Method GetPackageInfo looks up or creates an info structure for the given
978% Image__Magick reference. If it does create a new one, the information in
979% package_info is used to initialize it.
980%
981% The format of the GetPackageInfo routine is:
982%
983% struct PackageInfo *GetPackageInfo(void *reference,
984% struct PackageInfo *package_info,ExceptionInfo *exception)
985%
986% A description of each parameter follows:
987%
988% o info: a structure of type info.
989%
990% o exception: Return any errors or warnings in this structure.
991%
992*/
993static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
994 struct PackageInfo *package_info,ExceptionInfo *exception)
995{
996 char
cristy151b66d2015-04-15 10:50:31 +0000997 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +0000998
999 struct PackageInfo
1000 *clone_info;
1001
1002 SV
1003 *sv;
1004
cristy151b66d2015-04-15 10:50:31 +00001005 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00001006 PackageName,XS_VERSION,reference);
1007 sv=perl_get_sv(message,(TRUE | 0x02));
1008 if (sv == (SV *) NULL)
1009 {
1010 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1011 message);
1012 return(package_info);
1013 }
1014 if (SvREFCNT(sv) == 0)
1015 (void) SvREFCNT_inc(sv);
1016 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1017 return(clone_info);
1018 clone_info=ClonePackageInfo(package_info,exception);
1019 sv_setiv(sv,PTR2IV(clone_info));
1020 return(clone_info);
1021}
1022
1023/*
1024%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1025% %
1026% %
1027% %
1028% S e t A t t r i b u t e %
1029% %
1030% %
1031% %
1032%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1033%
1034% SetAttribute() sets the attribute to the value in sval. This can change
1035% either or both of image or info.
1036%
1037% The format of the SetAttribute routine is:
1038%
1039% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1040% SV *sval,ExceptionInfo *exception)
1041%
1042% A description of each parameter follows:
1043%
1044% o list: a list of strings.
1045%
1046% o string: a character string.
1047%
1048*/
1049
1050static double SiPrefixToDoubleInterval(const char *string,const double interval)
1051{
1052 char
1053 *q;
1054
1055 double
1056 value;
1057
1058 value=InterpretSiPrefixValue(string,&q);
1059 if (*q == '%')
1060 value*=interval/100.0;
1061 return(value);
1062}
1063
1064static inline double StringToDouble(const char *string,char **sentinal)
1065{
1066 return(InterpretLocaleValue(string,sentinal));
1067}
1068
1069static double StringToDoubleInterval(const char *string,const double interval)
1070{
1071 char
1072 *q;
1073
1074 double
1075 value;
1076
1077 value=InterpretLocaleValue(string,&q);
1078 if (*q == '%')
1079 value*=interval/100.0;
1080 return(value);
1081}
1082
1083static inline ssize_t StringToLong(const char *value)
1084{
1085 return(strtol(value,(char **) NULL,10));
1086}
1087
1088static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1089 const char *attribute,SV *sval,ExceptionInfo *exception)
1090{
1091 GeometryInfo
1092 geometry_info;
1093
1094 long
1095 x,
1096 y;
1097
1098 PixelInfo
1099 pixel;
1100
1101 MagickStatusType
1102 flags;
1103
1104 PixelInfo
1105 *color,
1106 target_color;
1107
1108 ssize_t
1109 sp;
1110
1111 switch (*attribute)
1112 {
1113 case 'A':
1114 case 'a':
1115 {
1116 if (LocaleCompare(attribute,"adjoin") == 0)
1117 {
1118 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1119 SvPV(sval,na)) : SvIV(sval);
1120 if (sp < 0)
1121 {
1122 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1123 SvPV(sval,na));
1124 break;
1125 }
1126 if (info)
1127 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1128 break;
1129 }
1130 if (LocaleCompare(attribute,"alpha") == 0)
1131 {
1132 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1133 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1134 if (sp < 0)
1135 {
1136 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1137 SvPV(sval,na));
1138 break;
1139 }
1140 for ( ; image; image=image->next)
1141 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1142 exception);
1143 break;
1144 }
1145 if (LocaleCompare(attribute,"antialias") == 0)
1146 {
1147 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1148 SvPV(sval,na)) : SvIV(sval);
1149 if (sp < 0)
1150 {
1151 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1152 SvPV(sval,na));
1153 break;
1154 }
1155 if (info)
1156 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1157 break;
1158 }
1159 if (LocaleCompare(attribute,"area-limit") == 0)
1160 {
1161 MagickSizeType
1162 limit;
1163
1164 limit=MagickResourceInfinity;
1165 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1166 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1167 100.0);
1168 (void) SetMagickResourceLimit(AreaResource,limit);
1169 break;
1170 }
1171 if (LocaleCompare(attribute,"attenuate") == 0)
1172 {
1173 if (info)
1174 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1175 break;
1176 }
1177 if (LocaleCompare(attribute,"authenticate") == 0)
1178 {
1179 if (info)
1180 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1181 break;
1182 }
1183 if (info)
1184 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1185 for ( ; image; image=image->next)
1186 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1187 break;
1188 }
1189 case 'B':
1190 case 'b':
1191 {
1192 if (LocaleCompare(attribute,"background") == 0)
1193 {
1194 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1195 exception);
1196 if (info)
1197 info->image_info->background_color=target_color;
1198 for ( ; image; image=image->next)
1199 image->background_color=target_color;
1200 break;
1201 }
1202 if (LocaleCompare(attribute,"blue-primary") == 0)
1203 {
1204 for ( ; image; image=image->next)
1205 {
1206 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1207 image->chromaticity.blue_primary.x=geometry_info.rho;
1208 image->chromaticity.blue_primary.y=geometry_info.sigma;
1209 if ((flags & SigmaValue) == 0)
1210 image->chromaticity.blue_primary.y=
1211 image->chromaticity.blue_primary.x;
1212 }
1213 break;
1214 }
1215 if (LocaleCompare(attribute,"bordercolor") == 0)
1216 {
1217 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1218 exception);
1219 if (info)
1220 info->image_info->border_color=target_color;
1221 for ( ; image; image=image->next)
1222 image->border_color=target_color;
1223 break;
1224 }
1225 if (info)
1226 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1227 for ( ; image; image=image->next)
1228 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1229 break;
1230 }
1231 case 'C':
1232 case 'c':
1233 {
1234 if (LocaleCompare(attribute,"cache-threshold") == 0)
1235 {
1236 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1237 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1238 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1239 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1240 break;
1241 }
1242 if (LocaleCompare(attribute,"clip-mask") == 0)
1243 {
1244 Image
1245 *clip_mask;
1246
1247 clip_mask=(Image *) NULL;
1248 if (SvPOK(sval))
1249 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1250 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001251 SetImageMask(image,ReadPixelMask,clip_mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001252 break;
1253 }
1254 if (LocaleNCompare(attribute,"colormap",8) == 0)
1255 {
1256 for ( ; image; image=image->next)
1257 {
1258 int
1259 items;
1260
1261 long
1262 i;
1263
1264 if (image->storage_class == DirectClass)
1265 continue;
1266 i=0;
1267 items=sscanf(attribute,"%*[^[][%ld",&i);
1268 (void) items;
1269 if (i > (ssize_t) image->colors)
1270 i%=image->colors;
1271 if ((strchr(SvPV(sval,na),',') == 0) ||
1272 (strchr(SvPV(sval,na),')') != 0))
1273 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1274 image->colormap+i,exception);
1275 else
1276 {
1277 color=image->colormap+i;
1278 pixel.red=color->red;
1279 pixel.green=color->green;
1280 pixel.blue=color->blue;
1281 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1282 pixel.red=geometry_info.rho;
1283 pixel.green=geometry_info.sigma;
1284 pixel.blue=geometry_info.xi;
1285 color->red=ClampToQuantum(pixel.red);
1286 color->green=ClampToQuantum(pixel.green);
1287 color->blue=ClampToQuantum(pixel.blue);
1288 }
1289 }
1290 break;
1291 }
1292 if (LocaleCompare(attribute,"colorspace") == 0)
1293 {
1294 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1295 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1296 if (sp < 0)
1297 {
1298 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1299 SvPV(sval,na));
1300 break;
1301 }
1302 for ( ; image; image=image->next)
Cristy59262d92016-12-05 15:21:50 -05001303 (void) SetImageColorspace(image,(ColorspaceType) sp,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001304 break;
1305 }
1306 if (LocaleCompare(attribute,"comment") == 0)
1307 {
1308 for ( ; image; image=image->next)
1309 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1310 info ? info->image_info : (ImageInfo *) NULL,image,
1311 SvPV(sval,na),exception),exception);
1312 break;
1313 }
1314 if (LocaleCompare(attribute,"compression") == 0)
1315 {
1316 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1317 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1318 if (sp < 0)
1319 {
1320 ThrowPerlException(exception,OptionError,
1321 "UnrecognizedImageCompression",SvPV(sval,na));
1322 break;
1323 }
1324 if (info)
1325 info->image_info->compression=(CompressionType) sp;
1326 for ( ; image; image=image->next)
1327 image->compression=(CompressionType) sp;
1328 break;
1329 }
1330 if (info)
1331 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1332 for ( ; image; image=image->next)
1333 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1334 break;
1335 }
1336 case 'D':
1337 case 'd':
1338 {
1339 if (LocaleCompare(attribute,"debug") == 0)
1340 {
1341 SetLogEventMask(SvPV(sval,na));
1342 break;
1343 }
1344 if (LocaleCompare(attribute,"delay") == 0)
1345 {
1346 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1347 for ( ; image; image=image->next)
1348 {
1349 image->delay=(size_t) floor(geometry_info.rho+0.5);
1350 if ((flags & SigmaValue) != 0)
1351 image->ticks_per_second=(ssize_t)
1352 floor(geometry_info.sigma+0.5);
1353 }
1354 break;
1355 }
1356 if (LocaleCompare(attribute,"disk-limit") == 0)
1357 {
1358 MagickSizeType
1359 limit;
1360
1361 limit=MagickResourceInfinity;
1362 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1363 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1364 100.0);
1365 (void) SetMagickResourceLimit(DiskResource,limit);
1366 break;
1367 }
1368 if (LocaleCompare(attribute,"density") == 0)
1369 {
1370 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1371 {
1372 ThrowPerlException(exception,OptionError,"MissingGeometry",
1373 SvPV(sval,na));
1374 break;
1375 }
1376 if (info)
1377 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1378 for ( ; image; image=image->next)
1379 {
1380 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1381 image->resolution.x=geometry_info.rho;
1382 image->resolution.y=geometry_info.sigma;
1383 if ((flags & SigmaValue) == 0)
1384 image->resolution.y=image->resolution.x;
1385 }
1386 break;
1387 }
1388 if (LocaleCompare(attribute,"depth") == 0)
1389 {
1390 if (info)
1391 info->image_info->depth=SvIV(sval);
1392 for ( ; image; image=image->next)
1393 (void) SetImageDepth(image,SvIV(sval),exception);
1394 break;
1395 }
1396 if (LocaleCompare(attribute,"dispose") == 0)
1397 {
1398 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1399 SvPV(sval,na)) : SvIV(sval);
1400 if (sp < 0)
1401 {
1402 ThrowPerlException(exception,OptionError,
1403 "UnrecognizedDisposeMethod",SvPV(sval,na));
1404 break;
1405 }
1406 for ( ; image; image=image->next)
1407 image->dispose=(DisposeType) sp;
1408 break;
1409 }
1410 if (LocaleCompare(attribute,"dither") == 0)
1411 {
1412 if (info)
1413 {
1414 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1415 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1416 if (sp < 0)
1417 {
1418 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1419 SvPV(sval,na));
1420 break;
1421 }
1422 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1423 }
1424 break;
1425 }
1426 if (LocaleCompare(attribute,"display") == 0)
1427 {
1428 display:
1429 if (info)
1430 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1431 break;
1432 }
1433 if (info)
1434 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1435 for ( ; image; image=image->next)
1436 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1437 break;
1438 }
1439 case 'E':
1440 case 'e':
1441 {
1442 if (LocaleCompare(attribute,"endian") == 0)
1443 {
1444 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1445 SvPV(sval,na)) : SvIV(sval);
1446 if (sp < 0)
1447 {
1448 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1449 SvPV(sval,na));
1450 break;
1451 }
1452 if (info)
1453 info->image_info->endian=(EndianType) sp;
1454 for ( ; image; image=image->next)
1455 image->endian=(EndianType) sp;
1456 break;
1457 }
1458 if (LocaleCompare(attribute,"extract") == 0)
1459 {
1460 /*
1461 Set image extract geometry.
1462 */
1463 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1464 break;
1465 }
1466 if (info)
1467 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1468 for ( ; image; image=image->next)
1469 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1470 break;
1471 }
1472 case 'F':
1473 case 'f':
1474 {
1475 if (LocaleCompare(attribute,"filename") == 0)
1476 {
1477 if (info)
1478 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001479 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001480 for ( ; image; image=image->next)
1481 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001482 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001483 break;
1484 }
1485 if (LocaleCompare(attribute,"file") == 0)
1486 {
1487 FILE
1488 *file;
1489
1490 PerlIO
1491 *io_info;
1492
1493 if (info == (struct PackageInfo *) NULL)
1494 break;
1495 io_info=IoIFP(sv_2io(sval));
1496 if (io_info == (PerlIO *) NULL)
1497 {
1498 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1499 PackageName);
1500 break;
1501 }
1502 file=PerlIO_findFILE(io_info);
1503 if (file == (FILE *) NULL)
1504 {
1505 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1506 PackageName);
1507 break;
1508 }
1509 SetImageInfoFile(info->image_info,file);
1510 break;
1511 }
1512 if (LocaleCompare(attribute,"fill") == 0)
1513 {
1514 if (info)
1515 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1516 break;
1517 }
1518 if (LocaleCompare(attribute,"font") == 0)
1519 {
1520 if (info)
1521 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1522 break;
1523 }
1524 if (LocaleCompare(attribute,"foreground") == 0)
1525 break;
1526 if (LocaleCompare(attribute,"fuzz") == 0)
1527 {
1528 if (info)
1529 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1530 QuantumRange+1.0);
1531 for ( ; image; image=image->next)
1532 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1533 QuantumRange+1.0);
1534 break;
1535 }
1536 if (info)
1537 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1538 for ( ; image; image=image->next)
1539 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1540 break;
1541 }
1542 case 'G':
1543 case 'g':
1544 {
1545 if (LocaleCompare(attribute,"gamma") == 0)
1546 {
1547 for ( ; image; image=image->next)
1548 image->gamma=SvNV(sval);
1549 break;
1550 }
1551 if (LocaleCompare(attribute,"gravity") == 0)
1552 {
1553 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1554 SvPV(sval,na)) : SvIV(sval);
1555 if (sp < 0)
1556 {
1557 ThrowPerlException(exception,OptionError,
1558 "UnrecognizedGravityType",SvPV(sval,na));
1559 break;
1560 }
1561 if (info)
1562 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1563 for ( ; image; image=image->next)
1564 image->gravity=(GravityType) sp;
1565 break;
1566 }
1567 if (LocaleCompare(attribute,"green-primary") == 0)
1568 {
1569 for ( ; image; image=image->next)
1570 {
1571 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1572 image->chromaticity.green_primary.x=geometry_info.rho;
1573 image->chromaticity.green_primary.y=geometry_info.sigma;
1574 if ((flags & SigmaValue) == 0)
1575 image->chromaticity.green_primary.y=
1576 image->chromaticity.green_primary.x;
1577 }
1578 break;
1579 }
1580 if (info)
1581 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1582 for ( ; image; image=image->next)
1583 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1584 break;
1585 }
1586 case 'I':
1587 case 'i':
1588 {
1589 if (LocaleNCompare(attribute,"index",5) == 0)
1590 {
1591 int
1592 items;
1593
1594 long
1595 index;
1596
1597 register Quantum
1598 *q;
1599
1600 CacheView
1601 *image_view;
1602
1603 for ( ; image; image=image->next)
1604 {
1605 if (image->storage_class != PseudoClass)
1606 continue;
1607 x=0;
1608 y=0;
1609 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1610 (void) items;
1611 image_view=AcquireAuthenticCacheView(image,exception);
1612 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1613 if (q != (Quantum *) NULL)
1614 {
1615 items=sscanf(SvPV(sval,na),"%ld",&index);
1616 if ((index >= 0) && (index < (ssize_t) image->colors))
1617 SetPixelIndex(image,index,q);
1618 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1619 }
1620 image_view=DestroyCacheView(image_view);
1621 }
1622 break;
1623 }
1624 if (LocaleCompare(attribute,"iterations") == 0)
1625 {
1626 iterations:
1627 for ( ; image; image=image->next)
1628 image->iterations=SvIV(sval);
1629 break;
1630 }
1631 if (LocaleCompare(attribute,"interlace") == 0)
1632 {
1633 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1634 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1635 if (sp < 0)
1636 {
1637 ThrowPerlException(exception,OptionError,
1638 "UnrecognizedInterlaceType",SvPV(sval,na));
1639 break;
1640 }
1641 if (info)
1642 info->image_info->interlace=(InterlaceType) sp;
1643 for ( ; image; image=image->next)
1644 image->interlace=(InterlaceType) sp;
1645 break;
1646 }
1647 if (info)
1648 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1649 for ( ; image; image=image->next)
1650 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1651 break;
1652 }
1653 case 'L':
1654 case 'l':
1655 {
1656 if (LocaleCompare(attribute,"label") == 0)
1657 {
1658 for ( ; image; image=image->next)
1659 (void) SetImageProperty(image,"label",InterpretImageProperties(
1660 info ? info->image_info : (ImageInfo *) NULL,image,
1661 SvPV(sval,na),exception),exception);
1662 break;
1663 }
1664 if (LocaleCompare(attribute,"loop") == 0)
1665 goto iterations;
1666 if (info)
1667 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1668 for ( ; image; image=image->next)
1669 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1670 break;
1671 }
1672 case 'M':
1673 case 'm':
1674 {
1675 if (LocaleCompare(attribute,"magick") == 0)
1676 {
1677 if (info)
cristy151b66d2015-04-15 10:50:31 +00001678 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00001679 "%s:",SvPV(sval,na));
1680 for ( ; image; image=image->next)
cristy151b66d2015-04-15 10:50:31 +00001681 (void) CopyMagickString(image->magick,SvPV(sval,na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001682 break;
1683 }
1684 if (LocaleCompare(attribute,"map-limit") == 0)
1685 {
1686 MagickSizeType
1687 limit;
1688
1689 limit=MagickResourceInfinity;
1690 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1691 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1692 100.0);
1693 (void) SetMagickResourceLimit(MapResource,limit);
1694 break;
1695 }
1696 if (LocaleCompare(attribute,"mask") == 0)
1697 {
1698 Image
1699 *mask;
1700
1701 mask=(Image *) NULL;
1702 if (SvPOK(sval))
1703 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1704 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001705 SetImageMask(image,ReadPixelMask,mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001706 break;
1707 }
1708 if (LocaleCompare(attribute,"mattecolor") == 0)
1709 {
1710 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1711 exception);
1712 if (info)
Cristy8645e042016-02-03 16:35:29 -05001713 info->image_info->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001714 for ( ; image; image=image->next)
Cristy8645e042016-02-03 16:35:29 -05001715 image->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001716 break;
1717 }
1718 if (LocaleCompare(attribute,"matte") == 0)
1719 {
1720 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1721 SvPV(sval,na)) : SvIV(sval);
1722 if (sp < 0)
1723 {
1724 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1725 SvPV(sval,na));
1726 break;
1727 }
1728 for ( ; image; image=image->next)
1729 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1730 break;
1731 }
1732 if (LocaleCompare(attribute,"memory-limit") == 0)
1733 {
1734 MagickSizeType
1735 limit;
1736
1737 limit=MagickResourceInfinity;
1738 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1739 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1740 100.0);
1741 (void) SetMagickResourceLimit(MemoryResource,limit);
1742 break;
1743 }
1744 if (LocaleCompare(attribute,"monochrome") == 0)
1745 {
1746 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1747 SvPV(sval,na)) : SvIV(sval);
1748 if (sp < 0)
1749 {
1750 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1751 SvPV(sval,na));
1752 break;
1753 }
1754 if (info)
1755 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1756 for ( ; image; image=image->next)
1757 (void) SetImageType(image,BilevelType,exception);
1758 break;
1759 }
1760 if (info)
1761 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1762 for ( ; image; image=image->next)
1763 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1764 break;
1765 }
1766 case 'O':
1767 case 'o':
1768 {
1769 if (LocaleCompare(attribute,"option") == 0)
1770 {
1771 if (info)
1772 DefineImageOption(info->image_info,SvPV(sval,na));
1773 break;
1774 }
1775 if (LocaleCompare(attribute,"orientation") == 0)
1776 {
1777 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1778 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1779 if (sp < 0)
1780 {
1781 ThrowPerlException(exception,OptionError,
1782 "UnrecognizedOrientationType",SvPV(sval,na));
1783 break;
1784 }
1785 if (info)
1786 info->image_info->orientation=(OrientationType) sp;
1787 for ( ; image; image=image->next)
1788 image->orientation=(OrientationType) sp;
1789 break;
1790 }
1791 if (info)
1792 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1793 for ( ; image; image=image->next)
1794 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1795 break;
1796 }
1797 case 'P':
1798 case 'p':
1799 {
1800 if (LocaleCompare(attribute,"page") == 0)
1801 {
1802 char
1803 *geometry;
1804
1805 geometry=GetPageGeometry(SvPV(sval,na));
1806 if (info)
1807 (void) CloneString(&info->image_info->page,geometry);
1808 for ( ; image; image=image->next)
1809 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1810 geometry=(char *) RelinquishMagickMemory(geometry);
1811 break;
1812 }
1813 if (LocaleNCompare(attribute,"pixel",5) == 0)
1814 {
1815 int
1816 items;
1817
1818 PixelInfo
1819 pixel;
1820
1821 register Quantum
1822 *q;
1823
1824 CacheView
1825 *image_view;
1826
1827 for ( ; image; image=image->next)
1828 {
1829 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1830 break;
1831 x=0;
1832 y=0;
1833 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1834 (void) items;
1835 image_view=AcquireVirtualCacheView(image,exception);
1836 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1837 if (q != (Quantum *) NULL)
1838 {
1839 if ((strchr(SvPV(sval,na),',') == 0) ||
1840 (strchr(SvPV(sval,na),')') != 0))
1841 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1842 &pixel,exception);
1843 else
1844 {
1845 GetPixelInfo(image,&pixel);
1846 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1847 pixel.red=geometry_info.rho;
1848 if ((flags & SigmaValue) != 0)
1849 pixel.green=geometry_info.sigma;
1850 if ((flags & XiValue) != 0)
1851 pixel.blue=geometry_info.xi;
1852 if ((flags & PsiValue) != 0)
1853 pixel.alpha=geometry_info.psi;
1854 if ((flags & ChiValue) != 0)
1855 pixel.black=geometry_info.chi;
1856 }
1857 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1858 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1859 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1860 if (image->colorspace == CMYKColorspace)
1861 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1862 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1863 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1864 }
1865 image_view=DestroyCacheView(image_view);
1866 }
1867 break;
1868 }
1869 if (LocaleCompare(attribute,"pointsize") == 0)
1870 {
1871 if (info)
1872 {
1873 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1874 info->image_info->pointsize=geometry_info.rho;
1875 }
1876 break;
1877 }
cristy4a3ce0a2013-08-03 20:06:59 +00001878 if (info)
1879 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1880 for ( ; image; image=image->next)
1881 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1882 break;
1883 }
1884 case 'Q':
1885 case 'q':
1886 {
1887 if (LocaleCompare(attribute,"quality") == 0)
1888 {
1889 if (info)
1890 info->image_info->quality=SvIV(sval);
1891 for ( ; image; image=image->next)
1892 image->quality=SvIV(sval);
1893 break;
1894 }
1895 if (info)
1896 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1897 for ( ; image; image=image->next)
1898 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1899 break;
1900 }
1901 case 'R':
1902 case 'r':
1903 {
cristyc0fe4752015-07-27 18:02:39 +00001904 if (LocaleCompare(attribute,"read-mask") == 0)
1905 {
1906 Image
1907 *mask;
1908
1909 mask=(Image *) NULL;
1910 if (SvPOK(sval))
1911 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1912 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001913 SetImageMask(image,ReadPixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00001914 break;
1915 }
cristy4a3ce0a2013-08-03 20:06:59 +00001916 if (LocaleCompare(attribute,"red-primary") == 0)
1917 {
1918 for ( ; image; image=image->next)
1919 {
1920 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1921 image->chromaticity.red_primary.x=geometry_info.rho;
1922 image->chromaticity.red_primary.y=geometry_info.sigma;
1923 if ((flags & SigmaValue) == 0)
1924 image->chromaticity.red_primary.y=
1925 image->chromaticity.red_primary.x;
1926 }
1927 break;
1928 }
1929 if (LocaleCompare(attribute,"render") == 0)
1930 {
1931 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1932 SvPV(sval,na)) : SvIV(sval);
1933 if (sp < 0)
1934 {
1935 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1936 SvPV(sval,na));
1937 break;
1938 }
1939 for ( ; image; image=image->next)
1940 image->rendering_intent=(RenderingIntent) sp;
1941 break;
1942 }
1943 if (LocaleCompare(attribute,"repage") == 0)
1944 {
1945 RectangleInfo
1946 geometry;
1947
1948 for ( ; image; image=image->next)
1949 {
1950 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1951 if ((flags & WidthValue) != 0)
1952 {
1953 if ((flags & HeightValue) == 0)
1954 geometry.height=geometry.width;
1955 image->page.width=geometry.width;
1956 image->page.height=geometry.height;
1957 }
1958 if ((flags & AspectValue) != 0)
1959 {
1960 if ((flags & XValue) != 0)
1961 image->page.x+=geometry.x;
1962 if ((flags & YValue) != 0)
1963 image->page.y+=geometry.y;
1964 }
1965 else
1966 {
1967 if ((flags & XValue) != 0)
1968 {
1969 image->page.x=geometry.x;
1970 if (((flags & WidthValue) != 0) && (geometry.x > 0))
1971 image->page.width=image->columns+geometry.x;
1972 }
1973 if ((flags & YValue) != 0)
1974 {
1975 image->page.y=geometry.y;
1976 if (((flags & HeightValue) != 0) && (geometry.y > 0))
1977 image->page.height=image->rows+geometry.y;
1978 }
1979 }
1980 }
1981 break;
1982 }
1983 if (info)
1984 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1985 for ( ; image; image=image->next)
1986 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1987 break;
1988 }
1989 case 'S':
1990 case 's':
1991 {
1992 if (LocaleCompare(attribute,"sampling-factor") == 0)
1993 {
1994 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1995 {
1996 ThrowPerlException(exception,OptionError,"MissingGeometry",
1997 SvPV(sval,na));
1998 break;
1999 }
2000 if (info)
2001 (void) CloneString(&info->image_info->sampling_factor,
2002 SvPV(sval,na));
2003 break;
2004 }
2005 if (LocaleCompare(attribute,"scene") == 0)
2006 {
2007 for ( ; image; image=image->next)
2008 image->scene=SvIV(sval);
2009 break;
2010 }
2011 if (LocaleCompare(attribute,"server") == 0)
2012 goto display;
2013 if (LocaleCompare(attribute,"size") == 0)
2014 {
2015 if (info)
2016 {
2017 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2018 {
2019 ThrowPerlException(exception,OptionError,"MissingGeometry",
2020 SvPV(sval,na));
2021 break;
2022 }
2023 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2024 }
2025 break;
2026 }
2027 if (LocaleCompare(attribute,"stroke") == 0)
2028 {
2029 if (info)
2030 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2031 break;
2032 }
2033 if (info)
2034 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2035 for ( ; image; image=image->next)
2036 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2037 break;
2038 }
2039 case 'T':
2040 case 't':
2041 {
2042 if (LocaleCompare(attribute,"texture") == 0)
2043 {
2044 if (info)
2045 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2046 break;
2047 }
2048 if (LocaleCompare(attribute,"thread-limit") == 0)
2049 {
2050 MagickSizeType
2051 limit;
2052
2053 limit=MagickResourceInfinity;
2054 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2055 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2056 100.0);
2057 (void) SetMagickResourceLimit(ThreadResource,limit);
2058 break;
2059 }
2060 if (LocaleCompare(attribute,"tile-offset") == 0)
2061 {
2062 char
2063 *geometry;
2064
2065 geometry=GetPageGeometry(SvPV(sval,na));
2066 if (info)
2067 (void) CloneString(&info->image_info->page,geometry);
2068 for ( ; image; image=image->next)
2069 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2070 exception);
2071 geometry=(char *) RelinquishMagickMemory(geometry);
2072 break;
2073 }
2074 if (LocaleCompare(attribute,"time-limit") == 0)
2075 {
2076 MagickSizeType
2077 limit;
2078
2079 limit=MagickResourceInfinity;
2080 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2081 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2082 100.0);
2083 (void) SetMagickResourceLimit(TimeResource,limit);
2084 break;
2085 }
2086 if (LocaleCompare(attribute,"transparent-color") == 0)
2087 {
2088 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2089 exception);
2090 if (info)
2091 info->image_info->transparent_color=target_color;
2092 for ( ; image; image=image->next)
2093 image->transparent_color=target_color;
2094 break;
2095 }
2096 if (LocaleCompare(attribute,"type") == 0)
2097 {
2098 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2099 SvPV(sval,na)) : SvIV(sval);
2100 if (sp < 0)
2101 {
2102 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2103 SvPV(sval,na));
2104 break;
2105 }
2106 if (info)
2107 info->image_info->type=(ImageType) sp;
2108 for ( ; image; image=image->next)
2109 SetImageType(image,(ImageType) sp,exception);
2110 break;
2111 }
2112 if (info)
2113 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2114 for ( ; image; image=image->next)
2115 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2116 break;
2117 }
2118 case 'U':
2119 case 'u':
2120 {
2121 if (LocaleCompare(attribute,"units") == 0)
2122 {
2123 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2124 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2125 if (sp < 0)
2126 {
2127 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2128 SvPV(sval,na));
2129 break;
2130 }
2131 if (info)
2132 info->image_info->units=(ResolutionType) sp;
2133 for ( ; image; image=image->next)
2134 {
2135 ResolutionType
2136 units;
2137
2138 units=(ResolutionType) sp;
2139 if (image->units != units)
2140 switch (image->units)
2141 {
2142 case UndefinedResolution:
2143 case PixelsPerInchResolution:
2144 {
2145 if (units == PixelsPerCentimeterResolution)
2146 {
2147 image->resolution.x*=2.54;
2148 image->resolution.y*=2.54;
2149 }
2150 break;
2151 }
2152 case PixelsPerCentimeterResolution:
2153 {
2154 if (units == PixelsPerInchResolution)
2155 {
2156 image->resolution.x/=2.54;
2157 image->resolution.y/=2.54;
2158 }
2159 break;
2160 }
2161 }
2162 image->units=units;
2163 }
2164 break;
2165 }
2166 if (info)
2167 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2168 for ( ; image; image=image->next)
2169 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2170 break;
2171 }
2172 case 'V':
2173 case 'v':
2174 {
2175 if (LocaleCompare(attribute,"verbose") == 0)
2176 {
2177 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2178 SvPV(sval,na)) : SvIV(sval);
2179 if (sp < 0)
2180 {
2181 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2182 SvPV(sval,na));
2183 break;
2184 }
2185 if (info)
2186 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2187 break;
2188 }
cristy4a3ce0a2013-08-03 20:06:59 +00002189 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2190 {
2191 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2192 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2193 if (sp < 0)
2194 {
2195 ThrowPerlException(exception,OptionError,
2196 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2197 break;
2198 }
2199 for ( ; image; image=image->next)
2200 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2201 break;
2202 }
2203 if (info)
2204 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2205 for ( ; image; image=image->next)
2206 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2207 break;
2208 }
2209 case 'W':
2210 case 'w':
2211 {
2212 if (LocaleCompare(attribute,"white-point") == 0)
2213 {
2214 for ( ; image; image=image->next)
2215 {
2216 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2217 image->chromaticity.white_point.x=geometry_info.rho;
2218 image->chromaticity.white_point.y=geometry_info.sigma;
2219 if ((flags & SigmaValue) == 0)
2220 image->chromaticity.white_point.y=
2221 image->chromaticity.white_point.x;
2222 }
2223 break;
2224 }
cristyc0fe4752015-07-27 18:02:39 +00002225 if (LocaleCompare(attribute,"write-mask") == 0)
2226 {
2227 Image
2228 *mask;
2229
2230 mask=(Image *) NULL;
2231 if (SvPOK(sval))
2232 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2233 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002234 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002235 break;
2236 }
cristy4a3ce0a2013-08-03 20:06:59 +00002237 if (info)
2238 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2239 for ( ; image; image=image->next)
2240 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2241 break;
2242 }
2243 default:
2244 {
2245 if (info)
2246 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2247 for ( ; image; image=image->next)
2248 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2249 break;
2250 }
2251 }
2252}
2253
2254/*
2255%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2256% %
2257% %
2258% %
2259% S e t u p L i s t %
2260% %
2261% %
2262% %
2263%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2264%
2265% Method SetupList returns the list of all the images linked by their
2266% image->next and image->previous link lists for use with ImageMagick. If
2267% info is non-NULL, an info structure is returned in *info. If
2268% reference_vector is non-NULL,an array of SV* are returned in
2269% *reference_vector. Reference_vector is used when the images are going to be
2270% replaced with new Image*'s.
2271%
2272% The format of the SetupList routine is:
2273%
2274% Image *SetupList(SV *reference,struct PackageInfo **info,
2275% SV ***reference_vector,ExceptionInfo *exception)
2276%
2277% A description of each parameter follows:
2278%
2279% o list: a list of strings.
2280%
2281% o string: a character string.
2282%
2283% o exception: Return any errors or warnings in this structure.
2284%
2285*/
2286static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2287 SV ***reference_vector,ExceptionInfo *exception)
2288{
2289 Image
2290 *image;
2291
2292 ssize_t
2293 current,
2294 last;
2295
2296 if (reference_vector)
2297 *reference_vector=NULL;
2298 if (info)
2299 *info=NULL;
2300 current=0;
2301 last=0;
2302 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2303 if (info && (SvTYPE(reference) == SVt_PVAV))
2304 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2305 exception);
2306 return(image);
2307}
2308
2309/*
2310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2311% %
2312% %
2313% %
2314% s t r E Q c a s e %
2315% %
2316% %
2317% %
2318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2319%
2320% strEQcase() compares two strings and returns 0 if they are the
2321% same or if the second string runs out first. The comparison is case
2322% insensitive.
2323%
2324% The format of the strEQcase routine is:
2325%
2326% ssize_t strEQcase(const char *p,const char *q)
2327%
2328% A description of each parameter follows:
2329%
2330% o p: a character string.
2331%
2332% o q: a character string.
2333%
2334%
2335*/
2336static ssize_t strEQcase(const char *p,const char *q)
2337{
2338 char
2339 c;
2340
2341 register ssize_t
2342 i;
2343
2344 for (i=0 ; (c=(*q)) != 0; i++)
2345 {
2346 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2347 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2348 return(0);
2349 p++;
2350 q++;
2351 }
2352 return(((*q == 0) && (*p == 0)) ? i : 0);
2353}
2354
2355/*
2356%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2357% %
2358% %
2359% %
2360% I m a g e : : M a g i c k %
2361% %
2362% %
2363% %
2364%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2365%
2366%
2367*/
2368MODULE = Image::Magick PACKAGE = Image::Magick
2369
2370PROTOTYPES: ENABLE
2371
2372BOOT:
2373 MagickCoreGenesis("PerlMagick",MagickFalse);
2374 SetWarningHandler(NULL);
2375 SetErrorHandler(NULL);
2376 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2377 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2378
2379void
2380UNLOAD()
2381 PPCODE:
2382 {
2383 if (magick_registry != (SplayTreeInfo *) NULL)
2384 magick_registry=DestroySplayTree(magick_registry);
2385 MagickCoreTerminus();
2386 }
2387
2388double
2389constant(name,argument)
2390 char *name
2391 ssize_t argument
2392
2393#
2394###############################################################################
2395# #
2396# #
2397# #
2398# A n i m a t e #
2399# #
2400# #
2401# #
2402###############################################################################
2403#
2404#
2405void
2406Animate(ref,...)
2407 Image::Magick ref=NO_INIT
2408 ALIAS:
2409 AnimateImage = 1
2410 animate = 2
2411 animateimage = 3
2412 PPCODE:
2413 {
2414 ExceptionInfo
2415 *exception;
2416
2417 Image
2418 *image;
2419
2420 register ssize_t
2421 i;
2422
2423 struct PackageInfo
2424 *info,
2425 *package_info;
2426
2427 SV
2428 *perl_exception,
2429 *reference;
2430
2431 PERL_UNUSED_VAR(ref);
2432 PERL_UNUSED_VAR(ix);
2433 exception=AcquireExceptionInfo();
2434 perl_exception=newSVpv("",0);
2435 package_info=(struct PackageInfo *) NULL;
2436 if (sv_isobject(ST(0)) == 0)
2437 {
2438 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2439 PackageName);
2440 goto PerlException;
2441 }
2442 reference=SvRV(ST(0));
2443 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2444 if (image == (Image *) NULL)
2445 {
2446 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2447 PackageName);
2448 goto PerlException;
2449 }
2450 package_info=ClonePackageInfo(info,exception);
2451 if (items == 2)
2452 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2453 else
2454 if (items > 2)
2455 for (i=2; i < items; i+=2)
2456 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2457 exception);
2458 (void) AnimateImages(package_info->image_info,image,exception);
2459 (void) CatchImageException(image);
2460
2461 PerlException:
2462 if (package_info != (struct PackageInfo *) NULL)
2463 DestroyPackageInfo(package_info);
2464 InheritPerlException(exception,perl_exception);
2465 exception=DestroyExceptionInfo(exception);
2466 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2467 SvPOK_on(perl_exception);
2468 ST(0)=sv_2mortal(perl_exception);
2469 XSRETURN(1);
2470 }
2471
2472#
2473###############################################################################
2474# #
2475# #
2476# #
2477# A p p e n d #
2478# #
2479# #
2480# #
2481###############################################################################
2482#
2483#
2484void
2485Append(ref,...)
2486 Image::Magick ref=NO_INIT
2487 ALIAS:
2488 AppendImage = 1
2489 append = 2
2490 appendimage = 3
2491 PPCODE:
2492 {
2493 AV
2494 *av;
2495
2496 char
2497 *attribute;
2498
2499 ExceptionInfo
2500 *exception;
2501
2502 HV
2503 *hv;
2504
2505 Image
2506 *image;
2507
2508 register ssize_t
2509 i;
2510
2511 ssize_t
2512 stack;
2513
2514 struct PackageInfo
2515 *info;
2516
2517 SV
2518 *av_reference,
2519 *perl_exception,
2520 *reference,
2521 *rv,
2522 *sv;
2523
2524 PERL_UNUSED_VAR(ref);
2525 PERL_UNUSED_VAR(ix);
2526 exception=AcquireExceptionInfo();
2527 perl_exception=newSVpv("",0);
2528 sv=NULL;
2529 attribute=NULL;
2530 av=NULL;
2531 if (sv_isobject(ST(0)) == 0)
2532 {
2533 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2534 PackageName);
2535 goto PerlException;
2536 }
2537 reference=SvRV(ST(0));
2538 hv=SvSTASH(reference);
2539 av=newAV();
2540 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2541 SvREFCNT_dec(av);
2542 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2543 if (image == (Image *) NULL)
2544 {
2545 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2546 PackageName);
2547 goto PerlException;
2548 }
2549 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2550 /*
2551 Get options.
2552 */
2553 stack=MagickTrue;
2554 for (i=2; i < items; i+=2)
2555 {
2556 attribute=(char *) SvPV(ST(i-1),na);
2557 switch (*attribute)
2558 {
2559 case 'S':
2560 case 's':
2561 {
2562 if (LocaleCompare(attribute,"stack") == 0)
2563 {
2564 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2565 SvPV(ST(i),na));
2566 if (stack < 0)
2567 {
2568 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2569 SvPV(ST(i),na));
2570 return;
2571 }
2572 break;
2573 }
2574 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2575 attribute);
2576 break;
2577 }
2578 default:
2579 {
2580 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2581 attribute);
2582 break;
2583 }
2584 }
2585 }
2586 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2587 if (image == (Image *) NULL)
2588 goto PerlException;
2589 for ( ; image; image=image->next)
2590 {
2591 AddImageToRegistry(sv,image);
2592 rv=newRV(sv);
2593 av_push(av,sv_bless(rv,hv));
2594 SvREFCNT_dec(sv);
2595 }
2596 exception=DestroyExceptionInfo(exception);
2597 ST(0)=av_reference;
2598 SvREFCNT_dec(perl_exception);
2599 XSRETURN(1);
2600
2601 PerlException:
2602 InheritPerlException(exception,perl_exception);
2603 exception=DestroyExceptionInfo(exception);
2604 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2605 SvPOK_on(perl_exception);
2606 ST(0)=sv_2mortal(perl_exception);
2607 XSRETURN(1);
2608 }
2609
2610#
2611###############################################################################
2612# #
2613# #
2614# #
2615# A v e r a g e #
2616# #
2617# #
2618# #
2619###############################################################################
2620#
2621#
2622void
2623Average(ref)
2624 Image::Magick ref=NO_INIT
2625 ALIAS:
2626 AverageImage = 1
2627 average = 2
2628 averageimage = 3
2629 PPCODE:
2630 {
2631 AV
2632 *av;
2633
2634 char
2635 *p;
2636
2637 ExceptionInfo
2638 *exception;
2639
2640 HV
2641 *hv;
2642
2643 Image
2644 *image;
2645
2646 struct PackageInfo
2647 *info;
2648
2649 SV
2650 *perl_exception,
2651 *reference,
2652 *rv,
2653 *sv;
2654
2655 PERL_UNUSED_VAR(ref);
2656 PERL_UNUSED_VAR(ix);
2657 exception=AcquireExceptionInfo();
2658 perl_exception=newSVpv("",0);
2659 sv=NULL;
2660 if (sv_isobject(ST(0)) == 0)
2661 {
2662 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2663 PackageName);
2664 goto PerlException;
2665 }
2666 reference=SvRV(ST(0));
2667 hv=SvSTASH(reference);
2668 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2669 if (image == (Image *) NULL)
2670 {
2671 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2672 PackageName);
2673 goto PerlException;
2674 }
2675 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2676 if (image == (Image *) NULL)
2677 goto PerlException;
2678 /*
2679 Create blessed Perl array for the returned image.
2680 */
2681 av=newAV();
2682 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2683 SvREFCNT_dec(av);
2684 AddImageToRegistry(sv,image);
2685 rv=newRV(sv);
2686 av_push(av,sv_bless(rv,hv));
2687 SvREFCNT_dec(sv);
2688 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002689 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2690 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002691 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2692 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002693 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002694 SetImageInfo(info->image_info,0,exception);
2695 exception=DestroyExceptionInfo(exception);
2696 SvREFCNT_dec(perl_exception);
2697 XSRETURN(1);
2698
2699 PerlException:
2700 InheritPerlException(exception,perl_exception);
2701 exception=DestroyExceptionInfo(exception);
2702 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2703 SvPOK_on(perl_exception);
2704 ST(0)=sv_2mortal(perl_exception);
2705 XSRETURN(1);
2706 }
2707
2708#
2709###############################################################################
2710# #
2711# #
2712# #
2713# B l o b T o I m a g e #
2714# #
2715# #
2716# #
2717###############################################################################
2718#
2719#
2720void
2721BlobToImage(ref,...)
2722 Image::Magick ref=NO_INIT
2723 ALIAS:
2724 BlobToImage = 1
2725 blobtoimage = 2
2726 blobto = 3
2727 PPCODE:
2728 {
2729 AV
2730 *av;
2731
2732 char
2733 **keep,
2734 **list;
2735
2736 ExceptionInfo
2737 *exception;
2738
2739 HV
2740 *hv;
2741
2742 Image
2743 *image;
2744
2745 register char
2746 **p;
2747
2748 register ssize_t
2749 i;
2750
2751 ssize_t
2752 ac,
2753 n,
2754 number_images;
2755
2756 STRLEN
2757 *length;
2758
2759 struct PackageInfo
2760 *info;
2761
2762 SV
2763 *perl_exception,
2764 *reference,
2765 *rv,
2766 *sv;
2767
2768 PERL_UNUSED_VAR(ref);
2769 PERL_UNUSED_VAR(ix);
2770 exception=AcquireExceptionInfo();
2771 perl_exception=newSVpv("",0);
2772 sv=NULL;
2773 number_images=0;
2774 ac=(items < 2) ? 1 : items-1;
2775 length=(STRLEN *) NULL;
2776 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2777 if (list == (char **) NULL)
2778 {
2779 ThrowPerlException(exception,ResourceLimitError,
2780 "MemoryAllocationFailed",PackageName);
2781 goto PerlException;
2782 }
2783 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2784 if (length == (STRLEN *) NULL)
2785 {
2786 ThrowPerlException(exception,ResourceLimitError,
2787 "MemoryAllocationFailed",PackageName);
2788 goto PerlException;
2789 }
2790 if (sv_isobject(ST(0)) == 0)
2791 {
2792 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2793 PackageName);
2794 goto PerlException;
2795 }
2796 reference=SvRV(ST(0));
2797 hv=SvSTASH(reference);
2798 if (SvTYPE(reference) != SVt_PVAV)
2799 {
2800 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2801 PackageName);
2802 goto PerlException;
2803 }
2804 av=(AV *) reference;
2805 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2806 exception);
2807 n=1;
2808 if (items <= 1)
2809 {
2810 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2811 goto PerlException;
2812 }
2813 for (n=0, i=0; i < ac; i++)
2814 {
2815 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2816 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2817 {
2818 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2819 continue;
2820 }
2821 n++;
2822 }
2823 list[n]=(char *) NULL;
2824 keep=list;
2825 for (i=number_images=0; i < n; i++)
2826 {
2827 image=BlobToImage(info->image_info,list[i],length[i],exception);
2828 if (image == (Image *) NULL)
2829 break;
2830 for ( ; image; image=image->next)
2831 {
2832 AddImageToRegistry(sv,image);
2833 rv=newRV(sv);
2834 av_push(av,sv_bless(rv,hv));
2835 SvREFCNT_dec(sv);
2836 number_images++;
2837 }
2838 }
2839 /*
2840 Free resources.
2841 */
2842 for (i=0; i < n; i++)
2843 if (list[i] != (char *) NULL)
2844 for (p=keep; list[i] != *p++; )
2845 if (*p == (char *) NULL)
2846 {
2847 list[i]=(char *) RelinquishMagickMemory(list[i]);
2848 break;
2849 }
2850
2851 PerlException:
2852 if (list)
2853 list=(char **) RelinquishMagickMemory(list);
2854 if (length)
2855 length=(STRLEN *) RelinquishMagickMemory(length);
2856 InheritPerlException(exception,perl_exception);
2857 exception=DestroyExceptionInfo(exception);
2858 sv_setiv(perl_exception,(IV) number_images);
2859 SvPOK_on(perl_exception);
2860 ST(0)=sv_2mortal(perl_exception);
2861 XSRETURN(1);
2862 }
2863
2864#
2865###############################################################################
2866# #
2867# #
2868# #
2869# C h a n n e l F x #
2870# #
2871# #
2872# #
2873###############################################################################
2874#
2875#
2876void
2877ChannelFx(ref,...)
2878 Image::Magick ref=NO_INIT
2879 ALIAS:
2880 ChannelFxImage = 1
2881 channelfx = 2
2882 channelfximage = 3
2883 PPCODE:
2884 {
2885 AV
2886 *av;
2887
2888 char
2889 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002890 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002891
2892 ChannelType
2893 channel,
2894 channel_mask;
2895
2896 ExceptionInfo
2897 *exception;
2898
2899 HV
2900 *hv;
2901
2902 Image
2903 *image;
2904
2905 register ssize_t
2906 i;
2907
2908 struct PackageInfo
2909 *info;
2910
2911 SV
2912 *av_reference,
2913 *perl_exception,
2914 *reference,
2915 *rv,
2916 *sv;
2917
2918 PERL_UNUSED_VAR(ref);
2919 PERL_UNUSED_VAR(ix);
2920 exception=AcquireExceptionInfo();
2921 perl_exception=newSVpv("",0);
2922 sv=NULL;
2923 attribute=NULL;
2924 av=NULL;
2925 if (sv_isobject(ST(0)) == 0)
2926 {
2927 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2928 PackageName);
2929 goto PerlException;
2930 }
2931 reference=SvRV(ST(0));
2932 hv=SvSTASH(reference);
2933 av=newAV();
2934 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2935 SvREFCNT_dec(av);
2936 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2937 if (image == (Image *) NULL)
2938 {
2939 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2940 PackageName);
2941 goto PerlException;
2942 }
2943 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2944 /*
2945 Get options.
2946 */
2947 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00002948 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002949 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00002950 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002951 else
2952 for (i=2; i < items; i+=2)
2953 {
2954 attribute=(char *) SvPV(ST(i-1),na);
2955 switch (*attribute)
2956 {
2957 case 'C':
2958 case 'c':
2959 {
2960 if (LocaleCompare(attribute,"channel") == 0)
2961 {
2962 ssize_t
2963 option;
2964
2965 option=ParseChannelOption(SvPV(ST(i),na));
2966 if (option < 0)
2967 {
2968 ThrowPerlException(exception,OptionError,
2969 "UnrecognizedType",SvPV(ST(i),na));
2970 return;
2971 }
2972 channel=(ChannelType) option;
2973 break;
2974 }
2975 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2976 attribute);
2977 break;
2978 }
2979 case 'E':
2980 case 'e':
2981 {
2982 if (LocaleCompare(attribute,"expression") == 0)
2983 {
2984 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00002985 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002986 break;
2987 }
2988 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2989 attribute);
2990 break;
2991 }
2992 default:
2993 {
2994 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2995 attribute);
2996 break;
2997 }
2998 }
2999 }
3000 channel_mask=SetImageChannelMask(image,channel);
3001 image=ChannelFxImage(image,expression,exception);
3002 if (image != (Image *) NULL)
3003 (void) SetImageChannelMask(image,channel_mask);
3004 if (image == (Image *) NULL)
3005 goto PerlException;
3006 for ( ; image; image=image->next)
3007 {
3008 AddImageToRegistry(sv,image);
3009 rv=newRV(sv);
3010 av_push(av,sv_bless(rv,hv));
3011 SvREFCNT_dec(sv);
3012 }
3013 exception=DestroyExceptionInfo(exception);
3014 ST(0)=av_reference;
3015 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3016 XSRETURN(1);
3017
3018 PerlException:
3019 InheritPerlException(exception,perl_exception);
3020 exception=DestroyExceptionInfo(exception);
3021 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3022 SvPOK_on(perl_exception);
3023 ST(0)=sv_2mortal(perl_exception);
3024 XSRETURN(1);
3025 }
3026
3027#
3028###############################################################################
3029# #
3030# #
3031# #
3032# C l o n e #
3033# #
3034# #
3035# #
3036###############################################################################
3037#
3038#
3039void
3040Clone(ref)
3041 Image::Magick ref=NO_INIT
3042 ALIAS:
3043 CopyImage = 1
3044 copy = 2
3045 copyimage = 3
3046 CloneImage = 4
3047 clone = 5
3048 cloneimage = 6
3049 Clone = 7
3050 PPCODE:
3051 {
3052 AV
3053 *av;
3054
3055 ExceptionInfo
3056 *exception;
3057
3058 HV
3059 *hv;
3060
3061 Image
3062 *clone,
3063 *image;
3064
3065 struct PackageInfo
3066 *info;
3067
3068 SV
3069 *perl_exception,
3070 *reference,
3071 *rv,
3072 *sv;
3073
3074 PERL_UNUSED_VAR(ref);
3075 PERL_UNUSED_VAR(ix);
3076 exception=AcquireExceptionInfo();
3077 perl_exception=newSVpv("",0);
3078 sv=NULL;
3079 if (sv_isobject(ST(0)) == 0)
3080 {
3081 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3082 PackageName);
3083 goto PerlException;
3084 }
3085 reference=SvRV(ST(0));
3086 hv=SvSTASH(reference);
3087 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3088 if (image == (Image *) NULL)
3089 {
3090 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3091 PackageName);
3092 goto PerlException;
3093 }
3094 /*
3095 Create blessed Perl array for the returned image.
3096 */
3097 av=newAV();
3098 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3099 SvREFCNT_dec(av);
3100 for ( ; image; image=image->next)
3101 {
3102 clone=CloneImage(image,0,0,MagickTrue,exception);
3103 if (clone == (Image *) NULL)
3104 break;
3105 AddImageToRegistry(sv,clone);
3106 rv=newRV(sv);
3107 av_push(av,sv_bless(rv,hv));
3108 SvREFCNT_dec(sv);
3109 }
3110 exception=DestroyExceptionInfo(exception);
3111 SvREFCNT_dec(perl_exception);
3112 XSRETURN(1);
3113
3114 PerlException:
3115 InheritPerlException(exception,perl_exception);
3116 exception=DestroyExceptionInfo(exception);
3117 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3118 SvPOK_on(perl_exception);
3119 ST(0)=sv_2mortal(perl_exception);
3120 XSRETURN(1);
3121 }
3122
3123#
3124###############################################################################
3125# #
3126# #
3127# #
3128# C L O N E #
3129# #
3130# #
3131# #
3132###############################################################################
3133#
3134#
3135void
3136CLONE(ref,...)
3137 SV *ref;
3138 CODE:
3139 {
3140 PERL_UNUSED_VAR(ref);
3141 if (magick_registry != (SplayTreeInfo *) NULL)
3142 {
3143 register Image
3144 *p;
3145
3146 ResetSplayTreeIterator(magick_registry);
3147 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3148 while (p != (Image *) NULL)
3149 {
3150 ReferenceImage(p);
3151 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3152 }
3153 }
3154 }
3155
3156#
3157###############################################################################
3158# #
3159# #
3160# #
3161# C o a l e s c e #
3162# #
3163# #
3164# #
3165###############################################################################
3166#
3167#
3168void
3169Coalesce(ref)
3170 Image::Magick ref=NO_INIT
3171 ALIAS:
3172 CoalesceImage = 1
3173 coalesce = 2
3174 coalesceimage = 3
3175 PPCODE:
3176 {
3177 AV
3178 *av;
3179
3180 ExceptionInfo
3181 *exception;
3182
3183 HV
3184 *hv;
3185
3186 Image
3187 *image;
3188
3189 struct PackageInfo
3190 *info;
3191
3192 SV
3193 *av_reference,
3194 *perl_exception,
3195 *reference,
3196 *rv,
3197 *sv;
3198
3199 PERL_UNUSED_VAR(ref);
3200 PERL_UNUSED_VAR(ix);
3201 exception=AcquireExceptionInfo();
3202 perl_exception=newSVpv("",0);
3203 sv=NULL;
3204 if (sv_isobject(ST(0)) == 0)
3205 {
3206 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3207 PackageName);
3208 goto PerlException;
3209 }
3210 reference=SvRV(ST(0));
3211 hv=SvSTASH(reference);
3212 av=newAV();
3213 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3214 SvREFCNT_dec(av);
3215 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3216 if (image == (Image *) NULL)
3217 {
3218 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3219 PackageName);
3220 goto PerlException;
3221 }
3222 image=CoalesceImages(image,exception);
3223 if (image == (Image *) NULL)
3224 goto PerlException;
3225 for ( ; image; image=image->next)
3226 {
3227 AddImageToRegistry(sv,image);
3228 rv=newRV(sv);
3229 av_push(av,sv_bless(rv,hv));
3230 SvREFCNT_dec(sv);
3231 }
3232 exception=DestroyExceptionInfo(exception);
3233 ST(0)=av_reference;
3234 SvREFCNT_dec(perl_exception);
3235 XSRETURN(1);
3236
3237 PerlException:
3238 InheritPerlException(exception,perl_exception);
3239 exception=DestroyExceptionInfo(exception);
3240 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3241 SvPOK_on(perl_exception);
3242 ST(0)=sv_2mortal(perl_exception);
3243 XSRETURN(1);
3244 }
3245
3246#
3247###############################################################################
3248# #
3249# #
3250# #
3251# C o m p a r e #
3252# #
3253# #
3254# #
3255###############################################################################
3256#
3257#
3258void
3259Compare(ref,...)
3260 Image::Magick ref=NO_INIT
3261 ALIAS:
3262 CompareImages = 1
3263 compare = 2
3264 compareimage = 3
3265 PPCODE:
3266 {
3267 AV
3268 *av;
3269
3270 char
3271 *attribute;
3272
3273 double
3274 distortion;
3275
3276 ExceptionInfo
3277 *exception;
3278
3279 HV
3280 *hv;
3281
3282 Image
3283 *difference_image,
3284 *image,
3285 *reconstruct_image;
3286
3287 MetricType
3288 metric;
3289
3290 register ssize_t
3291 i;
3292
3293 ssize_t
3294 option;
3295
3296 struct PackageInfo
3297 *info;
3298
3299 SV
3300 *av_reference,
3301 *perl_exception,
3302 *reference,
3303 *rv,
3304 *sv;
3305
3306 PERL_UNUSED_VAR(ref);
3307 PERL_UNUSED_VAR(ix);
3308 exception=AcquireExceptionInfo();
3309 perl_exception=newSVpv("",0);
3310 sv=NULL;
3311 av=NULL;
3312 attribute=NULL;
3313 if (sv_isobject(ST(0)) == 0)
3314 {
3315 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3316 PackageName);
3317 goto PerlException;
3318 }
3319 reference=SvRV(ST(0));
3320 hv=SvSTASH(reference);
3321 av=newAV();
3322 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3323 SvREFCNT_dec(av);
3324 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3325 if (image == (Image *) NULL)
3326 {
3327 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3328 PackageName);
3329 goto PerlException;
3330 }
3331 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3332 /*
3333 Get attribute.
3334 */
3335 reconstruct_image=image;
3336 metric=RootMeanSquaredErrorMetric;
3337 for (i=2; i < items; i+=2)
3338 {
3339 attribute=(char *) SvPV(ST(i-1),na);
3340 switch (*attribute)
3341 {
3342 case 'C':
3343 case 'c':
3344 {
3345 if (LocaleCompare(attribute,"channel") == 0)
3346 {
3347 ssize_t
3348 option;
3349
3350 option=ParseChannelOption(SvPV(ST(i),na));
3351 if (option < 0)
3352 {
3353 ThrowPerlException(exception,OptionError,
3354 "UnrecognizedType",SvPV(ST(i),na));
3355 return;
3356 }
cristybcd59342015-06-07 14:07:19 +00003357 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003358 break;
3359 }
3360 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3361 attribute);
3362 break;
3363 }
3364 case 'F':
3365 case 'f':
3366 {
3367 if (LocaleCompare(attribute,"fuzz") == 0)
3368 {
3369 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3370 break;
3371 }
3372 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3373 attribute);
3374 break;
3375 }
3376 case 'I':
3377 case 'i':
3378 {
3379 if (LocaleCompare(attribute,"image") == 0)
3380 {
3381 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3382 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3383 break;
3384 }
3385 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3386 attribute);
3387 break;
3388 }
3389 case 'M':
3390 case 'm':
3391 {
3392 if (LocaleCompare(attribute,"metric") == 0)
3393 {
3394 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3395 SvPV(ST(i),na));
3396 if (option < 0)
3397 {
3398 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3399 SvPV(ST(i),na));
3400 break;
3401 }
3402 metric=(MetricType) option;
3403 break;
3404 }
3405 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3406 attribute);
3407 break;
3408 }
3409 default:
3410 {
3411 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3412 attribute);
3413 break;
3414 }
3415 }
3416 }
3417 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3418 exception);
3419 if (difference_image != (Image *) NULL)
3420 {
3421 difference_image->error.mean_error_per_pixel=distortion;
3422 AddImageToRegistry(sv,difference_image);
3423 rv=newRV(sv);
3424 av_push(av,sv_bless(rv,hv));
3425 SvREFCNT_dec(sv);
3426 }
3427 exception=DestroyExceptionInfo(exception);
3428 ST(0)=av_reference;
3429 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3430 XSRETURN(1);
3431
3432 PerlException:
3433 InheritPerlException(exception,perl_exception);
3434 exception=DestroyExceptionInfo(exception);
3435 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3436 SvPOK_on(perl_exception);
3437 ST(0)=sv_2mortal(perl_exception);
3438 XSRETURN(1);
3439 }
3440
3441#
3442###############################################################################
3443# #
3444# #
3445# #
cristy15655332013-10-06 00:27:33 +00003446# C o m p l e x I m a g e s #
3447# #
3448# #
3449# #
3450###############################################################################
3451#
3452#
3453void
3454ComplexImages(ref)
3455 Image::Magick ref=NO_INIT
3456 ALIAS:
3457 ComplexImages = 1
3458 compleximages = 2
3459 PPCODE:
3460 {
3461 AV
3462 *av;
3463
3464 char
3465 *attribute,
3466 *p;
3467
cristyfa21e9e2013-10-07 10:37:38 +00003468 ComplexOperator
3469 op;
3470
cristy15655332013-10-06 00:27:33 +00003471 ExceptionInfo
3472 *exception;
3473
3474 HV
3475 *hv;
3476
3477 Image
3478 *image;
3479
cristy15655332013-10-06 00:27:33 +00003480 register ssize_t
3481 i;
3482
3483 struct PackageInfo
3484 *info;
3485
3486 SV
3487 *perl_exception,
3488 *reference,
3489 *rv,
3490 *sv;
3491
3492 PERL_UNUSED_VAR(ref);
3493 PERL_UNUSED_VAR(ix);
3494 exception=AcquireExceptionInfo();
3495 perl_exception=newSVpv("",0);
3496 sv=NULL;
3497 if (sv_isobject(ST(0)) == 0)
3498 {
3499 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3500 PackageName);
3501 goto PerlException;
3502 }
3503 reference=SvRV(ST(0));
3504 hv=SvSTASH(reference);
3505 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3506 if (image == (Image *) NULL)
3507 {
3508 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3509 PackageName);
3510 goto PerlException;
3511 }
cristyfd168722013-10-07 15:59:31 +00003512 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003513 if (items == 2)
3514 {
3515 ssize_t
3516 in;
3517
3518 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3519 SvPV(ST(1),na));
3520 if (in < 0)
3521 {
3522 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3523 SvPV(ST(1),na));
3524 return;
3525 }
cristyfa21e9e2013-10-07 10:37:38 +00003526 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003527 }
3528 else
3529 for (i=2; i < items; i+=2)
3530 {
3531 attribute=(char *) SvPV(ST(i-1),na);
3532 switch (*attribute)
3533 {
3534 case 'O':
3535 case 'o':
3536 {
3537 if (LocaleCompare(attribute,"operator") == 0)
3538 {
3539 ssize_t
3540 in;
3541
3542 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3543 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3544 if (in < 0)
3545 {
3546 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3547 SvPV(ST(i),na));
3548 return;
3549 }
cristyfa21e9e2013-10-07 10:37:38 +00003550 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003551 break;
3552 }
3553 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3554 attribute);
3555 break;
3556 }
3557 default:
3558 {
3559 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3560 attribute);
3561 break;
3562 }
3563 }
3564 }
3565 image=ComplexImages(image,op,exception);
3566 if (image == (Image *) NULL)
3567 goto PerlException;
3568 /*
3569 Create blessed Perl array for the returned image.
3570 */
3571 av=newAV();
3572 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3573 SvREFCNT_dec(av);
3574 AddImageToRegistry(sv,image);
3575 rv=newRV(sv);
3576 av_push(av,sv_bless(rv,hv));
3577 SvREFCNT_dec(sv);
3578 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003579 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3580 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003581 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3582 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003583 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003584 SetImageInfo(info->image_info,0,exception);
3585 exception=DestroyExceptionInfo(exception);
3586 SvREFCNT_dec(perl_exception);
3587 XSRETURN(1);
3588
3589 PerlException:
3590 InheritPerlException(exception,perl_exception);
3591 exception=DestroyExceptionInfo(exception);
3592 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3593 SvPOK_on(perl_exception);
3594 ST(0)=sv_2mortal(perl_exception);
3595 XSRETURN(1);
3596 }
3597
3598#
3599###############################################################################
3600# #
3601# #
3602# #
cristy4a3ce0a2013-08-03 20:06:59 +00003603# C o m p a r e L a y e r s #
3604# #
3605# #
3606# #
3607###############################################################################
3608#
3609#
3610void
3611CompareLayers(ref)
3612 Image::Magick ref=NO_INIT
3613 ALIAS:
3614 CompareImagesLayers = 1
3615 comparelayers = 2
3616 compareimagelayers = 3
3617 PPCODE:
3618 {
3619 AV
3620 *av;
3621
3622 char
3623 *attribute;
3624
3625 ExceptionInfo
3626 *exception;
3627
3628 HV
3629 *hv;
3630
3631 Image
3632 *image;
3633
3634 LayerMethod
3635 method;
3636
3637 register ssize_t
3638 i;
3639
3640 ssize_t
3641 option;
3642
3643 struct PackageInfo
3644 *info;
3645
3646 SV
3647 *av_reference,
3648 *perl_exception,
3649 *reference,
3650 *rv,
3651 *sv;
3652
3653 PERL_UNUSED_VAR(ref);
3654 PERL_UNUSED_VAR(ix);
3655 exception=AcquireExceptionInfo();
3656 perl_exception=newSVpv("",0);
3657 sv=NULL;
3658 if (sv_isobject(ST(0)) == 0)
3659 {
3660 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3661 PackageName);
3662 goto PerlException;
3663 }
3664 reference=SvRV(ST(0));
3665 hv=SvSTASH(reference);
3666 av=newAV();
3667 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3668 SvREFCNT_dec(av);
3669 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3670 if (image == (Image *) NULL)
3671 {
3672 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3673 PackageName);
3674 goto PerlException;
3675 }
3676 method=CompareAnyLayer;
3677 for (i=2; i < items; i+=2)
3678 {
3679 attribute=(char *) SvPV(ST(i-1),na);
3680 switch (*attribute)
3681 {
3682 case 'M':
3683 case 'm':
3684 {
3685 if (LocaleCompare(attribute,"method") == 0)
3686 {
3687 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3688 SvPV(ST(i),na));
3689 if (option < 0)
3690 {
3691 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3692 SvPV(ST(i),na));
3693 break;
3694 }
3695 method=(LayerMethod) option;
3696 break;
3697 }
3698 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3699 attribute);
3700 break;
3701 }
3702 default:
3703 {
3704 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3705 attribute);
3706 break;
3707 }
3708 }
3709 }
3710 image=CompareImagesLayers(image,method,exception);
3711 if (image == (Image *) NULL)
3712 goto PerlException;
3713 for ( ; image; image=image->next)
3714 {
3715 AddImageToRegistry(sv,image);
3716 rv=newRV(sv);
3717 av_push(av,sv_bless(rv,hv));
3718 SvREFCNT_dec(sv);
3719 }
3720 exception=DestroyExceptionInfo(exception);
3721 ST(0)=av_reference;
3722 SvREFCNT_dec(perl_exception);
3723 XSRETURN(1);
3724
3725 PerlException:
3726 InheritPerlException(exception,perl_exception);
3727 exception=DestroyExceptionInfo(exception);
3728 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3729 SvPOK_on(perl_exception);
3730 ST(0)=sv_2mortal(perl_exception);
3731 XSRETURN(1);
3732 }
3733
3734#
3735###############################################################################
3736# #
3737# #
3738# #
3739# D e s t r o y #
3740# #
3741# #
3742# #
3743###############################################################################
3744#
3745#
3746void
3747DESTROY(ref)
3748 Image::Magick ref=NO_INIT
3749 PPCODE:
3750 {
3751 SV
3752 *reference;
3753
3754 PERL_UNUSED_VAR(ref);
3755 if (sv_isobject(ST(0)) == 0)
3756 croak("ReferenceIsNotMyType");
3757 reference=SvRV(ST(0));
3758 switch (SvTYPE(reference))
3759 {
3760 case SVt_PVAV:
3761 {
3762 char
cristy151b66d2015-04-15 10:50:31 +00003763 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003764
3765 const SV
3766 *key;
3767
3768 HV
3769 *hv;
3770
3771 GV
3772 **gvp;
3773
3774 struct PackageInfo
3775 *info;
3776
3777 SV
3778 *sv;
3779
3780 /*
3781 Array (AV *) reference
3782 */
cristy151b66d2015-04-15 10:50:31 +00003783 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003784 XS_VERSION,reference);
3785 hv=gv_stashpv(PackageName, FALSE);
3786 if (!hv)
3787 break;
3788 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3789 if (!gvp)
3790 break;
3791 sv=GvSV(*gvp);
3792 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3793 {
3794 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3795 DestroyPackageInfo(info);
3796 }
3797 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3798 (void) key;
3799 break;
3800 }
3801 case SVt_PVMG:
3802 {
3803 Image
3804 *image;
3805
3806 /*
3807 Blessed scalar = (Image *) SvIV(reference)
3808 */
3809 image=INT2PTR(Image *,SvIV(reference));
3810 if (image != (Image *) NULL)
3811 DeleteImageFromRegistry(reference,image);
3812 break;
3813 }
3814 default:
3815 break;
3816 }
3817 }
3818
3819#
3820###############################################################################
3821# #
3822# #
3823# #
3824# D i s p l a y #
3825# #
3826# #
3827# #
3828###############################################################################
3829#
3830#
3831void
3832Display(ref,...)
3833 Image::Magick ref=NO_INIT
3834 ALIAS:
3835 DisplayImage = 1
3836 display = 2
3837 displayimage = 3
3838 PPCODE:
3839 {
3840 ExceptionInfo
3841 *exception;
3842
3843 Image
3844 *image;
3845
3846 register ssize_t
3847 i;
3848
3849 struct PackageInfo
3850 *info,
3851 *package_info;
3852
3853 SV
3854 *perl_exception,
3855 *reference;
3856
3857 PERL_UNUSED_VAR(ref);
3858 PERL_UNUSED_VAR(ix);
3859 exception=AcquireExceptionInfo();
3860 perl_exception=newSVpv("",0);
3861 package_info=(struct PackageInfo *) NULL;
3862 if (sv_isobject(ST(0)) == 0)
3863 {
3864 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3865 PackageName);
3866 goto PerlException;
3867 }
3868 reference=SvRV(ST(0));
3869 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3870 if (image == (Image *) NULL)
3871 {
3872 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3873 PackageName);
3874 goto PerlException;
3875 }
3876 package_info=ClonePackageInfo(info,exception);
3877 if (items == 2)
3878 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3879 else
3880 if (items > 2)
3881 for (i=2; i < items; i+=2)
3882 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3883 exception);
3884 (void) DisplayImages(package_info->image_info,image,exception);
3885 (void) CatchImageException(image);
3886
3887 PerlException:
3888 if (package_info != (struct PackageInfo *) NULL)
3889 DestroyPackageInfo(package_info);
3890 InheritPerlException(exception,perl_exception);
3891 exception=DestroyExceptionInfo(exception);
3892 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3893 SvPOK_on(perl_exception);
3894 ST(0)=sv_2mortal(perl_exception);
3895 XSRETURN(1);
3896 }
3897
3898#
3899###############################################################################
3900# #
3901# #
3902# #
3903# E v a l u a t e I m a g e s #
3904# #
3905# #
3906# #
3907###############################################################################
3908#
3909#
3910void
3911EvaluateImages(ref)
3912 Image::Magick ref=NO_INIT
3913 ALIAS:
3914 EvaluateImages = 1
3915 evaluateimages = 2
3916 PPCODE:
3917 {
3918 AV
3919 *av;
3920
3921 char
3922 *attribute,
3923 *p;
3924
3925 ExceptionInfo
3926 *exception;
3927
3928 HV
3929 *hv;
3930
3931 Image
3932 *image;
3933
3934 MagickEvaluateOperator
3935 op;
3936
3937 register ssize_t
3938 i;
3939
3940 struct PackageInfo
3941 *info;
3942
3943 SV
3944 *perl_exception,
3945 *reference,
3946 *rv,
3947 *sv;
3948
3949 PERL_UNUSED_VAR(ref);
3950 PERL_UNUSED_VAR(ix);
3951 exception=AcquireExceptionInfo();
3952 perl_exception=newSVpv("",0);
3953 sv=NULL;
3954 if (sv_isobject(ST(0)) == 0)
3955 {
3956 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3957 PackageName);
3958 goto PerlException;
3959 }
3960 reference=SvRV(ST(0));
3961 hv=SvSTASH(reference);
3962 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3963 if (image == (Image *) NULL)
3964 {
3965 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3966 PackageName);
3967 goto PerlException;
3968 }
3969 op=MeanEvaluateOperator;
3970 if (items == 2)
3971 {
3972 ssize_t
3973 in;
3974
3975 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
3976 SvPV(ST(1),na));
3977 if (in < 0)
3978 {
3979 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3980 SvPV(ST(1),na));
3981 return;
3982 }
3983 op=(MagickEvaluateOperator) in;
3984 }
3985 else
3986 for (i=2; i < items; i+=2)
3987 {
3988 attribute=(char *) SvPV(ST(i-1),na);
3989 switch (*attribute)
3990 {
3991 case 'O':
3992 case 'o':
3993 {
3994 if (LocaleCompare(attribute,"operator") == 0)
3995 {
3996 ssize_t
3997 in;
3998
3999 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4000 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4001 if (in < 0)
4002 {
4003 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4004 SvPV(ST(i),na));
4005 return;
4006 }
4007 op=(MagickEvaluateOperator) in;
4008 break;
4009 }
4010 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4011 attribute);
4012 break;
4013 }
4014 default:
4015 {
4016 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4017 attribute);
4018 break;
4019 }
4020 }
4021 }
4022 image=EvaluateImages(image,op,exception);
4023 if (image == (Image *) NULL)
4024 goto PerlException;
4025 /*
4026 Create blessed Perl array for the returned image.
4027 */
4028 av=newAV();
4029 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4030 SvREFCNT_dec(av);
4031 AddImageToRegistry(sv,image);
4032 rv=newRV(sv);
4033 av_push(av,sv_bless(rv,hv));
4034 SvREFCNT_dec(sv);
4035 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004036 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4037 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004038 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4039 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004040 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004041 SetImageInfo(info->image_info,0,exception);
4042 exception=DestroyExceptionInfo(exception);
4043 SvREFCNT_dec(perl_exception);
4044 XSRETURN(1);
4045
4046 PerlException:
4047 InheritPerlException(exception,perl_exception);
4048 exception=DestroyExceptionInfo(exception);
4049 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4050 SvPOK_on(perl_exception);
4051 ST(0)=sv_2mortal(perl_exception);
4052 XSRETURN(1);
4053 }
4054
4055#
4056###############################################################################
4057# #
4058# #
4059# #
4060# F e a t u r e s #
4061# #
4062# #
4063# #
4064###############################################################################
4065#
4066#
4067void
4068Features(ref,...)
4069 Image::Magick ref=NO_INIT
4070 ALIAS:
4071 FeaturesImage = 1
4072 features = 2
4073 featuresimage = 3
4074 PPCODE:
4075 {
4076#define ChannelFeatures(channel,direction) \
4077{ \
Cristyb1710fe2017-02-11 13:51:48 -05004078 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004079 channel_features[channel].angular_second_moment[direction]); \
4080 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004081 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004082 channel_features[channel].contrast[direction]); \
4083 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004084 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004085 channel_features[channel].contrast[direction]); \
4086 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004087 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004088 channel_features[channel].variance_sum_of_squares[direction]); \
4089 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004090 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004091 channel_features[channel].inverse_difference_moment[direction]); \
4092 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004093 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004094 channel_features[channel].sum_average[direction]); \
4095 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004096 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004097 channel_features[channel].sum_variance[direction]); \
4098 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004099 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004100 channel_features[channel].sum_entropy[direction]); \
4101 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004102 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004103 channel_features[channel].entropy[direction]); \
4104 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004105 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004106 channel_features[channel].difference_variance[direction]); \
4107 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004108 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004109 channel_features[channel].difference_entropy[direction]); \
4110 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004111 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004112 channel_features[channel].measure_of_correlation_1[direction]); \
4113 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004114 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004115 channel_features[channel].measure_of_correlation_2[direction]); \
4116 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004117 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004118 channel_features[channel].maximum_correlation_coefficient[direction]); \
4119 PUSHs(sv_2mortal(newSVpv(message,0))); \
4120}
4121
4122 AV
4123 *av;
4124
4125 char
4126 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004127 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004128
4129 ChannelFeatures
4130 *channel_features;
4131
4132 double
4133 distance;
4134
4135 ExceptionInfo
4136 *exception;
4137
4138 Image
4139 *image;
4140
4141 register ssize_t
4142 i;
4143
4144 ssize_t
4145 count;
4146
4147 struct PackageInfo
4148 *info;
4149
4150 SV
4151 *perl_exception,
4152 *reference;
4153
4154 PERL_UNUSED_VAR(ref);
4155 PERL_UNUSED_VAR(ix);
4156 exception=AcquireExceptionInfo();
4157 perl_exception=newSVpv("",0);
4158 av=NULL;
4159 if (sv_isobject(ST(0)) == 0)
4160 {
4161 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4162 PackageName);
4163 goto PerlException;
4164 }
4165 reference=SvRV(ST(0));
4166 av=newAV();
4167 SvREFCNT_dec(av);
4168 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4169 if (image == (Image *) NULL)
4170 {
4171 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4172 PackageName);
4173 goto PerlException;
4174 }
cristy7dbd9262014-07-02 17:53:42 +00004175 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004176 for (i=2; i < items; i+=2)
4177 {
4178 attribute=(char *) SvPV(ST(i-1),na);
4179 switch (*attribute)
4180 {
4181 case 'D':
4182 case 'd':
4183 {
4184 if (LocaleCompare(attribute,"distance") == 0)
4185 {
4186 distance=StringToLong((char *) SvPV(ST(1),na));
4187 break;
4188 }
4189 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4190 attribute);
4191 break;
4192 }
4193 default:
4194 {
4195 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4196 attribute);
4197 break;
4198 }
4199 }
4200 }
4201 count=0;
4202 for ( ; image; image=image->next)
4203 {
4204 channel_features=GetImageFeatures(image,distance,exception);
4205 if (channel_features == (ChannelFeatures *) NULL)
4206 continue;
4207 count++;
cristyfcf3bdf2014-07-02 14:35:58 +00004208 EXTEND(sp,280*count);
cristy4a3ce0a2013-08-03 20:06:59 +00004209 for (i=0; i < 4; i++)
4210 {
4211 ChannelFeatures(RedChannel,i);
4212 ChannelFeatures(GreenChannel,i);
4213 ChannelFeatures(BlueChannel,i);
4214 if (image->colorspace == CMYKColorspace)
4215 ChannelFeatures(BlackChannel,i);
cristy17f11b02014-12-20 19:37:04 +00004216 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00004217 ChannelFeatures(AlphaChannel,i);
4218 }
4219 channel_features=(ChannelFeatures *)
4220 RelinquishMagickMemory(channel_features);
4221 }
4222
4223 PerlException:
4224 InheritPerlException(exception,perl_exception);
4225 exception=DestroyExceptionInfo(exception);
4226 SvREFCNT_dec(perl_exception);
4227 }
4228
4229#
4230###############################################################################
4231# #
4232# #
4233# #
4234# F l a t t e n #
4235# #
4236# #
4237# #
4238###############################################################################
4239#
4240#
4241void
4242Flatten(ref)
4243 Image::Magick ref=NO_INIT
4244 ALIAS:
4245 FlattenImage = 1
4246 flatten = 2
4247 flattenimage = 3
4248 PPCODE:
4249 {
4250 AV
4251 *av;
4252
4253 char
4254 *attribute,
4255 *p;
4256
4257 ExceptionInfo
4258 *exception;
4259
4260 HV
4261 *hv;
4262
4263 Image
4264 *image;
4265
4266 PixelInfo
4267 background_color;
4268
4269 register ssize_t
4270 i;
4271
4272 struct PackageInfo
4273 *info;
4274
4275 SV
4276 *perl_exception,
4277 *reference,
4278 *rv,
4279 *sv;
4280
4281 PERL_UNUSED_VAR(ref);
4282 PERL_UNUSED_VAR(ix);
4283 exception=AcquireExceptionInfo();
4284 perl_exception=newSVpv("",0);
4285 sv=NULL;
4286 if (sv_isobject(ST(0)) == 0)
4287 {
4288 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4289 PackageName);
4290 goto PerlException;
4291 }
4292 reference=SvRV(ST(0));
4293 hv=SvSTASH(reference);
4294 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4295 if (image == (Image *) NULL)
4296 {
4297 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4298 PackageName);
4299 goto PerlException;
4300 }
4301 background_color=image->background_color;
4302 if (items == 2)
4303 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4304 &background_color,exception);
4305 else
4306 for (i=2; i < items; i+=2)
4307 {
4308 attribute=(char *) SvPV(ST(i-1),na);
4309 switch (*attribute)
4310 {
4311 case 'B':
4312 case 'b':
4313 {
4314 if (LocaleCompare(attribute,"background") == 0)
4315 {
4316 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4317 AllCompliance,&background_color,exception);
4318 break;
4319 }
4320 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4321 attribute);
4322 break;
4323 }
4324 default:
4325 {
4326 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4327 attribute);
4328 break;
4329 }
4330 }
4331 }
4332 image->background_color=background_color;
4333 image=MergeImageLayers(image,FlattenLayer,exception);
4334 if (image == (Image *) NULL)
4335 goto PerlException;
4336 /*
4337 Create blessed Perl array for the returned image.
4338 */
4339 av=newAV();
4340 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4341 SvREFCNT_dec(av);
4342 AddImageToRegistry(sv,image);
4343 rv=newRV(sv);
4344 av_push(av,sv_bless(rv,hv));
4345 SvREFCNT_dec(sv);
4346 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004347 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4348 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004349 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4350 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004351 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004352 SetImageInfo(info->image_info,0,exception);
4353 exception=DestroyExceptionInfo(exception);
4354 SvREFCNT_dec(perl_exception);
4355 XSRETURN(1);
4356
4357 PerlException:
4358 InheritPerlException(exception,perl_exception);
4359 exception=DestroyExceptionInfo(exception);
4360 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4361 SvPOK_on(perl_exception); /* return messages in string context */
4362 ST(0)=sv_2mortal(perl_exception);
4363 XSRETURN(1);
4364 }
4365
4366#
4367###############################################################################
4368# #
4369# #
4370# #
4371# F x #
4372# #
4373# #
4374# #
4375###############################################################################
4376#
4377#
4378void
4379Fx(ref,...)
4380 Image::Magick ref=NO_INIT
4381 ALIAS:
4382 FxImage = 1
4383 fx = 2
4384 fximage = 3
4385 PPCODE:
4386 {
4387 AV
4388 *av;
4389
4390 char
4391 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004392 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004393
4394 ChannelType
4395 channel,
4396 channel_mask;
4397
4398 ExceptionInfo
4399 *exception;
4400
4401 HV
4402 *hv;
4403
4404 Image
4405 *image;
4406
4407 register ssize_t
4408 i;
4409
4410 struct PackageInfo
4411 *info;
4412
4413 SV
4414 *av_reference,
4415 *perl_exception,
4416 *reference,
4417 *rv,
4418 *sv;
4419
4420 PERL_UNUSED_VAR(ref);
4421 PERL_UNUSED_VAR(ix);
4422 exception=AcquireExceptionInfo();
4423 perl_exception=newSVpv("",0);
4424 sv=NULL;
4425 attribute=NULL;
4426 av=NULL;
4427 if (sv_isobject(ST(0)) == 0)
4428 {
4429 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4430 PackageName);
4431 goto PerlException;
4432 }
4433 reference=SvRV(ST(0));
4434 hv=SvSTASH(reference);
4435 av=newAV();
4436 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4437 SvREFCNT_dec(av);
4438 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4439 if (image == (Image *) NULL)
4440 {
4441 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4442 PackageName);
4443 goto PerlException;
4444 }
4445 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4446 /*
4447 Get options.
4448 */
4449 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004450 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004451 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004452 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004453 else
4454 for (i=2; i < items; i+=2)
4455 {
4456 attribute=(char *) SvPV(ST(i-1),na);
4457 switch (*attribute)
4458 {
4459 case 'C':
4460 case 'c':
4461 {
4462 if (LocaleCompare(attribute,"channel") == 0)
4463 {
4464 ssize_t
4465 option;
4466
4467 option=ParseChannelOption(SvPV(ST(i),na));
4468 if (option < 0)
4469 {
4470 ThrowPerlException(exception,OptionError,
4471 "UnrecognizedType",SvPV(ST(i),na));
4472 return;
4473 }
4474 channel=(ChannelType) option;
4475 break;
4476 }
4477 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4478 attribute);
4479 break;
4480 }
4481 case 'E':
4482 case 'e':
4483 {
4484 if (LocaleCompare(attribute,"expression") == 0)
4485 {
4486 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004487 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004488 break;
4489 }
4490 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4491 attribute);
4492 break;
4493 }
4494 default:
4495 {
4496 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4497 attribute);
4498 break;
4499 }
4500 }
4501 }
4502 channel_mask=SetImageChannelMask(image,channel);
4503 image=FxImage(image,expression,exception);
4504 if (image != (Image *) NULL)
4505 (void) SetImageChannelMask(image,channel_mask);
4506 if (image == (Image *) NULL)
4507 goto PerlException;
4508 for ( ; image; image=image->next)
4509 {
4510 AddImageToRegistry(sv,image);
4511 rv=newRV(sv);
4512 av_push(av,sv_bless(rv,hv));
4513 SvREFCNT_dec(sv);
4514 }
4515 exception=DestroyExceptionInfo(exception);
4516 ST(0)=av_reference;
4517 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4518 XSRETURN(1);
4519
4520 PerlException:
4521 InheritPerlException(exception,perl_exception);
4522 exception=DestroyExceptionInfo(exception);
4523 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4524 SvPOK_on(perl_exception);
4525 ST(0)=sv_2mortal(perl_exception);
4526 XSRETURN(1);
4527 }
4528
4529#
4530###############################################################################
4531# #
4532# #
4533# #
4534# G e t #
4535# #
4536# #
4537# #
4538###############################################################################
4539#
4540#
4541void
4542Get(ref,...)
4543 Image::Magick ref=NO_INIT
4544 ALIAS:
4545 GetAttributes = 1
4546 GetAttribute = 2
4547 get = 3
4548 getattributes = 4
4549 getattribute = 5
4550 PPCODE:
4551 {
4552 char
4553 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004554 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004555
4556 const char
4557 *value;
4558
4559 ExceptionInfo
4560 *exception;
4561
4562 Image
4563 *image;
4564
4565 long
4566 j;
4567
4568 register ssize_t
4569 i;
4570
4571 struct PackageInfo
4572 *info;
4573
4574 SV
4575 *perl_exception,
4576 *reference,
4577 *s;
4578
4579 PERL_UNUSED_VAR(ref);
4580 PERL_UNUSED_VAR(ix);
4581 exception=AcquireExceptionInfo();
4582 perl_exception=newSVpv("",0);
4583 if (sv_isobject(ST(0)) == 0)
4584 {
4585 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4586 PackageName);
4587 XSRETURN_EMPTY;
4588 }
4589 reference=SvRV(ST(0));
4590 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4591 if (image == (Image *) NULL && !info)
4592 XSRETURN_EMPTY;
4593 EXTEND(sp,items);
4594 for (i=1; i < items; i++)
4595 {
4596 attribute=(char *) SvPV(ST(i),na);
4597 s=NULL;
4598 switch (*attribute)
4599 {
4600 case 'A':
4601 case 'a':
4602 {
4603 if (LocaleCompare(attribute,"adjoin") == 0)
4604 {
4605 if (info)
4606 s=newSViv((ssize_t) info->image_info->adjoin);
4607 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4608 continue;
4609 }
4610 if (LocaleCompare(attribute,"antialias") == 0)
4611 {
4612 if (info)
4613 s=newSViv((ssize_t) info->image_info->antialias);
4614 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4615 continue;
4616 }
4617 if (LocaleCompare(attribute,"area") == 0)
4618 {
4619 s=newSViv(GetMagickResource(AreaResource));
4620 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4621 continue;
4622 }
4623 if (LocaleCompare(attribute,"attenuate") == 0)
4624 {
4625 const char
4626 *value;
4627
4628 value=GetImageProperty(image,attribute,exception);
4629 if (value != (const char *) NULL)
4630 s=newSVpv(value,0);
4631 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4632 continue;
4633 }
4634 if (LocaleCompare(attribute,"authenticate") == 0)
4635 {
4636 if (info)
4637 {
4638 const char
4639 *option;
4640
4641 option=GetImageOption(info->image_info,attribute);
4642 if (option != (const char *) NULL)
4643 s=newSVpv(option,0);
4644 }
4645 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4646 continue;
4647 }
4648 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4649 attribute);
4650 break;
4651 }
4652 case 'B':
4653 case 'b':
4654 {
4655 if (LocaleCompare(attribute,"background") == 0)
4656 {
4657 if (image == (Image *) NULL)
4658 break;
cristy151b66d2015-04-15 10:50:31 +00004659 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004660 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4661 (double) image->background_color.green,
4662 (double) image->background_color.blue,
4663 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004664 s=newSVpv(color,0);
4665 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4666 continue;
4667 }
4668 if (LocaleCompare(attribute,"base-columns") == 0)
4669 {
4670 if (image != (Image *) NULL)
4671 s=newSViv((ssize_t) image->magick_columns);
4672 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4673 continue;
4674 }
4675 if (LocaleCompare(attribute,"base-filename") == 0)
4676 {
4677 if (image != (Image *) NULL)
4678 s=newSVpv(image->magick_filename,0);
4679 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4680 continue;
4681 }
4682 if (LocaleCompare(attribute,"base-height") == 0)
4683 {
4684 if (image != (Image *) NULL)
4685 s=newSViv((ssize_t) image->magick_rows);
4686 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4687 continue;
4688 }
4689 if (LocaleCompare(attribute,"base-rows") == 0)
4690 {
4691 if (image != (Image *) NULL)
4692 s=newSViv((ssize_t) image->magick_rows);
4693 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4694 continue;
4695 }
4696 if (LocaleCompare(attribute,"base-width") == 0)
4697 {
4698 if (image != (Image *) NULL)
4699 s=newSViv((ssize_t) image->magick_columns);
4700 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4701 continue;
4702 }
4703 if (LocaleCompare(attribute,"blue-primary") == 0)
4704 {
4705 if (image == (Image *) NULL)
4706 break;
Cristyb1710fe2017-02-11 13:51:48 -05004707 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004708 image->chromaticity.blue_primary.x,
4709 image->chromaticity.blue_primary.y);
4710 s=newSVpv(color,0);
4711 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4712 continue;
4713 }
4714 if (LocaleCompare(attribute,"bordercolor") == 0)
4715 {
4716 if (image == (Image *) NULL)
4717 break;
cristy151b66d2015-04-15 10:50:31 +00004718 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004719 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4720 (double) image->border_color.green,
4721 (double) image->border_color.blue,
4722 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004723 s=newSVpv(color,0);
4724 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4725 continue;
4726 }
4727 if (LocaleCompare(attribute,"bounding-box") == 0)
4728 {
4729 char
cristy151b66d2015-04-15 10:50:31 +00004730 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004731
4732 RectangleInfo
4733 page;
4734
4735 if (image == (Image *) NULL)
4736 break;
4737 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004738 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004739 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4740 page.height,(double) page.x,(double) page.y);
4741 s=newSVpv(geometry,0);
4742 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4743 continue;
4744 }
4745 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4746 attribute);
4747 break;
4748 }
4749 case 'C':
4750 case 'c':
4751 {
4752 if (LocaleCompare(attribute,"class") == 0)
4753 {
4754 if (image == (Image *) NULL)
4755 break;
4756 s=newSViv(image->storage_class);
4757 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4758 image->storage_class));
4759 SvIOK_on(s);
4760 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4761 continue;
4762 }
4763 if (LocaleCompare(attribute,"clip-mask") == 0)
4764 {
4765 if (image != (Image *) NULL)
4766 {
4767 Image
4768 *mask_image;
4769
4770 SV
4771 *sv;
4772
4773 sv=NULL;
4774 if (image->read_mask == MagickFalse)
4775 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004776 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004777 if (mask_image != (Image *) NULL)
4778 {
4779 AddImageToRegistry(sv,mask_image);
4780 s=sv_bless(newRV(sv),SvSTASH(reference));
4781 }
4782 }
4783 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4784 continue;
4785 }
4786 if (LocaleCompare(attribute,"clip-path") == 0)
4787 {
4788 if (image != (Image *) NULL)
4789 {
4790 Image
4791 *mask_image;
4792
4793 SV
4794 *sv;
4795
4796 sv=NULL;
4797 if (image->read_mask != MagickFalse)
4798 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004799 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004800 if (mask_image != (Image *) NULL)
4801 {
4802 AddImageToRegistry(sv,mask_image);
4803 s=sv_bless(newRV(sv),SvSTASH(reference));
4804 }
4805 }
4806 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4807 continue;
4808 }
4809 if (LocaleCompare(attribute,"compression") == 0)
4810 {
4811 j=info ? info->image_info->compression : image ?
4812 image->compression : UndefinedCompression;
4813 if (info)
4814 if (info->image_info->compression == UndefinedCompression)
4815 j=image->compression;
4816 s=newSViv(j);
4817 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4818 j));
4819 SvIOK_on(s);
4820 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4821 continue;
4822 }
4823 if (LocaleCompare(attribute,"colorspace") == 0)
4824 {
4825 j=image ? image->colorspace : RGBColorspace;
4826 s=newSViv(j);
4827 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4828 j));
4829 SvIOK_on(s);
4830 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4831 continue;
4832 }
4833 if (LocaleCompare(attribute,"colors") == 0)
4834 {
4835 if (image != (Image *) NULL)
4836 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4837 exception));
4838 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4839 continue;
4840 }
4841 if (LocaleNCompare(attribute,"colormap",8) == 0)
4842 {
4843 int
4844 items;
4845
4846 if (image == (Image *) NULL || !image->colormap)
4847 break;
4848 j=0;
4849 items=sscanf(attribute,"%*[^[][%ld",&j);
4850 (void) items;
4851 if (j > (ssize_t) image->colors)
4852 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004853 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004854 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4855 (double) image->colormap[j].green,
4856 (double) image->colormap[j].blue,
4857 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004858 s=newSVpv(color,0);
4859 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4860 continue;
4861 }
4862 if (LocaleCompare(attribute,"columns") == 0)
4863 {
4864 if (image != (Image *) NULL)
4865 s=newSViv((ssize_t) image->columns);
4866 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4867 continue;
4868 }
4869 if (LocaleCompare(attribute,"comment") == 0)
4870 {
4871 const char
4872 *value;
4873
4874 value=GetImageProperty(image,attribute,exception);
4875 if (value != (const char *) NULL)
4876 s=newSVpv(value,0);
4877 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4878 continue;
4879 }
4880 if (LocaleCompare(attribute,"copyright") == 0)
4881 {
4882 s=newSVpv(GetMagickCopyright(),0);
4883 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4884 continue;
4885 }
4886 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4887 attribute);
4888 break;
4889 }
4890 case 'D':
4891 case 'd':
4892 {
4893 if (LocaleCompare(attribute,"density") == 0)
4894 {
4895 char
cristy151b66d2015-04-15 10:50:31 +00004896 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004897
4898 if (image == (Image *) NULL)
4899 break;
Cristyb1710fe2017-02-11 13:51:48 -05004900 (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004901 image->resolution.x,image->resolution.y);
4902 s=newSVpv(geometry,0);
4903 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4904 continue;
4905 }
4906 if (LocaleCompare(attribute,"delay") == 0)
4907 {
4908 if (image != (Image *) NULL)
4909 s=newSViv((ssize_t) image->delay);
4910 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4911 continue;
4912 }
4913 if (LocaleCompare(attribute,"depth") == 0)
4914 {
4915 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4916 if (image != (Image *) NULL)
4917 s=newSViv((ssize_t) GetImageDepth(image,exception));
4918 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4919 continue;
4920 }
4921 if (LocaleCompare(attribute,"directory") == 0)
4922 {
4923 if (image && image->directory)
4924 s=newSVpv(image->directory,0);
4925 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4926 continue;
4927 }
4928 if (LocaleCompare(attribute,"dispose") == 0)
4929 {
4930 if (image == (Image *) NULL)
4931 break;
4932
4933 s=newSViv(image->dispose);
4934 (void) sv_setpv(s,
4935 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
4936 SvIOK_on(s);
4937 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4938 continue;
4939 }
4940 if (LocaleCompare(attribute,"disk") == 0)
4941 {
4942 s=newSViv(GetMagickResource(DiskResource));
4943 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4944 continue;
4945 }
4946 if (LocaleCompare(attribute,"dither") == 0)
4947 {
4948 if (info)
4949 s=newSViv((ssize_t) info->image_info->dither);
4950 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4951 continue;
4952 }
4953 if (LocaleCompare(attribute,"display") == 0) /* same as server */
4954 {
4955 if (info && info->image_info->server_name)
4956 s=newSVpv(info->image_info->server_name,0);
4957 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4958 continue;
4959 }
4960 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4961 attribute);
4962 break;
4963 }
4964 case 'E':
4965 case 'e':
4966 {
4967 if (LocaleCompare(attribute,"elapsed-time") == 0)
4968 {
4969 if (image != (Image *) NULL)
4970 s=newSVnv(GetElapsedTime(&image->timer));
4971 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4972 continue;
4973 }
4974 if (LocaleCompare(attribute,"endian") == 0)
4975 {
4976 j=info ? info->image_info->endian : image ? image->endian :
4977 UndefinedEndian;
4978 s=newSViv(j);
4979 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
4980 SvIOK_on(s);
4981 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4982 continue;
4983 }
4984 if (LocaleCompare(attribute,"error") == 0)
4985 {
4986 if (image != (Image *) NULL)
4987 s=newSVnv(image->error.mean_error_per_pixel);
4988 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4989 continue;
4990 }
4991 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4992 attribute);
4993 break;
4994 }
4995 case 'F':
4996 case 'f':
4997 {
4998 if (LocaleCompare(attribute,"filesize") == 0)
4999 {
5000 if (image != (Image *) NULL)
5001 s=newSViv((ssize_t) GetBlobSize(image));
5002 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5003 continue;
5004 }
5005 if (LocaleCompare(attribute,"filename") == 0)
5006 {
5007 if (info && info->image_info->filename &&
5008 *info->image_info->filename)
5009 s=newSVpv(info->image_info->filename,0);
5010 if (image != (Image *) NULL)
5011 s=newSVpv(image->filename,0);
5012 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5013 continue;
5014 }
5015 if (LocaleCompare(attribute,"filter") == 0)
5016 {
5017 s=image ? newSViv(image->filter) : newSViv(0);
5018 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5019 image->filter));
5020 SvIOK_on(s);
5021 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5022 continue;
5023 }
5024 if (LocaleCompare(attribute,"font") == 0)
5025 {
5026 if (info && info->image_info->font)
5027 s=newSVpv(info->image_info->font,0);
5028 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5029 continue;
5030 }
5031 if (LocaleCompare(attribute,"foreground") == 0)
5032 continue;
5033 if (LocaleCompare(attribute,"format") == 0)
5034 {
5035 const MagickInfo
5036 *magick_info;
5037
5038 magick_info=(const MagickInfo *) NULL;
5039 if (info && (*info->image_info->magick != '\0'))
5040 magick_info=GetMagickInfo(info->image_info->magick,exception);
5041 if (image != (Image *) NULL)
5042 magick_info=GetMagickInfo(image->magick,exception);
5043 if ((magick_info != (const MagickInfo *) NULL) &&
5044 (*magick_info->description != '\0'))
5045 s=newSVpv((char *) magick_info->description,0);
5046 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5047 continue;
5048 }
5049 if (LocaleCompare(attribute,"fuzz") == 0)
5050 {
5051 if (info)
5052 s=newSVnv(info->image_info->fuzz);
5053 if (image != (Image *) NULL)
5054 s=newSVnv(image->fuzz);
5055 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5056 continue;
5057 }
5058 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5059 attribute);
5060 break;
5061 }
5062 case 'G':
5063 case 'g':
5064 {
5065 if (LocaleCompare(attribute,"gamma") == 0)
5066 {
5067 if (image != (Image *) NULL)
5068 s=newSVnv(image->gamma);
5069 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5070 continue;
5071 }
5072 if (LocaleCompare(attribute,"geometry") == 0)
5073 {
5074 if (image && image->geometry)
5075 s=newSVpv(image->geometry,0);
5076 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5077 continue;
5078 }
5079 if (LocaleCompare(attribute,"gravity") == 0)
5080 {
5081 s=image ? newSViv(image->gravity) : newSViv(0);
5082 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5083 image->gravity));
5084 SvIOK_on(s);
5085 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5086 continue;
5087 }
5088 if (LocaleCompare(attribute,"green-primary") == 0)
5089 {
5090 if (image == (Image *) NULL)
5091 break;
Cristyb1710fe2017-02-11 13:51:48 -05005092 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005093 image->chromaticity.green_primary.x,
5094 image->chromaticity.green_primary.y);
5095 s=newSVpv(color,0);
5096 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5097 continue;
5098 }
5099 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5100 attribute);
5101 break;
5102 }
5103 case 'H':
5104 case 'h':
5105 {
5106 if (LocaleCompare(attribute,"height") == 0)
5107 {
5108 if (image != (Image *) NULL)
5109 s=newSViv((ssize_t) image->rows);
5110 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5111 continue;
5112 }
5113 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5114 attribute);
5115 break;
5116 }
5117 case 'I':
5118 case 'i':
5119 {
5120 if (LocaleCompare(attribute,"icc") == 0)
5121 {
5122 if (image != (Image *) NULL)
5123 {
5124 const StringInfo
5125 *profile;
5126
5127 profile=GetImageProfile(image,"icc");
5128 if (profile != (StringInfo *) NULL)
5129 s=newSVpv((const char *) GetStringInfoDatum(profile),
5130 GetStringInfoLength(profile));
5131 }
5132 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5133 continue;
5134 }
5135 if (LocaleCompare(attribute,"icm") == 0)
5136 {
5137 if (image != (Image *) NULL)
5138 {
5139 const StringInfo
5140 *profile;
5141
5142 profile=GetImageProfile(image,"icm");
5143 if (profile != (const StringInfo *) NULL)
5144 s=newSVpv((const char *) GetStringInfoDatum(profile),
5145 GetStringInfoLength(profile));
5146 }
5147 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5148 continue;
5149 }
5150 if (LocaleCompare(attribute,"id") == 0)
5151 {
5152 if (image != (Image *) NULL)
5153 {
5154 char
cristy151b66d2015-04-15 10:50:31 +00005155 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005156
5157 MagickBooleanType
5158 status;
5159
5160 static ssize_t
5161 id = 0;
5162
cristy151b66d2015-04-15 10:50:31 +00005163 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005164 id);
5165 status=SetImageRegistry(ImageRegistryType,key,image,
5166 exception);
5167 (void) status;
5168 s=newSViv(id++);
5169 }
5170 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5171 continue;
5172 }
5173 if (LocaleNCompare(attribute,"index",5) == 0)
5174 {
5175 char
cristy151b66d2015-04-15 10:50:31 +00005176 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005177
5178 int
5179 items;
5180
5181 long
5182 x,
5183 y;
5184
5185 register const Quantum
5186 *p;
5187
5188 CacheView
5189 *image_view;
5190
5191 if (image == (Image *) NULL)
5192 break;
5193 if (image->storage_class != PseudoClass)
5194 break;
5195 x=0;
5196 y=0;
5197 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5198 (void) items;
5199 image_view=AcquireVirtualCacheView(image,exception);
5200 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5201 if (p != (const Quantum *) NULL)
5202 {
cristy151b66d2015-04-15 10:50:31 +00005203 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005204 GetPixelIndex(image,p));
5205 s=newSVpv(name,0);
5206 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5207 }
5208 image_view=DestroyCacheView(image_view);
5209 continue;
5210 }
5211 if (LocaleCompare(attribute,"iptc") == 0)
5212 {
5213 if (image != (Image *) NULL)
5214 {
5215 const StringInfo
5216 *profile;
5217
5218 profile=GetImageProfile(image,"iptc");
5219 if (profile != (const StringInfo *) NULL)
5220 s=newSVpv((const char *) GetStringInfoDatum(profile),
5221 GetStringInfoLength(profile));
5222 }
5223 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5224 continue;
5225 }
5226 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5227 {
5228 if (image != (Image *) NULL)
5229 s=newSViv((ssize_t) image->iterations);
5230 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5231 continue;
5232 }
5233 if (LocaleCompare(attribute,"interlace") == 0)
5234 {
5235 j=info ? info->image_info->interlace : image ? image->interlace :
5236 UndefinedInterlace;
5237 s=newSViv(j);
5238 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5239 j));
5240 SvIOK_on(s);
5241 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5242 continue;
5243 }
5244 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5245 attribute);
5246 break;
5247 }
5248 case 'L':
5249 case 'l':
5250 {
5251 if (LocaleCompare(attribute,"label") == 0)
5252 {
5253 const char
5254 *value;
5255
5256 if (image == (Image *) NULL)
5257 break;
5258 value=GetImageProperty(image,"Label",exception);
5259 if (value != (const char *) NULL)
5260 s=newSVpv(value,0);
5261 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5262 continue;
5263 }
5264 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5265 {
5266 if (image != (Image *) NULL)
5267 s=newSViv((ssize_t) image->iterations);
5268 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5269 continue;
5270 }
5271 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5272 attribute);
5273 break;
5274 }
5275 case 'M':
5276 case 'm':
5277 {
5278 if (LocaleCompare(attribute,"magick") == 0)
5279 {
5280 if (info && *info->image_info->magick)
5281 s=newSVpv(info->image_info->magick,0);
5282 if (image != (Image *) NULL)
5283 s=newSVpv(image->magick,0);
5284 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5285 continue;
5286 }
5287 if (LocaleCompare(attribute,"map") == 0)
5288 {
5289 s=newSViv(GetMagickResource(MapResource));
5290 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5291 continue;
5292 }
5293 if (LocaleCompare(attribute,"maximum-error") == 0)
5294 {
5295 if (image != (Image *) NULL)
5296 s=newSVnv(image->error.normalized_maximum_error);
5297 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5298 continue;
5299 }
5300 if (LocaleCompare(attribute,"memory") == 0)
5301 {
5302 s=newSViv(GetMagickResource(MemoryResource));
5303 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5304 continue;
5305 }
5306 if (LocaleCompare(attribute,"mean-error") == 0)
5307 {
5308 if (image != (Image *) NULL)
5309 s=newSVnv(image->error.normalized_mean_error);
5310 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5311 continue;
5312 }
5313 if (LocaleCompare(attribute,"mime") == 0)
5314 {
5315 if (info && *info->image_info->magick)
5316 s=newSVpv(MagickToMime(info->image_info->magick),0);
5317 if (image != (Image *) NULL)
5318 s=newSVpv(MagickToMime(image->magick),0);
5319 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5320 continue;
5321 }
5322 if (LocaleCompare(attribute,"mattecolor") == 0)
5323 {
5324 if (image == (Image *) NULL)
5325 break;
cristy151b66d2015-04-15 10:50:31 +00005326 (void) FormatLocaleString(color,MagickPathExtent,
Cristy8645e042016-02-03 16:35:29 -05005327 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5328 (double) image->alpha_color.green,
5329 (double) image->alpha_color.blue,
5330 (double) image->alpha_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005331 s=newSVpv(color,0);
5332 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5333 continue;
5334 }
5335 if (LocaleCompare(attribute,"matte") == 0)
5336 {
5337 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005338 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005339 1 : 0);
5340 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5341 continue;
5342 }
5343 if (LocaleCompare(attribute,"mime") == 0)
5344 {
5345 const char
5346 *magick;
5347
5348 magick=NULL;
5349 if (info && *info->image_info->magick)
5350 magick=info->image_info->magick;
5351 if (image != (Image *) NULL)
5352 magick=image->magick;
5353 if (magick)
5354 {
5355 char
5356 *mime;
5357
5358 mime=MagickToMime(magick);
5359 s=newSVpv(mime,0);
5360 mime=(char *) RelinquishMagickMemory(mime);
5361 }
5362 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5363 continue;
5364 }
5365 if (LocaleCompare(attribute,"monochrome") == 0)
5366 {
5367 if (image == (Image *) NULL)
5368 continue;
5369 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005370 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005371 s=newSViv(j);
5372 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5373 continue;
5374 }
5375 if (LocaleCompare(attribute,"montage") == 0)
5376 {
5377 if (image && image->montage)
5378 s=newSVpv(image->montage,0);
5379 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5380 continue;
5381 }
5382 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5383 attribute);
5384 break;
5385 }
5386 case 'O':
5387 case 'o':
5388 {
5389 if (LocaleCompare(attribute,"orientation") == 0)
5390 {
5391 j=info ? info->image_info->orientation : image ?
5392 image->orientation : UndefinedOrientation;
5393 s=newSViv(j);
5394 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5395 j));
5396 SvIOK_on(s);
5397 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5398 continue;
5399 }
5400 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5401 attribute);
5402 break;
5403 }
5404 case 'P':
5405 case 'p':
5406 {
5407 if (LocaleCompare(attribute,"page") == 0)
5408 {
5409 if (info && info->image_info->page)
5410 s=newSVpv(info->image_info->page,0);
5411 if (image != (Image *) NULL)
5412 {
5413 char
cristy151b66d2015-04-15 10:50:31 +00005414 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005415
cristy151b66d2015-04-15 10:50:31 +00005416 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005417 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5418 (double) image->page.height,(double) image->page.x,(double)
5419 image->page.y);
5420 s=newSVpv(geometry,0);
5421 }
5422 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5423 continue;
5424 }
5425 if (LocaleCompare(attribute,"page.x") == 0)
5426 {
5427 if (image != (Image *) NULL)
5428 s=newSViv((ssize_t) image->page.x);
5429 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5430 continue;
5431 }
5432 if (LocaleCompare(attribute,"page.y") == 0)
5433 {
5434 if (image != (Image *) NULL)
5435 s=newSViv((ssize_t) image->page.y);
5436 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5437 continue;
5438 }
5439 if (LocaleNCompare(attribute,"pixel",5) == 0)
5440 {
5441 char
cristy151b66d2015-04-15 10:50:31 +00005442 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005443
5444 int
5445 items;
5446
5447 long
5448 x,
5449 y;
5450
5451 register const Quantum
5452 *p;
5453
5454 if (image == (Image *) NULL)
5455 break;
5456 x=0;
5457 y=0;
5458 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5459 (void) items;
5460 p=GetVirtualPixels(image,x,y,1,1,exception);
5461 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005462 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005463 QuantumFormat "," QuantumFormat "," QuantumFormat,
5464 GetPixelRed(image,p),GetPixelGreen(image,p),
5465 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5466 else
cristy151b66d2015-04-15 10:50:31 +00005467 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005468 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5469 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5470 GetPixelBlue(image,p),GetPixelBlack(image,p),
5471 GetPixelAlpha(image,p));
5472 s=newSVpv(tuple,0);
5473 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5474 continue;
5475 }
5476 if (LocaleCompare(attribute,"pointsize") == 0)
5477 {
5478 if (info)
5479 s=newSViv((ssize_t) info->image_info->pointsize);
5480 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5481 continue;
5482 }
cristy4a3ce0a2013-08-03 20:06:59 +00005483 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5484 attribute);
5485 break;
5486 }
5487 case 'Q':
5488 case 'q':
5489 {
5490 if (LocaleCompare(attribute,"quality") == 0)
5491 {
5492 if (info)
5493 s=newSViv((ssize_t) info->image_info->quality);
5494 if (image != (Image *) NULL)
5495 s=newSViv((ssize_t) image->quality);
5496 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5497 continue;
5498 }
5499 if (LocaleCompare(attribute,"quantum") == 0)
5500 {
5501 if (info)
5502 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5503 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5504 continue;
5505 }
5506 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5507 attribute);
5508 break;
5509 }
5510 case 'R':
5511 case 'r':
5512 {
5513 if (LocaleCompare(attribute,"rendering-intent") == 0)
5514 {
5515 s=newSViv(image->rendering_intent);
5516 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5517 image->rendering_intent));
5518 SvIOK_on(s);
5519 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5520 continue;
5521 }
5522 if (LocaleCompare(attribute,"red-primary") == 0)
5523 {
5524 if (image == (Image *) NULL)
5525 break;
Cristyb1710fe2017-02-11 13:51:48 -05005526 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005527 image->chromaticity.red_primary.x,
5528 image->chromaticity.red_primary.y);
5529 s=newSVpv(color,0);
5530 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5531 continue;
5532 }
5533 if (LocaleCompare(attribute,"rows") == 0)
5534 {
5535 if (image != (Image *) NULL)
5536 s=newSViv((ssize_t) image->rows);
5537 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5538 continue;
5539 }
5540 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5541 attribute);
5542 break;
5543 }
5544 case 'S':
5545 case 's':
5546 {
5547 if (LocaleCompare(attribute,"sampling-factor") == 0)
5548 {
5549 if (info && info->image_info->sampling_factor)
5550 s=newSVpv(info->image_info->sampling_factor,0);
5551 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5552 continue;
5553 }
5554 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5555 {
5556 if (info && info->image_info->server_name)
5557 s=newSVpv(info->image_info->server_name,0);
5558 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5559 continue;
5560 }
5561 if (LocaleCompare(attribute,"size") == 0)
5562 {
5563 if (info && info->image_info->size)
5564 s=newSVpv(info->image_info->size,0);
5565 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5566 continue;
5567 }
5568 if (LocaleCompare(attribute,"scene") == 0)
5569 {
5570 if (image != (Image *) NULL)
5571 s=newSViv((ssize_t) image->scene);
5572 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5573 continue;
5574 }
5575 if (LocaleCompare(attribute,"scenes") == 0)
5576 {
5577 if (image != (Image *) NULL)
5578 s=newSViv((ssize_t) info->image_info->number_scenes);
5579 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5580 continue;
5581 }
5582 if (LocaleCompare(attribute,"signature") == 0)
5583 {
5584 const char
5585 *value;
5586
5587 if (image == (Image *) NULL)
5588 break;
5589 (void) SignatureImage(image,exception);
5590 value=GetImageProperty(image,"Signature",exception);
5591 if (value != (const char *) NULL)
5592 s=newSVpv(value,0);
5593 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5594 continue;
5595 }
5596 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5597 attribute);
5598 break;
5599 }
5600 case 'T':
5601 case 't':
5602 {
5603 if (LocaleCompare(attribute,"taint") == 0)
5604 {
5605 if (image != (Image *) NULL)
5606 s=newSViv((ssize_t) IsTaintImage(image));
5607 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5608 continue;
5609 }
5610 if (LocaleCompare(attribute,"texture") == 0)
5611 {
5612 if (info && info->image_info->texture)
5613 s=newSVpv(info->image_info->texture,0);
5614 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5615 continue;
5616 }
5617 if (LocaleCompare(attribute,"total-ink-density") == 0)
5618 {
5619 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5620 if (image != (Image *) NULL)
5621 s=newSVnv(GetImageTotalInkDensity(image,exception));
5622 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5623 continue;
5624 }
5625 if (LocaleCompare(attribute,"transparent-color") == 0)
5626 {
5627 if (image == (Image *) NULL)
5628 break;
cristy151b66d2015-04-15 10:50:31 +00005629 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005630 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5631 (double) image->transparent_color.green,
5632 (double) image->transparent_color.blue,
5633 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005634 s=newSVpv(color,0);
5635 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5636 continue;
5637 }
5638 if (LocaleCompare(attribute,"type") == 0)
5639 {
5640 if (image == (Image *) NULL)
5641 break;
cristya26f54c2015-07-29 12:26:12 +00005642 j=(ssize_t) GetImageType(image);
cristy4a3ce0a2013-08-03 20:06:59 +00005643 s=newSViv(j);
5644 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5645 SvIOK_on(s);
5646 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5647 continue;
5648 }
5649 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5650 attribute);
5651 break;
5652 }
5653 case 'U':
5654 case 'u':
5655 {
5656 if (LocaleCompare(attribute,"units") == 0)
5657 {
5658 j=info ? info->image_info->units : image ? image->units :
5659 UndefinedResolution;
5660 if (info && (info->image_info->units == UndefinedResolution))
5661 if (image)
5662 j=image->units;
5663 if (j == UndefinedResolution)
5664 s=newSVpv("undefined units",0);
5665 else
5666 if (j == PixelsPerInchResolution)
5667 s=newSVpv("pixels / inch",0);
5668 else
5669 s=newSVpv("pixels / centimeter",0);
5670 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5671 continue;
5672 }
5673 if (LocaleCompare(attribute,"user-time") == 0)
5674 {
5675 if (image != (Image *) NULL)
5676 s=newSVnv(GetUserTime(&image->timer));
5677 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5678 continue;
5679 }
5680 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5681 attribute);
5682 break;
5683 }
5684 case 'V':
5685 case 'v':
5686 {
5687 if (LocaleCompare(attribute,"verbose") == 0)
5688 {
5689 if (info)
5690 s=newSViv((ssize_t) info->image_info->verbose);
5691 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5692 continue;
5693 }
5694 if (LocaleCompare(attribute,"version") == 0)
5695 {
5696 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5697 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5698 continue;
5699 }
cristy4a3ce0a2013-08-03 20:06:59 +00005700 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5701 {
5702 if (image == (Image *) NULL)
5703 break;
5704 j=(ssize_t) GetImageVirtualPixelMethod(image);
5705 s=newSViv(j);
5706 (void) sv_setpv(s,CommandOptionToMnemonic(
5707 MagickVirtualPixelOptions,j));
5708 SvIOK_on(s);
5709 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5710 continue;
5711 }
5712 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5713 attribute);
5714 break;
5715 }
5716 case 'W':
5717 case 'w':
5718 {
5719 if (LocaleCompare(attribute,"white-point") == 0)
5720 {
5721 if (image == (Image *) NULL)
5722 break;
Cristyb1710fe2017-02-11 13:51:48 -05005723 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005724 image->chromaticity.white_point.x,
5725 image->chromaticity.white_point.y);
5726 s=newSVpv(color,0);
5727 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5728 continue;
5729 }
5730 if (LocaleCompare(attribute,"width") == 0)
5731 {
5732 if (image != (Image *) NULL)
5733 s=newSViv((ssize_t) image->columns);
5734 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5735 continue;
5736 }
5737 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5738 attribute);
5739 break;
5740 }
5741 case 'X':
5742 case 'x':
5743 {
Cristyc1f9f9f2016-01-05 08:19:28 -05005744 if (LocaleCompare(attribute,"xmp") == 0)
5745 {
5746 if (image != (Image *) NULL)
5747 {
5748 const StringInfo
5749 *profile;
5750
5751 profile=GetImageProfile(image,"xmp");
5752 if (profile != (StringInfo *) NULL)
5753 s=newSVpv((const char *) GetStringInfoDatum(profile),
5754 GetStringInfoLength(profile));
5755 }
5756 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5757 continue;
5758 }
cristy4a3ce0a2013-08-03 20:06:59 +00005759 if (LocaleCompare(attribute,"x-resolution") == 0)
5760 {
5761 if (image != (Image *) NULL)
5762 s=newSVnv(image->resolution.x);
5763 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5764 continue;
5765 }
5766 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5767 attribute);
5768 break;
5769 }
5770 case 'Y':
5771 case 'y':
5772 {
5773 if (LocaleCompare(attribute,"y-resolution") == 0)
5774 {
5775 if (image != (Image *) NULL)
5776 s=newSVnv(image->resolution.y);
5777 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5778 continue;
5779 }
5780 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5781 attribute);
5782 break;
5783 }
5784 default:
5785 break;
5786 }
5787 if (image == (Image *) NULL)
5788 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5789 attribute)
5790 else
5791 {
5792 value=GetImageProperty(image,attribute,exception);
5793 if (value != (const char *) NULL)
5794 {
5795 s=newSVpv(value,0);
5796 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5797 }
5798 else
5799 if (*attribute != '%')
5800 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5801 attribute)
5802 else
5803 {
5804 char
5805 *meta;
5806
5807 meta=InterpretImageProperties(info ? info->image_info :
5808 (ImageInfo *) NULL,image,attribute,exception);
5809 s=newSVpv(meta,0);
5810 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5811 meta=(char *) RelinquishMagickMemory(meta);
5812 }
5813 }
5814 }
5815 exception=DestroyExceptionInfo(exception);
5816 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5817 }
5818
5819#
5820###############################################################################
5821# #
5822# #
5823# #
5824# G e t A u t h e n t i c P i x e l s #
5825# #
5826# #
5827# #
5828###############################################################################
5829#
5830#
5831void *
5832GetAuthenticPixels(ref,...)
5833 Image::Magick ref = NO_INIT
5834 ALIAS:
5835 getauthenticpixels = 1
5836 GetImagePixels = 2
5837 getimagepixels = 3
5838 CODE:
5839 {
5840 char
5841 *attribute;
5842
5843 ExceptionInfo
5844 *exception;
5845
5846 Image
5847 *image;
5848
5849 RectangleInfo
5850 region;
5851
5852 ssize_t
5853 i;
5854
5855 struct PackageInfo
5856 *info;
5857
5858 SV
5859 *perl_exception,
5860 *reference;
5861
5862 void
5863 *blob = NULL;
5864
5865 PERL_UNUSED_VAR(ref);
5866 PERL_UNUSED_VAR(ix);
5867 exception=AcquireExceptionInfo();
5868 perl_exception=newSVpv("",0);
5869 if (sv_isobject(ST(0)) == 0)
5870 {
5871 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5872 PackageName);
5873 goto PerlException;
5874 }
5875 reference=SvRV(ST(0));
5876
5877 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5878 if (image == (Image *) NULL)
5879 {
5880 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5881 PackageName);
5882 goto PerlException;
5883 }
5884
5885 region.x=0;
5886 region.y=0;
5887 region.width=image->columns;
5888 region.height=1;
5889 if (items == 1)
5890 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5891 for (i=2; i < items; i+=2)
5892 {
5893 attribute=(char *) SvPV(ST(i-1),na);
5894 switch (*attribute)
5895 {
5896 case 'g':
5897 case 'G':
5898 {
5899 if (LocaleCompare(attribute,"geometry") == 0)
5900 {
5901 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5902 break;
5903 }
5904 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5905 attribute);
5906 break;
5907 }
5908 case 'H':
5909 case 'h':
5910 {
5911 if (LocaleCompare(attribute,"height") == 0)
5912 {
5913 region.height=SvIV(ST(i));
5914 continue;
5915 }
5916 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5917 attribute);
5918 break;
5919 }
5920 case 'X':
5921 case 'x':
5922 {
5923 if (LocaleCompare(attribute,"x") == 0)
5924 {
5925 region.x=SvIV(ST(i));
5926 continue;
5927 }
5928 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5929 attribute);
5930 break;
5931 }
5932 case 'Y':
5933 case 'y':
5934 {
5935 if (LocaleCompare(attribute,"y") == 0)
5936 {
5937 region.y=SvIV(ST(i));
5938 continue;
5939 }
5940 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5941 attribute);
5942 break;
5943 }
5944 case 'W':
5945 case 'w':
5946 {
5947 if (LocaleCompare(attribute,"width") == 0)
5948 {
5949 region.width=SvIV(ST(i));
5950 continue;
5951 }
5952 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5953 attribute);
5954 break;
5955 }
5956 }
5957 }
5958 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5959 region.height,exception);
5960 if (blob != (void *) NULL)
5961 goto PerlEnd;
5962
5963 PerlException:
5964 InheritPerlException(exception,perl_exception);
5965 exception=DestroyExceptionInfo(exception);
5966 SvREFCNT_dec(perl_exception); /* throw away all errors */
5967
5968 PerlEnd:
5969 RETVAL = blob;
5970 }
5971 OUTPUT:
5972 RETVAL
5973
5974#
5975###############################################################################
5976# #
5977# #
5978# #
5979# G e t V i r t u a l P i x e l s #
5980# #
5981# #
5982# #
5983###############################################################################
5984#
5985#
5986void *
5987GetVirtualPixels(ref,...)
5988 Image::Magick ref = NO_INIT
5989 ALIAS:
5990 getvirtualpixels = 1
5991 AcquireImagePixels = 2
5992 acquireimagepixels = 3
5993 CODE:
5994 {
5995 char
5996 *attribute;
5997
5998 const void
5999 *blob = NULL;
6000
6001 ExceptionInfo
6002 *exception;
6003
6004 Image
6005 *image;
6006
6007 RectangleInfo
6008 region;
6009
6010 ssize_t
6011 i;
6012
6013 struct PackageInfo
6014 *info;
6015
6016 SV
6017 *perl_exception,
6018 *reference;
6019
6020 PERL_UNUSED_VAR(ref);
6021 PERL_UNUSED_VAR(ix);
6022 exception=AcquireExceptionInfo();
6023 perl_exception=newSVpv("",0);
6024 if (sv_isobject(ST(0)) == 0)
6025 {
6026 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6027 PackageName);
6028 goto PerlException;
6029 }
6030 reference=SvRV(ST(0));
6031
6032 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6033 if (image == (Image *) NULL)
6034 {
6035 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6036 PackageName);
6037 goto PerlException;
6038 }
6039
6040 region.x=0;
6041 region.y=0;
6042 region.width=image->columns;
6043 region.height=1;
6044 if (items == 1)
6045 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6046 for (i=2; i < items; i+=2)
6047 {
6048 attribute=(char *) SvPV(ST(i-1),na);
6049 switch (*attribute)
6050 {
6051 case 'g':
6052 case 'G':
6053 {
6054 if (LocaleCompare(attribute,"geometry") == 0)
6055 {
6056 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6057 break;
6058 }
6059 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6060 attribute);
6061 break;
6062 }
6063 case 'H':
6064 case 'h':
6065 {
6066 if (LocaleCompare(attribute,"height") == 0)
6067 {
6068 region.height=SvIV(ST(i));
6069 continue;
6070 }
6071 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6072 attribute);
6073 break;
6074 }
6075 case 'X':
6076 case 'x':
6077 {
6078 if (LocaleCompare(attribute,"x") == 0)
6079 {
6080 region.x=SvIV(ST(i));
6081 continue;
6082 }
6083 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6084 attribute);
6085 break;
6086 }
6087 case 'Y':
6088 case 'y':
6089 {
6090 if (LocaleCompare(attribute,"y") == 0)
6091 {
6092 region.y=SvIV(ST(i));
6093 continue;
6094 }
6095 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6096 attribute);
6097 break;
6098 }
6099 case 'W':
6100 case 'w':
6101 {
6102 if (LocaleCompare(attribute,"width") == 0)
6103 {
6104 region.width=SvIV(ST(i));
6105 continue;
6106 }
6107 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6108 attribute);
6109 break;
6110 }
6111 }
6112 }
6113 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6114 region.height,exception);
6115 if (blob != (void *) NULL)
6116 goto PerlEnd;
6117
6118 PerlException:
6119 InheritPerlException(exception,perl_exception);
6120 exception=DestroyExceptionInfo(exception);
6121 SvREFCNT_dec(perl_exception); /* throw away all errors */
6122
6123 PerlEnd:
6124 RETVAL = (void *) blob;
6125 }
6126 OUTPUT:
6127 RETVAL
6128
6129#
6130###############################################################################
6131# #
6132# #
6133# #
6134# G e t A u t h e n t i c M e t a c o n t e n t #
6135# #
6136# #
6137# #
6138###############################################################################
6139#
6140#
6141void *
6142GetAuthenticMetacontent(ref,...)
6143 Image::Magick ref = NO_INIT
6144 ALIAS:
6145 getauthenticmetacontent = 1
6146 GetMetacontent = 2
6147 getmetacontent = 3
6148 CODE:
6149 {
6150 ExceptionInfo
6151 *exception;
6152
6153 Image
6154 *image;
6155
6156 struct PackageInfo
6157 *info;
6158
6159 SV
6160 *perl_exception,
6161 *reference;
6162
6163 void
6164 *blob = NULL;
6165
6166 PERL_UNUSED_VAR(ref);
6167 PERL_UNUSED_VAR(ix);
6168 exception=AcquireExceptionInfo();
6169 perl_exception=newSVpv("",0);
6170 if (sv_isobject(ST(0)) == 0)
6171 {
6172 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6173 PackageName);
6174 goto PerlException;
6175 }
6176 reference=SvRV(ST(0));
6177
6178 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6179 if (image == (Image *) NULL)
6180 {
6181 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6182 PackageName);
6183 goto PerlException;
6184 }
6185
6186 blob=(void *) GetAuthenticMetacontent(image);
6187 if (blob != (void *) NULL)
6188 goto PerlEnd;
6189
6190 PerlException:
6191 InheritPerlException(exception,perl_exception);
6192 exception=DestroyExceptionInfo(exception);
6193 SvREFCNT_dec(perl_exception); /* throw away all errors */
6194
6195 PerlEnd:
6196 RETVAL = blob;
6197 }
6198 OUTPUT:
6199 RETVAL
6200
6201#
6202###############################################################################
6203# #
6204# #
6205# #
6206# G e t V i r t u a l M e t a c o n t e n t #
6207# #
6208# #
6209# #
6210###############################################################################
6211#
6212#
6213void *
6214GetVirtualMetacontent(ref,...)
6215 Image::Magick ref = NO_INIT
6216 ALIAS:
6217 getvirtualmetacontent = 1
6218 CODE:
6219 {
6220 ExceptionInfo
6221 *exception;
6222
6223 Image
6224 *image;
6225
6226 struct PackageInfo
6227 *info;
6228
6229 SV
6230 *perl_exception,
6231 *reference;
6232
6233 void
6234 *blob = NULL;
6235
6236 PERL_UNUSED_VAR(ref);
6237 PERL_UNUSED_VAR(ix);
6238 exception=AcquireExceptionInfo();
6239 perl_exception=newSVpv("",0);
6240 if (sv_isobject(ST(0)) == 0)
6241 {
6242 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6243 PackageName);
6244 goto PerlException;
6245 }
6246 reference=SvRV(ST(0));
6247
6248 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6249 if (image == (Image *) NULL)
6250 {
6251 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6252 PackageName);
6253 goto PerlException;
6254 }
6255
6256 blob=(void *) GetVirtualMetacontent(image);
6257 if (blob != (void *) NULL)
6258 goto PerlEnd;
6259
6260 PerlException:
6261 InheritPerlException(exception,perl_exception);
6262 exception=DestroyExceptionInfo(exception);
6263 SvREFCNT_dec(perl_exception); /* throw away all errors */
6264
6265 PerlEnd:
6266 RETVAL = blob;
6267 }
6268 OUTPUT:
6269 RETVAL
6270
6271#
6272###############################################################################
6273# #
6274# #
6275# #
6276# H i s t o g r a m #
6277# #
6278# #
6279# #
6280###############################################################################
6281#
6282#
6283void
6284Histogram(ref,...)
6285 Image::Magick ref=NO_INIT
6286 ALIAS:
6287 HistogramImage = 1
6288 histogram = 2
6289 histogramimage = 3
6290 PPCODE:
6291 {
6292 AV
6293 *av;
6294
6295 char
cristy151b66d2015-04-15 10:50:31 +00006296 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006297
6298 PixelInfo
6299 *histogram;
6300
6301 ExceptionInfo
6302 *exception;
6303
6304 Image
6305 *image;
6306
6307 register ssize_t
6308 i;
6309
6310 ssize_t
6311 count;
6312
6313 struct PackageInfo
6314 *info;
6315
6316 SV
6317 *perl_exception,
6318 *reference;
6319
6320 size_t
6321 number_colors;
6322
6323 PERL_UNUSED_VAR(ref);
6324 PERL_UNUSED_VAR(ix);
6325 exception=AcquireExceptionInfo();
6326 perl_exception=newSVpv("",0);
6327 av=NULL;
6328 if (sv_isobject(ST(0)) == 0)
6329 {
6330 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6331 PackageName);
6332 goto PerlException;
6333 }
6334 reference=SvRV(ST(0));
6335 av=newAV();
6336 SvREFCNT_dec(av);
6337 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6338 if (image == (Image *) NULL)
6339 {
6340 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6341 PackageName);
6342 goto PerlException;
6343 }
cristy4a3ce0a2013-08-03 20:06:59 +00006344 count=0;
6345 for ( ; image; image=image->next)
6346 {
6347 histogram=GetImageHistogram(image,&number_colors,exception);
6348 if (histogram == (PixelInfo *) NULL)
6349 continue;
6350 count+=(ssize_t) number_colors;
6351 EXTEND(sp,6*count);
6352 for (i=0; i < (ssize_t) number_colors; i++)
6353 {
cristy151b66d2015-04-15 10:50:31 +00006354 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006355 histogram[i].red);
6356 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006357 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006358 histogram[i].green);
6359 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006360 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006361 histogram[i].blue);
6362 PUSHs(sv_2mortal(newSVpv(message,0)));
6363 if (image->colorspace == CMYKColorspace)
6364 {
cristy151b66d2015-04-15 10:50:31 +00006365 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006366 histogram[i].black);
6367 PUSHs(sv_2mortal(newSVpv(message,0)));
6368 }
cristy151b66d2015-04-15 10:50:31 +00006369 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006370 histogram[i].alpha);
6371 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006372 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006373 histogram[i].count);
6374 PUSHs(sv_2mortal(newSVpv(message,0)));
6375 }
6376 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6377 }
6378
6379 PerlException:
6380 InheritPerlException(exception,perl_exception);
6381 exception=DestroyExceptionInfo(exception);
6382 SvREFCNT_dec(perl_exception);
6383 }
6384
6385#
6386###############################################################################
6387# #
6388# #
6389# #
6390# G e t P i x e l #
6391# #
6392# #
6393# #
6394###############################################################################
6395#
6396#
6397void
6398GetPixel(ref,...)
6399 Image::Magick ref=NO_INIT
6400 ALIAS:
6401 getpixel = 1
6402 getPixel = 2
6403 PPCODE:
6404 {
6405 AV
6406 *av;
6407
6408 char
6409 *attribute;
6410
6411 ExceptionInfo
6412 *exception;
6413
6414 Image
6415 *image;
6416
6417 MagickBooleanType
6418 normalize;
6419
6420 RectangleInfo
6421 region;
6422
6423 register const Quantum
6424 *p;
6425
6426 register ssize_t
6427 i;
6428
6429 ssize_t
6430 option;
6431
6432 struct PackageInfo
6433 *info;
6434
6435 SV
6436 *perl_exception,
6437 *reference; /* reference is the SV* of ref=SvIV(reference) */
6438
6439 PERL_UNUSED_VAR(ref);
6440 PERL_UNUSED_VAR(ix);
6441 exception=AcquireExceptionInfo();
6442 perl_exception=newSVpv("",0);
6443 reference=SvRV(ST(0));
6444 av=(AV *) reference;
6445 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6446 exception);
6447 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6448 if (image == (Image *) NULL)
6449 {
6450 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6451 PackageName);
6452 goto PerlException;
6453 }
6454 normalize=MagickTrue;
6455 region.x=0;
6456 region.y=0;
6457 region.width=image->columns;
6458 region.height=1;
6459 if (items == 1)
6460 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6461 for (i=2; i < items; i+=2)
6462 {
6463 attribute=(char *) SvPV(ST(i-1),na);
6464 switch (*attribute)
6465 {
6466 case 'C':
6467 case 'c':
6468 {
6469 if (LocaleCompare(attribute,"channel") == 0)
6470 {
6471 ssize_t
6472 option;
6473
6474 option=ParseChannelOption(SvPV(ST(i),na));
6475 if (option < 0)
6476 {
6477 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6478 SvPV(ST(i),na));
6479 return;
6480 }
cristybcd59342015-06-07 14:07:19 +00006481 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00006482 break;
6483 }
6484 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6485 attribute);
6486 break;
6487 }
6488 case 'g':
6489 case 'G':
6490 {
6491 if (LocaleCompare(attribute,"geometry") == 0)
6492 {
6493 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6494 break;
6495 }
6496 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6497 attribute);
6498 break;
6499 }
6500 case 'N':
6501 case 'n':
6502 {
6503 if (LocaleCompare(attribute,"normalize") == 0)
6504 {
6505 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6506 SvPV(ST(i),na));
6507 if (option < 0)
6508 {
6509 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6510 SvPV(ST(i),na));
6511 break;
6512 }
6513 normalize=option != 0 ? MagickTrue : MagickFalse;
6514 break;
6515 }
6516 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6517 attribute);
6518 break;
6519 }
6520 case 'x':
6521 case 'X':
6522 {
6523 if (LocaleCompare(attribute,"x") == 0)
6524 {
6525 region.x=SvIV(ST(i));
6526 break;
6527 }
6528 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6529 attribute);
6530 break;
6531 }
6532 case 'y':
6533 case 'Y':
6534 {
6535 if (LocaleCompare(attribute,"y") == 0)
6536 {
6537 region.y=SvIV(ST(i));
6538 break;
6539 }
6540 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6541 attribute);
6542 break;
6543 }
6544 default:
6545 {
6546 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6547 attribute);
6548 break;
6549 }
6550 }
6551 }
6552 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6553 if (p == (const Quantum *) NULL)
6554 PUSHs(&sv_undef);
6555 else
6556 {
6557 double
6558 scale;
6559
6560 scale=1.0;
6561 if (normalize != MagickFalse)
6562 scale=1.0/QuantumRange;
6563 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6564 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6565 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6566 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6567 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6568 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6569 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6570 (image->colorspace == CMYKColorspace))
6571 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6572 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6573 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6574 }
6575
6576 PerlException:
6577 InheritPerlException(exception,perl_exception);
6578 exception=DestroyExceptionInfo(exception);
6579 SvREFCNT_dec(perl_exception);
6580 }
6581
6582#
6583###############################################################################
6584# #
6585# #
6586# #
6587# G e t P i x e l s #
6588# #
6589# #
6590# #
6591###############################################################################
6592#
6593#
6594void
6595GetPixels(ref,...)
6596 Image::Magick ref=NO_INIT
6597 ALIAS:
6598 getpixels = 1
6599 getPixels = 2
6600 PPCODE:
6601 {
6602 AV
6603 *av;
6604
6605 char
6606 *attribute;
6607
6608 const char
6609 *map;
6610
6611 ExceptionInfo
6612 *exception;
6613
6614 Image
6615 *image;
6616
6617 MagickBooleanType
6618 normalize,
6619 status;
6620
6621 RectangleInfo
6622 region;
6623
6624 register ssize_t
6625 i;
6626
6627 ssize_t
6628 option;
6629
6630 struct PackageInfo
6631 *info;
6632
6633 SV
6634 *perl_exception,
6635 *reference; /* reference is the SV* of ref=SvIV(reference) */
6636
6637 PERL_UNUSED_VAR(ref);
6638 PERL_UNUSED_VAR(ix);
6639 exception=AcquireExceptionInfo();
6640 perl_exception=newSVpv("",0);
6641 reference=SvRV(ST(0));
6642 av=(AV *) reference;
6643 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6644 exception);
6645 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6646 if (image == (Image *) NULL)
6647 {
6648 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6649 PackageName);
6650 goto PerlException;
6651 }
6652 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006653 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006654 map="RGBA";
6655 if (image->colorspace == CMYKColorspace)
6656 {
6657 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006658 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006659 map="CMYKA";
6660 }
6661 normalize=MagickFalse;
6662 region.x=0;
6663 region.y=0;
6664 region.width=image->columns;
6665 region.height=1;
6666 if (items == 1)
6667 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6668 for (i=2; i < items; i+=2)
6669 {
6670 attribute=(char *) SvPV(ST(i-1),na);
6671 switch (*attribute)
6672 {
6673 case 'g':
6674 case 'G':
6675 {
6676 if (LocaleCompare(attribute,"geometry") == 0)
6677 {
6678 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6679 break;
6680 }
6681 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6682 attribute);
6683 break;
6684 }
6685 case 'H':
6686 case 'h':
6687 {
6688 if (LocaleCompare(attribute,"height") == 0)
6689 {
6690 region.height=SvIV(ST(i));
6691 break;
6692 }
6693 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6694 attribute);
6695 break;
6696 }
6697 case 'M':
6698 case 'm':
6699 {
6700 if (LocaleCompare(attribute,"map") == 0)
6701 {
6702 map=SvPV(ST(i),na);
6703 break;
6704 }
6705 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6706 attribute);
6707 break;
6708 }
6709 case 'N':
6710 case 'n':
6711 {
6712 if (LocaleCompare(attribute,"normalize") == 0)
6713 {
6714 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6715 SvPV(ST(i),na));
6716 if (option < 0)
6717 {
6718 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6719 SvPV(ST(i),na));
6720 break;
6721 }
6722 normalize=option != 0 ? MagickTrue : MagickFalse;
6723 break;
6724 }
6725 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6726 attribute);
6727 break;
6728 }
6729 case 'W':
6730 case 'w':
6731 {
6732 if (LocaleCompare(attribute,"width") == 0)
6733 {
6734 region.width=SvIV(ST(i));
6735 break;
6736 }
6737 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6738 attribute);
6739 break;
6740 }
6741 case 'x':
6742 case 'X':
6743 {
6744 if (LocaleCompare(attribute,"x") == 0)
6745 {
6746 region.x=SvIV(ST(i));
6747 break;
6748 }
6749 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6750 attribute);
6751 break;
6752 }
6753 case 'y':
6754 case 'Y':
6755 {
6756 if (LocaleCompare(attribute,"y") == 0)
6757 {
6758 region.y=SvIV(ST(i));
6759 break;
6760 }
6761 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6762 attribute);
6763 break;
6764 }
6765 default:
6766 {
6767 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6768 attribute);
6769 break;
6770 }
6771 }
6772 }
6773 if (normalize != MagickFalse)
6774 {
6775 float
6776 *pixels;
6777
6778 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6779 region.height*sizeof(*pixels));
6780 if (pixels == (float *) NULL)
6781 {
6782 ThrowPerlException(exception,ResourceLimitError,
6783 "MemoryAllocationFailed",PackageName);
6784 goto PerlException;
6785 }
6786 status=ExportImagePixels(image,region.x,region.y,region.width,
6787 region.height,map,FloatPixel,pixels,exception);
6788 if (status == MagickFalse)
6789 PUSHs(&sv_undef);
6790 else
6791 {
6792 EXTEND(sp,strlen(map)*region.width*region.height);
6793 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6794 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6795 }
6796 pixels=(float *) RelinquishMagickMemory(pixels);
6797 }
6798 else
6799 {
6800 Quantum
6801 *pixels;
6802
6803 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6804 region.height*sizeof(*pixels));
6805 if (pixels == (Quantum *) NULL)
6806 {
6807 ThrowPerlException(exception,ResourceLimitError,
6808 "MemoryAllocationFailed",PackageName);
6809 goto PerlException;
6810 }
6811 status=ExportImagePixels(image,region.x,region.y,region.width,
6812 region.height,map,QuantumPixel,pixels,exception);
6813 if (status == MagickFalse)
6814 PUSHs(&sv_undef);
6815 else
6816 {
6817 EXTEND(sp,strlen(map)*region.width*region.height);
6818 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6819 PUSHs(sv_2mortal(newSViv(pixels[i])));
6820 }
6821 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6822 }
6823
6824 PerlException:
6825 InheritPerlException(exception,perl_exception);
6826 exception=DestroyExceptionInfo(exception);
6827 SvREFCNT_dec(perl_exception);
6828 }
6829
6830#
6831###############################################################################
6832# #
6833# #
6834# #
6835# I m a g e T o B l o b #
6836# #
6837# #
6838# #
6839###############################################################################
6840#
6841#
6842void
6843ImageToBlob(ref,...)
6844 Image::Magick ref=NO_INIT
6845 ALIAS:
6846 ImageToBlob = 1
6847 imagetoblob = 2
6848 toblob = 3
6849 blob = 4
6850 PPCODE:
6851 {
6852 char
cristy151b66d2015-04-15 10:50:31 +00006853 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006854
6855 ExceptionInfo
6856 *exception;
6857
6858 Image
6859 *image,
6860 *next;
6861
6862 register ssize_t
6863 i;
6864
6865 struct PackageInfo
6866 *info,
6867 *package_info;
6868
6869 size_t
6870 length;
6871
6872 ssize_t
6873 scene;
6874
6875 SV
6876 *perl_exception,
6877 *reference;
6878
6879 void
6880 *blob;
6881
6882 PERL_UNUSED_VAR(ref);
6883 PERL_UNUSED_VAR(ix);
6884 exception=AcquireExceptionInfo();
6885 perl_exception=newSVpv("",0);
6886 package_info=(struct PackageInfo *) NULL;
6887 if (sv_isobject(ST(0)) == 0)
6888 {
6889 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6890 PackageName);
6891 goto PerlException;
6892 }
6893 reference=SvRV(ST(0));
6894 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6895 if (image == (Image *) NULL)
6896 {
6897 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6898 PackageName);
6899 goto PerlException;
6900 }
6901 package_info=ClonePackageInfo(info,exception);
6902 for (i=2; i < items; i+=2)
6903 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6904 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006905 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006906 scene=0;
6907 for (next=image; next; next=next->next)
6908 {
cristy151b66d2015-04-15 10:50:31 +00006909 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006910 next->scene=scene++;
6911 }
6912 SetImageInfo(package_info->image_info,(unsigned int)
6913 GetImageListLength(image),exception);
6914 EXTEND(sp,(ssize_t) GetImageListLength(image));
6915 for ( ; image; image=image->next)
6916 {
6917 length=0;
6918 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6919 if (blob != (char *) NULL)
6920 {
6921 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6922 blob=(unsigned char *) RelinquishMagickMemory(blob);
6923 }
6924 if (package_info->image_info->adjoin)
6925 break;
6926 }
6927
6928 PerlException:
6929 if (package_info != (struct PackageInfo *) NULL)
6930 DestroyPackageInfo(package_info);
6931 InheritPerlException(exception,perl_exception);
6932 exception=DestroyExceptionInfo(exception);
6933 SvREFCNT_dec(perl_exception); /* throw away all errors */
6934 }
6935
6936#
6937###############################################################################
6938# #
6939# #
6940# #
6941# L a y e r s #
6942# #
6943# #
6944# #
6945###############################################################################
6946#
6947#
6948void
6949Layers(ref,...)
6950 Image::Magick ref=NO_INIT
6951 ALIAS:
6952 Layers = 1
6953 layers = 2
6954 OptimizeImageLayers = 3
6955 optimizelayers = 4
6956 optimizeimagelayers = 5
6957 PPCODE:
6958 {
6959 AV
6960 *av;
6961
6962 char
6963 *attribute;
6964
6965 CompositeOperator
6966 compose;
6967
6968 ExceptionInfo
6969 *exception;
6970
6971 HV
6972 *hv;
6973
6974 Image
6975 *image,
6976 *layers;
6977
6978 LayerMethod
6979 method;
6980
6981 register ssize_t
6982 i;
6983
6984 ssize_t
6985 option,
6986 sp;
6987
6988 struct PackageInfo
6989 *info;
6990
6991 SV
6992 *av_reference,
6993 *perl_exception,
6994 *reference,
6995 *rv,
6996 *sv;
6997
6998 PERL_UNUSED_VAR(ref);
6999 PERL_UNUSED_VAR(ix);
7000 exception=AcquireExceptionInfo();
7001 perl_exception=newSVpv("",0);
7002 sv=NULL;
7003 if (sv_isobject(ST(0)) == 0)
7004 {
7005 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7006 PackageName);
7007 goto PerlException;
7008 }
7009 reference=SvRV(ST(0));
7010 hv=SvSTASH(reference);
7011 av=newAV();
7012 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7013 SvREFCNT_dec(av);
7014 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7015 if (image == (Image *) NULL)
7016 {
7017 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7018 PackageName);
7019 goto PerlException;
7020 }
7021 compose=image->compose;
7022 method=OptimizeLayer;
7023 for (i=2; i < items; i+=2)
7024 {
7025 attribute=(char *) SvPV(ST(i-1),na);
7026 switch (*attribute)
7027 {
7028 case 'C':
7029 case 'c':
7030 {
7031 if (LocaleCompare(attribute,"compose") == 0)
7032 {
7033 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7034 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7035 if (sp < 0)
7036 {
7037 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7038 SvPV(ST(i),na));
7039 break;
7040 }
7041 compose=(CompositeOperator) sp;
7042 break;
7043 }
7044 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7045 attribute);
7046 break;
7047 }
7048 case 'M':
7049 case 'm':
7050 {
7051 if (LocaleCompare(attribute,"method") == 0)
7052 {
7053 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7054 SvPV(ST(i),na));
7055 if (option < 0)
7056 {
7057 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7058 SvPV(ST(i),na));
7059 break;
7060 }
7061 method=(LayerMethod) option;
7062 break;
7063 }
7064 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7065 attribute);
7066 break;
7067 }
7068 default:
7069 {
7070 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7071 attribute);
7072 break;
7073 }
7074 }
7075 }
7076 layers=(Image *) NULL;
7077 switch (method)
7078 {
7079 case CompareAnyLayer:
7080 case CompareClearLayer:
7081 case CompareOverlayLayer:
7082 default:
7083 {
7084 layers=CompareImagesLayers(image,method,exception);
7085 break;
7086 }
7087 case MergeLayer:
7088 case FlattenLayer:
7089 case MosaicLayer:
7090 {
7091 layers=MergeImageLayers(image,method,exception);
7092 break;
7093 }
7094 case DisposeLayer:
7095 {
7096 layers=DisposeImages(image,exception);
7097 break;
7098 }
7099 case OptimizeImageLayer:
7100 {
7101 layers=OptimizeImageLayers(image,exception);
7102 break;
7103 }
7104 case OptimizePlusLayer:
7105 {
7106 layers=OptimizePlusImageLayers(image,exception);
7107 break;
7108 }
7109 case OptimizeTransLayer:
7110 {
7111 OptimizeImageTransparency(image,exception);
7112 break;
7113 }
7114 case RemoveDupsLayer:
7115 {
7116 RemoveDuplicateLayers(&image,exception);
7117 break;
7118 }
7119 case RemoveZeroLayer:
7120 {
7121 RemoveZeroDelayLayers(&image,exception);
7122 break;
7123 }
7124 case OptimizeLayer:
7125 {
7126 QuantizeInfo
7127 *quantize_info;
7128
7129 /*
7130 General Purpose, GIF Animation Optimizer.
7131 */
7132 layers=CoalesceImages(image,exception);
7133 if (layers == (Image *) NULL)
7134 break;
7135 image=layers;
7136 layers=OptimizeImageLayers(image,exception);
7137 if (layers == (Image *) NULL)
7138 break;
7139 image=DestroyImageList(image);
7140 image=layers;
7141 layers=(Image *) NULL;
7142 OptimizeImageTransparency(image,exception);
7143 quantize_info=AcquireQuantizeInfo(info->image_info);
7144 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7145 quantize_info=DestroyQuantizeInfo(quantize_info);
7146 break;
7147 }
7148 case CompositeLayer:
7149 {
7150 Image
7151 *source;
7152
7153 RectangleInfo
7154 geometry;
7155
7156 /*
7157 Split image sequence at the first 'NULL:' image.
7158 */
7159 source=image;
7160 while (source != (Image *) NULL)
7161 {
7162 source=GetNextImageInList(source);
7163 if ((source != (Image *) NULL) &&
7164 (LocaleCompare(source->magick,"NULL") == 0))
7165 break;
7166 }
7167 if (source != (Image *) NULL)
7168 {
7169 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7170 (GetNextImageInList(source) == (Image *) NULL))
7171 source=(Image *) NULL;
7172 else
7173 {
7174 /*
7175 Separate the two lists, junk the null: image.
7176 */
7177 source=SplitImageList(source->previous);
7178 DeleteImageFromList(&source);
7179 }
7180 }
7181 if (source == (Image *) NULL)
7182 {
7183 (void) ThrowMagickException(exception,GetMagickModule(),
7184 OptionError,"MissingNullSeparator","layers Composite");
7185 break;
7186 }
7187 /*
7188 Adjust offset with gravity and virtual canvas.
7189 */
7190 SetGeometry(image,&geometry);
7191 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7192 geometry.width=source->page.width != 0 ? source->page.width :
7193 source->columns;
7194 geometry.height=source->page.height != 0 ? source->page.height :
7195 source->rows;
7196 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7197 image->columns,image->page.height != 0 ? image->page.height :
7198 image->rows,image->gravity,&geometry);
7199 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7200 source=DestroyImageList(source);
7201 break;
7202 }
7203 }
7204 if (layers != (Image *) NULL)
7205 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007206 else
7207 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007208 if (image == (Image *) NULL)
7209 goto PerlException;
7210 for ( ; image; image=image->next)
7211 {
7212 AddImageToRegistry(sv,image);
7213 rv=newRV(sv);
7214 av_push(av,sv_bless(rv,hv));
7215 SvREFCNT_dec(sv);
7216 }
7217 exception=DestroyExceptionInfo(exception);
7218 ST(0)=av_reference;
7219 SvREFCNT_dec(perl_exception);
7220 XSRETURN(1);
7221
7222 PerlException:
7223 InheritPerlException(exception,perl_exception);
7224 exception=DestroyExceptionInfo(exception);
7225 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7226 SvPOK_on(perl_exception);
7227 ST(0)=sv_2mortal(perl_exception);
7228 XSRETURN(1);
7229 }
7230
7231#
7232###############################################################################
7233# #
7234# #
7235# #
7236# M a g i c k T o M i m e #
7237# #
7238# #
7239# #
7240###############################################################################
7241#
7242#
7243SV *
7244MagickToMime(ref,name)
7245 Image::Magick ref=NO_INIT
7246 char *name
7247 ALIAS:
7248 magicktomime = 1
7249 CODE:
7250 {
7251 char
7252 *mime;
7253
7254 PERL_UNUSED_VAR(ref);
7255 PERL_UNUSED_VAR(ix);
7256 mime=MagickToMime(name);
7257 RETVAL=newSVpv(mime,0);
7258 mime=(char *) RelinquishMagickMemory(mime);
7259 }
7260 OUTPUT:
7261 RETVAL
7262
7263#
7264###############################################################################
7265# #
7266# #
7267# #
7268# M o g r i f y #
7269# #
7270# #
7271# #
7272###############################################################################
7273#
7274#
7275void
7276Mogrify(ref,...)
7277 Image::Magick ref=NO_INIT
7278 ALIAS:
7279 Comment = 1
7280 CommentImage = 2
7281 Label = 3
7282 LabelImage = 4
7283 AddNoise = 5
7284 AddNoiseImage = 6
7285 Colorize = 7
7286 ColorizeImage = 8
7287 Border = 9
7288 BorderImage = 10
7289 Blur = 11
7290 BlurImage = 12
7291 Chop = 13
7292 ChopImage = 14
7293 Crop = 15
7294 CropImage = 16
7295 Despeckle = 17
7296 DespeckleImage = 18
7297 Edge = 19
7298 EdgeImage = 20
7299 Emboss = 21
7300 EmbossImage = 22
7301 Enhance = 23
7302 EnhanceImage = 24
7303 Flip = 25
7304 FlipImage = 26
7305 Flop = 27
7306 FlopImage = 28
7307 Frame = 29
7308 FrameImage = 30
7309 Implode = 31
7310 ImplodeImage = 32
7311 Magnify = 33
7312 MagnifyImage = 34
7313 MedianFilter = 35
7314 MedianConvolveImage = 36
7315 Minify = 37
7316 MinifyImage = 38
7317 OilPaint = 39
7318 OilPaintImage = 40
7319 ReduceNoise = 41
7320 ReduceNoiseImage = 42
7321 Roll = 43
7322 RollImage = 44
7323 Rotate = 45
7324 RotateImage = 46
7325 Sample = 47
7326 SampleImage = 48
7327 Scale = 49
7328 ScaleImage = 50
7329 Shade = 51
7330 ShadeImage = 52
7331 Sharpen = 53
7332 SharpenImage = 54
7333 Shear = 55
7334 ShearImage = 56
7335 Spread = 57
7336 SpreadImage = 58
7337 Swirl = 59
7338 SwirlImage = 60
7339 Resize = 61
7340 ResizeImage = 62
7341 Zoom = 63
7342 ZoomImage = 64
7343 Annotate = 65
7344 AnnotateImage = 66
7345 ColorFloodfill = 67
7346 ColorFloodfillImage= 68
7347 Composite = 69
7348 CompositeImage = 70
7349 Contrast = 71
7350 ContrastImage = 72
7351 CycleColormap = 73
7352 CycleColormapImage = 74
7353 Draw = 75
7354 DrawImage = 76
7355 Equalize = 77
7356 EqualizeImage = 78
7357 Gamma = 79
7358 GammaImage = 80
7359 Map = 81
7360 MapImage = 82
7361 MatteFloodfill = 83
7362 MatteFloodfillImage= 84
7363 Modulate = 85
7364 ModulateImage = 86
7365 Negate = 87
7366 NegateImage = 88
7367 Normalize = 89
7368 NormalizeImage = 90
7369 NumberColors = 91
7370 NumberColorsImage = 92
7371 Opaque = 93
7372 OpaqueImage = 94
7373 Quantize = 95
7374 QuantizeImage = 96
7375 Raise = 97
7376 RaiseImage = 98
7377 Segment = 99
7378 SegmentImage = 100
7379 Signature = 101
7380 SignatureImage = 102
7381 Solarize = 103
7382 SolarizeImage = 104
7383 Sync = 105
7384 SyncImage = 106
7385 Texture = 107
7386 TextureImage = 108
7387 Evaluate = 109
7388 EvaluateImage = 110
7389 Transparent = 111
7390 TransparentImage = 112
7391 Threshold = 113
7392 ThresholdImage = 114
7393 Charcoal = 115
7394 CharcoalImage = 116
7395 Trim = 117
7396 TrimImage = 118
7397 Wave = 119
7398 WaveImage = 120
7399 Separate = 121
7400 SeparateImage = 122
7401 Stereo = 125
7402 StereoImage = 126
7403 Stegano = 127
7404 SteganoImage = 128
7405 Deconstruct = 129
7406 DeconstructImage = 130
7407 GaussianBlur = 131
7408 GaussianBlurImage = 132
7409 Convolve = 133
7410 ConvolveImage = 134
7411 Profile = 135
7412 ProfileImage = 136
7413 UnsharpMask = 137
7414 UnsharpMaskImage = 138
7415 MotionBlur = 139
7416 MotionBlurImage = 140
7417 OrderedDither = 141
7418 OrderedDitherImage = 142
7419 Shave = 143
7420 ShaveImage = 144
7421 Level = 145
7422 LevelImage = 146
7423 Clip = 147
7424 ClipImage = 148
7425 AffineTransform = 149
7426 AffineTransformImage = 150
7427 Difference = 151
7428 DifferenceImage = 152
7429 AdaptiveThreshold = 153
7430 AdaptiveThresholdImage = 154
7431 Resample = 155
7432 ResampleImage = 156
7433 Describe = 157
7434 DescribeImage = 158
7435 BlackThreshold = 159
7436 BlackThresholdImage= 160
7437 WhiteThreshold = 161
7438 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007439 RotationalBlur = 163
7440 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007441 Thumbnail = 165
7442 ThumbnailImage = 166
7443 Strip = 167
7444 StripImage = 168
7445 Tint = 169
7446 TintImage = 170
7447 Channel = 171
7448 ChannelImage = 172
7449 Splice = 173
7450 SpliceImage = 174
7451 Posterize = 175
7452 PosterizeImage = 176
7453 Shadow = 177
7454 ShadowImage = 178
7455 Identify = 179
7456 IdentifyImage = 180
7457 SepiaTone = 181
7458 SepiaToneImage = 182
7459 SigmoidalContrast = 183
7460 SigmoidalContrastImage = 184
7461 Extent = 185
7462 ExtentImage = 186
7463 Vignette = 187
7464 VignetteImage = 188
7465 ContrastStretch = 189
7466 ContrastStretchImage = 190
7467 Sans0 = 191
7468 Sans0Image = 192
7469 Sans1 = 193
7470 Sans1Image = 194
7471 AdaptiveSharpen = 195
7472 AdaptiveSharpenImage = 196
7473 Transpose = 197
7474 TransposeImage = 198
7475 Transverse = 199
7476 TransverseImage = 200
7477 AutoOrient = 201
7478 AutoOrientImage = 202
7479 AdaptiveBlur = 203
7480 AdaptiveBlurImage = 204
7481 Sketch = 205
7482 SketchImage = 206
7483 UniqueColors = 207
7484 UniqueColorsImage = 208
7485 AdaptiveResize = 209
7486 AdaptiveResizeImage= 210
7487 ClipMask = 211
7488 ClipMaskImage = 212
7489 LinearStretch = 213
7490 LinearStretchImage = 214
7491 ColorMatrix = 215
7492 ColorMatrixImage = 216
7493 Mask = 217
7494 MaskImage = 218
7495 Polaroid = 219
7496 PolaroidImage = 220
7497 FloodfillPaint = 221
7498 FloodfillPaintImage= 222
7499 Distort = 223
7500 DistortImage = 224
7501 Clut = 225
7502 ClutImage = 226
7503 LiquidRescale = 227
7504 LiquidRescaleImage = 228
7505 Encipher = 229
7506 EncipherImage = 230
7507 Decipher = 231
7508 DecipherImage = 232
7509 Deskew = 233
7510 DeskewImage = 234
7511 Remap = 235
7512 RemapImage = 236
7513 SparseColor = 237
7514 SparseColorImage = 238
7515 Function = 239
7516 FunctionImage = 240
7517 SelectiveBlur = 241
7518 SelectiveBlurImage = 242
7519 HaldClut = 243
7520 HaldClutImage = 244
7521 BlueShift = 245
7522 BlueShiftImage = 246
7523 ForwardFourierTransform = 247
7524 ForwardFourierTransformImage = 248
7525 InverseFourierTransform = 249
7526 InverseFourierTransformImage = 250
7527 ColorDecisionList = 251
7528 ColorDecisionListImage = 252
7529 AutoGamma = 253
7530 AutoGammaImage = 254
7531 AutoLevel = 255
7532 AutoLevelImage = 256
7533 LevelColors = 257
7534 LevelImageColors = 258
7535 Clamp = 259
7536 ClampImage = 260
7537 BrightnessContrast = 261
7538 BrightnessContrastImage = 262
7539 Morphology = 263
7540 MorphologyImage = 264
Cristy3ca633e2016-02-13 12:49:01 -05007541 Mode = 265
7542 ModeImage = 266
7543 Statistic = 267
7544 StatisticImage = 268
7545 Perceptible = 269
7546 PerceptibleImage = 270
7547 Poly = 271
7548 PolyImage = 272
7549 Grayscale = 273
7550 GrayscaleImage = 274
7551 CannyEdge = 275
7552 CannyEdgeImage = 276
7553 HoughLine = 277
7554 HoughLineImage = 278
7555 MeanShift = 279
7556 MeanShiftImage = 280
7557 Kuwahara = 281
7558 KuwaharaImage = 282
7559 ConnectedComponent = 283
7560 ConnectedComponentImage = 284
7561 CopyPixels = 285
7562 CopyImagePixels = 286
Cristy5488c982016-02-13 14:07:50 -05007563 Color = 287
7564 ColorImage = 288
Cristy2d830ed2016-02-21 10:54:16 -05007565 WaveletDenoise = 289
7566 WaveletDenoiseImage= 290
Cristy99a57162016-12-05 11:47:57 -05007567 Colorspace = 291
7568 ColorspaceImage = 292
cristy4a3ce0a2013-08-03 20:06:59 +00007569 MogrifyRegion = 666
7570 PPCODE:
7571 {
7572 AffineMatrix
7573 affine,
7574 current;
7575
7576 char
7577 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007578 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007579
7580 ChannelType
7581 channel,
7582 channel_mask;
7583
7584 CompositeOperator
7585 compose;
7586
7587 const char
7588 *attribute,
7589 *value;
7590
7591 double
7592 angle;
7593
7594 ExceptionInfo
7595 *exception;
7596
7597 GeometryInfo
7598 geometry_info;
7599
7600 Image
7601 *image,
7602 *next,
7603 *region_image;
7604
7605 MagickBooleanType
7606 status;
7607
7608 MagickStatusType
7609 flags;
7610
7611 PixelInfo
7612 fill_color;
7613
7614 RectangleInfo
7615 geometry,
7616 region_info;
7617
7618 register ssize_t
7619 i;
7620
7621 ssize_t
7622 base,
7623 j,
7624 number_images;
7625
7626 struct Methods
7627 *rp;
7628
7629 struct PackageInfo
7630 *info;
7631
7632 SV
7633 *perl_exception,
7634 **pv,
7635 *reference,
7636 **reference_vector;
7637
7638 struct ArgumentList
7639 argument_list[MaxArguments];
7640
7641 PERL_UNUSED_VAR(ref);
7642 PERL_UNUSED_VAR(ix);
7643 exception=AcquireExceptionInfo();
7644 perl_exception=newSVpv("",0);
7645 reference_vector=NULL;
7646 region_image=NULL;
7647 number_images=0;
7648 base=2;
7649 if (sv_isobject(ST(0)) == 0)
7650 {
7651 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7652 PackageName);
7653 goto PerlException;
7654 }
7655 reference=SvRV(ST(0));
7656 region_info.width=0;
7657 region_info.height=0;
7658 region_info.x=0;
7659 region_info.y=0;
7660 region_image=(Image *) NULL;
7661 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7662 if (ix && (ix != 666))
7663 {
7664 /*
7665 Called as Method(...)
7666 */
7667 ix=(ix+1)/2;
7668 rp=(&Methods[ix-1]);
7669 attribute=rp->name;
7670 }
7671 else
7672 {
7673 /*
7674 Called as Mogrify("Method",...)
7675 */
7676 attribute=(char *) SvPV(ST(1),na);
7677 if (ix)
7678 {
7679 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7680 attribute=(char *) SvPV(ST(2),na);
7681 base++;
7682 }
7683 for (rp=Methods; ; rp++)
7684 {
7685 if (rp >= EndOf(Methods))
7686 {
7687 ThrowPerlException(exception,OptionError,
7688 "UnrecognizedPerlMagickMethod",attribute);
7689 goto PerlException;
7690 }
7691 if (strEQcase(attribute,rp->name))
7692 break;
7693 }
7694 ix=rp-Methods+1;
7695 base++;
7696 }
7697 if (image == (Image *) NULL)
7698 {
7699 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7700 goto PerlException;
7701 }
7702 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7703 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7704 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7705 {
7706 Arguments
7707 *pp,
7708 *qq;
7709
7710 ssize_t
7711 ssize_test;
7712
7713 struct ArgumentList
7714 *al;
7715
7716 SV
7717 *sv;
7718
7719 sv=NULL;
7720 ssize_test=0;
7721 pp=(Arguments *) NULL;
7722 qq=rp->arguments;
7723 if (i == items)
7724 {
7725 pp=rp->arguments,
7726 sv=ST(i-1);
7727 }
7728 else
7729 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7730 {
7731 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7732 break;
7733 if (strEQcase(attribute,qq->method) > ssize_test)
7734 {
7735 pp=qq;
7736 ssize_test=strEQcase(attribute,qq->method);
7737 }
7738 }
7739 if (pp == (Arguments *) NULL)
7740 {
7741 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7742 attribute);
7743 goto continue_outer_loop;
7744 }
7745 al=(&argument_list[pp-rp->arguments]);
7746 switch (pp->type)
7747 {
7748 case ArrayReference:
7749 {
7750 if (SvTYPE(sv) != SVt_RV)
7751 {
cristy151b66d2015-04-15 10:50:31 +00007752 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007753 "invalid %.60s value",pp->method);
7754 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7755 goto continue_outer_loop;
7756 }
7757 al->array_reference=SvRV(sv);
7758 break;
7759 }
7760 case RealReference:
7761 {
7762 al->real_reference=SvNV(sv);
7763 break;
7764 }
7765 case FileReference:
7766 {
7767 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7768 break;
7769 }
7770 case ImageReference:
7771 {
7772 if (!sv_isobject(sv) ||
7773 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7774 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7775 {
7776 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7777 PackageName);
7778 goto PerlException;
7779 }
7780 break;
7781 }
7782 case IntegerReference:
7783 {
7784 al->integer_reference=SvIV(sv);
7785 break;
7786 }
7787 case StringReference:
7788 {
7789 al->string_reference=(char *) SvPV(sv,al->length);
7790 if (sv_isobject(sv))
7791 al->image_reference=SetupList(aTHX_ SvRV(sv),
7792 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7793 break;
7794 }
7795 default:
7796 {
7797 /*
7798 Is a string; look up name.
7799 */
7800 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7801 {
7802 al->string_reference=(char *) SvPV(sv,al->length);
7803 al->integer_reference=(-1);
7804 break;
7805 }
7806 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7807 MagickFalse,SvPV(sv,na));
7808 if (pp->type == MagickChannelOptions)
7809 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7810 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7811 {
cristy151b66d2015-04-15 10:50:31 +00007812 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007813 "invalid %.60s value",pp->method);
7814 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7815 goto continue_outer_loop;
7816 }
7817 break;
7818 }
7819 }
7820 attribute_flag[pp-rp->arguments]++;
7821 continue_outer_loop: ;
7822 }
7823 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7824 pv=reference_vector;
7825 SetGeometryInfo(&geometry_info);
7826 channel=DefaultChannels;
7827 for (next=image; next; next=next->next)
7828 {
7829 image=next;
7830 SetGeometry(image,&geometry);
7831 if ((region_info.width*region_info.height) != 0)
7832 {
7833 region_image=image;
7834 image=CropImage(image,&region_info,exception);
7835 }
7836 switch (ix)
7837 {
7838 default:
7839 {
cristy151b66d2015-04-15 10:50:31 +00007840 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007841 ThrowPerlException(exception,OptionError,
7842 "UnrecognizedPerlMagickMethod",message);
7843 goto PerlException;
7844 }
7845 case 1: /* Comment */
7846 {
7847 if (attribute_flag[0] == 0)
7848 argument_list[0].string_reference=(char *) NULL;
7849 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7850 info ? info->image_info : (ImageInfo *) NULL,image,
7851 argument_list[0].string_reference,exception),exception);
7852 break;
7853 }
7854 case 2: /* Label */
7855 {
7856 if (attribute_flag[0] == 0)
7857 argument_list[0].string_reference=(char *) NULL;
7858 (void) SetImageProperty(image,"label",InterpretImageProperties(
7859 info ? info->image_info : (ImageInfo *) NULL,image,
7860 argument_list[0].string_reference,exception),exception);
7861 break;
7862 }
7863 case 3: /* AddNoise */
7864 {
7865 double
7866 attenuate;
7867
7868 if (attribute_flag[0] == 0)
7869 argument_list[0].integer_reference=UniformNoise;
7870 attenuate=1.0;
7871 if (attribute_flag[1] != 0)
7872 attenuate=argument_list[1].real_reference;
7873 if (attribute_flag[2] != 0)
7874 channel=(ChannelType) argument_list[2].integer_reference;
7875 channel_mask=SetImageChannelMask(image,channel);
7876 image=AddNoiseImage(image,(NoiseType)
7877 argument_list[0].integer_reference,attenuate,exception);
7878 if (image != (Image *) NULL)
7879 (void) SetImageChannelMask(image,channel_mask);
7880 break;
7881 }
7882 case 4: /* Colorize */
7883 {
7884 PixelInfo
7885 target;
7886
7887 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7888 0,0,&target,exception);
7889 if (attribute_flag[0] != 0)
7890 (void) QueryColorCompliance(argument_list[0].string_reference,
7891 AllCompliance,&target,exception);
7892 if (attribute_flag[1] == 0)
7893 argument_list[1].string_reference="100%";
7894 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7895 exception);
7896 break;
7897 }
7898 case 5: /* Border */
7899 {
7900 CompositeOperator
7901 compose;
7902
7903 geometry.width=0;
7904 geometry.height=0;
7905 if (attribute_flag[0] != 0)
7906 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7907 &geometry,exception);
7908 if (attribute_flag[1] != 0)
7909 geometry.width=argument_list[1].integer_reference;
7910 if (attribute_flag[2] != 0)
7911 geometry.height=argument_list[2].integer_reference;
7912 if (attribute_flag[3] != 0)
7913 QueryColorCompliance(argument_list[3].string_reference,
7914 AllCompliance,&image->border_color,exception);
7915 if (attribute_flag[4] != 0)
7916 QueryColorCompliance(argument_list[4].string_reference,
7917 AllCompliance,&image->border_color,exception);
7918 if (attribute_flag[5] != 0)
7919 QueryColorCompliance(argument_list[5].string_reference,
7920 AllCompliance,&image->border_color,exception);
7921 compose=image->compose;
7922 if (attribute_flag[6] != 0)
7923 compose=(CompositeOperator) argument_list[6].integer_reference;
7924 image=BorderImage(image,&geometry,compose,exception);
7925 break;
7926 }
7927 case 6: /* Blur */
7928 {
7929 if (attribute_flag[0] != 0)
7930 {
7931 flags=ParseGeometry(argument_list[0].string_reference,
7932 &geometry_info);
7933 if ((flags & SigmaValue) == 0)
7934 geometry_info.sigma=1.0;
7935 }
7936 if (attribute_flag[1] != 0)
7937 geometry_info.rho=argument_list[1].real_reference;
7938 if (attribute_flag[2] != 0)
7939 geometry_info.sigma=argument_list[2].real_reference;
7940 if (attribute_flag[3] != 0)
7941 channel=(ChannelType) argument_list[3].integer_reference;
7942 channel_mask=SetImageChannelMask(image,channel);
7943 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
7944 exception);
7945 if (image != (Image *) NULL)
7946 (void) SetImageChannelMask(image,channel_mask);
7947 break;
7948 }
7949 case 7: /* Chop */
7950 {
cristy260bd762014-08-15 12:46:34 +00007951 if (attribute_flag[5] != 0)
7952 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00007953 if (attribute_flag[0] != 0)
7954 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7955 &geometry,exception);
7956 if (attribute_flag[1] != 0)
7957 geometry.width=argument_list[1].integer_reference;
7958 if (attribute_flag[2] != 0)
7959 geometry.height=argument_list[2].integer_reference;
7960 if (attribute_flag[3] != 0)
7961 geometry.x=argument_list[3].integer_reference;
7962 if (attribute_flag[4] != 0)
7963 geometry.y=argument_list[4].integer_reference;
7964 image=ChopImage(image,&geometry,exception);
7965 break;
7966 }
7967 case 8: /* Crop */
7968 {
7969 if (attribute_flag[6] != 0)
7970 image->gravity=(GravityType) argument_list[6].integer_reference;
7971 if (attribute_flag[0] != 0)
7972 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7973 &geometry,exception);
7974 if (attribute_flag[1] != 0)
7975 geometry.width=argument_list[1].integer_reference;
7976 if (attribute_flag[2] != 0)
7977 geometry.height=argument_list[2].integer_reference;
7978 if (attribute_flag[3] != 0)
7979 geometry.x=argument_list[3].integer_reference;
7980 if (attribute_flag[4] != 0)
7981 geometry.y=argument_list[4].integer_reference;
7982 if (attribute_flag[5] != 0)
7983 image->fuzz=StringToDoubleInterval(
7984 argument_list[5].string_reference,(double) QuantumRange+1.0);
7985 image=CropImage(image,&geometry,exception);
7986 break;
7987 }
7988 case 9: /* Despeckle */
7989 {
7990 image=DespeckleImage(image,exception);
7991 break;
7992 }
7993 case 10: /* Edge */
7994 {
7995 if (attribute_flag[0] != 0)
7996 geometry_info.rho=argument_list[0].real_reference;
7997 image=EdgeImage(image,geometry_info.rho,exception);
7998 break;
7999 }
8000 case 11: /* Emboss */
8001 {
8002 if (attribute_flag[0] != 0)
8003 {
8004 flags=ParseGeometry(argument_list[0].string_reference,
8005 &geometry_info);
8006 if ((flags & SigmaValue) == 0)
8007 geometry_info.sigma=1.0;
8008 }
8009 if (attribute_flag[1] != 0)
8010 geometry_info.rho=argument_list[1].real_reference;
8011 if (attribute_flag[2] != 0)
8012 geometry_info.sigma=argument_list[2].real_reference;
8013 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8014 exception);
8015 break;
8016 }
8017 case 12: /* Enhance */
8018 {
8019 image=EnhanceImage(image,exception);
8020 break;
8021 }
8022 case 13: /* Flip */
8023 {
8024 image=FlipImage(image,exception);
8025 break;
8026 }
8027 case 14: /* Flop */
8028 {
8029 image=FlopImage(image,exception);
8030 break;
8031 }
8032 case 15: /* Frame */
8033 {
8034 CompositeOperator
8035 compose;
8036
8037 FrameInfo
8038 frame_info;
8039
8040 if (attribute_flag[0] != 0)
8041 {
8042 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8043 &geometry,exception);
8044 frame_info.width=geometry.width;
8045 frame_info.height=geometry.height;
8046 frame_info.outer_bevel=geometry.x;
8047 frame_info.inner_bevel=geometry.y;
8048 }
8049 if (attribute_flag[1] != 0)
8050 frame_info.width=argument_list[1].integer_reference;
8051 if (attribute_flag[2] != 0)
8052 frame_info.height=argument_list[2].integer_reference;
8053 if (attribute_flag[3] != 0)
8054 frame_info.inner_bevel=argument_list[3].integer_reference;
8055 if (attribute_flag[4] != 0)
8056 frame_info.outer_bevel=argument_list[4].integer_reference;
8057 if (attribute_flag[5] != 0)
8058 QueryColorCompliance(argument_list[5].string_reference,
8059 AllCompliance,&fill_color,exception);
8060 if (attribute_flag[6] != 0)
8061 QueryColorCompliance(argument_list[6].string_reference,
8062 AllCompliance,&fill_color,exception);
8063 frame_info.x=(ssize_t) frame_info.width;
8064 frame_info.y=(ssize_t) frame_info.height;
8065 frame_info.width=image->columns+2*frame_info.x;
8066 frame_info.height=image->rows+2*frame_info.y;
8067 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
Cristy8645e042016-02-03 16:35:29 -05008068 image->alpha_color=fill_color;
cristy4a3ce0a2013-08-03 20:06:59 +00008069 compose=image->compose;
8070 if (attribute_flag[7] != 0)
8071 compose=(CompositeOperator) argument_list[7].integer_reference;
8072 image=FrameImage(image,&frame_info,compose,exception);
8073 break;
8074 }
8075 case 16: /* Implode */
8076 {
8077 PixelInterpolateMethod
8078 method;
8079
8080 if (attribute_flag[0] == 0)
8081 argument_list[0].real_reference=0.5;
8082 method=UndefinedInterpolatePixel;
8083 if (attribute_flag[1] != 0)
8084 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8085 image=ImplodeImage(image,argument_list[0].real_reference,
8086 method,exception);
8087 break;
8088 }
8089 case 17: /* Magnify */
8090 {
8091 image=MagnifyImage(image,exception);
8092 break;
8093 }
8094 case 18: /* MedianFilter */
8095 {
8096 if (attribute_flag[0] != 0)
8097 {
8098 flags=ParseGeometry(argument_list[0].string_reference,
8099 &geometry_info);
8100 if ((flags & SigmaValue) == 0)
8101 geometry_info.sigma=geometry_info.rho;
8102 }
8103 if (attribute_flag[1] != 0)
8104 geometry_info.rho=argument_list[1].real_reference;
8105 if (attribute_flag[2] != 0)
8106 geometry_info.sigma=argument_list[2].real_reference;
8107 if (attribute_flag[3] != 0)
8108 channel=(ChannelType) argument_list[3].integer_reference;
8109 channel_mask=SetImageChannelMask(image,channel);
8110 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8111 (size_t) geometry_info.sigma,exception);
8112 if (image != (Image *) NULL)
8113 (void) SetImageChannelMask(image,channel_mask);
8114 break;
8115 }
8116 case 19: /* Minify */
8117 {
8118 image=MinifyImage(image,exception);
8119 break;
8120 }
8121 case 20: /* OilPaint */
8122 {
8123 if (attribute_flag[0] == 0)
8124 argument_list[0].real_reference=0.0;
8125 if (attribute_flag[1] == 0)
8126 argument_list[1].real_reference=1.0;
8127 image=OilPaintImage(image,argument_list[0].real_reference,
8128 argument_list[1].real_reference,exception);
8129 break;
8130 }
8131 case 21: /* ReduceNoise */
8132 {
8133 if (attribute_flag[0] != 0)
8134 {
8135 flags=ParseGeometry(argument_list[0].string_reference,
8136 &geometry_info);
8137 if ((flags & SigmaValue) == 0)
8138 geometry_info.sigma=1.0;
8139 }
8140 if (attribute_flag[1] != 0)
8141 geometry_info.rho=argument_list[1].real_reference;
8142 if (attribute_flag[2] != 0)
8143 geometry_info.sigma=argument_list[2].real_reference;
8144 if (attribute_flag[3] != 0)
8145 channel=(ChannelType) argument_list[3].integer_reference;
8146 channel_mask=SetImageChannelMask(image,channel);
8147 image=StatisticImage(image,NonpeakStatistic,(size_t)
8148 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8149 if (image != (Image *) NULL)
8150 (void) SetImageChannelMask(image,channel_mask);
8151 break;
8152 }
8153 case 22: /* Roll */
8154 {
8155 if (attribute_flag[0] != 0)
8156 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8157 &geometry,exception);
8158 if (attribute_flag[1] != 0)
8159 geometry.x=argument_list[1].integer_reference;
8160 if (attribute_flag[2] != 0)
8161 geometry.y=argument_list[2].integer_reference;
8162 image=RollImage(image,geometry.x,geometry.y,exception);
8163 break;
8164 }
8165 case 23: /* Rotate */
8166 {
8167 if (attribute_flag[0] == 0)
8168 argument_list[0].real_reference=90.0;
8169 if (attribute_flag[1] != 0)
8170 {
8171 QueryColorCompliance(argument_list[1].string_reference,
8172 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008173 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8174 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008175 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8176 }
8177 image=RotateImage(image,argument_list[0].real_reference,exception);
8178 break;
8179 }
8180 case 24: /* Sample */
8181 {
8182 if (attribute_flag[0] != 0)
8183 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8184 &geometry,exception);
8185 if (attribute_flag[1] != 0)
8186 geometry.width=argument_list[1].integer_reference;
8187 if (attribute_flag[2] != 0)
8188 geometry.height=argument_list[2].integer_reference;
8189 image=SampleImage(image,geometry.width,geometry.height,exception);
8190 break;
8191 }
8192 case 25: /* Scale */
8193 {
8194 if (attribute_flag[0] != 0)
8195 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8196 &geometry,exception);
8197 if (attribute_flag[1] != 0)
8198 geometry.width=argument_list[1].integer_reference;
8199 if (attribute_flag[2] != 0)
8200 geometry.height=argument_list[2].integer_reference;
8201 image=ScaleImage(image,geometry.width,geometry.height,exception);
8202 break;
8203 }
8204 case 26: /* Shade */
8205 {
8206 if (attribute_flag[0] != 0)
8207 {
8208 flags=ParseGeometry(argument_list[0].string_reference,
8209 &geometry_info);
8210 if ((flags & SigmaValue) == 0)
8211 geometry_info.sigma=0.0;
8212 }
8213 if (attribute_flag[1] != 0)
8214 geometry_info.rho=argument_list[1].real_reference;
8215 if (attribute_flag[2] != 0)
8216 geometry_info.sigma=argument_list[2].real_reference;
8217 image=ShadeImage(image,
8218 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8219 geometry_info.rho,geometry_info.sigma,exception);
8220 break;
8221 }
8222 case 27: /* Sharpen */
8223 {
8224 if (attribute_flag[0] != 0)
8225 {
8226 flags=ParseGeometry(argument_list[0].string_reference,
8227 &geometry_info);
8228 if ((flags & SigmaValue) == 0)
8229 geometry_info.sigma=1.0;
8230 }
8231 if (attribute_flag[1] != 0)
8232 geometry_info.rho=argument_list[1].real_reference;
8233 if (attribute_flag[2] != 0)
8234 geometry_info.sigma=argument_list[2].real_reference;
8235 if (attribute_flag[3] != 0)
8236 channel=(ChannelType) argument_list[3].integer_reference;
8237 channel_mask=SetImageChannelMask(image,channel);
8238 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8239 exception);
8240 if (image != (Image *) NULL)
8241 (void) SetImageChannelMask(image,channel_mask);
8242 break;
8243 }
8244 case 28: /* Shear */
8245 {
8246 if (attribute_flag[0] != 0)
8247 {
8248 flags=ParseGeometry(argument_list[0].string_reference,
8249 &geometry_info);
8250 if ((flags & SigmaValue) == 0)
8251 geometry_info.sigma=geometry_info.rho;
8252 }
8253 if (attribute_flag[1] != 0)
8254 geometry_info.rho=argument_list[1].real_reference;
8255 if (attribute_flag[2] != 0)
8256 geometry_info.sigma=argument_list[2].real_reference;
8257 if (attribute_flag[3] != 0)
8258 QueryColorCompliance(argument_list[3].string_reference,
8259 AllCompliance,&image->background_color,exception);
8260 if (attribute_flag[4] != 0)
8261 QueryColorCompliance(argument_list[4].string_reference,
8262 AllCompliance,&image->background_color,exception);
8263 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8264 exception);
8265 break;
8266 }
8267 case 29: /* Spread */
8268 {
Cristye3319c12015-08-24 07:11:48 -04008269 PixelInterpolateMethod
8270 method;
8271
cristy4a3ce0a2013-08-03 20:06:59 +00008272 if (attribute_flag[0] == 0)
8273 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008274 method=UndefinedInterpolatePixel;
8275 if (attribute_flag[1] != 0)
8276 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8277 image=SpreadImage(image,method,argument_list[0].real_reference,
8278 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008279 break;
8280 }
8281 case 30: /* Swirl */
8282 {
8283 PixelInterpolateMethod
8284 method;
8285
8286 if (attribute_flag[0] == 0)
8287 argument_list[0].real_reference=50.0;
8288 method=UndefinedInterpolatePixel;
8289 if (attribute_flag[1] != 0)
8290 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8291 image=SwirlImage(image,argument_list[0].real_reference,
8292 method,exception);
8293 break;
8294 }
8295 case 31: /* Resize */
8296 case 32: /* Zoom */
8297 {
8298 if (attribute_flag[0] != 0)
8299 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8300 &geometry,exception);
8301 if (attribute_flag[1] != 0)
8302 geometry.width=argument_list[1].integer_reference;
8303 if (attribute_flag[2] != 0)
8304 geometry.height=argument_list[2].integer_reference;
8305 if (attribute_flag[3] == 0)
8306 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8307 if (attribute_flag[4] != 0)
8308 SetImageArtifact(image,"filter:support",
8309 argument_list[4].string_reference);
8310 image=ResizeImage(image,geometry.width,geometry.height,
Cristy8645e042016-02-03 16:35:29 -05008311 (FilterType) argument_list[3].integer_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00008312 exception);
8313 break;
8314 }
8315 case 33: /* Annotate */
8316 {
8317 DrawInfo
8318 *draw_info;
8319
8320 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8321 (DrawInfo *) NULL);
8322 if (attribute_flag[0] != 0)
8323 {
8324 char
8325 *text;
8326
8327 text=InterpretImageProperties(info ? info->image_info :
8328 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8329 exception);
8330 (void) CloneString(&draw_info->text,text);
8331 text=DestroyString(text);
8332 }
8333 if (attribute_flag[1] != 0)
8334 (void) CloneString(&draw_info->font,
8335 argument_list[1].string_reference);
8336 if (attribute_flag[2] != 0)
8337 draw_info->pointsize=argument_list[2].real_reference;
8338 if (attribute_flag[3] != 0)
8339 (void) CloneString(&draw_info->density,
8340 argument_list[3].string_reference);
8341 if (attribute_flag[4] != 0)
8342 (void) QueryColorCompliance(argument_list[4].string_reference,
8343 AllCompliance,&draw_info->undercolor,exception);
8344 if (attribute_flag[5] != 0)
8345 {
8346 (void) QueryColorCompliance(argument_list[5].string_reference,
8347 AllCompliance,&draw_info->stroke,exception);
8348 if (argument_list[5].image_reference != (Image *) NULL)
8349 draw_info->stroke_pattern=CloneImage(
8350 argument_list[5].image_reference,0,0,MagickTrue,exception);
8351 }
8352 if (attribute_flag[6] != 0)
8353 {
8354 (void) QueryColorCompliance(argument_list[6].string_reference,
8355 AllCompliance,&draw_info->fill,exception);
8356 if (argument_list[6].image_reference != (Image *) NULL)
8357 draw_info->fill_pattern=CloneImage(
8358 argument_list[6].image_reference,0,0,MagickTrue,exception);
8359 }
8360 if (attribute_flag[7] != 0)
8361 {
8362 (void) CloneString(&draw_info->geometry,
8363 argument_list[7].string_reference);
8364 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8365 &geometry,exception);
8366 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8367 geometry_info.sigma=geometry_info.xi;
8368 }
8369 if (attribute_flag[8] != 0)
8370 (void) QueryColorCompliance(argument_list[8].string_reference,
8371 AllCompliance,&draw_info->fill,exception);
8372 if (attribute_flag[11] != 0)
8373 draw_info->gravity=(GravityType)
8374 argument_list[11].integer_reference;
8375 if (attribute_flag[25] != 0)
8376 {
8377 AV
8378 *av;
8379
8380 av=(AV *) argument_list[25].array_reference;
8381 if ((av_len(av) != 3) && (av_len(av) != 5))
8382 {
8383 ThrowPerlException(exception,OptionError,
8384 "affine matrix must have 4 or 6 elements",PackageName);
8385 goto PerlException;
8386 }
8387 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8388 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8389 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8390 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8391 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8392 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8393 {
8394 ThrowPerlException(exception,OptionError,
8395 "affine matrix is singular",PackageName);
8396 goto PerlException;
8397 }
8398 if (av_len(av) == 5)
8399 {
8400 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8401 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8402 }
8403 }
8404 for (j=12; j < 17; j++)
8405 {
8406 if (attribute_flag[j] == 0)
8407 continue;
8408 value=argument_list[j].string_reference;
8409 angle=argument_list[j].real_reference;
8410 current=draw_info->affine;
8411 GetAffineMatrix(&affine);
8412 switch (j)
8413 {
8414 case 12:
8415 {
8416 /*
8417 Translate.
8418 */
8419 flags=ParseGeometry(value,&geometry_info);
8420 affine.tx=geometry_info.xi;
8421 affine.ty=geometry_info.psi;
8422 if ((flags & PsiValue) == 0)
8423 affine.ty=affine.tx;
8424 break;
8425 }
8426 case 13:
8427 {
8428 /*
8429 Scale.
8430 */
8431 flags=ParseGeometry(value,&geometry_info);
8432 affine.sx=geometry_info.rho;
8433 affine.sy=geometry_info.sigma;
8434 if ((flags & SigmaValue) == 0)
8435 affine.sy=affine.sx;
8436 break;
8437 }
8438 case 14:
8439 {
8440 /*
8441 Rotate.
8442 */
8443 if (angle == 0.0)
8444 break;
8445 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8446 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8447 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8448 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8449 break;
8450 }
8451 case 15:
8452 {
8453 /*
8454 SkewX.
8455 */
8456 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8457 break;
8458 }
8459 case 16:
8460 {
8461 /*
8462 SkewY.
8463 */
8464 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8465 break;
8466 }
8467 }
8468 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8469 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8470 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8471 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8472 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8473 current.tx;
8474 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8475 current.ty;
8476 }
8477 if (attribute_flag[9] == 0)
8478 argument_list[9].real_reference=0.0;
8479 if (attribute_flag[10] == 0)
8480 argument_list[10].real_reference=0.0;
8481 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8482 {
8483 char
cristy151b66d2015-04-15 10:50:31 +00008484 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008485
cristy151b66d2015-04-15 10:50:31 +00008486 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008487 (double) argument_list[9].real_reference+draw_info->affine.tx,
8488 (double) argument_list[10].real_reference+draw_info->affine.ty);
8489 (void) CloneString(&draw_info->geometry,geometry);
8490 }
8491 if (attribute_flag[17] != 0)
8492 draw_info->stroke_width=argument_list[17].real_reference;
8493 if (attribute_flag[18] != 0)
8494 {
8495 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8496 MagickTrue : MagickFalse;
8497 draw_info->stroke_antialias=draw_info->text_antialias;
8498 }
8499 if (attribute_flag[19] != 0)
8500 (void) CloneString(&draw_info->family,
8501 argument_list[19].string_reference);
8502 if (attribute_flag[20] != 0)
8503 draw_info->style=(StyleType) argument_list[20].integer_reference;
8504 if (attribute_flag[21] != 0)
8505 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8506 if (attribute_flag[22] != 0)
8507 draw_info->weight=argument_list[22].integer_reference;
8508 if (attribute_flag[23] != 0)
8509 draw_info->align=(AlignType) argument_list[23].integer_reference;
8510 if (attribute_flag[24] != 0)
8511 (void) CloneString(&draw_info->encoding,
8512 argument_list[24].string_reference);
8513 if (attribute_flag[25] != 0)
8514 draw_info->fill_pattern=CloneImage(
8515 argument_list[25].image_reference,0,0,MagickTrue,exception);
8516 if (attribute_flag[26] != 0)
8517 draw_info->fill_pattern=CloneImage(
8518 argument_list[26].image_reference,0,0,MagickTrue,exception);
8519 if (attribute_flag[27] != 0)
8520 draw_info->stroke_pattern=CloneImage(
8521 argument_list[27].image_reference,0,0,MagickTrue,exception);
8522 if (attribute_flag[29] != 0)
8523 draw_info->kerning=argument_list[29].real_reference;
8524 if (attribute_flag[30] != 0)
8525 draw_info->interline_spacing=argument_list[30].real_reference;
8526 if (attribute_flag[31] != 0)
8527 draw_info->interword_spacing=argument_list[31].real_reference;
8528 if (attribute_flag[32] != 0)
8529 draw_info->direction=(DirectionType)
8530 argument_list[32].integer_reference;
8531 (void) AnnotateImage(image,draw_info,exception);
8532 draw_info=DestroyDrawInfo(draw_info);
8533 break;
8534 }
8535 case 34: /* ColorFloodfill */
8536 {
8537 DrawInfo
8538 *draw_info;
8539
8540 MagickBooleanType
8541 invert;
8542
8543 PixelInfo
8544 target;
8545
8546 draw_info=CloneDrawInfo(info ? info->image_info :
8547 (ImageInfo *) NULL,(DrawInfo *) NULL);
8548 if (attribute_flag[0] != 0)
8549 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8550 &geometry,exception);
8551 if (attribute_flag[1] != 0)
8552 geometry.x=argument_list[1].integer_reference;
8553 if (attribute_flag[2] != 0)
8554 geometry.y=argument_list[2].integer_reference;
8555 if (attribute_flag[3] != 0)
8556 (void) QueryColorCompliance(argument_list[3].string_reference,
8557 AllCompliance,&draw_info->fill,exception);
8558 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8559 geometry.x,geometry.y,&target,exception);
8560 invert=MagickFalse;
8561 if (attribute_flag[4] != 0)
8562 {
8563 QueryColorCompliance(argument_list[4].string_reference,
8564 AllCompliance,&target,exception);
8565 invert=MagickTrue;
8566 }
8567 if (attribute_flag[5] != 0)
8568 image->fuzz=StringToDoubleInterval(
8569 argument_list[5].string_reference,(double) QuantumRange+1.0);
8570 if (attribute_flag[6] != 0)
8571 invert=(MagickBooleanType) argument_list[6].integer_reference;
8572 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8573 geometry.y,invert,exception);
8574 draw_info=DestroyDrawInfo(draw_info);
8575 break;
8576 }
8577 case 35: /* Composite */
8578 {
8579 char
cristy151b66d2015-04-15 10:50:31 +00008580 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008581
8582 Image
8583 *composite_image,
8584 *rotate_image;
8585
8586 MagickBooleanType
8587 clip_to_self;
8588
8589 compose=OverCompositeOp;
8590 if (attribute_flag[0] != 0)
8591 composite_image=argument_list[0].image_reference;
8592 else
8593 {
8594 ThrowPerlException(exception,OptionError,
8595 "CompositeImageRequired",PackageName);
8596 goto PerlException;
8597 }
8598 /*
8599 Parameter Handling used for BOTH normal and tiled composition.
8600 */
8601 if (attribute_flag[1] != 0) /* compose */
8602 compose=(CompositeOperator) argument_list[1].integer_reference;
8603 if (attribute_flag[6] != 0) /* opacity */
8604 {
8605 if (compose != DissolveCompositeOp)
8606 (void) SetImageAlpha(composite_image,(Quantum)
8607 StringToDoubleInterval(argument_list[6].string_reference,
8608 (double) QuantumRange+1.0),exception);
8609 else
8610 {
8611 CacheView
8612 *composite_view;
8613
8614 double
8615 opacity;
8616
8617 MagickBooleanType
8618 sync;
8619
8620 register ssize_t
8621 x;
8622
8623 register Quantum
8624 *q;
8625
8626 ssize_t
8627 y;
8628
8629 /*
8630 Handle dissolve composite operator (patch by
8631 Kevin A. McGrail).
8632 */
8633 (void) CloneString(&image->geometry,
8634 argument_list[6].string_reference);
8635 opacity=(Quantum) StringToDoubleInterval(
8636 argument_list[6].string_reference,(double) QuantumRange+
8637 1.0);
cristy17f11b02014-12-20 19:37:04 +00008638 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008639 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8640 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8641 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8642 {
8643 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8644 composite_image->columns,1,exception);
8645 for (x=0; x < (ssize_t) composite_image->columns; x++)
8646 {
8647 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8648 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8649 q);
8650 q+=GetPixelChannels(composite_image);
8651 }
8652 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8653 if (sync == MagickFalse)
8654 break;
8655 }
8656 composite_view=DestroyCacheView(composite_view);
8657 }
8658 }
8659 if (attribute_flag[9] != 0) /* "color=>" */
8660 QueryColorCompliance(argument_list[9].string_reference,
8661 AllCompliance,&composite_image->background_color,exception);
8662 if (attribute_flag[12] != 0) /* "interpolate=>" */
8663 image->interpolate=(PixelInterpolateMethod)
8664 argument_list[12].integer_reference;
8665 if (attribute_flag[13] != 0) /* "args=>" */
8666 (void) SetImageArtifact(composite_image,"compose:args",
8667 argument_list[13].string_reference);
8668 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8669 (void) SetImageArtifact(composite_image,"compose:args",
8670 argument_list[14].string_reference);
8671 clip_to_self=MagickTrue;
8672 if (attribute_flag[15] != 0)
8673 clip_to_self=(MagickBooleanType)
8674 argument_list[15].integer_reference;
8675 /*
8676 Tiling Composition (with orthogonal rotate).
8677 */
8678 rotate_image=(Image *) NULL;
8679 if (attribute_flag[8] != 0) /* "rotate=>" */
8680 {
8681 /*
8682 Rotate image.
8683 */
8684 rotate_image=RotateImage(composite_image,
8685 argument_list[8].real_reference,exception);
8686 if (rotate_image == (Image *) NULL)
8687 break;
8688 }
8689 if ((attribute_flag[7] != 0) &&
8690 (argument_list[7].integer_reference != 0)) /* tile */
8691 {
8692 ssize_t
8693 x,
8694 y;
8695
8696 /*
8697 Tile the composite image.
8698 */
8699 if (attribute_flag[8] != 0) /* "tile=>" */
8700 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8701 "false");
8702 else
8703 (void) SetImageArtifact(composite_image,
8704 "compose:outside-overlay","false");
8705 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8706 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8707 {
8708 if (attribute_flag[8] != 0) /* rotate */
8709 (void) CompositeImage(image,rotate_image,compose,
8710 MagickTrue,x,y,exception);
8711 else
8712 (void) CompositeImage(image,composite_image,compose,
8713 MagickTrue,x,y,exception);
8714 }
8715 if (attribute_flag[8] != 0) /* rotate */
8716 rotate_image=DestroyImage(rotate_image);
8717 break;
8718 }
8719 /*
8720 Parameter Handling used used ONLY for normal composition.
8721 */
8722 if (attribute_flag[5] != 0) /* gravity */
8723 image->gravity=(GravityType) argument_list[5].integer_reference;
8724 if (attribute_flag[2] != 0) /* geometry offset */
8725 {
8726 SetGeometry(image,&geometry);
8727 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8728 &geometry);
8729 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8730 &geometry);
8731 }
8732 if (attribute_flag[3] != 0) /* x offset */
8733 geometry.x=argument_list[3].integer_reference;
8734 if (attribute_flag[4] != 0) /* y offset */
8735 geometry.y=argument_list[4].integer_reference;
8736 if (attribute_flag[10] != 0) /* mask */
8737 {
8738 if ((image->compose == DisplaceCompositeOp) ||
8739 (image->compose == DistortCompositeOp))
8740 {
8741 /*
8742 Merge Y displacement into X displacement image.
8743 */
8744 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8745 exception);
8746 (void) CompositeImage(composite_image,
8747 argument_list[10].image_reference,CopyGreenCompositeOp,
8748 MagickTrue,0,0,exception);
8749 }
8750 else
8751 {
8752 Image
8753 *mask_image;
8754
8755 /*
8756 Set a blending mask for the composition.
8757 */
8758 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8759 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008760 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008761 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008762 mask_image=DestroyImage(mask_image);
8763 }
8764 }
8765 if (attribute_flag[11] != 0) /* channel */
8766 channel=(ChannelType) argument_list[11].integer_reference;
8767 /*
8768 Composite two images (normal composition).
8769 */
cristy151b66d2015-04-15 10:50:31 +00008770 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008771 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8772 (double) composite_image->rows,(double) geometry.x,(double)
8773 geometry.y);
8774 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8775 exception);
8776 channel_mask=SetImageChannelMask(image,channel);
8777 if (attribute_flag[8] == 0) /* no rotate */
8778 CompositeImage(image,composite_image,compose,clip_to_self,
8779 geometry.x,geometry.y,exception);
8780 else
8781 {
8782 /*
8783 Position adjust rotated image then composite.
8784 */
8785 geometry.x-=(ssize_t) (rotate_image->columns-
8786 composite_image->columns)/2;
8787 geometry.y-=(ssize_t) (rotate_image->rows-
8788 composite_image->rows)/2;
8789 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8790 geometry.y,exception);
8791 rotate_image=DestroyImage(rotate_image);
8792 }
8793 if (attribute_flag[10] != 0) /* mask */
8794 {
8795 if ((image->compose == DisplaceCompositeOp) ||
8796 (image->compose == DistortCompositeOp))
8797 composite_image=DestroyImage(composite_image);
8798 else
cristy1f7ffb72015-07-29 11:07:03 +00008799 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008800 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008801 }
8802 (void) SetImageChannelMask(image,channel_mask);
8803 break;
8804 }
8805 case 36: /* Contrast */
8806 {
8807 if (attribute_flag[0] == 0)
8808 argument_list[0].integer_reference=0;
8809 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8810 MagickTrue : MagickFalse,exception);
8811 break;
8812 }
8813 case 37: /* CycleColormap */
8814 {
8815 if (attribute_flag[0] == 0)
8816 argument_list[0].integer_reference=6;
8817 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8818 exception);
8819 break;
8820 }
8821 case 38: /* Draw */
8822 {
8823 DrawInfo
8824 *draw_info;
8825
8826 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8827 (DrawInfo *) NULL);
8828 (void) CloneString(&draw_info->primitive,"point");
8829 if (attribute_flag[0] != 0)
8830 {
8831 if (argument_list[0].integer_reference < 0)
8832 (void) CloneString(&draw_info->primitive,
8833 argument_list[0].string_reference);
8834 else
8835 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8836 MagickPrimitiveOptions,argument_list[0].integer_reference));
8837 }
8838 if (attribute_flag[1] != 0)
8839 {
8840 if (LocaleCompare(draw_info->primitive,"path") == 0)
8841 {
8842 (void) ConcatenateString(&draw_info->primitive," '");
8843 ConcatenateString(&draw_info->primitive,
8844 argument_list[1].string_reference);
8845 (void) ConcatenateString(&draw_info->primitive,"'");
8846 }
8847 else
8848 {
8849 (void) ConcatenateString(&draw_info->primitive," ");
8850 ConcatenateString(&draw_info->primitive,
8851 argument_list[1].string_reference);
8852 }
8853 }
8854 if (attribute_flag[2] != 0)
8855 {
8856 (void) ConcatenateString(&draw_info->primitive," ");
8857 (void) ConcatenateString(&draw_info->primitive,
8858 CommandOptionToMnemonic(MagickMethodOptions,
8859 argument_list[2].integer_reference));
8860 }
8861 if (attribute_flag[3] != 0)
8862 {
8863 (void) QueryColorCompliance(argument_list[3].string_reference,
8864 AllCompliance,&draw_info->stroke,exception);
8865 if (argument_list[3].image_reference != (Image *) NULL)
8866 draw_info->stroke_pattern=CloneImage(
8867 argument_list[3].image_reference,0,0,MagickTrue,exception);
8868 }
8869 if (attribute_flag[4] != 0)
8870 {
8871 (void) QueryColorCompliance(argument_list[4].string_reference,
8872 AllCompliance,&draw_info->fill,exception);
8873 if (argument_list[4].image_reference != (Image *) NULL)
8874 draw_info->fill_pattern=CloneImage(
8875 argument_list[4].image_reference,0,0,MagickTrue,exception);
8876 }
8877 if (attribute_flag[5] != 0)
8878 draw_info->stroke_width=argument_list[5].real_reference;
8879 if (attribute_flag[6] != 0)
8880 (void) CloneString(&draw_info->font,
8881 argument_list[6].string_reference);
8882 if (attribute_flag[7] != 0)
8883 (void) QueryColorCompliance(argument_list[7].string_reference,
8884 AllCompliance,&draw_info->border_color,exception);
8885 if (attribute_flag[8] != 0)
8886 draw_info->affine.tx=argument_list[8].real_reference;
8887 if (attribute_flag[9] != 0)
8888 draw_info->affine.ty=argument_list[9].real_reference;
8889 if (attribute_flag[20] != 0)
8890 {
8891 AV
8892 *av;
8893
8894 av=(AV *) argument_list[20].array_reference;
8895 if ((av_len(av) != 3) && (av_len(av) != 5))
8896 {
8897 ThrowPerlException(exception,OptionError,
8898 "affine matrix must have 4 or 6 elements",PackageName);
8899 goto PerlException;
8900 }
8901 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8902 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8903 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8904 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8905 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8906 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8907 {
8908 ThrowPerlException(exception,OptionError,
8909 "affine matrix is singular",PackageName);
8910 goto PerlException;
8911 }
8912 if (av_len(av) == 5)
8913 {
8914 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8915 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8916 }
8917 }
8918 for (j=10; j < 15; j++)
8919 {
8920 if (attribute_flag[j] == 0)
8921 continue;
8922 value=argument_list[j].string_reference;
8923 angle=argument_list[j].real_reference;
8924 current=draw_info->affine;
8925 GetAffineMatrix(&affine);
8926 switch (j)
8927 {
8928 case 10:
8929 {
8930 /*
8931 Translate.
8932 */
8933 flags=ParseGeometry(value,&geometry_info);
8934 affine.tx=geometry_info.xi;
8935 affine.ty=geometry_info.psi;
8936 if ((flags & PsiValue) == 0)
8937 affine.ty=affine.tx;
8938 break;
8939 }
8940 case 11:
8941 {
8942 /*
8943 Scale.
8944 */
8945 flags=ParseGeometry(value,&geometry_info);
8946 affine.sx=geometry_info.rho;
8947 affine.sy=geometry_info.sigma;
8948 if ((flags & SigmaValue) == 0)
8949 affine.sy=affine.sx;
8950 break;
8951 }
8952 case 12:
8953 {
8954 /*
8955 Rotate.
8956 */
8957 if (angle == 0.0)
8958 break;
8959 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8960 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8961 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8962 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8963 break;
8964 }
8965 case 13:
8966 {
8967 /*
8968 SkewX.
8969 */
8970 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8971 break;
8972 }
8973 case 14:
8974 {
8975 /*
8976 SkewY.
8977 */
8978 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8979 break;
8980 }
8981 }
8982 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8983 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8984 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8985 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8986 draw_info->affine.tx=
8987 current.sx*affine.tx+current.ry*affine.ty+current.tx;
8988 draw_info->affine.ty=
8989 current.rx*affine.tx+current.sy*affine.ty+current.ty;
8990 }
8991 if (attribute_flag[15] != 0)
8992 draw_info->fill_pattern=CloneImage(
8993 argument_list[15].image_reference,0,0,MagickTrue,exception);
8994 if (attribute_flag[16] != 0)
8995 draw_info->pointsize=argument_list[16].real_reference;
8996 if (attribute_flag[17] != 0)
8997 {
8998 draw_info->stroke_antialias=argument_list[17].integer_reference != 0
8999 ? MagickTrue : MagickFalse;
9000 draw_info->text_antialias=draw_info->stroke_antialias;
9001 }
9002 if (attribute_flag[18] != 0)
9003 (void) CloneString(&draw_info->density,
9004 argument_list[18].string_reference);
9005 if (attribute_flag[19] != 0)
9006 draw_info->stroke_width=argument_list[19].real_reference;
9007 if (attribute_flag[21] != 0)
9008 draw_info->dash_offset=argument_list[21].real_reference;
9009 if (attribute_flag[22] != 0)
9010 {
9011 AV
9012 *av;
9013
9014 av=(AV *) argument_list[22].array_reference;
9015 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9016 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9017 if (draw_info->dash_pattern != (double *) NULL)
9018 {
9019 for (i=0; i <= av_len(av); i++)
9020 draw_info->dash_pattern[i]=(double)
9021 SvNV(*(av_fetch(av,i,0)));
9022 draw_info->dash_pattern[i]=0.0;
9023 }
9024 }
9025 if (attribute_flag[23] != 0)
9026 image->interpolate=(PixelInterpolateMethod)
9027 argument_list[23].integer_reference;
9028 if ((attribute_flag[24] != 0) &&
9029 (draw_info->fill_pattern != (Image *) NULL))
9030 flags=ParsePageGeometry(draw_info->fill_pattern,
9031 argument_list[24].string_reference,
9032 &draw_info->fill_pattern->tile_offset,exception);
9033 if (attribute_flag[25] != 0)
9034 {
9035 (void) ConcatenateString(&draw_info->primitive," '");
9036 (void) ConcatenateString(&draw_info->primitive,
9037 argument_list[25].string_reference);
9038 (void) ConcatenateString(&draw_info->primitive,"'");
9039 }
9040 if (attribute_flag[26] != 0)
9041 draw_info->fill_pattern=CloneImage(
9042 argument_list[26].image_reference,0,0,MagickTrue,exception);
9043 if (attribute_flag[27] != 0)
9044 draw_info->stroke_pattern=CloneImage(
9045 argument_list[27].image_reference,0,0,MagickTrue,exception);
9046 if (attribute_flag[28] != 0)
9047 (void) CloneString(&draw_info->primitive,
9048 argument_list[28].string_reference);
9049 if (attribute_flag[29] != 0)
9050 draw_info->kerning=argument_list[29].real_reference;
9051 if (attribute_flag[30] != 0)
9052 draw_info->interline_spacing=argument_list[30].real_reference;
9053 if (attribute_flag[31] != 0)
9054 draw_info->interword_spacing=argument_list[31].real_reference;
9055 if (attribute_flag[32] != 0)
9056 draw_info->direction=(DirectionType)
9057 argument_list[32].integer_reference;
9058 DrawImage(image,draw_info,exception);
9059 draw_info=DestroyDrawInfo(draw_info);
9060 break;
9061 }
9062 case 39: /* Equalize */
9063 {
9064 if (attribute_flag[0] != 0)
9065 channel=(ChannelType) argument_list[0].integer_reference;
9066 channel_mask=SetImageChannelMask(image,channel);
9067 EqualizeImage(image,exception);
9068 (void) SetImageChannelMask(image,channel_mask);
9069 break;
9070 }
9071 case 40: /* Gamma */
9072 {
9073 if (attribute_flag[1] != 0)
9074 channel=(ChannelType) argument_list[1].integer_reference;
9075 if (attribute_flag[2] == 0)
9076 argument_list[2].real_reference=1.0;
9077 if (attribute_flag[3] == 0)
9078 argument_list[3].real_reference=1.0;
9079 if (attribute_flag[4] == 0)
9080 argument_list[4].real_reference=1.0;
9081 if (attribute_flag[0] == 0)
9082 {
cristy151b66d2015-04-15 10:50:31 +00009083 (void) FormatLocaleString(message,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -05009084 "%.20g,%.20g,%.20g",(double) argument_list[2].real_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009085 (double) argument_list[3].real_reference,
9086 (double) argument_list[4].real_reference);
9087 argument_list[0].string_reference=message;
9088 }
9089 (void) GammaImage(image,StringToDouble(
9090 argument_list[0].string_reference,(char **) NULL),exception);
9091 break;
9092 }
9093 case 41: /* Map */
9094 {
9095 QuantizeInfo
9096 *quantize_info;
9097
9098 if (attribute_flag[0] == 0)
9099 {
9100 ThrowPerlException(exception,OptionError,"MapImageRequired",
9101 PackageName);
9102 goto PerlException;
9103 }
9104 quantize_info=AcquireQuantizeInfo(info->image_info);
9105 if (attribute_flag[1] != 0)
9106 quantize_info->dither_method=(DitherMethod)
9107 argument_list[1].integer_reference;
9108 (void) RemapImages(quantize_info,image,
9109 argument_list[0].image_reference,exception);
9110 quantize_info=DestroyQuantizeInfo(quantize_info);
9111 break;
9112 }
9113 case 42: /* MatteFloodfill */
9114 {
9115 DrawInfo
9116 *draw_info;
9117
9118 MagickBooleanType
9119 invert;
9120
9121 PixelInfo
9122 target;
9123
9124 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9125 (DrawInfo *) NULL);
9126 if (attribute_flag[0] != 0)
9127 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9128 &geometry,exception);
9129 if (attribute_flag[1] != 0)
9130 geometry.x=argument_list[1].integer_reference;
9131 if (attribute_flag[2] != 0)
9132 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009133 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009134 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9135 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9136 geometry.x,geometry.y,&target,exception);
9137 if (attribute_flag[4] != 0)
9138 QueryColorCompliance(argument_list[4].string_reference,
9139 AllCompliance,&target,exception);
9140 if (attribute_flag[3] != 0)
9141 target.alpha=StringToDoubleInterval(
9142 argument_list[3].string_reference,(double) (double) QuantumRange+
9143 1.0);
9144 if (attribute_flag[5] != 0)
9145 image->fuzz=StringToDoubleInterval(
9146 argument_list[5].string_reference,(double) QuantumRange+1.0);
9147 invert=MagickFalse;
9148 if (attribute_flag[6] != 0)
9149 invert=(MagickBooleanType) argument_list[6].integer_reference;
9150 channel_mask=SetImageChannelMask(image,AlphaChannel);
9151 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9152 geometry.y,invert,exception);
9153 (void) SetImageChannelMask(image,channel_mask);
9154 draw_info=DestroyDrawInfo(draw_info);
9155 break;
9156 }
9157 case 43: /* Modulate */
9158 {
9159 char
cristy151b66d2015-04-15 10:50:31 +00009160 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009161
9162 geometry_info.rho=100.0;
9163 geometry_info.sigma=100.0;
9164 geometry_info.xi=100.0;
9165 if (attribute_flag[0] != 0)
9166 (void)ParseGeometry(argument_list[0].string_reference,
9167 &geometry_info);
9168 if (attribute_flag[1] != 0)
9169 geometry_info.xi=argument_list[1].real_reference;
9170 if (attribute_flag[2] != 0)
9171 geometry_info.sigma=argument_list[2].real_reference;
9172 if (attribute_flag[3] != 0)
9173 {
9174 geometry_info.sigma=argument_list[3].real_reference;
9175 SetImageArtifact(image,"modulate:colorspace","HWB");
9176 }
9177 if (attribute_flag[4] != 0)
9178 {
9179 geometry_info.rho=argument_list[4].real_reference;
9180 SetImageArtifact(image,"modulate:colorspace","HSB");
9181 }
9182 if (attribute_flag[5] != 0)
9183 {
9184 geometry_info.sigma=argument_list[5].real_reference;
9185 SetImageArtifact(image,"modulate:colorspace","HSL");
9186 }
9187 if (attribute_flag[6] != 0)
9188 {
9189 geometry_info.rho=argument_list[6].real_reference;
9190 SetImageArtifact(image,"modulate:colorspace","HWB");
9191 }
Cristyb1710fe2017-02-11 13:51:48 -05009192 (void) FormatLocaleString(modulate,MagickPathExtent,"%.20g,%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00009193 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
9194 (void) ModulateImage(image,modulate,exception);
9195 break;
9196 }
9197 case 44: /* Negate */
9198 {
9199 if (attribute_flag[0] == 0)
9200 argument_list[0].integer_reference=0;
9201 if (attribute_flag[1] != 0)
9202 channel=(ChannelType) argument_list[1].integer_reference;
9203 channel_mask=SetImageChannelMask(image,channel);
9204 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9205 MagickTrue : MagickFalse,exception);
9206 (void) SetImageChannelMask(image,channel_mask);
9207 break;
9208 }
9209 case 45: /* Normalize */
9210 {
9211 if (attribute_flag[0] != 0)
9212 channel=(ChannelType) argument_list[0].integer_reference;
9213 channel_mask=SetImageChannelMask(image,channel);
9214 NormalizeImage(image,exception);
9215 (void) SetImageChannelMask(image,channel_mask);
9216 break;
9217 }
9218 case 46: /* NumberColors */
9219 break;
9220 case 47: /* Opaque */
9221 {
9222 MagickBooleanType
9223 invert;
9224
9225 PixelInfo
9226 fill_color,
9227 target;
9228
9229 (void) QueryColorCompliance("none",AllCompliance,&target,
9230 exception);
9231 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9232 exception);
9233 if (attribute_flag[0] != 0)
9234 (void) QueryColorCompliance(argument_list[0].string_reference,
9235 AllCompliance,&target,exception);
9236 if (attribute_flag[1] != 0)
9237 (void) QueryColorCompliance(argument_list[1].string_reference,
9238 AllCompliance,&fill_color,exception);
9239 if (attribute_flag[2] != 0)
9240 image->fuzz=StringToDoubleInterval(
9241 argument_list[2].string_reference,(double) QuantumRange+1.0);
9242 if (attribute_flag[3] != 0)
9243 channel=(ChannelType) argument_list[3].integer_reference;
9244 invert=MagickFalse;
9245 if (attribute_flag[4] != 0)
9246 invert=(MagickBooleanType) argument_list[4].integer_reference;
9247 channel_mask=SetImageChannelMask(image,channel);
9248 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9249 (void) SetImageChannelMask(image,channel_mask);
9250 break;
9251 }
9252 case 48: /* Quantize */
9253 {
9254 QuantizeInfo
9255 *quantize_info;
9256
9257 quantize_info=AcquireQuantizeInfo(info->image_info);
9258 if (attribute_flag[0] != 0)
9259 quantize_info->number_colors=(size_t)
9260 argument_list[0].integer_reference;
9261 if (attribute_flag[1] != 0)
9262 quantize_info->tree_depth=(size_t)
9263 argument_list[1].integer_reference;
9264 if (attribute_flag[2] != 0)
9265 quantize_info->colorspace=(ColorspaceType)
9266 argument_list[2].integer_reference;
9267 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009268 quantize_info->dither_method=(DitherMethod)
9269 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009270 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009271 quantize_info->measure_error=
9272 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009273 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009274 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009275 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009276 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009277 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009278 argument_list[7].integer_reference;
9279 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009280 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009281 else
cristyf7563392014-03-25 13:54:04 +00009282 if ((image->storage_class == DirectClass) ||
9283 (image->colors > quantize_info->number_colors) ||
9284 (quantize_info->colorspace == GRAYColorspace))
9285 (void) QuantizeImage(quantize_info,image,exception);
9286 else
9287 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009288 quantize_info=DestroyQuantizeInfo(quantize_info);
9289 break;
9290 }
9291 case 49: /* Raise */
9292 {
9293 if (attribute_flag[0] != 0)
9294 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9295 &geometry,exception);
9296 if (attribute_flag[1] != 0)
9297 geometry.width=argument_list[1].integer_reference;
9298 if (attribute_flag[2] != 0)
9299 geometry.height=argument_list[2].integer_reference;
9300 if (attribute_flag[3] == 0)
9301 argument_list[3].integer_reference=1;
9302 (void) RaiseImage(image,&geometry,
9303 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9304 exception);
9305 break;
9306 }
9307 case 50: /* Segment */
9308 {
9309 ColorspaceType
9310 colorspace;
9311
9312 double
9313 cluster_threshold,
9314 smoothing_threshold;
9315
9316 MagickBooleanType
9317 verbose;
9318
9319 cluster_threshold=1.0;
9320 smoothing_threshold=1.5;
9321 colorspace=sRGBColorspace;
9322 verbose=MagickFalse;
9323 if (attribute_flag[0] != 0)
9324 {
9325 flags=ParseGeometry(argument_list[0].string_reference,
9326 &geometry_info);
9327 cluster_threshold=geometry_info.rho;
9328 if (flags & SigmaValue)
9329 smoothing_threshold=geometry_info.sigma;
9330 }
9331 if (attribute_flag[1] != 0)
9332 cluster_threshold=argument_list[1].real_reference;
9333 if (attribute_flag[2] != 0)
9334 smoothing_threshold=argument_list[2].real_reference;
9335 if (attribute_flag[3] != 0)
9336 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9337 if (attribute_flag[4] != 0)
9338 verbose=argument_list[4].integer_reference != 0 ?
9339 MagickTrue : MagickFalse;
9340 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9341 smoothing_threshold,exception);
9342 break;
9343 }
9344 case 51: /* Signature */
9345 {
9346 (void) SignatureImage(image,exception);
9347 break;
9348 }
9349 case 52: /* Solarize */
9350 {
9351 geometry_info.rho=QuantumRange/2.0;
9352 if (attribute_flag[0] != 0)
9353 flags=ParseGeometry(argument_list[0].string_reference,
9354 &geometry_info);
9355 if (attribute_flag[1] != 0)
9356 geometry_info.rho=StringToDoubleInterval(
9357 argument_list[1].string_reference,(double) QuantumRange+1.0);
9358 (void) SolarizeImage(image,geometry_info.rho,exception);
9359 break;
9360 }
9361 case 53: /* Sync */
9362 {
9363 (void) SyncImage(image,exception);
9364 break;
9365 }
9366 case 54: /* Texture */
9367 {
9368 if (attribute_flag[0] == 0)
9369 break;
9370 TextureImage(image,argument_list[0].image_reference,exception);
9371 break;
9372 }
9373 case 55: /* Evalute */
9374 {
9375 MagickEvaluateOperator
9376 op;
9377
9378 op=SetEvaluateOperator;
9379 if (attribute_flag[0] == MagickFalse)
9380 argument_list[0].real_reference=0.0;
9381 if (attribute_flag[1] != MagickFalse)
9382 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9383 if (attribute_flag[2] != MagickFalse)
9384 channel=(ChannelType) argument_list[2].integer_reference;
9385 channel_mask=SetImageChannelMask(image,channel);
9386 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9387 exception);
9388 (void) SetImageChannelMask(image,channel_mask);
9389 break;
9390 }
9391 case 56: /* Transparent */
9392 {
9393 double
9394 opacity;
9395
9396 MagickBooleanType
9397 invert;
9398
9399 PixelInfo
9400 target;
9401
9402 (void) QueryColorCompliance("none",AllCompliance,&target,
9403 exception);
9404 if (attribute_flag[0] != 0)
9405 (void) QueryColorCompliance(argument_list[0].string_reference,
9406 AllCompliance,&target,exception);
9407 opacity=TransparentAlpha;
9408 if (attribute_flag[1] != 0)
9409 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9410 (double) QuantumRange+1.0);
9411 if (attribute_flag[2] != 0)
9412 image->fuzz=StringToDoubleInterval(
9413 argument_list[2].string_reference,(double) QuantumRange+1.0);
9414 if (attribute_flag[3] == 0)
9415 argument_list[3].integer_reference=0;
9416 invert=MagickFalse;
9417 if (attribute_flag[3] != 0)
9418 invert=(MagickBooleanType) argument_list[3].integer_reference;
9419 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9420 invert,exception);
9421 break;
9422 }
9423 case 57: /* Threshold */
9424 {
9425 double
9426 threshold;
9427
9428 if (attribute_flag[0] == 0)
9429 argument_list[0].string_reference="50%";
9430 if (attribute_flag[1] != 0)
9431 channel=(ChannelType) argument_list[1].integer_reference;
9432 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9433 (double) QuantumRange+1.0);
9434 channel_mask=SetImageChannelMask(image,channel);
9435 (void) BilevelImage(image,threshold,exception);
9436 (void) SetImageChannelMask(image,channel_mask);
9437 break;
9438 }
9439 case 58: /* Charcoal */
9440 {
9441 if (attribute_flag[0] != 0)
9442 {
9443 flags=ParseGeometry(argument_list[0].string_reference,
9444 &geometry_info);
9445 if ((flags & SigmaValue) == 0)
9446 geometry_info.sigma=1.0;
9447 }
9448 if (attribute_flag[1] != 0)
9449 geometry_info.rho=argument_list[1].real_reference;
9450 if (attribute_flag[2] != 0)
9451 geometry_info.sigma=argument_list[2].real_reference;
9452 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9453 exception);
9454 break;
9455 }
9456 case 59: /* Trim */
9457 {
9458 if (attribute_flag[0] != 0)
9459 image->fuzz=StringToDoubleInterval(
9460 argument_list[0].string_reference,(double) QuantumRange+1.0);
9461 image=TrimImage(image,exception);
9462 break;
9463 }
9464 case 60: /* Wave */
9465 {
9466 PixelInterpolateMethod
9467 method;
9468
9469 if (attribute_flag[0] != 0)
9470 {
9471 flags=ParseGeometry(argument_list[0].string_reference,
9472 &geometry_info);
9473 if ((flags & SigmaValue) == 0)
9474 geometry_info.sigma=1.0;
9475 }
9476 if (attribute_flag[1] != 0)
9477 geometry_info.rho=argument_list[1].real_reference;
9478 if (attribute_flag[2] != 0)
9479 geometry_info.sigma=argument_list[2].real_reference;
9480 method=UndefinedInterpolatePixel;
9481 if (attribute_flag[3] != 0)
9482 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9483 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9484 method,exception);
9485 break;
9486 }
9487 case 61: /* Separate */
9488 {
9489 if (attribute_flag[0] != 0)
9490 channel=(ChannelType) argument_list[0].integer_reference;
9491 image=SeparateImage(image,channel,exception);
9492 break;
9493 }
9494 case 63: /* Stereo */
9495 {
9496 if (attribute_flag[0] == 0)
9497 {
9498 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9499 PackageName);
9500 goto PerlException;
9501 }
9502 if (attribute_flag[1] != 0)
9503 geometry.x=argument_list[1].integer_reference;
9504 if (attribute_flag[2] != 0)
9505 geometry.y=argument_list[2].integer_reference;
9506 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9507 geometry.x,geometry.y,exception);
9508 break;
9509 }
9510 case 64: /* Stegano */
9511 {
9512 if (attribute_flag[0] == 0)
9513 {
9514 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9515 PackageName);
9516 goto PerlException;
9517 }
9518 if (attribute_flag[1] == 0)
9519 argument_list[1].integer_reference=0;
9520 image->offset=argument_list[1].integer_reference;
9521 image=SteganoImage(image,argument_list[0].image_reference,exception);
9522 break;
9523 }
9524 case 65: /* Deconstruct */
9525 {
9526 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9527 break;
9528 }
9529 case 66: /* GaussianBlur */
9530 {
9531 if (attribute_flag[0] != 0)
9532 {
9533 flags=ParseGeometry(argument_list[0].string_reference,
9534 &geometry_info);
9535 if ((flags & SigmaValue) == 0)
9536 geometry_info.sigma=1.0;
9537 }
9538 if (attribute_flag[1] != 0)
9539 geometry_info.rho=argument_list[1].real_reference;
9540 if (attribute_flag[2] != 0)
9541 geometry_info.sigma=argument_list[2].real_reference;
9542 if (attribute_flag[3] != 0)
9543 channel=(ChannelType) argument_list[3].integer_reference;
9544 channel_mask=SetImageChannelMask(image,channel);
9545 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9546 exception);
9547 if (image != (Image *) NULL)
9548 (void) SetImageChannelMask(image,channel_mask);
9549 break;
9550 }
9551 case 67: /* Convolve */
9552 {
9553 KernelInfo
9554 *kernel;
9555
9556 kernel=(KernelInfo *) NULL;
9557 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9558 break;
9559 if (attribute_flag[0] != 0)
9560 {
9561 AV
9562 *av;
9563
9564 size_t
9565 order;
9566
cristy2c57b742014-10-31 00:40:34 +00009567 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009568 if (kernel == (KernelInfo *) NULL)
9569 break;
9570 av=(AV *) argument_list[0].array_reference;
9571 order=(size_t) sqrt(av_len(av)+1);
9572 kernel->width=order;
9573 kernel->height=order;
9574 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9575 order*sizeof(*kernel->values));
9576 if (kernel->values == (MagickRealType *) NULL)
9577 {
9578 kernel=DestroyKernelInfo(kernel);
9579 ThrowPerlException(exception,ResourceLimitFatalError,
9580 "MemoryAllocationFailed",PackageName);
9581 goto PerlException;
9582 }
9583 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9584 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9585 for ( ; j < (ssize_t) (order*order); j++)
9586 kernel->values[j]=0.0;
9587 }
9588 if (attribute_flag[1] != 0)
9589 channel=(ChannelType) argument_list[1].integer_reference;
9590 if (attribute_flag[2] != 0)
9591 SetImageArtifact(image,"filter:blur",
9592 argument_list[2].string_reference);
9593 if (attribute_flag[3] != 0)
9594 {
cristy2c57b742014-10-31 00:40:34 +00009595 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9596 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009597 if (kernel == (KernelInfo *) NULL)
9598 break;
9599 }
9600 channel_mask=SetImageChannelMask(image,channel);
9601 image=ConvolveImage(image,kernel,exception);
9602 if (image != (Image *) NULL)
9603 (void) SetImageChannelMask(image,channel_mask);
9604 kernel=DestroyKernelInfo(kernel);
9605 break;
9606 }
9607 case 68: /* Profile */
9608 {
9609 const char
9610 *name;
9611
9612 Image
9613 *profile_image;
9614
9615 ImageInfo
9616 *profile_info;
9617
9618 StringInfo
9619 *profile;
9620
9621 name="*";
9622 if (attribute_flag[0] != 0)
9623 name=argument_list[0].string_reference;
9624 if (attribute_flag[2] != 0)
9625 image->rendering_intent=(RenderingIntent)
9626 argument_list[2].integer_reference;
9627 if (attribute_flag[3] != 0)
9628 image->black_point_compensation=
9629 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9630 if (attribute_flag[1] != 0)
9631 {
9632 if (argument_list[1].length == 0)
9633 {
9634 /*
9635 Remove a profile from the image.
9636 */
9637 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9638 exception);
9639 break;
9640 }
9641 /*
9642 Associate user supplied profile with the image.
9643 */
9644 profile=AcquireStringInfo(argument_list[1].length);
9645 SetStringInfoDatum(profile,(const unsigned char *)
9646 argument_list[1].string_reference);
9647 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9648 (size_t) GetStringInfoLength(profile),exception);
9649 profile=DestroyStringInfo(profile);
9650 break;
9651 }
9652 /*
9653 Associate a profile with the image.
9654 */
9655 profile_info=CloneImageInfo(info ? info->image_info :
9656 (ImageInfo *) NULL);
9657 profile_image=ReadImages(profile_info,name,exception);
9658 if (profile_image == (Image *) NULL)
9659 break;
9660 ResetImageProfileIterator(profile_image);
9661 name=GetNextImageProfile(profile_image);
9662 while (name != (const char *) NULL)
9663 {
9664 const StringInfo
9665 *profile;
9666
9667 profile=GetImageProfile(profile_image,name);
9668 if (profile != (const StringInfo *) NULL)
9669 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9670 (size_t) GetStringInfoLength(profile),exception);
9671 name=GetNextImageProfile(profile_image);
9672 }
9673 profile_image=DestroyImage(profile_image);
9674 profile_info=DestroyImageInfo(profile_info);
9675 break;
9676 }
9677 case 69: /* UnsharpMask */
9678 {
9679 if (attribute_flag[0] != 0)
9680 {
9681 flags=ParseGeometry(argument_list[0].string_reference,
9682 &geometry_info);
9683 if ((flags & SigmaValue) == 0)
9684 geometry_info.sigma=1.0;
9685 if ((flags & XiValue) == 0)
9686 geometry_info.xi=1.0;
9687 if ((flags & PsiValue) == 0)
9688 geometry_info.psi=0.5;
9689 }
9690 if (attribute_flag[1] != 0)
9691 geometry_info.rho=argument_list[1].real_reference;
9692 if (attribute_flag[2] != 0)
9693 geometry_info.sigma=argument_list[2].real_reference;
9694 if (attribute_flag[3] != 0)
9695 geometry_info.xi=argument_list[3].real_reference;
9696 if (attribute_flag[4] != 0)
9697 geometry_info.psi=argument_list[4].real_reference;
9698 if (attribute_flag[5] != 0)
9699 channel=(ChannelType) argument_list[5].integer_reference;
9700 channel_mask=SetImageChannelMask(image,channel);
9701 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9702 geometry_info.xi,geometry_info.psi,exception);
9703 if (image != (Image *) NULL)
9704 (void) SetImageChannelMask(image,channel_mask);
9705 break;
9706 }
9707 case 70: /* MotionBlur */
9708 {
9709 if (attribute_flag[0] != 0)
9710 {
9711 flags=ParseGeometry(argument_list[0].string_reference,
9712 &geometry_info);
9713 if ((flags & SigmaValue) == 0)
9714 geometry_info.sigma=1.0;
9715 if ((flags & XiValue) == 0)
9716 geometry_info.xi=1.0;
9717 }
9718 if (attribute_flag[1] != 0)
9719 geometry_info.rho=argument_list[1].real_reference;
9720 if (attribute_flag[2] != 0)
9721 geometry_info.sigma=argument_list[2].real_reference;
9722 if (attribute_flag[3] != 0)
9723 geometry_info.xi=argument_list[3].real_reference;
9724 if (attribute_flag[4] != 0)
9725 channel=(ChannelType) argument_list[4].integer_reference;
9726 channel_mask=SetImageChannelMask(image,channel);
9727 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9728 geometry_info.xi,exception);
9729 if (image != (Image *) NULL)
9730 (void) SetImageChannelMask(image,channel_mask);
9731 break;
9732 }
9733 case 71: /* OrderedDither */
9734 {
9735 if (attribute_flag[0] == 0)
9736 argument_list[0].string_reference="o8x8";
9737 if (attribute_flag[1] != 0)
9738 channel=(ChannelType) argument_list[1].integer_reference;
9739 channel_mask=SetImageChannelMask(image,channel);
Cristy6b93c072016-02-04 07:45:48 -05009740 (void) OrderedDitherImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009741 exception);
9742 (void) SetImageChannelMask(image,channel_mask);
9743 break;
9744 }
9745 case 72: /* Shave */
9746 {
9747 if (attribute_flag[0] != 0)
9748 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9749 &geometry,exception);
9750 if (attribute_flag[1] != 0)
9751 geometry.width=argument_list[1].integer_reference;
9752 if (attribute_flag[2] != 0)
9753 geometry.height=argument_list[2].integer_reference;
9754 image=ShaveImage(image,&geometry,exception);
9755 break;
9756 }
9757 case 73: /* Level */
9758 {
9759 double
9760 black_point,
9761 gamma,
9762 white_point;
9763
9764 black_point=0.0;
9765 white_point=(double) image->columns*image->rows;
9766 gamma=1.0;
9767 if (attribute_flag[0] != 0)
9768 {
9769 flags=ParseGeometry(argument_list[0].string_reference,
9770 &geometry_info);
9771 black_point=geometry_info.rho;
9772 if ((flags & SigmaValue) != 0)
9773 white_point=geometry_info.sigma;
9774 if ((flags & XiValue) != 0)
9775 gamma=geometry_info.xi;
9776 if ((flags & PercentValue) != 0)
9777 {
9778 black_point*=(double) (QuantumRange/100.0);
9779 white_point*=(double) (QuantumRange/100.0);
9780 }
9781 if ((flags & SigmaValue) == 0)
9782 white_point=(double) QuantumRange-black_point;
9783 }
9784 if (attribute_flag[1] != 0)
9785 black_point=argument_list[1].real_reference;
9786 if (attribute_flag[2] != 0)
9787 white_point=argument_list[2].real_reference;
9788 if (attribute_flag[3] != 0)
9789 gamma=argument_list[3].real_reference;
9790 if (attribute_flag[4] != 0)
9791 channel=(ChannelType) argument_list[4].integer_reference;
9792 if (attribute_flag[5] != 0)
9793 {
9794 argument_list[0].real_reference=argument_list[5].real_reference;
9795 attribute_flag[0]=attribute_flag[5];
9796 }
9797 channel_mask=SetImageChannelMask(image,channel);
9798 (void) LevelImage(image,black_point,white_point,gamma,exception);
9799 (void) SetImageChannelMask(image,channel_mask);
9800 break;
9801 }
9802 case 74: /* Clip */
9803 {
9804 if (attribute_flag[0] == 0)
9805 argument_list[0].string_reference="#1";
9806 if (attribute_flag[1] == 0)
9807 argument_list[1].integer_reference=MagickTrue;
9808 (void) ClipImagePath(image,argument_list[0].string_reference,
9809 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9810 exception);
9811 break;
9812 }
9813 case 75: /* AffineTransform */
9814 {
9815 DrawInfo
9816 *draw_info;
9817
9818 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9819 (DrawInfo *) NULL);
9820 if (attribute_flag[0] != 0)
9821 {
9822 AV
9823 *av;
9824
9825 av=(AV *) argument_list[0].array_reference;
9826 if ((av_len(av) != 3) && (av_len(av) != 5))
9827 {
9828 ThrowPerlException(exception,OptionError,
9829 "affine matrix must have 4 or 6 elements",PackageName);
9830 goto PerlException;
9831 }
9832 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9833 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9834 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9835 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9836 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9837 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9838 {
9839 ThrowPerlException(exception,OptionError,
9840 "affine matrix is singular",PackageName);
9841 goto PerlException;
9842 }
9843 if (av_len(av) == 5)
9844 {
9845 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9846 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9847 }
9848 }
9849 for (j=1; j < 6; j++)
9850 {
9851 if (attribute_flag[j] == 0)
9852 continue;
9853 value=argument_list[j].string_reference;
9854 angle=argument_list[j].real_reference;
9855 current=draw_info->affine;
9856 GetAffineMatrix(&affine);
9857 switch (j)
9858 {
9859 case 1:
9860 {
9861 /*
9862 Translate.
9863 */
9864 flags=ParseGeometry(value,&geometry_info);
9865 affine.tx=geometry_info.xi;
9866 affine.ty=geometry_info.psi;
9867 if ((flags & PsiValue) == 0)
9868 affine.ty=affine.tx;
9869 break;
9870 }
9871 case 2:
9872 {
9873 /*
9874 Scale.
9875 */
9876 flags=ParseGeometry(value,&geometry_info);
9877 affine.sx=geometry_info.rho;
9878 affine.sy=geometry_info.sigma;
9879 if ((flags & SigmaValue) == 0)
9880 affine.sy=affine.sx;
9881 break;
9882 }
9883 case 3:
9884 {
9885 /*
9886 Rotate.
9887 */
9888 if (angle == 0.0)
9889 break;
9890 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9891 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9892 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9893 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9894 break;
9895 }
9896 case 4:
9897 {
9898 /*
9899 SkewX.
9900 */
9901 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9902 break;
9903 }
9904 case 5:
9905 {
9906 /*
9907 SkewY.
9908 */
9909 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9910 break;
9911 }
9912 }
9913 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9914 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9915 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9916 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9917 draw_info->affine.tx=
9918 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9919 draw_info->affine.ty=
9920 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9921 }
9922 if (attribute_flag[6] != 0)
9923 image->interpolate=(PixelInterpolateMethod)
9924 argument_list[6].integer_reference;
9925 if (attribute_flag[7] != 0)
9926 QueryColorCompliance(argument_list[7].string_reference,
9927 AllCompliance,&image->background_color,exception);
9928 image=AffineTransformImage(image,&draw_info->affine,exception);
9929 draw_info=DestroyDrawInfo(draw_info);
9930 break;
9931 }
9932 case 76: /* Difference */
9933 {
9934 if (attribute_flag[0] == 0)
9935 {
9936 ThrowPerlException(exception,OptionError,
9937 "ReferenceImageRequired",PackageName);
9938 goto PerlException;
9939 }
9940 if (attribute_flag[1] != 0)
9941 image->fuzz=StringToDoubleInterval(
9942 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -05009943 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009944 exception);
9945 break;
9946 }
9947 case 77: /* AdaptiveThreshold */
9948 {
9949 if (attribute_flag[0] != 0)
9950 {
9951 flags=ParseGeometry(argument_list[0].string_reference,
9952 &geometry_info);
9953 if ((flags & PercentValue) != 0)
9954 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9955 }
9956 if (attribute_flag[1] != 0)
9957 geometry_info.rho=argument_list[1].integer_reference;
9958 if (attribute_flag[2] != 0)
9959 geometry_info.sigma=argument_list[2].integer_reference;
9960 if (attribute_flag[3] != 0)
9961 geometry_info.xi=argument_list[3].integer_reference;;
9962 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9963 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9964 break;
9965 }
9966 case 78: /* Resample */
9967 {
9968 size_t
9969 height,
9970 width;
9971
9972 if (attribute_flag[0] != 0)
9973 {
9974 flags=ParseGeometry(argument_list[0].string_reference,
9975 &geometry_info);
9976 if ((flags & SigmaValue) == 0)
9977 geometry_info.sigma=geometry_info.rho;
9978 }
9979 if (attribute_flag[1] != 0)
9980 geometry_info.rho=argument_list[1].real_reference;
9981 if (attribute_flag[2] != 0)
9982 geometry_info.sigma=argument_list[2].real_reference;
9983 if (attribute_flag[3] == 0)
9984 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
9985 if (attribute_flag[4] == 0)
9986 SetImageArtifact(image,"filter:support",
9987 argument_list[4].string_reference);
9988 width=(size_t) (geometry_info.rho*image->columns/
9989 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
9990 height=(size_t) (geometry_info.sigma*image->rows/
9991 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
Cristy8645e042016-02-03 16:35:29 -05009992 image=ResizeImage(image,width,height,(FilterType)
cristy4a3ce0a2013-08-03 20:06:59 +00009993 argument_list[3].integer_reference,exception);
9994 if (image != (Image *) NULL)
9995 {
9996 image->resolution.x=geometry_info.rho;
9997 image->resolution.y=geometry_info.sigma;
9998 }
9999 break;
10000 }
10001 case 79: /* Describe */
10002 {
10003 if (attribute_flag[0] == 0)
10004 argument_list[0].file_reference=(FILE *) NULL;
10005 if (attribute_flag[1] != 0)
10006 (void) SetImageArtifact(image,"identify:features",
10007 argument_list[1].string_reference);
10008 (void) IdentifyImage(image,argument_list[0].file_reference,
10009 MagickTrue,exception);
10010 break;
10011 }
10012 case 80: /* BlackThreshold */
10013 {
10014 if (attribute_flag[0] == 0)
10015 argument_list[0].string_reference="50%";
10016 if (attribute_flag[2] != 0)
10017 channel=(ChannelType) argument_list[2].integer_reference;
10018 channel_mask=SetImageChannelMask(image,channel);
10019 BlackThresholdImage(image,argument_list[0].string_reference,
10020 exception);
10021 (void) SetImageChannelMask(image,channel_mask);
10022 break;
10023 }
10024 case 81: /* WhiteThreshold */
10025 {
10026 if (attribute_flag[0] == 0)
10027 argument_list[0].string_reference="50%";
10028 if (attribute_flag[2] != 0)
10029 channel=(ChannelType) argument_list[2].integer_reference;
10030 channel_mask=SetImageChannelMask(image,channel);
10031 WhiteThresholdImage(image,argument_list[0].string_reference,
10032 exception);
10033 (void) SetImageChannelMask(image,channel_mask);
10034 break;
10035 }
cristy60c73c02014-03-25 12:09:58 +000010036 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010037 {
10038 if (attribute_flag[0] != 0)
10039 {
10040 flags=ParseGeometry(argument_list[0].string_reference,
10041 &geometry_info);
10042 }
10043 if (attribute_flag[1] != 0)
10044 geometry_info.rho=argument_list[1].real_reference;
10045 if (attribute_flag[2] != 0)
10046 channel=(ChannelType) argument_list[2].integer_reference;
10047 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010048 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010049 if (image != (Image *) NULL)
10050 (void) SetImageChannelMask(image,channel_mask);
10051 break;
10052 }
10053 case 83: /* Thumbnail */
10054 {
10055 if (attribute_flag[0] != 0)
10056 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10057 &geometry,exception);
10058 if (attribute_flag[1] != 0)
10059 geometry.width=argument_list[1].integer_reference;
10060 if (attribute_flag[2] != 0)
10061 geometry.height=argument_list[2].integer_reference;
10062 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10063 break;
10064 }
10065 case 84: /* Strip */
10066 {
10067 (void) StripImage(image,exception);
10068 break;
10069 }
10070 case 85: /* Tint */
10071 {
10072 PixelInfo
10073 tint;
10074
10075 GetPixelInfo(image,&tint);
10076 if (attribute_flag[0] != 0)
10077 (void) QueryColorCompliance(argument_list[0].string_reference,
10078 AllCompliance,&tint,exception);
10079 if (attribute_flag[1] == 0)
10080 argument_list[1].string_reference="100";
10081 image=TintImage(image,argument_list[1].string_reference,&tint,
10082 exception);
10083 break;
10084 }
10085 case 86: /* Channel */
10086 {
10087 if (attribute_flag[0] != 0)
10088 channel=(ChannelType) argument_list[0].integer_reference;
10089 image=SeparateImage(image,channel,exception);
10090 break;
10091 }
10092 case 87: /* Splice */
10093 {
cristy260bd762014-08-15 12:46:34 +000010094 if (attribute_flag[7] != 0)
10095 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010096 if (attribute_flag[0] != 0)
10097 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10098 &geometry,exception);
10099 if (attribute_flag[1] != 0)
10100 geometry.width=argument_list[1].integer_reference;
10101 if (attribute_flag[2] != 0)
10102 geometry.height=argument_list[2].integer_reference;
10103 if (attribute_flag[3] != 0)
10104 geometry.x=argument_list[3].integer_reference;
10105 if (attribute_flag[4] != 0)
10106 geometry.y=argument_list[4].integer_reference;
10107 if (attribute_flag[5] != 0)
10108 image->fuzz=StringToDoubleInterval(
10109 argument_list[5].string_reference,(double) QuantumRange+1.0);
10110 if (attribute_flag[6] != 0)
10111 (void) QueryColorCompliance(argument_list[6].string_reference,
10112 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010113 image=SpliceImage(image,&geometry,exception);
10114 break;
10115 }
10116 case 88: /* Posterize */
10117 {
10118 if (attribute_flag[0] == 0)
10119 argument_list[0].integer_reference=3;
10120 if (attribute_flag[1] == 0)
10121 argument_list[1].integer_reference=0;
10122 (void) PosterizeImage(image,argument_list[0].integer_reference,
10123 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10124 NoDitherMethod,exception);
10125 break;
10126 }
10127 case 89: /* Shadow */
10128 {
10129 if (attribute_flag[0] != 0)
10130 {
10131 flags=ParseGeometry(argument_list[0].string_reference,
10132 &geometry_info);
10133 if ((flags & SigmaValue) == 0)
10134 geometry_info.sigma=1.0;
10135 if ((flags & XiValue) == 0)
10136 geometry_info.xi=4.0;
10137 if ((flags & PsiValue) == 0)
10138 geometry_info.psi=4.0;
10139 }
10140 if (attribute_flag[1] != 0)
10141 geometry_info.rho=argument_list[1].real_reference;
10142 if (attribute_flag[2] != 0)
10143 geometry_info.sigma=argument_list[2].real_reference;
10144 if (attribute_flag[3] != 0)
10145 geometry_info.xi=argument_list[3].integer_reference;
10146 if (attribute_flag[4] != 0)
10147 geometry_info.psi=argument_list[4].integer_reference;
10148 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10149 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10150 ceil(geometry_info.psi-0.5),exception);
10151 break;
10152 }
10153 case 90: /* Identify */
10154 {
10155 if (attribute_flag[0] == 0)
10156 argument_list[0].file_reference=(FILE *) NULL;
10157 if (attribute_flag[1] != 0)
10158 (void) SetImageArtifact(image,"identify:features",
10159 argument_list[1].string_reference);
10160 if ((attribute_flag[2] != 0) &&
10161 (argument_list[2].integer_reference != 0))
10162 (void) SetImageArtifact(image,"identify:unique","true");
10163 (void) IdentifyImage(image,argument_list[0].file_reference,
10164 MagickTrue,exception);
10165 break;
10166 }
10167 case 91: /* SepiaTone */
10168 {
10169 if (attribute_flag[0] == 0)
10170 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10171 image=SepiaToneImage(image,argument_list[0].real_reference,
10172 exception);
10173 break;
10174 }
10175 case 92: /* SigmoidalContrast */
10176 {
10177 MagickBooleanType
10178 sharpen;
10179
10180 if (attribute_flag[0] != 0)
10181 {
10182 flags=ParseGeometry(argument_list[0].string_reference,
10183 &geometry_info);
10184 if ((flags & SigmaValue) == 0)
10185 geometry_info.sigma=QuantumRange/2.0;
10186 if ((flags & PercentValue) != 0)
10187 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10188 }
10189 if (attribute_flag[1] != 0)
10190 geometry_info.rho=argument_list[1].real_reference;
10191 if (attribute_flag[2] != 0)
10192 geometry_info.sigma=argument_list[2].real_reference;
10193 if (attribute_flag[3] != 0)
10194 channel=(ChannelType) argument_list[3].integer_reference;
10195 sharpen=MagickTrue;
10196 if (attribute_flag[4] != 0)
10197 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10198 MagickFalse;
10199 channel_mask=SetImageChannelMask(image,channel);
10200 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10201 geometry_info.sigma,exception);
10202 (void) SetImageChannelMask(image,channel_mask);
10203 break;
10204 }
10205 case 93: /* Extent */
10206 {
10207 if (attribute_flag[7] != 0)
10208 image->gravity=(GravityType) argument_list[7].integer_reference;
10209 if (attribute_flag[0] != 0)
10210 {
10211 int
10212 flags;
10213
10214 flags=ParseGravityGeometry(image,
10215 argument_list[0].string_reference,&geometry,exception);
10216 (void) flags;
10217 if (geometry.width == 0)
10218 geometry.width=image->columns;
10219 if (geometry.height == 0)
10220 geometry.height=image->rows;
10221 }
10222 if (attribute_flag[1] != 0)
10223 geometry.width=argument_list[1].integer_reference;
10224 if (attribute_flag[2] != 0)
10225 geometry.height=argument_list[2].integer_reference;
10226 if (attribute_flag[3] != 0)
10227 geometry.x=argument_list[3].integer_reference;
10228 if (attribute_flag[4] != 0)
10229 geometry.y=argument_list[4].integer_reference;
10230 if (attribute_flag[5] != 0)
10231 image->fuzz=StringToDoubleInterval(
10232 argument_list[5].string_reference,(double) QuantumRange+1.0);
10233 if (attribute_flag[6] != 0)
10234 (void) QueryColorCompliance(argument_list[6].string_reference,
10235 AllCompliance,&image->background_color,exception);
10236 image=ExtentImage(image,&geometry,exception);
10237 break;
10238 }
10239 case 94: /* Vignette */
10240 {
10241 if (attribute_flag[0] != 0)
10242 {
10243 flags=ParseGeometry(argument_list[0].string_reference,
10244 &geometry_info);
10245 if ((flags & SigmaValue) == 0)
10246 geometry_info.sigma=1.0;
10247 if ((flags & XiValue) == 0)
10248 geometry_info.xi=0.1*image->columns;
10249 if ((flags & PsiValue) == 0)
10250 geometry_info.psi=0.1*image->rows;
10251 }
10252 if (attribute_flag[1] != 0)
10253 geometry_info.rho=argument_list[1].real_reference;
10254 if (attribute_flag[2] != 0)
10255 geometry_info.sigma=argument_list[2].real_reference;
10256 if (attribute_flag[3] != 0)
10257 geometry_info.xi=argument_list[3].integer_reference;
10258 if (attribute_flag[4] != 0)
10259 geometry_info.psi=argument_list[4].integer_reference;
10260 if (attribute_flag[5] != 0)
10261 (void) QueryColorCompliance(argument_list[5].string_reference,
10262 AllCompliance,&image->background_color,exception);
10263 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10264 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10265 ceil(geometry_info.psi-0.5),exception);
10266 break;
10267 }
10268 case 95: /* ContrastStretch */
10269 {
10270 double
10271 black_point,
10272 white_point;
10273
10274 black_point=0.0;
10275 white_point=(double) image->columns*image->rows;
10276 if (attribute_flag[0] != 0)
10277 {
10278 flags=ParseGeometry(argument_list[0].string_reference,
10279 &geometry_info);
10280 black_point=geometry_info.rho;
10281 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10282 black_point;
10283 if ((flags & PercentValue) != 0)
10284 {
10285 black_point*=(double) image->columns*image->rows/100.0;
10286 white_point*=(double) image->columns*image->rows/100.0;
10287 }
10288 white_point=(double) image->columns*image->rows-
10289 white_point;
10290 }
10291 if (attribute_flag[1] != 0)
10292 black_point=argument_list[1].real_reference;
10293 if (attribute_flag[2] != 0)
10294 white_point=argument_list[2].real_reference;
10295 if (attribute_flag[4] != 0)
10296 channel=(ChannelType) argument_list[4].integer_reference;
10297 channel_mask=SetImageChannelMask(image,channel);
10298 (void) ContrastStretchImage(image,black_point,white_point,exception);
10299 (void) SetImageChannelMask(image,channel_mask);
10300 break;
10301 }
10302 case 96: /* Sans0 */
10303 {
10304 break;
10305 }
10306 case 97: /* Sans1 */
10307 {
10308 break;
10309 }
10310 case 98: /* AdaptiveSharpen */
10311 {
10312 if (attribute_flag[0] != 0)
10313 {
10314 flags=ParseGeometry(argument_list[0].string_reference,
10315 &geometry_info);
10316 if ((flags & SigmaValue) == 0)
10317 geometry_info.sigma=1.0;
10318 if ((flags & XiValue) == 0)
10319 geometry_info.xi=0.0;
10320 }
10321 if (attribute_flag[1] != 0)
10322 geometry_info.rho=argument_list[1].real_reference;
10323 if (attribute_flag[2] != 0)
10324 geometry_info.sigma=argument_list[2].real_reference;
10325 if (attribute_flag[3] != 0)
10326 geometry_info.xi=argument_list[3].real_reference;
10327 if (attribute_flag[4] != 0)
10328 channel=(ChannelType) argument_list[4].integer_reference;
10329 channel_mask=SetImageChannelMask(image,channel);
10330 image=AdaptiveSharpenImage(image,geometry_info.rho,
10331 geometry_info.sigma,exception);
10332 if (image != (Image *) NULL)
10333 (void) SetImageChannelMask(image,channel_mask);
10334 break;
10335 }
10336 case 99: /* Transpose */
10337 {
10338 image=TransposeImage(image,exception);
10339 break;
10340 }
10341 case 100: /* Tranverse */
10342 {
10343 image=TransverseImage(image,exception);
10344 break;
10345 }
10346 case 101: /* AutoOrient */
10347 {
10348 image=AutoOrientImage(image,image->orientation,exception);
10349 break;
10350 }
10351 case 102: /* AdaptiveBlur */
10352 {
10353 if (attribute_flag[0] != 0)
10354 {
10355 flags=ParseGeometry(argument_list[0].string_reference,
10356 &geometry_info);
10357 if ((flags & SigmaValue) == 0)
10358 geometry_info.sigma=1.0;
10359 if ((flags & XiValue) == 0)
10360 geometry_info.xi=0.0;
10361 }
10362 if (attribute_flag[1] != 0)
10363 geometry_info.rho=argument_list[1].real_reference;
10364 if (attribute_flag[2] != 0)
10365 geometry_info.sigma=argument_list[2].real_reference;
10366 if (attribute_flag[3] != 0)
10367 channel=(ChannelType) argument_list[3].integer_reference;
10368 channel_mask=SetImageChannelMask(image,channel);
10369 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10370 exception);
10371 if (image != (Image *) NULL)
10372 (void) SetImageChannelMask(image,channel_mask);
10373 break;
10374 }
10375 case 103: /* Sketch */
10376 {
10377 if (attribute_flag[0] != 0)
10378 {
10379 flags=ParseGeometry(argument_list[0].string_reference,
10380 &geometry_info);
10381 if ((flags & SigmaValue) == 0)
10382 geometry_info.sigma=1.0;
10383 if ((flags & XiValue) == 0)
10384 geometry_info.xi=1.0;
10385 }
10386 if (attribute_flag[1] != 0)
10387 geometry_info.rho=argument_list[1].real_reference;
10388 if (attribute_flag[2] != 0)
10389 geometry_info.sigma=argument_list[2].real_reference;
10390 if (attribute_flag[3] != 0)
10391 geometry_info.xi=argument_list[3].real_reference;
10392 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10393 geometry_info.xi,exception);
10394 break;
10395 }
10396 case 104: /* UniqueColors */
10397 {
10398 image=UniqueImageColors(image,exception);
10399 break;
10400 }
10401 case 105: /* AdaptiveResize */
10402 {
10403 if (attribute_flag[0] != 0)
10404 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10405 &geometry,exception);
10406 if (attribute_flag[1] != 0)
10407 geometry.width=argument_list[1].integer_reference;
10408 if (attribute_flag[2] != 0)
10409 geometry.height=argument_list[2].integer_reference;
10410 if (attribute_flag[3] != 0)
Cristy8645e042016-02-03 16:35:29 -050010411 image->filter=(FilterType) argument_list[4].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010412 if (attribute_flag[4] != 0)
10413 SetImageArtifact(image,"filter:support",
10414 argument_list[4].string_reference);
10415 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10416 exception);
10417 break;
10418 }
10419 case 106: /* ClipMask */
10420 {
10421 Image
10422 *mask_image;
10423
10424 if (attribute_flag[0] == 0)
10425 {
10426 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10427 PackageName);
10428 goto PerlException;
10429 }
10430 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10431 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010432 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010433 mask_image=DestroyImage(mask_image);
10434 break;
10435 }
10436 case 107: /* LinearStretch */
10437 {
10438 double
10439 black_point,
10440 white_point;
10441
10442 black_point=0.0;
10443 white_point=(double) image->columns*image->rows;
10444 if (attribute_flag[0] != 0)
10445 {
10446 flags=ParseGeometry(argument_list[0].string_reference,
10447 &geometry_info);
10448 if ((flags & SigmaValue) != 0)
10449 white_point=geometry_info.sigma;
10450 if ((flags & PercentValue) != 0)
10451 {
10452 black_point*=(double) image->columns*image->rows/100.0;
10453 white_point*=(double) image->columns*image->rows/100.0;
10454 }
10455 if ((flags & SigmaValue) == 0)
10456 white_point=(double) image->columns*image->rows-black_point;
10457 }
10458 if (attribute_flag[1] != 0)
10459 black_point=argument_list[1].real_reference;
10460 if (attribute_flag[2] != 0)
10461 white_point=argument_list[2].real_reference;
10462 (void) LinearStretchImage(image,black_point,white_point,exception);
10463 break;
10464 }
10465 case 108: /* ColorMatrix */
10466 {
10467 AV
10468 *av;
10469
10470 double
10471 *color_matrix;
10472
10473 KernelInfo
10474 *kernel_info;
10475
10476 size_t
10477 order;
10478
10479 if (attribute_flag[0] == 0)
10480 break;
10481 av=(AV *) argument_list[0].array_reference;
10482 order=(size_t) sqrt(av_len(av)+1);
10483 color_matrix=(double *) AcquireQuantumMemory(order,order*
10484 sizeof(*color_matrix));
10485 if (color_matrix == (double *) NULL)
10486 {
10487 ThrowPerlException(exception,ResourceLimitFatalError,
10488 "MemoryAllocationFailed",PackageName);
10489 goto PerlException;
10490 }
10491 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10492 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10493 for ( ; j < (ssize_t) (order*order); j++)
10494 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010495 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010496 if (kernel_info == (KernelInfo *) NULL)
10497 break;
10498 kernel_info->width=order;
10499 kernel_info->height=order;
10500 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10501 order*sizeof(*kernel_info->values));
10502 if (kernel_info->values != (MagickRealType *) NULL)
10503 {
10504 for (i=0; i < (ssize_t) (order*order); i++)
10505 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10506 image=ColorMatrixImage(image,kernel_info,exception);
10507 }
10508 kernel_info=DestroyKernelInfo(kernel_info);
10509 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10510 break;
10511 }
10512 case 109: /* Mask */
10513 {
10514 Image
10515 *mask_image;
10516
10517 if (attribute_flag[0] == 0)
10518 {
10519 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10520 PackageName);
10521 goto PerlException;
10522 }
10523 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10524 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010525 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010526 mask_image=DestroyImage(mask_image);
10527 break;
10528 }
10529 case 110: /* Polaroid */
10530 {
10531 char
10532 *caption;
10533
10534 DrawInfo
10535 *draw_info;
10536
10537 double
10538 angle;
10539
10540 PixelInterpolateMethod
10541 method;
10542
10543 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10544 (DrawInfo *) NULL);
10545 caption=(char *) NULL;
10546 if (attribute_flag[0] != 0)
10547 caption=InterpretImageProperties(info ? info->image_info :
10548 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10549 exception);
10550 angle=0.0;
10551 if (attribute_flag[1] != 0)
10552 angle=argument_list[1].real_reference;
10553 if (attribute_flag[2] != 0)
10554 (void) CloneString(&draw_info->font,
10555 argument_list[2].string_reference);
10556 if (attribute_flag[3] != 0)
10557 (void) QueryColorCompliance(argument_list[3].string_reference,
10558 AllCompliance,&draw_info->stroke,exception);
10559 if (attribute_flag[4] != 0)
10560 (void) QueryColorCompliance(argument_list[4].string_reference,
10561 AllCompliance,&draw_info->fill,exception);
10562 if (attribute_flag[5] != 0)
10563 draw_info->stroke_width=argument_list[5].real_reference;
10564 if (attribute_flag[6] != 0)
10565 draw_info->pointsize=argument_list[6].real_reference;
10566 if (attribute_flag[7] != 0)
10567 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10568 if (attribute_flag[8] != 0)
10569 (void) QueryColorCompliance(argument_list[8].string_reference,
10570 AllCompliance,&image->background_color,exception);
10571 method=UndefinedInterpolatePixel;
10572 if (attribute_flag[9] != 0)
10573 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10574 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10575 draw_info=DestroyDrawInfo(draw_info);
10576 if (caption != (char *) NULL)
10577 caption=DestroyString(caption);
10578 break;
10579 }
10580 case 111: /* FloodfillPaint */
10581 {
10582 DrawInfo
10583 *draw_info;
10584
10585 MagickBooleanType
10586 invert;
10587
10588 PixelInfo
10589 target;
10590
10591 draw_info=CloneDrawInfo(info ? info->image_info :
10592 (ImageInfo *) NULL,(DrawInfo *) NULL);
10593 if (attribute_flag[0] != 0)
10594 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10595 &geometry,exception);
10596 if (attribute_flag[1] != 0)
10597 geometry.x=argument_list[1].integer_reference;
10598 if (attribute_flag[2] != 0)
10599 geometry.y=argument_list[2].integer_reference;
10600 if (attribute_flag[3] != 0)
10601 (void) QueryColorCompliance(argument_list[3].string_reference,
10602 AllCompliance,&draw_info->fill,exception);
10603 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10604 geometry.x,geometry.y,&target,exception);
10605 if (attribute_flag[4] != 0)
10606 QueryColorCompliance(argument_list[4].string_reference,
10607 AllCompliance,&target,exception);
10608 if (attribute_flag[5] != 0)
10609 image->fuzz=StringToDoubleInterval(
10610 argument_list[5].string_reference,(double) QuantumRange+1.0);
10611 if (attribute_flag[6] != 0)
10612 channel=(ChannelType) argument_list[6].integer_reference;
10613 invert=MagickFalse;
10614 if (attribute_flag[7] != 0)
10615 invert=(MagickBooleanType) argument_list[7].integer_reference;
10616 channel_mask=SetImageChannelMask(image,channel);
10617 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10618 geometry.y,invert,exception);
10619 (void) SetImageChannelMask(image,channel_mask);
10620 draw_info=DestroyDrawInfo(draw_info);
10621 break;
10622 }
10623 case 112: /* Distort */
10624 {
10625 AV
10626 *av;
10627
10628 double
10629 *coordinates;
10630
Cristy8645e042016-02-03 16:35:29 -050010631 DistortMethod
cristy4a3ce0a2013-08-03 20:06:59 +000010632 method;
10633
10634 size_t
10635 number_coordinates;
10636
10637 VirtualPixelMethod
10638 virtual_pixel;
10639
10640 if (attribute_flag[0] == 0)
10641 break;
10642 method=UndefinedDistortion;
10643 if (attribute_flag[1] != 0)
Cristy8645e042016-02-03 16:35:29 -050010644 method=(DistortMethod) argument_list[1].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010645 av=(AV *) argument_list[0].array_reference;
10646 number_coordinates=(size_t) av_len(av)+1;
10647 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10648 sizeof(*coordinates));
10649 if (coordinates == (double *) NULL)
10650 {
10651 ThrowPerlException(exception,ResourceLimitFatalError,
10652 "MemoryAllocationFailed",PackageName);
10653 goto PerlException;
10654 }
10655 for (j=0; j < (ssize_t) number_coordinates; j++)
10656 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10657 virtual_pixel=UndefinedVirtualPixelMethod;
10658 if (attribute_flag[2] != 0)
10659 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10660 argument_list[2].integer_reference,exception);
10661 image=DistortImage(image,method,number_coordinates,coordinates,
10662 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10663 exception);
10664 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10665 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10666 exception);
10667 coordinates=(double *) RelinquishMagickMemory(coordinates);
10668 break;
10669 }
10670 case 113: /* Clut */
10671 {
10672 PixelInterpolateMethod
10673 method;
10674
10675 if (attribute_flag[0] == 0)
10676 {
10677 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10678 PackageName);
10679 goto PerlException;
10680 }
10681 method=UndefinedInterpolatePixel;
10682 if (attribute_flag[1] != 0)
10683 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10684 if (attribute_flag[2] != 0)
10685 channel=(ChannelType) argument_list[2].integer_reference;
10686 channel_mask=SetImageChannelMask(image,channel);
10687 (void) ClutImage(image,argument_list[0].image_reference,method,
10688 exception);
10689 (void) SetImageChannelMask(image,channel_mask);
10690 break;
10691 }
10692 case 114: /* LiquidRescale */
10693 {
10694 if (attribute_flag[0] != 0)
10695 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10696 &geometry,exception);
10697 if (attribute_flag[1] != 0)
10698 geometry.width=argument_list[1].integer_reference;
10699 if (attribute_flag[2] != 0)
10700 geometry.height=argument_list[2].integer_reference;
10701 if (attribute_flag[3] == 0)
10702 argument_list[3].real_reference=1.0;
10703 if (attribute_flag[4] == 0)
10704 argument_list[4].real_reference=0.0;
10705 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10706 argument_list[3].real_reference,argument_list[4].real_reference,
10707 exception);
10708 break;
10709 }
10710 case 115: /* EncipherImage */
10711 {
10712 (void) EncipherImage(image,argument_list[0].string_reference,
10713 exception);
10714 break;
10715 }
10716 case 116: /* DecipherImage */
10717 {
10718 (void) DecipherImage(image,argument_list[0].string_reference,
10719 exception);
10720 break;
10721 }
10722 case 117: /* Deskew */
10723 {
10724 geometry_info.rho=QuantumRange/2.0;
10725 if (attribute_flag[0] != 0)
10726 flags=ParseGeometry(argument_list[0].string_reference,
10727 &geometry_info);
10728 if (attribute_flag[1] != 0)
10729 geometry_info.rho=StringToDoubleInterval(
10730 argument_list[1].string_reference,(double) QuantumRange+1.0);
10731 image=DeskewImage(image,geometry_info.rho,exception);
10732 break;
10733 }
10734 case 118: /* Remap */
10735 {
10736 QuantizeInfo
10737 *quantize_info;
10738
10739 if (attribute_flag[0] == 0)
10740 {
10741 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10742 PackageName);
10743 goto PerlException;
10744 }
10745 quantize_info=AcquireQuantizeInfo(info->image_info);
10746 if (attribute_flag[1] != 0)
10747 quantize_info->dither_method=(DitherMethod)
10748 argument_list[1].integer_reference;
10749 (void) RemapImages(quantize_info,image,
10750 argument_list[0].image_reference,exception);
10751 quantize_info=DestroyQuantizeInfo(quantize_info);
10752 break;
10753 }
10754 case 119: /* SparseColor */
10755 {
10756 AV
10757 *av;
10758
10759 double
10760 *coordinates;
10761
10762 SparseColorMethod
10763 method;
10764
10765 size_t
10766 number_coordinates;
10767
10768 VirtualPixelMethod
10769 virtual_pixel;
10770
10771 if (attribute_flag[0] == 0)
10772 break;
10773 method=UndefinedColorInterpolate;
10774 if (attribute_flag[1] != 0)
10775 method=(SparseColorMethod) argument_list[1].integer_reference;
10776 av=(AV *) argument_list[0].array_reference;
10777 number_coordinates=(size_t) av_len(av)+1;
10778 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10779 sizeof(*coordinates));
10780 if (coordinates == (double *) NULL)
10781 {
10782 ThrowPerlException(exception,ResourceLimitFatalError,
10783 "MemoryAllocationFailed",PackageName);
10784 goto PerlException;
10785 }
10786 for (j=0; j < (ssize_t) number_coordinates; j++)
10787 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10788 virtual_pixel=UndefinedVirtualPixelMethod;
10789 if (attribute_flag[2] != 0)
10790 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10791 argument_list[2].integer_reference,exception);
10792 if (attribute_flag[3] != 0)
10793 channel=(ChannelType) argument_list[3].integer_reference;
10794 channel_mask=SetImageChannelMask(image,channel);
10795 image=SparseColorImage(image,method,number_coordinates,coordinates,
10796 exception);
10797 if (image != (Image *) NULL)
10798 (void) SetImageChannelMask(image,channel_mask);
10799 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10800 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10801 exception);
10802 coordinates=(double *) RelinquishMagickMemory(coordinates);
10803 break;
10804 }
10805 case 120: /* Function */
10806 {
10807 AV
10808 *av;
10809
10810 double
10811 *parameters;
10812
10813 MagickFunction
10814 function;
10815
10816 size_t
10817 number_parameters;
10818
10819 VirtualPixelMethod
10820 virtual_pixel;
10821
10822 if (attribute_flag[0] == 0)
10823 break;
10824 function=UndefinedFunction;
10825 if (attribute_flag[1] != 0)
10826 function=(MagickFunction) argument_list[1].integer_reference;
10827 av=(AV *) argument_list[0].array_reference;
10828 number_parameters=(size_t) av_len(av)+1;
10829 parameters=(double *) AcquireQuantumMemory(number_parameters,
10830 sizeof(*parameters));
10831 if (parameters == (double *) NULL)
10832 {
10833 ThrowPerlException(exception,ResourceLimitFatalError,
10834 "MemoryAllocationFailed",PackageName);
10835 goto PerlException;
10836 }
10837 for (j=0; j < (ssize_t) number_parameters; j++)
10838 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10839 virtual_pixel=UndefinedVirtualPixelMethod;
10840 if (attribute_flag[2] != 0)
10841 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10842 argument_list[2].integer_reference,exception);
10843 (void) FunctionImage(image,function,number_parameters,parameters,
10844 exception);
10845 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10846 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10847 exception);
10848 parameters=(double *) RelinquishMagickMemory(parameters);
10849 break;
10850 }
10851 case 121: /* SelectiveBlur */
10852 {
10853 if (attribute_flag[0] != 0)
10854 {
10855 flags=ParseGeometry(argument_list[0].string_reference,
10856 &geometry_info);
10857 if ((flags & SigmaValue) == 0)
10858 geometry_info.sigma=1.0;
10859 if ((flags & PercentValue) != 0)
10860 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10861 }
10862 if (attribute_flag[1] != 0)
10863 geometry_info.rho=argument_list[1].real_reference;
10864 if (attribute_flag[2] != 0)
10865 geometry_info.sigma=argument_list[2].real_reference;
10866 if (attribute_flag[3] != 0)
10867 geometry_info.xi=argument_list[3].integer_reference;;
10868 if (attribute_flag[5] != 0)
10869 channel=(ChannelType) argument_list[5].integer_reference;
10870 channel_mask=SetImageChannelMask(image,channel);
10871 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10872 geometry_info.xi,exception);
10873 if (image != (Image *) NULL)
10874 (void) SetImageChannelMask(image,channel_mask);
10875 break;
10876 }
10877 case 122: /* HaldClut */
10878 {
10879 if (attribute_flag[0] == 0)
10880 {
10881 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10882 PackageName);
10883 goto PerlException;
10884 }
10885 if (attribute_flag[1] != 0)
10886 channel=(ChannelType) argument_list[1].integer_reference;
10887 channel_mask=SetImageChannelMask(image,channel);
10888 (void) HaldClutImage(image,argument_list[0].image_reference,
10889 exception);
10890 (void) SetImageChannelMask(image,channel_mask);
10891 break;
10892 }
10893 case 123: /* BlueShift */
10894 {
10895 if (attribute_flag[0] != 0)
10896 (void) ParseGeometry(argument_list[0].string_reference,
10897 &geometry_info);
10898 image=BlueShiftImage(image,geometry_info.rho,exception);
10899 break;
10900 }
10901 case 124: /* ForwardFourierTransformImage */
10902 {
10903 image=ForwardFourierTransformImage(image,
10904 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10905 exception);
10906 break;
10907 }
10908 case 125: /* InverseFourierTransformImage */
10909 {
10910 image=InverseFourierTransformImage(image,image->next,
10911 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10912 exception);
10913 break;
10914 }
10915 case 126: /* ColorDecisionList */
10916 {
10917 if (attribute_flag[0] == 0)
10918 argument_list[0].string_reference=(char *) NULL;
10919 (void) ColorDecisionListImage(image,
10920 argument_list[0].string_reference,exception);
10921 break;
10922 }
10923 case 127: /* AutoGamma */
10924 {
10925 if (attribute_flag[0] != 0)
10926 channel=(ChannelType) argument_list[0].integer_reference;
10927 channel_mask=SetImageChannelMask(image,channel);
10928 (void) AutoGammaImage(image,exception);
10929 (void) SetImageChannelMask(image,channel_mask);
10930 break;
10931 }
10932 case 128: /* AutoLevel */
10933 {
10934 if (attribute_flag[0] != 0)
10935 channel=(ChannelType) argument_list[0].integer_reference;
10936 channel_mask=SetImageChannelMask(image,channel);
10937 (void) AutoLevelImage(image,exception);
10938 (void) SetImageChannelMask(image,channel_mask);
10939 break;
10940 }
10941 case 129: /* LevelColors */
10942 {
10943 PixelInfo
10944 black_point,
10945 white_point;
10946
10947 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10948 exception);
10949 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10950 exception);
10951 if (attribute_flag[1] != 0)
10952 (void) QueryColorCompliance(
10953 argument_list[1].string_reference,AllCompliance,&black_point,
10954 exception);
10955 if (attribute_flag[2] != 0)
10956 (void) QueryColorCompliance(
10957 argument_list[2].string_reference,AllCompliance,&white_point,
10958 exception);
10959 if (attribute_flag[3] != 0)
10960 channel=(ChannelType) argument_list[3].integer_reference;
10961 channel_mask=SetImageChannelMask(image,channel);
10962 (void) LevelImageColors(image,&black_point,&white_point,
10963 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10964 exception);
10965 (void) SetImageChannelMask(image,channel_mask);
10966 break;
10967 }
10968 case 130: /* Clamp */
10969 {
10970 if (attribute_flag[0] != 0)
10971 channel=(ChannelType) argument_list[0].integer_reference;
10972 channel_mask=SetImageChannelMask(image,channel);
10973 (void) ClampImage(image,exception);
10974 (void) SetImageChannelMask(image,channel_mask);
10975 break;
10976 }
10977 case 131: /* BrightnessContrast */
10978 {
10979 double
10980 brightness,
10981 contrast;
10982
10983 brightness=0.0;
10984 contrast=0.0;
10985 if (attribute_flag[0] != 0)
10986 {
10987 flags=ParseGeometry(argument_list[0].string_reference,
10988 &geometry_info);
10989 brightness=geometry_info.rho;
10990 if ((flags & SigmaValue) == 0)
10991 contrast=geometry_info.sigma;
10992 }
10993 if (attribute_flag[1] != 0)
10994 brightness=argument_list[1].real_reference;
10995 if (attribute_flag[2] != 0)
10996 contrast=argument_list[2].real_reference;
10997 if (attribute_flag[4] != 0)
10998 channel=(ChannelType) argument_list[4].integer_reference;
10999 channel_mask=SetImageChannelMask(image,channel);
11000 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11001 (void) SetImageChannelMask(image,channel_mask);
11002 break;
11003 }
11004 case 132: /* Morphology */
11005 {
11006 KernelInfo
11007 *kernel;
11008
11009 MorphologyMethod
11010 method;
11011
11012 ssize_t
11013 iterations;
11014
11015 if (attribute_flag[0] == 0)
11016 break;
cristy2c57b742014-10-31 00:40:34 +000011017 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011018 if (kernel == (KernelInfo *) NULL)
11019 break;
11020 if (attribute_flag[1] != 0)
11021 channel=(ChannelType) argument_list[1].integer_reference;
11022 method=UndefinedMorphology;
11023 if (attribute_flag[2] != 0)
11024 method=argument_list[2].integer_reference;
11025 iterations=1;
11026 if (attribute_flag[3] != 0)
11027 iterations=argument_list[3].integer_reference;
11028 channel_mask=SetImageChannelMask(image,channel);
11029 image=MorphologyImage(image,method,iterations,kernel,exception);
11030 if (image != (Image *) NULL)
11031 (void) SetImageChannelMask(image,channel_mask);
11032 kernel=DestroyKernelInfo(kernel);
11033 break;
11034 }
11035 case 133: /* Mode */
11036 {
11037 if (attribute_flag[0] != 0)
11038 {
11039 flags=ParseGeometry(argument_list[0].string_reference,
11040 &geometry_info);
11041 if ((flags & SigmaValue) == 0)
11042 geometry_info.sigma=1.0;
11043 }
11044 if (attribute_flag[1] != 0)
11045 geometry_info.rho=argument_list[1].real_reference;
11046 if (attribute_flag[2] != 0)
11047 geometry_info.sigma=argument_list[2].real_reference;
11048 if (attribute_flag[3] != 0)
11049 channel=(ChannelType) argument_list[3].integer_reference;
11050 channel_mask=SetImageChannelMask(image,channel);
11051 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11052 (size_t) geometry_info.sigma,exception);
11053 if (image != (Image *) NULL)
11054 (void) SetImageChannelMask(image,channel_mask);
11055 break;
11056 }
11057 case 134: /* Statistic */
11058 {
11059 StatisticType
11060 statistic;
11061
11062 statistic=UndefinedStatistic;
11063 if (attribute_flag[0] != 0)
11064 {
11065 flags=ParseGeometry(argument_list[0].string_reference,
11066 &geometry_info);
11067 if ((flags & SigmaValue) == 0)
11068 geometry_info.sigma=1.0;
11069 }
11070 if (attribute_flag[1] != 0)
11071 geometry_info.rho=argument_list[1].real_reference;
11072 if (attribute_flag[2] != 0)
11073 geometry_info.sigma=argument_list[2].real_reference;
11074 if (attribute_flag[3] != 0)
11075 channel=(ChannelType) argument_list[3].integer_reference;
11076 if (attribute_flag[4] != 0)
11077 statistic=(StatisticType) argument_list[4].integer_reference;
11078 channel_mask=SetImageChannelMask(image,channel);
11079 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11080 (size_t) geometry_info.sigma,exception);
11081 if (image != (Image *) NULL)
11082 (void) SetImageChannelMask(image,channel_mask);
11083 break;
11084 }
11085 case 135: /* Perceptible */
11086 {
11087 double
11088 epsilon;
11089
11090 epsilon=MagickEpsilon;
11091 if (attribute_flag[0] != 0)
11092 epsilon=argument_list[0].real_reference;
11093 if (attribute_flag[1] != 0)
11094 channel=(ChannelType) argument_list[1].integer_reference;
11095 channel_mask=SetImageChannelMask(image,channel);
11096 (void) PerceptibleImage(image,epsilon,exception);
11097 (void) SetImageChannelMask(image,channel_mask);
11098 break;
11099 }
11100 case 136: /* Poly */
11101 {
11102 AV
11103 *av;
11104
11105 double
11106 *terms;
11107
11108 size_t
11109 number_terms;
11110
11111 if (attribute_flag[0] == 0)
11112 break;
11113 if (attribute_flag[1] != 0)
11114 channel=(ChannelType) argument_list[1].integer_reference;
11115 av=(AV *) argument_list[0].array_reference;
11116 number_terms=(size_t) av_len(av);
11117 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11118 if (terms == (double *) NULL)
11119 {
11120 ThrowPerlException(exception,ResourceLimitFatalError,
11121 "MemoryAllocationFailed",PackageName);
11122 goto PerlException;
11123 }
11124 for (j=0; j < av_len(av); j++)
11125 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11126 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11127 terms=(double *) RelinquishMagickMemory(terms);
11128 break;
11129 }
11130 case 137: /* Grayscale */
11131 {
11132 PixelIntensityMethod
11133 method;
11134
11135 method=UndefinedPixelIntensityMethod;
11136 if (attribute_flag[0] != 0)
11137 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11138 (void) GrayscaleImage(image,method,exception);
11139 break;
11140 }
cristy4ceadb82014-03-29 15:30:43 +000011141 case 138: /* Canny */
11142 {
11143 if (attribute_flag[0] != 0)
11144 {
11145 flags=ParseGeometry(argument_list[0].string_reference,
11146 &geometry_info);
11147 if ((flags & SigmaValue) == 0)
11148 geometry_info.sigma=1.0;
11149 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011150 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011151 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011152 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011153 if ((flags & PercentValue) != 0)
11154 {
11155 geometry_info.xi/=100.0;
11156 geometry_info.psi/=100.0;
11157 }
cristy4ceadb82014-03-29 15:30:43 +000011158 }
11159 if (attribute_flag[1] != 0)
11160 geometry_info.rho=argument_list[1].real_reference;
11161 if (attribute_flag[2] != 0)
11162 geometry_info.sigma=argument_list[2].real_reference;
11163 if (attribute_flag[3] != 0)
11164 geometry_info.xi=argument_list[3].real_reference;
11165 if (attribute_flag[4] != 0)
11166 geometry_info.psi=argument_list[4].real_reference;
11167 if (attribute_flag[5] != 0)
11168 channel=(ChannelType) argument_list[5].integer_reference;
11169 channel_mask=SetImageChannelMask(image,channel);
11170 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11171 geometry_info.xi,geometry_info.psi,exception);
11172 if (image != (Image *) NULL)
11173 (void) SetImageChannelMask(image,channel_mask);
11174 break;
11175 }
cristy2fc10e52014-04-26 14:13:53 +000011176 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011177 {
11178 if (attribute_flag[0] != 0)
11179 {
11180 flags=ParseGeometry(argument_list[0].string_reference,
11181 &geometry_info);
11182 if ((flags & SigmaValue) == 0)
11183 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011184 if ((flags & XiValue) == 0)
11185 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011186 }
11187 if (attribute_flag[1] != 0)
11188 geometry_info.rho=(double) argument_list[1].integer_reference;
11189 if (attribute_flag[2] != 0)
11190 geometry_info.sigma=(double) argument_list[2].integer_reference;
11191 if (attribute_flag[3] != 0)
11192 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011193 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11194 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11195 break;
11196 }
11197 case 140: /* MeanShift */
11198 {
11199 if (attribute_flag[0] != 0)
11200 {
11201 flags=ParseGeometry(argument_list[0].string_reference,
11202 &geometry_info);
11203 if ((flags & SigmaValue) == 0)
11204 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011205 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011206 geometry_info.xi=0.10*QuantumRange;
11207 if ((flags & PercentValue) != 0)
11208 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011209 }
11210 if (attribute_flag[1] != 0)
11211 geometry_info.rho=(double) argument_list[1].integer_reference;
11212 if (attribute_flag[2] != 0)
11213 geometry_info.sigma=(double) argument_list[2].integer_reference;
11214 if (attribute_flag[3] != 0)
11215 geometry_info.xi=(double) argument_list[3].integer_reference;
11216 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011217 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011218 break;
11219 }
cristy3b207f82014-09-27 14:21:20 +000011220 case 141: /* Kuwahara */
11221 {
11222 if (attribute_flag[0] != 0)
11223 {
11224 flags=ParseGeometry(argument_list[0].string_reference,
11225 &geometry_info);
11226 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011227 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011228 }
11229 if (attribute_flag[1] != 0)
11230 geometry_info.rho=argument_list[1].real_reference;
11231 if (attribute_flag[2] != 0)
11232 geometry_info.sigma=argument_list[2].real_reference;
11233 if (attribute_flag[3] != 0)
11234 channel=(ChannelType) argument_list[3].integer_reference;
11235 channel_mask=SetImageChannelMask(image,channel);
11236 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11237 exception);
11238 if (image != (Image *) NULL)
11239 (void) SetImageChannelMask(image,channel_mask);
11240 break;
11241 }
cristy6e0b3bc2014-10-19 17:51:42 +000011242 case 142: /* ConnectedComponent */
11243 {
11244 size_t
11245 connectivity;
11246
11247 connectivity=4;
11248 if (attribute_flag[0] != 0)
11249 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011250 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011251 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011252 break;
11253 }
cristy0b94b392015-06-22 18:56:37 +000011254 case 143: /* Copy */
11255 {
11256 Image
11257 *source_image;
11258
11259 OffsetInfo
11260 offset;
11261
cristy2ffdb092015-06-25 14:31:20 +000011262 RectangleInfo
11263 offset_geometry;
11264
cristyf3a724a2015-06-25 13:02:53 +000011265 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011266 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011267 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011268 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011269 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011270 flags=ParseGravityGeometry(source_image,
11271 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011272 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011273 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011274 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011275 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011276 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011277 geometry.x=argument_list[4].integer_reference;
11278 if (attribute_flag[5] != 0)
11279 geometry.y=argument_list[5].integer_reference;
11280 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011281 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011282 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011283 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011284 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11285 &offset_geometry,exception);
11286 offset.x=offset_geometry.x;
11287 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011288 if (attribute_flag[8] != 0)
11289 offset.x=argument_list[8].integer_reference;
11290 if (attribute_flag[9] != 0)
11291 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011292 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11293 exception);
cristy0b94b392015-06-22 18:56:37 +000011294 break;
11295 }
Cristy5488c982016-02-13 14:07:50 -050011296 case 144: /* Color */
11297 {
11298 PixelInfo
11299 color;
11300
Cristyf20e3562016-02-14 09:08:15 -050011301 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011302 if (attribute_flag[0] != 0)
Cristyf20e3562016-02-14 09:08:15 -050011303 (void) QueryColorCompliance(argument_list[0].string_reference,
11304 AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011305 (void) SetImageColor(image,&color,exception);
11306 break;
11307 }
Cristy2d830ed2016-02-21 10:54:16 -050011308 case 145: /* WaveletDenoise */
11309 {
Cristyc1759412016-02-27 12:17:58 -050011310 if (attribute_flag[0] != 0)
Cristyee21f7f2016-02-27 15:56:49 -050011311 {
11312 flags=ParseGeometry(argument_list[0].string_reference,
11313 &geometry_info);
11314 if ((flags & PercentValue) != 0)
Cristy23446632016-02-29 09:36:34 -050011315 {
11316 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11317 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
11318 }
Cristyee21f7f2016-02-27 15:56:49 -050011319 if ((flags & SigmaValue) == 0)
11320 geometry_info.sigma=0.0;
11321 }
Cristyc1759412016-02-27 12:17:58 -050011322 if (attribute_flag[1] != 0)
11323 geometry_info.rho=argument_list[1].real_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011324 if (attribute_flag[2] != 0)
Cristyc1759412016-02-27 12:17:58 -050011325 geometry_info.sigma=argument_list[2].real_reference;
11326 if (attribute_flag[3] != 0)
11327 channel=(ChannelType) argument_list[3].integer_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011328 channel_mask=SetImageChannelMask(image,channel);
Cristyc1759412016-02-27 12:17:58 -050011329 image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11330 exception);
Cristy2d830ed2016-02-21 10:54:16 -050011331 if (image != (Image *) NULL)
11332 (void) SetImageChannelMask(image,channel_mask);
11333 break;
11334 }
Cristy99a57162016-12-05 11:47:57 -050011335 case 146: /* Colorspace */
11336 {
11337 ColorspaceType
11338 colorspace;
11339
11340 colorspace=sRGBColorspace;
11341 if (attribute_flag[0] != 0)
11342 colorspace=(ColorspaceType) argument_list[0].integer_reference;
11343 (void) TransformImageColorspace(image,colorspace,exception);
11344 break;
11345 }
cristy4a3ce0a2013-08-03 20:06:59 +000011346 }
11347 if (next != (Image *) NULL)
11348 (void) CatchImageException(next);
11349 if (region_image != (Image *) NULL)
11350 {
11351 /*
11352 Composite region.
cristy83a28a02013-08-03 20:25:48 +000011353 */
cristy4a3ce0a2013-08-03 20:06:59 +000011354 status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11355 region_info.x,region_info.y,exception);
11356 (void) status;
11357 (void) CatchImageException(region_image);
11358 image=DestroyImage(image);
11359 image=region_image;
11360 }
11361 if (image != (Image *) NULL)
11362 {
11363 number_images++;
11364 if (next && (next != image))
11365 {
11366 image->next=next->next;
11367 if (image->next != (Image *) NULL)
11368 image->next->previous=image;
11369 DeleteImageFromRegistry(*pv,next);
11370 }
11371 sv_setiv(*pv,PTR2IV(image));
11372 next=image;
11373 }
11374 if (*pv)
11375 pv++;
11376 }
11377
11378 PerlException:
11379 if (reference_vector)
11380 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11381 InheritPerlException(exception,perl_exception);
11382 exception=DestroyExceptionInfo(exception);
11383 sv_setiv(perl_exception,(IV) number_images);
11384 SvPOK_on(perl_exception);
11385 ST(0)=sv_2mortal(perl_exception);
11386 XSRETURN(1);
11387 }
11388
11389#
11390###############################################################################
11391# #
11392# #
11393# #
11394# M o n t a g e #
11395# #
11396# #
11397# #
11398###############################################################################
11399#
11400#
11401void
11402Montage(ref,...)
11403 Image::Magick ref=NO_INIT
11404 ALIAS:
11405 MontageImage = 1
11406 montage = 2
11407 montageimage = 3
11408 PPCODE:
11409 {
11410 AV
11411 *av;
11412
11413 char
11414 *attribute;
11415
11416 ExceptionInfo
11417 *exception;
11418
11419 HV
11420 *hv;
11421
11422 Image
11423 *image,
11424 *next;
11425
11426 PixelInfo
11427 transparent_color;
11428
11429 MontageInfo
11430 *montage_info;
11431
11432 register ssize_t
11433 i;
11434
11435 ssize_t
11436 sp;
11437
11438 struct PackageInfo
11439 *info;
11440
11441 SV
11442 *av_reference,
11443 *perl_exception,
11444 *reference,
11445 *rv,
11446 *sv;
11447
11448 PERL_UNUSED_VAR(ref);
11449 PERL_UNUSED_VAR(ix);
11450 exception=AcquireExceptionInfo();
11451 perl_exception=newSVpv("",0);
11452 sv=NULL;
11453 attribute=NULL;
11454 if (sv_isobject(ST(0)) == 0)
11455 {
11456 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11457 PackageName);
11458 goto PerlException;
11459 }
11460 reference=SvRV(ST(0));
11461 hv=SvSTASH(reference);
11462 av=newAV();
11463 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11464 SvREFCNT_dec(av);
11465 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11466 if (image == (Image *) NULL)
11467 {
11468 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11469 PackageName);
11470 goto PerlException;
11471 }
11472 /*
11473 Get options.
11474 */
11475 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11476 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11477 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11478 exception);
11479 for (i=2; i < items; i+=2)
11480 {
11481 attribute=(char *) SvPV(ST(i-1),na);
11482 switch (*attribute)
11483 {
11484 case 'B':
11485 case 'b':
11486 {
11487 if (LocaleCompare(attribute,"background") == 0)
11488 {
11489 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11490 &montage_info->background_color,exception);
11491 for (next=image; next; next=next->next)
11492 next->background_color=montage_info->background_color;
11493 break;
11494 }
11495 if (LocaleCompare(attribute,"border") == 0)
11496 {
11497 montage_info->border_width=SvIV(ST(i));
11498 break;
11499 }
11500 if (LocaleCompare(attribute,"bordercolor") == 0)
11501 {
11502 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11503 &montage_info->border_color,exception);
11504 for (next=image; next; next=next->next)
11505 next->border_color=montage_info->border_color;
11506 break;
11507 }
11508 if (LocaleCompare(attribute,"borderwidth") == 0)
11509 {
11510 montage_info->border_width=SvIV(ST(i));
11511 break;
11512 }
11513 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11514 attribute);
11515 break;
11516 }
11517 case 'C':
11518 case 'c':
11519 {
11520 if (LocaleCompare(attribute,"compose") == 0)
11521 {
11522 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11523 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11524 if (sp < 0)
11525 {
11526 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11527 SvPV(ST(i),na));
11528 break;
11529 }
11530 for (next=image; next; next=next->next)
11531 next->compose=(CompositeOperator) sp;
11532 break;
11533 }
11534 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11535 attribute);
11536 break;
11537 }
11538 case 'F':
11539 case 'f':
11540 {
11541 if (LocaleCompare(attribute,"fill") == 0)
11542 {
11543 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11544 &montage_info->fill,exception);
11545 break;
11546 }
11547 if (LocaleCompare(attribute,"font") == 0)
11548 {
11549 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11550 break;
11551 }
11552 if (LocaleCompare(attribute,"frame") == 0)
11553 {
11554 char
11555 *p;
11556
11557 p=SvPV(ST(i),na);
11558 if (IsGeometry(p) == MagickFalse)
11559 {
11560 ThrowPerlException(exception,OptionError,"MissingGeometry",
11561 p);
11562 break;
11563 }
11564 (void) CloneString(&montage_info->frame,p);
11565 if (*p == '\0')
11566 montage_info->frame=(char *) NULL;
11567 break;
11568 }
11569 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11570 attribute);
11571 break;
11572 }
11573 case 'G':
11574 case 'g':
11575 {
11576 if (LocaleCompare(attribute,"geometry") == 0)
11577 {
11578 char
11579 *p;
11580
11581 p=SvPV(ST(i),na);
11582 if (IsGeometry(p) == MagickFalse)
11583 {
11584 ThrowPerlException(exception,OptionError,"MissingGeometry",
11585 p);
11586 break;
11587 }
11588 (void) CloneString(&montage_info->geometry,p);
11589 if (*p == '\0')
11590 montage_info->geometry=(char *) NULL;
11591 break;
11592 }
11593 if (LocaleCompare(attribute,"gravity") == 0)
11594 {
11595 ssize_t
11596 in;
11597
11598 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11599 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11600 if (in < 0)
11601 {
11602 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11603 SvPV(ST(i),na));
11604 return;
11605 }
11606 montage_info->gravity=(GravityType) in;
11607 for (next=image; next; next=next->next)
11608 next->gravity=(GravityType) in;
11609 break;
11610 }
11611 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11612 attribute);
11613 break;
11614 }
11615 case 'L':
11616 case 'l':
11617 {
11618 if (LocaleCompare(attribute,"label") == 0)
11619 {
11620 for (next=image; next; next=next->next)
11621 (void) SetImageProperty(next,"label",InterpretImageProperties(
11622 info ? info->image_info : (ImageInfo *) NULL,next,
11623 SvPV(ST(i),na),exception),exception);
11624 break;
11625 }
11626 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11627 attribute);
11628 break;
11629 }
11630 case 'M':
11631 case 'm':
11632 {
11633 if (LocaleCompare(attribute,"mattecolor") == 0)
11634 {
11635 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
Cristy8645e042016-02-03 16:35:29 -050011636 &montage_info->alpha_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011637 for (next=image; next; next=next->next)
Cristy8645e042016-02-03 16:35:29 -050011638 next->alpha_color=montage_info->alpha_color;
cristy4a3ce0a2013-08-03 20:06:59 +000011639 break;
11640 }
11641 if (LocaleCompare(attribute,"mode") == 0)
11642 {
11643 ssize_t
11644 in;
11645
11646 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11647 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11648 switch (in)
11649 {
11650 default:
11651 {
11652 ThrowPerlException(exception,OptionError,
11653 "UnrecognizedModeType",SvPV(ST(i),na));
11654 break;
11655 }
11656 case FrameMode:
11657 {
11658 (void) CloneString(&montage_info->frame,"15x15+3+3");
11659 montage_info->shadow=MagickTrue;
11660 break;
11661 }
11662 case UnframeMode:
11663 {
11664 montage_info->frame=(char *) NULL;
11665 montage_info->shadow=MagickFalse;
11666 montage_info->border_width=0;
11667 break;
11668 }
11669 case ConcatenateMode:
11670 {
11671 montage_info->frame=(char *) NULL;
11672 montage_info->shadow=MagickFalse;
11673 (void) CloneString(&montage_info->geometry,"+0+0");
11674 montage_info->border_width=0;
11675 }
11676 }
11677 break;
11678 }
11679 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11680 attribute);
11681 break;
11682 }
11683 case 'P':
11684 case 'p':
11685 {
11686 if (LocaleCompare(attribute,"pointsize") == 0)
11687 {
11688 montage_info->pointsize=SvIV(ST(i));
11689 break;
11690 }
11691 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11692 attribute);
11693 break;
11694 }
11695 case 'S':
11696 case 's':
11697 {
11698 if (LocaleCompare(attribute,"shadow") == 0)
11699 {
11700 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11701 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11702 if (sp < 0)
11703 {
11704 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11705 SvPV(ST(i),na));
11706 break;
11707 }
11708 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11709 break;
11710 }
11711 if (LocaleCompare(attribute,"stroke") == 0)
11712 {
11713 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11714 &montage_info->stroke,exception);
11715 break;
11716 }
11717 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11718 attribute);
11719 break;
11720 }
11721 case 'T':
11722 case 't':
11723 {
11724 if (LocaleCompare(attribute,"texture") == 0)
11725 {
11726 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11727 break;
11728 }
11729 if (LocaleCompare(attribute,"tile") == 0)
11730 {
11731 char *p=SvPV(ST(i),na);
11732 if (IsGeometry(p) == MagickFalse)
11733 {
11734 ThrowPerlException(exception,OptionError,"MissingGeometry",
11735 p);
11736 break;
11737 }
11738 (void) CloneString(&montage_info->tile,p);
11739 if (*p == '\0')
11740 montage_info->tile=(char *) NULL;
11741 break;
11742 }
11743 if (LocaleCompare(attribute,"title") == 0)
11744 {
11745 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11746 break;
11747 }
11748 if (LocaleCompare(attribute,"transparent") == 0)
11749 {
11750 PixelInfo
11751 transparent_color;
11752
11753 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11754 &transparent_color,exception);
11755 for (next=image; next; next=next->next)
11756 (void) TransparentPaintImage(next,&transparent_color,
11757 TransparentAlpha,MagickFalse,exception);
11758 break;
11759 }
11760 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11761 attribute);
11762 break;
11763 }
11764 default:
11765 {
11766 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11767 attribute);
11768 break;
11769 }
11770 }
11771 }
11772 image=MontageImageList(info->image_info,montage_info,image,exception);
11773 montage_info=DestroyMontageInfo(montage_info);
11774 if (image == (Image *) NULL)
11775 goto PerlException;
11776 if (transparent_color.alpha != TransparentAlpha)
11777 for (next=image; next; next=next->next)
11778 (void) TransparentPaintImage(next,&transparent_color,
11779 TransparentAlpha,MagickFalse,exception);
11780 for ( ; image; image=image->next)
11781 {
11782 AddImageToRegistry(sv,image);
11783 rv=newRV(sv);
11784 av_push(av,sv_bless(rv,hv));
11785 SvREFCNT_dec(sv);
11786 }
11787 exception=DestroyExceptionInfo(exception);
11788 ST(0)=av_reference;
11789 SvREFCNT_dec(perl_exception);
11790 XSRETURN(1);
11791
11792 PerlException:
11793 InheritPerlException(exception,perl_exception);
11794 exception=DestroyExceptionInfo(exception);
11795 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11796 SvPOK_on(perl_exception);
11797 ST(0)=sv_2mortal(perl_exception);
11798 XSRETURN(1);
11799 }
11800
11801#
11802###############################################################################
11803# #
11804# #
11805# #
11806# M o r p h #
11807# #
11808# #
11809# #
11810###############################################################################
11811#
11812#
11813void
11814Morph(ref,...)
11815 Image::Magick ref=NO_INIT
11816 ALIAS:
11817 MorphImage = 1
11818 morph = 2
11819 morphimage = 3
11820 PPCODE:
11821 {
11822 AV
11823 *av;
11824
11825 char
11826 *attribute;
11827
11828 ExceptionInfo
11829 *exception;
11830
11831 HV
11832 *hv;
11833
11834 Image
11835 *image;
11836
11837 register ssize_t
11838 i;
11839
11840 ssize_t
11841 number_frames;
11842
11843 struct PackageInfo
11844 *info;
11845
11846 SV
11847 *av_reference,
11848 *perl_exception,
11849 *reference,
11850 *rv,
11851 *sv;
11852
11853 PERL_UNUSED_VAR(ref);
11854 PERL_UNUSED_VAR(ix);
11855 exception=AcquireExceptionInfo();
11856 perl_exception=newSVpv("",0);
11857 sv=NULL;
11858 av=NULL;
11859 attribute=NULL;
11860 if (sv_isobject(ST(0)) == 0)
11861 {
11862 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11863 PackageName);
11864 goto PerlException;
11865 }
11866 reference=SvRV(ST(0));
11867 hv=SvSTASH(reference);
11868 av=newAV();
11869 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11870 SvREFCNT_dec(av);
11871 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11872 if (image == (Image *) NULL)
11873 {
11874 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11875 PackageName);
11876 goto PerlException;
11877 }
11878 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11879 /*
11880 Get attribute.
11881 */
11882 number_frames=30;
11883 for (i=2; i < items; i+=2)
11884 {
11885 attribute=(char *) SvPV(ST(i-1),na);
11886 switch (*attribute)
11887 {
11888 case 'F':
11889 case 'f':
11890 {
11891 if (LocaleCompare(attribute,"frames") == 0)
11892 {
11893 number_frames=SvIV(ST(i));
11894 break;
11895 }
11896 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11897 attribute);
11898 break;
11899 }
11900 default:
11901 {
11902 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11903 attribute);
11904 break;
11905 }
11906 }
11907 }
11908 image=MorphImages(image,number_frames,exception);
11909 if (image == (Image *) NULL)
11910 goto PerlException;
11911 for ( ; image; image=image->next)
11912 {
11913 AddImageToRegistry(sv,image);
11914 rv=newRV(sv);
11915 av_push(av,sv_bless(rv,hv));
11916 SvREFCNT_dec(sv);
11917 }
11918 exception=DestroyExceptionInfo(exception);
11919 ST(0)=av_reference;
11920 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11921 XSRETURN(1);
11922
11923 PerlException:
11924 InheritPerlException(exception,perl_exception);
11925 exception=DestroyExceptionInfo(exception);
11926 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11927 SvPOK_on(perl_exception);
11928 ST(0)=sv_2mortal(perl_exception);
11929 XSRETURN(1);
11930 }
11931
11932#
11933###############################################################################
11934# #
11935# #
11936# #
11937# M o s a i c #
11938# #
11939# #
11940# #
11941###############################################################################
11942#
11943#
11944void
11945Mosaic(ref)
11946 Image::Magick ref=NO_INIT
11947 ALIAS:
11948 MosaicImage = 1
11949 mosaic = 2
11950 mosaicimage = 3
11951 PPCODE:
11952 {
11953 AV
11954 *av;
11955
11956 ExceptionInfo
11957 *exception;
11958
11959 HV
11960 *hv;
11961
11962 Image
11963 *image;
11964
11965 struct PackageInfo
11966 *info;
11967
11968 SV
11969 *perl_exception,
11970 *reference,
11971 *rv,
11972 *sv;
11973
11974 PERL_UNUSED_VAR(ref);
11975 PERL_UNUSED_VAR(ix);
11976 exception=AcquireExceptionInfo();
11977 perl_exception=newSVpv("",0);
11978 sv=NULL;
11979 if (sv_isobject(ST(0)) == 0)
11980 {
11981 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11982 PackageName);
11983 goto PerlException;
11984 }
11985 reference=SvRV(ST(0));
11986 hv=SvSTASH(reference);
11987 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11988 if (image == (Image *) NULL)
11989 {
11990 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11991 PackageName);
11992 goto PerlException;
11993 }
11994 image=MergeImageLayers(image,MosaicLayer,exception);
11995 /*
11996 Create blessed Perl array for the returned image.
11997 */
11998 av=newAV();
11999 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12000 SvREFCNT_dec(av);
12001 AddImageToRegistry(sv,image);
12002 rv=newRV(sv);
12003 av_push(av,sv_bless(rv,hv));
12004 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000012005 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000012006 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012007 SetImageInfo(info->image_info,0,exception);
12008 exception=DestroyExceptionInfo(exception);
12009 SvREFCNT_dec(perl_exception);
12010 XSRETURN(1);
12011
12012 PerlException:
12013 InheritPerlException(exception,perl_exception);
12014 exception=DestroyExceptionInfo(exception);
12015 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12016 SvPOK_on(perl_exception); /* return messages in string context */
12017 ST(0)=sv_2mortal(perl_exception);
12018 XSRETURN(1);
12019 }
12020
12021#
12022###############################################################################
12023# #
12024# #
12025# #
12026# P i n g #
12027# #
12028# #
12029# #
12030###############################################################################
12031#
12032#
12033void
12034Ping(ref,...)
12035 Image::Magick ref=NO_INIT
12036 ALIAS:
12037 PingImage = 1
12038 ping = 2
12039 pingimage = 3
12040 PPCODE:
12041 {
12042 AV
12043 *av;
12044
12045 char
12046 **keep,
12047 **list;
12048
12049 ExceptionInfo
12050 *exception;
12051
12052 Image
12053 *image,
12054 *next;
12055
12056 int
12057 n;
12058
12059 MagickBooleanType
12060 status;
12061
12062 register char
12063 **p;
12064
12065 register ssize_t
12066 i;
12067
12068 ssize_t
12069 ac;
12070
12071 STRLEN
12072 *length;
12073
12074 struct PackageInfo
12075 *info,
12076 *package_info;
12077
12078 SV
12079 *perl_exception,
12080 *reference;
12081
12082 size_t
12083 count;
12084
12085 PERL_UNUSED_VAR(ref);
12086 PERL_UNUSED_VAR(ix);
12087 exception=AcquireExceptionInfo();
12088 perl_exception=newSVpv("",0);
12089 package_info=(struct PackageInfo *) NULL;
12090 ac=(items < 2) ? 1 : items-1;
12091 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12092 keep=list;
12093 length=(STRLEN *) NULL;
12094 if (list == (char **) NULL)
12095 {
12096 ThrowPerlException(exception,ResourceLimitError,
12097 "MemoryAllocationFailed",PackageName);
12098 goto PerlException;
12099 }
12100 keep=list;
12101 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12102 if (length == (STRLEN *) NULL)
12103 {
12104 ThrowPerlException(exception,ResourceLimitError,
12105 "MemoryAllocationFailed",PackageName);
12106 goto PerlException;
12107 }
12108 if (sv_isobject(ST(0)) == 0)
12109 {
12110 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12111 PackageName);
12112 goto PerlException;
12113 }
12114 reference=SvRV(ST(0));
12115 if (SvTYPE(reference) != SVt_PVAV)
12116 {
12117 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12118 PackageName);
12119 goto PerlException;
12120 }
12121 av=(AV *) reference;
12122 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12123 exception);
12124 package_info=ClonePackageInfo(info,exception);
12125 n=1;
12126 if (items <= 1)
12127 *list=(char *) (*package_info->image_info->filename ?
12128 package_info->image_info->filename : "XC:black");
12129 else
12130 for (n=0, i=0; i < ac; i++)
12131 {
12132 list[n]=(char *) SvPV(ST(i+1),length[n]);
12133 if ((items >= 3) && strEQcase(list[n],"blob"))
12134 {
12135 void
12136 *blob;
12137
12138 i++;
12139 blob=(void *) (SvPV(ST(i+1),length[n]));
12140 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12141 }
12142 if ((items >= 3) && strEQcase(list[n],"filename"))
12143 continue;
12144 if ((items >= 3) && strEQcase(list[n],"file"))
12145 {
12146 FILE
12147 *file;
12148
12149 PerlIO
12150 *io_info;
12151
12152 i++;
12153 io_info=IoIFP(sv_2io(ST(i+1)));
12154 if (io_info == (PerlIO *) NULL)
12155 {
12156 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12157 PackageName);
12158 continue;
12159 }
12160 file=PerlIO_findFILE(io_info);
12161 if (file == (FILE *) NULL)
12162 {
12163 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12164 PackageName);
12165 continue;
12166 }
12167 SetImageInfoFile(package_info->image_info,file);
12168 }
12169 if ((items >= 3) && strEQcase(list[n],"magick"))
12170 continue;
12171 n++;
12172 }
12173 list[n]=(char *) NULL;
12174 keep=list;
12175 status=ExpandFilenames(&n,&list);
12176 if (status == MagickFalse)
12177 {
12178 ThrowPerlException(exception,ResourceLimitError,
12179 "MemoryAllocationFailed",PackageName);
12180 goto PerlException;
12181 }
12182 count=0;
12183 for (i=0; i < n; i++)
12184 {
12185 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012186 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012187 image=PingImage(package_info->image_info,exception);
12188 if (image == (Image *) NULL)
12189 break;
12190 if ((package_info->image_info->file != (FILE *) NULL) ||
12191 (package_info->image_info->blob != (void *) NULL))
12192 DisassociateImageStream(image);
12193 count+=GetImageListLength(image);
12194 EXTEND(sp,4*count);
12195 for (next=image; next; next=next->next)
12196 {
12197 PUSHs(sv_2mortal(newSViv(next->columns)));
12198 PUSHs(sv_2mortal(newSViv(next->rows)));
12199 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12200 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12201 }
12202 image=DestroyImageList(image);
12203 }
12204 /*
12205 Free resources.
12206 */
12207 for (i=0; i < n; i++)
12208 if (list[i] != (char *) NULL)
12209 for (p=keep; list[i] != *p++; )
12210 if (*p == NULL)
12211 {
12212 list[i]=(char *) RelinquishMagickMemory(list[i]);
12213 break;
12214 }
12215
12216 PerlException:
12217 if (package_info != (struct PackageInfo *) NULL)
12218 DestroyPackageInfo(package_info);
12219 if (list && (list != keep))
12220 list=(char **) RelinquishMagickMemory(list);
12221 if (keep)
12222 keep=(char **) RelinquishMagickMemory(keep);
12223 if (length)
12224 length=(STRLEN *) RelinquishMagickMemory(length);
12225 InheritPerlException(exception,perl_exception);
12226 exception=DestroyExceptionInfo(exception);
12227 SvREFCNT_dec(perl_exception); /* throw away all errors */
12228 }
12229
12230#
12231###############################################################################
12232# #
12233# #
12234# #
12235# P r e v i e w #
12236# #
12237# #
12238# #
12239###############################################################################
12240#
12241#
12242void
12243Preview(ref,...)
12244 Image::Magick ref=NO_INIT
12245 ALIAS:
12246 PreviewImage = 1
12247 preview = 2
12248 previewimage = 3
12249 PPCODE:
12250 {
12251 AV
12252 *av;
12253
12254 ExceptionInfo
12255 *exception;
12256
12257 HV
12258 *hv;
12259
12260 Image
12261 *image,
12262 *preview_image;
12263
12264 PreviewType
12265 preview_type;
12266
12267 struct PackageInfo
12268 *info;
12269
12270 SV
12271 *av_reference,
12272 *perl_exception,
12273 *reference,
12274 *rv,
12275 *sv;
12276
12277 PERL_UNUSED_VAR(ref);
12278 PERL_UNUSED_VAR(ix);
12279 exception=AcquireExceptionInfo();
12280 perl_exception=newSVpv("",0);
12281 sv=NULL;
12282 av=NULL;
12283 if (sv_isobject(ST(0)) == 0)
12284 {
12285 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12286 PackageName);
12287 goto PerlException;
12288 }
12289 reference=SvRV(ST(0));
12290 hv=SvSTASH(reference);
12291 av=newAV();
12292 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12293 SvREFCNT_dec(av);
12294 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12295 if (image == (Image *) NULL)
12296 {
12297 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12298 PackageName);
12299 goto PerlException;
12300 }
12301 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12302 preview_type=GammaPreview;
12303 if (items > 1)
12304 preview_type=(PreviewType)
12305 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12306 for ( ; image; image=image->next)
12307 {
12308 preview_image=PreviewImage(image,preview_type,exception);
12309 if (preview_image == (Image *) NULL)
12310 goto PerlException;
12311 AddImageToRegistry(sv,preview_image);
12312 rv=newRV(sv);
12313 av_push(av,sv_bless(rv,hv));
12314 SvREFCNT_dec(sv);
12315 }
12316 exception=DestroyExceptionInfo(exception);
12317 ST(0)=av_reference;
12318 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12319 XSRETURN(1);
12320
12321 PerlException:
12322 InheritPerlException(exception,perl_exception);
12323 exception=DestroyExceptionInfo(exception);
12324 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12325 SvPOK_on(perl_exception);
12326 ST(0)=sv_2mortal(perl_exception);
12327 XSRETURN(1);
12328 }
12329
12330#
12331###############################################################################
12332# #
12333# #
12334# #
12335# Q u e r y C o l o r #
12336# #
12337# #
12338# #
12339###############################################################################
12340#
12341#
12342void
12343QueryColor(ref,...)
12344 Image::Magick ref=NO_INIT
12345 ALIAS:
12346 querycolor = 1
12347 PPCODE:
12348 {
12349 char
12350 *name;
12351
12352 ExceptionInfo
12353 *exception;
12354
12355 PixelInfo
12356 color;
12357
12358 register ssize_t
12359 i;
12360
12361 SV
12362 *perl_exception;
12363
12364 PERL_UNUSED_VAR(ref);
12365 PERL_UNUSED_VAR(ix);
12366 exception=AcquireExceptionInfo();
12367 perl_exception=newSVpv("",0);
12368 if (items == 1)
12369 {
12370 const ColorInfo
12371 **colorlist;
12372
12373 size_t
12374 colors;
12375
12376 colorlist=GetColorInfoList("*",&colors,exception);
12377 EXTEND(sp,colors);
12378 for (i=0; i < (ssize_t) colors; i++)
12379 {
12380 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12381 }
12382 colorlist=(const ColorInfo **)
12383 RelinquishMagickMemory((ColorInfo **) colorlist);
12384 goto PerlException;
12385 }
12386 EXTEND(sp,5*items);
12387 for (i=1; i < items; i++)
12388 {
12389 name=(char *) SvPV(ST(i),na);
12390 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12391 {
12392 PUSHs(&sv_undef);
12393 continue;
12394 }
12395 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12396 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12397 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12398 if (color.colorspace == CMYKColorspace)
12399 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012400 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012401 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12402 }
12403
12404 PerlException:
12405 InheritPerlException(exception,perl_exception);
12406 exception=DestroyExceptionInfo(exception);
12407 SvREFCNT_dec(perl_exception);
12408 }
12409
12410#
12411###############################################################################
12412# #
12413# #
12414# #
12415# Q u e r y C o l o r N a m e #
12416# #
12417# #
12418# #
12419###############################################################################
12420#
12421#
12422void
12423QueryColorname(ref,...)
12424 Image::Magick ref=NO_INIT
12425 ALIAS:
12426 querycolorname = 1
12427 PPCODE:
12428 {
12429 AV
12430 *av;
12431
12432 char
cristy151b66d2015-04-15 10:50:31 +000012433 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012434
12435 ExceptionInfo
12436 *exception;
12437
12438 Image
12439 *image;
12440
12441 PixelInfo
12442 target_color;
12443
12444 register ssize_t
12445 i;
12446
12447 struct PackageInfo
12448 *info;
12449
12450 SV
12451 *perl_exception,
12452 *reference; /* reference is the SV* of ref=SvIV(reference) */
12453
12454 PERL_UNUSED_VAR(ref);
12455 PERL_UNUSED_VAR(ix);
12456 exception=AcquireExceptionInfo();
12457 perl_exception=newSVpv("",0);
12458 reference=SvRV(ST(0));
12459 av=(AV *) reference;
12460 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12461 exception);
12462 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12463 if (image == (Image *) NULL)
12464 {
12465 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12466 PackageName);
12467 goto PerlException;
12468 }
12469 EXTEND(sp,items);
12470 for (i=1; i < items; i++)
12471 {
12472 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12473 exception);
12474 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12475 exception);
12476 PUSHs(sv_2mortal(newSVpv(message,0)));
12477 }
12478
12479 PerlException:
12480 InheritPerlException(exception,perl_exception);
12481 exception=DestroyExceptionInfo(exception);
12482 SvREFCNT_dec(perl_exception);
12483 }
12484
12485#
12486###############################################################################
12487# #
12488# #
12489# #
12490# Q u e r y F o n t #
12491# #
12492# #
12493# #
12494###############################################################################
12495#
12496#
12497void
12498QueryFont(ref,...)
12499 Image::Magick ref=NO_INIT
12500 ALIAS:
12501 queryfont = 1
12502 PPCODE:
12503 {
12504 char
12505 *name,
cristy151b66d2015-04-15 10:50:31 +000012506 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012507
12508 ExceptionInfo
12509 *exception;
12510
12511 register ssize_t
12512 i;
12513
12514 SV
12515 *perl_exception;
12516
12517 volatile const TypeInfo
12518 *type_info;
12519
12520 PERL_UNUSED_VAR(ref);
12521 PERL_UNUSED_VAR(ix);
12522 exception=AcquireExceptionInfo();
12523 perl_exception=newSVpv("",0);
12524 if (items == 1)
12525 {
12526 const TypeInfo
12527 **typelist;
12528
12529 size_t
12530 types;
12531
12532 typelist=GetTypeInfoList("*",&types,exception);
12533 EXTEND(sp,types);
12534 for (i=0; i < (ssize_t) types; i++)
12535 {
12536 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12537 }
12538 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12539 typelist);
12540 goto PerlException;
12541 }
12542 EXTEND(sp,10*items);
12543 for (i=1; i < items; i++)
12544 {
12545 name=(char *) SvPV(ST(i),na);
12546 type_info=GetTypeInfo(name,exception);
12547 if (type_info == (TypeInfo *) NULL)
12548 {
12549 PUSHs(&sv_undef);
12550 continue;
12551 }
12552 if (type_info->name == (char *) NULL)
12553 PUSHs(&sv_undef);
12554 else
12555 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12556 if (type_info->description == (char *) NULL)
12557 PUSHs(&sv_undef);
12558 else
12559 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12560 if (type_info->family == (char *) NULL)
12561 PUSHs(&sv_undef);
12562 else
12563 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12564 if (type_info->style == UndefinedStyle)
12565 PUSHs(&sv_undef);
12566 else
12567 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12568 type_info->style),0)));
12569 if (type_info->stretch == UndefinedStretch)
12570 PUSHs(&sv_undef);
12571 else
12572 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12573 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012574 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012575 type_info->weight);
12576 PUSHs(sv_2mortal(newSVpv(message,0)));
12577 if (type_info->encoding == (char *) NULL)
12578 PUSHs(&sv_undef);
12579 else
12580 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12581 if (type_info->foundry == (char *) NULL)
12582 PUSHs(&sv_undef);
12583 else
12584 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12585 if (type_info->format == (char *) NULL)
12586 PUSHs(&sv_undef);
12587 else
12588 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12589 if (type_info->metrics == (char *) NULL)
12590 PUSHs(&sv_undef);
12591 else
12592 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12593 if (type_info->glyphs == (char *) NULL)
12594 PUSHs(&sv_undef);
12595 else
12596 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12597 }
12598
12599 PerlException:
12600 InheritPerlException(exception,perl_exception);
12601 exception=DestroyExceptionInfo(exception);
12602 SvREFCNT_dec(perl_exception);
12603 }
12604
12605#
12606###############################################################################
12607# #
12608# #
12609# #
12610# Q u e r y F o n t M e t r i c s #
12611# #
12612# #
12613# #
12614###############################################################################
12615#
12616#
12617void
12618QueryFontMetrics(ref,...)
12619 Image::Magick ref=NO_INIT
12620 ALIAS:
12621 queryfontmetrics = 1
12622 PPCODE:
12623 {
12624 AffineMatrix
12625 affine,
12626 current;
12627
12628 AV
12629 *av;
12630
12631 char
12632 *attribute;
12633
12634 double
12635 x,
12636 y;
12637
12638 DrawInfo
12639 *draw_info;
12640
12641 ExceptionInfo
12642 *exception;
12643
12644 GeometryInfo
12645 geometry_info;
12646
12647 Image
12648 *image;
12649
12650 MagickBooleanType
12651 status;
12652
12653 MagickStatusType
12654 flags;
12655
12656 register ssize_t
12657 i;
12658
12659 ssize_t
12660 type;
12661
12662 struct PackageInfo
12663 *info,
12664 *package_info;
12665
12666 SV
12667 *perl_exception,
12668 *reference; /* reference is the SV* of ref=SvIV(reference) */
12669
12670 TypeMetric
12671 metrics;
12672
12673 PERL_UNUSED_VAR(ref);
12674 PERL_UNUSED_VAR(ix);
12675 exception=AcquireExceptionInfo();
12676 package_info=(struct PackageInfo *) NULL;
12677 perl_exception=newSVpv("",0);
12678 reference=SvRV(ST(0));
12679 av=(AV *) reference;
12680 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12681 exception);
12682 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12683 if (image == (Image *) NULL)
12684 {
12685 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12686 PackageName);
12687 goto PerlException;
12688 }
12689 package_info=ClonePackageInfo(info,exception);
12690 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12691 CloneString(&draw_info->text,"");
12692 current=draw_info->affine;
12693 GetAffineMatrix(&affine);
12694 x=0.0;
12695 y=0.0;
12696 EXTEND(sp,7*items);
12697 for (i=2; i < items; i+=2)
12698 {
12699 attribute=(char *) SvPV(ST(i-1),na);
12700 switch (*attribute)
12701 {
12702 case 'A':
12703 case 'a':
12704 {
12705 if (LocaleCompare(attribute,"antialias") == 0)
12706 {
12707 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12708 SvPV(ST(i),na));
12709 if (type < 0)
12710 {
12711 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12712 SvPV(ST(i),na));
12713 break;
12714 }
12715 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12716 break;
12717 }
12718 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12719 attribute);
12720 break;
12721 }
12722 case 'd':
12723 case 'D':
12724 {
12725 if (LocaleCompare(attribute,"density") == 0)
12726 {
12727 CloneString(&draw_info->density,SvPV(ST(i),na));
12728 break;
12729 }
12730 if (LocaleCompare(attribute,"direction") == 0)
12731 {
12732 draw_info->direction=(DirectionType) ParseCommandOption(
12733 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12734 break;
12735 }
12736 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12737 attribute);
12738 break;
12739 }
12740 case 'e':
12741 case 'E':
12742 {
12743 if (LocaleCompare(attribute,"encoding") == 0)
12744 {
12745 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12746 break;
12747 }
12748 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12749 attribute);
12750 break;
12751 }
12752 case 'f':
12753 case 'F':
12754 {
12755 if (LocaleCompare(attribute,"family") == 0)
12756 {
12757 CloneString(&draw_info->family,SvPV(ST(i),na));
12758 break;
12759 }
12760 if (LocaleCompare(attribute,"fill") == 0)
12761 {
12762 if (info)
12763 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12764 &draw_info->fill,exception);
12765 break;
12766 }
12767 if (LocaleCompare(attribute,"font") == 0)
12768 {
12769 CloneString(&draw_info->font,SvPV(ST(i),na));
12770 break;
12771 }
12772 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12773 attribute);
12774 break;
12775 }
12776 case 'g':
12777 case 'G':
12778 {
12779 if (LocaleCompare(attribute,"geometry") == 0)
12780 {
12781 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12782 break;
12783 }
12784 if (LocaleCompare(attribute,"gravity") == 0)
12785 {
12786 draw_info->gravity=(GravityType) ParseCommandOption(
12787 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12788 break;
12789 }
12790 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12791 attribute);
12792 break;
12793 }
12794 case 'i':
12795 case 'I':
12796 {
12797 if (LocaleCompare(attribute,"interline-spacing") == 0)
12798 {
12799 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12800 draw_info->interline_spacing=geometry_info.rho;
12801 break;
12802 }
12803 if (LocaleCompare(attribute,"interword-spacing") == 0)
12804 {
12805 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12806 draw_info->interword_spacing=geometry_info.rho;
12807 break;
12808 }
12809 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12810 attribute);
12811 break;
12812 }
12813 case 'k':
12814 case 'K':
12815 {
12816 if (LocaleCompare(attribute,"kerning") == 0)
12817 {
12818 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12819 draw_info->kerning=geometry_info.rho;
12820 break;
12821 }
12822 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12823 attribute);
12824 break;
12825 }
12826 case 'p':
12827 case 'P':
12828 {
12829 if (LocaleCompare(attribute,"pointsize") == 0)
12830 {
12831 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12832 draw_info->pointsize=geometry_info.rho;
12833 break;
12834 }
12835 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12836 attribute);
12837 break;
12838 }
12839 case 'r':
12840 case 'R':
12841 {
12842 if (LocaleCompare(attribute,"rotate") == 0)
12843 {
12844 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12845 affine.rx=geometry_info.rho;
12846 affine.ry=geometry_info.sigma;
12847 if ((flags & SigmaValue) == 0)
12848 affine.ry=affine.rx;
12849 break;
12850 }
12851 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12852 attribute);
12853 break;
12854 }
12855 case 's':
12856 case 'S':
12857 {
12858 if (LocaleCompare(attribute,"scale") == 0)
12859 {
12860 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12861 affine.sx=geometry_info.rho;
12862 affine.sy=geometry_info.sigma;
12863 if ((flags & SigmaValue) == 0)
12864 affine.sy=affine.sx;
12865 break;
12866 }
12867 if (LocaleCompare(attribute,"skew") == 0)
12868 {
12869 double
12870 x_angle,
12871 y_angle;
12872
12873 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12874 x_angle=geometry_info.rho;
12875 y_angle=geometry_info.sigma;
12876 if ((flags & SigmaValue) == 0)
12877 y_angle=x_angle;
12878 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12879 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12880 break;
12881 }
12882 if (LocaleCompare(attribute,"stroke") == 0)
12883 {
12884 if (info)
12885 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12886 &draw_info->stroke,exception);
12887 break;
12888 }
12889 if (LocaleCompare(attribute,"style") == 0)
12890 {
12891 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12892 SvPV(ST(i),na));
12893 if (type < 0)
12894 {
12895 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12896 SvPV(ST(i),na));
12897 break;
12898 }
12899 draw_info->style=(StyleType) type;
12900 break;
12901 }
12902 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12903 attribute);
12904 break;
12905 }
12906 case 't':
12907 case 'T':
12908 {
12909 if (LocaleCompare(attribute,"text") == 0)
12910 {
12911 CloneString(&draw_info->text,SvPV(ST(i),na));
12912 break;
12913 }
12914 if (LocaleCompare(attribute,"translate") == 0)
12915 {
12916 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12917 affine.tx=geometry_info.rho;
12918 affine.ty=geometry_info.sigma;
12919 if ((flags & SigmaValue) == 0)
12920 affine.ty=affine.tx;
12921 break;
12922 }
12923 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12924 attribute);
12925 break;
12926 }
12927 case 'w':
12928 case 'W':
12929 {
12930 if (LocaleCompare(attribute,"weight") == 0)
12931 {
12932 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12933 draw_info->weight=(size_t) geometry_info.rho;
12934 break;
12935 }
12936 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12937 attribute);
12938 break;
12939 }
12940 case 'x':
12941 case 'X':
12942 {
12943 if (LocaleCompare(attribute,"x") == 0)
12944 {
12945 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12946 x=geometry_info.rho;
12947 break;
12948 }
12949 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12950 attribute);
12951 break;
12952 }
12953 case 'y':
12954 case 'Y':
12955 {
12956 if (LocaleCompare(attribute,"y") == 0)
12957 {
12958 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12959 y=geometry_info.rho;
12960 break;
12961 }
12962 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12963 attribute);
12964 break;
12965 }
12966 default:
12967 {
12968 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12969 attribute);
12970 break;
12971 }
12972 }
12973 }
12974 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12975 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12976 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12977 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12978 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12979 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12980 if (draw_info->geometry == (char *) NULL)
12981 {
12982 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000012983 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050012984 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000012985 }
12986 status=GetTypeMetrics(image,draw_info,&metrics,exception);
12987 (void) CatchImageException(image);
12988 if (status == MagickFalse)
12989 PUSHs(&sv_undef);
12990 else
12991 {
12992 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12993 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12994 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12995 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12996 PUSHs(sv_2mortal(newSVnv(metrics.width)));
12997 PUSHs(sv_2mortal(newSVnv(metrics.height)));
12998 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12999 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13000 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13001 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13002 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13003 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13004 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13005 }
13006 draw_info=DestroyDrawInfo(draw_info);
13007
13008 PerlException:
13009 if (package_info != (struct PackageInfo *) NULL)
13010 DestroyPackageInfo(package_info);
13011 InheritPerlException(exception,perl_exception);
13012 exception=DestroyExceptionInfo(exception);
13013 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13014 }
13015
13016#
13017###############################################################################
13018# #
13019# #
13020# #
13021# 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 #
13022# #
13023# #
13024# #
13025###############################################################################
13026#
13027#
13028void
13029QueryMultilineFontMetrics(ref,...)
13030 Image::Magick ref=NO_INIT
13031 ALIAS:
13032 querymultilinefontmetrics = 1
13033 PPCODE:
13034 {
13035 AffineMatrix
13036 affine,
13037 current;
13038
13039 AV
13040 *av;
13041
13042 char
13043 *attribute;
13044
13045 double
13046 x,
13047 y;
13048
13049 DrawInfo
13050 *draw_info;
13051
13052 ExceptionInfo
13053 *exception;
13054
13055 GeometryInfo
13056 geometry_info;
13057
13058 Image
13059 *image;
13060
13061 MagickBooleanType
13062 status;
13063
13064 MagickStatusType
13065 flags;
13066
13067 register ssize_t
13068 i;
13069
13070 ssize_t
13071 type;
13072
13073 struct PackageInfo
13074 *info,
13075 *package_info;
13076
13077 SV
13078 *perl_exception,
13079 *reference; /* reference is the SV* of ref=SvIV(reference) */
13080
13081 TypeMetric
13082 metrics;
13083
13084 PERL_UNUSED_VAR(ref);
13085 PERL_UNUSED_VAR(ix);
13086 exception=AcquireExceptionInfo();
13087 package_info=(struct PackageInfo *) NULL;
13088 perl_exception=newSVpv("",0);
13089 reference=SvRV(ST(0));
13090 av=(AV *) reference;
13091 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13092 exception);
13093 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13094 if (image == (Image *) NULL)
13095 {
13096 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13097 PackageName);
13098 goto PerlException;
13099 }
13100 package_info=ClonePackageInfo(info,exception);
13101 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13102 CloneString(&draw_info->text,"");
13103 current=draw_info->affine;
13104 GetAffineMatrix(&affine);
13105 x=0.0;
13106 y=0.0;
13107 EXTEND(sp,7*items);
13108 for (i=2; i < items; i+=2)
13109 {
13110 attribute=(char *) SvPV(ST(i-1),na);
13111 switch (*attribute)
13112 {
13113 case 'A':
13114 case 'a':
13115 {
13116 if (LocaleCompare(attribute,"antialias") == 0)
13117 {
13118 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13119 SvPV(ST(i),na));
13120 if (type < 0)
13121 {
13122 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13123 SvPV(ST(i),na));
13124 break;
13125 }
13126 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13127 break;
13128 }
13129 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13130 attribute);
13131 break;
13132 }
13133 case 'd':
13134 case 'D':
13135 {
13136 if (LocaleCompare(attribute,"density") == 0)
13137 {
13138 CloneString(&draw_info->density,SvPV(ST(i),na));
13139 break;
13140 }
13141 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13142 attribute);
13143 break;
13144 }
13145 case 'e':
13146 case 'E':
13147 {
13148 if (LocaleCompare(attribute,"encoding") == 0)
13149 {
13150 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13151 break;
13152 }
13153 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13154 attribute);
13155 break;
13156 }
13157 case 'f':
13158 case 'F':
13159 {
13160 if (LocaleCompare(attribute,"family") == 0)
13161 {
13162 CloneString(&draw_info->family,SvPV(ST(i),na));
13163 break;
13164 }
13165 if (LocaleCompare(attribute,"fill") == 0)
13166 {
13167 if (info)
13168 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13169 &draw_info->fill,exception);
13170 break;
13171 }
13172 if (LocaleCompare(attribute,"font") == 0)
13173 {
13174 CloneString(&draw_info->font,SvPV(ST(i),na));
13175 break;
13176 }
13177 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13178 attribute);
13179 break;
13180 }
13181 case 'g':
13182 case 'G':
13183 {
13184 if (LocaleCompare(attribute,"geometry") == 0)
13185 {
13186 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13187 break;
13188 }
13189 if (LocaleCompare(attribute,"gravity") == 0)
13190 {
13191 draw_info->gravity=(GravityType) ParseCommandOption(
13192 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13193 break;
13194 }
13195 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13196 attribute);
13197 break;
13198 }
13199 case 'p':
13200 case 'P':
13201 {
13202 if (LocaleCompare(attribute,"pointsize") == 0)
13203 {
13204 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13205 draw_info->pointsize=geometry_info.rho;
13206 break;
13207 }
13208 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13209 attribute);
13210 break;
13211 }
13212 case 'r':
13213 case 'R':
13214 {
13215 if (LocaleCompare(attribute,"rotate") == 0)
13216 {
13217 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13218 affine.rx=geometry_info.rho;
13219 affine.ry=geometry_info.sigma;
13220 if ((flags & SigmaValue) == 0)
13221 affine.ry=affine.rx;
13222 break;
13223 }
13224 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13225 attribute);
13226 break;
13227 }
13228 case 's':
13229 case 'S':
13230 {
13231 if (LocaleCompare(attribute,"scale") == 0)
13232 {
13233 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13234 affine.sx=geometry_info.rho;
13235 affine.sy=geometry_info.sigma;
13236 if ((flags & SigmaValue) == 0)
13237 affine.sy=affine.sx;
13238 break;
13239 }
13240 if (LocaleCompare(attribute,"skew") == 0)
13241 {
13242 double
13243 x_angle,
13244 y_angle;
13245
13246 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13247 x_angle=geometry_info.rho;
13248 y_angle=geometry_info.sigma;
13249 if ((flags & SigmaValue) == 0)
13250 y_angle=x_angle;
13251 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13252 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13253 break;
13254 }
13255 if (LocaleCompare(attribute,"stroke") == 0)
13256 {
13257 if (info)
13258 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13259 &draw_info->stroke,exception);
13260 break;
13261 }
13262 if (LocaleCompare(attribute,"style") == 0)
13263 {
13264 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13265 SvPV(ST(i),na));
13266 if (type < 0)
13267 {
13268 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13269 SvPV(ST(i),na));
13270 break;
13271 }
13272 draw_info->style=(StyleType) type;
13273 break;
13274 }
13275 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13276 attribute);
13277 break;
13278 }
13279 case 't':
13280 case 'T':
13281 {
13282 if (LocaleCompare(attribute,"text") == 0)
13283 {
13284 CloneString(&draw_info->text,SvPV(ST(i),na));
13285 break;
13286 }
13287 if (LocaleCompare(attribute,"translate") == 0)
13288 {
13289 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13290 affine.tx=geometry_info.rho;
13291 affine.ty=geometry_info.sigma;
13292 if ((flags & SigmaValue) == 0)
13293 affine.ty=affine.tx;
13294 break;
13295 }
13296 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13297 attribute);
13298 break;
13299 }
13300 case 'w':
13301 case 'W':
13302 {
13303 if (LocaleCompare(attribute,"weight") == 0)
13304 {
13305 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13306 draw_info->weight=(size_t) geometry_info.rho;
13307 break;
13308 }
13309 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13310 attribute);
13311 break;
13312 }
13313 case 'x':
13314 case 'X':
13315 {
13316 if (LocaleCompare(attribute,"x") == 0)
13317 {
13318 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13319 x=geometry_info.rho;
13320 break;
13321 }
13322 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13323 attribute);
13324 break;
13325 }
13326 case 'y':
13327 case 'Y':
13328 {
13329 if (LocaleCompare(attribute,"y") == 0)
13330 {
13331 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13332 y=geometry_info.rho;
13333 break;
13334 }
13335 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13336 attribute);
13337 break;
13338 }
13339 default:
13340 {
13341 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13342 attribute);
13343 break;
13344 }
13345 }
13346 }
13347 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13348 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13349 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13350 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13351 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13352 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13353 if (draw_info->geometry == (char *) NULL)
13354 {
13355 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013356 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013357 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013358 }
13359 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13360 (void) CatchException(exception);
13361 if (status == MagickFalse)
13362 PUSHs(&sv_undef);
13363 else
13364 {
13365 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13366 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13367 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13368 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13369 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13370 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13371 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13372 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13373 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13374 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13375 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13376 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13377 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13378 }
13379 draw_info=DestroyDrawInfo(draw_info);
13380
13381 PerlException:
13382 if (package_info != (struct PackageInfo *) NULL)
13383 DestroyPackageInfo(package_info);
13384 InheritPerlException(exception,perl_exception);
13385 exception=DestroyExceptionInfo(exception);
13386 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13387 }
13388
13389#
13390###############################################################################
13391# #
13392# #
13393# #
13394# Q u e r y F o r m a t #
13395# #
13396# #
13397# #
13398###############################################################################
13399#
13400#
13401void
13402QueryFormat(ref,...)
13403 Image::Magick ref=NO_INIT
13404 ALIAS:
13405 queryformat = 1
13406 PPCODE:
13407 {
13408 char
13409 *name;
13410
13411 ExceptionInfo
13412 *exception;
13413
13414 register ssize_t
13415 i;
13416
13417 SV
13418 *perl_exception;
13419
13420 volatile const MagickInfo
13421 *magick_info;
13422
13423 PERL_UNUSED_VAR(ref);
13424 PERL_UNUSED_VAR(ix);
13425 exception=AcquireExceptionInfo();
13426 perl_exception=newSVpv("",0);
13427 if (items == 1)
13428 {
13429 char
cristy151b66d2015-04-15 10:50:31 +000013430 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013431
13432 const MagickInfo
13433 **format_list;
13434
13435 size_t
13436 types;
13437
13438 format_list=GetMagickInfoList("*",&types,exception);
13439 EXTEND(sp,types);
13440 for (i=0; i < (ssize_t) types; i++)
13441 {
cristy151b66d2015-04-15 10:50:31 +000013442 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013443 LocaleLower(format);
13444 PUSHs(sv_2mortal(newSVpv(format,0)));
13445 }
13446 format_list=(const MagickInfo **)
13447 RelinquishMagickMemory((MagickInfo *) format_list);
13448 goto PerlException;
13449 }
13450 EXTEND(sp,8*items);
13451 for (i=1; i < items; i++)
13452 {
13453 name=(char *) SvPV(ST(i),na);
13454 magick_info=GetMagickInfo(name,exception);
13455 if (magick_info == (const MagickInfo *) NULL)
13456 {
13457 PUSHs(&sv_undef);
13458 continue;
13459 }
cristy4a3ce0a2013-08-03 20:06:59 +000013460 if (magick_info->description == (char *) NULL)
13461 PUSHs(&sv_undef);
13462 else
13463 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13464 if (magick_info->module == (char *) NULL)
13465 PUSHs(&sv_undef);
13466 else
13467 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13468 }
13469
13470 PerlException:
13471 InheritPerlException(exception,perl_exception);
13472 exception=DestroyExceptionInfo(exception);
13473 SvREFCNT_dec(perl_exception);
13474 }
13475
13476#
13477###############################################################################
13478# #
13479# #
13480# #
13481# Q u e r y O p t i o n #
13482# #
13483# #
13484# #
13485###############################################################################
13486#
13487#
13488void
13489QueryOption(ref,...)
13490 Image::Magick ref=NO_INIT
13491 ALIAS:
13492 queryoption = 1
13493 PPCODE:
13494 {
13495 char
13496 **options;
13497
13498 ExceptionInfo
13499 *exception;
13500
13501 register ssize_t
13502 i;
13503
13504 ssize_t
13505 j,
13506 option;
13507
13508 SV
13509 *perl_exception;
13510
13511 PERL_UNUSED_VAR(ref);
13512 PERL_UNUSED_VAR(ix);
13513 exception=AcquireExceptionInfo();
13514 perl_exception=newSVpv("",0);
13515 EXTEND(sp,8*items);
13516 for (i=1; i < items; i++)
13517 {
13518 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13519 SvPV(ST(i),na));
13520 options=GetCommandOptions((CommandOption) option);
13521 if (options == (char **) NULL)
13522 PUSHs(&sv_undef);
13523 else
13524 {
13525 for (j=0; options[j] != (char *) NULL; j++)
13526 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13527 options=DestroyStringList(options);
13528 }
13529 }
13530
13531 InheritPerlException(exception,perl_exception);
13532 exception=DestroyExceptionInfo(exception);
13533 SvREFCNT_dec(perl_exception);
13534 }
13535
13536#
13537###############################################################################
13538# #
13539# #
13540# #
13541# R e a d #
13542# #
13543# #
13544# #
13545###############################################################################
13546#
13547#
13548void
13549Read(ref,...)
13550 Image::Magick ref=NO_INIT
13551 ALIAS:
13552 ReadImage = 1
13553 read = 2
13554 readimage = 3
13555 PPCODE:
13556 {
13557 AV
13558 *av;
13559
13560 char
13561 **keep,
13562 **list;
13563
13564 ExceptionInfo
13565 *exception;
13566
13567 HV
13568 *hv;
13569
13570 Image
13571 *image;
13572
13573 int
13574 n;
13575
13576 MagickBooleanType
13577 status;
13578
13579 register char
13580 **p;
13581
13582 register ssize_t
13583 i;
13584
13585 ssize_t
13586 ac,
13587 number_images;
13588
13589 STRLEN
13590 *length;
13591
13592 struct PackageInfo
13593 *info,
13594 *package_info;
13595
13596 SV
13597 *perl_exception, /* Perl variable for storing messages */
13598 *reference,
13599 *rv,
13600 *sv;
13601
13602 PERL_UNUSED_VAR(ref);
13603 PERL_UNUSED_VAR(ix);
13604 exception=AcquireExceptionInfo();
13605 perl_exception=newSVpv("",0);
13606 sv=NULL;
13607 package_info=(struct PackageInfo *) NULL;
13608 number_images=0;
13609 ac=(items < 2) ? 1 : items-1;
13610 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13611 keep=list;
13612 length=(STRLEN *) NULL;
13613 if (list == (char **) NULL)
13614 {
13615 ThrowPerlException(exception,ResourceLimitError,
13616 "MemoryAllocationFailed",PackageName);
13617 goto PerlException;
13618 }
13619 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13620 if (length == (STRLEN *) NULL)
13621 {
13622 ThrowPerlException(exception,ResourceLimitError,
13623 "MemoryAllocationFailed",PackageName);
13624 goto PerlException;
13625 }
13626 if (sv_isobject(ST(0)) == 0)
13627 {
13628 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13629 PackageName);
13630 goto PerlException;
13631 }
13632 reference=SvRV(ST(0));
13633 hv=SvSTASH(reference);
13634 if (SvTYPE(reference) != SVt_PVAV)
13635 {
13636 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13637 PackageName);
13638 goto PerlException;
13639 }
13640 av=(AV *) reference;
13641 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13642 exception);
13643 package_info=ClonePackageInfo(info,exception);
13644 n=1;
13645 if (items <= 1)
13646 *list=(char *) (*package_info->image_info->filename ?
13647 package_info->image_info->filename : "XC:black");
13648 else
13649 for (n=0, i=0; i < ac; i++)
13650 {
13651 list[n]=(char *) SvPV(ST(i+1),length[n]);
13652 if ((items >= 3) && strEQcase(list[n],"blob"))
13653 {
13654 void
13655 *blob;
13656
13657 i++;
13658 blob=(void *) (SvPV(ST(i+1),length[n]));
13659 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13660 }
13661 if ((items >= 3) && strEQcase(list[n],"filename"))
13662 continue;
13663 if ((items >= 3) && strEQcase(list[n],"file"))
13664 {
13665 FILE
13666 *file;
13667
13668 PerlIO
13669 *io_info;
13670
13671 i++;
13672 io_info=IoIFP(sv_2io(ST(i+1)));
13673 if (io_info == (PerlIO *) NULL)
13674 {
13675 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13676 PackageName);
13677 continue;
13678 }
13679 file=PerlIO_findFILE(io_info);
13680 if (file == (FILE *) NULL)
13681 {
13682 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13683 PackageName);
13684 continue;
13685 }
13686 SetImageInfoFile(package_info->image_info,file);
13687 }
13688 if ((items >= 3) && strEQcase(list[n],"magick"))
13689 continue;
13690 n++;
13691 }
13692 list[n]=(char *) NULL;
13693 keep=list;
13694 status=ExpandFilenames(&n,&list);
13695 if (status == MagickFalse)
13696 {
13697 ThrowPerlException(exception,ResourceLimitError,
13698 "MemoryAllocationFailed",PackageName);
13699 goto PerlException;
13700 }
13701 number_images=0;
13702 for (i=0; i < n; i++)
13703 {
13704 if ((package_info->image_info->file == (FILE *) NULL) &&
13705 (package_info->image_info->blob == (void *) NULL))
13706 image=ReadImages(package_info->image_info,list[i],exception);
13707 else
13708 {
13709 image=ReadImages(package_info->image_info,
13710 package_info->image_info->filename,exception);
13711 if (image != (Image *) NULL)
13712 DisassociateImageStream(image);
13713 }
13714 if (image == (Image *) NULL)
13715 break;
13716 for ( ; image; image=image->next)
13717 {
13718 AddImageToRegistry(sv,image);
13719 rv=newRV(sv);
13720 av_push(av,sv_bless(rv,hv));
13721 SvREFCNT_dec(sv);
13722 number_images++;
13723 }
13724 }
13725 /*
13726 Free resources.
13727 */
13728 for (i=0; i < n; i++)
13729 if (list[i] != (char *) NULL)
13730 for (p=keep; list[i] != *p++; )
13731 if (*p == (char *) NULL)
13732 {
13733 list[i]=(char *) RelinquishMagickMemory(list[i]);
13734 break;
13735 }
13736
13737 PerlException:
13738 if (package_info != (struct PackageInfo *) NULL)
13739 DestroyPackageInfo(package_info);
13740 if (list && (list != keep))
13741 list=(char **) RelinquishMagickMemory(list);
13742 if (keep)
13743 keep=(char **) RelinquishMagickMemory(keep);
13744 if (length)
13745 length=(STRLEN *) RelinquishMagickMemory(length);
13746 InheritPerlException(exception,perl_exception);
13747 exception=DestroyExceptionInfo(exception);
13748 sv_setiv(perl_exception,(IV) number_images);
13749 SvPOK_on(perl_exception);
13750 ST(0)=sv_2mortal(perl_exception);
13751 XSRETURN(1);
13752 }
13753
13754#
13755###############################################################################
13756# #
13757# #
13758# #
13759# R e m o t e #
13760# #
13761# #
13762# #
13763###############################################################################
13764#
13765#
13766void
13767Remote(ref,...)
13768 Image::Magick ref=NO_INIT
13769 ALIAS:
13770 RemoteCommand = 1
13771 remote = 2
13772 remoteCommand = 3
13773 PPCODE:
13774 {
13775 AV
13776 *av;
13777
13778 ExceptionInfo
13779 *exception;
13780
13781 register ssize_t
13782 i;
13783
13784 SV
13785 *perl_exception,
13786 *reference;
13787
13788 struct PackageInfo
13789 *info;
13790
13791 PERL_UNUSED_VAR(ref);
13792 PERL_UNUSED_VAR(ix);
13793 exception=AcquireExceptionInfo();
13794 perl_exception=newSVpv("",0);
13795 reference=SvRV(ST(0));
13796 av=(AV *) reference;
13797 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13798 exception);
13799 for (i=1; i < items; i++)
13800 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13801 SvPV(ST(i),na),exception);
13802 InheritPerlException(exception,perl_exception);
13803 exception=DestroyExceptionInfo(exception);
13804 SvREFCNT_dec(perl_exception); /* throw away all errors */
13805 }
13806
13807#
13808###############################################################################
13809# #
13810# #
13811# #
13812# S e t #
13813# #
13814# #
13815# #
13816###############################################################################
13817#
13818#
13819void
13820Set(ref,...)
13821 Image::Magick ref=NO_INIT
13822 ALIAS:
13823 SetAttributes = 1
13824 SetAttribute = 2
13825 set = 3
13826 setattributes = 4
13827 setattribute = 5
13828 PPCODE:
13829 {
13830 ExceptionInfo
13831 *exception;
13832
13833 Image
13834 *image;
13835
13836 register ssize_t
13837 i;
13838
13839 struct PackageInfo
13840 *info;
13841
13842 SV
13843 *perl_exception,
13844 *reference; /* reference is the SV* of ref=SvIV(reference) */
13845
13846 PERL_UNUSED_VAR(ref);
13847 PERL_UNUSED_VAR(ix);
13848 exception=AcquireExceptionInfo();
13849 perl_exception=newSVpv("",0);
13850 if (sv_isobject(ST(0)) == 0)
13851 {
13852 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13853 PackageName);
13854 goto PerlException;
13855 }
13856 reference=SvRV(ST(0));
13857 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13858 if (items == 2)
13859 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13860 else
13861 for (i=2; i < items; i+=2)
13862 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13863
13864 PerlException:
13865 InheritPerlException(exception,perl_exception);
13866 exception=DestroyExceptionInfo(exception);
13867 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13868 SvPOK_on(perl_exception);
13869 ST(0)=sv_2mortal(perl_exception);
13870 XSRETURN(1);
13871 }
13872
13873#
13874###############################################################################
13875# #
13876# #
13877# #
13878# S e t P i x e l #
13879# #
13880# #
13881# #
13882###############################################################################
13883#
13884#
13885void
13886SetPixel(ref,...)
13887 Image::Magick ref=NO_INIT
13888 ALIAS:
13889 setpixel = 1
13890 setPixel = 2
13891 PPCODE:
13892 {
13893 AV
13894 *av;
13895
13896 char
13897 *attribute;
13898
13899 ChannelType
13900 channel,
13901 channel_mask;
13902
13903 ExceptionInfo
13904 *exception;
13905
13906 Image
13907 *image;
13908
13909 MagickBooleanType
13910 normalize;
13911
13912 RectangleInfo
13913 region;
13914
13915 register ssize_t
13916 i;
13917
13918 register Quantum
13919 *q;
13920
13921 ssize_t
13922 option;
13923
13924 struct PackageInfo
13925 *info;
13926
13927 SV
13928 *perl_exception,
13929 *reference; /* reference is the SV* of ref=SvIV(reference) */
13930
13931 PERL_UNUSED_VAR(ref);
13932 PERL_UNUSED_VAR(ix);
13933 exception=AcquireExceptionInfo();
13934 perl_exception=newSVpv("",0);
13935 reference=SvRV(ST(0));
13936 av=(AV *) reference;
13937 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13938 exception);
13939 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13940 if (image == (Image *) NULL)
13941 {
13942 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13943 PackageName);
13944 goto PerlException;
13945 }
13946 av=(AV *) NULL;
13947 normalize=MagickTrue;
13948 region.x=0;
13949 region.y=0;
13950 region.width=image->columns;
13951 region.height=1;
13952 if (items == 1)
13953 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
13954 channel=DefaultChannels;
13955 for (i=2; i < items; i+=2)
13956 {
13957 attribute=(char *) SvPV(ST(i-1),na);
13958 switch (*attribute)
13959 {
13960 case 'C':
13961 case 'c':
13962 {
13963 if (LocaleCompare(attribute,"channel") == 0)
13964 {
13965 ssize_t
13966 option;
13967
13968 option=ParseChannelOption(SvPV(ST(i),na));
13969 if (option < 0)
13970 {
13971 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13972 SvPV(ST(i),na));
13973 return;
13974 }
13975 channel=(ChannelType) option;
13976 break;
13977 }
13978 if (LocaleCompare(attribute,"color") == 0)
13979 {
13980 if (SvTYPE(ST(i)) != SVt_RV)
13981 {
13982 char
cristy151b66d2015-04-15 10:50:31 +000013983 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013984
cristy151b66d2015-04-15 10:50:31 +000013985 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013986 "invalid %.60s value",attribute);
13987 ThrowPerlException(exception,OptionError,message,
13988 SvPV(ST(i),na));
13989 }
13990 av=(AV *) SvRV(ST(i));
13991 break;
13992 }
13993 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13994 attribute);
13995 break;
13996 }
13997 case 'g':
13998 case 'G':
13999 {
14000 if (LocaleCompare(attribute,"geometry") == 0)
14001 {
14002 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14003 break;
14004 }
14005 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14006 attribute);
14007 break;
14008 }
14009 case 'N':
14010 case 'n':
14011 {
14012 if (LocaleCompare(attribute,"normalize") == 0)
14013 {
14014 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14015 SvPV(ST(i),na));
14016 if (option < 0)
14017 {
14018 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14019 SvPV(ST(i),na));
14020 break;
14021 }
14022 normalize=option != 0 ? MagickTrue : MagickFalse;
14023 break;
14024 }
14025 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14026 attribute);
14027 break;
14028 }
14029 case 'x':
14030 case 'X':
14031 {
14032 if (LocaleCompare(attribute,"x") == 0)
14033 {
14034 region.x=SvIV(ST(i));
14035 break;
14036 }
14037 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14038 attribute);
14039 break;
14040 }
14041 case 'y':
14042 case 'Y':
14043 {
14044 if (LocaleCompare(attribute,"y") == 0)
14045 {
14046 region.y=SvIV(ST(i));
14047 break;
14048 }
14049 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14050 attribute);
14051 break;
14052 }
14053 default:
14054 {
14055 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14056 attribute);
14057 break;
14058 }
14059 }
14060 }
14061 (void) SetImageStorageClass(image,DirectClass,exception);
14062 channel_mask=SetImageChannelMask(image,channel);
14063 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14064 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14065 (SvTYPE(av) != SVt_PVAV))
14066 PUSHs(&sv_undef);
14067 else
14068 {
14069 double
14070 scale;
14071
14072 register ssize_t
14073 i;
14074
14075 i=0;
14076 scale=1.0;
14077 if (normalize != MagickFalse)
14078 scale=QuantumRange;
14079 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14080 (i <= av_len(av)))
14081 {
14082 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14083 av_fetch(av,i,0)))),q);
14084 i++;
14085 }
14086 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14087 (i <= av_len(av)))
14088 {
14089 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14090 av_fetch(av,i,0)))),q);
14091 i++;
14092 }
14093 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14094 (i <= av_len(av)))
14095 {
14096 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14097 av_fetch(av,i,0)))),q);
14098 i++;
14099 }
14100 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14101 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14102 {
14103 SetPixelBlack(image,ClampToQuantum(scale*
14104 SvNV(*(av_fetch(av,i,0)))),q);
14105 i++;
14106 }
14107 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14108 (i <= av_len(av)))
14109 {
14110 SetPixelAlpha(image,ClampToQuantum(scale*
14111 SvNV(*(av_fetch(av,i,0)))),q);
14112 i++;
14113 }
14114 (void) SyncAuthenticPixels(image,exception);
14115 }
14116 (void) SetImageChannelMask(image,channel_mask);
14117
14118 PerlException:
14119 InheritPerlException(exception,perl_exception);
14120 exception=DestroyExceptionInfo(exception);
14121 SvREFCNT_dec(perl_exception);
14122 }
14123
14124#
14125###############################################################################
14126# #
14127# #
14128# #
14129# S m u s h #
14130# #
14131# #
14132# #
14133###############################################################################
14134#
14135#
14136void
14137Smush(ref,...)
14138 Image::Magick ref=NO_INIT
14139 ALIAS:
14140 SmushImage = 1
14141 smush = 2
14142 smushimage = 3
14143 PPCODE:
14144 {
14145 AV
14146 *av;
14147
14148 char
14149 *attribute;
14150
14151 ExceptionInfo
14152 *exception;
14153
14154 HV
14155 *hv;
14156
14157 Image
14158 *image;
14159
14160 register ssize_t
14161 i;
14162
14163 ssize_t
14164 offset,
14165 stack;
14166
14167 struct PackageInfo
14168 *info;
14169
14170 SV
14171 *av_reference,
14172 *perl_exception,
14173 *reference,
14174 *rv,
14175 *sv;
14176
14177 PERL_UNUSED_VAR(ref);
14178 PERL_UNUSED_VAR(ix);
14179 exception=AcquireExceptionInfo();
14180 perl_exception=newSVpv("",0);
14181 sv=NULL;
14182 attribute=NULL;
14183 av=NULL;
14184 if (sv_isobject(ST(0)) == 0)
14185 {
14186 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14187 PackageName);
14188 goto PerlException;
14189 }
14190 reference=SvRV(ST(0));
14191 hv=SvSTASH(reference);
14192 av=newAV();
14193 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14194 SvREFCNT_dec(av);
14195 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14196 if (image == (Image *) NULL)
14197 {
14198 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14199 PackageName);
14200 goto PerlException;
14201 }
14202 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14203 /*
14204 Get options.
14205 */
14206 offset=0;
14207 stack=MagickTrue;
14208 for (i=2; i < items; i+=2)
14209 {
14210 attribute=(char *) SvPV(ST(i-1),na);
14211 switch (*attribute)
14212 {
14213 case 'O':
14214 case 'o':
14215 {
14216 if (LocaleCompare(attribute,"offset") == 0)
14217 {
14218 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14219 break;
14220 }
14221 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14222 attribute);
14223 break;
14224 }
14225 case 'S':
14226 case 's':
14227 {
14228 if (LocaleCompare(attribute,"stack") == 0)
14229 {
14230 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14231 SvPV(ST(i),na));
14232 if (stack < 0)
14233 {
14234 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14235 SvPV(ST(i),na));
14236 return;
14237 }
14238 break;
14239 }
14240 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14241 attribute);
14242 break;
14243 }
14244 default:
14245 {
14246 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14247 attribute);
14248 break;
14249 }
14250 }
14251 }
14252 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14253 exception);
14254 if (image == (Image *) NULL)
14255 goto PerlException;
14256 for ( ; image; image=image->next)
14257 {
14258 AddImageToRegistry(sv,image);
14259 rv=newRV(sv);
14260 av_push(av,sv_bless(rv,hv));
14261 SvREFCNT_dec(sv);
14262 }
14263 exception=DestroyExceptionInfo(exception);
14264 ST(0)=av_reference;
14265 SvREFCNT_dec(perl_exception);
14266 XSRETURN(1);
14267
14268 PerlException:
14269 InheritPerlException(exception,perl_exception);
14270 exception=DestroyExceptionInfo(exception);
14271 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14272 SvPOK_on(perl_exception);
14273 ST(0)=sv_2mortal(perl_exception);
14274 XSRETURN(1);
14275 }
14276
14277#
14278###############################################################################
14279# #
14280# #
14281# #
14282# S t a t i s t i c s #
14283# #
14284# #
14285# #
14286###############################################################################
14287#
14288#
14289void
14290Statistics(ref,...)
14291 Image::Magick ref=NO_INIT
14292 ALIAS:
14293 StatisticsImage = 1
14294 statistics = 2
14295 statisticsimage = 3
14296 PPCODE:
14297 {
14298#define ChannelStatistics(channel) \
14299{ \
cristy151b66d2015-04-15 10:50:31 +000014300 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014301 (double) channel_statistics[channel].depth); \
14302 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014303 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014304 channel_statistics[channel].minima/scale); \
14305 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014306 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014307 channel_statistics[channel].maxima/scale); \
14308 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014309 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014310 channel_statistics[channel].mean/scale); \
14311 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014312 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014313 channel_statistics[channel].standard_deviation/scale); \
14314 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014315 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014316 channel_statistics[channel].kurtosis); \
14317 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014318 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014319 channel_statistics[channel].skewness); \
14320 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014321 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy275bdd92014-11-08 23:45:03 +000014322 channel_statistics[channel].entropy); \
14323 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014324}
14325
14326 AV
14327 *av;
14328
14329 char
cristy151b66d2015-04-15 10:50:31 +000014330 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014331
14332 ChannelStatistics
14333 *channel_statistics;
14334
14335 double
14336 scale;
14337
14338 ExceptionInfo
14339 *exception;
14340
14341 Image
14342 *image;
14343
14344 ssize_t
14345 count;
14346
14347 struct PackageInfo
14348 *info;
14349
14350 SV
14351 *perl_exception,
14352 *reference;
14353
14354 PERL_UNUSED_VAR(ref);
14355 PERL_UNUSED_VAR(ix);
14356 exception=AcquireExceptionInfo();
14357 perl_exception=newSVpv("",0);
14358 av=NULL;
14359 if (sv_isobject(ST(0)) == 0)
14360 {
14361 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14362 PackageName);
14363 goto PerlException;
14364 }
14365 reference=SvRV(ST(0));
14366 av=newAV();
14367 SvREFCNT_dec(av);
14368 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14369 if (image == (Image *) NULL)
14370 {
14371 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14372 PackageName);
14373 goto PerlException;
14374 }
cristy4a3ce0a2013-08-03 20:06:59 +000014375 count=0;
14376 for ( ; image; image=image->next)
14377 {
Cristyb1710fe2017-02-11 13:51:48 -050014378 register size_t
14379 i;
14380
cristy4a3ce0a2013-08-03 20:06:59 +000014381 channel_statistics=GetImageStatistics(image,exception);
14382 if (channel_statistics == (ChannelStatistics *) NULL)
14383 continue;
14384 count++;
Cristyb1710fe2017-02-11 13:51:48 -050014385 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
14386 {
14387 PixelChannel channel=GetPixelChannelChannel(image,i);
14388 PixelTrait traits=GetPixelChannelTraits(image,channel);
14389 if ((traits & UpdatePixelTrait) == 0)
14390 continue;
14391 EXTEND(sp,8*i*count);
14392 ChannelStatistics(channel);
14393 }
cristy4a3ce0a2013-08-03 20:06:59 +000014394 channel_statistics=(ChannelStatistics *)
14395 RelinquishMagickMemory(channel_statistics);
14396 }
14397
14398 PerlException:
14399 InheritPerlException(exception,perl_exception);
14400 exception=DestroyExceptionInfo(exception);
14401 SvREFCNT_dec(perl_exception);
14402 }
14403
14404#
14405###############################################################################
14406# #
14407# #
14408# #
14409# S y n c A u t h e n t i c P i x e l s #
14410# #
14411# #
14412# #
14413###############################################################################
14414#
14415#
14416void
14417SyncAuthenticPixels(ref,...)
14418 Image::Magick ref = NO_INIT
14419 ALIAS:
14420 Syncauthenticpixels = 1
14421 SyncImagePixels = 2
14422 syncimagepixels = 3
14423 CODE:
14424 {
14425 ExceptionInfo
14426 *exception;
14427
14428 Image
14429 *image;
14430
14431 MagickBooleanType
14432 status;
14433
14434 struct PackageInfo
14435 *info;
14436
14437 SV
14438 *perl_exception,
14439 *reference;
14440
14441 PERL_UNUSED_VAR(ref);
14442 PERL_UNUSED_VAR(ix);
14443 exception=AcquireExceptionInfo();
14444 perl_exception=newSVpv("",0);
14445 if (sv_isobject(ST(0)) == 0)
14446 {
14447 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14448 PackageName);
14449 goto PerlException;
14450 }
14451
14452 reference=SvRV(ST(0));
14453 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14454 if (image == (Image *) NULL)
14455 {
14456 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14457 PackageName);
14458 goto PerlException;
14459 }
14460
14461 status=SyncAuthenticPixels(image,exception);
14462 if (status != MagickFalse)
14463 return;
14464
14465 PerlException:
14466 InheritPerlException(exception,perl_exception);
14467 exception=DestroyExceptionInfo(exception);
14468 SvREFCNT_dec(perl_exception); /* throw away all errors */
14469 }
14470
14471#
14472###############################################################################
14473# #
14474# #
14475# #
cristy4a3ce0a2013-08-03 20:06:59 +000014476# W r i t e #
14477# #
14478# #
14479# #
14480###############################################################################
14481#
14482#
14483void
14484Write(ref,...)
14485 Image::Magick ref=NO_INIT
14486 ALIAS:
14487 WriteImage = 1
14488 write = 2
14489 writeimage = 3
14490 PPCODE:
14491 {
14492 char
cristy151b66d2015-04-15 10:50:31 +000014493 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014494
14495 ExceptionInfo
14496 *exception;
14497
14498 Image
14499 *image,
14500 *next;
14501
14502 register ssize_t
14503 i;
14504
14505 ssize_t
14506 number_images,
14507 scene;
14508
14509 struct PackageInfo
14510 *info,
14511 *package_info;
14512
14513 SV
14514 *perl_exception,
14515 *reference;
14516
14517 PERL_UNUSED_VAR(ref);
14518 PERL_UNUSED_VAR(ix);
14519 exception=AcquireExceptionInfo();
14520 perl_exception=newSVpv("",0);
14521 number_images=0;
14522 package_info=(struct PackageInfo *) NULL;
14523 if (sv_isobject(ST(0)) == 0)
14524 {
14525 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14526 PackageName);
14527 goto PerlException;
14528 }
14529 reference=SvRV(ST(0));
14530 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14531 if (image == (Image *) NULL)
14532 {
14533 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14534 PackageName);
14535 goto PerlException;
14536 }
14537 package_info=ClonePackageInfo(info,exception);
14538 if (items == 2)
14539 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14540 else
14541 if (items > 2)
14542 for (i=2; i < items; i+=2)
14543 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14544 exception);
14545 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014546 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014547 scene=0;
14548 for (next=image; next; next=next->next)
14549 {
cristy151b66d2015-04-15 10:50:31 +000014550 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014551 next->scene=scene++;
14552 }
cristy68bd79a2015-02-25 12:23:36 +000014553 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014554 SetImageInfo(package_info->image_info,(unsigned int)
14555 GetImageListLength(image),exception);
14556 for (next=image; next; next=next->next)
14557 {
14558 (void) WriteImage(package_info->image_info,next,exception);
14559 number_images++;
14560 if (package_info->image_info->adjoin)
14561 break;
14562 }
14563
14564 PerlException:
14565 if (package_info != (struct PackageInfo *) NULL)
14566 DestroyPackageInfo(package_info);
14567 InheritPerlException(exception,perl_exception);
14568 exception=DestroyExceptionInfo(exception);
14569 sv_setiv(perl_exception,(IV) number_images);
14570 SvPOK_on(perl_exception);
14571 ST(0)=sv_2mortal(perl_exception);
14572 XSRETURN(1);
14573 }