blob: 6d3b01177f28d2a405a72b6ab1cbcbd7f72e5104 [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% %
Cristy7ce65e72015-12-12 18:03:16 -050026% Copyright 1999-2016 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} } },
Cristy2d830ed2016-02-21 10:54:16 -0500563 { "WaveletDenoise", { {"threshold", StringReference},
564 {"channel", MagickChannelOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000565 };
566
567static SplayTreeInfo
568 *magick_registry = (SplayTreeInfo *) NULL;
569
570/*
571 Forward declarations.
572*/
573static Image
574 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
575
576static ssize_t
577 strEQcase(const char *,const char *);
578
579/*
580%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
581% %
582% %
583% %
584% C l o n e P a c k a g e I n f o %
585% %
586% %
587% %
588%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
589%
590% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
591% a new one.
592%
593% The format of the ClonePackageInfo routine is:
594%
595% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
596% exception)
597%
598% A description of each parameter follows:
599%
600% o info: a structure of type info.
601%
602% o exception: Return any errors or warnings in this structure.
603%
604*/
605static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
606 ExceptionInfo *exception)
607{
608 struct PackageInfo
609 *clone_info;
610
611 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
612 if (clone_info == (struct PackageInfo *) NULL)
613 {
614 ThrowPerlException(exception,ResourceLimitError,
615 "UnableToClonePackageInfo",PackageName);
616 return((struct PackageInfo *) NULL);
617 }
618 if (info == (struct PackageInfo *) NULL)
619 {
620 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
621 return(clone_info);
622 }
623 *clone_info=(*info);
624 clone_info->image_info=CloneImageInfo(info->image_info);
625 return(clone_info);
626}
627
628/*
629%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
630% %
631% %
632% %
633% c o n s t a n t %
634% %
635% %
636% %
637%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
638%
639% constant() returns a double value for the specified name.
640%
641% The format of the constant routine is:
642%
643% double constant(char *name,ssize_t sans)
644%
645% A description of each parameter follows:
646%
647% o value: Method constant returns a double value for the specified name.
648%
649% o name: The name of the constant.
650%
651% o sans: This integer value is not used.
652%
653*/
654static double constant(char *name,ssize_t sans)
655{
656 (void) sans;
657 errno=0;
658 switch (*name)
659 {
660 case 'B':
661 {
662 if (strEQ(name,"BlobError"))
663 return(BlobError);
664 if (strEQ(name,"BlobWarning"))
665 return(BlobWarning);
666 break;
667 }
668 case 'C':
669 {
670 if (strEQ(name,"CacheError"))
671 return(CacheError);
672 if (strEQ(name,"CacheWarning"))
673 return(CacheWarning);
674 if (strEQ(name,"CoderError"))
675 return(CoderError);
676 if (strEQ(name,"CoderWarning"))
677 return(CoderWarning);
678 if (strEQ(name,"ConfigureError"))
679 return(ConfigureError);
680 if (strEQ(name,"ConfigureWarning"))
681 return(ConfigureWarning);
682 if (strEQ(name,"CorruptImageError"))
683 return(CorruptImageError);
684 if (strEQ(name,"CorruptImageWarning"))
685 return(CorruptImageWarning);
686 break;
687 }
688 case 'D':
689 {
690 if (strEQ(name,"DelegateError"))
691 return(DelegateError);
692 if (strEQ(name,"DelegateWarning"))
693 return(DelegateWarning);
694 if (strEQ(name,"DrawError"))
695 return(DrawError);
696 if (strEQ(name,"DrawWarning"))
697 return(DrawWarning);
698 break;
699 }
700 case 'E':
701 {
702 if (strEQ(name,"ErrorException"))
703 return(ErrorException);
704 if (strEQ(name,"ExceptionError"))
705 return(CoderError);
706 if (strEQ(name,"ExceptionWarning"))
707 return(CoderWarning);
708 break;
709 }
710 case 'F':
711 {
712 if (strEQ(name,"FatalErrorException"))
713 return(FatalErrorException);
714 if (strEQ(name,"FileOpenError"))
715 return(FileOpenError);
716 if (strEQ(name,"FileOpenWarning"))
717 return(FileOpenWarning);
718 break;
719 }
720 case 'I':
721 {
722 if (strEQ(name,"ImageError"))
723 return(ImageError);
724 if (strEQ(name,"ImageWarning"))
725 return(ImageWarning);
726 break;
727 }
728 case 'M':
729 {
730 if (strEQ(name,"MaxRGB"))
731 return(QuantumRange);
732 if (strEQ(name,"MissingDelegateError"))
733 return(MissingDelegateError);
734 if (strEQ(name,"MissingDelegateWarning"))
735 return(MissingDelegateWarning);
736 if (strEQ(name,"ModuleError"))
737 return(ModuleError);
738 if (strEQ(name,"ModuleWarning"))
739 return(ModuleWarning);
740 break;
741 }
742 case 'O':
743 {
744 if (strEQ(name,"Opaque"))
745 return(OpaqueAlpha);
746 if (strEQ(name,"OptionError"))
747 return(OptionError);
748 if (strEQ(name,"OptionWarning"))
749 return(OptionWarning);
750 break;
751 }
752 case 'Q':
753 {
754 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
755 return(MAGICKCORE_QUANTUM_DEPTH);
756 if (strEQ(name,"QuantumDepth"))
757 return(MAGICKCORE_QUANTUM_DEPTH);
758 if (strEQ(name,"QuantumRange"))
759 return(QuantumRange);
760 break;
761 }
762 case 'R':
763 {
764 if (strEQ(name,"ResourceLimitError"))
765 return(ResourceLimitError);
766 if (strEQ(name,"ResourceLimitWarning"))
767 return(ResourceLimitWarning);
768 if (strEQ(name,"RegistryError"))
769 return(RegistryError);
770 if (strEQ(name,"RegistryWarning"))
771 return(RegistryWarning);
772 break;
773 }
774 case 'S':
775 {
776 if (strEQ(name,"StreamError"))
777 return(StreamError);
778 if (strEQ(name,"StreamWarning"))
779 return(StreamWarning);
780 if (strEQ(name,"Success"))
781 return(0);
782 break;
783 }
784 case 'T':
785 {
786 if (strEQ(name,"Transparent"))
787 return(TransparentAlpha);
788 if (strEQ(name,"TypeError"))
789 return(TypeError);
790 if (strEQ(name,"TypeWarning"))
791 return(TypeWarning);
792 break;
793 }
794 case 'W':
795 {
796 if (strEQ(name,"WarningException"))
797 return(WarningException);
798 break;
799 }
800 case 'X':
801 {
802 if (strEQ(name,"XServerError"))
803 return(XServerError);
804 if (strEQ(name,"XServerWarning"))
805 return(XServerWarning);
806 break;
807 }
808 }
809 errno=EINVAL;
810 return(0);
811}
812
813/*
814%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
815% %
816% %
817% %
818% D e s t r o y P a c k a g e I n f o %
819% %
820% %
821% %
822%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
823%
824% Method DestroyPackageInfo frees a previously created info structure.
825%
826% The format of the DestroyPackageInfo routine is:
827%
828% DestroyPackageInfo(struct PackageInfo *info)
829%
830% A description of each parameter follows:
831%
832% o info: a structure of type info.
833%
834*/
835static void DestroyPackageInfo(struct PackageInfo *info)
836{
837 info->image_info=DestroyImageInfo(info->image_info);
838 info=(struct PackageInfo *) RelinquishMagickMemory(info);
839}
840
841/*
842%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
843% %
844% %
845% %
846% G e t L i s t %
847% %
848% %
849% %
850%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
851%
852% Method GetList is recursively called by SetupList to traverse the
853% Image__Magick reference. If building an reference_vector (see SetupList),
854% *current is the current position in *reference_vector and *last is the final
855% entry in *reference_vector.
856%
857% The format of the GetList routine is:
858%
859% GetList(info)
860%
861% A description of each parameter follows:
862%
863% o info: a structure of type info.
864%
865*/
866static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
867 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
868{
869 Image
870 *image;
871
872 if (reference == (SV *) NULL)
873 return(NULL);
874 switch (SvTYPE(reference))
875 {
876 case SVt_PVAV:
877 {
878 AV
879 *av;
880
881 Image
882 *head,
883 *previous;
884
885 register ssize_t
886 i;
887
888 ssize_t
889 n;
890
891 /*
892 Array of images.
893 */
894 previous=(Image *) NULL;
895 head=(Image *) NULL;
896 av=(AV *) reference;
897 n=av_len(av);
898 for (i=0; i <= n; i++)
899 {
900 SV
901 **rv;
902
903 rv=av_fetch(av,i,0);
904 if (rv && *rv && sv_isobject(*rv))
905 {
906 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
907 exception);
908 if (image == (Image *) NULL)
909 continue;
910 if (image == previous)
911 {
912 image=CloneImage(image,0,0,MagickTrue,exception);
913 if (image == (Image *) NULL)
914 return(NULL);
915 }
916 image->previous=previous;
917 *(previous ? &previous->next : &head)=image;
918 for (previous=image; previous->next; previous=previous->next) ;
919 }
920 }
921 return(head);
922 }
923 case SVt_PVMG:
924 {
925 /*
926 Blessed scalar, one image.
927 */
928 image=INT2PTR(Image *,SvIV(reference));
929 if (image == (Image *) NULL)
930 return(NULL);
931 image->previous=(Image *) NULL;
932 image->next=(Image *) NULL;
933 if (reference_vector)
934 {
935 if (*current == *last)
936 {
937 *last+=256;
938 if (*reference_vector == (SV **) NULL)
939 *reference_vector=(SV **) AcquireQuantumMemory(*last,
940 sizeof(*reference_vector));
941 else
942 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
943 *last,sizeof(*reference_vector));
944 }
945 if (*reference_vector == (SV **) NULL)
946 {
947 ThrowPerlException(exception,ResourceLimitError,
948 "MemoryAllocationFailed",PackageName);
949 return((Image *) NULL);
950 }
951 (*reference_vector)[*current]=reference;
952 (*reference_vector)[++(*current)]=NULL;
953 }
954 return(image);
955 }
956 default:
957 break;
958 }
959 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
960 (double) SvTYPE(reference));
961 return((Image *) NULL);
962}
963
964/*
965%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
966% %
967% %
968% %
969% G e t P a c k a g e I n f o %
970% %
971% %
972% %
973%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
974%
975% Method GetPackageInfo looks up or creates an info structure for the given
976% Image__Magick reference. If it does create a new one, the information in
977% package_info is used to initialize it.
978%
979% The format of the GetPackageInfo routine is:
980%
981% struct PackageInfo *GetPackageInfo(void *reference,
982% struct PackageInfo *package_info,ExceptionInfo *exception)
983%
984% A description of each parameter follows:
985%
986% o info: a structure of type info.
987%
988% o exception: Return any errors or warnings in this structure.
989%
990*/
991static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
992 struct PackageInfo *package_info,ExceptionInfo *exception)
993{
994 char
cristy151b66d2015-04-15 10:50:31 +0000995 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +0000996
997 struct PackageInfo
998 *clone_info;
999
1000 SV
1001 *sv;
1002
cristy151b66d2015-04-15 10:50:31 +00001003 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00001004 PackageName,XS_VERSION,reference);
1005 sv=perl_get_sv(message,(TRUE | 0x02));
1006 if (sv == (SV *) NULL)
1007 {
1008 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1009 message);
1010 return(package_info);
1011 }
1012 if (SvREFCNT(sv) == 0)
1013 (void) SvREFCNT_inc(sv);
1014 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1015 return(clone_info);
1016 clone_info=ClonePackageInfo(package_info,exception);
1017 sv_setiv(sv,PTR2IV(clone_info));
1018 return(clone_info);
1019}
1020
1021/*
1022%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1023% %
1024% %
1025% %
1026% S e t A t t r i b u t e %
1027% %
1028% %
1029% %
1030%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1031%
1032% SetAttribute() sets the attribute to the value in sval. This can change
1033% either or both of image or info.
1034%
1035% The format of the SetAttribute routine is:
1036%
1037% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1038% SV *sval,ExceptionInfo *exception)
1039%
1040% A description of each parameter follows:
1041%
1042% o list: a list of strings.
1043%
1044% o string: a character string.
1045%
1046*/
1047
1048static double SiPrefixToDoubleInterval(const char *string,const double interval)
1049{
1050 char
1051 *q;
1052
1053 double
1054 value;
1055
1056 value=InterpretSiPrefixValue(string,&q);
1057 if (*q == '%')
1058 value*=interval/100.0;
1059 return(value);
1060}
1061
1062static inline double StringToDouble(const char *string,char **sentinal)
1063{
1064 return(InterpretLocaleValue(string,sentinal));
1065}
1066
1067static double StringToDoubleInterval(const char *string,const double interval)
1068{
1069 char
1070 *q;
1071
1072 double
1073 value;
1074
1075 value=InterpretLocaleValue(string,&q);
1076 if (*q == '%')
1077 value*=interval/100.0;
1078 return(value);
1079}
1080
1081static inline ssize_t StringToLong(const char *value)
1082{
1083 return(strtol(value,(char **) NULL,10));
1084}
1085
1086static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1087 const char *attribute,SV *sval,ExceptionInfo *exception)
1088{
1089 GeometryInfo
1090 geometry_info;
1091
1092 long
1093 x,
1094 y;
1095
1096 PixelInfo
1097 pixel;
1098
1099 MagickStatusType
1100 flags;
1101
1102 PixelInfo
1103 *color,
1104 target_color;
1105
1106 ssize_t
1107 sp;
1108
1109 switch (*attribute)
1110 {
1111 case 'A':
1112 case 'a':
1113 {
1114 if (LocaleCompare(attribute,"adjoin") == 0)
1115 {
1116 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1117 SvPV(sval,na)) : SvIV(sval);
1118 if (sp < 0)
1119 {
1120 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1121 SvPV(sval,na));
1122 break;
1123 }
1124 if (info)
1125 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1126 break;
1127 }
1128 if (LocaleCompare(attribute,"alpha") == 0)
1129 {
1130 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1131 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1132 if (sp < 0)
1133 {
1134 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1135 SvPV(sval,na));
1136 break;
1137 }
1138 for ( ; image; image=image->next)
1139 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1140 exception);
1141 break;
1142 }
1143 if (LocaleCompare(attribute,"antialias") == 0)
1144 {
1145 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1146 SvPV(sval,na)) : SvIV(sval);
1147 if (sp < 0)
1148 {
1149 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1150 SvPV(sval,na));
1151 break;
1152 }
1153 if (info)
1154 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1155 break;
1156 }
1157 if (LocaleCompare(attribute,"area-limit") == 0)
1158 {
1159 MagickSizeType
1160 limit;
1161
1162 limit=MagickResourceInfinity;
1163 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1164 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1165 100.0);
1166 (void) SetMagickResourceLimit(AreaResource,limit);
1167 break;
1168 }
1169 if (LocaleCompare(attribute,"attenuate") == 0)
1170 {
1171 if (info)
1172 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1173 break;
1174 }
1175 if (LocaleCompare(attribute,"authenticate") == 0)
1176 {
1177 if (info)
1178 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1179 break;
1180 }
1181 if (info)
1182 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1183 for ( ; image; image=image->next)
1184 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1185 break;
1186 }
1187 case 'B':
1188 case 'b':
1189 {
1190 if (LocaleCompare(attribute,"background") == 0)
1191 {
1192 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1193 exception);
1194 if (info)
1195 info->image_info->background_color=target_color;
1196 for ( ; image; image=image->next)
1197 image->background_color=target_color;
1198 break;
1199 }
1200 if (LocaleCompare(attribute,"blue-primary") == 0)
1201 {
1202 for ( ; image; image=image->next)
1203 {
1204 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1205 image->chromaticity.blue_primary.x=geometry_info.rho;
1206 image->chromaticity.blue_primary.y=geometry_info.sigma;
1207 if ((flags & SigmaValue) == 0)
1208 image->chromaticity.blue_primary.y=
1209 image->chromaticity.blue_primary.x;
1210 }
1211 break;
1212 }
1213 if (LocaleCompare(attribute,"bordercolor") == 0)
1214 {
1215 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1216 exception);
1217 if (info)
1218 info->image_info->border_color=target_color;
1219 for ( ; image; image=image->next)
1220 image->border_color=target_color;
1221 break;
1222 }
1223 if (info)
1224 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1225 for ( ; image; image=image->next)
1226 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1227 break;
1228 }
1229 case 'C':
1230 case 'c':
1231 {
1232 if (LocaleCompare(attribute,"cache-threshold") == 0)
1233 {
1234 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1235 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1236 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1237 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1238 break;
1239 }
1240 if (LocaleCompare(attribute,"clip-mask") == 0)
1241 {
1242 Image
1243 *clip_mask;
1244
1245 clip_mask=(Image *) NULL;
1246 if (SvPOK(sval))
1247 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1248 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001249 SetImageMask(image,ReadPixelMask,clip_mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001250 break;
1251 }
1252 if (LocaleNCompare(attribute,"colormap",8) == 0)
1253 {
1254 for ( ; image; image=image->next)
1255 {
1256 int
1257 items;
1258
1259 long
1260 i;
1261
1262 if (image->storage_class == DirectClass)
1263 continue;
1264 i=0;
1265 items=sscanf(attribute,"%*[^[][%ld",&i);
1266 (void) items;
1267 if (i > (ssize_t) image->colors)
1268 i%=image->colors;
1269 if ((strchr(SvPV(sval,na),',') == 0) ||
1270 (strchr(SvPV(sval,na),')') != 0))
1271 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1272 image->colormap+i,exception);
1273 else
1274 {
1275 color=image->colormap+i;
1276 pixel.red=color->red;
1277 pixel.green=color->green;
1278 pixel.blue=color->blue;
1279 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1280 pixel.red=geometry_info.rho;
1281 pixel.green=geometry_info.sigma;
1282 pixel.blue=geometry_info.xi;
1283 color->red=ClampToQuantum(pixel.red);
1284 color->green=ClampToQuantum(pixel.green);
1285 color->blue=ClampToQuantum(pixel.blue);
1286 }
1287 }
1288 break;
1289 }
1290 if (LocaleCompare(attribute,"colorspace") == 0)
1291 {
1292 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1293 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1294 if (sp < 0)
1295 {
1296 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1297 SvPV(sval,na));
1298 break;
1299 }
1300 for ( ; image; image=image->next)
1301 (void) TransformImageColorspace(image,(ColorspaceType) sp,
1302 exception);
1303 break;
1304 }
1305 if (LocaleCompare(attribute,"comment") == 0)
1306 {
1307 for ( ; image; image=image->next)
1308 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1309 info ? info->image_info : (ImageInfo *) NULL,image,
1310 SvPV(sval,na),exception),exception);
1311 break;
1312 }
1313 if (LocaleCompare(attribute,"compression") == 0)
1314 {
1315 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1316 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1317 if (sp < 0)
1318 {
1319 ThrowPerlException(exception,OptionError,
1320 "UnrecognizedImageCompression",SvPV(sval,na));
1321 break;
1322 }
1323 if (info)
1324 info->image_info->compression=(CompressionType) sp;
1325 for ( ; image; image=image->next)
1326 image->compression=(CompressionType) sp;
1327 break;
1328 }
1329 if (info)
1330 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1331 for ( ; image; image=image->next)
1332 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1333 break;
1334 }
1335 case 'D':
1336 case 'd':
1337 {
1338 if (LocaleCompare(attribute,"debug") == 0)
1339 {
1340 SetLogEventMask(SvPV(sval,na));
1341 break;
1342 }
1343 if (LocaleCompare(attribute,"delay") == 0)
1344 {
1345 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1346 for ( ; image; image=image->next)
1347 {
1348 image->delay=(size_t) floor(geometry_info.rho+0.5);
1349 if ((flags & SigmaValue) != 0)
1350 image->ticks_per_second=(ssize_t)
1351 floor(geometry_info.sigma+0.5);
1352 }
1353 break;
1354 }
1355 if (LocaleCompare(attribute,"disk-limit") == 0)
1356 {
1357 MagickSizeType
1358 limit;
1359
1360 limit=MagickResourceInfinity;
1361 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1362 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1363 100.0);
1364 (void) SetMagickResourceLimit(DiskResource,limit);
1365 break;
1366 }
1367 if (LocaleCompare(attribute,"density") == 0)
1368 {
1369 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1370 {
1371 ThrowPerlException(exception,OptionError,"MissingGeometry",
1372 SvPV(sval,na));
1373 break;
1374 }
1375 if (info)
1376 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1377 for ( ; image; image=image->next)
1378 {
1379 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1380 image->resolution.x=geometry_info.rho;
1381 image->resolution.y=geometry_info.sigma;
1382 if ((flags & SigmaValue) == 0)
1383 image->resolution.y=image->resolution.x;
1384 }
1385 break;
1386 }
1387 if (LocaleCompare(attribute,"depth") == 0)
1388 {
1389 if (info)
1390 info->image_info->depth=SvIV(sval);
1391 for ( ; image; image=image->next)
1392 (void) SetImageDepth(image,SvIV(sval),exception);
1393 break;
1394 }
1395 if (LocaleCompare(attribute,"dispose") == 0)
1396 {
1397 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1398 SvPV(sval,na)) : SvIV(sval);
1399 if (sp < 0)
1400 {
1401 ThrowPerlException(exception,OptionError,
1402 "UnrecognizedDisposeMethod",SvPV(sval,na));
1403 break;
1404 }
1405 for ( ; image; image=image->next)
1406 image->dispose=(DisposeType) sp;
1407 break;
1408 }
1409 if (LocaleCompare(attribute,"dither") == 0)
1410 {
1411 if (info)
1412 {
1413 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1414 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1415 if (sp < 0)
1416 {
1417 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1418 SvPV(sval,na));
1419 break;
1420 }
1421 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1422 }
1423 break;
1424 }
1425 if (LocaleCompare(attribute,"display") == 0)
1426 {
1427 display:
1428 if (info)
1429 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1430 break;
1431 }
1432 if (info)
1433 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1434 for ( ; image; image=image->next)
1435 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1436 break;
1437 }
1438 case 'E':
1439 case 'e':
1440 {
1441 if (LocaleCompare(attribute,"endian") == 0)
1442 {
1443 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1444 SvPV(sval,na)) : SvIV(sval);
1445 if (sp < 0)
1446 {
1447 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1448 SvPV(sval,na));
1449 break;
1450 }
1451 if (info)
1452 info->image_info->endian=(EndianType) sp;
1453 for ( ; image; image=image->next)
1454 image->endian=(EndianType) sp;
1455 break;
1456 }
1457 if (LocaleCompare(attribute,"extract") == 0)
1458 {
1459 /*
1460 Set image extract geometry.
1461 */
1462 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1463 break;
1464 }
1465 if (info)
1466 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1467 for ( ; image; image=image->next)
1468 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1469 break;
1470 }
1471 case 'F':
1472 case 'f':
1473 {
1474 if (LocaleCompare(attribute,"filename") == 0)
1475 {
1476 if (info)
1477 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001478 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001479 for ( ; image; image=image->next)
1480 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001481 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001482 break;
1483 }
1484 if (LocaleCompare(attribute,"file") == 0)
1485 {
1486 FILE
1487 *file;
1488
1489 PerlIO
1490 *io_info;
1491
1492 if (info == (struct PackageInfo *) NULL)
1493 break;
1494 io_info=IoIFP(sv_2io(sval));
1495 if (io_info == (PerlIO *) NULL)
1496 {
1497 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1498 PackageName);
1499 break;
1500 }
1501 file=PerlIO_findFILE(io_info);
1502 if (file == (FILE *) NULL)
1503 {
1504 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1505 PackageName);
1506 break;
1507 }
1508 SetImageInfoFile(info->image_info,file);
1509 break;
1510 }
1511 if (LocaleCompare(attribute,"fill") == 0)
1512 {
1513 if (info)
1514 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1515 break;
1516 }
1517 if (LocaleCompare(attribute,"font") == 0)
1518 {
1519 if (info)
1520 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1521 break;
1522 }
1523 if (LocaleCompare(attribute,"foreground") == 0)
1524 break;
1525 if (LocaleCompare(attribute,"fuzz") == 0)
1526 {
1527 if (info)
1528 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1529 QuantumRange+1.0);
1530 for ( ; image; image=image->next)
1531 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1532 QuantumRange+1.0);
1533 break;
1534 }
1535 if (info)
1536 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1537 for ( ; image; image=image->next)
1538 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1539 break;
1540 }
1541 case 'G':
1542 case 'g':
1543 {
1544 if (LocaleCompare(attribute,"gamma") == 0)
1545 {
1546 for ( ; image; image=image->next)
1547 image->gamma=SvNV(sval);
1548 break;
1549 }
1550 if (LocaleCompare(attribute,"gravity") == 0)
1551 {
1552 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1553 SvPV(sval,na)) : SvIV(sval);
1554 if (sp < 0)
1555 {
1556 ThrowPerlException(exception,OptionError,
1557 "UnrecognizedGravityType",SvPV(sval,na));
1558 break;
1559 }
1560 if (info)
1561 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1562 for ( ; image; image=image->next)
1563 image->gravity=(GravityType) sp;
1564 break;
1565 }
1566 if (LocaleCompare(attribute,"green-primary") == 0)
1567 {
1568 for ( ; image; image=image->next)
1569 {
1570 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1571 image->chromaticity.green_primary.x=geometry_info.rho;
1572 image->chromaticity.green_primary.y=geometry_info.sigma;
1573 if ((flags & SigmaValue) == 0)
1574 image->chromaticity.green_primary.y=
1575 image->chromaticity.green_primary.x;
1576 }
1577 break;
1578 }
1579 if (info)
1580 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1581 for ( ; image; image=image->next)
1582 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1583 break;
1584 }
1585 case 'I':
1586 case 'i':
1587 {
1588 if (LocaleNCompare(attribute,"index",5) == 0)
1589 {
1590 int
1591 items;
1592
1593 long
1594 index;
1595
1596 register Quantum
1597 *q;
1598
1599 CacheView
1600 *image_view;
1601
1602 for ( ; image; image=image->next)
1603 {
1604 if (image->storage_class != PseudoClass)
1605 continue;
1606 x=0;
1607 y=0;
1608 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1609 (void) items;
1610 image_view=AcquireAuthenticCacheView(image,exception);
1611 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1612 if (q != (Quantum *) NULL)
1613 {
1614 items=sscanf(SvPV(sval,na),"%ld",&index);
1615 if ((index >= 0) && (index < (ssize_t) image->colors))
1616 SetPixelIndex(image,index,q);
1617 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1618 }
1619 image_view=DestroyCacheView(image_view);
1620 }
1621 break;
1622 }
1623 if (LocaleCompare(attribute,"iterations") == 0)
1624 {
1625 iterations:
1626 for ( ; image; image=image->next)
1627 image->iterations=SvIV(sval);
1628 break;
1629 }
1630 if (LocaleCompare(attribute,"interlace") == 0)
1631 {
1632 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1633 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1634 if (sp < 0)
1635 {
1636 ThrowPerlException(exception,OptionError,
1637 "UnrecognizedInterlaceType",SvPV(sval,na));
1638 break;
1639 }
1640 if (info)
1641 info->image_info->interlace=(InterlaceType) sp;
1642 for ( ; image; image=image->next)
1643 image->interlace=(InterlaceType) sp;
1644 break;
1645 }
1646 if (info)
1647 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1648 for ( ; image; image=image->next)
1649 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1650 break;
1651 }
1652 case 'L':
1653 case 'l':
1654 {
1655 if (LocaleCompare(attribute,"label") == 0)
1656 {
1657 for ( ; image; image=image->next)
1658 (void) SetImageProperty(image,"label",InterpretImageProperties(
1659 info ? info->image_info : (ImageInfo *) NULL,image,
1660 SvPV(sval,na),exception),exception);
1661 break;
1662 }
1663 if (LocaleCompare(attribute,"loop") == 0)
1664 goto iterations;
1665 if (info)
1666 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1667 for ( ; image; image=image->next)
1668 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1669 break;
1670 }
1671 case 'M':
1672 case 'm':
1673 {
1674 if (LocaleCompare(attribute,"magick") == 0)
1675 {
1676 if (info)
cristy151b66d2015-04-15 10:50:31 +00001677 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00001678 "%s:",SvPV(sval,na));
1679 for ( ; image; image=image->next)
cristy151b66d2015-04-15 10:50:31 +00001680 (void) CopyMagickString(image->magick,SvPV(sval,na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001681 break;
1682 }
1683 if (LocaleCompare(attribute,"map-limit") == 0)
1684 {
1685 MagickSizeType
1686 limit;
1687
1688 limit=MagickResourceInfinity;
1689 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1690 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1691 100.0);
1692 (void) SetMagickResourceLimit(MapResource,limit);
1693 break;
1694 }
1695 if (LocaleCompare(attribute,"mask") == 0)
1696 {
1697 Image
1698 *mask;
1699
1700 mask=(Image *) NULL;
1701 if (SvPOK(sval))
1702 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1703 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001704 SetImageMask(image,ReadPixelMask,mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001705 break;
1706 }
1707 if (LocaleCompare(attribute,"mattecolor") == 0)
1708 {
1709 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1710 exception);
1711 if (info)
Cristy8645e042016-02-03 16:35:29 -05001712 info->image_info->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001713 for ( ; image; image=image->next)
Cristy8645e042016-02-03 16:35:29 -05001714 image->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001715 break;
1716 }
1717 if (LocaleCompare(attribute,"matte") == 0)
1718 {
1719 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1720 SvPV(sval,na)) : SvIV(sval);
1721 if (sp < 0)
1722 {
1723 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1724 SvPV(sval,na));
1725 break;
1726 }
1727 for ( ; image; image=image->next)
1728 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1729 break;
1730 }
1731 if (LocaleCompare(attribute,"memory-limit") == 0)
1732 {
1733 MagickSizeType
1734 limit;
1735
1736 limit=MagickResourceInfinity;
1737 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1738 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1739 100.0);
1740 (void) SetMagickResourceLimit(MemoryResource,limit);
1741 break;
1742 }
1743 if (LocaleCompare(attribute,"monochrome") == 0)
1744 {
1745 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1746 SvPV(sval,na)) : SvIV(sval);
1747 if (sp < 0)
1748 {
1749 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1750 SvPV(sval,na));
1751 break;
1752 }
1753 if (info)
1754 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1755 for ( ; image; image=image->next)
1756 (void) SetImageType(image,BilevelType,exception);
1757 break;
1758 }
1759 if (info)
1760 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1761 for ( ; image; image=image->next)
1762 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1763 break;
1764 }
1765 case 'O':
1766 case 'o':
1767 {
1768 if (LocaleCompare(attribute,"option") == 0)
1769 {
1770 if (info)
1771 DefineImageOption(info->image_info,SvPV(sval,na));
1772 break;
1773 }
1774 if (LocaleCompare(attribute,"orientation") == 0)
1775 {
1776 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1777 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1778 if (sp < 0)
1779 {
1780 ThrowPerlException(exception,OptionError,
1781 "UnrecognizedOrientationType",SvPV(sval,na));
1782 break;
1783 }
1784 if (info)
1785 info->image_info->orientation=(OrientationType) sp;
1786 for ( ; image; image=image->next)
1787 image->orientation=(OrientationType) sp;
1788 break;
1789 }
1790 if (info)
1791 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1792 for ( ; image; image=image->next)
1793 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1794 break;
1795 }
1796 case 'P':
1797 case 'p':
1798 {
1799 if (LocaleCompare(attribute,"page") == 0)
1800 {
1801 char
1802 *geometry;
1803
1804 geometry=GetPageGeometry(SvPV(sval,na));
1805 if (info)
1806 (void) CloneString(&info->image_info->page,geometry);
1807 for ( ; image; image=image->next)
1808 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1809 geometry=(char *) RelinquishMagickMemory(geometry);
1810 break;
1811 }
1812 if (LocaleNCompare(attribute,"pixel",5) == 0)
1813 {
1814 int
1815 items;
1816
1817 PixelInfo
1818 pixel;
1819
1820 register Quantum
1821 *q;
1822
1823 CacheView
1824 *image_view;
1825
1826 for ( ; image; image=image->next)
1827 {
1828 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1829 break;
1830 x=0;
1831 y=0;
1832 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1833 (void) items;
1834 image_view=AcquireVirtualCacheView(image,exception);
1835 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1836 if (q != (Quantum *) NULL)
1837 {
1838 if ((strchr(SvPV(sval,na),',') == 0) ||
1839 (strchr(SvPV(sval,na),')') != 0))
1840 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1841 &pixel,exception);
1842 else
1843 {
1844 GetPixelInfo(image,&pixel);
1845 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1846 pixel.red=geometry_info.rho;
1847 if ((flags & SigmaValue) != 0)
1848 pixel.green=geometry_info.sigma;
1849 if ((flags & XiValue) != 0)
1850 pixel.blue=geometry_info.xi;
1851 if ((flags & PsiValue) != 0)
1852 pixel.alpha=geometry_info.psi;
1853 if ((flags & ChiValue) != 0)
1854 pixel.black=geometry_info.chi;
1855 }
1856 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1857 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1858 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1859 if (image->colorspace == CMYKColorspace)
1860 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1861 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1862 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1863 }
1864 image_view=DestroyCacheView(image_view);
1865 }
1866 break;
1867 }
1868 if (LocaleCompare(attribute,"pointsize") == 0)
1869 {
1870 if (info)
1871 {
1872 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1873 info->image_info->pointsize=geometry_info.rho;
1874 }
1875 break;
1876 }
1877 if (LocaleCompare(attribute,"preview") == 0)
1878 {
1879 sp=SvPOK(sval) ? ParseCommandOption(MagickPreviewOptions,MagickFalse,
1880 SvPV(sval,na)) : SvIV(sval);
1881 if (sp < 0)
1882 {
1883 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1884 SvPV(sval,na));
1885 break;
1886 }
1887 if (info)
1888 info->image_info->preview_type=(PreviewType) sp;
1889 break;
1890 }
1891 if (info)
1892 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1893 for ( ; image; image=image->next)
1894 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1895 break;
1896 }
1897 case 'Q':
1898 case 'q':
1899 {
1900 if (LocaleCompare(attribute,"quality") == 0)
1901 {
1902 if (info)
1903 info->image_info->quality=SvIV(sval);
1904 for ( ; image; image=image->next)
1905 image->quality=SvIV(sval);
1906 break;
1907 }
1908 if (info)
1909 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1910 for ( ; image; image=image->next)
1911 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1912 break;
1913 }
1914 case 'R':
1915 case 'r':
1916 {
cristyc0fe4752015-07-27 18:02:39 +00001917 if (LocaleCompare(attribute,"read-mask") == 0)
1918 {
1919 Image
1920 *mask;
1921
1922 mask=(Image *) NULL;
1923 if (SvPOK(sval))
1924 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1925 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001926 SetImageMask(image,ReadPixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00001927 break;
1928 }
cristy4a3ce0a2013-08-03 20:06:59 +00001929 if (LocaleCompare(attribute,"red-primary") == 0)
1930 {
1931 for ( ; image; image=image->next)
1932 {
1933 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1934 image->chromaticity.red_primary.x=geometry_info.rho;
1935 image->chromaticity.red_primary.y=geometry_info.sigma;
1936 if ((flags & SigmaValue) == 0)
1937 image->chromaticity.red_primary.y=
1938 image->chromaticity.red_primary.x;
1939 }
1940 break;
1941 }
1942 if (LocaleCompare(attribute,"render") == 0)
1943 {
1944 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1945 SvPV(sval,na)) : SvIV(sval);
1946 if (sp < 0)
1947 {
1948 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1949 SvPV(sval,na));
1950 break;
1951 }
1952 for ( ; image; image=image->next)
1953 image->rendering_intent=(RenderingIntent) sp;
1954 break;
1955 }
1956 if (LocaleCompare(attribute,"repage") == 0)
1957 {
1958 RectangleInfo
1959 geometry;
1960
1961 for ( ; image; image=image->next)
1962 {
1963 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1964 if ((flags & WidthValue) != 0)
1965 {
1966 if ((flags & HeightValue) == 0)
1967 geometry.height=geometry.width;
1968 image->page.width=geometry.width;
1969 image->page.height=geometry.height;
1970 }
1971 if ((flags & AspectValue) != 0)
1972 {
1973 if ((flags & XValue) != 0)
1974 image->page.x+=geometry.x;
1975 if ((flags & YValue) != 0)
1976 image->page.y+=geometry.y;
1977 }
1978 else
1979 {
1980 if ((flags & XValue) != 0)
1981 {
1982 image->page.x=geometry.x;
1983 if (((flags & WidthValue) != 0) && (geometry.x > 0))
1984 image->page.width=image->columns+geometry.x;
1985 }
1986 if ((flags & YValue) != 0)
1987 {
1988 image->page.y=geometry.y;
1989 if (((flags & HeightValue) != 0) && (geometry.y > 0))
1990 image->page.height=image->rows+geometry.y;
1991 }
1992 }
1993 }
1994 break;
1995 }
1996 if (info)
1997 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1998 for ( ; image; image=image->next)
1999 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2000 break;
2001 }
2002 case 'S':
2003 case 's':
2004 {
2005 if (LocaleCompare(attribute,"sampling-factor") == 0)
2006 {
2007 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2008 {
2009 ThrowPerlException(exception,OptionError,"MissingGeometry",
2010 SvPV(sval,na));
2011 break;
2012 }
2013 if (info)
2014 (void) CloneString(&info->image_info->sampling_factor,
2015 SvPV(sval,na));
2016 break;
2017 }
2018 if (LocaleCompare(attribute,"scene") == 0)
2019 {
2020 for ( ; image; image=image->next)
2021 image->scene=SvIV(sval);
2022 break;
2023 }
2024 if (LocaleCompare(attribute,"server") == 0)
2025 goto display;
2026 if (LocaleCompare(attribute,"size") == 0)
2027 {
2028 if (info)
2029 {
2030 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2031 {
2032 ThrowPerlException(exception,OptionError,"MissingGeometry",
2033 SvPV(sval,na));
2034 break;
2035 }
2036 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2037 }
2038 break;
2039 }
2040 if (LocaleCompare(attribute,"stroke") == 0)
2041 {
2042 if (info)
2043 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2044 break;
2045 }
2046 if (info)
2047 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2048 for ( ; image; image=image->next)
2049 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2050 break;
2051 }
2052 case 'T':
2053 case 't':
2054 {
2055 if (LocaleCompare(attribute,"texture") == 0)
2056 {
2057 if (info)
2058 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2059 break;
2060 }
2061 if (LocaleCompare(attribute,"thread-limit") == 0)
2062 {
2063 MagickSizeType
2064 limit;
2065
2066 limit=MagickResourceInfinity;
2067 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2068 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2069 100.0);
2070 (void) SetMagickResourceLimit(ThreadResource,limit);
2071 break;
2072 }
2073 if (LocaleCompare(attribute,"tile-offset") == 0)
2074 {
2075 char
2076 *geometry;
2077
2078 geometry=GetPageGeometry(SvPV(sval,na));
2079 if (info)
2080 (void) CloneString(&info->image_info->page,geometry);
2081 for ( ; image; image=image->next)
2082 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2083 exception);
2084 geometry=(char *) RelinquishMagickMemory(geometry);
2085 break;
2086 }
2087 if (LocaleCompare(attribute,"time-limit") == 0)
2088 {
2089 MagickSizeType
2090 limit;
2091
2092 limit=MagickResourceInfinity;
2093 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2094 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2095 100.0);
2096 (void) SetMagickResourceLimit(TimeResource,limit);
2097 break;
2098 }
2099 if (LocaleCompare(attribute,"transparent-color") == 0)
2100 {
2101 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2102 exception);
2103 if (info)
2104 info->image_info->transparent_color=target_color;
2105 for ( ; image; image=image->next)
2106 image->transparent_color=target_color;
2107 break;
2108 }
2109 if (LocaleCompare(attribute,"type") == 0)
2110 {
2111 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2112 SvPV(sval,na)) : SvIV(sval);
2113 if (sp < 0)
2114 {
2115 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2116 SvPV(sval,na));
2117 break;
2118 }
2119 if (info)
2120 info->image_info->type=(ImageType) sp;
2121 for ( ; image; image=image->next)
2122 SetImageType(image,(ImageType) sp,exception);
2123 break;
2124 }
2125 if (info)
2126 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2127 for ( ; image; image=image->next)
2128 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2129 break;
2130 }
2131 case 'U':
2132 case 'u':
2133 {
2134 if (LocaleCompare(attribute,"units") == 0)
2135 {
2136 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2137 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2138 if (sp < 0)
2139 {
2140 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2141 SvPV(sval,na));
2142 break;
2143 }
2144 if (info)
2145 info->image_info->units=(ResolutionType) sp;
2146 for ( ; image; image=image->next)
2147 {
2148 ResolutionType
2149 units;
2150
2151 units=(ResolutionType) sp;
2152 if (image->units != units)
2153 switch (image->units)
2154 {
2155 case UndefinedResolution:
2156 case PixelsPerInchResolution:
2157 {
2158 if (units == PixelsPerCentimeterResolution)
2159 {
2160 image->resolution.x*=2.54;
2161 image->resolution.y*=2.54;
2162 }
2163 break;
2164 }
2165 case PixelsPerCentimeterResolution:
2166 {
2167 if (units == PixelsPerInchResolution)
2168 {
2169 image->resolution.x/=2.54;
2170 image->resolution.y/=2.54;
2171 }
2172 break;
2173 }
2174 }
2175 image->units=units;
2176 }
2177 break;
2178 }
2179 if (info)
2180 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2181 for ( ; image; image=image->next)
2182 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2183 break;
2184 }
2185 case 'V':
2186 case 'v':
2187 {
2188 if (LocaleCompare(attribute,"verbose") == 0)
2189 {
2190 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2191 SvPV(sval,na)) : SvIV(sval);
2192 if (sp < 0)
2193 {
2194 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2195 SvPV(sval,na));
2196 break;
2197 }
2198 if (info)
2199 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2200 break;
2201 }
cristy4a3ce0a2013-08-03 20:06:59 +00002202 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2203 {
2204 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2205 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2206 if (sp < 0)
2207 {
2208 ThrowPerlException(exception,OptionError,
2209 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2210 break;
2211 }
2212 for ( ; image; image=image->next)
2213 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2214 break;
2215 }
2216 if (info)
2217 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2218 for ( ; image; image=image->next)
2219 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2220 break;
2221 }
2222 case 'W':
2223 case 'w':
2224 {
2225 if (LocaleCompare(attribute,"white-point") == 0)
2226 {
2227 for ( ; image; image=image->next)
2228 {
2229 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2230 image->chromaticity.white_point.x=geometry_info.rho;
2231 image->chromaticity.white_point.y=geometry_info.sigma;
2232 if ((flags & SigmaValue) == 0)
2233 image->chromaticity.white_point.y=
2234 image->chromaticity.white_point.x;
2235 }
2236 break;
2237 }
cristyc0fe4752015-07-27 18:02:39 +00002238 if (LocaleCompare(attribute,"write-mask") == 0)
2239 {
2240 Image
2241 *mask;
2242
2243 mask=(Image *) NULL;
2244 if (SvPOK(sval))
2245 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2246 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002247 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002248 break;
2249 }
cristy4a3ce0a2013-08-03 20:06:59 +00002250 if (info)
2251 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2252 for ( ; image; image=image->next)
2253 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2254 break;
2255 }
2256 default:
2257 {
2258 if (info)
2259 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2260 for ( ; image; image=image->next)
2261 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2262 break;
2263 }
2264 }
2265}
2266
2267/*
2268%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2269% %
2270% %
2271% %
2272% S e t u p L i s t %
2273% %
2274% %
2275% %
2276%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2277%
2278% Method SetupList returns the list of all the images linked by their
2279% image->next and image->previous link lists for use with ImageMagick. If
2280% info is non-NULL, an info structure is returned in *info. If
2281% reference_vector is non-NULL,an array of SV* are returned in
2282% *reference_vector. Reference_vector is used when the images are going to be
2283% replaced with new Image*'s.
2284%
2285% The format of the SetupList routine is:
2286%
2287% Image *SetupList(SV *reference,struct PackageInfo **info,
2288% SV ***reference_vector,ExceptionInfo *exception)
2289%
2290% A description of each parameter follows:
2291%
2292% o list: a list of strings.
2293%
2294% o string: a character string.
2295%
2296% o exception: Return any errors or warnings in this structure.
2297%
2298*/
2299static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2300 SV ***reference_vector,ExceptionInfo *exception)
2301{
2302 Image
2303 *image;
2304
2305 ssize_t
2306 current,
2307 last;
2308
2309 if (reference_vector)
2310 *reference_vector=NULL;
2311 if (info)
2312 *info=NULL;
2313 current=0;
2314 last=0;
2315 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2316 if (info && (SvTYPE(reference) == SVt_PVAV))
2317 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2318 exception);
2319 return(image);
2320}
2321
2322/*
2323%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2324% %
2325% %
2326% %
2327% s t r E Q c a s e %
2328% %
2329% %
2330% %
2331%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2332%
2333% strEQcase() compares two strings and returns 0 if they are the
2334% same or if the second string runs out first. The comparison is case
2335% insensitive.
2336%
2337% The format of the strEQcase routine is:
2338%
2339% ssize_t strEQcase(const char *p,const char *q)
2340%
2341% A description of each parameter follows:
2342%
2343% o p: a character string.
2344%
2345% o q: a character string.
2346%
2347%
2348*/
2349static ssize_t strEQcase(const char *p,const char *q)
2350{
2351 char
2352 c;
2353
2354 register ssize_t
2355 i;
2356
2357 for (i=0 ; (c=(*q)) != 0; i++)
2358 {
2359 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2360 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2361 return(0);
2362 p++;
2363 q++;
2364 }
2365 return(((*q == 0) && (*p == 0)) ? i : 0);
2366}
2367
2368/*
2369%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2370% %
2371% %
2372% %
2373% I m a g e : : M a g i c k %
2374% %
2375% %
2376% %
2377%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2378%
2379%
2380*/
2381MODULE = Image::Magick PACKAGE = Image::Magick
2382
2383PROTOTYPES: ENABLE
2384
2385BOOT:
2386 MagickCoreGenesis("PerlMagick",MagickFalse);
2387 SetWarningHandler(NULL);
2388 SetErrorHandler(NULL);
2389 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2390 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2391
2392void
2393UNLOAD()
2394 PPCODE:
2395 {
2396 if (magick_registry != (SplayTreeInfo *) NULL)
2397 magick_registry=DestroySplayTree(magick_registry);
2398 MagickCoreTerminus();
2399 }
2400
2401double
2402constant(name,argument)
2403 char *name
2404 ssize_t argument
2405
2406#
2407###############################################################################
2408# #
2409# #
2410# #
2411# A n i m a t e #
2412# #
2413# #
2414# #
2415###############################################################################
2416#
2417#
2418void
2419Animate(ref,...)
2420 Image::Magick ref=NO_INIT
2421 ALIAS:
2422 AnimateImage = 1
2423 animate = 2
2424 animateimage = 3
2425 PPCODE:
2426 {
2427 ExceptionInfo
2428 *exception;
2429
2430 Image
2431 *image;
2432
2433 register ssize_t
2434 i;
2435
2436 struct PackageInfo
2437 *info,
2438 *package_info;
2439
2440 SV
2441 *perl_exception,
2442 *reference;
2443
2444 PERL_UNUSED_VAR(ref);
2445 PERL_UNUSED_VAR(ix);
2446 exception=AcquireExceptionInfo();
2447 perl_exception=newSVpv("",0);
2448 package_info=(struct PackageInfo *) NULL;
2449 if (sv_isobject(ST(0)) == 0)
2450 {
2451 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2452 PackageName);
2453 goto PerlException;
2454 }
2455 reference=SvRV(ST(0));
2456 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2457 if (image == (Image *) NULL)
2458 {
2459 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2460 PackageName);
2461 goto PerlException;
2462 }
2463 package_info=ClonePackageInfo(info,exception);
2464 if (items == 2)
2465 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2466 else
2467 if (items > 2)
2468 for (i=2; i < items; i+=2)
2469 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2470 exception);
2471 (void) AnimateImages(package_info->image_info,image,exception);
2472 (void) CatchImageException(image);
2473
2474 PerlException:
2475 if (package_info != (struct PackageInfo *) NULL)
2476 DestroyPackageInfo(package_info);
2477 InheritPerlException(exception,perl_exception);
2478 exception=DestroyExceptionInfo(exception);
2479 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2480 SvPOK_on(perl_exception);
2481 ST(0)=sv_2mortal(perl_exception);
2482 XSRETURN(1);
2483 }
2484
2485#
2486###############################################################################
2487# #
2488# #
2489# #
2490# A p p e n d #
2491# #
2492# #
2493# #
2494###############################################################################
2495#
2496#
2497void
2498Append(ref,...)
2499 Image::Magick ref=NO_INIT
2500 ALIAS:
2501 AppendImage = 1
2502 append = 2
2503 appendimage = 3
2504 PPCODE:
2505 {
2506 AV
2507 *av;
2508
2509 char
2510 *attribute;
2511
2512 ExceptionInfo
2513 *exception;
2514
2515 HV
2516 *hv;
2517
2518 Image
2519 *image;
2520
2521 register ssize_t
2522 i;
2523
2524 ssize_t
2525 stack;
2526
2527 struct PackageInfo
2528 *info;
2529
2530 SV
2531 *av_reference,
2532 *perl_exception,
2533 *reference,
2534 *rv,
2535 *sv;
2536
2537 PERL_UNUSED_VAR(ref);
2538 PERL_UNUSED_VAR(ix);
2539 exception=AcquireExceptionInfo();
2540 perl_exception=newSVpv("",0);
2541 sv=NULL;
2542 attribute=NULL;
2543 av=NULL;
2544 if (sv_isobject(ST(0)) == 0)
2545 {
2546 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2547 PackageName);
2548 goto PerlException;
2549 }
2550 reference=SvRV(ST(0));
2551 hv=SvSTASH(reference);
2552 av=newAV();
2553 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2554 SvREFCNT_dec(av);
2555 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2556 if (image == (Image *) NULL)
2557 {
2558 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2559 PackageName);
2560 goto PerlException;
2561 }
2562 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2563 /*
2564 Get options.
2565 */
2566 stack=MagickTrue;
2567 for (i=2; i < items; i+=2)
2568 {
2569 attribute=(char *) SvPV(ST(i-1),na);
2570 switch (*attribute)
2571 {
2572 case 'S':
2573 case 's':
2574 {
2575 if (LocaleCompare(attribute,"stack") == 0)
2576 {
2577 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2578 SvPV(ST(i),na));
2579 if (stack < 0)
2580 {
2581 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2582 SvPV(ST(i),na));
2583 return;
2584 }
2585 break;
2586 }
2587 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2588 attribute);
2589 break;
2590 }
2591 default:
2592 {
2593 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2594 attribute);
2595 break;
2596 }
2597 }
2598 }
2599 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2600 if (image == (Image *) NULL)
2601 goto PerlException;
2602 for ( ; image; image=image->next)
2603 {
2604 AddImageToRegistry(sv,image);
2605 rv=newRV(sv);
2606 av_push(av,sv_bless(rv,hv));
2607 SvREFCNT_dec(sv);
2608 }
2609 exception=DestroyExceptionInfo(exception);
2610 ST(0)=av_reference;
2611 SvREFCNT_dec(perl_exception);
2612 XSRETURN(1);
2613
2614 PerlException:
2615 InheritPerlException(exception,perl_exception);
2616 exception=DestroyExceptionInfo(exception);
2617 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2618 SvPOK_on(perl_exception);
2619 ST(0)=sv_2mortal(perl_exception);
2620 XSRETURN(1);
2621 }
2622
2623#
2624###############################################################################
2625# #
2626# #
2627# #
2628# A v e r a g e #
2629# #
2630# #
2631# #
2632###############################################################################
2633#
2634#
2635void
2636Average(ref)
2637 Image::Magick ref=NO_INIT
2638 ALIAS:
2639 AverageImage = 1
2640 average = 2
2641 averageimage = 3
2642 PPCODE:
2643 {
2644 AV
2645 *av;
2646
2647 char
2648 *p;
2649
2650 ExceptionInfo
2651 *exception;
2652
2653 HV
2654 *hv;
2655
2656 Image
2657 *image;
2658
2659 struct PackageInfo
2660 *info;
2661
2662 SV
2663 *perl_exception,
2664 *reference,
2665 *rv,
2666 *sv;
2667
2668 PERL_UNUSED_VAR(ref);
2669 PERL_UNUSED_VAR(ix);
2670 exception=AcquireExceptionInfo();
2671 perl_exception=newSVpv("",0);
2672 sv=NULL;
2673 if (sv_isobject(ST(0)) == 0)
2674 {
2675 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2676 PackageName);
2677 goto PerlException;
2678 }
2679 reference=SvRV(ST(0));
2680 hv=SvSTASH(reference);
2681 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2682 if (image == (Image *) NULL)
2683 {
2684 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2685 PackageName);
2686 goto PerlException;
2687 }
2688 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2689 if (image == (Image *) NULL)
2690 goto PerlException;
2691 /*
2692 Create blessed Perl array for the returned image.
2693 */
2694 av=newAV();
2695 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2696 SvREFCNT_dec(av);
2697 AddImageToRegistry(sv,image);
2698 rv=newRV(sv);
2699 av_push(av,sv_bless(rv,hv));
2700 SvREFCNT_dec(sv);
2701 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002702 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2703 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002704 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2705 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002706 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002707 SetImageInfo(info->image_info,0,exception);
2708 exception=DestroyExceptionInfo(exception);
2709 SvREFCNT_dec(perl_exception);
2710 XSRETURN(1);
2711
2712 PerlException:
2713 InheritPerlException(exception,perl_exception);
2714 exception=DestroyExceptionInfo(exception);
2715 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2716 SvPOK_on(perl_exception);
2717 ST(0)=sv_2mortal(perl_exception);
2718 XSRETURN(1);
2719 }
2720
2721#
2722###############################################################################
2723# #
2724# #
2725# #
2726# B l o b T o I m a g e #
2727# #
2728# #
2729# #
2730###############################################################################
2731#
2732#
2733void
2734BlobToImage(ref,...)
2735 Image::Magick ref=NO_INIT
2736 ALIAS:
2737 BlobToImage = 1
2738 blobtoimage = 2
2739 blobto = 3
2740 PPCODE:
2741 {
2742 AV
2743 *av;
2744
2745 char
2746 **keep,
2747 **list;
2748
2749 ExceptionInfo
2750 *exception;
2751
2752 HV
2753 *hv;
2754
2755 Image
2756 *image;
2757
2758 register char
2759 **p;
2760
2761 register ssize_t
2762 i;
2763
2764 ssize_t
2765 ac,
2766 n,
2767 number_images;
2768
2769 STRLEN
2770 *length;
2771
2772 struct PackageInfo
2773 *info;
2774
2775 SV
2776 *perl_exception,
2777 *reference,
2778 *rv,
2779 *sv;
2780
2781 PERL_UNUSED_VAR(ref);
2782 PERL_UNUSED_VAR(ix);
2783 exception=AcquireExceptionInfo();
2784 perl_exception=newSVpv("",0);
2785 sv=NULL;
2786 number_images=0;
2787 ac=(items < 2) ? 1 : items-1;
2788 length=(STRLEN *) NULL;
2789 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2790 if (list == (char **) NULL)
2791 {
2792 ThrowPerlException(exception,ResourceLimitError,
2793 "MemoryAllocationFailed",PackageName);
2794 goto PerlException;
2795 }
2796 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2797 if (length == (STRLEN *) NULL)
2798 {
2799 ThrowPerlException(exception,ResourceLimitError,
2800 "MemoryAllocationFailed",PackageName);
2801 goto PerlException;
2802 }
2803 if (sv_isobject(ST(0)) == 0)
2804 {
2805 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2806 PackageName);
2807 goto PerlException;
2808 }
2809 reference=SvRV(ST(0));
2810 hv=SvSTASH(reference);
2811 if (SvTYPE(reference) != SVt_PVAV)
2812 {
2813 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2814 PackageName);
2815 goto PerlException;
2816 }
2817 av=(AV *) reference;
2818 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2819 exception);
2820 n=1;
2821 if (items <= 1)
2822 {
2823 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2824 goto PerlException;
2825 }
2826 for (n=0, i=0; i < ac; i++)
2827 {
2828 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2829 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2830 {
2831 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2832 continue;
2833 }
2834 n++;
2835 }
2836 list[n]=(char *) NULL;
2837 keep=list;
2838 for (i=number_images=0; i < n; i++)
2839 {
2840 image=BlobToImage(info->image_info,list[i],length[i],exception);
2841 if (image == (Image *) NULL)
2842 break;
2843 for ( ; image; image=image->next)
2844 {
2845 AddImageToRegistry(sv,image);
2846 rv=newRV(sv);
2847 av_push(av,sv_bless(rv,hv));
2848 SvREFCNT_dec(sv);
2849 number_images++;
2850 }
2851 }
2852 /*
2853 Free resources.
2854 */
2855 for (i=0; i < n; i++)
2856 if (list[i] != (char *) NULL)
2857 for (p=keep; list[i] != *p++; )
2858 if (*p == (char *) NULL)
2859 {
2860 list[i]=(char *) RelinquishMagickMemory(list[i]);
2861 break;
2862 }
2863
2864 PerlException:
2865 if (list)
2866 list=(char **) RelinquishMagickMemory(list);
2867 if (length)
2868 length=(STRLEN *) RelinquishMagickMemory(length);
2869 InheritPerlException(exception,perl_exception);
2870 exception=DestroyExceptionInfo(exception);
2871 sv_setiv(perl_exception,(IV) number_images);
2872 SvPOK_on(perl_exception);
2873 ST(0)=sv_2mortal(perl_exception);
2874 XSRETURN(1);
2875 }
2876
2877#
2878###############################################################################
2879# #
2880# #
2881# #
2882# C h a n n e l F x #
2883# #
2884# #
2885# #
2886###############################################################################
2887#
2888#
2889void
2890ChannelFx(ref,...)
2891 Image::Magick ref=NO_INIT
2892 ALIAS:
2893 ChannelFxImage = 1
2894 channelfx = 2
2895 channelfximage = 3
2896 PPCODE:
2897 {
2898 AV
2899 *av;
2900
2901 char
2902 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002903 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002904
2905 ChannelType
2906 channel,
2907 channel_mask;
2908
2909 ExceptionInfo
2910 *exception;
2911
2912 HV
2913 *hv;
2914
2915 Image
2916 *image;
2917
2918 register ssize_t
2919 i;
2920
2921 struct PackageInfo
2922 *info;
2923
2924 SV
2925 *av_reference,
2926 *perl_exception,
2927 *reference,
2928 *rv,
2929 *sv;
2930
2931 PERL_UNUSED_VAR(ref);
2932 PERL_UNUSED_VAR(ix);
2933 exception=AcquireExceptionInfo();
2934 perl_exception=newSVpv("",0);
2935 sv=NULL;
2936 attribute=NULL;
2937 av=NULL;
2938 if (sv_isobject(ST(0)) == 0)
2939 {
2940 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2941 PackageName);
2942 goto PerlException;
2943 }
2944 reference=SvRV(ST(0));
2945 hv=SvSTASH(reference);
2946 av=newAV();
2947 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2948 SvREFCNT_dec(av);
2949 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2950 if (image == (Image *) NULL)
2951 {
2952 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2953 PackageName);
2954 goto PerlException;
2955 }
2956 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2957 /*
2958 Get options.
2959 */
2960 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00002961 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002962 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00002963 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002964 else
2965 for (i=2; i < items; i+=2)
2966 {
2967 attribute=(char *) SvPV(ST(i-1),na);
2968 switch (*attribute)
2969 {
2970 case 'C':
2971 case 'c':
2972 {
2973 if (LocaleCompare(attribute,"channel") == 0)
2974 {
2975 ssize_t
2976 option;
2977
2978 option=ParseChannelOption(SvPV(ST(i),na));
2979 if (option < 0)
2980 {
2981 ThrowPerlException(exception,OptionError,
2982 "UnrecognizedType",SvPV(ST(i),na));
2983 return;
2984 }
2985 channel=(ChannelType) option;
2986 break;
2987 }
2988 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2989 attribute);
2990 break;
2991 }
2992 case 'E':
2993 case 'e':
2994 {
2995 if (LocaleCompare(attribute,"expression") == 0)
2996 {
2997 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00002998 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002999 break;
3000 }
3001 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3002 attribute);
3003 break;
3004 }
3005 default:
3006 {
3007 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3008 attribute);
3009 break;
3010 }
3011 }
3012 }
3013 channel_mask=SetImageChannelMask(image,channel);
3014 image=ChannelFxImage(image,expression,exception);
3015 if (image != (Image *) NULL)
3016 (void) SetImageChannelMask(image,channel_mask);
3017 if (image == (Image *) NULL)
3018 goto PerlException;
3019 for ( ; image; image=image->next)
3020 {
3021 AddImageToRegistry(sv,image);
3022 rv=newRV(sv);
3023 av_push(av,sv_bless(rv,hv));
3024 SvREFCNT_dec(sv);
3025 }
3026 exception=DestroyExceptionInfo(exception);
3027 ST(0)=av_reference;
3028 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3029 XSRETURN(1);
3030
3031 PerlException:
3032 InheritPerlException(exception,perl_exception);
3033 exception=DestroyExceptionInfo(exception);
3034 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3035 SvPOK_on(perl_exception);
3036 ST(0)=sv_2mortal(perl_exception);
3037 XSRETURN(1);
3038 }
3039
3040#
3041###############################################################################
3042# #
3043# #
3044# #
3045# C l o n e #
3046# #
3047# #
3048# #
3049###############################################################################
3050#
3051#
3052void
3053Clone(ref)
3054 Image::Magick ref=NO_INIT
3055 ALIAS:
3056 CopyImage = 1
3057 copy = 2
3058 copyimage = 3
3059 CloneImage = 4
3060 clone = 5
3061 cloneimage = 6
3062 Clone = 7
3063 PPCODE:
3064 {
3065 AV
3066 *av;
3067
3068 ExceptionInfo
3069 *exception;
3070
3071 HV
3072 *hv;
3073
3074 Image
3075 *clone,
3076 *image;
3077
3078 struct PackageInfo
3079 *info;
3080
3081 SV
3082 *perl_exception,
3083 *reference,
3084 *rv,
3085 *sv;
3086
3087 PERL_UNUSED_VAR(ref);
3088 PERL_UNUSED_VAR(ix);
3089 exception=AcquireExceptionInfo();
3090 perl_exception=newSVpv("",0);
3091 sv=NULL;
3092 if (sv_isobject(ST(0)) == 0)
3093 {
3094 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3095 PackageName);
3096 goto PerlException;
3097 }
3098 reference=SvRV(ST(0));
3099 hv=SvSTASH(reference);
3100 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3101 if (image == (Image *) NULL)
3102 {
3103 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3104 PackageName);
3105 goto PerlException;
3106 }
3107 /*
3108 Create blessed Perl array for the returned image.
3109 */
3110 av=newAV();
3111 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3112 SvREFCNT_dec(av);
3113 for ( ; image; image=image->next)
3114 {
3115 clone=CloneImage(image,0,0,MagickTrue,exception);
3116 if (clone == (Image *) NULL)
3117 break;
3118 AddImageToRegistry(sv,clone);
3119 rv=newRV(sv);
3120 av_push(av,sv_bless(rv,hv));
3121 SvREFCNT_dec(sv);
3122 }
3123 exception=DestroyExceptionInfo(exception);
3124 SvREFCNT_dec(perl_exception);
3125 XSRETURN(1);
3126
3127 PerlException:
3128 InheritPerlException(exception,perl_exception);
3129 exception=DestroyExceptionInfo(exception);
3130 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3131 SvPOK_on(perl_exception);
3132 ST(0)=sv_2mortal(perl_exception);
3133 XSRETURN(1);
3134 }
3135
3136#
3137###############################################################################
3138# #
3139# #
3140# #
3141# C L O N E #
3142# #
3143# #
3144# #
3145###############################################################################
3146#
3147#
3148void
3149CLONE(ref,...)
3150 SV *ref;
3151 CODE:
3152 {
3153 PERL_UNUSED_VAR(ref);
3154 if (magick_registry != (SplayTreeInfo *) NULL)
3155 {
3156 register Image
3157 *p;
3158
3159 ResetSplayTreeIterator(magick_registry);
3160 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3161 while (p != (Image *) NULL)
3162 {
3163 ReferenceImage(p);
3164 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3165 }
3166 }
3167 }
3168
3169#
3170###############################################################################
3171# #
3172# #
3173# #
3174# C o a l e s c e #
3175# #
3176# #
3177# #
3178###############################################################################
3179#
3180#
3181void
3182Coalesce(ref)
3183 Image::Magick ref=NO_INIT
3184 ALIAS:
3185 CoalesceImage = 1
3186 coalesce = 2
3187 coalesceimage = 3
3188 PPCODE:
3189 {
3190 AV
3191 *av;
3192
3193 ExceptionInfo
3194 *exception;
3195
3196 HV
3197 *hv;
3198
3199 Image
3200 *image;
3201
3202 struct PackageInfo
3203 *info;
3204
3205 SV
3206 *av_reference,
3207 *perl_exception,
3208 *reference,
3209 *rv,
3210 *sv;
3211
3212 PERL_UNUSED_VAR(ref);
3213 PERL_UNUSED_VAR(ix);
3214 exception=AcquireExceptionInfo();
3215 perl_exception=newSVpv("",0);
3216 sv=NULL;
3217 if (sv_isobject(ST(0)) == 0)
3218 {
3219 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3220 PackageName);
3221 goto PerlException;
3222 }
3223 reference=SvRV(ST(0));
3224 hv=SvSTASH(reference);
3225 av=newAV();
3226 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3227 SvREFCNT_dec(av);
3228 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3229 if (image == (Image *) NULL)
3230 {
3231 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3232 PackageName);
3233 goto PerlException;
3234 }
3235 image=CoalesceImages(image,exception);
3236 if (image == (Image *) NULL)
3237 goto PerlException;
3238 for ( ; image; image=image->next)
3239 {
3240 AddImageToRegistry(sv,image);
3241 rv=newRV(sv);
3242 av_push(av,sv_bless(rv,hv));
3243 SvREFCNT_dec(sv);
3244 }
3245 exception=DestroyExceptionInfo(exception);
3246 ST(0)=av_reference;
3247 SvREFCNT_dec(perl_exception);
3248 XSRETURN(1);
3249
3250 PerlException:
3251 InheritPerlException(exception,perl_exception);
3252 exception=DestroyExceptionInfo(exception);
3253 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3254 SvPOK_on(perl_exception);
3255 ST(0)=sv_2mortal(perl_exception);
3256 XSRETURN(1);
3257 }
3258
3259#
3260###############################################################################
3261# #
3262# #
3263# #
3264# C o m p a r e #
3265# #
3266# #
3267# #
3268###############################################################################
3269#
3270#
3271void
3272Compare(ref,...)
3273 Image::Magick ref=NO_INIT
3274 ALIAS:
3275 CompareImages = 1
3276 compare = 2
3277 compareimage = 3
3278 PPCODE:
3279 {
3280 AV
3281 *av;
3282
3283 char
3284 *attribute;
3285
3286 double
3287 distortion;
3288
3289 ExceptionInfo
3290 *exception;
3291
3292 HV
3293 *hv;
3294
3295 Image
3296 *difference_image,
3297 *image,
3298 *reconstruct_image;
3299
3300 MetricType
3301 metric;
3302
3303 register ssize_t
3304 i;
3305
3306 ssize_t
3307 option;
3308
3309 struct PackageInfo
3310 *info;
3311
3312 SV
3313 *av_reference,
3314 *perl_exception,
3315 *reference,
3316 *rv,
3317 *sv;
3318
3319 PERL_UNUSED_VAR(ref);
3320 PERL_UNUSED_VAR(ix);
3321 exception=AcquireExceptionInfo();
3322 perl_exception=newSVpv("",0);
3323 sv=NULL;
3324 av=NULL;
3325 attribute=NULL;
3326 if (sv_isobject(ST(0)) == 0)
3327 {
3328 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3329 PackageName);
3330 goto PerlException;
3331 }
3332 reference=SvRV(ST(0));
3333 hv=SvSTASH(reference);
3334 av=newAV();
3335 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3336 SvREFCNT_dec(av);
3337 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3338 if (image == (Image *) NULL)
3339 {
3340 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3341 PackageName);
3342 goto PerlException;
3343 }
3344 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3345 /*
3346 Get attribute.
3347 */
3348 reconstruct_image=image;
3349 metric=RootMeanSquaredErrorMetric;
3350 for (i=2; i < items; i+=2)
3351 {
3352 attribute=(char *) SvPV(ST(i-1),na);
3353 switch (*attribute)
3354 {
3355 case 'C':
3356 case 'c':
3357 {
3358 if (LocaleCompare(attribute,"channel") == 0)
3359 {
3360 ssize_t
3361 option;
3362
3363 option=ParseChannelOption(SvPV(ST(i),na));
3364 if (option < 0)
3365 {
3366 ThrowPerlException(exception,OptionError,
3367 "UnrecognizedType",SvPV(ST(i),na));
3368 return;
3369 }
cristybcd59342015-06-07 14:07:19 +00003370 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003371 break;
3372 }
3373 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3374 attribute);
3375 break;
3376 }
3377 case 'F':
3378 case 'f':
3379 {
3380 if (LocaleCompare(attribute,"fuzz") == 0)
3381 {
3382 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3383 break;
3384 }
3385 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3386 attribute);
3387 break;
3388 }
3389 case 'I':
3390 case 'i':
3391 {
3392 if (LocaleCompare(attribute,"image") == 0)
3393 {
3394 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3395 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3396 break;
3397 }
3398 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3399 attribute);
3400 break;
3401 }
3402 case 'M':
3403 case 'm':
3404 {
3405 if (LocaleCompare(attribute,"metric") == 0)
3406 {
3407 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3408 SvPV(ST(i),na));
3409 if (option < 0)
3410 {
3411 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3412 SvPV(ST(i),na));
3413 break;
3414 }
3415 metric=(MetricType) option;
3416 break;
3417 }
3418 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3419 attribute);
3420 break;
3421 }
3422 default:
3423 {
3424 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3425 attribute);
3426 break;
3427 }
3428 }
3429 }
3430 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3431 exception);
3432 if (difference_image != (Image *) NULL)
3433 {
3434 difference_image->error.mean_error_per_pixel=distortion;
3435 AddImageToRegistry(sv,difference_image);
3436 rv=newRV(sv);
3437 av_push(av,sv_bless(rv,hv));
3438 SvREFCNT_dec(sv);
3439 }
3440 exception=DestroyExceptionInfo(exception);
3441 ST(0)=av_reference;
3442 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3443 XSRETURN(1);
3444
3445 PerlException:
3446 InheritPerlException(exception,perl_exception);
3447 exception=DestroyExceptionInfo(exception);
3448 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3449 SvPOK_on(perl_exception);
3450 ST(0)=sv_2mortal(perl_exception);
3451 XSRETURN(1);
3452 }
3453
3454#
3455###############################################################################
3456# #
3457# #
3458# #
cristy15655332013-10-06 00:27:33 +00003459# C o m p l e x I m a g e s #
3460# #
3461# #
3462# #
3463###############################################################################
3464#
3465#
3466void
3467ComplexImages(ref)
3468 Image::Magick ref=NO_INIT
3469 ALIAS:
3470 ComplexImages = 1
3471 compleximages = 2
3472 PPCODE:
3473 {
3474 AV
3475 *av;
3476
3477 char
3478 *attribute,
3479 *p;
3480
cristyfa21e9e2013-10-07 10:37:38 +00003481 ComplexOperator
3482 op;
3483
cristy15655332013-10-06 00:27:33 +00003484 ExceptionInfo
3485 *exception;
3486
3487 HV
3488 *hv;
3489
3490 Image
3491 *image;
3492
cristy15655332013-10-06 00:27:33 +00003493 register ssize_t
3494 i;
3495
3496 struct PackageInfo
3497 *info;
3498
3499 SV
3500 *perl_exception,
3501 *reference,
3502 *rv,
3503 *sv;
3504
3505 PERL_UNUSED_VAR(ref);
3506 PERL_UNUSED_VAR(ix);
3507 exception=AcquireExceptionInfo();
3508 perl_exception=newSVpv("",0);
3509 sv=NULL;
3510 if (sv_isobject(ST(0)) == 0)
3511 {
3512 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3513 PackageName);
3514 goto PerlException;
3515 }
3516 reference=SvRV(ST(0));
3517 hv=SvSTASH(reference);
3518 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3519 if (image == (Image *) NULL)
3520 {
3521 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3522 PackageName);
3523 goto PerlException;
3524 }
cristyfd168722013-10-07 15:59:31 +00003525 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003526 if (items == 2)
3527 {
3528 ssize_t
3529 in;
3530
3531 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3532 SvPV(ST(1),na));
3533 if (in < 0)
3534 {
3535 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3536 SvPV(ST(1),na));
3537 return;
3538 }
cristyfa21e9e2013-10-07 10:37:38 +00003539 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003540 }
3541 else
3542 for (i=2; i < items; i+=2)
3543 {
3544 attribute=(char *) SvPV(ST(i-1),na);
3545 switch (*attribute)
3546 {
3547 case 'O':
3548 case 'o':
3549 {
3550 if (LocaleCompare(attribute,"operator") == 0)
3551 {
3552 ssize_t
3553 in;
3554
3555 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3556 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3557 if (in < 0)
3558 {
3559 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3560 SvPV(ST(i),na));
3561 return;
3562 }
cristyfa21e9e2013-10-07 10:37:38 +00003563 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003564 break;
3565 }
3566 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3567 attribute);
3568 break;
3569 }
3570 default:
3571 {
3572 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3573 attribute);
3574 break;
3575 }
3576 }
3577 }
3578 image=ComplexImages(image,op,exception);
3579 if (image == (Image *) NULL)
3580 goto PerlException;
3581 /*
3582 Create blessed Perl array for the returned image.
3583 */
3584 av=newAV();
3585 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3586 SvREFCNT_dec(av);
3587 AddImageToRegistry(sv,image);
3588 rv=newRV(sv);
3589 av_push(av,sv_bless(rv,hv));
3590 SvREFCNT_dec(sv);
3591 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003592 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3593 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003594 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3595 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003596 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003597 SetImageInfo(info->image_info,0,exception);
3598 exception=DestroyExceptionInfo(exception);
3599 SvREFCNT_dec(perl_exception);
3600 XSRETURN(1);
3601
3602 PerlException:
3603 InheritPerlException(exception,perl_exception);
3604 exception=DestroyExceptionInfo(exception);
3605 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3606 SvPOK_on(perl_exception);
3607 ST(0)=sv_2mortal(perl_exception);
3608 XSRETURN(1);
3609 }
3610
3611#
3612###############################################################################
3613# #
3614# #
3615# #
cristy4a3ce0a2013-08-03 20:06:59 +00003616# C o m p a r e L a y e r s #
3617# #
3618# #
3619# #
3620###############################################################################
3621#
3622#
3623void
3624CompareLayers(ref)
3625 Image::Magick ref=NO_INIT
3626 ALIAS:
3627 CompareImagesLayers = 1
3628 comparelayers = 2
3629 compareimagelayers = 3
3630 PPCODE:
3631 {
3632 AV
3633 *av;
3634
3635 char
3636 *attribute;
3637
3638 ExceptionInfo
3639 *exception;
3640
3641 HV
3642 *hv;
3643
3644 Image
3645 *image;
3646
3647 LayerMethod
3648 method;
3649
3650 register ssize_t
3651 i;
3652
3653 ssize_t
3654 option;
3655
3656 struct PackageInfo
3657 *info;
3658
3659 SV
3660 *av_reference,
3661 *perl_exception,
3662 *reference,
3663 *rv,
3664 *sv;
3665
3666 PERL_UNUSED_VAR(ref);
3667 PERL_UNUSED_VAR(ix);
3668 exception=AcquireExceptionInfo();
3669 perl_exception=newSVpv("",0);
3670 sv=NULL;
3671 if (sv_isobject(ST(0)) == 0)
3672 {
3673 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3674 PackageName);
3675 goto PerlException;
3676 }
3677 reference=SvRV(ST(0));
3678 hv=SvSTASH(reference);
3679 av=newAV();
3680 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3681 SvREFCNT_dec(av);
3682 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3683 if (image == (Image *) NULL)
3684 {
3685 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3686 PackageName);
3687 goto PerlException;
3688 }
3689 method=CompareAnyLayer;
3690 for (i=2; i < items; i+=2)
3691 {
3692 attribute=(char *) SvPV(ST(i-1),na);
3693 switch (*attribute)
3694 {
3695 case 'M':
3696 case 'm':
3697 {
3698 if (LocaleCompare(attribute,"method") == 0)
3699 {
3700 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3701 SvPV(ST(i),na));
3702 if (option < 0)
3703 {
3704 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3705 SvPV(ST(i),na));
3706 break;
3707 }
3708 method=(LayerMethod) option;
3709 break;
3710 }
3711 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3712 attribute);
3713 break;
3714 }
3715 default:
3716 {
3717 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3718 attribute);
3719 break;
3720 }
3721 }
3722 }
3723 image=CompareImagesLayers(image,method,exception);
3724 if (image == (Image *) NULL)
3725 goto PerlException;
3726 for ( ; image; image=image->next)
3727 {
3728 AddImageToRegistry(sv,image);
3729 rv=newRV(sv);
3730 av_push(av,sv_bless(rv,hv));
3731 SvREFCNT_dec(sv);
3732 }
3733 exception=DestroyExceptionInfo(exception);
3734 ST(0)=av_reference;
3735 SvREFCNT_dec(perl_exception);
3736 XSRETURN(1);
3737
3738 PerlException:
3739 InheritPerlException(exception,perl_exception);
3740 exception=DestroyExceptionInfo(exception);
3741 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3742 SvPOK_on(perl_exception);
3743 ST(0)=sv_2mortal(perl_exception);
3744 XSRETURN(1);
3745 }
3746
3747#
3748###############################################################################
3749# #
3750# #
3751# #
3752# D e s t r o y #
3753# #
3754# #
3755# #
3756###############################################################################
3757#
3758#
3759void
3760DESTROY(ref)
3761 Image::Magick ref=NO_INIT
3762 PPCODE:
3763 {
3764 SV
3765 *reference;
3766
3767 PERL_UNUSED_VAR(ref);
3768 if (sv_isobject(ST(0)) == 0)
3769 croak("ReferenceIsNotMyType");
3770 reference=SvRV(ST(0));
3771 switch (SvTYPE(reference))
3772 {
3773 case SVt_PVAV:
3774 {
3775 char
cristy151b66d2015-04-15 10:50:31 +00003776 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003777
3778 const SV
3779 *key;
3780
3781 HV
3782 *hv;
3783
3784 GV
3785 **gvp;
3786
3787 struct PackageInfo
3788 *info;
3789
3790 SV
3791 *sv;
3792
3793 /*
3794 Array (AV *) reference
3795 */
cristy151b66d2015-04-15 10:50:31 +00003796 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003797 XS_VERSION,reference);
3798 hv=gv_stashpv(PackageName, FALSE);
3799 if (!hv)
3800 break;
3801 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3802 if (!gvp)
3803 break;
3804 sv=GvSV(*gvp);
3805 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3806 {
3807 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3808 DestroyPackageInfo(info);
3809 }
3810 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3811 (void) key;
3812 break;
3813 }
3814 case SVt_PVMG:
3815 {
3816 Image
3817 *image;
3818
3819 /*
3820 Blessed scalar = (Image *) SvIV(reference)
3821 */
3822 image=INT2PTR(Image *,SvIV(reference));
3823 if (image != (Image *) NULL)
3824 DeleteImageFromRegistry(reference,image);
3825 break;
3826 }
3827 default:
3828 break;
3829 }
3830 }
3831
3832#
3833###############################################################################
3834# #
3835# #
3836# #
3837# D i s p l a y #
3838# #
3839# #
3840# #
3841###############################################################################
3842#
3843#
3844void
3845Display(ref,...)
3846 Image::Magick ref=NO_INIT
3847 ALIAS:
3848 DisplayImage = 1
3849 display = 2
3850 displayimage = 3
3851 PPCODE:
3852 {
3853 ExceptionInfo
3854 *exception;
3855
3856 Image
3857 *image;
3858
3859 register ssize_t
3860 i;
3861
3862 struct PackageInfo
3863 *info,
3864 *package_info;
3865
3866 SV
3867 *perl_exception,
3868 *reference;
3869
3870 PERL_UNUSED_VAR(ref);
3871 PERL_UNUSED_VAR(ix);
3872 exception=AcquireExceptionInfo();
3873 perl_exception=newSVpv("",0);
3874 package_info=(struct PackageInfo *) NULL;
3875 if (sv_isobject(ST(0)) == 0)
3876 {
3877 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3878 PackageName);
3879 goto PerlException;
3880 }
3881 reference=SvRV(ST(0));
3882 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3883 if (image == (Image *) NULL)
3884 {
3885 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3886 PackageName);
3887 goto PerlException;
3888 }
3889 package_info=ClonePackageInfo(info,exception);
3890 if (items == 2)
3891 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3892 else
3893 if (items > 2)
3894 for (i=2; i < items; i+=2)
3895 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3896 exception);
3897 (void) DisplayImages(package_info->image_info,image,exception);
3898 (void) CatchImageException(image);
3899
3900 PerlException:
3901 if (package_info != (struct PackageInfo *) NULL)
3902 DestroyPackageInfo(package_info);
3903 InheritPerlException(exception,perl_exception);
3904 exception=DestroyExceptionInfo(exception);
3905 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3906 SvPOK_on(perl_exception);
3907 ST(0)=sv_2mortal(perl_exception);
3908 XSRETURN(1);
3909 }
3910
3911#
3912###############################################################################
3913# #
3914# #
3915# #
3916# E v a l u a t e I m a g e s #
3917# #
3918# #
3919# #
3920###############################################################################
3921#
3922#
3923void
3924EvaluateImages(ref)
3925 Image::Magick ref=NO_INIT
3926 ALIAS:
3927 EvaluateImages = 1
3928 evaluateimages = 2
3929 PPCODE:
3930 {
3931 AV
3932 *av;
3933
3934 char
3935 *attribute,
3936 *p;
3937
3938 ExceptionInfo
3939 *exception;
3940
3941 HV
3942 *hv;
3943
3944 Image
3945 *image;
3946
3947 MagickEvaluateOperator
3948 op;
3949
3950 register ssize_t
3951 i;
3952
3953 struct PackageInfo
3954 *info;
3955
3956 SV
3957 *perl_exception,
3958 *reference,
3959 *rv,
3960 *sv;
3961
3962 PERL_UNUSED_VAR(ref);
3963 PERL_UNUSED_VAR(ix);
3964 exception=AcquireExceptionInfo();
3965 perl_exception=newSVpv("",0);
3966 sv=NULL;
3967 if (sv_isobject(ST(0)) == 0)
3968 {
3969 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3970 PackageName);
3971 goto PerlException;
3972 }
3973 reference=SvRV(ST(0));
3974 hv=SvSTASH(reference);
3975 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3976 if (image == (Image *) NULL)
3977 {
3978 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3979 PackageName);
3980 goto PerlException;
3981 }
3982 op=MeanEvaluateOperator;
3983 if (items == 2)
3984 {
3985 ssize_t
3986 in;
3987
3988 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
3989 SvPV(ST(1),na));
3990 if (in < 0)
3991 {
3992 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3993 SvPV(ST(1),na));
3994 return;
3995 }
3996 op=(MagickEvaluateOperator) in;
3997 }
3998 else
3999 for (i=2; i < items; i+=2)
4000 {
4001 attribute=(char *) SvPV(ST(i-1),na);
4002 switch (*attribute)
4003 {
4004 case 'O':
4005 case 'o':
4006 {
4007 if (LocaleCompare(attribute,"operator") == 0)
4008 {
4009 ssize_t
4010 in;
4011
4012 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4013 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4014 if (in < 0)
4015 {
4016 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4017 SvPV(ST(i),na));
4018 return;
4019 }
4020 op=(MagickEvaluateOperator) in;
4021 break;
4022 }
4023 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4024 attribute);
4025 break;
4026 }
4027 default:
4028 {
4029 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4030 attribute);
4031 break;
4032 }
4033 }
4034 }
4035 image=EvaluateImages(image,op,exception);
4036 if (image == (Image *) NULL)
4037 goto PerlException;
4038 /*
4039 Create blessed Perl array for the returned image.
4040 */
4041 av=newAV();
4042 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4043 SvREFCNT_dec(av);
4044 AddImageToRegistry(sv,image);
4045 rv=newRV(sv);
4046 av_push(av,sv_bless(rv,hv));
4047 SvREFCNT_dec(sv);
4048 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004049 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4050 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004051 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4052 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004053 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004054 SetImageInfo(info->image_info,0,exception);
4055 exception=DestroyExceptionInfo(exception);
4056 SvREFCNT_dec(perl_exception);
4057 XSRETURN(1);
4058
4059 PerlException:
4060 InheritPerlException(exception,perl_exception);
4061 exception=DestroyExceptionInfo(exception);
4062 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4063 SvPOK_on(perl_exception);
4064 ST(0)=sv_2mortal(perl_exception);
4065 XSRETURN(1);
4066 }
4067
4068#
4069###############################################################################
4070# #
4071# #
4072# #
4073# F e a t u r e s #
4074# #
4075# #
4076# #
4077###############################################################################
4078#
4079#
4080void
4081Features(ref,...)
4082 Image::Magick ref=NO_INIT
4083 ALIAS:
4084 FeaturesImage = 1
4085 features = 2
4086 featuresimage = 3
4087 PPCODE:
4088 {
4089#define ChannelFeatures(channel,direction) \
4090{ \
cristy151b66d2015-04-15 10:50:31 +00004091 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004092 channel_features[channel].angular_second_moment[direction]); \
4093 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004094 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004095 channel_features[channel].contrast[direction]); \
4096 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004097 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004098 channel_features[channel].contrast[direction]); \
4099 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004100 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004101 channel_features[channel].variance_sum_of_squares[direction]); \
4102 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004103 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004104 channel_features[channel].inverse_difference_moment[direction]); \
4105 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004106 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004107 channel_features[channel].sum_average[direction]); \
4108 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004109 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004110 channel_features[channel].sum_variance[direction]); \
4111 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004112 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004113 channel_features[channel].sum_entropy[direction]); \
4114 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004115 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004116 channel_features[channel].entropy[direction]); \
4117 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004118 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004119 channel_features[channel].difference_variance[direction]); \
4120 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004121 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004122 channel_features[channel].difference_entropy[direction]); \
4123 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004124 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004125 channel_features[channel].measure_of_correlation_1[direction]); \
4126 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004127 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004128 channel_features[channel].measure_of_correlation_2[direction]); \
4129 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004130 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004131 channel_features[channel].maximum_correlation_coefficient[direction]); \
4132 PUSHs(sv_2mortal(newSVpv(message,0))); \
4133}
4134
4135 AV
4136 *av;
4137
4138 char
4139 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004140 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004141
4142 ChannelFeatures
4143 *channel_features;
4144
4145 double
4146 distance;
4147
4148 ExceptionInfo
4149 *exception;
4150
4151 Image
4152 *image;
4153
4154 register ssize_t
4155 i;
4156
4157 ssize_t
4158 count;
4159
4160 struct PackageInfo
4161 *info;
4162
4163 SV
4164 *perl_exception,
4165 *reference;
4166
4167 PERL_UNUSED_VAR(ref);
4168 PERL_UNUSED_VAR(ix);
4169 exception=AcquireExceptionInfo();
4170 perl_exception=newSVpv("",0);
4171 av=NULL;
4172 if (sv_isobject(ST(0)) == 0)
4173 {
4174 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4175 PackageName);
4176 goto PerlException;
4177 }
4178 reference=SvRV(ST(0));
4179 av=newAV();
4180 SvREFCNT_dec(av);
4181 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4182 if (image == (Image *) NULL)
4183 {
4184 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4185 PackageName);
4186 goto PerlException;
4187 }
cristy7dbd9262014-07-02 17:53:42 +00004188 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004189 for (i=2; i < items; i+=2)
4190 {
4191 attribute=(char *) SvPV(ST(i-1),na);
4192 switch (*attribute)
4193 {
4194 case 'D':
4195 case 'd':
4196 {
4197 if (LocaleCompare(attribute,"distance") == 0)
4198 {
4199 distance=StringToLong((char *) SvPV(ST(1),na));
4200 break;
4201 }
4202 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4203 attribute);
4204 break;
4205 }
4206 default:
4207 {
4208 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4209 attribute);
4210 break;
4211 }
4212 }
4213 }
4214 count=0;
4215 for ( ; image; image=image->next)
4216 {
4217 channel_features=GetImageFeatures(image,distance,exception);
4218 if (channel_features == (ChannelFeatures *) NULL)
4219 continue;
4220 count++;
cristyfcf3bdf2014-07-02 14:35:58 +00004221 EXTEND(sp,280*count);
cristy4a3ce0a2013-08-03 20:06:59 +00004222 for (i=0; i < 4; i++)
4223 {
4224 ChannelFeatures(RedChannel,i);
4225 ChannelFeatures(GreenChannel,i);
4226 ChannelFeatures(BlueChannel,i);
4227 if (image->colorspace == CMYKColorspace)
4228 ChannelFeatures(BlackChannel,i);
cristy17f11b02014-12-20 19:37:04 +00004229 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00004230 ChannelFeatures(AlphaChannel,i);
4231 }
4232 channel_features=(ChannelFeatures *)
4233 RelinquishMagickMemory(channel_features);
4234 }
4235
4236 PerlException:
4237 InheritPerlException(exception,perl_exception);
4238 exception=DestroyExceptionInfo(exception);
4239 SvREFCNT_dec(perl_exception);
4240 }
4241
4242#
4243###############################################################################
4244# #
4245# #
4246# #
4247# F l a t t e n #
4248# #
4249# #
4250# #
4251###############################################################################
4252#
4253#
4254void
4255Flatten(ref)
4256 Image::Magick ref=NO_INIT
4257 ALIAS:
4258 FlattenImage = 1
4259 flatten = 2
4260 flattenimage = 3
4261 PPCODE:
4262 {
4263 AV
4264 *av;
4265
4266 char
4267 *attribute,
4268 *p;
4269
4270 ExceptionInfo
4271 *exception;
4272
4273 HV
4274 *hv;
4275
4276 Image
4277 *image;
4278
4279 PixelInfo
4280 background_color;
4281
4282 register ssize_t
4283 i;
4284
4285 struct PackageInfo
4286 *info;
4287
4288 SV
4289 *perl_exception,
4290 *reference,
4291 *rv,
4292 *sv;
4293
4294 PERL_UNUSED_VAR(ref);
4295 PERL_UNUSED_VAR(ix);
4296 exception=AcquireExceptionInfo();
4297 perl_exception=newSVpv("",0);
4298 sv=NULL;
4299 if (sv_isobject(ST(0)) == 0)
4300 {
4301 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4302 PackageName);
4303 goto PerlException;
4304 }
4305 reference=SvRV(ST(0));
4306 hv=SvSTASH(reference);
4307 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4308 if (image == (Image *) NULL)
4309 {
4310 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4311 PackageName);
4312 goto PerlException;
4313 }
4314 background_color=image->background_color;
4315 if (items == 2)
4316 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4317 &background_color,exception);
4318 else
4319 for (i=2; i < items; i+=2)
4320 {
4321 attribute=(char *) SvPV(ST(i-1),na);
4322 switch (*attribute)
4323 {
4324 case 'B':
4325 case 'b':
4326 {
4327 if (LocaleCompare(attribute,"background") == 0)
4328 {
4329 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4330 AllCompliance,&background_color,exception);
4331 break;
4332 }
4333 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4334 attribute);
4335 break;
4336 }
4337 default:
4338 {
4339 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4340 attribute);
4341 break;
4342 }
4343 }
4344 }
4345 image->background_color=background_color;
4346 image=MergeImageLayers(image,FlattenLayer,exception);
4347 if (image == (Image *) NULL)
4348 goto PerlException;
4349 /*
4350 Create blessed Perl array for the returned image.
4351 */
4352 av=newAV();
4353 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4354 SvREFCNT_dec(av);
4355 AddImageToRegistry(sv,image);
4356 rv=newRV(sv);
4357 av_push(av,sv_bless(rv,hv));
4358 SvREFCNT_dec(sv);
4359 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004360 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4361 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004362 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4363 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004364 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004365 SetImageInfo(info->image_info,0,exception);
4366 exception=DestroyExceptionInfo(exception);
4367 SvREFCNT_dec(perl_exception);
4368 XSRETURN(1);
4369
4370 PerlException:
4371 InheritPerlException(exception,perl_exception);
4372 exception=DestroyExceptionInfo(exception);
4373 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4374 SvPOK_on(perl_exception); /* return messages in string context */
4375 ST(0)=sv_2mortal(perl_exception);
4376 XSRETURN(1);
4377 }
4378
4379#
4380###############################################################################
4381# #
4382# #
4383# #
4384# F x #
4385# #
4386# #
4387# #
4388###############################################################################
4389#
4390#
4391void
4392Fx(ref,...)
4393 Image::Magick ref=NO_INIT
4394 ALIAS:
4395 FxImage = 1
4396 fx = 2
4397 fximage = 3
4398 PPCODE:
4399 {
4400 AV
4401 *av;
4402
4403 char
4404 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004405 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004406
4407 ChannelType
4408 channel,
4409 channel_mask;
4410
4411 ExceptionInfo
4412 *exception;
4413
4414 HV
4415 *hv;
4416
4417 Image
4418 *image;
4419
4420 register ssize_t
4421 i;
4422
4423 struct PackageInfo
4424 *info;
4425
4426 SV
4427 *av_reference,
4428 *perl_exception,
4429 *reference,
4430 *rv,
4431 *sv;
4432
4433 PERL_UNUSED_VAR(ref);
4434 PERL_UNUSED_VAR(ix);
4435 exception=AcquireExceptionInfo();
4436 perl_exception=newSVpv("",0);
4437 sv=NULL;
4438 attribute=NULL;
4439 av=NULL;
4440 if (sv_isobject(ST(0)) == 0)
4441 {
4442 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4443 PackageName);
4444 goto PerlException;
4445 }
4446 reference=SvRV(ST(0));
4447 hv=SvSTASH(reference);
4448 av=newAV();
4449 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4450 SvREFCNT_dec(av);
4451 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4452 if (image == (Image *) NULL)
4453 {
4454 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4455 PackageName);
4456 goto PerlException;
4457 }
4458 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4459 /*
4460 Get options.
4461 */
4462 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004463 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004464 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004465 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004466 else
4467 for (i=2; i < items; i+=2)
4468 {
4469 attribute=(char *) SvPV(ST(i-1),na);
4470 switch (*attribute)
4471 {
4472 case 'C':
4473 case 'c':
4474 {
4475 if (LocaleCompare(attribute,"channel") == 0)
4476 {
4477 ssize_t
4478 option;
4479
4480 option=ParseChannelOption(SvPV(ST(i),na));
4481 if (option < 0)
4482 {
4483 ThrowPerlException(exception,OptionError,
4484 "UnrecognizedType",SvPV(ST(i),na));
4485 return;
4486 }
4487 channel=(ChannelType) option;
4488 break;
4489 }
4490 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4491 attribute);
4492 break;
4493 }
4494 case 'E':
4495 case 'e':
4496 {
4497 if (LocaleCompare(attribute,"expression") == 0)
4498 {
4499 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004500 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004501 break;
4502 }
4503 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4504 attribute);
4505 break;
4506 }
4507 default:
4508 {
4509 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4510 attribute);
4511 break;
4512 }
4513 }
4514 }
4515 channel_mask=SetImageChannelMask(image,channel);
4516 image=FxImage(image,expression,exception);
4517 if (image != (Image *) NULL)
4518 (void) SetImageChannelMask(image,channel_mask);
4519 if (image == (Image *) NULL)
4520 goto PerlException;
4521 for ( ; image; image=image->next)
4522 {
4523 AddImageToRegistry(sv,image);
4524 rv=newRV(sv);
4525 av_push(av,sv_bless(rv,hv));
4526 SvREFCNT_dec(sv);
4527 }
4528 exception=DestroyExceptionInfo(exception);
4529 ST(0)=av_reference;
4530 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4531 XSRETURN(1);
4532
4533 PerlException:
4534 InheritPerlException(exception,perl_exception);
4535 exception=DestroyExceptionInfo(exception);
4536 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4537 SvPOK_on(perl_exception);
4538 ST(0)=sv_2mortal(perl_exception);
4539 XSRETURN(1);
4540 }
4541
4542#
4543###############################################################################
4544# #
4545# #
4546# #
4547# G e t #
4548# #
4549# #
4550# #
4551###############################################################################
4552#
4553#
4554void
4555Get(ref,...)
4556 Image::Magick ref=NO_INIT
4557 ALIAS:
4558 GetAttributes = 1
4559 GetAttribute = 2
4560 get = 3
4561 getattributes = 4
4562 getattribute = 5
4563 PPCODE:
4564 {
4565 char
4566 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004567 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004568
4569 const char
4570 *value;
4571
4572 ExceptionInfo
4573 *exception;
4574
4575 Image
4576 *image;
4577
4578 long
4579 j;
4580
4581 register ssize_t
4582 i;
4583
4584 struct PackageInfo
4585 *info;
4586
4587 SV
4588 *perl_exception,
4589 *reference,
4590 *s;
4591
4592 PERL_UNUSED_VAR(ref);
4593 PERL_UNUSED_VAR(ix);
4594 exception=AcquireExceptionInfo();
4595 perl_exception=newSVpv("",0);
4596 if (sv_isobject(ST(0)) == 0)
4597 {
4598 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4599 PackageName);
4600 XSRETURN_EMPTY;
4601 }
4602 reference=SvRV(ST(0));
4603 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4604 if (image == (Image *) NULL && !info)
4605 XSRETURN_EMPTY;
4606 EXTEND(sp,items);
4607 for (i=1; i < items; i++)
4608 {
4609 attribute=(char *) SvPV(ST(i),na);
4610 s=NULL;
4611 switch (*attribute)
4612 {
4613 case 'A':
4614 case 'a':
4615 {
4616 if (LocaleCompare(attribute,"adjoin") == 0)
4617 {
4618 if (info)
4619 s=newSViv((ssize_t) info->image_info->adjoin);
4620 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4621 continue;
4622 }
4623 if (LocaleCompare(attribute,"antialias") == 0)
4624 {
4625 if (info)
4626 s=newSViv((ssize_t) info->image_info->antialias);
4627 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4628 continue;
4629 }
4630 if (LocaleCompare(attribute,"area") == 0)
4631 {
4632 s=newSViv(GetMagickResource(AreaResource));
4633 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4634 continue;
4635 }
4636 if (LocaleCompare(attribute,"attenuate") == 0)
4637 {
4638 const char
4639 *value;
4640
4641 value=GetImageProperty(image,attribute,exception);
4642 if (value != (const char *) NULL)
4643 s=newSVpv(value,0);
4644 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4645 continue;
4646 }
4647 if (LocaleCompare(attribute,"authenticate") == 0)
4648 {
4649 if (info)
4650 {
4651 const char
4652 *option;
4653
4654 option=GetImageOption(info->image_info,attribute);
4655 if (option != (const char *) NULL)
4656 s=newSVpv(option,0);
4657 }
4658 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4659 continue;
4660 }
4661 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4662 attribute);
4663 break;
4664 }
4665 case 'B':
4666 case 'b':
4667 {
4668 if (LocaleCompare(attribute,"background") == 0)
4669 {
4670 if (image == (Image *) NULL)
4671 break;
cristy151b66d2015-04-15 10:50:31 +00004672 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004673 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4674 (double) image->background_color.green,
4675 (double) image->background_color.blue,
4676 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004677 s=newSVpv(color,0);
4678 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4679 continue;
4680 }
4681 if (LocaleCompare(attribute,"base-columns") == 0)
4682 {
4683 if (image != (Image *) NULL)
4684 s=newSViv((ssize_t) image->magick_columns);
4685 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4686 continue;
4687 }
4688 if (LocaleCompare(attribute,"base-filename") == 0)
4689 {
4690 if (image != (Image *) NULL)
4691 s=newSVpv(image->magick_filename,0);
4692 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4693 continue;
4694 }
4695 if (LocaleCompare(attribute,"base-height") == 0)
4696 {
4697 if (image != (Image *) NULL)
4698 s=newSViv((ssize_t) image->magick_rows);
4699 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4700 continue;
4701 }
4702 if (LocaleCompare(attribute,"base-rows") == 0)
4703 {
4704 if (image != (Image *) NULL)
4705 s=newSViv((ssize_t) image->magick_rows);
4706 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4707 continue;
4708 }
4709 if (LocaleCompare(attribute,"base-width") == 0)
4710 {
4711 if (image != (Image *) NULL)
4712 s=newSViv((ssize_t) image->magick_columns);
4713 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4714 continue;
4715 }
4716 if (LocaleCompare(attribute,"blue-primary") == 0)
4717 {
4718 if (image == (Image *) NULL)
4719 break;
cristy151b66d2015-04-15 10:50:31 +00004720 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00004721 image->chromaticity.blue_primary.x,
4722 image->chromaticity.blue_primary.y);
4723 s=newSVpv(color,0);
4724 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4725 continue;
4726 }
4727 if (LocaleCompare(attribute,"bordercolor") == 0)
4728 {
4729 if (image == (Image *) NULL)
4730 break;
cristy151b66d2015-04-15 10:50:31 +00004731 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004732 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4733 (double) image->border_color.green,
4734 (double) image->border_color.blue,
4735 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004736 s=newSVpv(color,0);
4737 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4738 continue;
4739 }
4740 if (LocaleCompare(attribute,"bounding-box") == 0)
4741 {
4742 char
cristy151b66d2015-04-15 10:50:31 +00004743 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004744
4745 RectangleInfo
4746 page;
4747
4748 if (image == (Image *) NULL)
4749 break;
4750 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004751 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004752 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4753 page.height,(double) page.x,(double) page.y);
4754 s=newSVpv(geometry,0);
4755 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4756 continue;
4757 }
4758 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4759 attribute);
4760 break;
4761 }
4762 case 'C':
4763 case 'c':
4764 {
4765 if (LocaleCompare(attribute,"class") == 0)
4766 {
4767 if (image == (Image *) NULL)
4768 break;
4769 s=newSViv(image->storage_class);
4770 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4771 image->storage_class));
4772 SvIOK_on(s);
4773 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4774 continue;
4775 }
4776 if (LocaleCompare(attribute,"clip-mask") == 0)
4777 {
4778 if (image != (Image *) NULL)
4779 {
4780 Image
4781 *mask_image;
4782
4783 SV
4784 *sv;
4785
4786 sv=NULL;
4787 if (image->read_mask == MagickFalse)
4788 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004789 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004790 if (mask_image != (Image *) NULL)
4791 {
4792 AddImageToRegistry(sv,mask_image);
4793 s=sv_bless(newRV(sv),SvSTASH(reference));
4794 }
4795 }
4796 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4797 continue;
4798 }
4799 if (LocaleCompare(attribute,"clip-path") == 0)
4800 {
4801 if (image != (Image *) NULL)
4802 {
4803 Image
4804 *mask_image;
4805
4806 SV
4807 *sv;
4808
4809 sv=NULL;
4810 if (image->read_mask != MagickFalse)
4811 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004812 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004813 if (mask_image != (Image *) NULL)
4814 {
4815 AddImageToRegistry(sv,mask_image);
4816 s=sv_bless(newRV(sv),SvSTASH(reference));
4817 }
4818 }
4819 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4820 continue;
4821 }
4822 if (LocaleCompare(attribute,"compression") == 0)
4823 {
4824 j=info ? info->image_info->compression : image ?
4825 image->compression : UndefinedCompression;
4826 if (info)
4827 if (info->image_info->compression == UndefinedCompression)
4828 j=image->compression;
4829 s=newSViv(j);
4830 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4831 j));
4832 SvIOK_on(s);
4833 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4834 continue;
4835 }
4836 if (LocaleCompare(attribute,"colorspace") == 0)
4837 {
4838 j=image ? image->colorspace : RGBColorspace;
4839 s=newSViv(j);
4840 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4841 j));
4842 SvIOK_on(s);
4843 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4844 continue;
4845 }
4846 if (LocaleCompare(attribute,"colors") == 0)
4847 {
4848 if (image != (Image *) NULL)
4849 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4850 exception));
4851 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4852 continue;
4853 }
4854 if (LocaleNCompare(attribute,"colormap",8) == 0)
4855 {
4856 int
4857 items;
4858
4859 if (image == (Image *) NULL || !image->colormap)
4860 break;
4861 j=0;
4862 items=sscanf(attribute,"%*[^[][%ld",&j);
4863 (void) items;
4864 if (j > (ssize_t) image->colors)
4865 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004866 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004867 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4868 (double) image->colormap[j].green,
4869 (double) image->colormap[j].blue,
4870 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004871 s=newSVpv(color,0);
4872 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4873 continue;
4874 }
4875 if (LocaleCompare(attribute,"columns") == 0)
4876 {
4877 if (image != (Image *) NULL)
4878 s=newSViv((ssize_t) image->columns);
4879 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4880 continue;
4881 }
4882 if (LocaleCompare(attribute,"comment") == 0)
4883 {
4884 const char
4885 *value;
4886
4887 value=GetImageProperty(image,attribute,exception);
4888 if (value != (const char *) NULL)
4889 s=newSVpv(value,0);
4890 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4891 continue;
4892 }
4893 if (LocaleCompare(attribute,"copyright") == 0)
4894 {
4895 s=newSVpv(GetMagickCopyright(),0);
4896 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4897 continue;
4898 }
4899 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4900 attribute);
4901 break;
4902 }
4903 case 'D':
4904 case 'd':
4905 {
4906 if (LocaleCompare(attribute,"density") == 0)
4907 {
4908 char
cristy151b66d2015-04-15 10:50:31 +00004909 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004910
4911 if (image == (Image *) NULL)
4912 break;
cristy151b66d2015-04-15 10:50:31 +00004913 (void) FormatLocaleString(geometry,MagickPathExtent,"%.15gx%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00004914 image->resolution.x,image->resolution.y);
4915 s=newSVpv(geometry,0);
4916 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4917 continue;
4918 }
4919 if (LocaleCompare(attribute,"delay") == 0)
4920 {
4921 if (image != (Image *) NULL)
4922 s=newSViv((ssize_t) image->delay);
4923 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4924 continue;
4925 }
4926 if (LocaleCompare(attribute,"depth") == 0)
4927 {
4928 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4929 if (image != (Image *) NULL)
4930 s=newSViv((ssize_t) GetImageDepth(image,exception));
4931 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4932 continue;
4933 }
4934 if (LocaleCompare(attribute,"directory") == 0)
4935 {
4936 if (image && image->directory)
4937 s=newSVpv(image->directory,0);
4938 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4939 continue;
4940 }
4941 if (LocaleCompare(attribute,"dispose") == 0)
4942 {
4943 if (image == (Image *) NULL)
4944 break;
4945
4946 s=newSViv(image->dispose);
4947 (void) sv_setpv(s,
4948 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
4949 SvIOK_on(s);
4950 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4951 continue;
4952 }
4953 if (LocaleCompare(attribute,"disk") == 0)
4954 {
4955 s=newSViv(GetMagickResource(DiskResource));
4956 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4957 continue;
4958 }
4959 if (LocaleCompare(attribute,"dither") == 0)
4960 {
4961 if (info)
4962 s=newSViv((ssize_t) info->image_info->dither);
4963 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4964 continue;
4965 }
4966 if (LocaleCompare(attribute,"display") == 0) /* same as server */
4967 {
4968 if (info && info->image_info->server_name)
4969 s=newSVpv(info->image_info->server_name,0);
4970 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4971 continue;
4972 }
4973 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4974 attribute);
4975 break;
4976 }
4977 case 'E':
4978 case 'e':
4979 {
4980 if (LocaleCompare(attribute,"elapsed-time") == 0)
4981 {
4982 if (image != (Image *) NULL)
4983 s=newSVnv(GetElapsedTime(&image->timer));
4984 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4985 continue;
4986 }
4987 if (LocaleCompare(attribute,"endian") == 0)
4988 {
4989 j=info ? info->image_info->endian : image ? image->endian :
4990 UndefinedEndian;
4991 s=newSViv(j);
4992 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
4993 SvIOK_on(s);
4994 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4995 continue;
4996 }
4997 if (LocaleCompare(attribute,"error") == 0)
4998 {
4999 if (image != (Image *) NULL)
5000 s=newSVnv(image->error.mean_error_per_pixel);
5001 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5002 continue;
5003 }
5004 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5005 attribute);
5006 break;
5007 }
5008 case 'F':
5009 case 'f':
5010 {
5011 if (LocaleCompare(attribute,"filesize") == 0)
5012 {
5013 if (image != (Image *) NULL)
5014 s=newSViv((ssize_t) GetBlobSize(image));
5015 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5016 continue;
5017 }
5018 if (LocaleCompare(attribute,"filename") == 0)
5019 {
5020 if (info && info->image_info->filename &&
5021 *info->image_info->filename)
5022 s=newSVpv(info->image_info->filename,0);
5023 if (image != (Image *) NULL)
5024 s=newSVpv(image->filename,0);
5025 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5026 continue;
5027 }
5028 if (LocaleCompare(attribute,"filter") == 0)
5029 {
5030 s=image ? newSViv(image->filter) : newSViv(0);
5031 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5032 image->filter));
5033 SvIOK_on(s);
5034 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5035 continue;
5036 }
5037 if (LocaleCompare(attribute,"font") == 0)
5038 {
5039 if (info && info->image_info->font)
5040 s=newSVpv(info->image_info->font,0);
5041 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5042 continue;
5043 }
5044 if (LocaleCompare(attribute,"foreground") == 0)
5045 continue;
5046 if (LocaleCompare(attribute,"format") == 0)
5047 {
5048 const MagickInfo
5049 *magick_info;
5050
5051 magick_info=(const MagickInfo *) NULL;
5052 if (info && (*info->image_info->magick != '\0'))
5053 magick_info=GetMagickInfo(info->image_info->magick,exception);
5054 if (image != (Image *) NULL)
5055 magick_info=GetMagickInfo(image->magick,exception);
5056 if ((magick_info != (const MagickInfo *) NULL) &&
5057 (*magick_info->description != '\0'))
5058 s=newSVpv((char *) magick_info->description,0);
5059 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5060 continue;
5061 }
5062 if (LocaleCompare(attribute,"fuzz") == 0)
5063 {
5064 if (info)
5065 s=newSVnv(info->image_info->fuzz);
5066 if (image != (Image *) NULL)
5067 s=newSVnv(image->fuzz);
5068 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5069 continue;
5070 }
5071 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5072 attribute);
5073 break;
5074 }
5075 case 'G':
5076 case 'g':
5077 {
5078 if (LocaleCompare(attribute,"gamma") == 0)
5079 {
5080 if (image != (Image *) NULL)
5081 s=newSVnv(image->gamma);
5082 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5083 continue;
5084 }
5085 if (LocaleCompare(attribute,"geometry") == 0)
5086 {
5087 if (image && image->geometry)
5088 s=newSVpv(image->geometry,0);
5089 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5090 continue;
5091 }
5092 if (LocaleCompare(attribute,"gravity") == 0)
5093 {
5094 s=image ? newSViv(image->gravity) : newSViv(0);
5095 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5096 image->gravity));
5097 SvIOK_on(s);
5098 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5099 continue;
5100 }
5101 if (LocaleCompare(attribute,"green-primary") == 0)
5102 {
5103 if (image == (Image *) NULL)
5104 break;
cristy151b66d2015-04-15 10:50:31 +00005105 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005106 image->chromaticity.green_primary.x,
5107 image->chromaticity.green_primary.y);
5108 s=newSVpv(color,0);
5109 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5110 continue;
5111 }
5112 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5113 attribute);
5114 break;
5115 }
5116 case 'H':
5117 case 'h':
5118 {
5119 if (LocaleCompare(attribute,"height") == 0)
5120 {
5121 if (image != (Image *) NULL)
5122 s=newSViv((ssize_t) image->rows);
5123 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5124 continue;
5125 }
5126 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5127 attribute);
5128 break;
5129 }
5130 case 'I':
5131 case 'i':
5132 {
5133 if (LocaleCompare(attribute,"icc") == 0)
5134 {
5135 if (image != (Image *) NULL)
5136 {
5137 const StringInfo
5138 *profile;
5139
5140 profile=GetImageProfile(image,"icc");
5141 if (profile != (StringInfo *) NULL)
5142 s=newSVpv((const char *) GetStringInfoDatum(profile),
5143 GetStringInfoLength(profile));
5144 }
5145 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5146 continue;
5147 }
5148 if (LocaleCompare(attribute,"icm") == 0)
5149 {
5150 if (image != (Image *) NULL)
5151 {
5152 const StringInfo
5153 *profile;
5154
5155 profile=GetImageProfile(image,"icm");
5156 if (profile != (const StringInfo *) NULL)
5157 s=newSVpv((const char *) GetStringInfoDatum(profile),
5158 GetStringInfoLength(profile));
5159 }
5160 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5161 continue;
5162 }
5163 if (LocaleCompare(attribute,"id") == 0)
5164 {
5165 if (image != (Image *) NULL)
5166 {
5167 char
cristy151b66d2015-04-15 10:50:31 +00005168 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005169
5170 MagickBooleanType
5171 status;
5172
5173 static ssize_t
5174 id = 0;
5175
cristy151b66d2015-04-15 10:50:31 +00005176 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005177 id);
5178 status=SetImageRegistry(ImageRegistryType,key,image,
5179 exception);
5180 (void) status;
5181 s=newSViv(id++);
5182 }
5183 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5184 continue;
5185 }
5186 if (LocaleNCompare(attribute,"index",5) == 0)
5187 {
5188 char
cristy151b66d2015-04-15 10:50:31 +00005189 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005190
5191 int
5192 items;
5193
5194 long
5195 x,
5196 y;
5197
5198 register const Quantum
5199 *p;
5200
5201 CacheView
5202 *image_view;
5203
5204 if (image == (Image *) NULL)
5205 break;
5206 if (image->storage_class != PseudoClass)
5207 break;
5208 x=0;
5209 y=0;
5210 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5211 (void) items;
5212 image_view=AcquireVirtualCacheView(image,exception);
5213 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5214 if (p != (const Quantum *) NULL)
5215 {
cristy151b66d2015-04-15 10:50:31 +00005216 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005217 GetPixelIndex(image,p));
5218 s=newSVpv(name,0);
5219 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5220 }
5221 image_view=DestroyCacheView(image_view);
5222 continue;
5223 }
5224 if (LocaleCompare(attribute,"iptc") == 0)
5225 {
5226 if (image != (Image *) NULL)
5227 {
5228 const StringInfo
5229 *profile;
5230
5231 profile=GetImageProfile(image,"iptc");
5232 if (profile != (const StringInfo *) NULL)
5233 s=newSVpv((const char *) GetStringInfoDatum(profile),
5234 GetStringInfoLength(profile));
5235 }
5236 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5237 continue;
5238 }
5239 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5240 {
5241 if (image != (Image *) NULL)
5242 s=newSViv((ssize_t) image->iterations);
5243 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5244 continue;
5245 }
5246 if (LocaleCompare(attribute,"interlace") == 0)
5247 {
5248 j=info ? info->image_info->interlace : image ? image->interlace :
5249 UndefinedInterlace;
5250 s=newSViv(j);
5251 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5252 j));
5253 SvIOK_on(s);
5254 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5255 continue;
5256 }
5257 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5258 attribute);
5259 break;
5260 }
5261 case 'L':
5262 case 'l':
5263 {
5264 if (LocaleCompare(attribute,"label") == 0)
5265 {
5266 const char
5267 *value;
5268
5269 if (image == (Image *) NULL)
5270 break;
5271 value=GetImageProperty(image,"Label",exception);
5272 if (value != (const char *) NULL)
5273 s=newSVpv(value,0);
5274 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5275 continue;
5276 }
5277 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5278 {
5279 if (image != (Image *) NULL)
5280 s=newSViv((ssize_t) image->iterations);
5281 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5282 continue;
5283 }
5284 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5285 attribute);
5286 break;
5287 }
5288 case 'M':
5289 case 'm':
5290 {
5291 if (LocaleCompare(attribute,"magick") == 0)
5292 {
5293 if (info && *info->image_info->magick)
5294 s=newSVpv(info->image_info->magick,0);
5295 if (image != (Image *) NULL)
5296 s=newSVpv(image->magick,0);
5297 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5298 continue;
5299 }
5300 if (LocaleCompare(attribute,"map") == 0)
5301 {
5302 s=newSViv(GetMagickResource(MapResource));
5303 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5304 continue;
5305 }
5306 if (LocaleCompare(attribute,"maximum-error") == 0)
5307 {
5308 if (image != (Image *) NULL)
5309 s=newSVnv(image->error.normalized_maximum_error);
5310 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5311 continue;
5312 }
5313 if (LocaleCompare(attribute,"memory") == 0)
5314 {
5315 s=newSViv(GetMagickResource(MemoryResource));
5316 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5317 continue;
5318 }
5319 if (LocaleCompare(attribute,"mean-error") == 0)
5320 {
5321 if (image != (Image *) NULL)
5322 s=newSVnv(image->error.normalized_mean_error);
5323 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5324 continue;
5325 }
5326 if (LocaleCompare(attribute,"mime") == 0)
5327 {
5328 if (info && *info->image_info->magick)
5329 s=newSVpv(MagickToMime(info->image_info->magick),0);
5330 if (image != (Image *) NULL)
5331 s=newSVpv(MagickToMime(image->magick),0);
5332 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5333 continue;
5334 }
5335 if (LocaleCompare(attribute,"mattecolor") == 0)
5336 {
5337 if (image == (Image *) NULL)
5338 break;
cristy151b66d2015-04-15 10:50:31 +00005339 (void) FormatLocaleString(color,MagickPathExtent,
Cristy8645e042016-02-03 16:35:29 -05005340 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5341 (double) image->alpha_color.green,
5342 (double) image->alpha_color.blue,
5343 (double) image->alpha_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005344 s=newSVpv(color,0);
5345 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5346 continue;
5347 }
5348 if (LocaleCompare(attribute,"matte") == 0)
5349 {
5350 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005351 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005352 1 : 0);
5353 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5354 continue;
5355 }
5356 if (LocaleCompare(attribute,"mime") == 0)
5357 {
5358 const char
5359 *magick;
5360
5361 magick=NULL;
5362 if (info && *info->image_info->magick)
5363 magick=info->image_info->magick;
5364 if (image != (Image *) NULL)
5365 magick=image->magick;
5366 if (magick)
5367 {
5368 char
5369 *mime;
5370
5371 mime=MagickToMime(magick);
5372 s=newSVpv(mime,0);
5373 mime=(char *) RelinquishMagickMemory(mime);
5374 }
5375 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5376 continue;
5377 }
5378 if (LocaleCompare(attribute,"monochrome") == 0)
5379 {
5380 if (image == (Image *) NULL)
5381 continue;
5382 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005383 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005384 s=newSViv(j);
5385 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5386 continue;
5387 }
5388 if (LocaleCompare(attribute,"montage") == 0)
5389 {
5390 if (image && image->montage)
5391 s=newSVpv(image->montage,0);
5392 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5393 continue;
5394 }
5395 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5396 attribute);
5397 break;
5398 }
5399 case 'O':
5400 case 'o':
5401 {
5402 if (LocaleCompare(attribute,"orientation") == 0)
5403 {
5404 j=info ? info->image_info->orientation : image ?
5405 image->orientation : UndefinedOrientation;
5406 s=newSViv(j);
5407 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5408 j));
5409 SvIOK_on(s);
5410 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5411 continue;
5412 }
5413 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5414 attribute);
5415 break;
5416 }
5417 case 'P':
5418 case 'p':
5419 {
5420 if (LocaleCompare(attribute,"page") == 0)
5421 {
5422 if (info && info->image_info->page)
5423 s=newSVpv(info->image_info->page,0);
5424 if (image != (Image *) NULL)
5425 {
5426 char
cristy151b66d2015-04-15 10:50:31 +00005427 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005428
cristy151b66d2015-04-15 10:50:31 +00005429 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005430 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5431 (double) image->page.height,(double) image->page.x,(double)
5432 image->page.y);
5433 s=newSVpv(geometry,0);
5434 }
5435 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5436 continue;
5437 }
5438 if (LocaleCompare(attribute,"page.x") == 0)
5439 {
5440 if (image != (Image *) NULL)
5441 s=newSViv((ssize_t) image->page.x);
5442 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5443 continue;
5444 }
5445 if (LocaleCompare(attribute,"page.y") == 0)
5446 {
5447 if (image != (Image *) NULL)
5448 s=newSViv((ssize_t) image->page.y);
5449 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5450 continue;
5451 }
5452 if (LocaleNCompare(attribute,"pixel",5) == 0)
5453 {
5454 char
cristy151b66d2015-04-15 10:50:31 +00005455 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005456
5457 int
5458 items;
5459
5460 long
5461 x,
5462 y;
5463
5464 register const Quantum
5465 *p;
5466
5467 if (image == (Image *) NULL)
5468 break;
5469 x=0;
5470 y=0;
5471 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5472 (void) items;
5473 p=GetVirtualPixels(image,x,y,1,1,exception);
5474 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005475 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005476 QuantumFormat "," QuantumFormat "," QuantumFormat,
5477 GetPixelRed(image,p),GetPixelGreen(image,p),
5478 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5479 else
cristy151b66d2015-04-15 10:50:31 +00005480 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005481 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5482 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5483 GetPixelBlue(image,p),GetPixelBlack(image,p),
5484 GetPixelAlpha(image,p));
5485 s=newSVpv(tuple,0);
5486 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5487 continue;
5488 }
5489 if (LocaleCompare(attribute,"pointsize") == 0)
5490 {
5491 if (info)
5492 s=newSViv((ssize_t) info->image_info->pointsize);
5493 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5494 continue;
5495 }
5496 if (LocaleCompare(attribute,"preview") == 0)
5497 {
5498 s=newSViv(info->image_info->preview_type);
5499 (void) sv_setpv(s,CommandOptionToMnemonic(MagickPreviewOptions,
5500 info->image_info->preview_type));
5501 SvIOK_on(s);
5502 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5503 continue;
5504 }
5505 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5506 attribute);
5507 break;
5508 }
5509 case 'Q':
5510 case 'q':
5511 {
5512 if (LocaleCompare(attribute,"quality") == 0)
5513 {
5514 if (info)
5515 s=newSViv((ssize_t) info->image_info->quality);
5516 if (image != (Image *) NULL)
5517 s=newSViv((ssize_t) image->quality);
5518 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5519 continue;
5520 }
5521 if (LocaleCompare(attribute,"quantum") == 0)
5522 {
5523 if (info)
5524 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5525 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5526 continue;
5527 }
5528 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5529 attribute);
5530 break;
5531 }
5532 case 'R':
5533 case 'r':
5534 {
5535 if (LocaleCompare(attribute,"rendering-intent") == 0)
5536 {
5537 s=newSViv(image->rendering_intent);
5538 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5539 image->rendering_intent));
5540 SvIOK_on(s);
5541 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5542 continue;
5543 }
5544 if (LocaleCompare(attribute,"red-primary") == 0)
5545 {
5546 if (image == (Image *) NULL)
5547 break;
cristy151b66d2015-04-15 10:50:31 +00005548 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005549 image->chromaticity.red_primary.x,
5550 image->chromaticity.red_primary.y);
5551 s=newSVpv(color,0);
5552 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5553 continue;
5554 }
5555 if (LocaleCompare(attribute,"rows") == 0)
5556 {
5557 if (image != (Image *) NULL)
5558 s=newSViv((ssize_t) image->rows);
5559 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5560 continue;
5561 }
5562 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5563 attribute);
5564 break;
5565 }
5566 case 'S':
5567 case 's':
5568 {
5569 if (LocaleCompare(attribute,"sampling-factor") == 0)
5570 {
5571 if (info && info->image_info->sampling_factor)
5572 s=newSVpv(info->image_info->sampling_factor,0);
5573 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5574 continue;
5575 }
5576 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5577 {
5578 if (info && info->image_info->server_name)
5579 s=newSVpv(info->image_info->server_name,0);
5580 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5581 continue;
5582 }
5583 if (LocaleCompare(attribute,"size") == 0)
5584 {
5585 if (info && info->image_info->size)
5586 s=newSVpv(info->image_info->size,0);
5587 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5588 continue;
5589 }
5590 if (LocaleCompare(attribute,"scene") == 0)
5591 {
5592 if (image != (Image *) NULL)
5593 s=newSViv((ssize_t) image->scene);
5594 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5595 continue;
5596 }
5597 if (LocaleCompare(attribute,"scenes") == 0)
5598 {
5599 if (image != (Image *) NULL)
5600 s=newSViv((ssize_t) info->image_info->number_scenes);
5601 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5602 continue;
5603 }
5604 if (LocaleCompare(attribute,"signature") == 0)
5605 {
5606 const char
5607 *value;
5608
5609 if (image == (Image *) NULL)
5610 break;
5611 (void) SignatureImage(image,exception);
5612 value=GetImageProperty(image,"Signature",exception);
5613 if (value != (const char *) NULL)
5614 s=newSVpv(value,0);
5615 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5616 continue;
5617 }
5618 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5619 attribute);
5620 break;
5621 }
5622 case 'T':
5623 case 't':
5624 {
5625 if (LocaleCompare(attribute,"taint") == 0)
5626 {
5627 if (image != (Image *) NULL)
5628 s=newSViv((ssize_t) IsTaintImage(image));
5629 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5630 continue;
5631 }
5632 if (LocaleCompare(attribute,"texture") == 0)
5633 {
5634 if (info && info->image_info->texture)
5635 s=newSVpv(info->image_info->texture,0);
5636 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5637 continue;
5638 }
5639 if (LocaleCompare(attribute,"total-ink-density") == 0)
5640 {
5641 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5642 if (image != (Image *) NULL)
5643 s=newSVnv(GetImageTotalInkDensity(image,exception));
5644 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5645 continue;
5646 }
5647 if (LocaleCompare(attribute,"transparent-color") == 0)
5648 {
5649 if (image == (Image *) NULL)
5650 break;
cristy151b66d2015-04-15 10:50:31 +00005651 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005652 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5653 (double) image->transparent_color.green,
5654 (double) image->transparent_color.blue,
5655 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005656 s=newSVpv(color,0);
5657 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5658 continue;
5659 }
5660 if (LocaleCompare(attribute,"type") == 0)
5661 {
5662 if (image == (Image *) NULL)
5663 break;
cristya26f54c2015-07-29 12:26:12 +00005664 j=(ssize_t) GetImageType(image);
cristy4a3ce0a2013-08-03 20:06:59 +00005665 s=newSViv(j);
5666 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5667 SvIOK_on(s);
5668 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5669 continue;
5670 }
5671 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5672 attribute);
5673 break;
5674 }
5675 case 'U':
5676 case 'u':
5677 {
5678 if (LocaleCompare(attribute,"units") == 0)
5679 {
5680 j=info ? info->image_info->units : image ? image->units :
5681 UndefinedResolution;
5682 if (info && (info->image_info->units == UndefinedResolution))
5683 if (image)
5684 j=image->units;
5685 if (j == UndefinedResolution)
5686 s=newSVpv("undefined units",0);
5687 else
5688 if (j == PixelsPerInchResolution)
5689 s=newSVpv("pixels / inch",0);
5690 else
5691 s=newSVpv("pixels / centimeter",0);
5692 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5693 continue;
5694 }
5695 if (LocaleCompare(attribute,"user-time") == 0)
5696 {
5697 if (image != (Image *) NULL)
5698 s=newSVnv(GetUserTime(&image->timer));
5699 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5700 continue;
5701 }
5702 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5703 attribute);
5704 break;
5705 }
5706 case 'V':
5707 case 'v':
5708 {
5709 if (LocaleCompare(attribute,"verbose") == 0)
5710 {
5711 if (info)
5712 s=newSViv((ssize_t) info->image_info->verbose);
5713 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5714 continue;
5715 }
5716 if (LocaleCompare(attribute,"version") == 0)
5717 {
5718 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5719 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5720 continue;
5721 }
cristy4a3ce0a2013-08-03 20:06:59 +00005722 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5723 {
5724 if (image == (Image *) NULL)
5725 break;
5726 j=(ssize_t) GetImageVirtualPixelMethod(image);
5727 s=newSViv(j);
5728 (void) sv_setpv(s,CommandOptionToMnemonic(
5729 MagickVirtualPixelOptions,j));
5730 SvIOK_on(s);
5731 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5732 continue;
5733 }
5734 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5735 attribute);
5736 break;
5737 }
5738 case 'W':
5739 case 'w':
5740 {
5741 if (LocaleCompare(attribute,"white-point") == 0)
5742 {
5743 if (image == (Image *) NULL)
5744 break;
cristy151b66d2015-04-15 10:50:31 +00005745 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005746 image->chromaticity.white_point.x,
5747 image->chromaticity.white_point.y);
5748 s=newSVpv(color,0);
5749 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5750 continue;
5751 }
5752 if (LocaleCompare(attribute,"width") == 0)
5753 {
5754 if (image != (Image *) NULL)
5755 s=newSViv((ssize_t) image->columns);
5756 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5757 continue;
5758 }
5759 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5760 attribute);
5761 break;
5762 }
5763 case 'X':
5764 case 'x':
5765 {
Cristyc1f9f9f2016-01-05 08:19:28 -05005766 if (LocaleCompare(attribute,"xmp") == 0)
5767 {
5768 if (image != (Image *) NULL)
5769 {
5770 const StringInfo
5771 *profile;
5772
5773 profile=GetImageProfile(image,"xmp");
5774 if (profile != (StringInfo *) NULL)
5775 s=newSVpv((const char *) GetStringInfoDatum(profile),
5776 GetStringInfoLength(profile));
5777 }
5778 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5779 continue;
5780 }
cristy4a3ce0a2013-08-03 20:06:59 +00005781 if (LocaleCompare(attribute,"x-resolution") == 0)
5782 {
5783 if (image != (Image *) NULL)
5784 s=newSVnv(image->resolution.x);
5785 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5786 continue;
5787 }
5788 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5789 attribute);
5790 break;
5791 }
5792 case 'Y':
5793 case 'y':
5794 {
5795 if (LocaleCompare(attribute,"y-resolution") == 0)
5796 {
5797 if (image != (Image *) NULL)
5798 s=newSVnv(image->resolution.y);
5799 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5800 continue;
5801 }
5802 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5803 attribute);
5804 break;
5805 }
5806 default:
5807 break;
5808 }
5809 if (image == (Image *) NULL)
5810 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5811 attribute)
5812 else
5813 {
5814 value=GetImageProperty(image,attribute,exception);
5815 if (value != (const char *) NULL)
5816 {
5817 s=newSVpv(value,0);
5818 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5819 }
5820 else
5821 if (*attribute != '%')
5822 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5823 attribute)
5824 else
5825 {
5826 char
5827 *meta;
5828
5829 meta=InterpretImageProperties(info ? info->image_info :
5830 (ImageInfo *) NULL,image,attribute,exception);
5831 s=newSVpv(meta,0);
5832 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5833 meta=(char *) RelinquishMagickMemory(meta);
5834 }
5835 }
5836 }
5837 exception=DestroyExceptionInfo(exception);
5838 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5839 }
5840
5841#
5842###############################################################################
5843# #
5844# #
5845# #
5846# G e t A u t h e n t i c P i x e l s #
5847# #
5848# #
5849# #
5850###############################################################################
5851#
5852#
5853void *
5854GetAuthenticPixels(ref,...)
5855 Image::Magick ref = NO_INIT
5856 ALIAS:
5857 getauthenticpixels = 1
5858 GetImagePixels = 2
5859 getimagepixels = 3
5860 CODE:
5861 {
5862 char
5863 *attribute;
5864
5865 ExceptionInfo
5866 *exception;
5867
5868 Image
5869 *image;
5870
5871 RectangleInfo
5872 region;
5873
5874 ssize_t
5875 i;
5876
5877 struct PackageInfo
5878 *info;
5879
5880 SV
5881 *perl_exception,
5882 *reference;
5883
5884 void
5885 *blob = NULL;
5886
5887 PERL_UNUSED_VAR(ref);
5888 PERL_UNUSED_VAR(ix);
5889 exception=AcquireExceptionInfo();
5890 perl_exception=newSVpv("",0);
5891 if (sv_isobject(ST(0)) == 0)
5892 {
5893 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5894 PackageName);
5895 goto PerlException;
5896 }
5897 reference=SvRV(ST(0));
5898
5899 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5900 if (image == (Image *) NULL)
5901 {
5902 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5903 PackageName);
5904 goto PerlException;
5905 }
5906
5907 region.x=0;
5908 region.y=0;
5909 region.width=image->columns;
5910 region.height=1;
5911 if (items == 1)
5912 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5913 for (i=2; i < items; i+=2)
5914 {
5915 attribute=(char *) SvPV(ST(i-1),na);
5916 switch (*attribute)
5917 {
5918 case 'g':
5919 case 'G':
5920 {
5921 if (LocaleCompare(attribute,"geometry") == 0)
5922 {
5923 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5924 break;
5925 }
5926 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5927 attribute);
5928 break;
5929 }
5930 case 'H':
5931 case 'h':
5932 {
5933 if (LocaleCompare(attribute,"height") == 0)
5934 {
5935 region.height=SvIV(ST(i));
5936 continue;
5937 }
5938 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5939 attribute);
5940 break;
5941 }
5942 case 'X':
5943 case 'x':
5944 {
5945 if (LocaleCompare(attribute,"x") == 0)
5946 {
5947 region.x=SvIV(ST(i));
5948 continue;
5949 }
5950 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5951 attribute);
5952 break;
5953 }
5954 case 'Y':
5955 case 'y':
5956 {
5957 if (LocaleCompare(attribute,"y") == 0)
5958 {
5959 region.y=SvIV(ST(i));
5960 continue;
5961 }
5962 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5963 attribute);
5964 break;
5965 }
5966 case 'W':
5967 case 'w':
5968 {
5969 if (LocaleCompare(attribute,"width") == 0)
5970 {
5971 region.width=SvIV(ST(i));
5972 continue;
5973 }
5974 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5975 attribute);
5976 break;
5977 }
5978 }
5979 }
5980 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5981 region.height,exception);
5982 if (blob != (void *) NULL)
5983 goto PerlEnd;
5984
5985 PerlException:
5986 InheritPerlException(exception,perl_exception);
5987 exception=DestroyExceptionInfo(exception);
5988 SvREFCNT_dec(perl_exception); /* throw away all errors */
5989
5990 PerlEnd:
5991 RETVAL = blob;
5992 }
5993 OUTPUT:
5994 RETVAL
5995
5996#
5997###############################################################################
5998# #
5999# #
6000# #
6001# G e t V i r t u a l P i x e l s #
6002# #
6003# #
6004# #
6005###############################################################################
6006#
6007#
6008void *
6009GetVirtualPixels(ref,...)
6010 Image::Magick ref = NO_INIT
6011 ALIAS:
6012 getvirtualpixels = 1
6013 AcquireImagePixels = 2
6014 acquireimagepixels = 3
6015 CODE:
6016 {
6017 char
6018 *attribute;
6019
6020 const void
6021 *blob = NULL;
6022
6023 ExceptionInfo
6024 *exception;
6025
6026 Image
6027 *image;
6028
6029 RectangleInfo
6030 region;
6031
6032 ssize_t
6033 i;
6034
6035 struct PackageInfo
6036 *info;
6037
6038 SV
6039 *perl_exception,
6040 *reference;
6041
6042 PERL_UNUSED_VAR(ref);
6043 PERL_UNUSED_VAR(ix);
6044 exception=AcquireExceptionInfo();
6045 perl_exception=newSVpv("",0);
6046 if (sv_isobject(ST(0)) == 0)
6047 {
6048 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6049 PackageName);
6050 goto PerlException;
6051 }
6052 reference=SvRV(ST(0));
6053
6054 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6055 if (image == (Image *) NULL)
6056 {
6057 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6058 PackageName);
6059 goto PerlException;
6060 }
6061
6062 region.x=0;
6063 region.y=0;
6064 region.width=image->columns;
6065 region.height=1;
6066 if (items == 1)
6067 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6068 for (i=2; i < items; i+=2)
6069 {
6070 attribute=(char *) SvPV(ST(i-1),na);
6071 switch (*attribute)
6072 {
6073 case 'g':
6074 case 'G':
6075 {
6076 if (LocaleCompare(attribute,"geometry") == 0)
6077 {
6078 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6079 break;
6080 }
6081 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6082 attribute);
6083 break;
6084 }
6085 case 'H':
6086 case 'h':
6087 {
6088 if (LocaleCompare(attribute,"height") == 0)
6089 {
6090 region.height=SvIV(ST(i));
6091 continue;
6092 }
6093 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6094 attribute);
6095 break;
6096 }
6097 case 'X':
6098 case 'x':
6099 {
6100 if (LocaleCompare(attribute,"x") == 0)
6101 {
6102 region.x=SvIV(ST(i));
6103 continue;
6104 }
6105 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6106 attribute);
6107 break;
6108 }
6109 case 'Y':
6110 case 'y':
6111 {
6112 if (LocaleCompare(attribute,"y") == 0)
6113 {
6114 region.y=SvIV(ST(i));
6115 continue;
6116 }
6117 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6118 attribute);
6119 break;
6120 }
6121 case 'W':
6122 case 'w':
6123 {
6124 if (LocaleCompare(attribute,"width") == 0)
6125 {
6126 region.width=SvIV(ST(i));
6127 continue;
6128 }
6129 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6130 attribute);
6131 break;
6132 }
6133 }
6134 }
6135 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6136 region.height,exception);
6137 if (blob != (void *) NULL)
6138 goto PerlEnd;
6139
6140 PerlException:
6141 InheritPerlException(exception,perl_exception);
6142 exception=DestroyExceptionInfo(exception);
6143 SvREFCNT_dec(perl_exception); /* throw away all errors */
6144
6145 PerlEnd:
6146 RETVAL = (void *) blob;
6147 }
6148 OUTPUT:
6149 RETVAL
6150
6151#
6152###############################################################################
6153# #
6154# #
6155# #
6156# G e t A u t h e n t i c M e t a c o n t e n t #
6157# #
6158# #
6159# #
6160###############################################################################
6161#
6162#
6163void *
6164GetAuthenticMetacontent(ref,...)
6165 Image::Magick ref = NO_INIT
6166 ALIAS:
6167 getauthenticmetacontent = 1
6168 GetMetacontent = 2
6169 getmetacontent = 3
6170 CODE:
6171 {
6172 ExceptionInfo
6173 *exception;
6174
6175 Image
6176 *image;
6177
6178 struct PackageInfo
6179 *info;
6180
6181 SV
6182 *perl_exception,
6183 *reference;
6184
6185 void
6186 *blob = NULL;
6187
6188 PERL_UNUSED_VAR(ref);
6189 PERL_UNUSED_VAR(ix);
6190 exception=AcquireExceptionInfo();
6191 perl_exception=newSVpv("",0);
6192 if (sv_isobject(ST(0)) == 0)
6193 {
6194 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6195 PackageName);
6196 goto PerlException;
6197 }
6198 reference=SvRV(ST(0));
6199
6200 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6201 if (image == (Image *) NULL)
6202 {
6203 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6204 PackageName);
6205 goto PerlException;
6206 }
6207
6208 blob=(void *) GetAuthenticMetacontent(image);
6209 if (blob != (void *) NULL)
6210 goto PerlEnd;
6211
6212 PerlException:
6213 InheritPerlException(exception,perl_exception);
6214 exception=DestroyExceptionInfo(exception);
6215 SvREFCNT_dec(perl_exception); /* throw away all errors */
6216
6217 PerlEnd:
6218 RETVAL = blob;
6219 }
6220 OUTPUT:
6221 RETVAL
6222
6223#
6224###############################################################################
6225# #
6226# #
6227# #
6228# G e t V i r t u a l M e t a c o n t e n t #
6229# #
6230# #
6231# #
6232###############################################################################
6233#
6234#
6235void *
6236GetVirtualMetacontent(ref,...)
6237 Image::Magick ref = NO_INIT
6238 ALIAS:
6239 getvirtualmetacontent = 1
6240 CODE:
6241 {
6242 ExceptionInfo
6243 *exception;
6244
6245 Image
6246 *image;
6247
6248 struct PackageInfo
6249 *info;
6250
6251 SV
6252 *perl_exception,
6253 *reference;
6254
6255 void
6256 *blob = NULL;
6257
6258 PERL_UNUSED_VAR(ref);
6259 PERL_UNUSED_VAR(ix);
6260 exception=AcquireExceptionInfo();
6261 perl_exception=newSVpv("",0);
6262 if (sv_isobject(ST(0)) == 0)
6263 {
6264 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6265 PackageName);
6266 goto PerlException;
6267 }
6268 reference=SvRV(ST(0));
6269
6270 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6271 if (image == (Image *) NULL)
6272 {
6273 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6274 PackageName);
6275 goto PerlException;
6276 }
6277
6278 blob=(void *) GetVirtualMetacontent(image);
6279 if (blob != (void *) NULL)
6280 goto PerlEnd;
6281
6282 PerlException:
6283 InheritPerlException(exception,perl_exception);
6284 exception=DestroyExceptionInfo(exception);
6285 SvREFCNT_dec(perl_exception); /* throw away all errors */
6286
6287 PerlEnd:
6288 RETVAL = blob;
6289 }
6290 OUTPUT:
6291 RETVAL
6292
6293#
6294###############################################################################
6295# #
6296# #
6297# #
6298# H i s t o g r a m #
6299# #
6300# #
6301# #
6302###############################################################################
6303#
6304#
6305void
6306Histogram(ref,...)
6307 Image::Magick ref=NO_INIT
6308 ALIAS:
6309 HistogramImage = 1
6310 histogram = 2
6311 histogramimage = 3
6312 PPCODE:
6313 {
6314 AV
6315 *av;
6316
6317 char
cristy151b66d2015-04-15 10:50:31 +00006318 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006319
6320 PixelInfo
6321 *histogram;
6322
6323 ExceptionInfo
6324 *exception;
6325
6326 Image
6327 *image;
6328
6329 register ssize_t
6330 i;
6331
6332 ssize_t
6333 count;
6334
6335 struct PackageInfo
6336 *info;
6337
6338 SV
6339 *perl_exception,
6340 *reference;
6341
6342 size_t
6343 number_colors;
6344
6345 PERL_UNUSED_VAR(ref);
6346 PERL_UNUSED_VAR(ix);
6347 exception=AcquireExceptionInfo();
6348 perl_exception=newSVpv("",0);
6349 av=NULL;
6350 if (sv_isobject(ST(0)) == 0)
6351 {
6352 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6353 PackageName);
6354 goto PerlException;
6355 }
6356 reference=SvRV(ST(0));
6357 av=newAV();
6358 SvREFCNT_dec(av);
6359 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6360 if (image == (Image *) NULL)
6361 {
6362 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6363 PackageName);
6364 goto PerlException;
6365 }
cristy4a3ce0a2013-08-03 20:06:59 +00006366 count=0;
6367 for ( ; image; image=image->next)
6368 {
6369 histogram=GetImageHistogram(image,&number_colors,exception);
6370 if (histogram == (PixelInfo *) NULL)
6371 continue;
6372 count+=(ssize_t) number_colors;
6373 EXTEND(sp,6*count);
6374 for (i=0; i < (ssize_t) number_colors; i++)
6375 {
cristy151b66d2015-04-15 10:50:31 +00006376 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006377 histogram[i].red);
6378 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006379 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006380 histogram[i].green);
6381 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006382 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006383 histogram[i].blue);
6384 PUSHs(sv_2mortal(newSVpv(message,0)));
6385 if (image->colorspace == CMYKColorspace)
6386 {
cristy151b66d2015-04-15 10:50:31 +00006387 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006388 histogram[i].black);
6389 PUSHs(sv_2mortal(newSVpv(message,0)));
6390 }
cristy151b66d2015-04-15 10:50:31 +00006391 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006392 histogram[i].alpha);
6393 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006394 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006395 histogram[i].count);
6396 PUSHs(sv_2mortal(newSVpv(message,0)));
6397 }
6398 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6399 }
6400
6401 PerlException:
6402 InheritPerlException(exception,perl_exception);
6403 exception=DestroyExceptionInfo(exception);
6404 SvREFCNT_dec(perl_exception);
6405 }
6406
6407#
6408###############################################################################
6409# #
6410# #
6411# #
6412# G e t P i x e l #
6413# #
6414# #
6415# #
6416###############################################################################
6417#
6418#
6419void
6420GetPixel(ref,...)
6421 Image::Magick ref=NO_INIT
6422 ALIAS:
6423 getpixel = 1
6424 getPixel = 2
6425 PPCODE:
6426 {
6427 AV
6428 *av;
6429
6430 char
6431 *attribute;
6432
6433 ExceptionInfo
6434 *exception;
6435
6436 Image
6437 *image;
6438
6439 MagickBooleanType
6440 normalize;
6441
6442 RectangleInfo
6443 region;
6444
6445 register const Quantum
6446 *p;
6447
6448 register ssize_t
6449 i;
6450
6451 ssize_t
6452 option;
6453
6454 struct PackageInfo
6455 *info;
6456
6457 SV
6458 *perl_exception,
6459 *reference; /* reference is the SV* of ref=SvIV(reference) */
6460
6461 PERL_UNUSED_VAR(ref);
6462 PERL_UNUSED_VAR(ix);
6463 exception=AcquireExceptionInfo();
6464 perl_exception=newSVpv("",0);
6465 reference=SvRV(ST(0));
6466 av=(AV *) reference;
6467 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6468 exception);
6469 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6470 if (image == (Image *) NULL)
6471 {
6472 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6473 PackageName);
6474 goto PerlException;
6475 }
6476 normalize=MagickTrue;
6477 region.x=0;
6478 region.y=0;
6479 region.width=image->columns;
6480 region.height=1;
6481 if (items == 1)
6482 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6483 for (i=2; i < items; i+=2)
6484 {
6485 attribute=(char *) SvPV(ST(i-1),na);
6486 switch (*attribute)
6487 {
6488 case 'C':
6489 case 'c':
6490 {
6491 if (LocaleCompare(attribute,"channel") == 0)
6492 {
6493 ssize_t
6494 option;
6495
6496 option=ParseChannelOption(SvPV(ST(i),na));
6497 if (option < 0)
6498 {
6499 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6500 SvPV(ST(i),na));
6501 return;
6502 }
cristybcd59342015-06-07 14:07:19 +00006503 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00006504 break;
6505 }
6506 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6507 attribute);
6508 break;
6509 }
6510 case 'g':
6511 case 'G':
6512 {
6513 if (LocaleCompare(attribute,"geometry") == 0)
6514 {
6515 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6516 break;
6517 }
6518 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6519 attribute);
6520 break;
6521 }
6522 case 'N':
6523 case 'n':
6524 {
6525 if (LocaleCompare(attribute,"normalize") == 0)
6526 {
6527 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6528 SvPV(ST(i),na));
6529 if (option < 0)
6530 {
6531 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6532 SvPV(ST(i),na));
6533 break;
6534 }
6535 normalize=option != 0 ? MagickTrue : MagickFalse;
6536 break;
6537 }
6538 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6539 attribute);
6540 break;
6541 }
6542 case 'x':
6543 case 'X':
6544 {
6545 if (LocaleCompare(attribute,"x") == 0)
6546 {
6547 region.x=SvIV(ST(i));
6548 break;
6549 }
6550 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6551 attribute);
6552 break;
6553 }
6554 case 'y':
6555 case 'Y':
6556 {
6557 if (LocaleCompare(attribute,"y") == 0)
6558 {
6559 region.y=SvIV(ST(i));
6560 break;
6561 }
6562 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6563 attribute);
6564 break;
6565 }
6566 default:
6567 {
6568 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6569 attribute);
6570 break;
6571 }
6572 }
6573 }
6574 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6575 if (p == (const Quantum *) NULL)
6576 PUSHs(&sv_undef);
6577 else
6578 {
6579 double
6580 scale;
6581
6582 scale=1.0;
6583 if (normalize != MagickFalse)
6584 scale=1.0/QuantumRange;
6585 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6586 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6587 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6588 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6589 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6590 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6591 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6592 (image->colorspace == CMYKColorspace))
6593 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6594 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6595 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6596 }
6597
6598 PerlException:
6599 InheritPerlException(exception,perl_exception);
6600 exception=DestroyExceptionInfo(exception);
6601 SvREFCNT_dec(perl_exception);
6602 }
6603
6604#
6605###############################################################################
6606# #
6607# #
6608# #
6609# G e t P i x e l s #
6610# #
6611# #
6612# #
6613###############################################################################
6614#
6615#
6616void
6617GetPixels(ref,...)
6618 Image::Magick ref=NO_INIT
6619 ALIAS:
6620 getpixels = 1
6621 getPixels = 2
6622 PPCODE:
6623 {
6624 AV
6625 *av;
6626
6627 char
6628 *attribute;
6629
6630 const char
6631 *map;
6632
6633 ExceptionInfo
6634 *exception;
6635
6636 Image
6637 *image;
6638
6639 MagickBooleanType
6640 normalize,
6641 status;
6642
6643 RectangleInfo
6644 region;
6645
6646 register ssize_t
6647 i;
6648
6649 ssize_t
6650 option;
6651
6652 struct PackageInfo
6653 *info;
6654
6655 SV
6656 *perl_exception,
6657 *reference; /* reference is the SV* of ref=SvIV(reference) */
6658
6659 PERL_UNUSED_VAR(ref);
6660 PERL_UNUSED_VAR(ix);
6661 exception=AcquireExceptionInfo();
6662 perl_exception=newSVpv("",0);
6663 reference=SvRV(ST(0));
6664 av=(AV *) reference;
6665 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6666 exception);
6667 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6668 if (image == (Image *) NULL)
6669 {
6670 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6671 PackageName);
6672 goto PerlException;
6673 }
6674 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006675 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006676 map="RGBA";
6677 if (image->colorspace == CMYKColorspace)
6678 {
6679 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006680 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006681 map="CMYKA";
6682 }
6683 normalize=MagickFalse;
6684 region.x=0;
6685 region.y=0;
6686 region.width=image->columns;
6687 region.height=1;
6688 if (items == 1)
6689 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6690 for (i=2; i < items; i+=2)
6691 {
6692 attribute=(char *) SvPV(ST(i-1),na);
6693 switch (*attribute)
6694 {
6695 case 'g':
6696 case 'G':
6697 {
6698 if (LocaleCompare(attribute,"geometry") == 0)
6699 {
6700 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6701 break;
6702 }
6703 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6704 attribute);
6705 break;
6706 }
6707 case 'H':
6708 case 'h':
6709 {
6710 if (LocaleCompare(attribute,"height") == 0)
6711 {
6712 region.height=SvIV(ST(i));
6713 break;
6714 }
6715 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6716 attribute);
6717 break;
6718 }
6719 case 'M':
6720 case 'm':
6721 {
6722 if (LocaleCompare(attribute,"map") == 0)
6723 {
6724 map=SvPV(ST(i),na);
6725 break;
6726 }
6727 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6728 attribute);
6729 break;
6730 }
6731 case 'N':
6732 case 'n':
6733 {
6734 if (LocaleCompare(attribute,"normalize") == 0)
6735 {
6736 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6737 SvPV(ST(i),na));
6738 if (option < 0)
6739 {
6740 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6741 SvPV(ST(i),na));
6742 break;
6743 }
6744 normalize=option != 0 ? MagickTrue : MagickFalse;
6745 break;
6746 }
6747 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6748 attribute);
6749 break;
6750 }
6751 case 'W':
6752 case 'w':
6753 {
6754 if (LocaleCompare(attribute,"width") == 0)
6755 {
6756 region.width=SvIV(ST(i));
6757 break;
6758 }
6759 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6760 attribute);
6761 break;
6762 }
6763 case 'x':
6764 case 'X':
6765 {
6766 if (LocaleCompare(attribute,"x") == 0)
6767 {
6768 region.x=SvIV(ST(i));
6769 break;
6770 }
6771 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6772 attribute);
6773 break;
6774 }
6775 case 'y':
6776 case 'Y':
6777 {
6778 if (LocaleCompare(attribute,"y") == 0)
6779 {
6780 region.y=SvIV(ST(i));
6781 break;
6782 }
6783 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6784 attribute);
6785 break;
6786 }
6787 default:
6788 {
6789 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6790 attribute);
6791 break;
6792 }
6793 }
6794 }
6795 if (normalize != MagickFalse)
6796 {
6797 float
6798 *pixels;
6799
6800 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6801 region.height*sizeof(*pixels));
6802 if (pixels == (float *) NULL)
6803 {
6804 ThrowPerlException(exception,ResourceLimitError,
6805 "MemoryAllocationFailed",PackageName);
6806 goto PerlException;
6807 }
6808 status=ExportImagePixels(image,region.x,region.y,region.width,
6809 region.height,map,FloatPixel,pixels,exception);
6810 if (status == MagickFalse)
6811 PUSHs(&sv_undef);
6812 else
6813 {
6814 EXTEND(sp,strlen(map)*region.width*region.height);
6815 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6816 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6817 }
6818 pixels=(float *) RelinquishMagickMemory(pixels);
6819 }
6820 else
6821 {
6822 Quantum
6823 *pixels;
6824
6825 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6826 region.height*sizeof(*pixels));
6827 if (pixels == (Quantum *) NULL)
6828 {
6829 ThrowPerlException(exception,ResourceLimitError,
6830 "MemoryAllocationFailed",PackageName);
6831 goto PerlException;
6832 }
6833 status=ExportImagePixels(image,region.x,region.y,region.width,
6834 region.height,map,QuantumPixel,pixels,exception);
6835 if (status == MagickFalse)
6836 PUSHs(&sv_undef);
6837 else
6838 {
6839 EXTEND(sp,strlen(map)*region.width*region.height);
6840 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6841 PUSHs(sv_2mortal(newSViv(pixels[i])));
6842 }
6843 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6844 }
6845
6846 PerlException:
6847 InheritPerlException(exception,perl_exception);
6848 exception=DestroyExceptionInfo(exception);
6849 SvREFCNT_dec(perl_exception);
6850 }
6851
6852#
6853###############################################################################
6854# #
6855# #
6856# #
6857# I m a g e T o B l o b #
6858# #
6859# #
6860# #
6861###############################################################################
6862#
6863#
6864void
6865ImageToBlob(ref,...)
6866 Image::Magick ref=NO_INIT
6867 ALIAS:
6868 ImageToBlob = 1
6869 imagetoblob = 2
6870 toblob = 3
6871 blob = 4
6872 PPCODE:
6873 {
6874 char
cristy151b66d2015-04-15 10:50:31 +00006875 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006876
6877 ExceptionInfo
6878 *exception;
6879
6880 Image
6881 *image,
6882 *next;
6883
6884 register ssize_t
6885 i;
6886
6887 struct PackageInfo
6888 *info,
6889 *package_info;
6890
6891 size_t
6892 length;
6893
6894 ssize_t
6895 scene;
6896
6897 SV
6898 *perl_exception,
6899 *reference;
6900
6901 void
6902 *blob;
6903
6904 PERL_UNUSED_VAR(ref);
6905 PERL_UNUSED_VAR(ix);
6906 exception=AcquireExceptionInfo();
6907 perl_exception=newSVpv("",0);
6908 package_info=(struct PackageInfo *) NULL;
6909 if (sv_isobject(ST(0)) == 0)
6910 {
6911 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6912 PackageName);
6913 goto PerlException;
6914 }
6915 reference=SvRV(ST(0));
6916 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6917 if (image == (Image *) NULL)
6918 {
6919 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6920 PackageName);
6921 goto PerlException;
6922 }
6923 package_info=ClonePackageInfo(info,exception);
6924 for (i=2; i < items; i+=2)
6925 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6926 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006927 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006928 scene=0;
6929 for (next=image; next; next=next->next)
6930 {
cristy151b66d2015-04-15 10:50:31 +00006931 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006932 next->scene=scene++;
6933 }
6934 SetImageInfo(package_info->image_info,(unsigned int)
6935 GetImageListLength(image),exception);
6936 EXTEND(sp,(ssize_t) GetImageListLength(image));
6937 for ( ; image; image=image->next)
6938 {
6939 length=0;
6940 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6941 if (blob != (char *) NULL)
6942 {
6943 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6944 blob=(unsigned char *) RelinquishMagickMemory(blob);
6945 }
6946 if (package_info->image_info->adjoin)
6947 break;
6948 }
6949
6950 PerlException:
6951 if (package_info != (struct PackageInfo *) NULL)
6952 DestroyPackageInfo(package_info);
6953 InheritPerlException(exception,perl_exception);
6954 exception=DestroyExceptionInfo(exception);
6955 SvREFCNT_dec(perl_exception); /* throw away all errors */
6956 }
6957
6958#
6959###############################################################################
6960# #
6961# #
6962# #
6963# L a y e r s #
6964# #
6965# #
6966# #
6967###############################################################################
6968#
6969#
6970void
6971Layers(ref,...)
6972 Image::Magick ref=NO_INIT
6973 ALIAS:
6974 Layers = 1
6975 layers = 2
6976 OptimizeImageLayers = 3
6977 optimizelayers = 4
6978 optimizeimagelayers = 5
6979 PPCODE:
6980 {
6981 AV
6982 *av;
6983
6984 char
6985 *attribute;
6986
6987 CompositeOperator
6988 compose;
6989
6990 ExceptionInfo
6991 *exception;
6992
6993 HV
6994 *hv;
6995
6996 Image
6997 *image,
6998 *layers;
6999
7000 LayerMethod
7001 method;
7002
7003 register ssize_t
7004 i;
7005
7006 ssize_t
7007 option,
7008 sp;
7009
7010 struct PackageInfo
7011 *info;
7012
7013 SV
7014 *av_reference,
7015 *perl_exception,
7016 *reference,
7017 *rv,
7018 *sv;
7019
7020 PERL_UNUSED_VAR(ref);
7021 PERL_UNUSED_VAR(ix);
7022 exception=AcquireExceptionInfo();
7023 perl_exception=newSVpv("",0);
7024 sv=NULL;
7025 if (sv_isobject(ST(0)) == 0)
7026 {
7027 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7028 PackageName);
7029 goto PerlException;
7030 }
7031 reference=SvRV(ST(0));
7032 hv=SvSTASH(reference);
7033 av=newAV();
7034 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7035 SvREFCNT_dec(av);
7036 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7037 if (image == (Image *) NULL)
7038 {
7039 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7040 PackageName);
7041 goto PerlException;
7042 }
7043 compose=image->compose;
7044 method=OptimizeLayer;
7045 for (i=2; i < items; i+=2)
7046 {
7047 attribute=(char *) SvPV(ST(i-1),na);
7048 switch (*attribute)
7049 {
7050 case 'C':
7051 case 'c':
7052 {
7053 if (LocaleCompare(attribute,"compose") == 0)
7054 {
7055 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7056 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7057 if (sp < 0)
7058 {
7059 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7060 SvPV(ST(i),na));
7061 break;
7062 }
7063 compose=(CompositeOperator) sp;
7064 break;
7065 }
7066 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7067 attribute);
7068 break;
7069 }
7070 case 'M':
7071 case 'm':
7072 {
7073 if (LocaleCompare(attribute,"method") == 0)
7074 {
7075 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7076 SvPV(ST(i),na));
7077 if (option < 0)
7078 {
7079 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7080 SvPV(ST(i),na));
7081 break;
7082 }
7083 method=(LayerMethod) option;
7084 break;
7085 }
7086 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7087 attribute);
7088 break;
7089 }
7090 default:
7091 {
7092 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7093 attribute);
7094 break;
7095 }
7096 }
7097 }
7098 layers=(Image *) NULL;
7099 switch (method)
7100 {
7101 case CompareAnyLayer:
7102 case CompareClearLayer:
7103 case CompareOverlayLayer:
7104 default:
7105 {
7106 layers=CompareImagesLayers(image,method,exception);
7107 break;
7108 }
7109 case MergeLayer:
7110 case FlattenLayer:
7111 case MosaicLayer:
7112 {
7113 layers=MergeImageLayers(image,method,exception);
7114 break;
7115 }
7116 case DisposeLayer:
7117 {
7118 layers=DisposeImages(image,exception);
7119 break;
7120 }
7121 case OptimizeImageLayer:
7122 {
7123 layers=OptimizeImageLayers(image,exception);
7124 break;
7125 }
7126 case OptimizePlusLayer:
7127 {
7128 layers=OptimizePlusImageLayers(image,exception);
7129 break;
7130 }
7131 case OptimizeTransLayer:
7132 {
7133 OptimizeImageTransparency(image,exception);
7134 break;
7135 }
7136 case RemoveDupsLayer:
7137 {
7138 RemoveDuplicateLayers(&image,exception);
7139 break;
7140 }
7141 case RemoveZeroLayer:
7142 {
7143 RemoveZeroDelayLayers(&image,exception);
7144 break;
7145 }
7146 case OptimizeLayer:
7147 {
7148 QuantizeInfo
7149 *quantize_info;
7150
7151 /*
7152 General Purpose, GIF Animation Optimizer.
7153 */
7154 layers=CoalesceImages(image,exception);
7155 if (layers == (Image *) NULL)
7156 break;
7157 image=layers;
7158 layers=OptimizeImageLayers(image,exception);
7159 if (layers == (Image *) NULL)
7160 break;
7161 image=DestroyImageList(image);
7162 image=layers;
7163 layers=(Image *) NULL;
7164 OptimizeImageTransparency(image,exception);
7165 quantize_info=AcquireQuantizeInfo(info->image_info);
7166 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7167 quantize_info=DestroyQuantizeInfo(quantize_info);
7168 break;
7169 }
7170 case CompositeLayer:
7171 {
7172 Image
7173 *source;
7174
7175 RectangleInfo
7176 geometry;
7177
7178 /*
7179 Split image sequence at the first 'NULL:' image.
7180 */
7181 source=image;
7182 while (source != (Image *) NULL)
7183 {
7184 source=GetNextImageInList(source);
7185 if ((source != (Image *) NULL) &&
7186 (LocaleCompare(source->magick,"NULL") == 0))
7187 break;
7188 }
7189 if (source != (Image *) NULL)
7190 {
7191 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7192 (GetNextImageInList(source) == (Image *) NULL))
7193 source=(Image *) NULL;
7194 else
7195 {
7196 /*
7197 Separate the two lists, junk the null: image.
7198 */
7199 source=SplitImageList(source->previous);
7200 DeleteImageFromList(&source);
7201 }
7202 }
7203 if (source == (Image *) NULL)
7204 {
7205 (void) ThrowMagickException(exception,GetMagickModule(),
7206 OptionError,"MissingNullSeparator","layers Composite");
7207 break;
7208 }
7209 /*
7210 Adjust offset with gravity and virtual canvas.
7211 */
7212 SetGeometry(image,&geometry);
7213 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7214 geometry.width=source->page.width != 0 ? source->page.width :
7215 source->columns;
7216 geometry.height=source->page.height != 0 ? source->page.height :
7217 source->rows;
7218 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7219 image->columns,image->page.height != 0 ? image->page.height :
7220 image->rows,image->gravity,&geometry);
7221 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7222 source=DestroyImageList(source);
7223 break;
7224 }
7225 }
7226 if (layers != (Image *) NULL)
7227 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007228 else
7229 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007230 if (image == (Image *) NULL)
7231 goto PerlException;
7232 for ( ; image; image=image->next)
7233 {
7234 AddImageToRegistry(sv,image);
7235 rv=newRV(sv);
7236 av_push(av,sv_bless(rv,hv));
7237 SvREFCNT_dec(sv);
7238 }
7239 exception=DestroyExceptionInfo(exception);
7240 ST(0)=av_reference;
7241 SvREFCNT_dec(perl_exception);
7242 XSRETURN(1);
7243
7244 PerlException:
7245 InheritPerlException(exception,perl_exception);
7246 exception=DestroyExceptionInfo(exception);
7247 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7248 SvPOK_on(perl_exception);
7249 ST(0)=sv_2mortal(perl_exception);
7250 XSRETURN(1);
7251 }
7252
7253#
7254###############################################################################
7255# #
7256# #
7257# #
7258# M a g i c k T o M i m e #
7259# #
7260# #
7261# #
7262###############################################################################
7263#
7264#
7265SV *
7266MagickToMime(ref,name)
7267 Image::Magick ref=NO_INIT
7268 char *name
7269 ALIAS:
7270 magicktomime = 1
7271 CODE:
7272 {
7273 char
7274 *mime;
7275
7276 PERL_UNUSED_VAR(ref);
7277 PERL_UNUSED_VAR(ix);
7278 mime=MagickToMime(name);
7279 RETVAL=newSVpv(mime,0);
7280 mime=(char *) RelinquishMagickMemory(mime);
7281 }
7282 OUTPUT:
7283 RETVAL
7284
7285#
7286###############################################################################
7287# #
7288# #
7289# #
7290# M o g r i f y #
7291# #
7292# #
7293# #
7294###############################################################################
7295#
7296#
7297void
7298Mogrify(ref,...)
7299 Image::Magick ref=NO_INIT
7300 ALIAS:
7301 Comment = 1
7302 CommentImage = 2
7303 Label = 3
7304 LabelImage = 4
7305 AddNoise = 5
7306 AddNoiseImage = 6
7307 Colorize = 7
7308 ColorizeImage = 8
7309 Border = 9
7310 BorderImage = 10
7311 Blur = 11
7312 BlurImage = 12
7313 Chop = 13
7314 ChopImage = 14
7315 Crop = 15
7316 CropImage = 16
7317 Despeckle = 17
7318 DespeckleImage = 18
7319 Edge = 19
7320 EdgeImage = 20
7321 Emboss = 21
7322 EmbossImage = 22
7323 Enhance = 23
7324 EnhanceImage = 24
7325 Flip = 25
7326 FlipImage = 26
7327 Flop = 27
7328 FlopImage = 28
7329 Frame = 29
7330 FrameImage = 30
7331 Implode = 31
7332 ImplodeImage = 32
7333 Magnify = 33
7334 MagnifyImage = 34
7335 MedianFilter = 35
7336 MedianConvolveImage = 36
7337 Minify = 37
7338 MinifyImage = 38
7339 OilPaint = 39
7340 OilPaintImage = 40
7341 ReduceNoise = 41
7342 ReduceNoiseImage = 42
7343 Roll = 43
7344 RollImage = 44
7345 Rotate = 45
7346 RotateImage = 46
7347 Sample = 47
7348 SampleImage = 48
7349 Scale = 49
7350 ScaleImage = 50
7351 Shade = 51
7352 ShadeImage = 52
7353 Sharpen = 53
7354 SharpenImage = 54
7355 Shear = 55
7356 ShearImage = 56
7357 Spread = 57
7358 SpreadImage = 58
7359 Swirl = 59
7360 SwirlImage = 60
7361 Resize = 61
7362 ResizeImage = 62
7363 Zoom = 63
7364 ZoomImage = 64
7365 Annotate = 65
7366 AnnotateImage = 66
7367 ColorFloodfill = 67
7368 ColorFloodfillImage= 68
7369 Composite = 69
7370 CompositeImage = 70
7371 Contrast = 71
7372 ContrastImage = 72
7373 CycleColormap = 73
7374 CycleColormapImage = 74
7375 Draw = 75
7376 DrawImage = 76
7377 Equalize = 77
7378 EqualizeImage = 78
7379 Gamma = 79
7380 GammaImage = 80
7381 Map = 81
7382 MapImage = 82
7383 MatteFloodfill = 83
7384 MatteFloodfillImage= 84
7385 Modulate = 85
7386 ModulateImage = 86
7387 Negate = 87
7388 NegateImage = 88
7389 Normalize = 89
7390 NormalizeImage = 90
7391 NumberColors = 91
7392 NumberColorsImage = 92
7393 Opaque = 93
7394 OpaqueImage = 94
7395 Quantize = 95
7396 QuantizeImage = 96
7397 Raise = 97
7398 RaiseImage = 98
7399 Segment = 99
7400 SegmentImage = 100
7401 Signature = 101
7402 SignatureImage = 102
7403 Solarize = 103
7404 SolarizeImage = 104
7405 Sync = 105
7406 SyncImage = 106
7407 Texture = 107
7408 TextureImage = 108
7409 Evaluate = 109
7410 EvaluateImage = 110
7411 Transparent = 111
7412 TransparentImage = 112
7413 Threshold = 113
7414 ThresholdImage = 114
7415 Charcoal = 115
7416 CharcoalImage = 116
7417 Trim = 117
7418 TrimImage = 118
7419 Wave = 119
7420 WaveImage = 120
7421 Separate = 121
7422 SeparateImage = 122
7423 Stereo = 125
7424 StereoImage = 126
7425 Stegano = 127
7426 SteganoImage = 128
7427 Deconstruct = 129
7428 DeconstructImage = 130
7429 GaussianBlur = 131
7430 GaussianBlurImage = 132
7431 Convolve = 133
7432 ConvolveImage = 134
7433 Profile = 135
7434 ProfileImage = 136
7435 UnsharpMask = 137
7436 UnsharpMaskImage = 138
7437 MotionBlur = 139
7438 MotionBlurImage = 140
7439 OrderedDither = 141
7440 OrderedDitherImage = 142
7441 Shave = 143
7442 ShaveImage = 144
7443 Level = 145
7444 LevelImage = 146
7445 Clip = 147
7446 ClipImage = 148
7447 AffineTransform = 149
7448 AffineTransformImage = 150
7449 Difference = 151
7450 DifferenceImage = 152
7451 AdaptiveThreshold = 153
7452 AdaptiveThresholdImage = 154
7453 Resample = 155
7454 ResampleImage = 156
7455 Describe = 157
7456 DescribeImage = 158
7457 BlackThreshold = 159
7458 BlackThresholdImage= 160
7459 WhiteThreshold = 161
7460 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007461 RotationalBlur = 163
7462 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007463 Thumbnail = 165
7464 ThumbnailImage = 166
7465 Strip = 167
7466 StripImage = 168
7467 Tint = 169
7468 TintImage = 170
7469 Channel = 171
7470 ChannelImage = 172
7471 Splice = 173
7472 SpliceImage = 174
7473 Posterize = 175
7474 PosterizeImage = 176
7475 Shadow = 177
7476 ShadowImage = 178
7477 Identify = 179
7478 IdentifyImage = 180
7479 SepiaTone = 181
7480 SepiaToneImage = 182
7481 SigmoidalContrast = 183
7482 SigmoidalContrastImage = 184
7483 Extent = 185
7484 ExtentImage = 186
7485 Vignette = 187
7486 VignetteImage = 188
7487 ContrastStretch = 189
7488 ContrastStretchImage = 190
7489 Sans0 = 191
7490 Sans0Image = 192
7491 Sans1 = 193
7492 Sans1Image = 194
7493 AdaptiveSharpen = 195
7494 AdaptiveSharpenImage = 196
7495 Transpose = 197
7496 TransposeImage = 198
7497 Transverse = 199
7498 TransverseImage = 200
7499 AutoOrient = 201
7500 AutoOrientImage = 202
7501 AdaptiveBlur = 203
7502 AdaptiveBlurImage = 204
7503 Sketch = 205
7504 SketchImage = 206
7505 UniqueColors = 207
7506 UniqueColorsImage = 208
7507 AdaptiveResize = 209
7508 AdaptiveResizeImage= 210
7509 ClipMask = 211
7510 ClipMaskImage = 212
7511 LinearStretch = 213
7512 LinearStretchImage = 214
7513 ColorMatrix = 215
7514 ColorMatrixImage = 216
7515 Mask = 217
7516 MaskImage = 218
7517 Polaroid = 219
7518 PolaroidImage = 220
7519 FloodfillPaint = 221
7520 FloodfillPaintImage= 222
7521 Distort = 223
7522 DistortImage = 224
7523 Clut = 225
7524 ClutImage = 226
7525 LiquidRescale = 227
7526 LiquidRescaleImage = 228
7527 Encipher = 229
7528 EncipherImage = 230
7529 Decipher = 231
7530 DecipherImage = 232
7531 Deskew = 233
7532 DeskewImage = 234
7533 Remap = 235
7534 RemapImage = 236
7535 SparseColor = 237
7536 SparseColorImage = 238
7537 Function = 239
7538 FunctionImage = 240
7539 SelectiveBlur = 241
7540 SelectiveBlurImage = 242
7541 HaldClut = 243
7542 HaldClutImage = 244
7543 BlueShift = 245
7544 BlueShiftImage = 246
7545 ForwardFourierTransform = 247
7546 ForwardFourierTransformImage = 248
7547 InverseFourierTransform = 249
7548 InverseFourierTransformImage = 250
7549 ColorDecisionList = 251
7550 ColorDecisionListImage = 252
7551 AutoGamma = 253
7552 AutoGammaImage = 254
7553 AutoLevel = 255
7554 AutoLevelImage = 256
7555 LevelColors = 257
7556 LevelImageColors = 258
7557 Clamp = 259
7558 ClampImage = 260
7559 BrightnessContrast = 261
7560 BrightnessContrastImage = 262
7561 Morphology = 263
7562 MorphologyImage = 264
Cristy3ca633e2016-02-13 12:49:01 -05007563 Mode = 265
7564 ModeImage = 266
7565 Statistic = 267
7566 StatisticImage = 268
7567 Perceptible = 269
7568 PerceptibleImage = 270
7569 Poly = 271
7570 PolyImage = 272
7571 Grayscale = 273
7572 GrayscaleImage = 274
7573 CannyEdge = 275
7574 CannyEdgeImage = 276
7575 HoughLine = 277
7576 HoughLineImage = 278
7577 MeanShift = 279
7578 MeanShiftImage = 280
7579 Kuwahara = 281
7580 KuwaharaImage = 282
7581 ConnectedComponent = 283
7582 ConnectedComponentImage = 284
7583 CopyPixels = 285
7584 CopyImagePixels = 286
Cristy5488c982016-02-13 14:07:50 -05007585 Color = 287
7586 ColorImage = 288
Cristy2d830ed2016-02-21 10:54:16 -05007587 WaveletDenoise = 289
7588 WaveletDenoiseImage= 290
cristy4a3ce0a2013-08-03 20:06:59 +00007589 MogrifyRegion = 666
7590 PPCODE:
7591 {
7592 AffineMatrix
7593 affine,
7594 current;
7595
7596 char
7597 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007598 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007599
7600 ChannelType
7601 channel,
7602 channel_mask;
7603
7604 CompositeOperator
7605 compose;
7606
7607 const char
7608 *attribute,
7609 *value;
7610
7611 double
7612 angle;
7613
7614 ExceptionInfo
7615 *exception;
7616
7617 GeometryInfo
7618 geometry_info;
7619
7620 Image
7621 *image,
7622 *next,
7623 *region_image;
7624
7625 MagickBooleanType
7626 status;
7627
7628 MagickStatusType
7629 flags;
7630
7631 PixelInfo
7632 fill_color;
7633
7634 RectangleInfo
7635 geometry,
7636 region_info;
7637
7638 register ssize_t
7639 i;
7640
7641 ssize_t
7642 base,
7643 j,
7644 number_images;
7645
7646 struct Methods
7647 *rp;
7648
7649 struct PackageInfo
7650 *info;
7651
7652 SV
7653 *perl_exception,
7654 **pv,
7655 *reference,
7656 **reference_vector;
7657
7658 struct ArgumentList
7659 argument_list[MaxArguments];
7660
7661 PERL_UNUSED_VAR(ref);
7662 PERL_UNUSED_VAR(ix);
7663 exception=AcquireExceptionInfo();
7664 perl_exception=newSVpv("",0);
7665 reference_vector=NULL;
7666 region_image=NULL;
7667 number_images=0;
7668 base=2;
7669 if (sv_isobject(ST(0)) == 0)
7670 {
7671 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7672 PackageName);
7673 goto PerlException;
7674 }
7675 reference=SvRV(ST(0));
7676 region_info.width=0;
7677 region_info.height=0;
7678 region_info.x=0;
7679 region_info.y=0;
7680 region_image=(Image *) NULL;
7681 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7682 if (ix && (ix != 666))
7683 {
7684 /*
7685 Called as Method(...)
7686 */
7687 ix=(ix+1)/2;
7688 rp=(&Methods[ix-1]);
7689 attribute=rp->name;
7690 }
7691 else
7692 {
7693 /*
7694 Called as Mogrify("Method",...)
7695 */
7696 attribute=(char *) SvPV(ST(1),na);
7697 if (ix)
7698 {
7699 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7700 attribute=(char *) SvPV(ST(2),na);
7701 base++;
7702 }
7703 for (rp=Methods; ; rp++)
7704 {
7705 if (rp >= EndOf(Methods))
7706 {
7707 ThrowPerlException(exception,OptionError,
7708 "UnrecognizedPerlMagickMethod",attribute);
7709 goto PerlException;
7710 }
7711 if (strEQcase(attribute,rp->name))
7712 break;
7713 }
7714 ix=rp-Methods+1;
7715 base++;
7716 }
7717 if (image == (Image *) NULL)
7718 {
7719 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7720 goto PerlException;
7721 }
7722 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7723 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7724 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7725 {
7726 Arguments
7727 *pp,
7728 *qq;
7729
7730 ssize_t
7731 ssize_test;
7732
7733 struct ArgumentList
7734 *al;
7735
7736 SV
7737 *sv;
7738
7739 sv=NULL;
7740 ssize_test=0;
7741 pp=(Arguments *) NULL;
7742 qq=rp->arguments;
7743 if (i == items)
7744 {
7745 pp=rp->arguments,
7746 sv=ST(i-1);
7747 }
7748 else
7749 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7750 {
7751 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7752 break;
7753 if (strEQcase(attribute,qq->method) > ssize_test)
7754 {
7755 pp=qq;
7756 ssize_test=strEQcase(attribute,qq->method);
7757 }
7758 }
7759 if (pp == (Arguments *) NULL)
7760 {
7761 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7762 attribute);
7763 goto continue_outer_loop;
7764 }
7765 al=(&argument_list[pp-rp->arguments]);
7766 switch (pp->type)
7767 {
7768 case ArrayReference:
7769 {
7770 if (SvTYPE(sv) != SVt_RV)
7771 {
cristy151b66d2015-04-15 10:50:31 +00007772 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007773 "invalid %.60s value",pp->method);
7774 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7775 goto continue_outer_loop;
7776 }
7777 al->array_reference=SvRV(sv);
7778 break;
7779 }
7780 case RealReference:
7781 {
7782 al->real_reference=SvNV(sv);
7783 break;
7784 }
7785 case FileReference:
7786 {
7787 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7788 break;
7789 }
7790 case ImageReference:
7791 {
7792 if (!sv_isobject(sv) ||
7793 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7794 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7795 {
7796 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7797 PackageName);
7798 goto PerlException;
7799 }
7800 break;
7801 }
7802 case IntegerReference:
7803 {
7804 al->integer_reference=SvIV(sv);
7805 break;
7806 }
7807 case StringReference:
7808 {
7809 al->string_reference=(char *) SvPV(sv,al->length);
7810 if (sv_isobject(sv))
7811 al->image_reference=SetupList(aTHX_ SvRV(sv),
7812 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7813 break;
7814 }
7815 default:
7816 {
7817 /*
7818 Is a string; look up name.
7819 */
7820 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7821 {
7822 al->string_reference=(char *) SvPV(sv,al->length);
7823 al->integer_reference=(-1);
7824 break;
7825 }
7826 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7827 MagickFalse,SvPV(sv,na));
7828 if (pp->type == MagickChannelOptions)
7829 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7830 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7831 {
cristy151b66d2015-04-15 10:50:31 +00007832 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007833 "invalid %.60s value",pp->method);
7834 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7835 goto continue_outer_loop;
7836 }
7837 break;
7838 }
7839 }
7840 attribute_flag[pp-rp->arguments]++;
7841 continue_outer_loop: ;
7842 }
7843 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7844 pv=reference_vector;
7845 SetGeometryInfo(&geometry_info);
7846 channel=DefaultChannels;
7847 for (next=image; next; next=next->next)
7848 {
7849 image=next;
7850 SetGeometry(image,&geometry);
7851 if ((region_info.width*region_info.height) != 0)
7852 {
7853 region_image=image;
7854 image=CropImage(image,&region_info,exception);
7855 }
7856 switch (ix)
7857 {
7858 default:
7859 {
cristy151b66d2015-04-15 10:50:31 +00007860 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007861 ThrowPerlException(exception,OptionError,
7862 "UnrecognizedPerlMagickMethod",message);
7863 goto PerlException;
7864 }
7865 case 1: /* Comment */
7866 {
7867 if (attribute_flag[0] == 0)
7868 argument_list[0].string_reference=(char *) NULL;
7869 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7870 info ? info->image_info : (ImageInfo *) NULL,image,
7871 argument_list[0].string_reference,exception),exception);
7872 break;
7873 }
7874 case 2: /* Label */
7875 {
7876 if (attribute_flag[0] == 0)
7877 argument_list[0].string_reference=(char *) NULL;
7878 (void) SetImageProperty(image,"label",InterpretImageProperties(
7879 info ? info->image_info : (ImageInfo *) NULL,image,
7880 argument_list[0].string_reference,exception),exception);
7881 break;
7882 }
7883 case 3: /* AddNoise */
7884 {
7885 double
7886 attenuate;
7887
7888 if (attribute_flag[0] == 0)
7889 argument_list[0].integer_reference=UniformNoise;
7890 attenuate=1.0;
7891 if (attribute_flag[1] != 0)
7892 attenuate=argument_list[1].real_reference;
7893 if (attribute_flag[2] != 0)
7894 channel=(ChannelType) argument_list[2].integer_reference;
7895 channel_mask=SetImageChannelMask(image,channel);
7896 image=AddNoiseImage(image,(NoiseType)
7897 argument_list[0].integer_reference,attenuate,exception);
7898 if (image != (Image *) NULL)
7899 (void) SetImageChannelMask(image,channel_mask);
7900 break;
7901 }
7902 case 4: /* Colorize */
7903 {
7904 PixelInfo
7905 target;
7906
7907 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7908 0,0,&target,exception);
7909 if (attribute_flag[0] != 0)
7910 (void) QueryColorCompliance(argument_list[0].string_reference,
7911 AllCompliance,&target,exception);
7912 if (attribute_flag[1] == 0)
7913 argument_list[1].string_reference="100%";
7914 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7915 exception);
7916 break;
7917 }
7918 case 5: /* Border */
7919 {
7920 CompositeOperator
7921 compose;
7922
7923 geometry.width=0;
7924 geometry.height=0;
7925 if (attribute_flag[0] != 0)
7926 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7927 &geometry,exception);
7928 if (attribute_flag[1] != 0)
7929 geometry.width=argument_list[1].integer_reference;
7930 if (attribute_flag[2] != 0)
7931 geometry.height=argument_list[2].integer_reference;
7932 if (attribute_flag[3] != 0)
7933 QueryColorCompliance(argument_list[3].string_reference,
7934 AllCompliance,&image->border_color,exception);
7935 if (attribute_flag[4] != 0)
7936 QueryColorCompliance(argument_list[4].string_reference,
7937 AllCompliance,&image->border_color,exception);
7938 if (attribute_flag[5] != 0)
7939 QueryColorCompliance(argument_list[5].string_reference,
7940 AllCompliance,&image->border_color,exception);
7941 compose=image->compose;
7942 if (attribute_flag[6] != 0)
7943 compose=(CompositeOperator) argument_list[6].integer_reference;
7944 image=BorderImage(image,&geometry,compose,exception);
7945 break;
7946 }
7947 case 6: /* Blur */
7948 {
7949 if (attribute_flag[0] != 0)
7950 {
7951 flags=ParseGeometry(argument_list[0].string_reference,
7952 &geometry_info);
7953 if ((flags & SigmaValue) == 0)
7954 geometry_info.sigma=1.0;
7955 }
7956 if (attribute_flag[1] != 0)
7957 geometry_info.rho=argument_list[1].real_reference;
7958 if (attribute_flag[2] != 0)
7959 geometry_info.sigma=argument_list[2].real_reference;
7960 if (attribute_flag[3] != 0)
7961 channel=(ChannelType) argument_list[3].integer_reference;
7962 channel_mask=SetImageChannelMask(image,channel);
7963 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
7964 exception);
7965 if (image != (Image *) NULL)
7966 (void) SetImageChannelMask(image,channel_mask);
7967 break;
7968 }
7969 case 7: /* Chop */
7970 {
cristy260bd762014-08-15 12:46:34 +00007971 if (attribute_flag[5] != 0)
7972 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00007973 if (attribute_flag[0] != 0)
7974 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7975 &geometry,exception);
7976 if (attribute_flag[1] != 0)
7977 geometry.width=argument_list[1].integer_reference;
7978 if (attribute_flag[2] != 0)
7979 geometry.height=argument_list[2].integer_reference;
7980 if (attribute_flag[3] != 0)
7981 geometry.x=argument_list[3].integer_reference;
7982 if (attribute_flag[4] != 0)
7983 geometry.y=argument_list[4].integer_reference;
7984 image=ChopImage(image,&geometry,exception);
7985 break;
7986 }
7987 case 8: /* Crop */
7988 {
7989 if (attribute_flag[6] != 0)
7990 image->gravity=(GravityType) argument_list[6].integer_reference;
7991 if (attribute_flag[0] != 0)
7992 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7993 &geometry,exception);
7994 if (attribute_flag[1] != 0)
7995 geometry.width=argument_list[1].integer_reference;
7996 if (attribute_flag[2] != 0)
7997 geometry.height=argument_list[2].integer_reference;
7998 if (attribute_flag[3] != 0)
7999 geometry.x=argument_list[3].integer_reference;
8000 if (attribute_flag[4] != 0)
8001 geometry.y=argument_list[4].integer_reference;
8002 if (attribute_flag[5] != 0)
8003 image->fuzz=StringToDoubleInterval(
8004 argument_list[5].string_reference,(double) QuantumRange+1.0);
8005 image=CropImage(image,&geometry,exception);
8006 break;
8007 }
8008 case 9: /* Despeckle */
8009 {
8010 image=DespeckleImage(image,exception);
8011 break;
8012 }
8013 case 10: /* Edge */
8014 {
8015 if (attribute_flag[0] != 0)
8016 geometry_info.rho=argument_list[0].real_reference;
8017 image=EdgeImage(image,geometry_info.rho,exception);
8018 break;
8019 }
8020 case 11: /* Emboss */
8021 {
8022 if (attribute_flag[0] != 0)
8023 {
8024 flags=ParseGeometry(argument_list[0].string_reference,
8025 &geometry_info);
8026 if ((flags & SigmaValue) == 0)
8027 geometry_info.sigma=1.0;
8028 }
8029 if (attribute_flag[1] != 0)
8030 geometry_info.rho=argument_list[1].real_reference;
8031 if (attribute_flag[2] != 0)
8032 geometry_info.sigma=argument_list[2].real_reference;
8033 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8034 exception);
8035 break;
8036 }
8037 case 12: /* Enhance */
8038 {
8039 image=EnhanceImage(image,exception);
8040 break;
8041 }
8042 case 13: /* Flip */
8043 {
8044 image=FlipImage(image,exception);
8045 break;
8046 }
8047 case 14: /* Flop */
8048 {
8049 image=FlopImage(image,exception);
8050 break;
8051 }
8052 case 15: /* Frame */
8053 {
8054 CompositeOperator
8055 compose;
8056
8057 FrameInfo
8058 frame_info;
8059
8060 if (attribute_flag[0] != 0)
8061 {
8062 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8063 &geometry,exception);
8064 frame_info.width=geometry.width;
8065 frame_info.height=geometry.height;
8066 frame_info.outer_bevel=geometry.x;
8067 frame_info.inner_bevel=geometry.y;
8068 }
8069 if (attribute_flag[1] != 0)
8070 frame_info.width=argument_list[1].integer_reference;
8071 if (attribute_flag[2] != 0)
8072 frame_info.height=argument_list[2].integer_reference;
8073 if (attribute_flag[3] != 0)
8074 frame_info.inner_bevel=argument_list[3].integer_reference;
8075 if (attribute_flag[4] != 0)
8076 frame_info.outer_bevel=argument_list[4].integer_reference;
8077 if (attribute_flag[5] != 0)
8078 QueryColorCompliance(argument_list[5].string_reference,
8079 AllCompliance,&fill_color,exception);
8080 if (attribute_flag[6] != 0)
8081 QueryColorCompliance(argument_list[6].string_reference,
8082 AllCompliance,&fill_color,exception);
8083 frame_info.x=(ssize_t) frame_info.width;
8084 frame_info.y=(ssize_t) frame_info.height;
8085 frame_info.width=image->columns+2*frame_info.x;
8086 frame_info.height=image->rows+2*frame_info.y;
8087 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
Cristy8645e042016-02-03 16:35:29 -05008088 image->alpha_color=fill_color;
cristy4a3ce0a2013-08-03 20:06:59 +00008089 compose=image->compose;
8090 if (attribute_flag[7] != 0)
8091 compose=(CompositeOperator) argument_list[7].integer_reference;
8092 image=FrameImage(image,&frame_info,compose,exception);
8093 break;
8094 }
8095 case 16: /* Implode */
8096 {
8097 PixelInterpolateMethod
8098 method;
8099
8100 if (attribute_flag[0] == 0)
8101 argument_list[0].real_reference=0.5;
8102 method=UndefinedInterpolatePixel;
8103 if (attribute_flag[1] != 0)
8104 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8105 image=ImplodeImage(image,argument_list[0].real_reference,
8106 method,exception);
8107 break;
8108 }
8109 case 17: /* Magnify */
8110 {
8111 image=MagnifyImage(image,exception);
8112 break;
8113 }
8114 case 18: /* MedianFilter */
8115 {
8116 if (attribute_flag[0] != 0)
8117 {
8118 flags=ParseGeometry(argument_list[0].string_reference,
8119 &geometry_info);
8120 if ((flags & SigmaValue) == 0)
8121 geometry_info.sigma=geometry_info.rho;
8122 }
8123 if (attribute_flag[1] != 0)
8124 geometry_info.rho=argument_list[1].real_reference;
8125 if (attribute_flag[2] != 0)
8126 geometry_info.sigma=argument_list[2].real_reference;
8127 if (attribute_flag[3] != 0)
8128 channel=(ChannelType) argument_list[3].integer_reference;
8129 channel_mask=SetImageChannelMask(image,channel);
8130 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8131 (size_t) geometry_info.sigma,exception);
8132 if (image != (Image *) NULL)
8133 (void) SetImageChannelMask(image,channel_mask);
8134 break;
8135 }
8136 case 19: /* Minify */
8137 {
8138 image=MinifyImage(image,exception);
8139 break;
8140 }
8141 case 20: /* OilPaint */
8142 {
8143 if (attribute_flag[0] == 0)
8144 argument_list[0].real_reference=0.0;
8145 if (attribute_flag[1] == 0)
8146 argument_list[1].real_reference=1.0;
8147 image=OilPaintImage(image,argument_list[0].real_reference,
8148 argument_list[1].real_reference,exception);
8149 break;
8150 }
8151 case 21: /* ReduceNoise */
8152 {
8153 if (attribute_flag[0] != 0)
8154 {
8155 flags=ParseGeometry(argument_list[0].string_reference,
8156 &geometry_info);
8157 if ((flags & SigmaValue) == 0)
8158 geometry_info.sigma=1.0;
8159 }
8160 if (attribute_flag[1] != 0)
8161 geometry_info.rho=argument_list[1].real_reference;
8162 if (attribute_flag[2] != 0)
8163 geometry_info.sigma=argument_list[2].real_reference;
8164 if (attribute_flag[3] != 0)
8165 channel=(ChannelType) argument_list[3].integer_reference;
8166 channel_mask=SetImageChannelMask(image,channel);
8167 image=StatisticImage(image,NonpeakStatistic,(size_t)
8168 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8169 if (image != (Image *) NULL)
8170 (void) SetImageChannelMask(image,channel_mask);
8171 break;
8172 }
8173 case 22: /* Roll */
8174 {
8175 if (attribute_flag[0] != 0)
8176 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8177 &geometry,exception);
8178 if (attribute_flag[1] != 0)
8179 geometry.x=argument_list[1].integer_reference;
8180 if (attribute_flag[2] != 0)
8181 geometry.y=argument_list[2].integer_reference;
8182 image=RollImage(image,geometry.x,geometry.y,exception);
8183 break;
8184 }
8185 case 23: /* Rotate */
8186 {
8187 if (attribute_flag[0] == 0)
8188 argument_list[0].real_reference=90.0;
8189 if (attribute_flag[1] != 0)
8190 {
8191 QueryColorCompliance(argument_list[1].string_reference,
8192 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008193 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8194 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008195 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8196 }
8197 image=RotateImage(image,argument_list[0].real_reference,exception);
8198 break;
8199 }
8200 case 24: /* Sample */
8201 {
8202 if (attribute_flag[0] != 0)
8203 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8204 &geometry,exception);
8205 if (attribute_flag[1] != 0)
8206 geometry.width=argument_list[1].integer_reference;
8207 if (attribute_flag[2] != 0)
8208 geometry.height=argument_list[2].integer_reference;
8209 image=SampleImage(image,geometry.width,geometry.height,exception);
8210 break;
8211 }
8212 case 25: /* Scale */
8213 {
8214 if (attribute_flag[0] != 0)
8215 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8216 &geometry,exception);
8217 if (attribute_flag[1] != 0)
8218 geometry.width=argument_list[1].integer_reference;
8219 if (attribute_flag[2] != 0)
8220 geometry.height=argument_list[2].integer_reference;
8221 image=ScaleImage(image,geometry.width,geometry.height,exception);
8222 break;
8223 }
8224 case 26: /* Shade */
8225 {
8226 if (attribute_flag[0] != 0)
8227 {
8228 flags=ParseGeometry(argument_list[0].string_reference,
8229 &geometry_info);
8230 if ((flags & SigmaValue) == 0)
8231 geometry_info.sigma=0.0;
8232 }
8233 if (attribute_flag[1] != 0)
8234 geometry_info.rho=argument_list[1].real_reference;
8235 if (attribute_flag[2] != 0)
8236 geometry_info.sigma=argument_list[2].real_reference;
8237 image=ShadeImage(image,
8238 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8239 geometry_info.rho,geometry_info.sigma,exception);
8240 break;
8241 }
8242 case 27: /* Sharpen */
8243 {
8244 if (attribute_flag[0] != 0)
8245 {
8246 flags=ParseGeometry(argument_list[0].string_reference,
8247 &geometry_info);
8248 if ((flags & SigmaValue) == 0)
8249 geometry_info.sigma=1.0;
8250 }
8251 if (attribute_flag[1] != 0)
8252 geometry_info.rho=argument_list[1].real_reference;
8253 if (attribute_flag[2] != 0)
8254 geometry_info.sigma=argument_list[2].real_reference;
8255 if (attribute_flag[3] != 0)
8256 channel=(ChannelType) argument_list[3].integer_reference;
8257 channel_mask=SetImageChannelMask(image,channel);
8258 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8259 exception);
8260 if (image != (Image *) NULL)
8261 (void) SetImageChannelMask(image,channel_mask);
8262 break;
8263 }
8264 case 28: /* Shear */
8265 {
8266 if (attribute_flag[0] != 0)
8267 {
8268 flags=ParseGeometry(argument_list[0].string_reference,
8269 &geometry_info);
8270 if ((flags & SigmaValue) == 0)
8271 geometry_info.sigma=geometry_info.rho;
8272 }
8273 if (attribute_flag[1] != 0)
8274 geometry_info.rho=argument_list[1].real_reference;
8275 if (attribute_flag[2] != 0)
8276 geometry_info.sigma=argument_list[2].real_reference;
8277 if (attribute_flag[3] != 0)
8278 QueryColorCompliance(argument_list[3].string_reference,
8279 AllCompliance,&image->background_color,exception);
8280 if (attribute_flag[4] != 0)
8281 QueryColorCompliance(argument_list[4].string_reference,
8282 AllCompliance,&image->background_color,exception);
8283 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8284 exception);
8285 break;
8286 }
8287 case 29: /* Spread */
8288 {
Cristye3319c12015-08-24 07:11:48 -04008289 PixelInterpolateMethod
8290 method;
8291
cristy4a3ce0a2013-08-03 20:06:59 +00008292 if (attribute_flag[0] == 0)
8293 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008294 method=UndefinedInterpolatePixel;
8295 if (attribute_flag[1] != 0)
8296 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8297 image=SpreadImage(image,method,argument_list[0].real_reference,
8298 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008299 break;
8300 }
8301 case 30: /* Swirl */
8302 {
8303 PixelInterpolateMethod
8304 method;
8305
8306 if (attribute_flag[0] == 0)
8307 argument_list[0].real_reference=50.0;
8308 method=UndefinedInterpolatePixel;
8309 if (attribute_flag[1] != 0)
8310 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8311 image=SwirlImage(image,argument_list[0].real_reference,
8312 method,exception);
8313 break;
8314 }
8315 case 31: /* Resize */
8316 case 32: /* Zoom */
8317 {
8318 if (attribute_flag[0] != 0)
8319 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8320 &geometry,exception);
8321 if (attribute_flag[1] != 0)
8322 geometry.width=argument_list[1].integer_reference;
8323 if (attribute_flag[2] != 0)
8324 geometry.height=argument_list[2].integer_reference;
8325 if (attribute_flag[3] == 0)
8326 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8327 if (attribute_flag[4] != 0)
8328 SetImageArtifact(image,"filter:support",
8329 argument_list[4].string_reference);
8330 image=ResizeImage(image,geometry.width,geometry.height,
Cristy8645e042016-02-03 16:35:29 -05008331 (FilterType) argument_list[3].integer_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00008332 exception);
8333 break;
8334 }
8335 case 33: /* Annotate */
8336 {
8337 DrawInfo
8338 *draw_info;
8339
8340 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8341 (DrawInfo *) NULL);
8342 if (attribute_flag[0] != 0)
8343 {
8344 char
8345 *text;
8346
8347 text=InterpretImageProperties(info ? info->image_info :
8348 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8349 exception);
8350 (void) CloneString(&draw_info->text,text);
8351 text=DestroyString(text);
8352 }
8353 if (attribute_flag[1] != 0)
8354 (void) CloneString(&draw_info->font,
8355 argument_list[1].string_reference);
8356 if (attribute_flag[2] != 0)
8357 draw_info->pointsize=argument_list[2].real_reference;
8358 if (attribute_flag[3] != 0)
8359 (void) CloneString(&draw_info->density,
8360 argument_list[3].string_reference);
8361 if (attribute_flag[4] != 0)
8362 (void) QueryColorCompliance(argument_list[4].string_reference,
8363 AllCompliance,&draw_info->undercolor,exception);
8364 if (attribute_flag[5] != 0)
8365 {
8366 (void) QueryColorCompliance(argument_list[5].string_reference,
8367 AllCompliance,&draw_info->stroke,exception);
8368 if (argument_list[5].image_reference != (Image *) NULL)
8369 draw_info->stroke_pattern=CloneImage(
8370 argument_list[5].image_reference,0,0,MagickTrue,exception);
8371 }
8372 if (attribute_flag[6] != 0)
8373 {
8374 (void) QueryColorCompliance(argument_list[6].string_reference,
8375 AllCompliance,&draw_info->fill,exception);
8376 if (argument_list[6].image_reference != (Image *) NULL)
8377 draw_info->fill_pattern=CloneImage(
8378 argument_list[6].image_reference,0,0,MagickTrue,exception);
8379 }
8380 if (attribute_flag[7] != 0)
8381 {
8382 (void) CloneString(&draw_info->geometry,
8383 argument_list[7].string_reference);
8384 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8385 &geometry,exception);
8386 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8387 geometry_info.sigma=geometry_info.xi;
8388 }
8389 if (attribute_flag[8] != 0)
8390 (void) QueryColorCompliance(argument_list[8].string_reference,
8391 AllCompliance,&draw_info->fill,exception);
8392 if (attribute_flag[11] != 0)
8393 draw_info->gravity=(GravityType)
8394 argument_list[11].integer_reference;
8395 if (attribute_flag[25] != 0)
8396 {
8397 AV
8398 *av;
8399
8400 av=(AV *) argument_list[25].array_reference;
8401 if ((av_len(av) != 3) && (av_len(av) != 5))
8402 {
8403 ThrowPerlException(exception,OptionError,
8404 "affine matrix must have 4 or 6 elements",PackageName);
8405 goto PerlException;
8406 }
8407 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8408 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8409 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8410 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8411 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8412 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8413 {
8414 ThrowPerlException(exception,OptionError,
8415 "affine matrix is singular",PackageName);
8416 goto PerlException;
8417 }
8418 if (av_len(av) == 5)
8419 {
8420 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8421 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8422 }
8423 }
8424 for (j=12; j < 17; j++)
8425 {
8426 if (attribute_flag[j] == 0)
8427 continue;
8428 value=argument_list[j].string_reference;
8429 angle=argument_list[j].real_reference;
8430 current=draw_info->affine;
8431 GetAffineMatrix(&affine);
8432 switch (j)
8433 {
8434 case 12:
8435 {
8436 /*
8437 Translate.
8438 */
8439 flags=ParseGeometry(value,&geometry_info);
8440 affine.tx=geometry_info.xi;
8441 affine.ty=geometry_info.psi;
8442 if ((flags & PsiValue) == 0)
8443 affine.ty=affine.tx;
8444 break;
8445 }
8446 case 13:
8447 {
8448 /*
8449 Scale.
8450 */
8451 flags=ParseGeometry(value,&geometry_info);
8452 affine.sx=geometry_info.rho;
8453 affine.sy=geometry_info.sigma;
8454 if ((flags & SigmaValue) == 0)
8455 affine.sy=affine.sx;
8456 break;
8457 }
8458 case 14:
8459 {
8460 /*
8461 Rotate.
8462 */
8463 if (angle == 0.0)
8464 break;
8465 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8466 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8467 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8468 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8469 break;
8470 }
8471 case 15:
8472 {
8473 /*
8474 SkewX.
8475 */
8476 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8477 break;
8478 }
8479 case 16:
8480 {
8481 /*
8482 SkewY.
8483 */
8484 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8485 break;
8486 }
8487 }
8488 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8489 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8490 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8491 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8492 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8493 current.tx;
8494 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8495 current.ty;
8496 }
8497 if (attribute_flag[9] == 0)
8498 argument_list[9].real_reference=0.0;
8499 if (attribute_flag[10] == 0)
8500 argument_list[10].real_reference=0.0;
8501 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8502 {
8503 char
cristy151b66d2015-04-15 10:50:31 +00008504 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008505
cristy151b66d2015-04-15 10:50:31 +00008506 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008507 (double) argument_list[9].real_reference+draw_info->affine.tx,
8508 (double) argument_list[10].real_reference+draw_info->affine.ty);
8509 (void) CloneString(&draw_info->geometry,geometry);
8510 }
8511 if (attribute_flag[17] != 0)
8512 draw_info->stroke_width=argument_list[17].real_reference;
8513 if (attribute_flag[18] != 0)
8514 {
8515 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8516 MagickTrue : MagickFalse;
8517 draw_info->stroke_antialias=draw_info->text_antialias;
8518 }
8519 if (attribute_flag[19] != 0)
8520 (void) CloneString(&draw_info->family,
8521 argument_list[19].string_reference);
8522 if (attribute_flag[20] != 0)
8523 draw_info->style=(StyleType) argument_list[20].integer_reference;
8524 if (attribute_flag[21] != 0)
8525 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8526 if (attribute_flag[22] != 0)
8527 draw_info->weight=argument_list[22].integer_reference;
8528 if (attribute_flag[23] != 0)
8529 draw_info->align=(AlignType) argument_list[23].integer_reference;
8530 if (attribute_flag[24] != 0)
8531 (void) CloneString(&draw_info->encoding,
8532 argument_list[24].string_reference);
8533 if (attribute_flag[25] != 0)
8534 draw_info->fill_pattern=CloneImage(
8535 argument_list[25].image_reference,0,0,MagickTrue,exception);
8536 if (attribute_flag[26] != 0)
8537 draw_info->fill_pattern=CloneImage(
8538 argument_list[26].image_reference,0,0,MagickTrue,exception);
8539 if (attribute_flag[27] != 0)
8540 draw_info->stroke_pattern=CloneImage(
8541 argument_list[27].image_reference,0,0,MagickTrue,exception);
8542 if (attribute_flag[29] != 0)
8543 draw_info->kerning=argument_list[29].real_reference;
8544 if (attribute_flag[30] != 0)
8545 draw_info->interline_spacing=argument_list[30].real_reference;
8546 if (attribute_flag[31] != 0)
8547 draw_info->interword_spacing=argument_list[31].real_reference;
8548 if (attribute_flag[32] != 0)
8549 draw_info->direction=(DirectionType)
8550 argument_list[32].integer_reference;
8551 (void) AnnotateImage(image,draw_info,exception);
8552 draw_info=DestroyDrawInfo(draw_info);
8553 break;
8554 }
8555 case 34: /* ColorFloodfill */
8556 {
8557 DrawInfo
8558 *draw_info;
8559
8560 MagickBooleanType
8561 invert;
8562
8563 PixelInfo
8564 target;
8565
8566 draw_info=CloneDrawInfo(info ? info->image_info :
8567 (ImageInfo *) NULL,(DrawInfo *) NULL);
8568 if (attribute_flag[0] != 0)
8569 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8570 &geometry,exception);
8571 if (attribute_flag[1] != 0)
8572 geometry.x=argument_list[1].integer_reference;
8573 if (attribute_flag[2] != 0)
8574 geometry.y=argument_list[2].integer_reference;
8575 if (attribute_flag[3] != 0)
8576 (void) QueryColorCompliance(argument_list[3].string_reference,
8577 AllCompliance,&draw_info->fill,exception);
8578 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8579 geometry.x,geometry.y,&target,exception);
8580 invert=MagickFalse;
8581 if (attribute_flag[4] != 0)
8582 {
8583 QueryColorCompliance(argument_list[4].string_reference,
8584 AllCompliance,&target,exception);
8585 invert=MagickTrue;
8586 }
8587 if (attribute_flag[5] != 0)
8588 image->fuzz=StringToDoubleInterval(
8589 argument_list[5].string_reference,(double) QuantumRange+1.0);
8590 if (attribute_flag[6] != 0)
8591 invert=(MagickBooleanType) argument_list[6].integer_reference;
8592 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8593 geometry.y,invert,exception);
8594 draw_info=DestroyDrawInfo(draw_info);
8595 break;
8596 }
8597 case 35: /* Composite */
8598 {
8599 char
cristy151b66d2015-04-15 10:50:31 +00008600 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008601
8602 Image
8603 *composite_image,
8604 *rotate_image;
8605
8606 MagickBooleanType
8607 clip_to_self;
8608
8609 compose=OverCompositeOp;
8610 if (attribute_flag[0] != 0)
8611 composite_image=argument_list[0].image_reference;
8612 else
8613 {
8614 ThrowPerlException(exception,OptionError,
8615 "CompositeImageRequired",PackageName);
8616 goto PerlException;
8617 }
8618 /*
8619 Parameter Handling used for BOTH normal and tiled composition.
8620 */
8621 if (attribute_flag[1] != 0) /* compose */
8622 compose=(CompositeOperator) argument_list[1].integer_reference;
8623 if (attribute_flag[6] != 0) /* opacity */
8624 {
8625 if (compose != DissolveCompositeOp)
8626 (void) SetImageAlpha(composite_image,(Quantum)
8627 StringToDoubleInterval(argument_list[6].string_reference,
8628 (double) QuantumRange+1.0),exception);
8629 else
8630 {
8631 CacheView
8632 *composite_view;
8633
8634 double
8635 opacity;
8636
8637 MagickBooleanType
8638 sync;
8639
8640 register ssize_t
8641 x;
8642
8643 register Quantum
8644 *q;
8645
8646 ssize_t
8647 y;
8648
8649 /*
8650 Handle dissolve composite operator (patch by
8651 Kevin A. McGrail).
8652 */
8653 (void) CloneString(&image->geometry,
8654 argument_list[6].string_reference);
8655 opacity=(Quantum) StringToDoubleInterval(
8656 argument_list[6].string_reference,(double) QuantumRange+
8657 1.0);
cristy17f11b02014-12-20 19:37:04 +00008658 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008659 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8660 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8661 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8662 {
8663 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8664 composite_image->columns,1,exception);
8665 for (x=0; x < (ssize_t) composite_image->columns; x++)
8666 {
8667 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8668 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8669 q);
8670 q+=GetPixelChannels(composite_image);
8671 }
8672 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8673 if (sync == MagickFalse)
8674 break;
8675 }
8676 composite_view=DestroyCacheView(composite_view);
8677 }
8678 }
8679 if (attribute_flag[9] != 0) /* "color=>" */
8680 QueryColorCompliance(argument_list[9].string_reference,
8681 AllCompliance,&composite_image->background_color,exception);
8682 if (attribute_flag[12] != 0) /* "interpolate=>" */
8683 image->interpolate=(PixelInterpolateMethod)
8684 argument_list[12].integer_reference;
8685 if (attribute_flag[13] != 0) /* "args=>" */
8686 (void) SetImageArtifact(composite_image,"compose:args",
8687 argument_list[13].string_reference);
8688 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8689 (void) SetImageArtifact(composite_image,"compose:args",
8690 argument_list[14].string_reference);
8691 clip_to_self=MagickTrue;
8692 if (attribute_flag[15] != 0)
8693 clip_to_self=(MagickBooleanType)
8694 argument_list[15].integer_reference;
8695 /*
8696 Tiling Composition (with orthogonal rotate).
8697 */
8698 rotate_image=(Image *) NULL;
8699 if (attribute_flag[8] != 0) /* "rotate=>" */
8700 {
8701 /*
8702 Rotate image.
8703 */
8704 rotate_image=RotateImage(composite_image,
8705 argument_list[8].real_reference,exception);
8706 if (rotate_image == (Image *) NULL)
8707 break;
8708 }
8709 if ((attribute_flag[7] != 0) &&
8710 (argument_list[7].integer_reference != 0)) /* tile */
8711 {
8712 ssize_t
8713 x,
8714 y;
8715
8716 /*
8717 Tile the composite image.
8718 */
8719 if (attribute_flag[8] != 0) /* "tile=>" */
8720 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8721 "false");
8722 else
8723 (void) SetImageArtifact(composite_image,
8724 "compose:outside-overlay","false");
8725 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8726 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8727 {
8728 if (attribute_flag[8] != 0) /* rotate */
8729 (void) CompositeImage(image,rotate_image,compose,
8730 MagickTrue,x,y,exception);
8731 else
8732 (void) CompositeImage(image,composite_image,compose,
8733 MagickTrue,x,y,exception);
8734 }
8735 if (attribute_flag[8] != 0) /* rotate */
8736 rotate_image=DestroyImage(rotate_image);
8737 break;
8738 }
8739 /*
8740 Parameter Handling used used ONLY for normal composition.
8741 */
8742 if (attribute_flag[5] != 0) /* gravity */
8743 image->gravity=(GravityType) argument_list[5].integer_reference;
8744 if (attribute_flag[2] != 0) /* geometry offset */
8745 {
8746 SetGeometry(image,&geometry);
8747 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8748 &geometry);
8749 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8750 &geometry);
8751 }
8752 if (attribute_flag[3] != 0) /* x offset */
8753 geometry.x=argument_list[3].integer_reference;
8754 if (attribute_flag[4] != 0) /* y offset */
8755 geometry.y=argument_list[4].integer_reference;
8756 if (attribute_flag[10] != 0) /* mask */
8757 {
8758 if ((image->compose == DisplaceCompositeOp) ||
8759 (image->compose == DistortCompositeOp))
8760 {
8761 /*
8762 Merge Y displacement into X displacement image.
8763 */
8764 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8765 exception);
8766 (void) CompositeImage(composite_image,
8767 argument_list[10].image_reference,CopyGreenCompositeOp,
8768 MagickTrue,0,0,exception);
8769 }
8770 else
8771 {
8772 Image
8773 *mask_image;
8774
8775 /*
8776 Set a blending mask for the composition.
8777 */
8778 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8779 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008780 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008781 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008782 mask_image=DestroyImage(mask_image);
8783 }
8784 }
8785 if (attribute_flag[11] != 0) /* channel */
8786 channel=(ChannelType) argument_list[11].integer_reference;
8787 /*
8788 Composite two images (normal composition).
8789 */
cristy151b66d2015-04-15 10:50:31 +00008790 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008791 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8792 (double) composite_image->rows,(double) geometry.x,(double)
8793 geometry.y);
8794 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8795 exception);
8796 channel_mask=SetImageChannelMask(image,channel);
8797 if (attribute_flag[8] == 0) /* no rotate */
8798 CompositeImage(image,composite_image,compose,clip_to_self,
8799 geometry.x,geometry.y,exception);
8800 else
8801 {
8802 /*
8803 Position adjust rotated image then composite.
8804 */
8805 geometry.x-=(ssize_t) (rotate_image->columns-
8806 composite_image->columns)/2;
8807 geometry.y-=(ssize_t) (rotate_image->rows-
8808 composite_image->rows)/2;
8809 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8810 geometry.y,exception);
8811 rotate_image=DestroyImage(rotate_image);
8812 }
8813 if (attribute_flag[10] != 0) /* mask */
8814 {
8815 if ((image->compose == DisplaceCompositeOp) ||
8816 (image->compose == DistortCompositeOp))
8817 composite_image=DestroyImage(composite_image);
8818 else
cristy1f7ffb72015-07-29 11:07:03 +00008819 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008820 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008821 }
8822 (void) SetImageChannelMask(image,channel_mask);
8823 break;
8824 }
8825 case 36: /* Contrast */
8826 {
8827 if (attribute_flag[0] == 0)
8828 argument_list[0].integer_reference=0;
8829 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8830 MagickTrue : MagickFalse,exception);
8831 break;
8832 }
8833 case 37: /* CycleColormap */
8834 {
8835 if (attribute_flag[0] == 0)
8836 argument_list[0].integer_reference=6;
8837 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8838 exception);
8839 break;
8840 }
8841 case 38: /* Draw */
8842 {
8843 DrawInfo
8844 *draw_info;
8845
8846 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8847 (DrawInfo *) NULL);
8848 (void) CloneString(&draw_info->primitive,"point");
8849 if (attribute_flag[0] != 0)
8850 {
8851 if (argument_list[0].integer_reference < 0)
8852 (void) CloneString(&draw_info->primitive,
8853 argument_list[0].string_reference);
8854 else
8855 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8856 MagickPrimitiveOptions,argument_list[0].integer_reference));
8857 }
8858 if (attribute_flag[1] != 0)
8859 {
8860 if (LocaleCompare(draw_info->primitive,"path") == 0)
8861 {
8862 (void) ConcatenateString(&draw_info->primitive," '");
8863 ConcatenateString(&draw_info->primitive,
8864 argument_list[1].string_reference);
8865 (void) ConcatenateString(&draw_info->primitive,"'");
8866 }
8867 else
8868 {
8869 (void) ConcatenateString(&draw_info->primitive," ");
8870 ConcatenateString(&draw_info->primitive,
8871 argument_list[1].string_reference);
8872 }
8873 }
8874 if (attribute_flag[2] != 0)
8875 {
8876 (void) ConcatenateString(&draw_info->primitive," ");
8877 (void) ConcatenateString(&draw_info->primitive,
8878 CommandOptionToMnemonic(MagickMethodOptions,
8879 argument_list[2].integer_reference));
8880 }
8881 if (attribute_flag[3] != 0)
8882 {
8883 (void) QueryColorCompliance(argument_list[3].string_reference,
8884 AllCompliance,&draw_info->stroke,exception);
8885 if (argument_list[3].image_reference != (Image *) NULL)
8886 draw_info->stroke_pattern=CloneImage(
8887 argument_list[3].image_reference,0,0,MagickTrue,exception);
8888 }
8889 if (attribute_flag[4] != 0)
8890 {
8891 (void) QueryColorCompliance(argument_list[4].string_reference,
8892 AllCompliance,&draw_info->fill,exception);
8893 if (argument_list[4].image_reference != (Image *) NULL)
8894 draw_info->fill_pattern=CloneImage(
8895 argument_list[4].image_reference,0,0,MagickTrue,exception);
8896 }
8897 if (attribute_flag[5] != 0)
8898 draw_info->stroke_width=argument_list[5].real_reference;
8899 if (attribute_flag[6] != 0)
8900 (void) CloneString(&draw_info->font,
8901 argument_list[6].string_reference);
8902 if (attribute_flag[7] != 0)
8903 (void) QueryColorCompliance(argument_list[7].string_reference,
8904 AllCompliance,&draw_info->border_color,exception);
8905 if (attribute_flag[8] != 0)
8906 draw_info->affine.tx=argument_list[8].real_reference;
8907 if (attribute_flag[9] != 0)
8908 draw_info->affine.ty=argument_list[9].real_reference;
8909 if (attribute_flag[20] != 0)
8910 {
8911 AV
8912 *av;
8913
8914 av=(AV *) argument_list[20].array_reference;
8915 if ((av_len(av) != 3) && (av_len(av) != 5))
8916 {
8917 ThrowPerlException(exception,OptionError,
8918 "affine matrix must have 4 or 6 elements",PackageName);
8919 goto PerlException;
8920 }
8921 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8922 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8923 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8924 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8925 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8926 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8927 {
8928 ThrowPerlException(exception,OptionError,
8929 "affine matrix is singular",PackageName);
8930 goto PerlException;
8931 }
8932 if (av_len(av) == 5)
8933 {
8934 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8935 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8936 }
8937 }
8938 for (j=10; j < 15; j++)
8939 {
8940 if (attribute_flag[j] == 0)
8941 continue;
8942 value=argument_list[j].string_reference;
8943 angle=argument_list[j].real_reference;
8944 current=draw_info->affine;
8945 GetAffineMatrix(&affine);
8946 switch (j)
8947 {
8948 case 10:
8949 {
8950 /*
8951 Translate.
8952 */
8953 flags=ParseGeometry(value,&geometry_info);
8954 affine.tx=geometry_info.xi;
8955 affine.ty=geometry_info.psi;
8956 if ((flags & PsiValue) == 0)
8957 affine.ty=affine.tx;
8958 break;
8959 }
8960 case 11:
8961 {
8962 /*
8963 Scale.
8964 */
8965 flags=ParseGeometry(value,&geometry_info);
8966 affine.sx=geometry_info.rho;
8967 affine.sy=geometry_info.sigma;
8968 if ((flags & SigmaValue) == 0)
8969 affine.sy=affine.sx;
8970 break;
8971 }
8972 case 12:
8973 {
8974 /*
8975 Rotate.
8976 */
8977 if (angle == 0.0)
8978 break;
8979 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8980 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8981 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8982 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8983 break;
8984 }
8985 case 13:
8986 {
8987 /*
8988 SkewX.
8989 */
8990 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8991 break;
8992 }
8993 case 14:
8994 {
8995 /*
8996 SkewY.
8997 */
8998 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8999 break;
9000 }
9001 }
9002 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9003 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9004 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9005 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9006 draw_info->affine.tx=
9007 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9008 draw_info->affine.ty=
9009 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9010 }
9011 if (attribute_flag[15] != 0)
9012 draw_info->fill_pattern=CloneImage(
9013 argument_list[15].image_reference,0,0,MagickTrue,exception);
9014 if (attribute_flag[16] != 0)
9015 draw_info->pointsize=argument_list[16].real_reference;
9016 if (attribute_flag[17] != 0)
9017 {
9018 draw_info->stroke_antialias=argument_list[17].integer_reference != 0
9019 ? MagickTrue : MagickFalse;
9020 draw_info->text_antialias=draw_info->stroke_antialias;
9021 }
9022 if (attribute_flag[18] != 0)
9023 (void) CloneString(&draw_info->density,
9024 argument_list[18].string_reference);
9025 if (attribute_flag[19] != 0)
9026 draw_info->stroke_width=argument_list[19].real_reference;
9027 if (attribute_flag[21] != 0)
9028 draw_info->dash_offset=argument_list[21].real_reference;
9029 if (attribute_flag[22] != 0)
9030 {
9031 AV
9032 *av;
9033
9034 av=(AV *) argument_list[22].array_reference;
9035 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9036 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9037 if (draw_info->dash_pattern != (double *) NULL)
9038 {
9039 for (i=0; i <= av_len(av); i++)
9040 draw_info->dash_pattern[i]=(double)
9041 SvNV(*(av_fetch(av,i,0)));
9042 draw_info->dash_pattern[i]=0.0;
9043 }
9044 }
9045 if (attribute_flag[23] != 0)
9046 image->interpolate=(PixelInterpolateMethod)
9047 argument_list[23].integer_reference;
9048 if ((attribute_flag[24] != 0) &&
9049 (draw_info->fill_pattern != (Image *) NULL))
9050 flags=ParsePageGeometry(draw_info->fill_pattern,
9051 argument_list[24].string_reference,
9052 &draw_info->fill_pattern->tile_offset,exception);
9053 if (attribute_flag[25] != 0)
9054 {
9055 (void) ConcatenateString(&draw_info->primitive," '");
9056 (void) ConcatenateString(&draw_info->primitive,
9057 argument_list[25].string_reference);
9058 (void) ConcatenateString(&draw_info->primitive,"'");
9059 }
9060 if (attribute_flag[26] != 0)
9061 draw_info->fill_pattern=CloneImage(
9062 argument_list[26].image_reference,0,0,MagickTrue,exception);
9063 if (attribute_flag[27] != 0)
9064 draw_info->stroke_pattern=CloneImage(
9065 argument_list[27].image_reference,0,0,MagickTrue,exception);
9066 if (attribute_flag[28] != 0)
9067 (void) CloneString(&draw_info->primitive,
9068 argument_list[28].string_reference);
9069 if (attribute_flag[29] != 0)
9070 draw_info->kerning=argument_list[29].real_reference;
9071 if (attribute_flag[30] != 0)
9072 draw_info->interline_spacing=argument_list[30].real_reference;
9073 if (attribute_flag[31] != 0)
9074 draw_info->interword_spacing=argument_list[31].real_reference;
9075 if (attribute_flag[32] != 0)
9076 draw_info->direction=(DirectionType)
9077 argument_list[32].integer_reference;
9078 DrawImage(image,draw_info,exception);
9079 draw_info=DestroyDrawInfo(draw_info);
9080 break;
9081 }
9082 case 39: /* Equalize */
9083 {
9084 if (attribute_flag[0] != 0)
9085 channel=(ChannelType) argument_list[0].integer_reference;
9086 channel_mask=SetImageChannelMask(image,channel);
9087 EqualizeImage(image,exception);
9088 (void) SetImageChannelMask(image,channel_mask);
9089 break;
9090 }
9091 case 40: /* Gamma */
9092 {
9093 if (attribute_flag[1] != 0)
9094 channel=(ChannelType) argument_list[1].integer_reference;
9095 if (attribute_flag[2] == 0)
9096 argument_list[2].real_reference=1.0;
9097 if (attribute_flag[3] == 0)
9098 argument_list[3].real_reference=1.0;
9099 if (attribute_flag[4] == 0)
9100 argument_list[4].real_reference=1.0;
9101 if (attribute_flag[0] == 0)
9102 {
cristy151b66d2015-04-15 10:50:31 +00009103 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00009104 "%.15g,%.15g,%.15g",(double) argument_list[2].real_reference,
9105 (double) argument_list[3].real_reference,
9106 (double) argument_list[4].real_reference);
9107 argument_list[0].string_reference=message;
9108 }
9109 (void) GammaImage(image,StringToDouble(
9110 argument_list[0].string_reference,(char **) NULL),exception);
9111 break;
9112 }
9113 case 41: /* Map */
9114 {
9115 QuantizeInfo
9116 *quantize_info;
9117
9118 if (attribute_flag[0] == 0)
9119 {
9120 ThrowPerlException(exception,OptionError,"MapImageRequired",
9121 PackageName);
9122 goto PerlException;
9123 }
9124 quantize_info=AcquireQuantizeInfo(info->image_info);
9125 if (attribute_flag[1] != 0)
9126 quantize_info->dither_method=(DitherMethod)
9127 argument_list[1].integer_reference;
9128 (void) RemapImages(quantize_info,image,
9129 argument_list[0].image_reference,exception);
9130 quantize_info=DestroyQuantizeInfo(quantize_info);
9131 break;
9132 }
9133 case 42: /* MatteFloodfill */
9134 {
9135 DrawInfo
9136 *draw_info;
9137
9138 MagickBooleanType
9139 invert;
9140
9141 PixelInfo
9142 target;
9143
9144 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9145 (DrawInfo *) NULL);
9146 if (attribute_flag[0] != 0)
9147 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9148 &geometry,exception);
9149 if (attribute_flag[1] != 0)
9150 geometry.x=argument_list[1].integer_reference;
9151 if (attribute_flag[2] != 0)
9152 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009153 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009154 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9155 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9156 geometry.x,geometry.y,&target,exception);
9157 if (attribute_flag[4] != 0)
9158 QueryColorCompliance(argument_list[4].string_reference,
9159 AllCompliance,&target,exception);
9160 if (attribute_flag[3] != 0)
9161 target.alpha=StringToDoubleInterval(
9162 argument_list[3].string_reference,(double) (double) QuantumRange+
9163 1.0);
9164 if (attribute_flag[5] != 0)
9165 image->fuzz=StringToDoubleInterval(
9166 argument_list[5].string_reference,(double) QuantumRange+1.0);
9167 invert=MagickFalse;
9168 if (attribute_flag[6] != 0)
9169 invert=(MagickBooleanType) argument_list[6].integer_reference;
9170 channel_mask=SetImageChannelMask(image,AlphaChannel);
9171 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9172 geometry.y,invert,exception);
9173 (void) SetImageChannelMask(image,channel_mask);
9174 draw_info=DestroyDrawInfo(draw_info);
9175 break;
9176 }
9177 case 43: /* Modulate */
9178 {
9179 char
cristy151b66d2015-04-15 10:50:31 +00009180 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009181
9182 geometry_info.rho=100.0;
9183 geometry_info.sigma=100.0;
9184 geometry_info.xi=100.0;
9185 if (attribute_flag[0] != 0)
9186 (void)ParseGeometry(argument_list[0].string_reference,
9187 &geometry_info);
9188 if (attribute_flag[1] != 0)
9189 geometry_info.xi=argument_list[1].real_reference;
9190 if (attribute_flag[2] != 0)
9191 geometry_info.sigma=argument_list[2].real_reference;
9192 if (attribute_flag[3] != 0)
9193 {
9194 geometry_info.sigma=argument_list[3].real_reference;
9195 SetImageArtifact(image,"modulate:colorspace","HWB");
9196 }
9197 if (attribute_flag[4] != 0)
9198 {
9199 geometry_info.rho=argument_list[4].real_reference;
9200 SetImageArtifact(image,"modulate:colorspace","HSB");
9201 }
9202 if (attribute_flag[5] != 0)
9203 {
9204 geometry_info.sigma=argument_list[5].real_reference;
9205 SetImageArtifact(image,"modulate:colorspace","HSL");
9206 }
9207 if (attribute_flag[6] != 0)
9208 {
9209 geometry_info.rho=argument_list[6].real_reference;
9210 SetImageArtifact(image,"modulate:colorspace","HWB");
9211 }
cristy151b66d2015-04-15 10:50:31 +00009212 (void) FormatLocaleString(modulate,MagickPathExtent,"%.15g,%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00009213 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
9214 (void) ModulateImage(image,modulate,exception);
9215 break;
9216 }
9217 case 44: /* Negate */
9218 {
9219 if (attribute_flag[0] == 0)
9220 argument_list[0].integer_reference=0;
9221 if (attribute_flag[1] != 0)
9222 channel=(ChannelType) argument_list[1].integer_reference;
9223 channel_mask=SetImageChannelMask(image,channel);
9224 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9225 MagickTrue : MagickFalse,exception);
9226 (void) SetImageChannelMask(image,channel_mask);
9227 break;
9228 }
9229 case 45: /* Normalize */
9230 {
9231 if (attribute_flag[0] != 0)
9232 channel=(ChannelType) argument_list[0].integer_reference;
9233 channel_mask=SetImageChannelMask(image,channel);
9234 NormalizeImage(image,exception);
9235 (void) SetImageChannelMask(image,channel_mask);
9236 break;
9237 }
9238 case 46: /* NumberColors */
9239 break;
9240 case 47: /* Opaque */
9241 {
9242 MagickBooleanType
9243 invert;
9244
9245 PixelInfo
9246 fill_color,
9247 target;
9248
9249 (void) QueryColorCompliance("none",AllCompliance,&target,
9250 exception);
9251 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9252 exception);
9253 if (attribute_flag[0] != 0)
9254 (void) QueryColorCompliance(argument_list[0].string_reference,
9255 AllCompliance,&target,exception);
9256 if (attribute_flag[1] != 0)
9257 (void) QueryColorCompliance(argument_list[1].string_reference,
9258 AllCompliance,&fill_color,exception);
9259 if (attribute_flag[2] != 0)
9260 image->fuzz=StringToDoubleInterval(
9261 argument_list[2].string_reference,(double) QuantumRange+1.0);
9262 if (attribute_flag[3] != 0)
9263 channel=(ChannelType) argument_list[3].integer_reference;
9264 invert=MagickFalse;
9265 if (attribute_flag[4] != 0)
9266 invert=(MagickBooleanType) argument_list[4].integer_reference;
9267 channel_mask=SetImageChannelMask(image,channel);
9268 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9269 (void) SetImageChannelMask(image,channel_mask);
9270 break;
9271 }
9272 case 48: /* Quantize */
9273 {
9274 QuantizeInfo
9275 *quantize_info;
9276
9277 quantize_info=AcquireQuantizeInfo(info->image_info);
9278 if (attribute_flag[0] != 0)
9279 quantize_info->number_colors=(size_t)
9280 argument_list[0].integer_reference;
9281 if (attribute_flag[1] != 0)
9282 quantize_info->tree_depth=(size_t)
9283 argument_list[1].integer_reference;
9284 if (attribute_flag[2] != 0)
9285 quantize_info->colorspace=(ColorspaceType)
9286 argument_list[2].integer_reference;
9287 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009288 quantize_info->dither_method=(DitherMethod)
9289 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009290 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009291 quantize_info->measure_error=
9292 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009293 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009294 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009295 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009296 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009297 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009298 argument_list[7].integer_reference;
9299 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009300 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009301 else
cristyf7563392014-03-25 13:54:04 +00009302 if ((image->storage_class == DirectClass) ||
9303 (image->colors > quantize_info->number_colors) ||
9304 (quantize_info->colorspace == GRAYColorspace))
9305 (void) QuantizeImage(quantize_info,image,exception);
9306 else
9307 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009308 quantize_info=DestroyQuantizeInfo(quantize_info);
9309 break;
9310 }
9311 case 49: /* Raise */
9312 {
9313 if (attribute_flag[0] != 0)
9314 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9315 &geometry,exception);
9316 if (attribute_flag[1] != 0)
9317 geometry.width=argument_list[1].integer_reference;
9318 if (attribute_flag[2] != 0)
9319 geometry.height=argument_list[2].integer_reference;
9320 if (attribute_flag[3] == 0)
9321 argument_list[3].integer_reference=1;
9322 (void) RaiseImage(image,&geometry,
9323 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9324 exception);
9325 break;
9326 }
9327 case 50: /* Segment */
9328 {
9329 ColorspaceType
9330 colorspace;
9331
9332 double
9333 cluster_threshold,
9334 smoothing_threshold;
9335
9336 MagickBooleanType
9337 verbose;
9338
9339 cluster_threshold=1.0;
9340 smoothing_threshold=1.5;
9341 colorspace=sRGBColorspace;
9342 verbose=MagickFalse;
9343 if (attribute_flag[0] != 0)
9344 {
9345 flags=ParseGeometry(argument_list[0].string_reference,
9346 &geometry_info);
9347 cluster_threshold=geometry_info.rho;
9348 if (flags & SigmaValue)
9349 smoothing_threshold=geometry_info.sigma;
9350 }
9351 if (attribute_flag[1] != 0)
9352 cluster_threshold=argument_list[1].real_reference;
9353 if (attribute_flag[2] != 0)
9354 smoothing_threshold=argument_list[2].real_reference;
9355 if (attribute_flag[3] != 0)
9356 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9357 if (attribute_flag[4] != 0)
9358 verbose=argument_list[4].integer_reference != 0 ?
9359 MagickTrue : MagickFalse;
9360 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9361 smoothing_threshold,exception);
9362 break;
9363 }
9364 case 51: /* Signature */
9365 {
9366 (void) SignatureImage(image,exception);
9367 break;
9368 }
9369 case 52: /* Solarize */
9370 {
9371 geometry_info.rho=QuantumRange/2.0;
9372 if (attribute_flag[0] != 0)
9373 flags=ParseGeometry(argument_list[0].string_reference,
9374 &geometry_info);
9375 if (attribute_flag[1] != 0)
9376 geometry_info.rho=StringToDoubleInterval(
9377 argument_list[1].string_reference,(double) QuantumRange+1.0);
9378 (void) SolarizeImage(image,geometry_info.rho,exception);
9379 break;
9380 }
9381 case 53: /* Sync */
9382 {
9383 (void) SyncImage(image,exception);
9384 break;
9385 }
9386 case 54: /* Texture */
9387 {
9388 if (attribute_flag[0] == 0)
9389 break;
9390 TextureImage(image,argument_list[0].image_reference,exception);
9391 break;
9392 }
9393 case 55: /* Evalute */
9394 {
9395 MagickEvaluateOperator
9396 op;
9397
9398 op=SetEvaluateOperator;
9399 if (attribute_flag[0] == MagickFalse)
9400 argument_list[0].real_reference=0.0;
9401 if (attribute_flag[1] != MagickFalse)
9402 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9403 if (attribute_flag[2] != MagickFalse)
9404 channel=(ChannelType) argument_list[2].integer_reference;
9405 channel_mask=SetImageChannelMask(image,channel);
9406 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9407 exception);
9408 (void) SetImageChannelMask(image,channel_mask);
9409 break;
9410 }
9411 case 56: /* Transparent */
9412 {
9413 double
9414 opacity;
9415
9416 MagickBooleanType
9417 invert;
9418
9419 PixelInfo
9420 target;
9421
9422 (void) QueryColorCompliance("none",AllCompliance,&target,
9423 exception);
9424 if (attribute_flag[0] != 0)
9425 (void) QueryColorCompliance(argument_list[0].string_reference,
9426 AllCompliance,&target,exception);
9427 opacity=TransparentAlpha;
9428 if (attribute_flag[1] != 0)
9429 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9430 (double) QuantumRange+1.0);
9431 if (attribute_flag[2] != 0)
9432 image->fuzz=StringToDoubleInterval(
9433 argument_list[2].string_reference,(double) QuantumRange+1.0);
9434 if (attribute_flag[3] == 0)
9435 argument_list[3].integer_reference=0;
9436 invert=MagickFalse;
9437 if (attribute_flag[3] != 0)
9438 invert=(MagickBooleanType) argument_list[3].integer_reference;
9439 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9440 invert,exception);
9441 break;
9442 }
9443 case 57: /* Threshold */
9444 {
9445 double
9446 threshold;
9447
9448 if (attribute_flag[0] == 0)
9449 argument_list[0].string_reference="50%";
9450 if (attribute_flag[1] != 0)
9451 channel=(ChannelType) argument_list[1].integer_reference;
9452 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9453 (double) QuantumRange+1.0);
9454 channel_mask=SetImageChannelMask(image,channel);
9455 (void) BilevelImage(image,threshold,exception);
9456 (void) SetImageChannelMask(image,channel_mask);
9457 break;
9458 }
9459 case 58: /* Charcoal */
9460 {
9461 if (attribute_flag[0] != 0)
9462 {
9463 flags=ParseGeometry(argument_list[0].string_reference,
9464 &geometry_info);
9465 if ((flags & SigmaValue) == 0)
9466 geometry_info.sigma=1.0;
9467 }
9468 if (attribute_flag[1] != 0)
9469 geometry_info.rho=argument_list[1].real_reference;
9470 if (attribute_flag[2] != 0)
9471 geometry_info.sigma=argument_list[2].real_reference;
9472 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9473 exception);
9474 break;
9475 }
9476 case 59: /* Trim */
9477 {
9478 if (attribute_flag[0] != 0)
9479 image->fuzz=StringToDoubleInterval(
9480 argument_list[0].string_reference,(double) QuantumRange+1.0);
9481 image=TrimImage(image,exception);
9482 break;
9483 }
9484 case 60: /* Wave */
9485 {
9486 PixelInterpolateMethod
9487 method;
9488
9489 if (attribute_flag[0] != 0)
9490 {
9491 flags=ParseGeometry(argument_list[0].string_reference,
9492 &geometry_info);
9493 if ((flags & SigmaValue) == 0)
9494 geometry_info.sigma=1.0;
9495 }
9496 if (attribute_flag[1] != 0)
9497 geometry_info.rho=argument_list[1].real_reference;
9498 if (attribute_flag[2] != 0)
9499 geometry_info.sigma=argument_list[2].real_reference;
9500 method=UndefinedInterpolatePixel;
9501 if (attribute_flag[3] != 0)
9502 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9503 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9504 method,exception);
9505 break;
9506 }
9507 case 61: /* Separate */
9508 {
9509 if (attribute_flag[0] != 0)
9510 channel=(ChannelType) argument_list[0].integer_reference;
9511 image=SeparateImage(image,channel,exception);
9512 break;
9513 }
9514 case 63: /* Stereo */
9515 {
9516 if (attribute_flag[0] == 0)
9517 {
9518 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9519 PackageName);
9520 goto PerlException;
9521 }
9522 if (attribute_flag[1] != 0)
9523 geometry.x=argument_list[1].integer_reference;
9524 if (attribute_flag[2] != 0)
9525 geometry.y=argument_list[2].integer_reference;
9526 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9527 geometry.x,geometry.y,exception);
9528 break;
9529 }
9530 case 64: /* Stegano */
9531 {
9532 if (attribute_flag[0] == 0)
9533 {
9534 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9535 PackageName);
9536 goto PerlException;
9537 }
9538 if (attribute_flag[1] == 0)
9539 argument_list[1].integer_reference=0;
9540 image->offset=argument_list[1].integer_reference;
9541 image=SteganoImage(image,argument_list[0].image_reference,exception);
9542 break;
9543 }
9544 case 65: /* Deconstruct */
9545 {
9546 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9547 break;
9548 }
9549 case 66: /* GaussianBlur */
9550 {
9551 if (attribute_flag[0] != 0)
9552 {
9553 flags=ParseGeometry(argument_list[0].string_reference,
9554 &geometry_info);
9555 if ((flags & SigmaValue) == 0)
9556 geometry_info.sigma=1.0;
9557 }
9558 if (attribute_flag[1] != 0)
9559 geometry_info.rho=argument_list[1].real_reference;
9560 if (attribute_flag[2] != 0)
9561 geometry_info.sigma=argument_list[2].real_reference;
9562 if (attribute_flag[3] != 0)
9563 channel=(ChannelType) argument_list[3].integer_reference;
9564 channel_mask=SetImageChannelMask(image,channel);
9565 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9566 exception);
9567 if (image != (Image *) NULL)
9568 (void) SetImageChannelMask(image,channel_mask);
9569 break;
9570 }
9571 case 67: /* Convolve */
9572 {
9573 KernelInfo
9574 *kernel;
9575
9576 kernel=(KernelInfo *) NULL;
9577 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9578 break;
9579 if (attribute_flag[0] != 0)
9580 {
9581 AV
9582 *av;
9583
9584 size_t
9585 order;
9586
cristy2c57b742014-10-31 00:40:34 +00009587 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009588 if (kernel == (KernelInfo *) NULL)
9589 break;
9590 av=(AV *) argument_list[0].array_reference;
9591 order=(size_t) sqrt(av_len(av)+1);
9592 kernel->width=order;
9593 kernel->height=order;
9594 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9595 order*sizeof(*kernel->values));
9596 if (kernel->values == (MagickRealType *) NULL)
9597 {
9598 kernel=DestroyKernelInfo(kernel);
9599 ThrowPerlException(exception,ResourceLimitFatalError,
9600 "MemoryAllocationFailed",PackageName);
9601 goto PerlException;
9602 }
9603 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9604 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9605 for ( ; j < (ssize_t) (order*order); j++)
9606 kernel->values[j]=0.0;
9607 }
9608 if (attribute_flag[1] != 0)
9609 channel=(ChannelType) argument_list[1].integer_reference;
9610 if (attribute_flag[2] != 0)
9611 SetImageArtifact(image,"filter:blur",
9612 argument_list[2].string_reference);
9613 if (attribute_flag[3] != 0)
9614 {
cristy2c57b742014-10-31 00:40:34 +00009615 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9616 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009617 if (kernel == (KernelInfo *) NULL)
9618 break;
9619 }
9620 channel_mask=SetImageChannelMask(image,channel);
9621 image=ConvolveImage(image,kernel,exception);
9622 if (image != (Image *) NULL)
9623 (void) SetImageChannelMask(image,channel_mask);
9624 kernel=DestroyKernelInfo(kernel);
9625 break;
9626 }
9627 case 68: /* Profile */
9628 {
9629 const char
9630 *name;
9631
9632 Image
9633 *profile_image;
9634
9635 ImageInfo
9636 *profile_info;
9637
9638 StringInfo
9639 *profile;
9640
9641 name="*";
9642 if (attribute_flag[0] != 0)
9643 name=argument_list[0].string_reference;
9644 if (attribute_flag[2] != 0)
9645 image->rendering_intent=(RenderingIntent)
9646 argument_list[2].integer_reference;
9647 if (attribute_flag[3] != 0)
9648 image->black_point_compensation=
9649 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9650 if (attribute_flag[1] != 0)
9651 {
9652 if (argument_list[1].length == 0)
9653 {
9654 /*
9655 Remove a profile from the image.
9656 */
9657 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9658 exception);
9659 break;
9660 }
9661 /*
9662 Associate user supplied profile with the image.
9663 */
9664 profile=AcquireStringInfo(argument_list[1].length);
9665 SetStringInfoDatum(profile,(const unsigned char *)
9666 argument_list[1].string_reference);
9667 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9668 (size_t) GetStringInfoLength(profile),exception);
9669 profile=DestroyStringInfo(profile);
9670 break;
9671 }
9672 /*
9673 Associate a profile with the image.
9674 */
9675 profile_info=CloneImageInfo(info ? info->image_info :
9676 (ImageInfo *) NULL);
9677 profile_image=ReadImages(profile_info,name,exception);
9678 if (profile_image == (Image *) NULL)
9679 break;
9680 ResetImageProfileIterator(profile_image);
9681 name=GetNextImageProfile(profile_image);
9682 while (name != (const char *) NULL)
9683 {
9684 const StringInfo
9685 *profile;
9686
9687 profile=GetImageProfile(profile_image,name);
9688 if (profile != (const StringInfo *) NULL)
9689 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9690 (size_t) GetStringInfoLength(profile),exception);
9691 name=GetNextImageProfile(profile_image);
9692 }
9693 profile_image=DestroyImage(profile_image);
9694 profile_info=DestroyImageInfo(profile_info);
9695 break;
9696 }
9697 case 69: /* UnsharpMask */
9698 {
9699 if (attribute_flag[0] != 0)
9700 {
9701 flags=ParseGeometry(argument_list[0].string_reference,
9702 &geometry_info);
9703 if ((flags & SigmaValue) == 0)
9704 geometry_info.sigma=1.0;
9705 if ((flags & XiValue) == 0)
9706 geometry_info.xi=1.0;
9707 if ((flags & PsiValue) == 0)
9708 geometry_info.psi=0.5;
9709 }
9710 if (attribute_flag[1] != 0)
9711 geometry_info.rho=argument_list[1].real_reference;
9712 if (attribute_flag[2] != 0)
9713 geometry_info.sigma=argument_list[2].real_reference;
9714 if (attribute_flag[3] != 0)
9715 geometry_info.xi=argument_list[3].real_reference;
9716 if (attribute_flag[4] != 0)
9717 geometry_info.psi=argument_list[4].real_reference;
9718 if (attribute_flag[5] != 0)
9719 channel=(ChannelType) argument_list[5].integer_reference;
9720 channel_mask=SetImageChannelMask(image,channel);
9721 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9722 geometry_info.xi,geometry_info.psi,exception);
9723 if (image != (Image *) NULL)
9724 (void) SetImageChannelMask(image,channel_mask);
9725 break;
9726 }
9727 case 70: /* MotionBlur */
9728 {
9729 if (attribute_flag[0] != 0)
9730 {
9731 flags=ParseGeometry(argument_list[0].string_reference,
9732 &geometry_info);
9733 if ((flags & SigmaValue) == 0)
9734 geometry_info.sigma=1.0;
9735 if ((flags & XiValue) == 0)
9736 geometry_info.xi=1.0;
9737 }
9738 if (attribute_flag[1] != 0)
9739 geometry_info.rho=argument_list[1].real_reference;
9740 if (attribute_flag[2] != 0)
9741 geometry_info.sigma=argument_list[2].real_reference;
9742 if (attribute_flag[3] != 0)
9743 geometry_info.xi=argument_list[3].real_reference;
9744 if (attribute_flag[4] != 0)
9745 channel=(ChannelType) argument_list[4].integer_reference;
9746 channel_mask=SetImageChannelMask(image,channel);
9747 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9748 geometry_info.xi,exception);
9749 if (image != (Image *) NULL)
9750 (void) SetImageChannelMask(image,channel_mask);
9751 break;
9752 }
9753 case 71: /* OrderedDither */
9754 {
9755 if (attribute_flag[0] == 0)
9756 argument_list[0].string_reference="o8x8";
9757 if (attribute_flag[1] != 0)
9758 channel=(ChannelType) argument_list[1].integer_reference;
9759 channel_mask=SetImageChannelMask(image,channel);
Cristy6b93c072016-02-04 07:45:48 -05009760 (void) OrderedDitherImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009761 exception);
9762 (void) SetImageChannelMask(image,channel_mask);
9763 break;
9764 }
9765 case 72: /* Shave */
9766 {
9767 if (attribute_flag[0] != 0)
9768 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9769 &geometry,exception);
9770 if (attribute_flag[1] != 0)
9771 geometry.width=argument_list[1].integer_reference;
9772 if (attribute_flag[2] != 0)
9773 geometry.height=argument_list[2].integer_reference;
9774 image=ShaveImage(image,&geometry,exception);
9775 break;
9776 }
9777 case 73: /* Level */
9778 {
9779 double
9780 black_point,
9781 gamma,
9782 white_point;
9783
9784 black_point=0.0;
9785 white_point=(double) image->columns*image->rows;
9786 gamma=1.0;
9787 if (attribute_flag[0] != 0)
9788 {
9789 flags=ParseGeometry(argument_list[0].string_reference,
9790 &geometry_info);
9791 black_point=geometry_info.rho;
9792 if ((flags & SigmaValue) != 0)
9793 white_point=geometry_info.sigma;
9794 if ((flags & XiValue) != 0)
9795 gamma=geometry_info.xi;
9796 if ((flags & PercentValue) != 0)
9797 {
9798 black_point*=(double) (QuantumRange/100.0);
9799 white_point*=(double) (QuantumRange/100.0);
9800 }
9801 if ((flags & SigmaValue) == 0)
9802 white_point=(double) QuantumRange-black_point;
9803 }
9804 if (attribute_flag[1] != 0)
9805 black_point=argument_list[1].real_reference;
9806 if (attribute_flag[2] != 0)
9807 white_point=argument_list[2].real_reference;
9808 if (attribute_flag[3] != 0)
9809 gamma=argument_list[3].real_reference;
9810 if (attribute_flag[4] != 0)
9811 channel=(ChannelType) argument_list[4].integer_reference;
9812 if (attribute_flag[5] != 0)
9813 {
9814 argument_list[0].real_reference=argument_list[5].real_reference;
9815 attribute_flag[0]=attribute_flag[5];
9816 }
9817 channel_mask=SetImageChannelMask(image,channel);
9818 (void) LevelImage(image,black_point,white_point,gamma,exception);
9819 (void) SetImageChannelMask(image,channel_mask);
9820 break;
9821 }
9822 case 74: /* Clip */
9823 {
9824 if (attribute_flag[0] == 0)
9825 argument_list[0].string_reference="#1";
9826 if (attribute_flag[1] == 0)
9827 argument_list[1].integer_reference=MagickTrue;
9828 (void) ClipImagePath(image,argument_list[0].string_reference,
9829 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9830 exception);
9831 break;
9832 }
9833 case 75: /* AffineTransform */
9834 {
9835 DrawInfo
9836 *draw_info;
9837
9838 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9839 (DrawInfo *) NULL);
9840 if (attribute_flag[0] != 0)
9841 {
9842 AV
9843 *av;
9844
9845 av=(AV *) argument_list[0].array_reference;
9846 if ((av_len(av) != 3) && (av_len(av) != 5))
9847 {
9848 ThrowPerlException(exception,OptionError,
9849 "affine matrix must have 4 or 6 elements",PackageName);
9850 goto PerlException;
9851 }
9852 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9853 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9854 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9855 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9856 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9857 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9858 {
9859 ThrowPerlException(exception,OptionError,
9860 "affine matrix is singular",PackageName);
9861 goto PerlException;
9862 }
9863 if (av_len(av) == 5)
9864 {
9865 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9866 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9867 }
9868 }
9869 for (j=1; j < 6; j++)
9870 {
9871 if (attribute_flag[j] == 0)
9872 continue;
9873 value=argument_list[j].string_reference;
9874 angle=argument_list[j].real_reference;
9875 current=draw_info->affine;
9876 GetAffineMatrix(&affine);
9877 switch (j)
9878 {
9879 case 1:
9880 {
9881 /*
9882 Translate.
9883 */
9884 flags=ParseGeometry(value,&geometry_info);
9885 affine.tx=geometry_info.xi;
9886 affine.ty=geometry_info.psi;
9887 if ((flags & PsiValue) == 0)
9888 affine.ty=affine.tx;
9889 break;
9890 }
9891 case 2:
9892 {
9893 /*
9894 Scale.
9895 */
9896 flags=ParseGeometry(value,&geometry_info);
9897 affine.sx=geometry_info.rho;
9898 affine.sy=geometry_info.sigma;
9899 if ((flags & SigmaValue) == 0)
9900 affine.sy=affine.sx;
9901 break;
9902 }
9903 case 3:
9904 {
9905 /*
9906 Rotate.
9907 */
9908 if (angle == 0.0)
9909 break;
9910 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9911 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9912 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9913 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9914 break;
9915 }
9916 case 4:
9917 {
9918 /*
9919 SkewX.
9920 */
9921 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9922 break;
9923 }
9924 case 5:
9925 {
9926 /*
9927 SkewY.
9928 */
9929 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9930 break;
9931 }
9932 }
9933 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9934 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9935 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9936 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9937 draw_info->affine.tx=
9938 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9939 draw_info->affine.ty=
9940 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9941 }
9942 if (attribute_flag[6] != 0)
9943 image->interpolate=(PixelInterpolateMethod)
9944 argument_list[6].integer_reference;
9945 if (attribute_flag[7] != 0)
9946 QueryColorCompliance(argument_list[7].string_reference,
9947 AllCompliance,&image->background_color,exception);
9948 image=AffineTransformImage(image,&draw_info->affine,exception);
9949 draw_info=DestroyDrawInfo(draw_info);
9950 break;
9951 }
9952 case 76: /* Difference */
9953 {
9954 if (attribute_flag[0] == 0)
9955 {
9956 ThrowPerlException(exception,OptionError,
9957 "ReferenceImageRequired",PackageName);
9958 goto PerlException;
9959 }
9960 if (attribute_flag[1] != 0)
9961 image->fuzz=StringToDoubleInterval(
9962 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -05009963 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009964 exception);
9965 break;
9966 }
9967 case 77: /* AdaptiveThreshold */
9968 {
9969 if (attribute_flag[0] != 0)
9970 {
9971 flags=ParseGeometry(argument_list[0].string_reference,
9972 &geometry_info);
9973 if ((flags & PercentValue) != 0)
9974 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9975 }
9976 if (attribute_flag[1] != 0)
9977 geometry_info.rho=argument_list[1].integer_reference;
9978 if (attribute_flag[2] != 0)
9979 geometry_info.sigma=argument_list[2].integer_reference;
9980 if (attribute_flag[3] != 0)
9981 geometry_info.xi=argument_list[3].integer_reference;;
9982 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9983 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9984 break;
9985 }
9986 case 78: /* Resample */
9987 {
9988 size_t
9989 height,
9990 width;
9991
9992 if (attribute_flag[0] != 0)
9993 {
9994 flags=ParseGeometry(argument_list[0].string_reference,
9995 &geometry_info);
9996 if ((flags & SigmaValue) == 0)
9997 geometry_info.sigma=geometry_info.rho;
9998 }
9999 if (attribute_flag[1] != 0)
10000 geometry_info.rho=argument_list[1].real_reference;
10001 if (attribute_flag[2] != 0)
10002 geometry_info.sigma=argument_list[2].real_reference;
10003 if (attribute_flag[3] == 0)
10004 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10005 if (attribute_flag[4] == 0)
10006 SetImageArtifact(image,"filter:support",
10007 argument_list[4].string_reference);
10008 width=(size_t) (geometry_info.rho*image->columns/
10009 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10010 height=(size_t) (geometry_info.sigma*image->rows/
10011 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
Cristy8645e042016-02-03 16:35:29 -050010012 image=ResizeImage(image,width,height,(FilterType)
cristy4a3ce0a2013-08-03 20:06:59 +000010013 argument_list[3].integer_reference,exception);
10014 if (image != (Image *) NULL)
10015 {
10016 image->resolution.x=geometry_info.rho;
10017 image->resolution.y=geometry_info.sigma;
10018 }
10019 break;
10020 }
10021 case 79: /* Describe */
10022 {
10023 if (attribute_flag[0] == 0)
10024 argument_list[0].file_reference=(FILE *) NULL;
10025 if (attribute_flag[1] != 0)
10026 (void) SetImageArtifact(image,"identify:features",
10027 argument_list[1].string_reference);
10028 (void) IdentifyImage(image,argument_list[0].file_reference,
10029 MagickTrue,exception);
10030 break;
10031 }
10032 case 80: /* BlackThreshold */
10033 {
10034 if (attribute_flag[0] == 0)
10035 argument_list[0].string_reference="50%";
10036 if (attribute_flag[2] != 0)
10037 channel=(ChannelType) argument_list[2].integer_reference;
10038 channel_mask=SetImageChannelMask(image,channel);
10039 BlackThresholdImage(image,argument_list[0].string_reference,
10040 exception);
10041 (void) SetImageChannelMask(image,channel_mask);
10042 break;
10043 }
10044 case 81: /* WhiteThreshold */
10045 {
10046 if (attribute_flag[0] == 0)
10047 argument_list[0].string_reference="50%";
10048 if (attribute_flag[2] != 0)
10049 channel=(ChannelType) argument_list[2].integer_reference;
10050 channel_mask=SetImageChannelMask(image,channel);
10051 WhiteThresholdImage(image,argument_list[0].string_reference,
10052 exception);
10053 (void) SetImageChannelMask(image,channel_mask);
10054 break;
10055 }
cristy60c73c02014-03-25 12:09:58 +000010056 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010057 {
10058 if (attribute_flag[0] != 0)
10059 {
10060 flags=ParseGeometry(argument_list[0].string_reference,
10061 &geometry_info);
10062 }
10063 if (attribute_flag[1] != 0)
10064 geometry_info.rho=argument_list[1].real_reference;
10065 if (attribute_flag[2] != 0)
10066 channel=(ChannelType) argument_list[2].integer_reference;
10067 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010068 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010069 if (image != (Image *) NULL)
10070 (void) SetImageChannelMask(image,channel_mask);
10071 break;
10072 }
10073 case 83: /* Thumbnail */
10074 {
10075 if (attribute_flag[0] != 0)
10076 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10077 &geometry,exception);
10078 if (attribute_flag[1] != 0)
10079 geometry.width=argument_list[1].integer_reference;
10080 if (attribute_flag[2] != 0)
10081 geometry.height=argument_list[2].integer_reference;
10082 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10083 break;
10084 }
10085 case 84: /* Strip */
10086 {
10087 (void) StripImage(image,exception);
10088 break;
10089 }
10090 case 85: /* Tint */
10091 {
10092 PixelInfo
10093 tint;
10094
10095 GetPixelInfo(image,&tint);
10096 if (attribute_flag[0] != 0)
10097 (void) QueryColorCompliance(argument_list[0].string_reference,
10098 AllCompliance,&tint,exception);
10099 if (attribute_flag[1] == 0)
10100 argument_list[1].string_reference="100";
10101 image=TintImage(image,argument_list[1].string_reference,&tint,
10102 exception);
10103 break;
10104 }
10105 case 86: /* Channel */
10106 {
10107 if (attribute_flag[0] != 0)
10108 channel=(ChannelType) argument_list[0].integer_reference;
10109 image=SeparateImage(image,channel,exception);
10110 break;
10111 }
10112 case 87: /* Splice */
10113 {
cristy260bd762014-08-15 12:46:34 +000010114 if (attribute_flag[7] != 0)
10115 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010116 if (attribute_flag[0] != 0)
10117 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10118 &geometry,exception);
10119 if (attribute_flag[1] != 0)
10120 geometry.width=argument_list[1].integer_reference;
10121 if (attribute_flag[2] != 0)
10122 geometry.height=argument_list[2].integer_reference;
10123 if (attribute_flag[3] != 0)
10124 geometry.x=argument_list[3].integer_reference;
10125 if (attribute_flag[4] != 0)
10126 geometry.y=argument_list[4].integer_reference;
10127 if (attribute_flag[5] != 0)
10128 image->fuzz=StringToDoubleInterval(
10129 argument_list[5].string_reference,(double) QuantumRange+1.0);
10130 if (attribute_flag[6] != 0)
10131 (void) QueryColorCompliance(argument_list[6].string_reference,
10132 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010133 image=SpliceImage(image,&geometry,exception);
10134 break;
10135 }
10136 case 88: /* Posterize */
10137 {
10138 if (attribute_flag[0] == 0)
10139 argument_list[0].integer_reference=3;
10140 if (attribute_flag[1] == 0)
10141 argument_list[1].integer_reference=0;
10142 (void) PosterizeImage(image,argument_list[0].integer_reference,
10143 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10144 NoDitherMethod,exception);
10145 break;
10146 }
10147 case 89: /* Shadow */
10148 {
10149 if (attribute_flag[0] != 0)
10150 {
10151 flags=ParseGeometry(argument_list[0].string_reference,
10152 &geometry_info);
10153 if ((flags & SigmaValue) == 0)
10154 geometry_info.sigma=1.0;
10155 if ((flags & XiValue) == 0)
10156 geometry_info.xi=4.0;
10157 if ((flags & PsiValue) == 0)
10158 geometry_info.psi=4.0;
10159 }
10160 if (attribute_flag[1] != 0)
10161 geometry_info.rho=argument_list[1].real_reference;
10162 if (attribute_flag[2] != 0)
10163 geometry_info.sigma=argument_list[2].real_reference;
10164 if (attribute_flag[3] != 0)
10165 geometry_info.xi=argument_list[3].integer_reference;
10166 if (attribute_flag[4] != 0)
10167 geometry_info.psi=argument_list[4].integer_reference;
10168 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10169 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10170 ceil(geometry_info.psi-0.5),exception);
10171 break;
10172 }
10173 case 90: /* Identify */
10174 {
10175 if (attribute_flag[0] == 0)
10176 argument_list[0].file_reference=(FILE *) NULL;
10177 if (attribute_flag[1] != 0)
10178 (void) SetImageArtifact(image,"identify:features",
10179 argument_list[1].string_reference);
10180 if ((attribute_flag[2] != 0) &&
10181 (argument_list[2].integer_reference != 0))
10182 (void) SetImageArtifact(image,"identify:unique","true");
10183 (void) IdentifyImage(image,argument_list[0].file_reference,
10184 MagickTrue,exception);
10185 break;
10186 }
10187 case 91: /* SepiaTone */
10188 {
10189 if (attribute_flag[0] == 0)
10190 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10191 image=SepiaToneImage(image,argument_list[0].real_reference,
10192 exception);
10193 break;
10194 }
10195 case 92: /* SigmoidalContrast */
10196 {
10197 MagickBooleanType
10198 sharpen;
10199
10200 if (attribute_flag[0] != 0)
10201 {
10202 flags=ParseGeometry(argument_list[0].string_reference,
10203 &geometry_info);
10204 if ((flags & SigmaValue) == 0)
10205 geometry_info.sigma=QuantumRange/2.0;
10206 if ((flags & PercentValue) != 0)
10207 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10208 }
10209 if (attribute_flag[1] != 0)
10210 geometry_info.rho=argument_list[1].real_reference;
10211 if (attribute_flag[2] != 0)
10212 geometry_info.sigma=argument_list[2].real_reference;
10213 if (attribute_flag[3] != 0)
10214 channel=(ChannelType) argument_list[3].integer_reference;
10215 sharpen=MagickTrue;
10216 if (attribute_flag[4] != 0)
10217 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10218 MagickFalse;
10219 channel_mask=SetImageChannelMask(image,channel);
10220 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10221 geometry_info.sigma,exception);
10222 (void) SetImageChannelMask(image,channel_mask);
10223 break;
10224 }
10225 case 93: /* Extent */
10226 {
10227 if (attribute_flag[7] != 0)
10228 image->gravity=(GravityType) argument_list[7].integer_reference;
10229 if (attribute_flag[0] != 0)
10230 {
10231 int
10232 flags;
10233
10234 flags=ParseGravityGeometry(image,
10235 argument_list[0].string_reference,&geometry,exception);
10236 (void) flags;
10237 if (geometry.width == 0)
10238 geometry.width=image->columns;
10239 if (geometry.height == 0)
10240 geometry.height=image->rows;
10241 }
10242 if (attribute_flag[1] != 0)
10243 geometry.width=argument_list[1].integer_reference;
10244 if (attribute_flag[2] != 0)
10245 geometry.height=argument_list[2].integer_reference;
10246 if (attribute_flag[3] != 0)
10247 geometry.x=argument_list[3].integer_reference;
10248 if (attribute_flag[4] != 0)
10249 geometry.y=argument_list[4].integer_reference;
10250 if (attribute_flag[5] != 0)
10251 image->fuzz=StringToDoubleInterval(
10252 argument_list[5].string_reference,(double) QuantumRange+1.0);
10253 if (attribute_flag[6] != 0)
10254 (void) QueryColorCompliance(argument_list[6].string_reference,
10255 AllCompliance,&image->background_color,exception);
10256 image=ExtentImage(image,&geometry,exception);
10257 break;
10258 }
10259 case 94: /* Vignette */
10260 {
10261 if (attribute_flag[0] != 0)
10262 {
10263 flags=ParseGeometry(argument_list[0].string_reference,
10264 &geometry_info);
10265 if ((flags & SigmaValue) == 0)
10266 geometry_info.sigma=1.0;
10267 if ((flags & XiValue) == 0)
10268 geometry_info.xi=0.1*image->columns;
10269 if ((flags & PsiValue) == 0)
10270 geometry_info.psi=0.1*image->rows;
10271 }
10272 if (attribute_flag[1] != 0)
10273 geometry_info.rho=argument_list[1].real_reference;
10274 if (attribute_flag[2] != 0)
10275 geometry_info.sigma=argument_list[2].real_reference;
10276 if (attribute_flag[3] != 0)
10277 geometry_info.xi=argument_list[3].integer_reference;
10278 if (attribute_flag[4] != 0)
10279 geometry_info.psi=argument_list[4].integer_reference;
10280 if (attribute_flag[5] != 0)
10281 (void) QueryColorCompliance(argument_list[5].string_reference,
10282 AllCompliance,&image->background_color,exception);
10283 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10284 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10285 ceil(geometry_info.psi-0.5),exception);
10286 break;
10287 }
10288 case 95: /* ContrastStretch */
10289 {
10290 double
10291 black_point,
10292 white_point;
10293
10294 black_point=0.0;
10295 white_point=(double) image->columns*image->rows;
10296 if (attribute_flag[0] != 0)
10297 {
10298 flags=ParseGeometry(argument_list[0].string_reference,
10299 &geometry_info);
10300 black_point=geometry_info.rho;
10301 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10302 black_point;
10303 if ((flags & PercentValue) != 0)
10304 {
10305 black_point*=(double) image->columns*image->rows/100.0;
10306 white_point*=(double) image->columns*image->rows/100.0;
10307 }
10308 white_point=(double) image->columns*image->rows-
10309 white_point;
10310 }
10311 if (attribute_flag[1] != 0)
10312 black_point=argument_list[1].real_reference;
10313 if (attribute_flag[2] != 0)
10314 white_point=argument_list[2].real_reference;
10315 if (attribute_flag[4] != 0)
10316 channel=(ChannelType) argument_list[4].integer_reference;
10317 channel_mask=SetImageChannelMask(image,channel);
10318 (void) ContrastStretchImage(image,black_point,white_point,exception);
10319 (void) SetImageChannelMask(image,channel_mask);
10320 break;
10321 }
10322 case 96: /* Sans0 */
10323 {
10324 break;
10325 }
10326 case 97: /* Sans1 */
10327 {
10328 break;
10329 }
10330 case 98: /* AdaptiveSharpen */
10331 {
10332 if (attribute_flag[0] != 0)
10333 {
10334 flags=ParseGeometry(argument_list[0].string_reference,
10335 &geometry_info);
10336 if ((flags & SigmaValue) == 0)
10337 geometry_info.sigma=1.0;
10338 if ((flags & XiValue) == 0)
10339 geometry_info.xi=0.0;
10340 }
10341 if (attribute_flag[1] != 0)
10342 geometry_info.rho=argument_list[1].real_reference;
10343 if (attribute_flag[2] != 0)
10344 geometry_info.sigma=argument_list[2].real_reference;
10345 if (attribute_flag[3] != 0)
10346 geometry_info.xi=argument_list[3].real_reference;
10347 if (attribute_flag[4] != 0)
10348 channel=(ChannelType) argument_list[4].integer_reference;
10349 channel_mask=SetImageChannelMask(image,channel);
10350 image=AdaptiveSharpenImage(image,geometry_info.rho,
10351 geometry_info.sigma,exception);
10352 if (image != (Image *) NULL)
10353 (void) SetImageChannelMask(image,channel_mask);
10354 break;
10355 }
10356 case 99: /* Transpose */
10357 {
10358 image=TransposeImage(image,exception);
10359 break;
10360 }
10361 case 100: /* Tranverse */
10362 {
10363 image=TransverseImage(image,exception);
10364 break;
10365 }
10366 case 101: /* AutoOrient */
10367 {
10368 image=AutoOrientImage(image,image->orientation,exception);
10369 break;
10370 }
10371 case 102: /* AdaptiveBlur */
10372 {
10373 if (attribute_flag[0] != 0)
10374 {
10375 flags=ParseGeometry(argument_list[0].string_reference,
10376 &geometry_info);
10377 if ((flags & SigmaValue) == 0)
10378 geometry_info.sigma=1.0;
10379 if ((flags & XiValue) == 0)
10380 geometry_info.xi=0.0;
10381 }
10382 if (attribute_flag[1] != 0)
10383 geometry_info.rho=argument_list[1].real_reference;
10384 if (attribute_flag[2] != 0)
10385 geometry_info.sigma=argument_list[2].real_reference;
10386 if (attribute_flag[3] != 0)
10387 channel=(ChannelType) argument_list[3].integer_reference;
10388 channel_mask=SetImageChannelMask(image,channel);
10389 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10390 exception);
10391 if (image != (Image *) NULL)
10392 (void) SetImageChannelMask(image,channel_mask);
10393 break;
10394 }
10395 case 103: /* Sketch */
10396 {
10397 if (attribute_flag[0] != 0)
10398 {
10399 flags=ParseGeometry(argument_list[0].string_reference,
10400 &geometry_info);
10401 if ((flags & SigmaValue) == 0)
10402 geometry_info.sigma=1.0;
10403 if ((flags & XiValue) == 0)
10404 geometry_info.xi=1.0;
10405 }
10406 if (attribute_flag[1] != 0)
10407 geometry_info.rho=argument_list[1].real_reference;
10408 if (attribute_flag[2] != 0)
10409 geometry_info.sigma=argument_list[2].real_reference;
10410 if (attribute_flag[3] != 0)
10411 geometry_info.xi=argument_list[3].real_reference;
10412 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10413 geometry_info.xi,exception);
10414 break;
10415 }
10416 case 104: /* UniqueColors */
10417 {
10418 image=UniqueImageColors(image,exception);
10419 break;
10420 }
10421 case 105: /* AdaptiveResize */
10422 {
10423 if (attribute_flag[0] != 0)
10424 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10425 &geometry,exception);
10426 if (attribute_flag[1] != 0)
10427 geometry.width=argument_list[1].integer_reference;
10428 if (attribute_flag[2] != 0)
10429 geometry.height=argument_list[2].integer_reference;
10430 if (attribute_flag[3] != 0)
Cristy8645e042016-02-03 16:35:29 -050010431 image->filter=(FilterType) argument_list[4].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010432 if (attribute_flag[4] != 0)
10433 SetImageArtifact(image,"filter:support",
10434 argument_list[4].string_reference);
10435 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10436 exception);
10437 break;
10438 }
10439 case 106: /* ClipMask */
10440 {
10441 Image
10442 *mask_image;
10443
10444 if (attribute_flag[0] == 0)
10445 {
10446 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10447 PackageName);
10448 goto PerlException;
10449 }
10450 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10451 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010452 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010453 mask_image=DestroyImage(mask_image);
10454 break;
10455 }
10456 case 107: /* LinearStretch */
10457 {
10458 double
10459 black_point,
10460 white_point;
10461
10462 black_point=0.0;
10463 white_point=(double) image->columns*image->rows;
10464 if (attribute_flag[0] != 0)
10465 {
10466 flags=ParseGeometry(argument_list[0].string_reference,
10467 &geometry_info);
10468 if ((flags & SigmaValue) != 0)
10469 white_point=geometry_info.sigma;
10470 if ((flags & PercentValue) != 0)
10471 {
10472 black_point*=(double) image->columns*image->rows/100.0;
10473 white_point*=(double) image->columns*image->rows/100.0;
10474 }
10475 if ((flags & SigmaValue) == 0)
10476 white_point=(double) image->columns*image->rows-black_point;
10477 }
10478 if (attribute_flag[1] != 0)
10479 black_point=argument_list[1].real_reference;
10480 if (attribute_flag[2] != 0)
10481 white_point=argument_list[2].real_reference;
10482 (void) LinearStretchImage(image,black_point,white_point,exception);
10483 break;
10484 }
10485 case 108: /* ColorMatrix */
10486 {
10487 AV
10488 *av;
10489
10490 double
10491 *color_matrix;
10492
10493 KernelInfo
10494 *kernel_info;
10495
10496 size_t
10497 order;
10498
10499 if (attribute_flag[0] == 0)
10500 break;
10501 av=(AV *) argument_list[0].array_reference;
10502 order=(size_t) sqrt(av_len(av)+1);
10503 color_matrix=(double *) AcquireQuantumMemory(order,order*
10504 sizeof(*color_matrix));
10505 if (color_matrix == (double *) NULL)
10506 {
10507 ThrowPerlException(exception,ResourceLimitFatalError,
10508 "MemoryAllocationFailed",PackageName);
10509 goto PerlException;
10510 }
10511 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10512 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10513 for ( ; j < (ssize_t) (order*order); j++)
10514 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010515 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010516 if (kernel_info == (KernelInfo *) NULL)
10517 break;
10518 kernel_info->width=order;
10519 kernel_info->height=order;
10520 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10521 order*sizeof(*kernel_info->values));
10522 if (kernel_info->values != (MagickRealType *) NULL)
10523 {
10524 for (i=0; i < (ssize_t) (order*order); i++)
10525 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10526 image=ColorMatrixImage(image,kernel_info,exception);
10527 }
10528 kernel_info=DestroyKernelInfo(kernel_info);
10529 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10530 break;
10531 }
10532 case 109: /* Mask */
10533 {
10534 Image
10535 *mask_image;
10536
10537 if (attribute_flag[0] == 0)
10538 {
10539 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10540 PackageName);
10541 goto PerlException;
10542 }
10543 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10544 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010545 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010546 mask_image=DestroyImage(mask_image);
10547 break;
10548 }
10549 case 110: /* Polaroid */
10550 {
10551 char
10552 *caption;
10553
10554 DrawInfo
10555 *draw_info;
10556
10557 double
10558 angle;
10559
10560 PixelInterpolateMethod
10561 method;
10562
10563 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10564 (DrawInfo *) NULL);
10565 caption=(char *) NULL;
10566 if (attribute_flag[0] != 0)
10567 caption=InterpretImageProperties(info ? info->image_info :
10568 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10569 exception);
10570 angle=0.0;
10571 if (attribute_flag[1] != 0)
10572 angle=argument_list[1].real_reference;
10573 if (attribute_flag[2] != 0)
10574 (void) CloneString(&draw_info->font,
10575 argument_list[2].string_reference);
10576 if (attribute_flag[3] != 0)
10577 (void) QueryColorCompliance(argument_list[3].string_reference,
10578 AllCompliance,&draw_info->stroke,exception);
10579 if (attribute_flag[4] != 0)
10580 (void) QueryColorCompliance(argument_list[4].string_reference,
10581 AllCompliance,&draw_info->fill,exception);
10582 if (attribute_flag[5] != 0)
10583 draw_info->stroke_width=argument_list[5].real_reference;
10584 if (attribute_flag[6] != 0)
10585 draw_info->pointsize=argument_list[6].real_reference;
10586 if (attribute_flag[7] != 0)
10587 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10588 if (attribute_flag[8] != 0)
10589 (void) QueryColorCompliance(argument_list[8].string_reference,
10590 AllCompliance,&image->background_color,exception);
10591 method=UndefinedInterpolatePixel;
10592 if (attribute_flag[9] != 0)
10593 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10594 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10595 draw_info=DestroyDrawInfo(draw_info);
10596 if (caption != (char *) NULL)
10597 caption=DestroyString(caption);
10598 break;
10599 }
10600 case 111: /* FloodfillPaint */
10601 {
10602 DrawInfo
10603 *draw_info;
10604
10605 MagickBooleanType
10606 invert;
10607
10608 PixelInfo
10609 target;
10610
10611 draw_info=CloneDrawInfo(info ? info->image_info :
10612 (ImageInfo *) NULL,(DrawInfo *) NULL);
10613 if (attribute_flag[0] != 0)
10614 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10615 &geometry,exception);
10616 if (attribute_flag[1] != 0)
10617 geometry.x=argument_list[1].integer_reference;
10618 if (attribute_flag[2] != 0)
10619 geometry.y=argument_list[2].integer_reference;
10620 if (attribute_flag[3] != 0)
10621 (void) QueryColorCompliance(argument_list[3].string_reference,
10622 AllCompliance,&draw_info->fill,exception);
10623 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10624 geometry.x,geometry.y,&target,exception);
10625 if (attribute_flag[4] != 0)
10626 QueryColorCompliance(argument_list[4].string_reference,
10627 AllCompliance,&target,exception);
10628 if (attribute_flag[5] != 0)
10629 image->fuzz=StringToDoubleInterval(
10630 argument_list[5].string_reference,(double) QuantumRange+1.0);
10631 if (attribute_flag[6] != 0)
10632 channel=(ChannelType) argument_list[6].integer_reference;
10633 invert=MagickFalse;
10634 if (attribute_flag[7] != 0)
10635 invert=(MagickBooleanType) argument_list[7].integer_reference;
10636 channel_mask=SetImageChannelMask(image,channel);
10637 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10638 geometry.y,invert,exception);
10639 (void) SetImageChannelMask(image,channel_mask);
10640 draw_info=DestroyDrawInfo(draw_info);
10641 break;
10642 }
10643 case 112: /* Distort */
10644 {
10645 AV
10646 *av;
10647
10648 double
10649 *coordinates;
10650
Cristy8645e042016-02-03 16:35:29 -050010651 DistortMethod
cristy4a3ce0a2013-08-03 20:06:59 +000010652 method;
10653
10654 size_t
10655 number_coordinates;
10656
10657 VirtualPixelMethod
10658 virtual_pixel;
10659
10660 if (attribute_flag[0] == 0)
10661 break;
10662 method=UndefinedDistortion;
10663 if (attribute_flag[1] != 0)
Cristy8645e042016-02-03 16:35:29 -050010664 method=(DistortMethod) argument_list[1].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010665 av=(AV *) argument_list[0].array_reference;
10666 number_coordinates=(size_t) av_len(av)+1;
10667 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10668 sizeof(*coordinates));
10669 if (coordinates == (double *) NULL)
10670 {
10671 ThrowPerlException(exception,ResourceLimitFatalError,
10672 "MemoryAllocationFailed",PackageName);
10673 goto PerlException;
10674 }
10675 for (j=0; j < (ssize_t) number_coordinates; j++)
10676 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10677 virtual_pixel=UndefinedVirtualPixelMethod;
10678 if (attribute_flag[2] != 0)
10679 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10680 argument_list[2].integer_reference,exception);
10681 image=DistortImage(image,method,number_coordinates,coordinates,
10682 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10683 exception);
10684 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10685 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10686 exception);
10687 coordinates=(double *) RelinquishMagickMemory(coordinates);
10688 break;
10689 }
10690 case 113: /* Clut */
10691 {
10692 PixelInterpolateMethod
10693 method;
10694
10695 if (attribute_flag[0] == 0)
10696 {
10697 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10698 PackageName);
10699 goto PerlException;
10700 }
10701 method=UndefinedInterpolatePixel;
10702 if (attribute_flag[1] != 0)
10703 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10704 if (attribute_flag[2] != 0)
10705 channel=(ChannelType) argument_list[2].integer_reference;
10706 channel_mask=SetImageChannelMask(image,channel);
10707 (void) ClutImage(image,argument_list[0].image_reference,method,
10708 exception);
10709 (void) SetImageChannelMask(image,channel_mask);
10710 break;
10711 }
10712 case 114: /* LiquidRescale */
10713 {
10714 if (attribute_flag[0] != 0)
10715 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10716 &geometry,exception);
10717 if (attribute_flag[1] != 0)
10718 geometry.width=argument_list[1].integer_reference;
10719 if (attribute_flag[2] != 0)
10720 geometry.height=argument_list[2].integer_reference;
10721 if (attribute_flag[3] == 0)
10722 argument_list[3].real_reference=1.0;
10723 if (attribute_flag[4] == 0)
10724 argument_list[4].real_reference=0.0;
10725 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10726 argument_list[3].real_reference,argument_list[4].real_reference,
10727 exception);
10728 break;
10729 }
10730 case 115: /* EncipherImage */
10731 {
10732 (void) EncipherImage(image,argument_list[0].string_reference,
10733 exception);
10734 break;
10735 }
10736 case 116: /* DecipherImage */
10737 {
10738 (void) DecipherImage(image,argument_list[0].string_reference,
10739 exception);
10740 break;
10741 }
10742 case 117: /* Deskew */
10743 {
10744 geometry_info.rho=QuantumRange/2.0;
10745 if (attribute_flag[0] != 0)
10746 flags=ParseGeometry(argument_list[0].string_reference,
10747 &geometry_info);
10748 if (attribute_flag[1] != 0)
10749 geometry_info.rho=StringToDoubleInterval(
10750 argument_list[1].string_reference,(double) QuantumRange+1.0);
10751 image=DeskewImage(image,geometry_info.rho,exception);
10752 break;
10753 }
10754 case 118: /* Remap */
10755 {
10756 QuantizeInfo
10757 *quantize_info;
10758
10759 if (attribute_flag[0] == 0)
10760 {
10761 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10762 PackageName);
10763 goto PerlException;
10764 }
10765 quantize_info=AcquireQuantizeInfo(info->image_info);
10766 if (attribute_flag[1] != 0)
10767 quantize_info->dither_method=(DitherMethod)
10768 argument_list[1].integer_reference;
10769 (void) RemapImages(quantize_info,image,
10770 argument_list[0].image_reference,exception);
10771 quantize_info=DestroyQuantizeInfo(quantize_info);
10772 break;
10773 }
10774 case 119: /* SparseColor */
10775 {
10776 AV
10777 *av;
10778
10779 double
10780 *coordinates;
10781
10782 SparseColorMethod
10783 method;
10784
10785 size_t
10786 number_coordinates;
10787
10788 VirtualPixelMethod
10789 virtual_pixel;
10790
10791 if (attribute_flag[0] == 0)
10792 break;
10793 method=UndefinedColorInterpolate;
10794 if (attribute_flag[1] != 0)
10795 method=(SparseColorMethod) argument_list[1].integer_reference;
10796 av=(AV *) argument_list[0].array_reference;
10797 number_coordinates=(size_t) av_len(av)+1;
10798 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10799 sizeof(*coordinates));
10800 if (coordinates == (double *) NULL)
10801 {
10802 ThrowPerlException(exception,ResourceLimitFatalError,
10803 "MemoryAllocationFailed",PackageName);
10804 goto PerlException;
10805 }
10806 for (j=0; j < (ssize_t) number_coordinates; j++)
10807 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10808 virtual_pixel=UndefinedVirtualPixelMethod;
10809 if (attribute_flag[2] != 0)
10810 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10811 argument_list[2].integer_reference,exception);
10812 if (attribute_flag[3] != 0)
10813 channel=(ChannelType) argument_list[3].integer_reference;
10814 channel_mask=SetImageChannelMask(image,channel);
10815 image=SparseColorImage(image,method,number_coordinates,coordinates,
10816 exception);
10817 if (image != (Image *) NULL)
10818 (void) SetImageChannelMask(image,channel_mask);
10819 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10820 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10821 exception);
10822 coordinates=(double *) RelinquishMagickMemory(coordinates);
10823 break;
10824 }
10825 case 120: /* Function */
10826 {
10827 AV
10828 *av;
10829
10830 double
10831 *parameters;
10832
10833 MagickFunction
10834 function;
10835
10836 size_t
10837 number_parameters;
10838
10839 VirtualPixelMethod
10840 virtual_pixel;
10841
10842 if (attribute_flag[0] == 0)
10843 break;
10844 function=UndefinedFunction;
10845 if (attribute_flag[1] != 0)
10846 function=(MagickFunction) argument_list[1].integer_reference;
10847 av=(AV *) argument_list[0].array_reference;
10848 number_parameters=(size_t) av_len(av)+1;
10849 parameters=(double *) AcquireQuantumMemory(number_parameters,
10850 sizeof(*parameters));
10851 if (parameters == (double *) NULL)
10852 {
10853 ThrowPerlException(exception,ResourceLimitFatalError,
10854 "MemoryAllocationFailed",PackageName);
10855 goto PerlException;
10856 }
10857 for (j=0; j < (ssize_t) number_parameters; j++)
10858 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10859 virtual_pixel=UndefinedVirtualPixelMethod;
10860 if (attribute_flag[2] != 0)
10861 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10862 argument_list[2].integer_reference,exception);
10863 (void) FunctionImage(image,function,number_parameters,parameters,
10864 exception);
10865 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10866 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10867 exception);
10868 parameters=(double *) RelinquishMagickMemory(parameters);
10869 break;
10870 }
10871 case 121: /* SelectiveBlur */
10872 {
10873 if (attribute_flag[0] != 0)
10874 {
10875 flags=ParseGeometry(argument_list[0].string_reference,
10876 &geometry_info);
10877 if ((flags & SigmaValue) == 0)
10878 geometry_info.sigma=1.0;
10879 if ((flags & PercentValue) != 0)
10880 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10881 }
10882 if (attribute_flag[1] != 0)
10883 geometry_info.rho=argument_list[1].real_reference;
10884 if (attribute_flag[2] != 0)
10885 geometry_info.sigma=argument_list[2].real_reference;
10886 if (attribute_flag[3] != 0)
10887 geometry_info.xi=argument_list[3].integer_reference;;
10888 if (attribute_flag[5] != 0)
10889 channel=(ChannelType) argument_list[5].integer_reference;
10890 channel_mask=SetImageChannelMask(image,channel);
10891 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10892 geometry_info.xi,exception);
10893 if (image != (Image *) NULL)
10894 (void) SetImageChannelMask(image,channel_mask);
10895 break;
10896 }
10897 case 122: /* HaldClut */
10898 {
10899 if (attribute_flag[0] == 0)
10900 {
10901 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10902 PackageName);
10903 goto PerlException;
10904 }
10905 if (attribute_flag[1] != 0)
10906 channel=(ChannelType) argument_list[1].integer_reference;
10907 channel_mask=SetImageChannelMask(image,channel);
10908 (void) HaldClutImage(image,argument_list[0].image_reference,
10909 exception);
10910 (void) SetImageChannelMask(image,channel_mask);
10911 break;
10912 }
10913 case 123: /* BlueShift */
10914 {
10915 if (attribute_flag[0] != 0)
10916 (void) ParseGeometry(argument_list[0].string_reference,
10917 &geometry_info);
10918 image=BlueShiftImage(image,geometry_info.rho,exception);
10919 break;
10920 }
10921 case 124: /* ForwardFourierTransformImage */
10922 {
10923 image=ForwardFourierTransformImage(image,
10924 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10925 exception);
10926 break;
10927 }
10928 case 125: /* InverseFourierTransformImage */
10929 {
10930 image=InverseFourierTransformImage(image,image->next,
10931 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10932 exception);
10933 break;
10934 }
10935 case 126: /* ColorDecisionList */
10936 {
10937 if (attribute_flag[0] == 0)
10938 argument_list[0].string_reference=(char *) NULL;
10939 (void) ColorDecisionListImage(image,
10940 argument_list[0].string_reference,exception);
10941 break;
10942 }
10943 case 127: /* AutoGamma */
10944 {
10945 if (attribute_flag[0] != 0)
10946 channel=(ChannelType) argument_list[0].integer_reference;
10947 channel_mask=SetImageChannelMask(image,channel);
10948 (void) AutoGammaImage(image,exception);
10949 (void) SetImageChannelMask(image,channel_mask);
10950 break;
10951 }
10952 case 128: /* AutoLevel */
10953 {
10954 if (attribute_flag[0] != 0)
10955 channel=(ChannelType) argument_list[0].integer_reference;
10956 channel_mask=SetImageChannelMask(image,channel);
10957 (void) AutoLevelImage(image,exception);
10958 (void) SetImageChannelMask(image,channel_mask);
10959 break;
10960 }
10961 case 129: /* LevelColors */
10962 {
10963 PixelInfo
10964 black_point,
10965 white_point;
10966
10967 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10968 exception);
10969 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10970 exception);
10971 if (attribute_flag[1] != 0)
10972 (void) QueryColorCompliance(
10973 argument_list[1].string_reference,AllCompliance,&black_point,
10974 exception);
10975 if (attribute_flag[2] != 0)
10976 (void) QueryColorCompliance(
10977 argument_list[2].string_reference,AllCompliance,&white_point,
10978 exception);
10979 if (attribute_flag[3] != 0)
10980 channel=(ChannelType) argument_list[3].integer_reference;
10981 channel_mask=SetImageChannelMask(image,channel);
10982 (void) LevelImageColors(image,&black_point,&white_point,
10983 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10984 exception);
10985 (void) SetImageChannelMask(image,channel_mask);
10986 break;
10987 }
10988 case 130: /* Clamp */
10989 {
10990 if (attribute_flag[0] != 0)
10991 channel=(ChannelType) argument_list[0].integer_reference;
10992 channel_mask=SetImageChannelMask(image,channel);
10993 (void) ClampImage(image,exception);
10994 (void) SetImageChannelMask(image,channel_mask);
10995 break;
10996 }
10997 case 131: /* BrightnessContrast */
10998 {
10999 double
11000 brightness,
11001 contrast;
11002
11003 brightness=0.0;
11004 contrast=0.0;
11005 if (attribute_flag[0] != 0)
11006 {
11007 flags=ParseGeometry(argument_list[0].string_reference,
11008 &geometry_info);
11009 brightness=geometry_info.rho;
11010 if ((flags & SigmaValue) == 0)
11011 contrast=geometry_info.sigma;
11012 }
11013 if (attribute_flag[1] != 0)
11014 brightness=argument_list[1].real_reference;
11015 if (attribute_flag[2] != 0)
11016 contrast=argument_list[2].real_reference;
11017 if (attribute_flag[4] != 0)
11018 channel=(ChannelType) argument_list[4].integer_reference;
11019 channel_mask=SetImageChannelMask(image,channel);
11020 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11021 (void) SetImageChannelMask(image,channel_mask);
11022 break;
11023 }
11024 case 132: /* Morphology */
11025 {
11026 KernelInfo
11027 *kernel;
11028
11029 MorphologyMethod
11030 method;
11031
11032 ssize_t
11033 iterations;
11034
11035 if (attribute_flag[0] == 0)
11036 break;
cristy2c57b742014-10-31 00:40:34 +000011037 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011038 if (kernel == (KernelInfo *) NULL)
11039 break;
11040 if (attribute_flag[1] != 0)
11041 channel=(ChannelType) argument_list[1].integer_reference;
11042 method=UndefinedMorphology;
11043 if (attribute_flag[2] != 0)
11044 method=argument_list[2].integer_reference;
11045 iterations=1;
11046 if (attribute_flag[3] != 0)
11047 iterations=argument_list[3].integer_reference;
11048 channel_mask=SetImageChannelMask(image,channel);
11049 image=MorphologyImage(image,method,iterations,kernel,exception);
11050 if (image != (Image *) NULL)
11051 (void) SetImageChannelMask(image,channel_mask);
11052 kernel=DestroyKernelInfo(kernel);
11053 break;
11054 }
11055 case 133: /* Mode */
11056 {
11057 if (attribute_flag[0] != 0)
11058 {
11059 flags=ParseGeometry(argument_list[0].string_reference,
11060 &geometry_info);
11061 if ((flags & SigmaValue) == 0)
11062 geometry_info.sigma=1.0;
11063 }
11064 if (attribute_flag[1] != 0)
11065 geometry_info.rho=argument_list[1].real_reference;
11066 if (attribute_flag[2] != 0)
11067 geometry_info.sigma=argument_list[2].real_reference;
11068 if (attribute_flag[3] != 0)
11069 channel=(ChannelType) argument_list[3].integer_reference;
11070 channel_mask=SetImageChannelMask(image,channel);
11071 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11072 (size_t) geometry_info.sigma,exception);
11073 if (image != (Image *) NULL)
11074 (void) SetImageChannelMask(image,channel_mask);
11075 break;
11076 }
11077 case 134: /* Statistic */
11078 {
11079 StatisticType
11080 statistic;
11081
11082 statistic=UndefinedStatistic;
11083 if (attribute_flag[0] != 0)
11084 {
11085 flags=ParseGeometry(argument_list[0].string_reference,
11086 &geometry_info);
11087 if ((flags & SigmaValue) == 0)
11088 geometry_info.sigma=1.0;
11089 }
11090 if (attribute_flag[1] != 0)
11091 geometry_info.rho=argument_list[1].real_reference;
11092 if (attribute_flag[2] != 0)
11093 geometry_info.sigma=argument_list[2].real_reference;
11094 if (attribute_flag[3] != 0)
11095 channel=(ChannelType) argument_list[3].integer_reference;
11096 if (attribute_flag[4] != 0)
11097 statistic=(StatisticType) argument_list[4].integer_reference;
11098 channel_mask=SetImageChannelMask(image,channel);
11099 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11100 (size_t) geometry_info.sigma,exception);
11101 if (image != (Image *) NULL)
11102 (void) SetImageChannelMask(image,channel_mask);
11103 break;
11104 }
11105 case 135: /* Perceptible */
11106 {
11107 double
11108 epsilon;
11109
11110 epsilon=MagickEpsilon;
11111 if (attribute_flag[0] != 0)
11112 epsilon=argument_list[0].real_reference;
11113 if (attribute_flag[1] != 0)
11114 channel=(ChannelType) argument_list[1].integer_reference;
11115 channel_mask=SetImageChannelMask(image,channel);
11116 (void) PerceptibleImage(image,epsilon,exception);
11117 (void) SetImageChannelMask(image,channel_mask);
11118 break;
11119 }
11120 case 136: /* Poly */
11121 {
11122 AV
11123 *av;
11124
11125 double
11126 *terms;
11127
11128 size_t
11129 number_terms;
11130
11131 if (attribute_flag[0] == 0)
11132 break;
11133 if (attribute_flag[1] != 0)
11134 channel=(ChannelType) argument_list[1].integer_reference;
11135 av=(AV *) argument_list[0].array_reference;
11136 number_terms=(size_t) av_len(av);
11137 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11138 if (terms == (double *) NULL)
11139 {
11140 ThrowPerlException(exception,ResourceLimitFatalError,
11141 "MemoryAllocationFailed",PackageName);
11142 goto PerlException;
11143 }
11144 for (j=0; j < av_len(av); j++)
11145 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11146 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11147 terms=(double *) RelinquishMagickMemory(terms);
11148 break;
11149 }
11150 case 137: /* Grayscale */
11151 {
11152 PixelIntensityMethod
11153 method;
11154
11155 method=UndefinedPixelIntensityMethod;
11156 if (attribute_flag[0] != 0)
11157 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11158 (void) GrayscaleImage(image,method,exception);
11159 break;
11160 }
cristy4ceadb82014-03-29 15:30:43 +000011161 case 138: /* Canny */
11162 {
11163 if (attribute_flag[0] != 0)
11164 {
11165 flags=ParseGeometry(argument_list[0].string_reference,
11166 &geometry_info);
11167 if ((flags & SigmaValue) == 0)
11168 geometry_info.sigma=1.0;
11169 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011170 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011171 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011172 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011173 if ((flags & PercentValue) != 0)
11174 {
11175 geometry_info.xi/=100.0;
11176 geometry_info.psi/=100.0;
11177 }
cristy4ceadb82014-03-29 15:30:43 +000011178 }
11179 if (attribute_flag[1] != 0)
11180 geometry_info.rho=argument_list[1].real_reference;
11181 if (attribute_flag[2] != 0)
11182 geometry_info.sigma=argument_list[2].real_reference;
11183 if (attribute_flag[3] != 0)
11184 geometry_info.xi=argument_list[3].real_reference;
11185 if (attribute_flag[4] != 0)
11186 geometry_info.psi=argument_list[4].real_reference;
11187 if (attribute_flag[5] != 0)
11188 channel=(ChannelType) argument_list[5].integer_reference;
11189 channel_mask=SetImageChannelMask(image,channel);
11190 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11191 geometry_info.xi,geometry_info.psi,exception);
11192 if (image != (Image *) NULL)
11193 (void) SetImageChannelMask(image,channel_mask);
11194 break;
11195 }
cristy2fc10e52014-04-26 14:13:53 +000011196 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011197 {
11198 if (attribute_flag[0] != 0)
11199 {
11200 flags=ParseGeometry(argument_list[0].string_reference,
11201 &geometry_info);
11202 if ((flags & SigmaValue) == 0)
11203 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011204 if ((flags & XiValue) == 0)
11205 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011206 }
11207 if (attribute_flag[1] != 0)
11208 geometry_info.rho=(double) argument_list[1].integer_reference;
11209 if (attribute_flag[2] != 0)
11210 geometry_info.sigma=(double) argument_list[2].integer_reference;
11211 if (attribute_flag[3] != 0)
11212 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011213 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11214 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11215 break;
11216 }
11217 case 140: /* MeanShift */
11218 {
11219 if (attribute_flag[0] != 0)
11220 {
11221 flags=ParseGeometry(argument_list[0].string_reference,
11222 &geometry_info);
11223 if ((flags & SigmaValue) == 0)
11224 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011225 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011226 geometry_info.xi=0.10*QuantumRange;
11227 if ((flags & PercentValue) != 0)
11228 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011229 }
11230 if (attribute_flag[1] != 0)
11231 geometry_info.rho=(double) argument_list[1].integer_reference;
11232 if (attribute_flag[2] != 0)
11233 geometry_info.sigma=(double) argument_list[2].integer_reference;
11234 if (attribute_flag[3] != 0)
11235 geometry_info.xi=(double) argument_list[3].integer_reference;
11236 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011237 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011238 break;
11239 }
cristy3b207f82014-09-27 14:21:20 +000011240 case 141: /* Kuwahara */
11241 {
11242 if (attribute_flag[0] != 0)
11243 {
11244 flags=ParseGeometry(argument_list[0].string_reference,
11245 &geometry_info);
11246 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011247 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011248 }
11249 if (attribute_flag[1] != 0)
11250 geometry_info.rho=argument_list[1].real_reference;
11251 if (attribute_flag[2] != 0)
11252 geometry_info.sigma=argument_list[2].real_reference;
11253 if (attribute_flag[3] != 0)
11254 channel=(ChannelType) argument_list[3].integer_reference;
11255 channel_mask=SetImageChannelMask(image,channel);
11256 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11257 exception);
11258 if (image != (Image *) NULL)
11259 (void) SetImageChannelMask(image,channel_mask);
11260 break;
11261 }
cristy6e0b3bc2014-10-19 17:51:42 +000011262 case 142: /* ConnectedComponent */
11263 {
11264 size_t
11265 connectivity;
11266
11267 connectivity=4;
11268 if (attribute_flag[0] != 0)
11269 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011270 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011271 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011272 break;
11273 }
cristy0b94b392015-06-22 18:56:37 +000011274 case 143: /* Copy */
11275 {
11276 Image
11277 *source_image;
11278
11279 OffsetInfo
11280 offset;
11281
cristy2ffdb092015-06-25 14:31:20 +000011282 RectangleInfo
11283 offset_geometry;
11284
cristyf3a724a2015-06-25 13:02:53 +000011285 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011286 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011287 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011288 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011289 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011290 flags=ParseGravityGeometry(source_image,
11291 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011292 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011293 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011294 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011295 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011296 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011297 geometry.x=argument_list[4].integer_reference;
11298 if (attribute_flag[5] != 0)
11299 geometry.y=argument_list[5].integer_reference;
11300 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011301 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011302 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011303 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011304 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11305 &offset_geometry,exception);
11306 offset.x=offset_geometry.x;
11307 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011308 if (attribute_flag[8] != 0)
11309 offset.x=argument_list[8].integer_reference;
11310 if (attribute_flag[9] != 0)
11311 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011312 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11313 exception);
cristy0b94b392015-06-22 18:56:37 +000011314 break;
11315 }
Cristy5488c982016-02-13 14:07:50 -050011316 case 144: /* Color */
11317 {
11318 PixelInfo
11319 color;
11320
Cristyf20e3562016-02-14 09:08:15 -050011321 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011322 if (attribute_flag[0] != 0)
Cristyf20e3562016-02-14 09:08:15 -050011323 (void) QueryColorCompliance(argument_list[0].string_reference,
11324 AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011325 (void) SetImageColor(image,&color,exception);
11326 break;
11327 }
Cristy2d830ed2016-02-21 10:54:16 -050011328 case 145: /* WaveletDenoise */
11329 {
11330 if (attribute_flag[0] == 0)
Cristya36d1292016-02-21 13:17:36 -050011331 argument_list[0].string_reference="5%";
Cristy2d830ed2016-02-21 10:54:16 -050011332 if (attribute_flag[2] != 0)
11333 channel=(ChannelType) argument_list[2].integer_reference;
Cristya36d1292016-02-21 13:17:36 -050011334 flags=ParseGeometry(argument_list[0].string_reference,&geometry_info);
11335 if ((flags & PercentValue) != 0)
11336 geometry_info.rho*=(double) (QuantumRange/100.0);
Cristy2d830ed2016-02-21 10:54:16 -050011337 channel_mask=SetImageChannelMask(image,channel);
Cristya36d1292016-02-21 13:17:36 -050011338 image=WaveletDenoiseImage(image,geometry_info.rho,exception);
Cristy2d830ed2016-02-21 10:54:16 -050011339 if (image != (Image *) NULL)
11340 (void) SetImageChannelMask(image,channel_mask);
11341 break;
11342 }
cristy4a3ce0a2013-08-03 20:06:59 +000011343 }
11344 if (next != (Image *) NULL)
11345 (void) CatchImageException(next);
11346 if (region_image != (Image *) NULL)
11347 {
11348 /*
11349 Composite region.
cristy83a28a02013-08-03 20:25:48 +000011350 */
cristy4a3ce0a2013-08-03 20:06:59 +000011351 status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11352 region_info.x,region_info.y,exception);
11353 (void) status;
11354 (void) CatchImageException(region_image);
11355 image=DestroyImage(image);
11356 image=region_image;
11357 }
11358 if (image != (Image *) NULL)
11359 {
11360 number_images++;
11361 if (next && (next != image))
11362 {
11363 image->next=next->next;
11364 if (image->next != (Image *) NULL)
11365 image->next->previous=image;
11366 DeleteImageFromRegistry(*pv,next);
11367 }
11368 sv_setiv(*pv,PTR2IV(image));
11369 next=image;
11370 }
11371 if (*pv)
11372 pv++;
11373 }
11374
11375 PerlException:
11376 if (reference_vector)
11377 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11378 InheritPerlException(exception,perl_exception);
11379 exception=DestroyExceptionInfo(exception);
11380 sv_setiv(perl_exception,(IV) number_images);
11381 SvPOK_on(perl_exception);
11382 ST(0)=sv_2mortal(perl_exception);
11383 XSRETURN(1);
11384 }
11385
11386#
11387###############################################################################
11388# #
11389# #
11390# #
11391# M o n t a g e #
11392# #
11393# #
11394# #
11395###############################################################################
11396#
11397#
11398void
11399Montage(ref,...)
11400 Image::Magick ref=NO_INIT
11401 ALIAS:
11402 MontageImage = 1
11403 montage = 2
11404 montageimage = 3
11405 PPCODE:
11406 {
11407 AV
11408 *av;
11409
11410 char
11411 *attribute;
11412
11413 ExceptionInfo
11414 *exception;
11415
11416 HV
11417 *hv;
11418
11419 Image
11420 *image,
11421 *next;
11422
11423 PixelInfo
11424 transparent_color;
11425
11426 MontageInfo
11427 *montage_info;
11428
11429 register ssize_t
11430 i;
11431
11432 ssize_t
11433 sp;
11434
11435 struct PackageInfo
11436 *info;
11437
11438 SV
11439 *av_reference,
11440 *perl_exception,
11441 *reference,
11442 *rv,
11443 *sv;
11444
11445 PERL_UNUSED_VAR(ref);
11446 PERL_UNUSED_VAR(ix);
11447 exception=AcquireExceptionInfo();
11448 perl_exception=newSVpv("",0);
11449 sv=NULL;
11450 attribute=NULL;
11451 if (sv_isobject(ST(0)) == 0)
11452 {
11453 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11454 PackageName);
11455 goto PerlException;
11456 }
11457 reference=SvRV(ST(0));
11458 hv=SvSTASH(reference);
11459 av=newAV();
11460 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11461 SvREFCNT_dec(av);
11462 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11463 if (image == (Image *) NULL)
11464 {
11465 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11466 PackageName);
11467 goto PerlException;
11468 }
11469 /*
11470 Get options.
11471 */
11472 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11473 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11474 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11475 exception);
11476 for (i=2; i < items; i+=2)
11477 {
11478 attribute=(char *) SvPV(ST(i-1),na);
11479 switch (*attribute)
11480 {
11481 case 'B':
11482 case 'b':
11483 {
11484 if (LocaleCompare(attribute,"background") == 0)
11485 {
11486 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11487 &montage_info->background_color,exception);
11488 for (next=image; next; next=next->next)
11489 next->background_color=montage_info->background_color;
11490 break;
11491 }
11492 if (LocaleCompare(attribute,"border") == 0)
11493 {
11494 montage_info->border_width=SvIV(ST(i));
11495 break;
11496 }
11497 if (LocaleCompare(attribute,"bordercolor") == 0)
11498 {
11499 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11500 &montage_info->border_color,exception);
11501 for (next=image; next; next=next->next)
11502 next->border_color=montage_info->border_color;
11503 break;
11504 }
11505 if (LocaleCompare(attribute,"borderwidth") == 0)
11506 {
11507 montage_info->border_width=SvIV(ST(i));
11508 break;
11509 }
11510 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11511 attribute);
11512 break;
11513 }
11514 case 'C':
11515 case 'c':
11516 {
11517 if (LocaleCompare(attribute,"compose") == 0)
11518 {
11519 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11520 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11521 if (sp < 0)
11522 {
11523 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11524 SvPV(ST(i),na));
11525 break;
11526 }
11527 for (next=image; next; next=next->next)
11528 next->compose=(CompositeOperator) sp;
11529 break;
11530 }
11531 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11532 attribute);
11533 break;
11534 }
11535 case 'F':
11536 case 'f':
11537 {
11538 if (LocaleCompare(attribute,"fill") == 0)
11539 {
11540 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11541 &montage_info->fill,exception);
11542 break;
11543 }
11544 if (LocaleCompare(attribute,"font") == 0)
11545 {
11546 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11547 break;
11548 }
11549 if (LocaleCompare(attribute,"frame") == 0)
11550 {
11551 char
11552 *p;
11553
11554 p=SvPV(ST(i),na);
11555 if (IsGeometry(p) == MagickFalse)
11556 {
11557 ThrowPerlException(exception,OptionError,"MissingGeometry",
11558 p);
11559 break;
11560 }
11561 (void) CloneString(&montage_info->frame,p);
11562 if (*p == '\0')
11563 montage_info->frame=(char *) NULL;
11564 break;
11565 }
11566 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11567 attribute);
11568 break;
11569 }
11570 case 'G':
11571 case 'g':
11572 {
11573 if (LocaleCompare(attribute,"geometry") == 0)
11574 {
11575 char
11576 *p;
11577
11578 p=SvPV(ST(i),na);
11579 if (IsGeometry(p) == MagickFalse)
11580 {
11581 ThrowPerlException(exception,OptionError,"MissingGeometry",
11582 p);
11583 break;
11584 }
11585 (void) CloneString(&montage_info->geometry,p);
11586 if (*p == '\0')
11587 montage_info->geometry=(char *) NULL;
11588 break;
11589 }
11590 if (LocaleCompare(attribute,"gravity") == 0)
11591 {
11592 ssize_t
11593 in;
11594
11595 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11596 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11597 if (in < 0)
11598 {
11599 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11600 SvPV(ST(i),na));
11601 return;
11602 }
11603 montage_info->gravity=(GravityType) in;
11604 for (next=image; next; next=next->next)
11605 next->gravity=(GravityType) in;
11606 break;
11607 }
11608 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11609 attribute);
11610 break;
11611 }
11612 case 'L':
11613 case 'l':
11614 {
11615 if (LocaleCompare(attribute,"label") == 0)
11616 {
11617 for (next=image; next; next=next->next)
11618 (void) SetImageProperty(next,"label",InterpretImageProperties(
11619 info ? info->image_info : (ImageInfo *) NULL,next,
11620 SvPV(ST(i),na),exception),exception);
11621 break;
11622 }
11623 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11624 attribute);
11625 break;
11626 }
11627 case 'M':
11628 case 'm':
11629 {
11630 if (LocaleCompare(attribute,"mattecolor") == 0)
11631 {
11632 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
Cristy8645e042016-02-03 16:35:29 -050011633 &montage_info->alpha_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011634 for (next=image; next; next=next->next)
Cristy8645e042016-02-03 16:35:29 -050011635 next->alpha_color=montage_info->alpha_color;
cristy4a3ce0a2013-08-03 20:06:59 +000011636 break;
11637 }
11638 if (LocaleCompare(attribute,"mode") == 0)
11639 {
11640 ssize_t
11641 in;
11642
11643 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11644 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11645 switch (in)
11646 {
11647 default:
11648 {
11649 ThrowPerlException(exception,OptionError,
11650 "UnrecognizedModeType",SvPV(ST(i),na));
11651 break;
11652 }
11653 case FrameMode:
11654 {
11655 (void) CloneString(&montage_info->frame,"15x15+3+3");
11656 montage_info->shadow=MagickTrue;
11657 break;
11658 }
11659 case UnframeMode:
11660 {
11661 montage_info->frame=(char *) NULL;
11662 montage_info->shadow=MagickFalse;
11663 montage_info->border_width=0;
11664 break;
11665 }
11666 case ConcatenateMode:
11667 {
11668 montage_info->frame=(char *) NULL;
11669 montage_info->shadow=MagickFalse;
11670 (void) CloneString(&montage_info->geometry,"+0+0");
11671 montage_info->border_width=0;
11672 }
11673 }
11674 break;
11675 }
11676 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11677 attribute);
11678 break;
11679 }
11680 case 'P':
11681 case 'p':
11682 {
11683 if (LocaleCompare(attribute,"pointsize") == 0)
11684 {
11685 montage_info->pointsize=SvIV(ST(i));
11686 break;
11687 }
11688 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11689 attribute);
11690 break;
11691 }
11692 case 'S':
11693 case 's':
11694 {
11695 if (LocaleCompare(attribute,"shadow") == 0)
11696 {
11697 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11698 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11699 if (sp < 0)
11700 {
11701 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11702 SvPV(ST(i),na));
11703 break;
11704 }
11705 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11706 break;
11707 }
11708 if (LocaleCompare(attribute,"stroke") == 0)
11709 {
11710 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11711 &montage_info->stroke,exception);
11712 break;
11713 }
11714 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11715 attribute);
11716 break;
11717 }
11718 case 'T':
11719 case 't':
11720 {
11721 if (LocaleCompare(attribute,"texture") == 0)
11722 {
11723 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11724 break;
11725 }
11726 if (LocaleCompare(attribute,"tile") == 0)
11727 {
11728 char *p=SvPV(ST(i),na);
11729 if (IsGeometry(p) == MagickFalse)
11730 {
11731 ThrowPerlException(exception,OptionError,"MissingGeometry",
11732 p);
11733 break;
11734 }
11735 (void) CloneString(&montage_info->tile,p);
11736 if (*p == '\0')
11737 montage_info->tile=(char *) NULL;
11738 break;
11739 }
11740 if (LocaleCompare(attribute,"title") == 0)
11741 {
11742 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11743 break;
11744 }
11745 if (LocaleCompare(attribute,"transparent") == 0)
11746 {
11747 PixelInfo
11748 transparent_color;
11749
11750 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11751 &transparent_color,exception);
11752 for (next=image; next; next=next->next)
11753 (void) TransparentPaintImage(next,&transparent_color,
11754 TransparentAlpha,MagickFalse,exception);
11755 break;
11756 }
11757 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11758 attribute);
11759 break;
11760 }
11761 default:
11762 {
11763 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11764 attribute);
11765 break;
11766 }
11767 }
11768 }
11769 image=MontageImageList(info->image_info,montage_info,image,exception);
11770 montage_info=DestroyMontageInfo(montage_info);
11771 if (image == (Image *) NULL)
11772 goto PerlException;
11773 if (transparent_color.alpha != TransparentAlpha)
11774 for (next=image; next; next=next->next)
11775 (void) TransparentPaintImage(next,&transparent_color,
11776 TransparentAlpha,MagickFalse,exception);
11777 for ( ; image; image=image->next)
11778 {
11779 AddImageToRegistry(sv,image);
11780 rv=newRV(sv);
11781 av_push(av,sv_bless(rv,hv));
11782 SvREFCNT_dec(sv);
11783 }
11784 exception=DestroyExceptionInfo(exception);
11785 ST(0)=av_reference;
11786 SvREFCNT_dec(perl_exception);
11787 XSRETURN(1);
11788
11789 PerlException:
11790 InheritPerlException(exception,perl_exception);
11791 exception=DestroyExceptionInfo(exception);
11792 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11793 SvPOK_on(perl_exception);
11794 ST(0)=sv_2mortal(perl_exception);
11795 XSRETURN(1);
11796 }
11797
11798#
11799###############################################################################
11800# #
11801# #
11802# #
11803# M o r p h #
11804# #
11805# #
11806# #
11807###############################################################################
11808#
11809#
11810void
11811Morph(ref,...)
11812 Image::Magick ref=NO_INIT
11813 ALIAS:
11814 MorphImage = 1
11815 morph = 2
11816 morphimage = 3
11817 PPCODE:
11818 {
11819 AV
11820 *av;
11821
11822 char
11823 *attribute;
11824
11825 ExceptionInfo
11826 *exception;
11827
11828 HV
11829 *hv;
11830
11831 Image
11832 *image;
11833
11834 register ssize_t
11835 i;
11836
11837 ssize_t
11838 number_frames;
11839
11840 struct PackageInfo
11841 *info;
11842
11843 SV
11844 *av_reference,
11845 *perl_exception,
11846 *reference,
11847 *rv,
11848 *sv;
11849
11850 PERL_UNUSED_VAR(ref);
11851 PERL_UNUSED_VAR(ix);
11852 exception=AcquireExceptionInfo();
11853 perl_exception=newSVpv("",0);
11854 sv=NULL;
11855 av=NULL;
11856 attribute=NULL;
11857 if (sv_isobject(ST(0)) == 0)
11858 {
11859 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11860 PackageName);
11861 goto PerlException;
11862 }
11863 reference=SvRV(ST(0));
11864 hv=SvSTASH(reference);
11865 av=newAV();
11866 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11867 SvREFCNT_dec(av);
11868 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11869 if (image == (Image *) NULL)
11870 {
11871 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11872 PackageName);
11873 goto PerlException;
11874 }
11875 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11876 /*
11877 Get attribute.
11878 */
11879 number_frames=30;
11880 for (i=2; i < items; i+=2)
11881 {
11882 attribute=(char *) SvPV(ST(i-1),na);
11883 switch (*attribute)
11884 {
11885 case 'F':
11886 case 'f':
11887 {
11888 if (LocaleCompare(attribute,"frames") == 0)
11889 {
11890 number_frames=SvIV(ST(i));
11891 break;
11892 }
11893 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11894 attribute);
11895 break;
11896 }
11897 default:
11898 {
11899 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11900 attribute);
11901 break;
11902 }
11903 }
11904 }
11905 image=MorphImages(image,number_frames,exception);
11906 if (image == (Image *) NULL)
11907 goto PerlException;
11908 for ( ; image; image=image->next)
11909 {
11910 AddImageToRegistry(sv,image);
11911 rv=newRV(sv);
11912 av_push(av,sv_bless(rv,hv));
11913 SvREFCNT_dec(sv);
11914 }
11915 exception=DestroyExceptionInfo(exception);
11916 ST(0)=av_reference;
11917 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11918 XSRETURN(1);
11919
11920 PerlException:
11921 InheritPerlException(exception,perl_exception);
11922 exception=DestroyExceptionInfo(exception);
11923 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11924 SvPOK_on(perl_exception);
11925 ST(0)=sv_2mortal(perl_exception);
11926 XSRETURN(1);
11927 }
11928
11929#
11930###############################################################################
11931# #
11932# #
11933# #
11934# M o s a i c #
11935# #
11936# #
11937# #
11938###############################################################################
11939#
11940#
11941void
11942Mosaic(ref)
11943 Image::Magick ref=NO_INIT
11944 ALIAS:
11945 MosaicImage = 1
11946 mosaic = 2
11947 mosaicimage = 3
11948 PPCODE:
11949 {
11950 AV
11951 *av;
11952
11953 ExceptionInfo
11954 *exception;
11955
11956 HV
11957 *hv;
11958
11959 Image
11960 *image;
11961
11962 struct PackageInfo
11963 *info;
11964
11965 SV
11966 *perl_exception,
11967 *reference,
11968 *rv,
11969 *sv;
11970
11971 PERL_UNUSED_VAR(ref);
11972 PERL_UNUSED_VAR(ix);
11973 exception=AcquireExceptionInfo();
11974 perl_exception=newSVpv("",0);
11975 sv=NULL;
11976 if (sv_isobject(ST(0)) == 0)
11977 {
11978 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11979 PackageName);
11980 goto PerlException;
11981 }
11982 reference=SvRV(ST(0));
11983 hv=SvSTASH(reference);
11984 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11985 if (image == (Image *) NULL)
11986 {
11987 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11988 PackageName);
11989 goto PerlException;
11990 }
11991 image=MergeImageLayers(image,MosaicLayer,exception);
11992 /*
11993 Create blessed Perl array for the returned image.
11994 */
11995 av=newAV();
11996 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11997 SvREFCNT_dec(av);
11998 AddImageToRegistry(sv,image);
11999 rv=newRV(sv);
12000 av_push(av,sv_bless(rv,hv));
12001 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000012002 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000012003 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012004 SetImageInfo(info->image_info,0,exception);
12005 exception=DestroyExceptionInfo(exception);
12006 SvREFCNT_dec(perl_exception);
12007 XSRETURN(1);
12008
12009 PerlException:
12010 InheritPerlException(exception,perl_exception);
12011 exception=DestroyExceptionInfo(exception);
12012 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12013 SvPOK_on(perl_exception); /* return messages in string context */
12014 ST(0)=sv_2mortal(perl_exception);
12015 XSRETURN(1);
12016 }
12017
12018#
12019###############################################################################
12020# #
12021# #
12022# #
12023# P i n g #
12024# #
12025# #
12026# #
12027###############################################################################
12028#
12029#
12030void
12031Ping(ref,...)
12032 Image::Magick ref=NO_INIT
12033 ALIAS:
12034 PingImage = 1
12035 ping = 2
12036 pingimage = 3
12037 PPCODE:
12038 {
12039 AV
12040 *av;
12041
12042 char
12043 **keep,
12044 **list;
12045
12046 ExceptionInfo
12047 *exception;
12048
12049 Image
12050 *image,
12051 *next;
12052
12053 int
12054 n;
12055
12056 MagickBooleanType
12057 status;
12058
12059 register char
12060 **p;
12061
12062 register ssize_t
12063 i;
12064
12065 ssize_t
12066 ac;
12067
12068 STRLEN
12069 *length;
12070
12071 struct PackageInfo
12072 *info,
12073 *package_info;
12074
12075 SV
12076 *perl_exception,
12077 *reference;
12078
12079 size_t
12080 count;
12081
12082 PERL_UNUSED_VAR(ref);
12083 PERL_UNUSED_VAR(ix);
12084 exception=AcquireExceptionInfo();
12085 perl_exception=newSVpv("",0);
12086 package_info=(struct PackageInfo *) NULL;
12087 ac=(items < 2) ? 1 : items-1;
12088 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12089 keep=list;
12090 length=(STRLEN *) NULL;
12091 if (list == (char **) NULL)
12092 {
12093 ThrowPerlException(exception,ResourceLimitError,
12094 "MemoryAllocationFailed",PackageName);
12095 goto PerlException;
12096 }
12097 keep=list;
12098 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12099 if (length == (STRLEN *) NULL)
12100 {
12101 ThrowPerlException(exception,ResourceLimitError,
12102 "MemoryAllocationFailed",PackageName);
12103 goto PerlException;
12104 }
12105 if (sv_isobject(ST(0)) == 0)
12106 {
12107 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12108 PackageName);
12109 goto PerlException;
12110 }
12111 reference=SvRV(ST(0));
12112 if (SvTYPE(reference) != SVt_PVAV)
12113 {
12114 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12115 PackageName);
12116 goto PerlException;
12117 }
12118 av=(AV *) reference;
12119 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12120 exception);
12121 package_info=ClonePackageInfo(info,exception);
12122 n=1;
12123 if (items <= 1)
12124 *list=(char *) (*package_info->image_info->filename ?
12125 package_info->image_info->filename : "XC:black");
12126 else
12127 for (n=0, i=0; i < ac; i++)
12128 {
12129 list[n]=(char *) SvPV(ST(i+1),length[n]);
12130 if ((items >= 3) && strEQcase(list[n],"blob"))
12131 {
12132 void
12133 *blob;
12134
12135 i++;
12136 blob=(void *) (SvPV(ST(i+1),length[n]));
12137 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12138 }
12139 if ((items >= 3) && strEQcase(list[n],"filename"))
12140 continue;
12141 if ((items >= 3) && strEQcase(list[n],"file"))
12142 {
12143 FILE
12144 *file;
12145
12146 PerlIO
12147 *io_info;
12148
12149 i++;
12150 io_info=IoIFP(sv_2io(ST(i+1)));
12151 if (io_info == (PerlIO *) NULL)
12152 {
12153 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12154 PackageName);
12155 continue;
12156 }
12157 file=PerlIO_findFILE(io_info);
12158 if (file == (FILE *) NULL)
12159 {
12160 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12161 PackageName);
12162 continue;
12163 }
12164 SetImageInfoFile(package_info->image_info,file);
12165 }
12166 if ((items >= 3) && strEQcase(list[n],"magick"))
12167 continue;
12168 n++;
12169 }
12170 list[n]=(char *) NULL;
12171 keep=list;
12172 status=ExpandFilenames(&n,&list);
12173 if (status == MagickFalse)
12174 {
12175 ThrowPerlException(exception,ResourceLimitError,
12176 "MemoryAllocationFailed",PackageName);
12177 goto PerlException;
12178 }
12179 count=0;
12180 for (i=0; i < n; i++)
12181 {
12182 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012183 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012184 image=PingImage(package_info->image_info,exception);
12185 if (image == (Image *) NULL)
12186 break;
12187 if ((package_info->image_info->file != (FILE *) NULL) ||
12188 (package_info->image_info->blob != (void *) NULL))
12189 DisassociateImageStream(image);
12190 count+=GetImageListLength(image);
12191 EXTEND(sp,4*count);
12192 for (next=image; next; next=next->next)
12193 {
12194 PUSHs(sv_2mortal(newSViv(next->columns)));
12195 PUSHs(sv_2mortal(newSViv(next->rows)));
12196 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12197 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12198 }
12199 image=DestroyImageList(image);
12200 }
12201 /*
12202 Free resources.
12203 */
12204 for (i=0; i < n; i++)
12205 if (list[i] != (char *) NULL)
12206 for (p=keep; list[i] != *p++; )
12207 if (*p == NULL)
12208 {
12209 list[i]=(char *) RelinquishMagickMemory(list[i]);
12210 break;
12211 }
12212
12213 PerlException:
12214 if (package_info != (struct PackageInfo *) NULL)
12215 DestroyPackageInfo(package_info);
12216 if (list && (list != keep))
12217 list=(char **) RelinquishMagickMemory(list);
12218 if (keep)
12219 keep=(char **) RelinquishMagickMemory(keep);
12220 if (length)
12221 length=(STRLEN *) RelinquishMagickMemory(length);
12222 InheritPerlException(exception,perl_exception);
12223 exception=DestroyExceptionInfo(exception);
12224 SvREFCNT_dec(perl_exception); /* throw away all errors */
12225 }
12226
12227#
12228###############################################################################
12229# #
12230# #
12231# #
12232# P r e v i e w #
12233# #
12234# #
12235# #
12236###############################################################################
12237#
12238#
12239void
12240Preview(ref,...)
12241 Image::Magick ref=NO_INIT
12242 ALIAS:
12243 PreviewImage = 1
12244 preview = 2
12245 previewimage = 3
12246 PPCODE:
12247 {
12248 AV
12249 *av;
12250
12251 ExceptionInfo
12252 *exception;
12253
12254 HV
12255 *hv;
12256
12257 Image
12258 *image,
12259 *preview_image;
12260
12261 PreviewType
12262 preview_type;
12263
12264 struct PackageInfo
12265 *info;
12266
12267 SV
12268 *av_reference,
12269 *perl_exception,
12270 *reference,
12271 *rv,
12272 *sv;
12273
12274 PERL_UNUSED_VAR(ref);
12275 PERL_UNUSED_VAR(ix);
12276 exception=AcquireExceptionInfo();
12277 perl_exception=newSVpv("",0);
12278 sv=NULL;
12279 av=NULL;
12280 if (sv_isobject(ST(0)) == 0)
12281 {
12282 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12283 PackageName);
12284 goto PerlException;
12285 }
12286 reference=SvRV(ST(0));
12287 hv=SvSTASH(reference);
12288 av=newAV();
12289 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12290 SvREFCNT_dec(av);
12291 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12292 if (image == (Image *) NULL)
12293 {
12294 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12295 PackageName);
12296 goto PerlException;
12297 }
12298 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12299 preview_type=GammaPreview;
12300 if (items > 1)
12301 preview_type=(PreviewType)
12302 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12303 for ( ; image; image=image->next)
12304 {
12305 preview_image=PreviewImage(image,preview_type,exception);
12306 if (preview_image == (Image *) NULL)
12307 goto PerlException;
12308 AddImageToRegistry(sv,preview_image);
12309 rv=newRV(sv);
12310 av_push(av,sv_bless(rv,hv));
12311 SvREFCNT_dec(sv);
12312 }
12313 exception=DestroyExceptionInfo(exception);
12314 ST(0)=av_reference;
12315 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12316 XSRETURN(1);
12317
12318 PerlException:
12319 InheritPerlException(exception,perl_exception);
12320 exception=DestroyExceptionInfo(exception);
12321 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12322 SvPOK_on(perl_exception);
12323 ST(0)=sv_2mortal(perl_exception);
12324 XSRETURN(1);
12325 }
12326
12327#
12328###############################################################################
12329# #
12330# #
12331# #
12332# Q u e r y C o l o r #
12333# #
12334# #
12335# #
12336###############################################################################
12337#
12338#
12339void
12340QueryColor(ref,...)
12341 Image::Magick ref=NO_INIT
12342 ALIAS:
12343 querycolor = 1
12344 PPCODE:
12345 {
12346 char
12347 *name;
12348
12349 ExceptionInfo
12350 *exception;
12351
12352 PixelInfo
12353 color;
12354
12355 register ssize_t
12356 i;
12357
12358 SV
12359 *perl_exception;
12360
12361 PERL_UNUSED_VAR(ref);
12362 PERL_UNUSED_VAR(ix);
12363 exception=AcquireExceptionInfo();
12364 perl_exception=newSVpv("",0);
12365 if (items == 1)
12366 {
12367 const ColorInfo
12368 **colorlist;
12369
12370 size_t
12371 colors;
12372
12373 colorlist=GetColorInfoList("*",&colors,exception);
12374 EXTEND(sp,colors);
12375 for (i=0; i < (ssize_t) colors; i++)
12376 {
12377 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12378 }
12379 colorlist=(const ColorInfo **)
12380 RelinquishMagickMemory((ColorInfo **) colorlist);
12381 goto PerlException;
12382 }
12383 EXTEND(sp,5*items);
12384 for (i=1; i < items; i++)
12385 {
12386 name=(char *) SvPV(ST(i),na);
12387 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12388 {
12389 PUSHs(&sv_undef);
12390 continue;
12391 }
12392 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12393 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12394 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12395 if (color.colorspace == CMYKColorspace)
12396 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012397 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012398 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12399 }
12400
12401 PerlException:
12402 InheritPerlException(exception,perl_exception);
12403 exception=DestroyExceptionInfo(exception);
12404 SvREFCNT_dec(perl_exception);
12405 }
12406
12407#
12408###############################################################################
12409# #
12410# #
12411# #
12412# Q u e r y C o l o r N a m e #
12413# #
12414# #
12415# #
12416###############################################################################
12417#
12418#
12419void
12420QueryColorname(ref,...)
12421 Image::Magick ref=NO_INIT
12422 ALIAS:
12423 querycolorname = 1
12424 PPCODE:
12425 {
12426 AV
12427 *av;
12428
12429 char
cristy151b66d2015-04-15 10:50:31 +000012430 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012431
12432 ExceptionInfo
12433 *exception;
12434
12435 Image
12436 *image;
12437
12438 PixelInfo
12439 target_color;
12440
12441 register ssize_t
12442 i;
12443
12444 struct PackageInfo
12445 *info;
12446
12447 SV
12448 *perl_exception,
12449 *reference; /* reference is the SV* of ref=SvIV(reference) */
12450
12451 PERL_UNUSED_VAR(ref);
12452 PERL_UNUSED_VAR(ix);
12453 exception=AcquireExceptionInfo();
12454 perl_exception=newSVpv("",0);
12455 reference=SvRV(ST(0));
12456 av=(AV *) reference;
12457 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12458 exception);
12459 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12460 if (image == (Image *) NULL)
12461 {
12462 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12463 PackageName);
12464 goto PerlException;
12465 }
12466 EXTEND(sp,items);
12467 for (i=1; i < items; i++)
12468 {
12469 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12470 exception);
12471 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12472 exception);
12473 PUSHs(sv_2mortal(newSVpv(message,0)));
12474 }
12475
12476 PerlException:
12477 InheritPerlException(exception,perl_exception);
12478 exception=DestroyExceptionInfo(exception);
12479 SvREFCNT_dec(perl_exception);
12480 }
12481
12482#
12483###############################################################################
12484# #
12485# #
12486# #
12487# Q u e r y F o n t #
12488# #
12489# #
12490# #
12491###############################################################################
12492#
12493#
12494void
12495QueryFont(ref,...)
12496 Image::Magick ref=NO_INIT
12497 ALIAS:
12498 queryfont = 1
12499 PPCODE:
12500 {
12501 char
12502 *name,
cristy151b66d2015-04-15 10:50:31 +000012503 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012504
12505 ExceptionInfo
12506 *exception;
12507
12508 register ssize_t
12509 i;
12510
12511 SV
12512 *perl_exception;
12513
12514 volatile const TypeInfo
12515 *type_info;
12516
12517 PERL_UNUSED_VAR(ref);
12518 PERL_UNUSED_VAR(ix);
12519 exception=AcquireExceptionInfo();
12520 perl_exception=newSVpv("",0);
12521 if (items == 1)
12522 {
12523 const TypeInfo
12524 **typelist;
12525
12526 size_t
12527 types;
12528
12529 typelist=GetTypeInfoList("*",&types,exception);
12530 EXTEND(sp,types);
12531 for (i=0; i < (ssize_t) types; i++)
12532 {
12533 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12534 }
12535 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12536 typelist);
12537 goto PerlException;
12538 }
12539 EXTEND(sp,10*items);
12540 for (i=1; i < items; i++)
12541 {
12542 name=(char *) SvPV(ST(i),na);
12543 type_info=GetTypeInfo(name,exception);
12544 if (type_info == (TypeInfo *) NULL)
12545 {
12546 PUSHs(&sv_undef);
12547 continue;
12548 }
12549 if (type_info->name == (char *) NULL)
12550 PUSHs(&sv_undef);
12551 else
12552 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12553 if (type_info->description == (char *) NULL)
12554 PUSHs(&sv_undef);
12555 else
12556 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12557 if (type_info->family == (char *) NULL)
12558 PUSHs(&sv_undef);
12559 else
12560 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12561 if (type_info->style == UndefinedStyle)
12562 PUSHs(&sv_undef);
12563 else
12564 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12565 type_info->style),0)));
12566 if (type_info->stretch == UndefinedStretch)
12567 PUSHs(&sv_undef);
12568 else
12569 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12570 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012571 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012572 type_info->weight);
12573 PUSHs(sv_2mortal(newSVpv(message,0)));
12574 if (type_info->encoding == (char *) NULL)
12575 PUSHs(&sv_undef);
12576 else
12577 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12578 if (type_info->foundry == (char *) NULL)
12579 PUSHs(&sv_undef);
12580 else
12581 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12582 if (type_info->format == (char *) NULL)
12583 PUSHs(&sv_undef);
12584 else
12585 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12586 if (type_info->metrics == (char *) NULL)
12587 PUSHs(&sv_undef);
12588 else
12589 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12590 if (type_info->glyphs == (char *) NULL)
12591 PUSHs(&sv_undef);
12592 else
12593 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12594 }
12595
12596 PerlException:
12597 InheritPerlException(exception,perl_exception);
12598 exception=DestroyExceptionInfo(exception);
12599 SvREFCNT_dec(perl_exception);
12600 }
12601
12602#
12603###############################################################################
12604# #
12605# #
12606# #
12607# Q u e r y F o n t M e t r i c s #
12608# #
12609# #
12610# #
12611###############################################################################
12612#
12613#
12614void
12615QueryFontMetrics(ref,...)
12616 Image::Magick ref=NO_INIT
12617 ALIAS:
12618 queryfontmetrics = 1
12619 PPCODE:
12620 {
12621 AffineMatrix
12622 affine,
12623 current;
12624
12625 AV
12626 *av;
12627
12628 char
12629 *attribute;
12630
12631 double
12632 x,
12633 y;
12634
12635 DrawInfo
12636 *draw_info;
12637
12638 ExceptionInfo
12639 *exception;
12640
12641 GeometryInfo
12642 geometry_info;
12643
12644 Image
12645 *image;
12646
12647 MagickBooleanType
12648 status;
12649
12650 MagickStatusType
12651 flags;
12652
12653 register ssize_t
12654 i;
12655
12656 ssize_t
12657 type;
12658
12659 struct PackageInfo
12660 *info,
12661 *package_info;
12662
12663 SV
12664 *perl_exception,
12665 *reference; /* reference is the SV* of ref=SvIV(reference) */
12666
12667 TypeMetric
12668 metrics;
12669
12670 PERL_UNUSED_VAR(ref);
12671 PERL_UNUSED_VAR(ix);
12672 exception=AcquireExceptionInfo();
12673 package_info=(struct PackageInfo *) NULL;
12674 perl_exception=newSVpv("",0);
12675 reference=SvRV(ST(0));
12676 av=(AV *) reference;
12677 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12678 exception);
12679 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12680 if (image == (Image *) NULL)
12681 {
12682 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12683 PackageName);
12684 goto PerlException;
12685 }
12686 package_info=ClonePackageInfo(info,exception);
12687 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12688 CloneString(&draw_info->text,"");
12689 current=draw_info->affine;
12690 GetAffineMatrix(&affine);
12691 x=0.0;
12692 y=0.0;
12693 EXTEND(sp,7*items);
12694 for (i=2; i < items; i+=2)
12695 {
12696 attribute=(char *) SvPV(ST(i-1),na);
12697 switch (*attribute)
12698 {
12699 case 'A':
12700 case 'a':
12701 {
12702 if (LocaleCompare(attribute,"antialias") == 0)
12703 {
12704 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12705 SvPV(ST(i),na));
12706 if (type < 0)
12707 {
12708 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12709 SvPV(ST(i),na));
12710 break;
12711 }
12712 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12713 break;
12714 }
12715 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12716 attribute);
12717 break;
12718 }
12719 case 'd':
12720 case 'D':
12721 {
12722 if (LocaleCompare(attribute,"density") == 0)
12723 {
12724 CloneString(&draw_info->density,SvPV(ST(i),na));
12725 break;
12726 }
12727 if (LocaleCompare(attribute,"direction") == 0)
12728 {
12729 draw_info->direction=(DirectionType) ParseCommandOption(
12730 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12731 break;
12732 }
12733 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12734 attribute);
12735 break;
12736 }
12737 case 'e':
12738 case 'E':
12739 {
12740 if (LocaleCompare(attribute,"encoding") == 0)
12741 {
12742 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12743 break;
12744 }
12745 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12746 attribute);
12747 break;
12748 }
12749 case 'f':
12750 case 'F':
12751 {
12752 if (LocaleCompare(attribute,"family") == 0)
12753 {
12754 CloneString(&draw_info->family,SvPV(ST(i),na));
12755 break;
12756 }
12757 if (LocaleCompare(attribute,"fill") == 0)
12758 {
12759 if (info)
12760 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12761 &draw_info->fill,exception);
12762 break;
12763 }
12764 if (LocaleCompare(attribute,"font") == 0)
12765 {
12766 CloneString(&draw_info->font,SvPV(ST(i),na));
12767 break;
12768 }
12769 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12770 attribute);
12771 break;
12772 }
12773 case 'g':
12774 case 'G':
12775 {
12776 if (LocaleCompare(attribute,"geometry") == 0)
12777 {
12778 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12779 break;
12780 }
12781 if (LocaleCompare(attribute,"gravity") == 0)
12782 {
12783 draw_info->gravity=(GravityType) ParseCommandOption(
12784 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12785 break;
12786 }
12787 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12788 attribute);
12789 break;
12790 }
12791 case 'i':
12792 case 'I':
12793 {
12794 if (LocaleCompare(attribute,"interline-spacing") == 0)
12795 {
12796 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12797 draw_info->interline_spacing=geometry_info.rho;
12798 break;
12799 }
12800 if (LocaleCompare(attribute,"interword-spacing") == 0)
12801 {
12802 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12803 draw_info->interword_spacing=geometry_info.rho;
12804 break;
12805 }
12806 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12807 attribute);
12808 break;
12809 }
12810 case 'k':
12811 case 'K':
12812 {
12813 if (LocaleCompare(attribute,"kerning") == 0)
12814 {
12815 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12816 draw_info->kerning=geometry_info.rho;
12817 break;
12818 }
12819 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12820 attribute);
12821 break;
12822 }
12823 case 'p':
12824 case 'P':
12825 {
12826 if (LocaleCompare(attribute,"pointsize") == 0)
12827 {
12828 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12829 draw_info->pointsize=geometry_info.rho;
12830 break;
12831 }
12832 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12833 attribute);
12834 break;
12835 }
12836 case 'r':
12837 case 'R':
12838 {
12839 if (LocaleCompare(attribute,"rotate") == 0)
12840 {
12841 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12842 affine.rx=geometry_info.rho;
12843 affine.ry=geometry_info.sigma;
12844 if ((flags & SigmaValue) == 0)
12845 affine.ry=affine.rx;
12846 break;
12847 }
12848 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12849 attribute);
12850 break;
12851 }
12852 case 's':
12853 case 'S':
12854 {
12855 if (LocaleCompare(attribute,"scale") == 0)
12856 {
12857 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12858 affine.sx=geometry_info.rho;
12859 affine.sy=geometry_info.sigma;
12860 if ((flags & SigmaValue) == 0)
12861 affine.sy=affine.sx;
12862 break;
12863 }
12864 if (LocaleCompare(attribute,"skew") == 0)
12865 {
12866 double
12867 x_angle,
12868 y_angle;
12869
12870 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12871 x_angle=geometry_info.rho;
12872 y_angle=geometry_info.sigma;
12873 if ((flags & SigmaValue) == 0)
12874 y_angle=x_angle;
12875 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12876 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12877 break;
12878 }
12879 if (LocaleCompare(attribute,"stroke") == 0)
12880 {
12881 if (info)
12882 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12883 &draw_info->stroke,exception);
12884 break;
12885 }
12886 if (LocaleCompare(attribute,"style") == 0)
12887 {
12888 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12889 SvPV(ST(i),na));
12890 if (type < 0)
12891 {
12892 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12893 SvPV(ST(i),na));
12894 break;
12895 }
12896 draw_info->style=(StyleType) type;
12897 break;
12898 }
12899 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12900 attribute);
12901 break;
12902 }
12903 case 't':
12904 case 'T':
12905 {
12906 if (LocaleCompare(attribute,"text") == 0)
12907 {
12908 CloneString(&draw_info->text,SvPV(ST(i),na));
12909 break;
12910 }
12911 if (LocaleCompare(attribute,"translate") == 0)
12912 {
12913 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12914 affine.tx=geometry_info.rho;
12915 affine.ty=geometry_info.sigma;
12916 if ((flags & SigmaValue) == 0)
12917 affine.ty=affine.tx;
12918 break;
12919 }
12920 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12921 attribute);
12922 break;
12923 }
12924 case 'w':
12925 case 'W':
12926 {
12927 if (LocaleCompare(attribute,"weight") == 0)
12928 {
12929 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12930 draw_info->weight=(size_t) geometry_info.rho;
12931 break;
12932 }
12933 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12934 attribute);
12935 break;
12936 }
12937 case 'x':
12938 case 'X':
12939 {
12940 if (LocaleCompare(attribute,"x") == 0)
12941 {
12942 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12943 x=geometry_info.rho;
12944 break;
12945 }
12946 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12947 attribute);
12948 break;
12949 }
12950 case 'y':
12951 case 'Y':
12952 {
12953 if (LocaleCompare(attribute,"y") == 0)
12954 {
12955 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12956 y=geometry_info.rho;
12957 break;
12958 }
12959 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12960 attribute);
12961 break;
12962 }
12963 default:
12964 {
12965 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12966 attribute);
12967 break;
12968 }
12969 }
12970 }
12971 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12972 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12973 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12974 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12975 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12976 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12977 if (draw_info->geometry == (char *) NULL)
12978 {
12979 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000012980 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000012981 "%.15g,%.15g",x,y);
12982 }
12983 status=GetTypeMetrics(image,draw_info,&metrics,exception);
12984 (void) CatchImageException(image);
12985 if (status == MagickFalse)
12986 PUSHs(&sv_undef);
12987 else
12988 {
12989 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12990 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12991 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12992 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12993 PUSHs(sv_2mortal(newSVnv(metrics.width)));
12994 PUSHs(sv_2mortal(newSVnv(metrics.height)));
12995 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12996 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
12997 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
12998 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
12999 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13000 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13001 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13002 }
13003 draw_info=DestroyDrawInfo(draw_info);
13004
13005 PerlException:
13006 if (package_info != (struct PackageInfo *) NULL)
13007 DestroyPackageInfo(package_info);
13008 InheritPerlException(exception,perl_exception);
13009 exception=DestroyExceptionInfo(exception);
13010 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13011 }
13012
13013#
13014###############################################################################
13015# #
13016# #
13017# #
13018# 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 #
13019# #
13020# #
13021# #
13022###############################################################################
13023#
13024#
13025void
13026QueryMultilineFontMetrics(ref,...)
13027 Image::Magick ref=NO_INIT
13028 ALIAS:
13029 querymultilinefontmetrics = 1
13030 PPCODE:
13031 {
13032 AffineMatrix
13033 affine,
13034 current;
13035
13036 AV
13037 *av;
13038
13039 char
13040 *attribute;
13041
13042 double
13043 x,
13044 y;
13045
13046 DrawInfo
13047 *draw_info;
13048
13049 ExceptionInfo
13050 *exception;
13051
13052 GeometryInfo
13053 geometry_info;
13054
13055 Image
13056 *image;
13057
13058 MagickBooleanType
13059 status;
13060
13061 MagickStatusType
13062 flags;
13063
13064 register ssize_t
13065 i;
13066
13067 ssize_t
13068 type;
13069
13070 struct PackageInfo
13071 *info,
13072 *package_info;
13073
13074 SV
13075 *perl_exception,
13076 *reference; /* reference is the SV* of ref=SvIV(reference) */
13077
13078 TypeMetric
13079 metrics;
13080
13081 PERL_UNUSED_VAR(ref);
13082 PERL_UNUSED_VAR(ix);
13083 exception=AcquireExceptionInfo();
13084 package_info=(struct PackageInfo *) NULL;
13085 perl_exception=newSVpv("",0);
13086 reference=SvRV(ST(0));
13087 av=(AV *) reference;
13088 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13089 exception);
13090 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13091 if (image == (Image *) NULL)
13092 {
13093 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13094 PackageName);
13095 goto PerlException;
13096 }
13097 package_info=ClonePackageInfo(info,exception);
13098 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13099 CloneString(&draw_info->text,"");
13100 current=draw_info->affine;
13101 GetAffineMatrix(&affine);
13102 x=0.0;
13103 y=0.0;
13104 EXTEND(sp,7*items);
13105 for (i=2; i < items; i+=2)
13106 {
13107 attribute=(char *) SvPV(ST(i-1),na);
13108 switch (*attribute)
13109 {
13110 case 'A':
13111 case 'a':
13112 {
13113 if (LocaleCompare(attribute,"antialias") == 0)
13114 {
13115 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13116 SvPV(ST(i),na));
13117 if (type < 0)
13118 {
13119 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13120 SvPV(ST(i),na));
13121 break;
13122 }
13123 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13124 break;
13125 }
13126 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13127 attribute);
13128 break;
13129 }
13130 case 'd':
13131 case 'D':
13132 {
13133 if (LocaleCompare(attribute,"density") == 0)
13134 {
13135 CloneString(&draw_info->density,SvPV(ST(i),na));
13136 break;
13137 }
13138 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13139 attribute);
13140 break;
13141 }
13142 case 'e':
13143 case 'E':
13144 {
13145 if (LocaleCompare(attribute,"encoding") == 0)
13146 {
13147 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13148 break;
13149 }
13150 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13151 attribute);
13152 break;
13153 }
13154 case 'f':
13155 case 'F':
13156 {
13157 if (LocaleCompare(attribute,"family") == 0)
13158 {
13159 CloneString(&draw_info->family,SvPV(ST(i),na));
13160 break;
13161 }
13162 if (LocaleCompare(attribute,"fill") == 0)
13163 {
13164 if (info)
13165 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13166 &draw_info->fill,exception);
13167 break;
13168 }
13169 if (LocaleCompare(attribute,"font") == 0)
13170 {
13171 CloneString(&draw_info->font,SvPV(ST(i),na));
13172 break;
13173 }
13174 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13175 attribute);
13176 break;
13177 }
13178 case 'g':
13179 case 'G':
13180 {
13181 if (LocaleCompare(attribute,"geometry") == 0)
13182 {
13183 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13184 break;
13185 }
13186 if (LocaleCompare(attribute,"gravity") == 0)
13187 {
13188 draw_info->gravity=(GravityType) ParseCommandOption(
13189 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13190 break;
13191 }
13192 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13193 attribute);
13194 break;
13195 }
13196 case 'p':
13197 case 'P':
13198 {
13199 if (LocaleCompare(attribute,"pointsize") == 0)
13200 {
13201 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13202 draw_info->pointsize=geometry_info.rho;
13203 break;
13204 }
13205 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13206 attribute);
13207 break;
13208 }
13209 case 'r':
13210 case 'R':
13211 {
13212 if (LocaleCompare(attribute,"rotate") == 0)
13213 {
13214 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13215 affine.rx=geometry_info.rho;
13216 affine.ry=geometry_info.sigma;
13217 if ((flags & SigmaValue) == 0)
13218 affine.ry=affine.rx;
13219 break;
13220 }
13221 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13222 attribute);
13223 break;
13224 }
13225 case 's':
13226 case 'S':
13227 {
13228 if (LocaleCompare(attribute,"scale") == 0)
13229 {
13230 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13231 affine.sx=geometry_info.rho;
13232 affine.sy=geometry_info.sigma;
13233 if ((flags & SigmaValue) == 0)
13234 affine.sy=affine.sx;
13235 break;
13236 }
13237 if (LocaleCompare(attribute,"skew") == 0)
13238 {
13239 double
13240 x_angle,
13241 y_angle;
13242
13243 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13244 x_angle=geometry_info.rho;
13245 y_angle=geometry_info.sigma;
13246 if ((flags & SigmaValue) == 0)
13247 y_angle=x_angle;
13248 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13249 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13250 break;
13251 }
13252 if (LocaleCompare(attribute,"stroke") == 0)
13253 {
13254 if (info)
13255 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13256 &draw_info->stroke,exception);
13257 break;
13258 }
13259 if (LocaleCompare(attribute,"style") == 0)
13260 {
13261 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13262 SvPV(ST(i),na));
13263 if (type < 0)
13264 {
13265 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13266 SvPV(ST(i),na));
13267 break;
13268 }
13269 draw_info->style=(StyleType) type;
13270 break;
13271 }
13272 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13273 attribute);
13274 break;
13275 }
13276 case 't':
13277 case 'T':
13278 {
13279 if (LocaleCompare(attribute,"text") == 0)
13280 {
13281 CloneString(&draw_info->text,SvPV(ST(i),na));
13282 break;
13283 }
13284 if (LocaleCompare(attribute,"translate") == 0)
13285 {
13286 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13287 affine.tx=geometry_info.rho;
13288 affine.ty=geometry_info.sigma;
13289 if ((flags & SigmaValue) == 0)
13290 affine.ty=affine.tx;
13291 break;
13292 }
13293 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13294 attribute);
13295 break;
13296 }
13297 case 'w':
13298 case 'W':
13299 {
13300 if (LocaleCompare(attribute,"weight") == 0)
13301 {
13302 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13303 draw_info->weight=(size_t) geometry_info.rho;
13304 break;
13305 }
13306 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13307 attribute);
13308 break;
13309 }
13310 case 'x':
13311 case 'X':
13312 {
13313 if (LocaleCompare(attribute,"x") == 0)
13314 {
13315 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13316 x=geometry_info.rho;
13317 break;
13318 }
13319 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13320 attribute);
13321 break;
13322 }
13323 case 'y':
13324 case 'Y':
13325 {
13326 if (LocaleCompare(attribute,"y") == 0)
13327 {
13328 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13329 y=geometry_info.rho;
13330 break;
13331 }
13332 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13333 attribute);
13334 break;
13335 }
13336 default:
13337 {
13338 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13339 attribute);
13340 break;
13341 }
13342 }
13343 }
13344 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13345 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13346 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13347 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13348 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13349 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13350 if (draw_info->geometry == (char *) NULL)
13351 {
13352 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013353 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013354 "%.15g,%.15g",x,y);
13355 }
13356 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13357 (void) CatchException(exception);
13358 if (status == MagickFalse)
13359 PUSHs(&sv_undef);
13360 else
13361 {
13362 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13363 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13364 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13365 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13366 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13367 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13368 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13369 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13370 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13371 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13372 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13373 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13374 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13375 }
13376 draw_info=DestroyDrawInfo(draw_info);
13377
13378 PerlException:
13379 if (package_info != (struct PackageInfo *) NULL)
13380 DestroyPackageInfo(package_info);
13381 InheritPerlException(exception,perl_exception);
13382 exception=DestroyExceptionInfo(exception);
13383 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13384 }
13385
13386#
13387###############################################################################
13388# #
13389# #
13390# #
13391# Q u e r y F o r m a t #
13392# #
13393# #
13394# #
13395###############################################################################
13396#
13397#
13398void
13399QueryFormat(ref,...)
13400 Image::Magick ref=NO_INIT
13401 ALIAS:
13402 queryformat = 1
13403 PPCODE:
13404 {
13405 char
13406 *name;
13407
13408 ExceptionInfo
13409 *exception;
13410
13411 register ssize_t
13412 i;
13413
13414 SV
13415 *perl_exception;
13416
13417 volatile const MagickInfo
13418 *magick_info;
13419
13420 PERL_UNUSED_VAR(ref);
13421 PERL_UNUSED_VAR(ix);
13422 exception=AcquireExceptionInfo();
13423 perl_exception=newSVpv("",0);
13424 if (items == 1)
13425 {
13426 char
cristy151b66d2015-04-15 10:50:31 +000013427 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013428
13429 const MagickInfo
13430 **format_list;
13431
13432 size_t
13433 types;
13434
13435 format_list=GetMagickInfoList("*",&types,exception);
13436 EXTEND(sp,types);
13437 for (i=0; i < (ssize_t) types; i++)
13438 {
cristy151b66d2015-04-15 10:50:31 +000013439 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013440 LocaleLower(format);
13441 PUSHs(sv_2mortal(newSVpv(format,0)));
13442 }
13443 format_list=(const MagickInfo **)
13444 RelinquishMagickMemory((MagickInfo *) format_list);
13445 goto PerlException;
13446 }
13447 EXTEND(sp,8*items);
13448 for (i=1; i < items; i++)
13449 {
13450 name=(char *) SvPV(ST(i),na);
13451 magick_info=GetMagickInfo(name,exception);
13452 if (magick_info == (const MagickInfo *) NULL)
13453 {
13454 PUSHs(&sv_undef);
13455 continue;
13456 }
cristy4a3ce0a2013-08-03 20:06:59 +000013457 if (magick_info->description == (char *) NULL)
13458 PUSHs(&sv_undef);
13459 else
13460 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13461 if (magick_info->module == (char *) NULL)
13462 PUSHs(&sv_undef);
13463 else
13464 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13465 }
13466
13467 PerlException:
13468 InheritPerlException(exception,perl_exception);
13469 exception=DestroyExceptionInfo(exception);
13470 SvREFCNT_dec(perl_exception);
13471 }
13472
13473#
13474###############################################################################
13475# #
13476# #
13477# #
13478# Q u e r y O p t i o n #
13479# #
13480# #
13481# #
13482###############################################################################
13483#
13484#
13485void
13486QueryOption(ref,...)
13487 Image::Magick ref=NO_INIT
13488 ALIAS:
13489 queryoption = 1
13490 PPCODE:
13491 {
13492 char
13493 **options;
13494
13495 ExceptionInfo
13496 *exception;
13497
13498 register ssize_t
13499 i;
13500
13501 ssize_t
13502 j,
13503 option;
13504
13505 SV
13506 *perl_exception;
13507
13508 PERL_UNUSED_VAR(ref);
13509 PERL_UNUSED_VAR(ix);
13510 exception=AcquireExceptionInfo();
13511 perl_exception=newSVpv("",0);
13512 EXTEND(sp,8*items);
13513 for (i=1; i < items; i++)
13514 {
13515 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13516 SvPV(ST(i),na));
13517 options=GetCommandOptions((CommandOption) option);
13518 if (options == (char **) NULL)
13519 PUSHs(&sv_undef);
13520 else
13521 {
13522 for (j=0; options[j] != (char *) NULL; j++)
13523 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13524 options=DestroyStringList(options);
13525 }
13526 }
13527
13528 InheritPerlException(exception,perl_exception);
13529 exception=DestroyExceptionInfo(exception);
13530 SvREFCNT_dec(perl_exception);
13531 }
13532
13533#
13534###############################################################################
13535# #
13536# #
13537# #
13538# R e a d #
13539# #
13540# #
13541# #
13542###############################################################################
13543#
13544#
13545void
13546Read(ref,...)
13547 Image::Magick ref=NO_INIT
13548 ALIAS:
13549 ReadImage = 1
13550 read = 2
13551 readimage = 3
13552 PPCODE:
13553 {
13554 AV
13555 *av;
13556
13557 char
13558 **keep,
13559 **list;
13560
13561 ExceptionInfo
13562 *exception;
13563
13564 HV
13565 *hv;
13566
13567 Image
13568 *image;
13569
13570 int
13571 n;
13572
13573 MagickBooleanType
13574 status;
13575
13576 register char
13577 **p;
13578
13579 register ssize_t
13580 i;
13581
13582 ssize_t
13583 ac,
13584 number_images;
13585
13586 STRLEN
13587 *length;
13588
13589 struct PackageInfo
13590 *info,
13591 *package_info;
13592
13593 SV
13594 *perl_exception, /* Perl variable for storing messages */
13595 *reference,
13596 *rv,
13597 *sv;
13598
13599 PERL_UNUSED_VAR(ref);
13600 PERL_UNUSED_VAR(ix);
13601 exception=AcquireExceptionInfo();
13602 perl_exception=newSVpv("",0);
13603 sv=NULL;
13604 package_info=(struct PackageInfo *) NULL;
13605 number_images=0;
13606 ac=(items < 2) ? 1 : items-1;
13607 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13608 keep=list;
13609 length=(STRLEN *) NULL;
13610 if (list == (char **) NULL)
13611 {
13612 ThrowPerlException(exception,ResourceLimitError,
13613 "MemoryAllocationFailed",PackageName);
13614 goto PerlException;
13615 }
13616 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13617 if (length == (STRLEN *) NULL)
13618 {
13619 ThrowPerlException(exception,ResourceLimitError,
13620 "MemoryAllocationFailed",PackageName);
13621 goto PerlException;
13622 }
13623 if (sv_isobject(ST(0)) == 0)
13624 {
13625 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13626 PackageName);
13627 goto PerlException;
13628 }
13629 reference=SvRV(ST(0));
13630 hv=SvSTASH(reference);
13631 if (SvTYPE(reference) != SVt_PVAV)
13632 {
13633 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13634 PackageName);
13635 goto PerlException;
13636 }
13637 av=(AV *) reference;
13638 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13639 exception);
13640 package_info=ClonePackageInfo(info,exception);
13641 n=1;
13642 if (items <= 1)
13643 *list=(char *) (*package_info->image_info->filename ?
13644 package_info->image_info->filename : "XC:black");
13645 else
13646 for (n=0, i=0; i < ac; i++)
13647 {
13648 list[n]=(char *) SvPV(ST(i+1),length[n]);
13649 if ((items >= 3) && strEQcase(list[n],"blob"))
13650 {
13651 void
13652 *blob;
13653
13654 i++;
13655 blob=(void *) (SvPV(ST(i+1),length[n]));
13656 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13657 }
13658 if ((items >= 3) && strEQcase(list[n],"filename"))
13659 continue;
13660 if ((items >= 3) && strEQcase(list[n],"file"))
13661 {
13662 FILE
13663 *file;
13664
13665 PerlIO
13666 *io_info;
13667
13668 i++;
13669 io_info=IoIFP(sv_2io(ST(i+1)));
13670 if (io_info == (PerlIO *) NULL)
13671 {
13672 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13673 PackageName);
13674 continue;
13675 }
13676 file=PerlIO_findFILE(io_info);
13677 if (file == (FILE *) NULL)
13678 {
13679 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13680 PackageName);
13681 continue;
13682 }
13683 SetImageInfoFile(package_info->image_info,file);
13684 }
13685 if ((items >= 3) && strEQcase(list[n],"magick"))
13686 continue;
13687 n++;
13688 }
13689 list[n]=(char *) NULL;
13690 keep=list;
13691 status=ExpandFilenames(&n,&list);
13692 if (status == MagickFalse)
13693 {
13694 ThrowPerlException(exception,ResourceLimitError,
13695 "MemoryAllocationFailed",PackageName);
13696 goto PerlException;
13697 }
13698 number_images=0;
13699 for (i=0; i < n; i++)
13700 {
13701 if ((package_info->image_info->file == (FILE *) NULL) &&
13702 (package_info->image_info->blob == (void *) NULL))
13703 image=ReadImages(package_info->image_info,list[i],exception);
13704 else
13705 {
13706 image=ReadImages(package_info->image_info,
13707 package_info->image_info->filename,exception);
13708 if (image != (Image *) NULL)
13709 DisassociateImageStream(image);
13710 }
13711 if (image == (Image *) NULL)
13712 break;
13713 for ( ; image; image=image->next)
13714 {
13715 AddImageToRegistry(sv,image);
13716 rv=newRV(sv);
13717 av_push(av,sv_bless(rv,hv));
13718 SvREFCNT_dec(sv);
13719 number_images++;
13720 }
13721 }
13722 /*
13723 Free resources.
13724 */
13725 for (i=0; i < n; i++)
13726 if (list[i] != (char *) NULL)
13727 for (p=keep; list[i] != *p++; )
13728 if (*p == (char *) NULL)
13729 {
13730 list[i]=(char *) RelinquishMagickMemory(list[i]);
13731 break;
13732 }
13733
13734 PerlException:
13735 if (package_info != (struct PackageInfo *) NULL)
13736 DestroyPackageInfo(package_info);
13737 if (list && (list != keep))
13738 list=(char **) RelinquishMagickMemory(list);
13739 if (keep)
13740 keep=(char **) RelinquishMagickMemory(keep);
13741 if (length)
13742 length=(STRLEN *) RelinquishMagickMemory(length);
13743 InheritPerlException(exception,perl_exception);
13744 exception=DestroyExceptionInfo(exception);
13745 sv_setiv(perl_exception,(IV) number_images);
13746 SvPOK_on(perl_exception);
13747 ST(0)=sv_2mortal(perl_exception);
13748 XSRETURN(1);
13749 }
13750
13751#
13752###############################################################################
13753# #
13754# #
13755# #
13756# R e m o t e #
13757# #
13758# #
13759# #
13760###############################################################################
13761#
13762#
13763void
13764Remote(ref,...)
13765 Image::Magick ref=NO_INIT
13766 ALIAS:
13767 RemoteCommand = 1
13768 remote = 2
13769 remoteCommand = 3
13770 PPCODE:
13771 {
13772 AV
13773 *av;
13774
13775 ExceptionInfo
13776 *exception;
13777
13778 register ssize_t
13779 i;
13780
13781 SV
13782 *perl_exception,
13783 *reference;
13784
13785 struct PackageInfo
13786 *info;
13787
13788 PERL_UNUSED_VAR(ref);
13789 PERL_UNUSED_VAR(ix);
13790 exception=AcquireExceptionInfo();
13791 perl_exception=newSVpv("",0);
13792 reference=SvRV(ST(0));
13793 av=(AV *) reference;
13794 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13795 exception);
13796 for (i=1; i < items; i++)
13797 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13798 SvPV(ST(i),na),exception);
13799 InheritPerlException(exception,perl_exception);
13800 exception=DestroyExceptionInfo(exception);
13801 SvREFCNT_dec(perl_exception); /* throw away all errors */
13802 }
13803
13804#
13805###############################################################################
13806# #
13807# #
13808# #
13809# S e t #
13810# #
13811# #
13812# #
13813###############################################################################
13814#
13815#
13816void
13817Set(ref,...)
13818 Image::Magick ref=NO_INIT
13819 ALIAS:
13820 SetAttributes = 1
13821 SetAttribute = 2
13822 set = 3
13823 setattributes = 4
13824 setattribute = 5
13825 PPCODE:
13826 {
13827 ExceptionInfo
13828 *exception;
13829
13830 Image
13831 *image;
13832
13833 register ssize_t
13834 i;
13835
13836 struct PackageInfo
13837 *info;
13838
13839 SV
13840 *perl_exception,
13841 *reference; /* reference is the SV* of ref=SvIV(reference) */
13842
13843 PERL_UNUSED_VAR(ref);
13844 PERL_UNUSED_VAR(ix);
13845 exception=AcquireExceptionInfo();
13846 perl_exception=newSVpv("",0);
13847 if (sv_isobject(ST(0)) == 0)
13848 {
13849 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13850 PackageName);
13851 goto PerlException;
13852 }
13853 reference=SvRV(ST(0));
13854 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13855 if (items == 2)
13856 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13857 else
13858 for (i=2; i < items; i+=2)
13859 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13860
13861 PerlException:
13862 InheritPerlException(exception,perl_exception);
13863 exception=DestroyExceptionInfo(exception);
13864 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13865 SvPOK_on(perl_exception);
13866 ST(0)=sv_2mortal(perl_exception);
13867 XSRETURN(1);
13868 }
13869
13870#
13871###############################################################################
13872# #
13873# #
13874# #
13875# S e t P i x e l #
13876# #
13877# #
13878# #
13879###############################################################################
13880#
13881#
13882void
13883SetPixel(ref,...)
13884 Image::Magick ref=NO_INIT
13885 ALIAS:
13886 setpixel = 1
13887 setPixel = 2
13888 PPCODE:
13889 {
13890 AV
13891 *av;
13892
13893 char
13894 *attribute;
13895
13896 ChannelType
13897 channel,
13898 channel_mask;
13899
13900 ExceptionInfo
13901 *exception;
13902
13903 Image
13904 *image;
13905
13906 MagickBooleanType
13907 normalize;
13908
13909 RectangleInfo
13910 region;
13911
13912 register ssize_t
13913 i;
13914
13915 register Quantum
13916 *q;
13917
13918 ssize_t
13919 option;
13920
13921 struct PackageInfo
13922 *info;
13923
13924 SV
13925 *perl_exception,
13926 *reference; /* reference is the SV* of ref=SvIV(reference) */
13927
13928 PERL_UNUSED_VAR(ref);
13929 PERL_UNUSED_VAR(ix);
13930 exception=AcquireExceptionInfo();
13931 perl_exception=newSVpv("",0);
13932 reference=SvRV(ST(0));
13933 av=(AV *) reference;
13934 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13935 exception);
13936 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13937 if (image == (Image *) NULL)
13938 {
13939 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13940 PackageName);
13941 goto PerlException;
13942 }
13943 av=(AV *) NULL;
13944 normalize=MagickTrue;
13945 region.x=0;
13946 region.y=0;
13947 region.width=image->columns;
13948 region.height=1;
13949 if (items == 1)
13950 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
13951 channel=DefaultChannels;
13952 for (i=2; i < items; i+=2)
13953 {
13954 attribute=(char *) SvPV(ST(i-1),na);
13955 switch (*attribute)
13956 {
13957 case 'C':
13958 case 'c':
13959 {
13960 if (LocaleCompare(attribute,"channel") == 0)
13961 {
13962 ssize_t
13963 option;
13964
13965 option=ParseChannelOption(SvPV(ST(i),na));
13966 if (option < 0)
13967 {
13968 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13969 SvPV(ST(i),na));
13970 return;
13971 }
13972 channel=(ChannelType) option;
13973 break;
13974 }
13975 if (LocaleCompare(attribute,"color") == 0)
13976 {
13977 if (SvTYPE(ST(i)) != SVt_RV)
13978 {
13979 char
cristy151b66d2015-04-15 10:50:31 +000013980 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013981
cristy151b66d2015-04-15 10:50:31 +000013982 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013983 "invalid %.60s value",attribute);
13984 ThrowPerlException(exception,OptionError,message,
13985 SvPV(ST(i),na));
13986 }
13987 av=(AV *) SvRV(ST(i));
13988 break;
13989 }
13990 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13991 attribute);
13992 break;
13993 }
13994 case 'g':
13995 case 'G':
13996 {
13997 if (LocaleCompare(attribute,"geometry") == 0)
13998 {
13999 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14000 break;
14001 }
14002 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14003 attribute);
14004 break;
14005 }
14006 case 'N':
14007 case 'n':
14008 {
14009 if (LocaleCompare(attribute,"normalize") == 0)
14010 {
14011 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14012 SvPV(ST(i),na));
14013 if (option < 0)
14014 {
14015 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14016 SvPV(ST(i),na));
14017 break;
14018 }
14019 normalize=option != 0 ? MagickTrue : MagickFalse;
14020 break;
14021 }
14022 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14023 attribute);
14024 break;
14025 }
14026 case 'x':
14027 case 'X':
14028 {
14029 if (LocaleCompare(attribute,"x") == 0)
14030 {
14031 region.x=SvIV(ST(i));
14032 break;
14033 }
14034 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14035 attribute);
14036 break;
14037 }
14038 case 'y':
14039 case 'Y':
14040 {
14041 if (LocaleCompare(attribute,"y") == 0)
14042 {
14043 region.y=SvIV(ST(i));
14044 break;
14045 }
14046 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14047 attribute);
14048 break;
14049 }
14050 default:
14051 {
14052 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14053 attribute);
14054 break;
14055 }
14056 }
14057 }
14058 (void) SetImageStorageClass(image,DirectClass,exception);
14059 channel_mask=SetImageChannelMask(image,channel);
14060 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14061 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14062 (SvTYPE(av) != SVt_PVAV))
14063 PUSHs(&sv_undef);
14064 else
14065 {
14066 double
14067 scale;
14068
14069 register ssize_t
14070 i;
14071
14072 i=0;
14073 scale=1.0;
14074 if (normalize != MagickFalse)
14075 scale=QuantumRange;
14076 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14077 (i <= av_len(av)))
14078 {
14079 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14080 av_fetch(av,i,0)))),q);
14081 i++;
14082 }
14083 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14084 (i <= av_len(av)))
14085 {
14086 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14087 av_fetch(av,i,0)))),q);
14088 i++;
14089 }
14090 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14091 (i <= av_len(av)))
14092 {
14093 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14094 av_fetch(av,i,0)))),q);
14095 i++;
14096 }
14097 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14098 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14099 {
14100 SetPixelBlack(image,ClampToQuantum(scale*
14101 SvNV(*(av_fetch(av,i,0)))),q);
14102 i++;
14103 }
14104 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14105 (i <= av_len(av)))
14106 {
14107 SetPixelAlpha(image,ClampToQuantum(scale*
14108 SvNV(*(av_fetch(av,i,0)))),q);
14109 i++;
14110 }
14111 (void) SyncAuthenticPixels(image,exception);
14112 }
14113 (void) SetImageChannelMask(image,channel_mask);
14114
14115 PerlException:
14116 InheritPerlException(exception,perl_exception);
14117 exception=DestroyExceptionInfo(exception);
14118 SvREFCNT_dec(perl_exception);
14119 }
14120
14121#
14122###############################################################################
14123# #
14124# #
14125# #
14126# S m u s h #
14127# #
14128# #
14129# #
14130###############################################################################
14131#
14132#
14133void
14134Smush(ref,...)
14135 Image::Magick ref=NO_INIT
14136 ALIAS:
14137 SmushImage = 1
14138 smush = 2
14139 smushimage = 3
14140 PPCODE:
14141 {
14142 AV
14143 *av;
14144
14145 char
14146 *attribute;
14147
14148 ExceptionInfo
14149 *exception;
14150
14151 HV
14152 *hv;
14153
14154 Image
14155 *image;
14156
14157 register ssize_t
14158 i;
14159
14160 ssize_t
14161 offset,
14162 stack;
14163
14164 struct PackageInfo
14165 *info;
14166
14167 SV
14168 *av_reference,
14169 *perl_exception,
14170 *reference,
14171 *rv,
14172 *sv;
14173
14174 PERL_UNUSED_VAR(ref);
14175 PERL_UNUSED_VAR(ix);
14176 exception=AcquireExceptionInfo();
14177 perl_exception=newSVpv("",0);
14178 sv=NULL;
14179 attribute=NULL;
14180 av=NULL;
14181 if (sv_isobject(ST(0)) == 0)
14182 {
14183 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14184 PackageName);
14185 goto PerlException;
14186 }
14187 reference=SvRV(ST(0));
14188 hv=SvSTASH(reference);
14189 av=newAV();
14190 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14191 SvREFCNT_dec(av);
14192 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14193 if (image == (Image *) NULL)
14194 {
14195 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14196 PackageName);
14197 goto PerlException;
14198 }
14199 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14200 /*
14201 Get options.
14202 */
14203 offset=0;
14204 stack=MagickTrue;
14205 for (i=2; i < items; i+=2)
14206 {
14207 attribute=(char *) SvPV(ST(i-1),na);
14208 switch (*attribute)
14209 {
14210 case 'O':
14211 case 'o':
14212 {
14213 if (LocaleCompare(attribute,"offset") == 0)
14214 {
14215 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14216 break;
14217 }
14218 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14219 attribute);
14220 break;
14221 }
14222 case 'S':
14223 case 's':
14224 {
14225 if (LocaleCompare(attribute,"stack") == 0)
14226 {
14227 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14228 SvPV(ST(i),na));
14229 if (stack < 0)
14230 {
14231 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14232 SvPV(ST(i),na));
14233 return;
14234 }
14235 break;
14236 }
14237 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14238 attribute);
14239 break;
14240 }
14241 default:
14242 {
14243 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14244 attribute);
14245 break;
14246 }
14247 }
14248 }
14249 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14250 exception);
14251 if (image == (Image *) NULL)
14252 goto PerlException;
14253 for ( ; image; image=image->next)
14254 {
14255 AddImageToRegistry(sv,image);
14256 rv=newRV(sv);
14257 av_push(av,sv_bless(rv,hv));
14258 SvREFCNT_dec(sv);
14259 }
14260 exception=DestroyExceptionInfo(exception);
14261 ST(0)=av_reference;
14262 SvREFCNT_dec(perl_exception);
14263 XSRETURN(1);
14264
14265 PerlException:
14266 InheritPerlException(exception,perl_exception);
14267 exception=DestroyExceptionInfo(exception);
14268 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14269 SvPOK_on(perl_exception);
14270 ST(0)=sv_2mortal(perl_exception);
14271 XSRETURN(1);
14272 }
14273
14274#
14275###############################################################################
14276# #
14277# #
14278# #
14279# S t a t i s t i c s #
14280# #
14281# #
14282# #
14283###############################################################################
14284#
14285#
14286void
14287Statistics(ref,...)
14288 Image::Magick ref=NO_INIT
14289 ALIAS:
14290 StatisticsImage = 1
14291 statistics = 2
14292 statisticsimage = 3
14293 PPCODE:
14294 {
14295#define ChannelStatistics(channel) \
14296{ \
cristy151b66d2015-04-15 10:50:31 +000014297 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014298 (double) channel_statistics[channel].depth); \
14299 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014300 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014301 channel_statistics[channel].minima/scale); \
14302 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014303 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014304 channel_statistics[channel].maxima/scale); \
14305 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014306 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014307 channel_statistics[channel].mean/scale); \
14308 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014309 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014310 channel_statistics[channel].standard_deviation/scale); \
14311 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014312 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014313 channel_statistics[channel].kurtosis); \
14314 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014315 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014316 channel_statistics[channel].skewness); \
14317 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014318 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy275bdd92014-11-08 23:45:03 +000014319 channel_statistics[channel].entropy); \
14320 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014321}
14322
14323 AV
14324 *av;
14325
14326 char
cristy151b66d2015-04-15 10:50:31 +000014327 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014328
14329 ChannelStatistics
14330 *channel_statistics;
14331
14332 double
14333 scale;
14334
14335 ExceptionInfo
14336 *exception;
14337
14338 Image
14339 *image;
14340
14341 ssize_t
14342 count;
14343
14344 struct PackageInfo
14345 *info;
14346
14347 SV
14348 *perl_exception,
14349 *reference;
14350
14351 PERL_UNUSED_VAR(ref);
14352 PERL_UNUSED_VAR(ix);
14353 exception=AcquireExceptionInfo();
14354 perl_exception=newSVpv("",0);
14355 av=NULL;
14356 if (sv_isobject(ST(0)) == 0)
14357 {
14358 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14359 PackageName);
14360 goto PerlException;
14361 }
14362 reference=SvRV(ST(0));
14363 av=newAV();
14364 SvREFCNT_dec(av);
14365 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14366 if (image == (Image *) NULL)
14367 {
14368 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14369 PackageName);
14370 goto PerlException;
14371 }
cristy4a3ce0a2013-08-03 20:06:59 +000014372 count=0;
14373 for ( ; image; image=image->next)
14374 {
14375 channel_statistics=GetImageStatistics(image,exception);
14376 if (channel_statistics == (ChannelStatistics *) NULL)
14377 continue;
14378 count++;
14379 EXTEND(sp,35*count);
14380 scale=(double) QuantumRange;
14381 ChannelStatistics(RedChannel);
14382 ChannelStatistics(GreenChannel);
14383 ChannelStatistics(BlueChannel);
14384 if (image->colorspace == CMYKColorspace)
14385 ChannelStatistics(BlackChannel);
cristy17f11b02014-12-20 19:37:04 +000014386 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000014387 ChannelStatistics(AlphaChannel);
14388 channel_statistics=(ChannelStatistics *)
14389 RelinquishMagickMemory(channel_statistics);
14390 }
14391
14392 PerlException:
14393 InheritPerlException(exception,perl_exception);
14394 exception=DestroyExceptionInfo(exception);
14395 SvREFCNT_dec(perl_exception);
14396 }
14397
14398#
14399###############################################################################
14400# #
14401# #
14402# #
14403# S y n c A u t h e n t i c P i x e l s #
14404# #
14405# #
14406# #
14407###############################################################################
14408#
14409#
14410void
14411SyncAuthenticPixels(ref,...)
14412 Image::Magick ref = NO_INIT
14413 ALIAS:
14414 Syncauthenticpixels = 1
14415 SyncImagePixels = 2
14416 syncimagepixels = 3
14417 CODE:
14418 {
14419 ExceptionInfo
14420 *exception;
14421
14422 Image
14423 *image;
14424
14425 MagickBooleanType
14426 status;
14427
14428 struct PackageInfo
14429 *info;
14430
14431 SV
14432 *perl_exception,
14433 *reference;
14434
14435 PERL_UNUSED_VAR(ref);
14436 PERL_UNUSED_VAR(ix);
14437 exception=AcquireExceptionInfo();
14438 perl_exception=newSVpv("",0);
14439 if (sv_isobject(ST(0)) == 0)
14440 {
14441 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14442 PackageName);
14443 goto PerlException;
14444 }
14445
14446 reference=SvRV(ST(0));
14447 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14448 if (image == (Image *) NULL)
14449 {
14450 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14451 PackageName);
14452 goto PerlException;
14453 }
14454
14455 status=SyncAuthenticPixels(image,exception);
14456 if (status != MagickFalse)
14457 return;
14458
14459 PerlException:
14460 InheritPerlException(exception,perl_exception);
14461 exception=DestroyExceptionInfo(exception);
14462 SvREFCNT_dec(perl_exception); /* throw away all errors */
14463 }
14464
14465#
14466###############################################################################
14467# #
14468# #
14469# #
14470# T r a n s f o r m #
14471# #
14472# #
14473# #
14474###############################################################################
14475#
14476#
14477void
14478Transform(ref,...)
14479 Image::Magick ref=NO_INIT
14480 ALIAS:
14481 TransformImage = 1
14482 transform = 2
14483 transformimage = 3
14484 PPCODE:
14485 {
14486 AV
14487 *av;
14488
14489 char
14490 *attribute,
14491 *crop_geometry,
14492 *geometry;
14493
14494 ExceptionInfo
14495 *exception;
14496
14497 HV
14498 *hv;
14499
14500 Image
14501 *clone,
14502 *image;
14503
14504 register ssize_t
14505 i;
14506
14507 struct PackageInfo
14508 *info;
14509
14510 SV
14511 *av_reference,
14512 *perl_exception,
14513 *reference,
14514 *rv,
14515 *sv;
14516
14517 PERL_UNUSED_VAR(ref);
14518 PERL_UNUSED_VAR(ix);
14519 exception=AcquireExceptionInfo();
14520 perl_exception=newSVpv("",0);
14521 sv=NULL;
14522 av=NULL;
14523 attribute=NULL;
14524 if (sv_isobject(ST(0)) == 0)
14525 {
14526 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14527 PackageName);
14528 goto PerlException;
14529 }
14530 reference=SvRV(ST(0));
14531 hv=SvSTASH(reference);
14532 av=newAV();
14533 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14534 SvREFCNT_dec(av);
14535 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14536 if (image == (Image *) NULL)
14537 {
14538 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14539 PackageName);
14540 goto PerlException;
14541 }
14542 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14543 /*
14544 Get attribute.
14545 */
14546 crop_geometry=(char *) NULL;
14547 geometry=(char *) NULL;
14548 for (i=2; i < items; i+=2)
14549 {
14550 attribute=(char *) SvPV(ST(i-1),na);
14551 switch (*attribute)
14552 {
14553 case 'c':
14554 case 'C':
14555 {
14556 if (LocaleCompare(attribute,"crop") == 0)
14557 {
14558 crop_geometry=SvPV(ST(i),na);
14559 break;
14560 }
14561 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14562 attribute);
14563 break;
14564 }
14565 case 'g':
14566 case 'G':
14567 {
14568 if (LocaleCompare(attribute,"geometry") == 0)
14569 {
14570 geometry=SvPV(ST(i),na);
14571 break;
14572 }
14573 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14574 attribute);
14575 break;
14576 }
14577 default:
14578 {
14579 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14580 attribute);
14581 break;
14582 }
14583 }
14584 }
14585 for ( ; image; image=image->next)
14586 {
14587 clone=CloneImage(image,0,0,MagickTrue,exception);
14588 if (clone == (Image *) NULL)
14589 goto PerlException;
14590 TransformImage(&clone,crop_geometry,geometry,exception);
14591 for ( ; clone; clone=clone->next)
14592 {
14593 AddImageToRegistry(sv,clone);
14594 rv=newRV(sv);
14595 av_push(av,sv_bless(rv,hv));
14596 SvREFCNT_dec(sv);
14597 }
14598 }
14599 exception=DestroyExceptionInfo(exception);
14600 ST(0)=av_reference;
14601 SvREFCNT_dec(perl_exception); /* can't return warning messages */
14602 XSRETURN(1);
14603
14604 PerlException:
14605 InheritPerlException(exception,perl_exception);
14606 exception=DestroyExceptionInfo(exception);
14607 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14608 SvPOK_on(perl_exception);
14609 ST(0)=sv_2mortal(perl_exception);
14610 XSRETURN(1);
14611 }
14612
14613#
14614###############################################################################
14615# #
14616# #
14617# #
14618# W r i t e #
14619# #
14620# #
14621# #
14622###############################################################################
14623#
14624#
14625void
14626Write(ref,...)
14627 Image::Magick ref=NO_INIT
14628 ALIAS:
14629 WriteImage = 1
14630 write = 2
14631 writeimage = 3
14632 PPCODE:
14633 {
14634 char
cristy151b66d2015-04-15 10:50:31 +000014635 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014636
14637 ExceptionInfo
14638 *exception;
14639
14640 Image
14641 *image,
14642 *next;
14643
14644 register ssize_t
14645 i;
14646
14647 ssize_t
14648 number_images,
14649 scene;
14650
14651 struct PackageInfo
14652 *info,
14653 *package_info;
14654
14655 SV
14656 *perl_exception,
14657 *reference;
14658
14659 PERL_UNUSED_VAR(ref);
14660 PERL_UNUSED_VAR(ix);
14661 exception=AcquireExceptionInfo();
14662 perl_exception=newSVpv("",0);
14663 number_images=0;
14664 package_info=(struct PackageInfo *) NULL;
14665 if (sv_isobject(ST(0)) == 0)
14666 {
14667 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14668 PackageName);
14669 goto PerlException;
14670 }
14671 reference=SvRV(ST(0));
14672 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14673 if (image == (Image *) NULL)
14674 {
14675 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14676 PackageName);
14677 goto PerlException;
14678 }
14679 package_info=ClonePackageInfo(info,exception);
14680 if (items == 2)
14681 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14682 else
14683 if (items > 2)
14684 for (i=2; i < items; i+=2)
14685 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14686 exception);
14687 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014688 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014689 scene=0;
14690 for (next=image; next; next=next->next)
14691 {
cristy151b66d2015-04-15 10:50:31 +000014692 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014693 next->scene=scene++;
14694 }
cristy68bd79a2015-02-25 12:23:36 +000014695 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014696 SetImageInfo(package_info->image_info,(unsigned int)
14697 GetImageListLength(image),exception);
14698 for (next=image; next; next=next->next)
14699 {
14700 (void) WriteImage(package_info->image_info,next,exception);
14701 number_images++;
14702 if (package_info->image_info->adjoin)
14703 break;
14704 }
14705
14706 PerlException:
14707 if (package_info != (struct PackageInfo *) NULL)
14708 DestroyPackageInfo(package_info);
14709 InheritPerlException(exception,perl_exception);
14710 exception=DestroyExceptionInfo(exception);
14711 sv_setiv(perl_exception,(IV) number_images);
14712 SvPOK_on(perl_exception);
14713 ST(0)=sv_2mortal(perl_exception);
14714 XSRETURN(1);
14715 }