blob: 22524926694d7c533970abf76d544e18ec68f8d5 [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} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000563 };
564
565static SplayTreeInfo
566 *magick_registry = (SplayTreeInfo *) NULL;
567
568/*
569 Forward declarations.
570*/
571static Image
572 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
573
574static ssize_t
575 strEQcase(const char *,const char *);
576
577/*
578%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
579% %
580% %
581% %
582% C l o n e P a c k a g e I n f o %
583% %
584% %
585% %
586%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
587%
588% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
589% a new one.
590%
591% The format of the ClonePackageInfo routine is:
592%
593% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
594% exception)
595%
596% A description of each parameter follows:
597%
598% o info: a structure of type info.
599%
600% o exception: Return any errors or warnings in this structure.
601%
602*/
603static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
604 ExceptionInfo *exception)
605{
606 struct PackageInfo
607 *clone_info;
608
609 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
610 if (clone_info == (struct PackageInfo *) NULL)
611 {
612 ThrowPerlException(exception,ResourceLimitError,
613 "UnableToClonePackageInfo",PackageName);
614 return((struct PackageInfo *) NULL);
615 }
616 if (info == (struct PackageInfo *) NULL)
617 {
618 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
619 return(clone_info);
620 }
621 *clone_info=(*info);
622 clone_info->image_info=CloneImageInfo(info->image_info);
623 return(clone_info);
624}
625
626/*
627%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
628% %
629% %
630% %
631% c o n s t a n t %
632% %
633% %
634% %
635%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
636%
637% constant() returns a double value for the specified name.
638%
639% The format of the constant routine is:
640%
641% double constant(char *name,ssize_t sans)
642%
643% A description of each parameter follows:
644%
645% o value: Method constant returns a double value for the specified name.
646%
647% o name: The name of the constant.
648%
649% o sans: This integer value is not used.
650%
651*/
652static double constant(char *name,ssize_t sans)
653{
654 (void) sans;
655 errno=0;
656 switch (*name)
657 {
658 case 'B':
659 {
660 if (strEQ(name,"BlobError"))
661 return(BlobError);
662 if (strEQ(name,"BlobWarning"))
663 return(BlobWarning);
664 break;
665 }
666 case 'C':
667 {
668 if (strEQ(name,"CacheError"))
669 return(CacheError);
670 if (strEQ(name,"CacheWarning"))
671 return(CacheWarning);
672 if (strEQ(name,"CoderError"))
673 return(CoderError);
674 if (strEQ(name,"CoderWarning"))
675 return(CoderWarning);
676 if (strEQ(name,"ConfigureError"))
677 return(ConfigureError);
678 if (strEQ(name,"ConfigureWarning"))
679 return(ConfigureWarning);
680 if (strEQ(name,"CorruptImageError"))
681 return(CorruptImageError);
682 if (strEQ(name,"CorruptImageWarning"))
683 return(CorruptImageWarning);
684 break;
685 }
686 case 'D':
687 {
688 if (strEQ(name,"DelegateError"))
689 return(DelegateError);
690 if (strEQ(name,"DelegateWarning"))
691 return(DelegateWarning);
692 if (strEQ(name,"DrawError"))
693 return(DrawError);
694 if (strEQ(name,"DrawWarning"))
695 return(DrawWarning);
696 break;
697 }
698 case 'E':
699 {
700 if (strEQ(name,"ErrorException"))
701 return(ErrorException);
702 if (strEQ(name,"ExceptionError"))
703 return(CoderError);
704 if (strEQ(name,"ExceptionWarning"))
705 return(CoderWarning);
706 break;
707 }
708 case 'F':
709 {
710 if (strEQ(name,"FatalErrorException"))
711 return(FatalErrorException);
712 if (strEQ(name,"FileOpenError"))
713 return(FileOpenError);
714 if (strEQ(name,"FileOpenWarning"))
715 return(FileOpenWarning);
716 break;
717 }
718 case 'I':
719 {
720 if (strEQ(name,"ImageError"))
721 return(ImageError);
722 if (strEQ(name,"ImageWarning"))
723 return(ImageWarning);
724 break;
725 }
726 case 'M':
727 {
728 if (strEQ(name,"MaxRGB"))
729 return(QuantumRange);
730 if (strEQ(name,"MissingDelegateError"))
731 return(MissingDelegateError);
732 if (strEQ(name,"MissingDelegateWarning"))
733 return(MissingDelegateWarning);
734 if (strEQ(name,"ModuleError"))
735 return(ModuleError);
736 if (strEQ(name,"ModuleWarning"))
737 return(ModuleWarning);
738 break;
739 }
740 case 'O':
741 {
742 if (strEQ(name,"Opaque"))
743 return(OpaqueAlpha);
744 if (strEQ(name,"OptionError"))
745 return(OptionError);
746 if (strEQ(name,"OptionWarning"))
747 return(OptionWarning);
748 break;
749 }
750 case 'Q':
751 {
752 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
753 return(MAGICKCORE_QUANTUM_DEPTH);
754 if (strEQ(name,"QuantumDepth"))
755 return(MAGICKCORE_QUANTUM_DEPTH);
756 if (strEQ(name,"QuantumRange"))
757 return(QuantumRange);
758 break;
759 }
760 case 'R':
761 {
762 if (strEQ(name,"ResourceLimitError"))
763 return(ResourceLimitError);
764 if (strEQ(name,"ResourceLimitWarning"))
765 return(ResourceLimitWarning);
766 if (strEQ(name,"RegistryError"))
767 return(RegistryError);
768 if (strEQ(name,"RegistryWarning"))
769 return(RegistryWarning);
770 break;
771 }
772 case 'S':
773 {
774 if (strEQ(name,"StreamError"))
775 return(StreamError);
776 if (strEQ(name,"StreamWarning"))
777 return(StreamWarning);
778 if (strEQ(name,"Success"))
779 return(0);
780 break;
781 }
782 case 'T':
783 {
784 if (strEQ(name,"Transparent"))
785 return(TransparentAlpha);
786 if (strEQ(name,"TypeError"))
787 return(TypeError);
788 if (strEQ(name,"TypeWarning"))
789 return(TypeWarning);
790 break;
791 }
792 case 'W':
793 {
794 if (strEQ(name,"WarningException"))
795 return(WarningException);
796 break;
797 }
798 case 'X':
799 {
800 if (strEQ(name,"XServerError"))
801 return(XServerError);
802 if (strEQ(name,"XServerWarning"))
803 return(XServerWarning);
804 break;
805 }
806 }
807 errno=EINVAL;
808 return(0);
809}
810
811/*
812%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
813% %
814% %
815% %
816% D e s t r o y P a c k a g e I n f o %
817% %
818% %
819% %
820%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
821%
822% Method DestroyPackageInfo frees a previously created info structure.
823%
824% The format of the DestroyPackageInfo routine is:
825%
826% DestroyPackageInfo(struct PackageInfo *info)
827%
828% A description of each parameter follows:
829%
830% o info: a structure of type info.
831%
832*/
833static void DestroyPackageInfo(struct PackageInfo *info)
834{
835 info->image_info=DestroyImageInfo(info->image_info);
836 info=(struct PackageInfo *) RelinquishMagickMemory(info);
837}
838
839/*
840%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
841% %
842% %
843% %
844% G e t L i s t %
845% %
846% %
847% %
848%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
849%
850% Method GetList is recursively called by SetupList to traverse the
851% Image__Magick reference. If building an reference_vector (see SetupList),
852% *current is the current position in *reference_vector and *last is the final
853% entry in *reference_vector.
854%
855% The format of the GetList routine is:
856%
857% GetList(info)
858%
859% A description of each parameter follows:
860%
861% o info: a structure of type info.
862%
863*/
864static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
865 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
866{
867 Image
868 *image;
869
870 if (reference == (SV *) NULL)
871 return(NULL);
872 switch (SvTYPE(reference))
873 {
874 case SVt_PVAV:
875 {
876 AV
877 *av;
878
879 Image
880 *head,
881 *previous;
882
883 register ssize_t
884 i;
885
886 ssize_t
887 n;
888
889 /*
890 Array of images.
891 */
892 previous=(Image *) NULL;
893 head=(Image *) NULL;
894 av=(AV *) reference;
895 n=av_len(av);
896 for (i=0; i <= n; i++)
897 {
898 SV
899 **rv;
900
901 rv=av_fetch(av,i,0);
902 if (rv && *rv && sv_isobject(*rv))
903 {
904 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
905 exception);
906 if (image == (Image *) NULL)
907 continue;
908 if (image == previous)
909 {
910 image=CloneImage(image,0,0,MagickTrue,exception);
911 if (image == (Image *) NULL)
912 return(NULL);
913 }
914 image->previous=previous;
915 *(previous ? &previous->next : &head)=image;
916 for (previous=image; previous->next; previous=previous->next) ;
917 }
918 }
919 return(head);
920 }
921 case SVt_PVMG:
922 {
923 /*
924 Blessed scalar, one image.
925 */
926 image=INT2PTR(Image *,SvIV(reference));
927 if (image == (Image *) NULL)
928 return(NULL);
929 image->previous=(Image *) NULL;
930 image->next=(Image *) NULL;
931 if (reference_vector)
932 {
933 if (*current == *last)
934 {
935 *last+=256;
936 if (*reference_vector == (SV **) NULL)
937 *reference_vector=(SV **) AcquireQuantumMemory(*last,
938 sizeof(*reference_vector));
939 else
940 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
941 *last,sizeof(*reference_vector));
942 }
943 if (*reference_vector == (SV **) NULL)
944 {
945 ThrowPerlException(exception,ResourceLimitError,
946 "MemoryAllocationFailed",PackageName);
947 return((Image *) NULL);
948 }
949 (*reference_vector)[*current]=reference;
950 (*reference_vector)[++(*current)]=NULL;
951 }
952 return(image);
953 }
954 default:
955 break;
956 }
957 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
958 (double) SvTYPE(reference));
959 return((Image *) NULL);
960}
961
962/*
963%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
964% %
965% %
966% %
967% G e t P a c k a g e I n f o %
968% %
969% %
970% %
971%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
972%
973% Method GetPackageInfo looks up or creates an info structure for the given
974% Image__Magick reference. If it does create a new one, the information in
975% package_info is used to initialize it.
976%
977% The format of the GetPackageInfo routine is:
978%
979% struct PackageInfo *GetPackageInfo(void *reference,
980% struct PackageInfo *package_info,ExceptionInfo *exception)
981%
982% A description of each parameter follows:
983%
984% o info: a structure of type info.
985%
986% o exception: Return any errors or warnings in this structure.
987%
988*/
989static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
990 struct PackageInfo *package_info,ExceptionInfo *exception)
991{
992 char
cristy151b66d2015-04-15 10:50:31 +0000993 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +0000994
995 struct PackageInfo
996 *clone_info;
997
998 SV
999 *sv;
1000
cristy151b66d2015-04-15 10:50:31 +00001001 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00001002 PackageName,XS_VERSION,reference);
1003 sv=perl_get_sv(message,(TRUE | 0x02));
1004 if (sv == (SV *) NULL)
1005 {
1006 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1007 message);
1008 return(package_info);
1009 }
1010 if (SvREFCNT(sv) == 0)
1011 (void) SvREFCNT_inc(sv);
1012 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1013 return(clone_info);
1014 clone_info=ClonePackageInfo(package_info,exception);
1015 sv_setiv(sv,PTR2IV(clone_info));
1016 return(clone_info);
1017}
1018
1019/*
1020%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1021% %
1022% %
1023% %
1024% S e t A t t r i b u t e %
1025% %
1026% %
1027% %
1028%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1029%
1030% SetAttribute() sets the attribute to the value in sval. This can change
1031% either or both of image or info.
1032%
1033% The format of the SetAttribute routine is:
1034%
1035% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1036% SV *sval,ExceptionInfo *exception)
1037%
1038% A description of each parameter follows:
1039%
1040% o list: a list of strings.
1041%
1042% o string: a character string.
1043%
1044*/
1045
1046static double SiPrefixToDoubleInterval(const char *string,const double interval)
1047{
1048 char
1049 *q;
1050
1051 double
1052 value;
1053
1054 value=InterpretSiPrefixValue(string,&q);
1055 if (*q == '%')
1056 value*=interval/100.0;
1057 return(value);
1058}
1059
1060static inline double StringToDouble(const char *string,char **sentinal)
1061{
1062 return(InterpretLocaleValue(string,sentinal));
1063}
1064
1065static double StringToDoubleInterval(const char *string,const double interval)
1066{
1067 char
1068 *q;
1069
1070 double
1071 value;
1072
1073 value=InterpretLocaleValue(string,&q);
1074 if (*q == '%')
1075 value*=interval/100.0;
1076 return(value);
1077}
1078
1079static inline ssize_t StringToLong(const char *value)
1080{
1081 return(strtol(value,(char **) NULL,10));
1082}
1083
1084static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1085 const char *attribute,SV *sval,ExceptionInfo *exception)
1086{
1087 GeometryInfo
1088 geometry_info;
1089
1090 long
1091 x,
1092 y;
1093
1094 PixelInfo
1095 pixel;
1096
1097 MagickStatusType
1098 flags;
1099
1100 PixelInfo
1101 *color,
1102 target_color;
1103
1104 ssize_t
1105 sp;
1106
1107 switch (*attribute)
1108 {
1109 case 'A':
1110 case 'a':
1111 {
1112 if (LocaleCompare(attribute,"adjoin") == 0)
1113 {
1114 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1115 SvPV(sval,na)) : SvIV(sval);
1116 if (sp < 0)
1117 {
1118 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1119 SvPV(sval,na));
1120 break;
1121 }
1122 if (info)
1123 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1124 break;
1125 }
1126 if (LocaleCompare(attribute,"alpha") == 0)
1127 {
1128 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1129 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1130 if (sp < 0)
1131 {
1132 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1133 SvPV(sval,na));
1134 break;
1135 }
1136 for ( ; image; image=image->next)
1137 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1138 exception);
1139 break;
1140 }
1141 if (LocaleCompare(attribute,"antialias") == 0)
1142 {
1143 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1144 SvPV(sval,na)) : SvIV(sval);
1145 if (sp < 0)
1146 {
1147 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1148 SvPV(sval,na));
1149 break;
1150 }
1151 if (info)
1152 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1153 break;
1154 }
1155 if (LocaleCompare(attribute,"area-limit") == 0)
1156 {
1157 MagickSizeType
1158 limit;
1159
1160 limit=MagickResourceInfinity;
1161 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1162 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1163 100.0);
1164 (void) SetMagickResourceLimit(AreaResource,limit);
1165 break;
1166 }
1167 if (LocaleCompare(attribute,"attenuate") == 0)
1168 {
1169 if (info)
1170 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1171 break;
1172 }
1173 if (LocaleCompare(attribute,"authenticate") == 0)
1174 {
1175 if (info)
1176 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1177 break;
1178 }
1179 if (info)
1180 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1181 for ( ; image; image=image->next)
1182 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1183 break;
1184 }
1185 case 'B':
1186 case 'b':
1187 {
1188 if (LocaleCompare(attribute,"background") == 0)
1189 {
1190 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1191 exception);
1192 if (info)
1193 info->image_info->background_color=target_color;
1194 for ( ; image; image=image->next)
1195 image->background_color=target_color;
1196 break;
1197 }
1198 if (LocaleCompare(attribute,"blue-primary") == 0)
1199 {
1200 for ( ; image; image=image->next)
1201 {
1202 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1203 image->chromaticity.blue_primary.x=geometry_info.rho;
1204 image->chromaticity.blue_primary.y=geometry_info.sigma;
1205 if ((flags & SigmaValue) == 0)
1206 image->chromaticity.blue_primary.y=
1207 image->chromaticity.blue_primary.x;
1208 }
1209 break;
1210 }
1211 if (LocaleCompare(attribute,"bordercolor") == 0)
1212 {
1213 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1214 exception);
1215 if (info)
1216 info->image_info->border_color=target_color;
1217 for ( ; image; image=image->next)
1218 image->border_color=target_color;
1219 break;
1220 }
1221 if (info)
1222 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1223 for ( ; image; image=image->next)
1224 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1225 break;
1226 }
1227 case 'C':
1228 case 'c':
1229 {
1230 if (LocaleCompare(attribute,"cache-threshold") == 0)
1231 {
1232 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1233 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1234 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1235 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1236 break;
1237 }
1238 if (LocaleCompare(attribute,"clip-mask") == 0)
1239 {
1240 Image
1241 *clip_mask;
1242
1243 clip_mask=(Image *) NULL;
1244 if (SvPOK(sval))
1245 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1246 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001247 SetImageMask(image,ReadPixelMask,clip_mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001248 break;
1249 }
1250 if (LocaleNCompare(attribute,"colormap",8) == 0)
1251 {
1252 for ( ; image; image=image->next)
1253 {
1254 int
1255 items;
1256
1257 long
1258 i;
1259
1260 if (image->storage_class == DirectClass)
1261 continue;
1262 i=0;
1263 items=sscanf(attribute,"%*[^[][%ld",&i);
1264 (void) items;
1265 if (i > (ssize_t) image->colors)
1266 i%=image->colors;
1267 if ((strchr(SvPV(sval,na),',') == 0) ||
1268 (strchr(SvPV(sval,na),')') != 0))
1269 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1270 image->colormap+i,exception);
1271 else
1272 {
1273 color=image->colormap+i;
1274 pixel.red=color->red;
1275 pixel.green=color->green;
1276 pixel.blue=color->blue;
1277 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1278 pixel.red=geometry_info.rho;
1279 pixel.green=geometry_info.sigma;
1280 pixel.blue=geometry_info.xi;
1281 color->red=ClampToQuantum(pixel.red);
1282 color->green=ClampToQuantum(pixel.green);
1283 color->blue=ClampToQuantum(pixel.blue);
1284 }
1285 }
1286 break;
1287 }
1288 if (LocaleCompare(attribute,"colorspace") == 0)
1289 {
1290 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1291 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1292 if (sp < 0)
1293 {
1294 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1295 SvPV(sval,na));
1296 break;
1297 }
1298 for ( ; image; image=image->next)
1299 (void) TransformImageColorspace(image,(ColorspaceType) sp,
1300 exception);
1301 break;
1302 }
1303 if (LocaleCompare(attribute,"comment") == 0)
1304 {
1305 for ( ; image; image=image->next)
1306 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1307 info ? info->image_info : (ImageInfo *) NULL,image,
1308 SvPV(sval,na),exception),exception);
1309 break;
1310 }
1311 if (LocaleCompare(attribute,"compression") == 0)
1312 {
1313 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1314 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1315 if (sp < 0)
1316 {
1317 ThrowPerlException(exception,OptionError,
1318 "UnrecognizedImageCompression",SvPV(sval,na));
1319 break;
1320 }
1321 if (info)
1322 info->image_info->compression=(CompressionType) sp;
1323 for ( ; image; image=image->next)
1324 image->compression=(CompressionType) sp;
1325 break;
1326 }
1327 if (info)
1328 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1329 for ( ; image; image=image->next)
1330 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1331 break;
1332 }
1333 case 'D':
1334 case 'd':
1335 {
1336 if (LocaleCompare(attribute,"debug") == 0)
1337 {
1338 SetLogEventMask(SvPV(sval,na));
1339 break;
1340 }
1341 if (LocaleCompare(attribute,"delay") == 0)
1342 {
1343 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1344 for ( ; image; image=image->next)
1345 {
1346 image->delay=(size_t) floor(geometry_info.rho+0.5);
1347 if ((flags & SigmaValue) != 0)
1348 image->ticks_per_second=(ssize_t)
1349 floor(geometry_info.sigma+0.5);
1350 }
1351 break;
1352 }
1353 if (LocaleCompare(attribute,"disk-limit") == 0)
1354 {
1355 MagickSizeType
1356 limit;
1357
1358 limit=MagickResourceInfinity;
1359 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1360 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1361 100.0);
1362 (void) SetMagickResourceLimit(DiskResource,limit);
1363 break;
1364 }
1365 if (LocaleCompare(attribute,"density") == 0)
1366 {
1367 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1368 {
1369 ThrowPerlException(exception,OptionError,"MissingGeometry",
1370 SvPV(sval,na));
1371 break;
1372 }
1373 if (info)
1374 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1375 for ( ; image; image=image->next)
1376 {
1377 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1378 image->resolution.x=geometry_info.rho;
1379 image->resolution.y=geometry_info.sigma;
1380 if ((flags & SigmaValue) == 0)
1381 image->resolution.y=image->resolution.x;
1382 }
1383 break;
1384 }
1385 if (LocaleCompare(attribute,"depth") == 0)
1386 {
1387 if (info)
1388 info->image_info->depth=SvIV(sval);
1389 for ( ; image; image=image->next)
1390 (void) SetImageDepth(image,SvIV(sval),exception);
1391 break;
1392 }
1393 if (LocaleCompare(attribute,"dispose") == 0)
1394 {
1395 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1396 SvPV(sval,na)) : SvIV(sval);
1397 if (sp < 0)
1398 {
1399 ThrowPerlException(exception,OptionError,
1400 "UnrecognizedDisposeMethod",SvPV(sval,na));
1401 break;
1402 }
1403 for ( ; image; image=image->next)
1404 image->dispose=(DisposeType) sp;
1405 break;
1406 }
1407 if (LocaleCompare(attribute,"dither") == 0)
1408 {
1409 if (info)
1410 {
1411 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1412 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1413 if (sp < 0)
1414 {
1415 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1416 SvPV(sval,na));
1417 break;
1418 }
1419 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1420 }
1421 break;
1422 }
1423 if (LocaleCompare(attribute,"display") == 0)
1424 {
1425 display:
1426 if (info)
1427 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1428 break;
1429 }
1430 if (info)
1431 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1432 for ( ; image; image=image->next)
1433 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1434 break;
1435 }
1436 case 'E':
1437 case 'e':
1438 {
1439 if (LocaleCompare(attribute,"endian") == 0)
1440 {
1441 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1442 SvPV(sval,na)) : SvIV(sval);
1443 if (sp < 0)
1444 {
1445 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1446 SvPV(sval,na));
1447 break;
1448 }
1449 if (info)
1450 info->image_info->endian=(EndianType) sp;
1451 for ( ; image; image=image->next)
1452 image->endian=(EndianType) sp;
1453 break;
1454 }
1455 if (LocaleCompare(attribute,"extract") == 0)
1456 {
1457 /*
1458 Set image extract geometry.
1459 */
1460 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1461 break;
1462 }
1463 if (info)
1464 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1465 for ( ; image; image=image->next)
1466 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1467 break;
1468 }
1469 case 'F':
1470 case 'f':
1471 {
1472 if (LocaleCompare(attribute,"filename") == 0)
1473 {
1474 if (info)
1475 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001476 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001477 for ( ; image; image=image->next)
1478 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001479 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001480 break;
1481 }
1482 if (LocaleCompare(attribute,"file") == 0)
1483 {
1484 FILE
1485 *file;
1486
1487 PerlIO
1488 *io_info;
1489
1490 if (info == (struct PackageInfo *) NULL)
1491 break;
1492 io_info=IoIFP(sv_2io(sval));
1493 if (io_info == (PerlIO *) NULL)
1494 {
1495 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1496 PackageName);
1497 break;
1498 }
1499 file=PerlIO_findFILE(io_info);
1500 if (file == (FILE *) NULL)
1501 {
1502 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1503 PackageName);
1504 break;
1505 }
1506 SetImageInfoFile(info->image_info,file);
1507 break;
1508 }
1509 if (LocaleCompare(attribute,"fill") == 0)
1510 {
1511 if (info)
1512 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1513 break;
1514 }
1515 if (LocaleCompare(attribute,"font") == 0)
1516 {
1517 if (info)
1518 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1519 break;
1520 }
1521 if (LocaleCompare(attribute,"foreground") == 0)
1522 break;
1523 if (LocaleCompare(attribute,"fuzz") == 0)
1524 {
1525 if (info)
1526 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1527 QuantumRange+1.0);
1528 for ( ; image; image=image->next)
1529 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1530 QuantumRange+1.0);
1531 break;
1532 }
1533 if (info)
1534 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1535 for ( ; image; image=image->next)
1536 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1537 break;
1538 }
1539 case 'G':
1540 case 'g':
1541 {
1542 if (LocaleCompare(attribute,"gamma") == 0)
1543 {
1544 for ( ; image; image=image->next)
1545 image->gamma=SvNV(sval);
1546 break;
1547 }
1548 if (LocaleCompare(attribute,"gravity") == 0)
1549 {
1550 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1551 SvPV(sval,na)) : SvIV(sval);
1552 if (sp < 0)
1553 {
1554 ThrowPerlException(exception,OptionError,
1555 "UnrecognizedGravityType",SvPV(sval,na));
1556 break;
1557 }
1558 if (info)
1559 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1560 for ( ; image; image=image->next)
1561 image->gravity=(GravityType) sp;
1562 break;
1563 }
1564 if (LocaleCompare(attribute,"green-primary") == 0)
1565 {
1566 for ( ; image; image=image->next)
1567 {
1568 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1569 image->chromaticity.green_primary.x=geometry_info.rho;
1570 image->chromaticity.green_primary.y=geometry_info.sigma;
1571 if ((flags & SigmaValue) == 0)
1572 image->chromaticity.green_primary.y=
1573 image->chromaticity.green_primary.x;
1574 }
1575 break;
1576 }
1577 if (info)
1578 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1579 for ( ; image; image=image->next)
1580 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1581 break;
1582 }
1583 case 'I':
1584 case 'i':
1585 {
1586 if (LocaleNCompare(attribute,"index",5) == 0)
1587 {
1588 int
1589 items;
1590
1591 long
1592 index;
1593
1594 register Quantum
1595 *q;
1596
1597 CacheView
1598 *image_view;
1599
1600 for ( ; image; image=image->next)
1601 {
1602 if (image->storage_class != PseudoClass)
1603 continue;
1604 x=0;
1605 y=0;
1606 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1607 (void) items;
1608 image_view=AcquireAuthenticCacheView(image,exception);
1609 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1610 if (q != (Quantum *) NULL)
1611 {
1612 items=sscanf(SvPV(sval,na),"%ld",&index);
1613 if ((index >= 0) && (index < (ssize_t) image->colors))
1614 SetPixelIndex(image,index,q);
1615 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1616 }
1617 image_view=DestroyCacheView(image_view);
1618 }
1619 break;
1620 }
1621 if (LocaleCompare(attribute,"iterations") == 0)
1622 {
1623 iterations:
1624 for ( ; image; image=image->next)
1625 image->iterations=SvIV(sval);
1626 break;
1627 }
1628 if (LocaleCompare(attribute,"interlace") == 0)
1629 {
1630 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1631 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1632 if (sp < 0)
1633 {
1634 ThrowPerlException(exception,OptionError,
1635 "UnrecognizedInterlaceType",SvPV(sval,na));
1636 break;
1637 }
1638 if (info)
1639 info->image_info->interlace=(InterlaceType) sp;
1640 for ( ; image; image=image->next)
1641 image->interlace=(InterlaceType) sp;
1642 break;
1643 }
1644 if (info)
1645 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1646 for ( ; image; image=image->next)
1647 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1648 break;
1649 }
1650 case 'L':
1651 case 'l':
1652 {
1653 if (LocaleCompare(attribute,"label") == 0)
1654 {
1655 for ( ; image; image=image->next)
1656 (void) SetImageProperty(image,"label",InterpretImageProperties(
1657 info ? info->image_info : (ImageInfo *) NULL,image,
1658 SvPV(sval,na),exception),exception);
1659 break;
1660 }
1661 if (LocaleCompare(attribute,"loop") == 0)
1662 goto iterations;
1663 if (info)
1664 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1665 for ( ; image; image=image->next)
1666 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1667 break;
1668 }
1669 case 'M':
1670 case 'm':
1671 {
1672 if (LocaleCompare(attribute,"magick") == 0)
1673 {
1674 if (info)
cristy151b66d2015-04-15 10:50:31 +00001675 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00001676 "%s:",SvPV(sval,na));
1677 for ( ; image; image=image->next)
cristy151b66d2015-04-15 10:50:31 +00001678 (void) CopyMagickString(image->magick,SvPV(sval,na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001679 break;
1680 }
1681 if (LocaleCompare(attribute,"map-limit") == 0)
1682 {
1683 MagickSizeType
1684 limit;
1685
1686 limit=MagickResourceInfinity;
1687 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1688 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1689 100.0);
1690 (void) SetMagickResourceLimit(MapResource,limit);
1691 break;
1692 }
1693 if (LocaleCompare(attribute,"mask") == 0)
1694 {
1695 Image
1696 *mask;
1697
1698 mask=(Image *) NULL;
1699 if (SvPOK(sval))
1700 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1701 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001702 SetImageMask(image,ReadPixelMask,mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001703 break;
1704 }
1705 if (LocaleCompare(attribute,"mattecolor") == 0)
1706 {
1707 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1708 exception);
1709 if (info)
Cristy8645e042016-02-03 16:35:29 -05001710 info->image_info->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001711 for ( ; image; image=image->next)
Cristy8645e042016-02-03 16:35:29 -05001712 image->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001713 break;
1714 }
1715 if (LocaleCompare(attribute,"matte") == 0)
1716 {
1717 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1718 SvPV(sval,na)) : SvIV(sval);
1719 if (sp < 0)
1720 {
1721 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1722 SvPV(sval,na));
1723 break;
1724 }
1725 for ( ; image; image=image->next)
1726 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1727 break;
1728 }
1729 if (LocaleCompare(attribute,"memory-limit") == 0)
1730 {
1731 MagickSizeType
1732 limit;
1733
1734 limit=MagickResourceInfinity;
1735 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1736 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1737 100.0);
1738 (void) SetMagickResourceLimit(MemoryResource,limit);
1739 break;
1740 }
1741 if (LocaleCompare(attribute,"monochrome") == 0)
1742 {
1743 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1744 SvPV(sval,na)) : SvIV(sval);
1745 if (sp < 0)
1746 {
1747 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1748 SvPV(sval,na));
1749 break;
1750 }
1751 if (info)
1752 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1753 for ( ; image; image=image->next)
1754 (void) SetImageType(image,BilevelType,exception);
1755 break;
1756 }
1757 if (info)
1758 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1759 for ( ; image; image=image->next)
1760 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1761 break;
1762 }
1763 case 'O':
1764 case 'o':
1765 {
1766 if (LocaleCompare(attribute,"option") == 0)
1767 {
1768 if (info)
1769 DefineImageOption(info->image_info,SvPV(sval,na));
1770 break;
1771 }
1772 if (LocaleCompare(attribute,"orientation") == 0)
1773 {
1774 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1775 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1776 if (sp < 0)
1777 {
1778 ThrowPerlException(exception,OptionError,
1779 "UnrecognizedOrientationType",SvPV(sval,na));
1780 break;
1781 }
1782 if (info)
1783 info->image_info->orientation=(OrientationType) sp;
1784 for ( ; image; image=image->next)
1785 image->orientation=(OrientationType) sp;
1786 break;
1787 }
1788 if (info)
1789 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1790 for ( ; image; image=image->next)
1791 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1792 break;
1793 }
1794 case 'P':
1795 case 'p':
1796 {
1797 if (LocaleCompare(attribute,"page") == 0)
1798 {
1799 char
1800 *geometry;
1801
1802 geometry=GetPageGeometry(SvPV(sval,na));
1803 if (info)
1804 (void) CloneString(&info->image_info->page,geometry);
1805 for ( ; image; image=image->next)
1806 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1807 geometry=(char *) RelinquishMagickMemory(geometry);
1808 break;
1809 }
1810 if (LocaleNCompare(attribute,"pixel",5) == 0)
1811 {
1812 int
1813 items;
1814
1815 PixelInfo
1816 pixel;
1817
1818 register Quantum
1819 *q;
1820
1821 CacheView
1822 *image_view;
1823
1824 for ( ; image; image=image->next)
1825 {
1826 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1827 break;
1828 x=0;
1829 y=0;
1830 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1831 (void) items;
1832 image_view=AcquireVirtualCacheView(image,exception);
1833 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1834 if (q != (Quantum *) NULL)
1835 {
1836 if ((strchr(SvPV(sval,na),',') == 0) ||
1837 (strchr(SvPV(sval,na),')') != 0))
1838 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1839 &pixel,exception);
1840 else
1841 {
1842 GetPixelInfo(image,&pixel);
1843 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1844 pixel.red=geometry_info.rho;
1845 if ((flags & SigmaValue) != 0)
1846 pixel.green=geometry_info.sigma;
1847 if ((flags & XiValue) != 0)
1848 pixel.blue=geometry_info.xi;
1849 if ((flags & PsiValue) != 0)
1850 pixel.alpha=geometry_info.psi;
1851 if ((flags & ChiValue) != 0)
1852 pixel.black=geometry_info.chi;
1853 }
1854 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1855 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1856 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1857 if (image->colorspace == CMYKColorspace)
1858 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1859 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1860 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1861 }
1862 image_view=DestroyCacheView(image_view);
1863 }
1864 break;
1865 }
1866 if (LocaleCompare(attribute,"pointsize") == 0)
1867 {
1868 if (info)
1869 {
1870 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1871 info->image_info->pointsize=geometry_info.rho;
1872 }
1873 break;
1874 }
1875 if (LocaleCompare(attribute,"preview") == 0)
1876 {
1877 sp=SvPOK(sval) ? ParseCommandOption(MagickPreviewOptions,MagickFalse,
1878 SvPV(sval,na)) : SvIV(sval);
1879 if (sp < 0)
1880 {
1881 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1882 SvPV(sval,na));
1883 break;
1884 }
1885 if (info)
1886 info->image_info->preview_type=(PreviewType) sp;
1887 break;
1888 }
1889 if (info)
1890 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1891 for ( ; image; image=image->next)
1892 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1893 break;
1894 }
1895 case 'Q':
1896 case 'q':
1897 {
1898 if (LocaleCompare(attribute,"quality") == 0)
1899 {
1900 if (info)
1901 info->image_info->quality=SvIV(sval);
1902 for ( ; image; image=image->next)
1903 image->quality=SvIV(sval);
1904 break;
1905 }
1906 if (info)
1907 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1908 for ( ; image; image=image->next)
1909 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1910 break;
1911 }
1912 case 'R':
1913 case 'r':
1914 {
cristyc0fe4752015-07-27 18:02:39 +00001915 if (LocaleCompare(attribute,"read-mask") == 0)
1916 {
1917 Image
1918 *mask;
1919
1920 mask=(Image *) NULL;
1921 if (SvPOK(sval))
1922 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1923 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001924 SetImageMask(image,ReadPixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00001925 break;
1926 }
cristy4a3ce0a2013-08-03 20:06:59 +00001927 if (LocaleCompare(attribute,"red-primary") == 0)
1928 {
1929 for ( ; image; image=image->next)
1930 {
1931 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1932 image->chromaticity.red_primary.x=geometry_info.rho;
1933 image->chromaticity.red_primary.y=geometry_info.sigma;
1934 if ((flags & SigmaValue) == 0)
1935 image->chromaticity.red_primary.y=
1936 image->chromaticity.red_primary.x;
1937 }
1938 break;
1939 }
1940 if (LocaleCompare(attribute,"render") == 0)
1941 {
1942 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1943 SvPV(sval,na)) : SvIV(sval);
1944 if (sp < 0)
1945 {
1946 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1947 SvPV(sval,na));
1948 break;
1949 }
1950 for ( ; image; image=image->next)
1951 image->rendering_intent=(RenderingIntent) sp;
1952 break;
1953 }
1954 if (LocaleCompare(attribute,"repage") == 0)
1955 {
1956 RectangleInfo
1957 geometry;
1958
1959 for ( ; image; image=image->next)
1960 {
1961 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1962 if ((flags & WidthValue) != 0)
1963 {
1964 if ((flags & HeightValue) == 0)
1965 geometry.height=geometry.width;
1966 image->page.width=geometry.width;
1967 image->page.height=geometry.height;
1968 }
1969 if ((flags & AspectValue) != 0)
1970 {
1971 if ((flags & XValue) != 0)
1972 image->page.x+=geometry.x;
1973 if ((flags & YValue) != 0)
1974 image->page.y+=geometry.y;
1975 }
1976 else
1977 {
1978 if ((flags & XValue) != 0)
1979 {
1980 image->page.x=geometry.x;
1981 if (((flags & WidthValue) != 0) && (geometry.x > 0))
1982 image->page.width=image->columns+geometry.x;
1983 }
1984 if ((flags & YValue) != 0)
1985 {
1986 image->page.y=geometry.y;
1987 if (((flags & HeightValue) != 0) && (geometry.y > 0))
1988 image->page.height=image->rows+geometry.y;
1989 }
1990 }
1991 }
1992 break;
1993 }
1994 if (info)
1995 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1996 for ( ; image; image=image->next)
1997 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1998 break;
1999 }
2000 case 'S':
2001 case 's':
2002 {
2003 if (LocaleCompare(attribute,"sampling-factor") == 0)
2004 {
2005 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2006 {
2007 ThrowPerlException(exception,OptionError,"MissingGeometry",
2008 SvPV(sval,na));
2009 break;
2010 }
2011 if (info)
2012 (void) CloneString(&info->image_info->sampling_factor,
2013 SvPV(sval,na));
2014 break;
2015 }
2016 if (LocaleCompare(attribute,"scene") == 0)
2017 {
2018 for ( ; image; image=image->next)
2019 image->scene=SvIV(sval);
2020 break;
2021 }
2022 if (LocaleCompare(attribute,"server") == 0)
2023 goto display;
2024 if (LocaleCompare(attribute,"size") == 0)
2025 {
2026 if (info)
2027 {
2028 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2029 {
2030 ThrowPerlException(exception,OptionError,"MissingGeometry",
2031 SvPV(sval,na));
2032 break;
2033 }
2034 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2035 }
2036 break;
2037 }
2038 if (LocaleCompare(attribute,"stroke") == 0)
2039 {
2040 if (info)
2041 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2042 break;
2043 }
2044 if (info)
2045 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2046 for ( ; image; image=image->next)
2047 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2048 break;
2049 }
2050 case 'T':
2051 case 't':
2052 {
2053 if (LocaleCompare(attribute,"texture") == 0)
2054 {
2055 if (info)
2056 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2057 break;
2058 }
2059 if (LocaleCompare(attribute,"thread-limit") == 0)
2060 {
2061 MagickSizeType
2062 limit;
2063
2064 limit=MagickResourceInfinity;
2065 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2066 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2067 100.0);
2068 (void) SetMagickResourceLimit(ThreadResource,limit);
2069 break;
2070 }
2071 if (LocaleCompare(attribute,"tile-offset") == 0)
2072 {
2073 char
2074 *geometry;
2075
2076 geometry=GetPageGeometry(SvPV(sval,na));
2077 if (info)
2078 (void) CloneString(&info->image_info->page,geometry);
2079 for ( ; image; image=image->next)
2080 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2081 exception);
2082 geometry=(char *) RelinquishMagickMemory(geometry);
2083 break;
2084 }
2085 if (LocaleCompare(attribute,"time-limit") == 0)
2086 {
2087 MagickSizeType
2088 limit;
2089
2090 limit=MagickResourceInfinity;
2091 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2092 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2093 100.0);
2094 (void) SetMagickResourceLimit(TimeResource,limit);
2095 break;
2096 }
2097 if (LocaleCompare(attribute,"transparent-color") == 0)
2098 {
2099 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2100 exception);
2101 if (info)
2102 info->image_info->transparent_color=target_color;
2103 for ( ; image; image=image->next)
2104 image->transparent_color=target_color;
2105 break;
2106 }
2107 if (LocaleCompare(attribute,"type") == 0)
2108 {
2109 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2110 SvPV(sval,na)) : SvIV(sval);
2111 if (sp < 0)
2112 {
2113 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2114 SvPV(sval,na));
2115 break;
2116 }
2117 if (info)
2118 info->image_info->type=(ImageType) sp;
2119 for ( ; image; image=image->next)
2120 SetImageType(image,(ImageType) sp,exception);
2121 break;
2122 }
2123 if (info)
2124 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2125 for ( ; image; image=image->next)
2126 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2127 break;
2128 }
2129 case 'U':
2130 case 'u':
2131 {
2132 if (LocaleCompare(attribute,"units") == 0)
2133 {
2134 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2135 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2136 if (sp < 0)
2137 {
2138 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2139 SvPV(sval,na));
2140 break;
2141 }
2142 if (info)
2143 info->image_info->units=(ResolutionType) sp;
2144 for ( ; image; image=image->next)
2145 {
2146 ResolutionType
2147 units;
2148
2149 units=(ResolutionType) sp;
2150 if (image->units != units)
2151 switch (image->units)
2152 {
2153 case UndefinedResolution:
2154 case PixelsPerInchResolution:
2155 {
2156 if (units == PixelsPerCentimeterResolution)
2157 {
2158 image->resolution.x*=2.54;
2159 image->resolution.y*=2.54;
2160 }
2161 break;
2162 }
2163 case PixelsPerCentimeterResolution:
2164 {
2165 if (units == PixelsPerInchResolution)
2166 {
2167 image->resolution.x/=2.54;
2168 image->resolution.y/=2.54;
2169 }
2170 break;
2171 }
2172 }
2173 image->units=units;
2174 }
2175 break;
2176 }
2177 if (info)
2178 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2179 for ( ; image; image=image->next)
2180 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2181 break;
2182 }
2183 case 'V':
2184 case 'v':
2185 {
2186 if (LocaleCompare(attribute,"verbose") == 0)
2187 {
2188 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2189 SvPV(sval,na)) : SvIV(sval);
2190 if (sp < 0)
2191 {
2192 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2193 SvPV(sval,na));
2194 break;
2195 }
2196 if (info)
2197 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2198 break;
2199 }
cristy4a3ce0a2013-08-03 20:06:59 +00002200 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2201 {
2202 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2203 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2204 if (sp < 0)
2205 {
2206 ThrowPerlException(exception,OptionError,
2207 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2208 break;
2209 }
2210 for ( ; image; image=image->next)
2211 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2212 break;
2213 }
2214 if (info)
2215 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2216 for ( ; image; image=image->next)
2217 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2218 break;
2219 }
2220 case 'W':
2221 case 'w':
2222 {
2223 if (LocaleCompare(attribute,"white-point") == 0)
2224 {
2225 for ( ; image; image=image->next)
2226 {
2227 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2228 image->chromaticity.white_point.x=geometry_info.rho;
2229 image->chromaticity.white_point.y=geometry_info.sigma;
2230 if ((flags & SigmaValue) == 0)
2231 image->chromaticity.white_point.y=
2232 image->chromaticity.white_point.x;
2233 }
2234 break;
2235 }
cristyc0fe4752015-07-27 18:02:39 +00002236 if (LocaleCompare(attribute,"write-mask") == 0)
2237 {
2238 Image
2239 *mask;
2240
2241 mask=(Image *) NULL;
2242 if (SvPOK(sval))
2243 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2244 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002245 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002246 break;
2247 }
cristy4a3ce0a2013-08-03 20:06:59 +00002248 if (info)
2249 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2250 for ( ; image; image=image->next)
2251 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2252 break;
2253 }
2254 default:
2255 {
2256 if (info)
2257 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2258 for ( ; image; image=image->next)
2259 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2260 break;
2261 }
2262 }
2263}
2264
2265/*
2266%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2267% %
2268% %
2269% %
2270% S e t u p L i s t %
2271% %
2272% %
2273% %
2274%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2275%
2276% Method SetupList returns the list of all the images linked by their
2277% image->next and image->previous link lists for use with ImageMagick. If
2278% info is non-NULL, an info structure is returned in *info. If
2279% reference_vector is non-NULL,an array of SV* are returned in
2280% *reference_vector. Reference_vector is used when the images are going to be
2281% replaced with new Image*'s.
2282%
2283% The format of the SetupList routine is:
2284%
2285% Image *SetupList(SV *reference,struct PackageInfo **info,
2286% SV ***reference_vector,ExceptionInfo *exception)
2287%
2288% A description of each parameter follows:
2289%
2290% o list: a list of strings.
2291%
2292% o string: a character string.
2293%
2294% o exception: Return any errors or warnings in this structure.
2295%
2296*/
2297static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2298 SV ***reference_vector,ExceptionInfo *exception)
2299{
2300 Image
2301 *image;
2302
2303 ssize_t
2304 current,
2305 last;
2306
2307 if (reference_vector)
2308 *reference_vector=NULL;
2309 if (info)
2310 *info=NULL;
2311 current=0;
2312 last=0;
2313 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2314 if (info && (SvTYPE(reference) == SVt_PVAV))
2315 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2316 exception);
2317 return(image);
2318}
2319
2320/*
2321%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2322% %
2323% %
2324% %
2325% s t r E Q c a s e %
2326% %
2327% %
2328% %
2329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2330%
2331% strEQcase() compares two strings and returns 0 if they are the
2332% same or if the second string runs out first. The comparison is case
2333% insensitive.
2334%
2335% The format of the strEQcase routine is:
2336%
2337% ssize_t strEQcase(const char *p,const char *q)
2338%
2339% A description of each parameter follows:
2340%
2341% o p: a character string.
2342%
2343% o q: a character string.
2344%
2345%
2346*/
2347static ssize_t strEQcase(const char *p,const char *q)
2348{
2349 char
2350 c;
2351
2352 register ssize_t
2353 i;
2354
2355 for (i=0 ; (c=(*q)) != 0; i++)
2356 {
2357 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2358 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2359 return(0);
2360 p++;
2361 q++;
2362 }
2363 return(((*q == 0) && (*p == 0)) ? i : 0);
2364}
2365
2366/*
2367%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2368% %
2369% %
2370% %
2371% I m a g e : : M a g i c k %
2372% %
2373% %
2374% %
2375%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2376%
2377%
2378*/
2379MODULE = Image::Magick PACKAGE = Image::Magick
2380
2381PROTOTYPES: ENABLE
2382
2383BOOT:
2384 MagickCoreGenesis("PerlMagick",MagickFalse);
2385 SetWarningHandler(NULL);
2386 SetErrorHandler(NULL);
2387 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2388 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2389
2390void
2391UNLOAD()
2392 PPCODE:
2393 {
2394 if (magick_registry != (SplayTreeInfo *) NULL)
2395 magick_registry=DestroySplayTree(magick_registry);
2396 MagickCoreTerminus();
2397 }
2398
2399double
2400constant(name,argument)
2401 char *name
2402 ssize_t argument
2403
2404#
2405###############################################################################
2406# #
2407# #
2408# #
2409# A n i m a t e #
2410# #
2411# #
2412# #
2413###############################################################################
2414#
2415#
2416void
2417Animate(ref,...)
2418 Image::Magick ref=NO_INIT
2419 ALIAS:
2420 AnimateImage = 1
2421 animate = 2
2422 animateimage = 3
2423 PPCODE:
2424 {
2425 ExceptionInfo
2426 *exception;
2427
2428 Image
2429 *image;
2430
2431 register ssize_t
2432 i;
2433
2434 struct PackageInfo
2435 *info,
2436 *package_info;
2437
2438 SV
2439 *perl_exception,
2440 *reference;
2441
2442 PERL_UNUSED_VAR(ref);
2443 PERL_UNUSED_VAR(ix);
2444 exception=AcquireExceptionInfo();
2445 perl_exception=newSVpv("",0);
2446 package_info=(struct PackageInfo *) NULL;
2447 if (sv_isobject(ST(0)) == 0)
2448 {
2449 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2450 PackageName);
2451 goto PerlException;
2452 }
2453 reference=SvRV(ST(0));
2454 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2455 if (image == (Image *) NULL)
2456 {
2457 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2458 PackageName);
2459 goto PerlException;
2460 }
2461 package_info=ClonePackageInfo(info,exception);
2462 if (items == 2)
2463 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2464 else
2465 if (items > 2)
2466 for (i=2; i < items; i+=2)
2467 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2468 exception);
2469 (void) AnimateImages(package_info->image_info,image,exception);
2470 (void) CatchImageException(image);
2471
2472 PerlException:
2473 if (package_info != (struct PackageInfo *) NULL)
2474 DestroyPackageInfo(package_info);
2475 InheritPerlException(exception,perl_exception);
2476 exception=DestroyExceptionInfo(exception);
2477 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2478 SvPOK_on(perl_exception);
2479 ST(0)=sv_2mortal(perl_exception);
2480 XSRETURN(1);
2481 }
2482
2483#
2484###############################################################################
2485# #
2486# #
2487# #
2488# A p p e n d #
2489# #
2490# #
2491# #
2492###############################################################################
2493#
2494#
2495void
2496Append(ref,...)
2497 Image::Magick ref=NO_INIT
2498 ALIAS:
2499 AppendImage = 1
2500 append = 2
2501 appendimage = 3
2502 PPCODE:
2503 {
2504 AV
2505 *av;
2506
2507 char
2508 *attribute;
2509
2510 ExceptionInfo
2511 *exception;
2512
2513 HV
2514 *hv;
2515
2516 Image
2517 *image;
2518
2519 register ssize_t
2520 i;
2521
2522 ssize_t
2523 stack;
2524
2525 struct PackageInfo
2526 *info;
2527
2528 SV
2529 *av_reference,
2530 *perl_exception,
2531 *reference,
2532 *rv,
2533 *sv;
2534
2535 PERL_UNUSED_VAR(ref);
2536 PERL_UNUSED_VAR(ix);
2537 exception=AcquireExceptionInfo();
2538 perl_exception=newSVpv("",0);
2539 sv=NULL;
2540 attribute=NULL;
2541 av=NULL;
2542 if (sv_isobject(ST(0)) == 0)
2543 {
2544 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2545 PackageName);
2546 goto PerlException;
2547 }
2548 reference=SvRV(ST(0));
2549 hv=SvSTASH(reference);
2550 av=newAV();
2551 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2552 SvREFCNT_dec(av);
2553 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2554 if (image == (Image *) NULL)
2555 {
2556 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2557 PackageName);
2558 goto PerlException;
2559 }
2560 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2561 /*
2562 Get options.
2563 */
2564 stack=MagickTrue;
2565 for (i=2; i < items; i+=2)
2566 {
2567 attribute=(char *) SvPV(ST(i-1),na);
2568 switch (*attribute)
2569 {
2570 case 'S':
2571 case 's':
2572 {
2573 if (LocaleCompare(attribute,"stack") == 0)
2574 {
2575 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2576 SvPV(ST(i),na));
2577 if (stack < 0)
2578 {
2579 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2580 SvPV(ST(i),na));
2581 return;
2582 }
2583 break;
2584 }
2585 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2586 attribute);
2587 break;
2588 }
2589 default:
2590 {
2591 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2592 attribute);
2593 break;
2594 }
2595 }
2596 }
2597 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2598 if (image == (Image *) NULL)
2599 goto PerlException;
2600 for ( ; image; image=image->next)
2601 {
2602 AddImageToRegistry(sv,image);
2603 rv=newRV(sv);
2604 av_push(av,sv_bless(rv,hv));
2605 SvREFCNT_dec(sv);
2606 }
2607 exception=DestroyExceptionInfo(exception);
2608 ST(0)=av_reference;
2609 SvREFCNT_dec(perl_exception);
2610 XSRETURN(1);
2611
2612 PerlException:
2613 InheritPerlException(exception,perl_exception);
2614 exception=DestroyExceptionInfo(exception);
2615 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2616 SvPOK_on(perl_exception);
2617 ST(0)=sv_2mortal(perl_exception);
2618 XSRETURN(1);
2619 }
2620
2621#
2622###############################################################################
2623# #
2624# #
2625# #
2626# A v e r a g e #
2627# #
2628# #
2629# #
2630###############################################################################
2631#
2632#
2633void
2634Average(ref)
2635 Image::Magick ref=NO_INIT
2636 ALIAS:
2637 AverageImage = 1
2638 average = 2
2639 averageimage = 3
2640 PPCODE:
2641 {
2642 AV
2643 *av;
2644
2645 char
2646 *p;
2647
2648 ExceptionInfo
2649 *exception;
2650
2651 HV
2652 *hv;
2653
2654 Image
2655 *image;
2656
2657 struct PackageInfo
2658 *info;
2659
2660 SV
2661 *perl_exception,
2662 *reference,
2663 *rv,
2664 *sv;
2665
2666 PERL_UNUSED_VAR(ref);
2667 PERL_UNUSED_VAR(ix);
2668 exception=AcquireExceptionInfo();
2669 perl_exception=newSVpv("",0);
2670 sv=NULL;
2671 if (sv_isobject(ST(0)) == 0)
2672 {
2673 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2674 PackageName);
2675 goto PerlException;
2676 }
2677 reference=SvRV(ST(0));
2678 hv=SvSTASH(reference);
2679 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2680 if (image == (Image *) NULL)
2681 {
2682 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2683 PackageName);
2684 goto PerlException;
2685 }
2686 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2687 if (image == (Image *) NULL)
2688 goto PerlException;
2689 /*
2690 Create blessed Perl array for the returned image.
2691 */
2692 av=newAV();
2693 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2694 SvREFCNT_dec(av);
2695 AddImageToRegistry(sv,image);
2696 rv=newRV(sv);
2697 av_push(av,sv_bless(rv,hv));
2698 SvREFCNT_dec(sv);
2699 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002700 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2701 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002702 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2703 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002704 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002705 SetImageInfo(info->image_info,0,exception);
2706 exception=DestroyExceptionInfo(exception);
2707 SvREFCNT_dec(perl_exception);
2708 XSRETURN(1);
2709
2710 PerlException:
2711 InheritPerlException(exception,perl_exception);
2712 exception=DestroyExceptionInfo(exception);
2713 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2714 SvPOK_on(perl_exception);
2715 ST(0)=sv_2mortal(perl_exception);
2716 XSRETURN(1);
2717 }
2718
2719#
2720###############################################################################
2721# #
2722# #
2723# #
2724# B l o b T o I m a g e #
2725# #
2726# #
2727# #
2728###############################################################################
2729#
2730#
2731void
2732BlobToImage(ref,...)
2733 Image::Magick ref=NO_INIT
2734 ALIAS:
2735 BlobToImage = 1
2736 blobtoimage = 2
2737 blobto = 3
2738 PPCODE:
2739 {
2740 AV
2741 *av;
2742
2743 char
2744 **keep,
2745 **list;
2746
2747 ExceptionInfo
2748 *exception;
2749
2750 HV
2751 *hv;
2752
2753 Image
2754 *image;
2755
2756 register char
2757 **p;
2758
2759 register ssize_t
2760 i;
2761
2762 ssize_t
2763 ac,
2764 n,
2765 number_images;
2766
2767 STRLEN
2768 *length;
2769
2770 struct PackageInfo
2771 *info;
2772
2773 SV
2774 *perl_exception,
2775 *reference,
2776 *rv,
2777 *sv;
2778
2779 PERL_UNUSED_VAR(ref);
2780 PERL_UNUSED_VAR(ix);
2781 exception=AcquireExceptionInfo();
2782 perl_exception=newSVpv("",0);
2783 sv=NULL;
2784 number_images=0;
2785 ac=(items < 2) ? 1 : items-1;
2786 length=(STRLEN *) NULL;
2787 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2788 if (list == (char **) NULL)
2789 {
2790 ThrowPerlException(exception,ResourceLimitError,
2791 "MemoryAllocationFailed",PackageName);
2792 goto PerlException;
2793 }
2794 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2795 if (length == (STRLEN *) NULL)
2796 {
2797 ThrowPerlException(exception,ResourceLimitError,
2798 "MemoryAllocationFailed",PackageName);
2799 goto PerlException;
2800 }
2801 if (sv_isobject(ST(0)) == 0)
2802 {
2803 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2804 PackageName);
2805 goto PerlException;
2806 }
2807 reference=SvRV(ST(0));
2808 hv=SvSTASH(reference);
2809 if (SvTYPE(reference) != SVt_PVAV)
2810 {
2811 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2812 PackageName);
2813 goto PerlException;
2814 }
2815 av=(AV *) reference;
2816 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2817 exception);
2818 n=1;
2819 if (items <= 1)
2820 {
2821 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2822 goto PerlException;
2823 }
2824 for (n=0, i=0; i < ac; i++)
2825 {
2826 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2827 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2828 {
2829 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2830 continue;
2831 }
2832 n++;
2833 }
2834 list[n]=(char *) NULL;
2835 keep=list;
2836 for (i=number_images=0; i < n; i++)
2837 {
2838 image=BlobToImage(info->image_info,list[i],length[i],exception);
2839 if (image == (Image *) NULL)
2840 break;
2841 for ( ; image; image=image->next)
2842 {
2843 AddImageToRegistry(sv,image);
2844 rv=newRV(sv);
2845 av_push(av,sv_bless(rv,hv));
2846 SvREFCNT_dec(sv);
2847 number_images++;
2848 }
2849 }
2850 /*
2851 Free resources.
2852 */
2853 for (i=0; i < n; i++)
2854 if (list[i] != (char *) NULL)
2855 for (p=keep; list[i] != *p++; )
2856 if (*p == (char *) NULL)
2857 {
2858 list[i]=(char *) RelinquishMagickMemory(list[i]);
2859 break;
2860 }
2861
2862 PerlException:
2863 if (list)
2864 list=(char **) RelinquishMagickMemory(list);
2865 if (length)
2866 length=(STRLEN *) RelinquishMagickMemory(length);
2867 InheritPerlException(exception,perl_exception);
2868 exception=DestroyExceptionInfo(exception);
2869 sv_setiv(perl_exception,(IV) number_images);
2870 SvPOK_on(perl_exception);
2871 ST(0)=sv_2mortal(perl_exception);
2872 XSRETURN(1);
2873 }
2874
2875#
2876###############################################################################
2877# #
2878# #
2879# #
2880# C h a n n e l F x #
2881# #
2882# #
2883# #
2884###############################################################################
2885#
2886#
2887void
2888ChannelFx(ref,...)
2889 Image::Magick ref=NO_INIT
2890 ALIAS:
2891 ChannelFxImage = 1
2892 channelfx = 2
2893 channelfximage = 3
2894 PPCODE:
2895 {
2896 AV
2897 *av;
2898
2899 char
2900 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002901 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002902
2903 ChannelType
2904 channel,
2905 channel_mask;
2906
2907 ExceptionInfo
2908 *exception;
2909
2910 HV
2911 *hv;
2912
2913 Image
2914 *image;
2915
2916 register ssize_t
2917 i;
2918
2919 struct PackageInfo
2920 *info;
2921
2922 SV
2923 *av_reference,
2924 *perl_exception,
2925 *reference,
2926 *rv,
2927 *sv;
2928
2929 PERL_UNUSED_VAR(ref);
2930 PERL_UNUSED_VAR(ix);
2931 exception=AcquireExceptionInfo();
2932 perl_exception=newSVpv("",0);
2933 sv=NULL;
2934 attribute=NULL;
2935 av=NULL;
2936 if (sv_isobject(ST(0)) == 0)
2937 {
2938 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2939 PackageName);
2940 goto PerlException;
2941 }
2942 reference=SvRV(ST(0));
2943 hv=SvSTASH(reference);
2944 av=newAV();
2945 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2946 SvREFCNT_dec(av);
2947 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2948 if (image == (Image *) NULL)
2949 {
2950 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2951 PackageName);
2952 goto PerlException;
2953 }
2954 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2955 /*
2956 Get options.
2957 */
2958 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00002959 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002960 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00002961 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002962 else
2963 for (i=2; i < items; i+=2)
2964 {
2965 attribute=(char *) SvPV(ST(i-1),na);
2966 switch (*attribute)
2967 {
2968 case 'C':
2969 case 'c':
2970 {
2971 if (LocaleCompare(attribute,"channel") == 0)
2972 {
2973 ssize_t
2974 option;
2975
2976 option=ParseChannelOption(SvPV(ST(i),na));
2977 if (option < 0)
2978 {
2979 ThrowPerlException(exception,OptionError,
2980 "UnrecognizedType",SvPV(ST(i),na));
2981 return;
2982 }
2983 channel=(ChannelType) option;
2984 break;
2985 }
2986 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2987 attribute);
2988 break;
2989 }
2990 case 'E':
2991 case 'e':
2992 {
2993 if (LocaleCompare(attribute,"expression") == 0)
2994 {
2995 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00002996 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002997 break;
2998 }
2999 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3000 attribute);
3001 break;
3002 }
3003 default:
3004 {
3005 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3006 attribute);
3007 break;
3008 }
3009 }
3010 }
3011 channel_mask=SetImageChannelMask(image,channel);
3012 image=ChannelFxImage(image,expression,exception);
3013 if (image != (Image *) NULL)
3014 (void) SetImageChannelMask(image,channel_mask);
3015 if (image == (Image *) NULL)
3016 goto PerlException;
3017 for ( ; image; image=image->next)
3018 {
3019 AddImageToRegistry(sv,image);
3020 rv=newRV(sv);
3021 av_push(av,sv_bless(rv,hv));
3022 SvREFCNT_dec(sv);
3023 }
3024 exception=DestroyExceptionInfo(exception);
3025 ST(0)=av_reference;
3026 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3027 XSRETURN(1);
3028
3029 PerlException:
3030 InheritPerlException(exception,perl_exception);
3031 exception=DestroyExceptionInfo(exception);
3032 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3033 SvPOK_on(perl_exception);
3034 ST(0)=sv_2mortal(perl_exception);
3035 XSRETURN(1);
3036 }
3037
3038#
3039###############################################################################
3040# #
3041# #
3042# #
3043# C l o n e #
3044# #
3045# #
3046# #
3047###############################################################################
3048#
3049#
3050void
3051Clone(ref)
3052 Image::Magick ref=NO_INIT
3053 ALIAS:
3054 CopyImage = 1
3055 copy = 2
3056 copyimage = 3
3057 CloneImage = 4
3058 clone = 5
3059 cloneimage = 6
3060 Clone = 7
3061 PPCODE:
3062 {
3063 AV
3064 *av;
3065
3066 ExceptionInfo
3067 *exception;
3068
3069 HV
3070 *hv;
3071
3072 Image
3073 *clone,
3074 *image;
3075
3076 struct PackageInfo
3077 *info;
3078
3079 SV
3080 *perl_exception,
3081 *reference,
3082 *rv,
3083 *sv;
3084
3085 PERL_UNUSED_VAR(ref);
3086 PERL_UNUSED_VAR(ix);
3087 exception=AcquireExceptionInfo();
3088 perl_exception=newSVpv("",0);
3089 sv=NULL;
3090 if (sv_isobject(ST(0)) == 0)
3091 {
3092 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3093 PackageName);
3094 goto PerlException;
3095 }
3096 reference=SvRV(ST(0));
3097 hv=SvSTASH(reference);
3098 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3099 if (image == (Image *) NULL)
3100 {
3101 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3102 PackageName);
3103 goto PerlException;
3104 }
3105 /*
3106 Create blessed Perl array for the returned image.
3107 */
3108 av=newAV();
3109 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3110 SvREFCNT_dec(av);
3111 for ( ; image; image=image->next)
3112 {
3113 clone=CloneImage(image,0,0,MagickTrue,exception);
3114 if (clone == (Image *) NULL)
3115 break;
3116 AddImageToRegistry(sv,clone);
3117 rv=newRV(sv);
3118 av_push(av,sv_bless(rv,hv));
3119 SvREFCNT_dec(sv);
3120 }
3121 exception=DestroyExceptionInfo(exception);
3122 SvREFCNT_dec(perl_exception);
3123 XSRETURN(1);
3124
3125 PerlException:
3126 InheritPerlException(exception,perl_exception);
3127 exception=DestroyExceptionInfo(exception);
3128 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3129 SvPOK_on(perl_exception);
3130 ST(0)=sv_2mortal(perl_exception);
3131 XSRETURN(1);
3132 }
3133
3134#
3135###############################################################################
3136# #
3137# #
3138# #
3139# C L O N E #
3140# #
3141# #
3142# #
3143###############################################################################
3144#
3145#
3146void
3147CLONE(ref,...)
3148 SV *ref;
3149 CODE:
3150 {
3151 PERL_UNUSED_VAR(ref);
3152 if (magick_registry != (SplayTreeInfo *) NULL)
3153 {
3154 register Image
3155 *p;
3156
3157 ResetSplayTreeIterator(magick_registry);
3158 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3159 while (p != (Image *) NULL)
3160 {
3161 ReferenceImage(p);
3162 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3163 }
3164 }
3165 }
3166
3167#
3168###############################################################################
3169# #
3170# #
3171# #
3172# C o a l e s c e #
3173# #
3174# #
3175# #
3176###############################################################################
3177#
3178#
3179void
3180Coalesce(ref)
3181 Image::Magick ref=NO_INIT
3182 ALIAS:
3183 CoalesceImage = 1
3184 coalesce = 2
3185 coalesceimage = 3
3186 PPCODE:
3187 {
3188 AV
3189 *av;
3190
3191 ExceptionInfo
3192 *exception;
3193
3194 HV
3195 *hv;
3196
3197 Image
3198 *image;
3199
3200 struct PackageInfo
3201 *info;
3202
3203 SV
3204 *av_reference,
3205 *perl_exception,
3206 *reference,
3207 *rv,
3208 *sv;
3209
3210 PERL_UNUSED_VAR(ref);
3211 PERL_UNUSED_VAR(ix);
3212 exception=AcquireExceptionInfo();
3213 perl_exception=newSVpv("",0);
3214 sv=NULL;
3215 if (sv_isobject(ST(0)) == 0)
3216 {
3217 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3218 PackageName);
3219 goto PerlException;
3220 }
3221 reference=SvRV(ST(0));
3222 hv=SvSTASH(reference);
3223 av=newAV();
3224 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3225 SvREFCNT_dec(av);
3226 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3227 if (image == (Image *) NULL)
3228 {
3229 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3230 PackageName);
3231 goto PerlException;
3232 }
3233 image=CoalesceImages(image,exception);
3234 if (image == (Image *) NULL)
3235 goto PerlException;
3236 for ( ; image; image=image->next)
3237 {
3238 AddImageToRegistry(sv,image);
3239 rv=newRV(sv);
3240 av_push(av,sv_bless(rv,hv));
3241 SvREFCNT_dec(sv);
3242 }
3243 exception=DestroyExceptionInfo(exception);
3244 ST(0)=av_reference;
3245 SvREFCNT_dec(perl_exception);
3246 XSRETURN(1);
3247
3248 PerlException:
3249 InheritPerlException(exception,perl_exception);
3250 exception=DestroyExceptionInfo(exception);
3251 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3252 SvPOK_on(perl_exception);
3253 ST(0)=sv_2mortal(perl_exception);
3254 XSRETURN(1);
3255 }
3256
3257#
3258###############################################################################
3259# #
3260# #
3261# #
3262# C o m p a r e #
3263# #
3264# #
3265# #
3266###############################################################################
3267#
3268#
3269void
3270Compare(ref,...)
3271 Image::Magick ref=NO_INIT
3272 ALIAS:
3273 CompareImages = 1
3274 compare = 2
3275 compareimage = 3
3276 PPCODE:
3277 {
3278 AV
3279 *av;
3280
3281 char
3282 *attribute;
3283
3284 double
3285 distortion;
3286
3287 ExceptionInfo
3288 *exception;
3289
3290 HV
3291 *hv;
3292
3293 Image
3294 *difference_image,
3295 *image,
3296 *reconstruct_image;
3297
3298 MetricType
3299 metric;
3300
3301 register ssize_t
3302 i;
3303
3304 ssize_t
3305 option;
3306
3307 struct PackageInfo
3308 *info;
3309
3310 SV
3311 *av_reference,
3312 *perl_exception,
3313 *reference,
3314 *rv,
3315 *sv;
3316
3317 PERL_UNUSED_VAR(ref);
3318 PERL_UNUSED_VAR(ix);
3319 exception=AcquireExceptionInfo();
3320 perl_exception=newSVpv("",0);
3321 sv=NULL;
3322 av=NULL;
3323 attribute=NULL;
3324 if (sv_isobject(ST(0)) == 0)
3325 {
3326 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3327 PackageName);
3328 goto PerlException;
3329 }
3330 reference=SvRV(ST(0));
3331 hv=SvSTASH(reference);
3332 av=newAV();
3333 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3334 SvREFCNT_dec(av);
3335 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3336 if (image == (Image *) NULL)
3337 {
3338 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3339 PackageName);
3340 goto PerlException;
3341 }
3342 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3343 /*
3344 Get attribute.
3345 */
3346 reconstruct_image=image;
3347 metric=RootMeanSquaredErrorMetric;
3348 for (i=2; i < items; i+=2)
3349 {
3350 attribute=(char *) SvPV(ST(i-1),na);
3351 switch (*attribute)
3352 {
3353 case 'C':
3354 case 'c':
3355 {
3356 if (LocaleCompare(attribute,"channel") == 0)
3357 {
3358 ssize_t
3359 option;
3360
3361 option=ParseChannelOption(SvPV(ST(i),na));
3362 if (option < 0)
3363 {
3364 ThrowPerlException(exception,OptionError,
3365 "UnrecognizedType",SvPV(ST(i),na));
3366 return;
3367 }
cristybcd59342015-06-07 14:07:19 +00003368 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003369 break;
3370 }
3371 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3372 attribute);
3373 break;
3374 }
3375 case 'F':
3376 case 'f':
3377 {
3378 if (LocaleCompare(attribute,"fuzz") == 0)
3379 {
3380 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3381 break;
3382 }
3383 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3384 attribute);
3385 break;
3386 }
3387 case 'I':
3388 case 'i':
3389 {
3390 if (LocaleCompare(attribute,"image") == 0)
3391 {
3392 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3393 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3394 break;
3395 }
3396 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3397 attribute);
3398 break;
3399 }
3400 case 'M':
3401 case 'm':
3402 {
3403 if (LocaleCompare(attribute,"metric") == 0)
3404 {
3405 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3406 SvPV(ST(i),na));
3407 if (option < 0)
3408 {
3409 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3410 SvPV(ST(i),na));
3411 break;
3412 }
3413 metric=(MetricType) option;
3414 break;
3415 }
3416 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3417 attribute);
3418 break;
3419 }
3420 default:
3421 {
3422 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3423 attribute);
3424 break;
3425 }
3426 }
3427 }
3428 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3429 exception);
3430 if (difference_image != (Image *) NULL)
3431 {
3432 difference_image->error.mean_error_per_pixel=distortion;
3433 AddImageToRegistry(sv,difference_image);
3434 rv=newRV(sv);
3435 av_push(av,sv_bless(rv,hv));
3436 SvREFCNT_dec(sv);
3437 }
3438 exception=DestroyExceptionInfo(exception);
3439 ST(0)=av_reference;
3440 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3441 XSRETURN(1);
3442
3443 PerlException:
3444 InheritPerlException(exception,perl_exception);
3445 exception=DestroyExceptionInfo(exception);
3446 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3447 SvPOK_on(perl_exception);
3448 ST(0)=sv_2mortal(perl_exception);
3449 XSRETURN(1);
3450 }
3451
3452#
3453###############################################################################
3454# #
3455# #
3456# #
cristy15655332013-10-06 00:27:33 +00003457# C o m p l e x I m a g e s #
3458# #
3459# #
3460# #
3461###############################################################################
3462#
3463#
3464void
3465ComplexImages(ref)
3466 Image::Magick ref=NO_INIT
3467 ALIAS:
3468 ComplexImages = 1
3469 compleximages = 2
3470 PPCODE:
3471 {
3472 AV
3473 *av;
3474
3475 char
3476 *attribute,
3477 *p;
3478
cristyfa21e9e2013-10-07 10:37:38 +00003479 ComplexOperator
3480 op;
3481
cristy15655332013-10-06 00:27:33 +00003482 ExceptionInfo
3483 *exception;
3484
3485 HV
3486 *hv;
3487
3488 Image
3489 *image;
3490
cristy15655332013-10-06 00:27:33 +00003491 register ssize_t
3492 i;
3493
3494 struct PackageInfo
3495 *info;
3496
3497 SV
3498 *perl_exception,
3499 *reference,
3500 *rv,
3501 *sv;
3502
3503 PERL_UNUSED_VAR(ref);
3504 PERL_UNUSED_VAR(ix);
3505 exception=AcquireExceptionInfo();
3506 perl_exception=newSVpv("",0);
3507 sv=NULL;
3508 if (sv_isobject(ST(0)) == 0)
3509 {
3510 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3511 PackageName);
3512 goto PerlException;
3513 }
3514 reference=SvRV(ST(0));
3515 hv=SvSTASH(reference);
3516 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3517 if (image == (Image *) NULL)
3518 {
3519 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3520 PackageName);
3521 goto PerlException;
3522 }
cristyfd168722013-10-07 15:59:31 +00003523 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003524 if (items == 2)
3525 {
3526 ssize_t
3527 in;
3528
3529 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3530 SvPV(ST(1),na));
3531 if (in < 0)
3532 {
3533 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3534 SvPV(ST(1),na));
3535 return;
3536 }
cristyfa21e9e2013-10-07 10:37:38 +00003537 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003538 }
3539 else
3540 for (i=2; i < items; i+=2)
3541 {
3542 attribute=(char *) SvPV(ST(i-1),na);
3543 switch (*attribute)
3544 {
3545 case 'O':
3546 case 'o':
3547 {
3548 if (LocaleCompare(attribute,"operator") == 0)
3549 {
3550 ssize_t
3551 in;
3552
3553 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3554 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3555 if (in < 0)
3556 {
3557 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3558 SvPV(ST(i),na));
3559 return;
3560 }
cristyfa21e9e2013-10-07 10:37:38 +00003561 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003562 break;
3563 }
3564 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3565 attribute);
3566 break;
3567 }
3568 default:
3569 {
3570 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3571 attribute);
3572 break;
3573 }
3574 }
3575 }
3576 image=ComplexImages(image,op,exception);
3577 if (image == (Image *) NULL)
3578 goto PerlException;
3579 /*
3580 Create blessed Perl array for the returned image.
3581 */
3582 av=newAV();
3583 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3584 SvREFCNT_dec(av);
3585 AddImageToRegistry(sv,image);
3586 rv=newRV(sv);
3587 av_push(av,sv_bless(rv,hv));
3588 SvREFCNT_dec(sv);
3589 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003590 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3591 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003592 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3593 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003594 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003595 SetImageInfo(info->image_info,0,exception);
3596 exception=DestroyExceptionInfo(exception);
3597 SvREFCNT_dec(perl_exception);
3598 XSRETURN(1);
3599
3600 PerlException:
3601 InheritPerlException(exception,perl_exception);
3602 exception=DestroyExceptionInfo(exception);
3603 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3604 SvPOK_on(perl_exception);
3605 ST(0)=sv_2mortal(perl_exception);
3606 XSRETURN(1);
3607 }
3608
3609#
3610###############################################################################
3611# #
3612# #
3613# #
cristy4a3ce0a2013-08-03 20:06:59 +00003614# C o m p a r e L a y e r s #
3615# #
3616# #
3617# #
3618###############################################################################
3619#
3620#
3621void
3622CompareLayers(ref)
3623 Image::Magick ref=NO_INIT
3624 ALIAS:
3625 CompareImagesLayers = 1
3626 comparelayers = 2
3627 compareimagelayers = 3
3628 PPCODE:
3629 {
3630 AV
3631 *av;
3632
3633 char
3634 *attribute;
3635
3636 ExceptionInfo
3637 *exception;
3638
3639 HV
3640 *hv;
3641
3642 Image
3643 *image;
3644
3645 LayerMethod
3646 method;
3647
3648 register ssize_t
3649 i;
3650
3651 ssize_t
3652 option;
3653
3654 struct PackageInfo
3655 *info;
3656
3657 SV
3658 *av_reference,
3659 *perl_exception,
3660 *reference,
3661 *rv,
3662 *sv;
3663
3664 PERL_UNUSED_VAR(ref);
3665 PERL_UNUSED_VAR(ix);
3666 exception=AcquireExceptionInfo();
3667 perl_exception=newSVpv("",0);
3668 sv=NULL;
3669 if (sv_isobject(ST(0)) == 0)
3670 {
3671 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3672 PackageName);
3673 goto PerlException;
3674 }
3675 reference=SvRV(ST(0));
3676 hv=SvSTASH(reference);
3677 av=newAV();
3678 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3679 SvREFCNT_dec(av);
3680 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3681 if (image == (Image *) NULL)
3682 {
3683 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3684 PackageName);
3685 goto PerlException;
3686 }
3687 method=CompareAnyLayer;
3688 for (i=2; i < items; i+=2)
3689 {
3690 attribute=(char *) SvPV(ST(i-1),na);
3691 switch (*attribute)
3692 {
3693 case 'M':
3694 case 'm':
3695 {
3696 if (LocaleCompare(attribute,"method") == 0)
3697 {
3698 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3699 SvPV(ST(i),na));
3700 if (option < 0)
3701 {
3702 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3703 SvPV(ST(i),na));
3704 break;
3705 }
3706 method=(LayerMethod) option;
3707 break;
3708 }
3709 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3710 attribute);
3711 break;
3712 }
3713 default:
3714 {
3715 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3716 attribute);
3717 break;
3718 }
3719 }
3720 }
3721 image=CompareImagesLayers(image,method,exception);
3722 if (image == (Image *) NULL)
3723 goto PerlException;
3724 for ( ; image; image=image->next)
3725 {
3726 AddImageToRegistry(sv,image);
3727 rv=newRV(sv);
3728 av_push(av,sv_bless(rv,hv));
3729 SvREFCNT_dec(sv);
3730 }
3731 exception=DestroyExceptionInfo(exception);
3732 ST(0)=av_reference;
3733 SvREFCNT_dec(perl_exception);
3734 XSRETURN(1);
3735
3736 PerlException:
3737 InheritPerlException(exception,perl_exception);
3738 exception=DestroyExceptionInfo(exception);
3739 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3740 SvPOK_on(perl_exception);
3741 ST(0)=sv_2mortal(perl_exception);
3742 XSRETURN(1);
3743 }
3744
3745#
3746###############################################################################
3747# #
3748# #
3749# #
3750# D e s t r o y #
3751# #
3752# #
3753# #
3754###############################################################################
3755#
3756#
3757void
3758DESTROY(ref)
3759 Image::Magick ref=NO_INIT
3760 PPCODE:
3761 {
3762 SV
3763 *reference;
3764
3765 PERL_UNUSED_VAR(ref);
3766 if (sv_isobject(ST(0)) == 0)
3767 croak("ReferenceIsNotMyType");
3768 reference=SvRV(ST(0));
3769 switch (SvTYPE(reference))
3770 {
3771 case SVt_PVAV:
3772 {
3773 char
cristy151b66d2015-04-15 10:50:31 +00003774 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003775
3776 const SV
3777 *key;
3778
3779 HV
3780 *hv;
3781
3782 GV
3783 **gvp;
3784
3785 struct PackageInfo
3786 *info;
3787
3788 SV
3789 *sv;
3790
3791 /*
3792 Array (AV *) reference
3793 */
cristy151b66d2015-04-15 10:50:31 +00003794 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003795 XS_VERSION,reference);
3796 hv=gv_stashpv(PackageName, FALSE);
3797 if (!hv)
3798 break;
3799 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3800 if (!gvp)
3801 break;
3802 sv=GvSV(*gvp);
3803 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3804 {
3805 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3806 DestroyPackageInfo(info);
3807 }
3808 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3809 (void) key;
3810 break;
3811 }
3812 case SVt_PVMG:
3813 {
3814 Image
3815 *image;
3816
3817 /*
3818 Blessed scalar = (Image *) SvIV(reference)
3819 */
3820 image=INT2PTR(Image *,SvIV(reference));
3821 if (image != (Image *) NULL)
3822 DeleteImageFromRegistry(reference,image);
3823 break;
3824 }
3825 default:
3826 break;
3827 }
3828 }
3829
3830#
3831###############################################################################
3832# #
3833# #
3834# #
3835# D i s p l a y #
3836# #
3837# #
3838# #
3839###############################################################################
3840#
3841#
3842void
3843Display(ref,...)
3844 Image::Magick ref=NO_INIT
3845 ALIAS:
3846 DisplayImage = 1
3847 display = 2
3848 displayimage = 3
3849 PPCODE:
3850 {
3851 ExceptionInfo
3852 *exception;
3853
3854 Image
3855 *image;
3856
3857 register ssize_t
3858 i;
3859
3860 struct PackageInfo
3861 *info,
3862 *package_info;
3863
3864 SV
3865 *perl_exception,
3866 *reference;
3867
3868 PERL_UNUSED_VAR(ref);
3869 PERL_UNUSED_VAR(ix);
3870 exception=AcquireExceptionInfo();
3871 perl_exception=newSVpv("",0);
3872 package_info=(struct PackageInfo *) NULL;
3873 if (sv_isobject(ST(0)) == 0)
3874 {
3875 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3876 PackageName);
3877 goto PerlException;
3878 }
3879 reference=SvRV(ST(0));
3880 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3881 if (image == (Image *) NULL)
3882 {
3883 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3884 PackageName);
3885 goto PerlException;
3886 }
3887 package_info=ClonePackageInfo(info,exception);
3888 if (items == 2)
3889 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3890 else
3891 if (items > 2)
3892 for (i=2; i < items; i+=2)
3893 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3894 exception);
3895 (void) DisplayImages(package_info->image_info,image,exception);
3896 (void) CatchImageException(image);
3897
3898 PerlException:
3899 if (package_info != (struct PackageInfo *) NULL)
3900 DestroyPackageInfo(package_info);
3901 InheritPerlException(exception,perl_exception);
3902 exception=DestroyExceptionInfo(exception);
3903 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3904 SvPOK_on(perl_exception);
3905 ST(0)=sv_2mortal(perl_exception);
3906 XSRETURN(1);
3907 }
3908
3909#
3910###############################################################################
3911# #
3912# #
3913# #
3914# E v a l u a t e I m a g e s #
3915# #
3916# #
3917# #
3918###############################################################################
3919#
3920#
3921void
3922EvaluateImages(ref)
3923 Image::Magick ref=NO_INIT
3924 ALIAS:
3925 EvaluateImages = 1
3926 evaluateimages = 2
3927 PPCODE:
3928 {
3929 AV
3930 *av;
3931
3932 char
3933 *attribute,
3934 *p;
3935
3936 ExceptionInfo
3937 *exception;
3938
3939 HV
3940 *hv;
3941
3942 Image
3943 *image;
3944
3945 MagickEvaluateOperator
3946 op;
3947
3948 register ssize_t
3949 i;
3950
3951 struct PackageInfo
3952 *info;
3953
3954 SV
3955 *perl_exception,
3956 *reference,
3957 *rv,
3958 *sv;
3959
3960 PERL_UNUSED_VAR(ref);
3961 PERL_UNUSED_VAR(ix);
3962 exception=AcquireExceptionInfo();
3963 perl_exception=newSVpv("",0);
3964 sv=NULL;
3965 if (sv_isobject(ST(0)) == 0)
3966 {
3967 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3968 PackageName);
3969 goto PerlException;
3970 }
3971 reference=SvRV(ST(0));
3972 hv=SvSTASH(reference);
3973 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3974 if (image == (Image *) NULL)
3975 {
3976 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3977 PackageName);
3978 goto PerlException;
3979 }
3980 op=MeanEvaluateOperator;
3981 if (items == 2)
3982 {
3983 ssize_t
3984 in;
3985
3986 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
3987 SvPV(ST(1),na));
3988 if (in < 0)
3989 {
3990 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3991 SvPV(ST(1),na));
3992 return;
3993 }
3994 op=(MagickEvaluateOperator) in;
3995 }
3996 else
3997 for (i=2; i < items; i+=2)
3998 {
3999 attribute=(char *) SvPV(ST(i-1),na);
4000 switch (*attribute)
4001 {
4002 case 'O':
4003 case 'o':
4004 {
4005 if (LocaleCompare(attribute,"operator") == 0)
4006 {
4007 ssize_t
4008 in;
4009
4010 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4011 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4012 if (in < 0)
4013 {
4014 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4015 SvPV(ST(i),na));
4016 return;
4017 }
4018 op=(MagickEvaluateOperator) in;
4019 break;
4020 }
4021 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4022 attribute);
4023 break;
4024 }
4025 default:
4026 {
4027 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4028 attribute);
4029 break;
4030 }
4031 }
4032 }
4033 image=EvaluateImages(image,op,exception);
4034 if (image == (Image *) NULL)
4035 goto PerlException;
4036 /*
4037 Create blessed Perl array for the returned image.
4038 */
4039 av=newAV();
4040 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4041 SvREFCNT_dec(av);
4042 AddImageToRegistry(sv,image);
4043 rv=newRV(sv);
4044 av_push(av,sv_bless(rv,hv));
4045 SvREFCNT_dec(sv);
4046 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004047 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4048 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004049 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4050 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004051 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004052 SetImageInfo(info->image_info,0,exception);
4053 exception=DestroyExceptionInfo(exception);
4054 SvREFCNT_dec(perl_exception);
4055 XSRETURN(1);
4056
4057 PerlException:
4058 InheritPerlException(exception,perl_exception);
4059 exception=DestroyExceptionInfo(exception);
4060 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4061 SvPOK_on(perl_exception);
4062 ST(0)=sv_2mortal(perl_exception);
4063 XSRETURN(1);
4064 }
4065
4066#
4067###############################################################################
4068# #
4069# #
4070# #
4071# F e a t u r e s #
4072# #
4073# #
4074# #
4075###############################################################################
4076#
4077#
4078void
4079Features(ref,...)
4080 Image::Magick ref=NO_INIT
4081 ALIAS:
4082 FeaturesImage = 1
4083 features = 2
4084 featuresimage = 3
4085 PPCODE:
4086 {
4087#define ChannelFeatures(channel,direction) \
4088{ \
cristy151b66d2015-04-15 10:50:31 +00004089 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004090 channel_features[channel].angular_second_moment[direction]); \
4091 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004092 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004093 channel_features[channel].contrast[direction]); \
4094 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004095 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004096 channel_features[channel].contrast[direction]); \
4097 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004098 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004099 channel_features[channel].variance_sum_of_squares[direction]); \
4100 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004101 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004102 channel_features[channel].inverse_difference_moment[direction]); \
4103 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004104 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004105 channel_features[channel].sum_average[direction]); \
4106 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004107 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004108 channel_features[channel].sum_variance[direction]); \
4109 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004110 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004111 channel_features[channel].sum_entropy[direction]); \
4112 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004113 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004114 channel_features[channel].entropy[direction]); \
4115 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004116 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004117 channel_features[channel].difference_variance[direction]); \
4118 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004119 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004120 channel_features[channel].difference_entropy[direction]); \
4121 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004122 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004123 channel_features[channel].measure_of_correlation_1[direction]); \
4124 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004125 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004126 channel_features[channel].measure_of_correlation_2[direction]); \
4127 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004128 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004129 channel_features[channel].maximum_correlation_coefficient[direction]); \
4130 PUSHs(sv_2mortal(newSVpv(message,0))); \
4131}
4132
4133 AV
4134 *av;
4135
4136 char
4137 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004138 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004139
4140 ChannelFeatures
4141 *channel_features;
4142
4143 double
4144 distance;
4145
4146 ExceptionInfo
4147 *exception;
4148
4149 Image
4150 *image;
4151
4152 register ssize_t
4153 i;
4154
4155 ssize_t
4156 count;
4157
4158 struct PackageInfo
4159 *info;
4160
4161 SV
4162 *perl_exception,
4163 *reference;
4164
4165 PERL_UNUSED_VAR(ref);
4166 PERL_UNUSED_VAR(ix);
4167 exception=AcquireExceptionInfo();
4168 perl_exception=newSVpv("",0);
4169 av=NULL;
4170 if (sv_isobject(ST(0)) == 0)
4171 {
4172 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4173 PackageName);
4174 goto PerlException;
4175 }
4176 reference=SvRV(ST(0));
4177 av=newAV();
4178 SvREFCNT_dec(av);
4179 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4180 if (image == (Image *) NULL)
4181 {
4182 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4183 PackageName);
4184 goto PerlException;
4185 }
cristy7dbd9262014-07-02 17:53:42 +00004186 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004187 for (i=2; i < items; i+=2)
4188 {
4189 attribute=(char *) SvPV(ST(i-1),na);
4190 switch (*attribute)
4191 {
4192 case 'D':
4193 case 'd':
4194 {
4195 if (LocaleCompare(attribute,"distance") == 0)
4196 {
4197 distance=StringToLong((char *) SvPV(ST(1),na));
4198 break;
4199 }
4200 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4201 attribute);
4202 break;
4203 }
4204 default:
4205 {
4206 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4207 attribute);
4208 break;
4209 }
4210 }
4211 }
4212 count=0;
4213 for ( ; image; image=image->next)
4214 {
4215 channel_features=GetImageFeatures(image,distance,exception);
4216 if (channel_features == (ChannelFeatures *) NULL)
4217 continue;
4218 count++;
cristyfcf3bdf2014-07-02 14:35:58 +00004219 EXTEND(sp,280*count);
cristy4a3ce0a2013-08-03 20:06:59 +00004220 for (i=0; i < 4; i++)
4221 {
4222 ChannelFeatures(RedChannel,i);
4223 ChannelFeatures(GreenChannel,i);
4224 ChannelFeatures(BlueChannel,i);
4225 if (image->colorspace == CMYKColorspace)
4226 ChannelFeatures(BlackChannel,i);
cristy17f11b02014-12-20 19:37:04 +00004227 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00004228 ChannelFeatures(AlphaChannel,i);
4229 }
4230 channel_features=(ChannelFeatures *)
4231 RelinquishMagickMemory(channel_features);
4232 }
4233
4234 PerlException:
4235 InheritPerlException(exception,perl_exception);
4236 exception=DestroyExceptionInfo(exception);
4237 SvREFCNT_dec(perl_exception);
4238 }
4239
4240#
4241###############################################################################
4242# #
4243# #
4244# #
4245# F l a t t e n #
4246# #
4247# #
4248# #
4249###############################################################################
4250#
4251#
4252void
4253Flatten(ref)
4254 Image::Magick ref=NO_INIT
4255 ALIAS:
4256 FlattenImage = 1
4257 flatten = 2
4258 flattenimage = 3
4259 PPCODE:
4260 {
4261 AV
4262 *av;
4263
4264 char
4265 *attribute,
4266 *p;
4267
4268 ExceptionInfo
4269 *exception;
4270
4271 HV
4272 *hv;
4273
4274 Image
4275 *image;
4276
4277 PixelInfo
4278 background_color;
4279
4280 register ssize_t
4281 i;
4282
4283 struct PackageInfo
4284 *info;
4285
4286 SV
4287 *perl_exception,
4288 *reference,
4289 *rv,
4290 *sv;
4291
4292 PERL_UNUSED_VAR(ref);
4293 PERL_UNUSED_VAR(ix);
4294 exception=AcquireExceptionInfo();
4295 perl_exception=newSVpv("",0);
4296 sv=NULL;
4297 if (sv_isobject(ST(0)) == 0)
4298 {
4299 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4300 PackageName);
4301 goto PerlException;
4302 }
4303 reference=SvRV(ST(0));
4304 hv=SvSTASH(reference);
4305 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4306 if (image == (Image *) NULL)
4307 {
4308 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4309 PackageName);
4310 goto PerlException;
4311 }
4312 background_color=image->background_color;
4313 if (items == 2)
4314 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4315 &background_color,exception);
4316 else
4317 for (i=2; i < items; i+=2)
4318 {
4319 attribute=(char *) SvPV(ST(i-1),na);
4320 switch (*attribute)
4321 {
4322 case 'B':
4323 case 'b':
4324 {
4325 if (LocaleCompare(attribute,"background") == 0)
4326 {
4327 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4328 AllCompliance,&background_color,exception);
4329 break;
4330 }
4331 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4332 attribute);
4333 break;
4334 }
4335 default:
4336 {
4337 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4338 attribute);
4339 break;
4340 }
4341 }
4342 }
4343 image->background_color=background_color;
4344 image=MergeImageLayers(image,FlattenLayer,exception);
4345 if (image == (Image *) NULL)
4346 goto PerlException;
4347 /*
4348 Create blessed Perl array for the returned image.
4349 */
4350 av=newAV();
4351 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4352 SvREFCNT_dec(av);
4353 AddImageToRegistry(sv,image);
4354 rv=newRV(sv);
4355 av_push(av,sv_bless(rv,hv));
4356 SvREFCNT_dec(sv);
4357 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004358 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4359 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004360 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4361 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004362 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004363 SetImageInfo(info->image_info,0,exception);
4364 exception=DestroyExceptionInfo(exception);
4365 SvREFCNT_dec(perl_exception);
4366 XSRETURN(1);
4367
4368 PerlException:
4369 InheritPerlException(exception,perl_exception);
4370 exception=DestroyExceptionInfo(exception);
4371 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4372 SvPOK_on(perl_exception); /* return messages in string context */
4373 ST(0)=sv_2mortal(perl_exception);
4374 XSRETURN(1);
4375 }
4376
4377#
4378###############################################################################
4379# #
4380# #
4381# #
4382# F x #
4383# #
4384# #
4385# #
4386###############################################################################
4387#
4388#
4389void
4390Fx(ref,...)
4391 Image::Magick ref=NO_INIT
4392 ALIAS:
4393 FxImage = 1
4394 fx = 2
4395 fximage = 3
4396 PPCODE:
4397 {
4398 AV
4399 *av;
4400
4401 char
4402 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004403 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004404
4405 ChannelType
4406 channel,
4407 channel_mask;
4408
4409 ExceptionInfo
4410 *exception;
4411
4412 HV
4413 *hv;
4414
4415 Image
4416 *image;
4417
4418 register ssize_t
4419 i;
4420
4421 struct PackageInfo
4422 *info;
4423
4424 SV
4425 *av_reference,
4426 *perl_exception,
4427 *reference,
4428 *rv,
4429 *sv;
4430
4431 PERL_UNUSED_VAR(ref);
4432 PERL_UNUSED_VAR(ix);
4433 exception=AcquireExceptionInfo();
4434 perl_exception=newSVpv("",0);
4435 sv=NULL;
4436 attribute=NULL;
4437 av=NULL;
4438 if (sv_isobject(ST(0)) == 0)
4439 {
4440 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4441 PackageName);
4442 goto PerlException;
4443 }
4444 reference=SvRV(ST(0));
4445 hv=SvSTASH(reference);
4446 av=newAV();
4447 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4448 SvREFCNT_dec(av);
4449 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4450 if (image == (Image *) NULL)
4451 {
4452 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4453 PackageName);
4454 goto PerlException;
4455 }
4456 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4457 /*
4458 Get options.
4459 */
4460 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004461 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004462 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004463 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004464 else
4465 for (i=2; i < items; i+=2)
4466 {
4467 attribute=(char *) SvPV(ST(i-1),na);
4468 switch (*attribute)
4469 {
4470 case 'C':
4471 case 'c':
4472 {
4473 if (LocaleCompare(attribute,"channel") == 0)
4474 {
4475 ssize_t
4476 option;
4477
4478 option=ParseChannelOption(SvPV(ST(i),na));
4479 if (option < 0)
4480 {
4481 ThrowPerlException(exception,OptionError,
4482 "UnrecognizedType",SvPV(ST(i),na));
4483 return;
4484 }
4485 channel=(ChannelType) option;
4486 break;
4487 }
4488 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4489 attribute);
4490 break;
4491 }
4492 case 'E':
4493 case 'e':
4494 {
4495 if (LocaleCompare(attribute,"expression") == 0)
4496 {
4497 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004498 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004499 break;
4500 }
4501 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4502 attribute);
4503 break;
4504 }
4505 default:
4506 {
4507 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4508 attribute);
4509 break;
4510 }
4511 }
4512 }
4513 channel_mask=SetImageChannelMask(image,channel);
4514 image=FxImage(image,expression,exception);
4515 if (image != (Image *) NULL)
4516 (void) SetImageChannelMask(image,channel_mask);
4517 if (image == (Image *) NULL)
4518 goto PerlException;
4519 for ( ; image; image=image->next)
4520 {
4521 AddImageToRegistry(sv,image);
4522 rv=newRV(sv);
4523 av_push(av,sv_bless(rv,hv));
4524 SvREFCNT_dec(sv);
4525 }
4526 exception=DestroyExceptionInfo(exception);
4527 ST(0)=av_reference;
4528 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4529 XSRETURN(1);
4530
4531 PerlException:
4532 InheritPerlException(exception,perl_exception);
4533 exception=DestroyExceptionInfo(exception);
4534 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4535 SvPOK_on(perl_exception);
4536 ST(0)=sv_2mortal(perl_exception);
4537 XSRETURN(1);
4538 }
4539
4540#
4541###############################################################################
4542# #
4543# #
4544# #
4545# G e t #
4546# #
4547# #
4548# #
4549###############################################################################
4550#
4551#
4552void
4553Get(ref,...)
4554 Image::Magick ref=NO_INIT
4555 ALIAS:
4556 GetAttributes = 1
4557 GetAttribute = 2
4558 get = 3
4559 getattributes = 4
4560 getattribute = 5
4561 PPCODE:
4562 {
4563 char
4564 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004565 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004566
4567 const char
4568 *value;
4569
4570 ExceptionInfo
4571 *exception;
4572
4573 Image
4574 *image;
4575
4576 long
4577 j;
4578
4579 register ssize_t
4580 i;
4581
4582 struct PackageInfo
4583 *info;
4584
4585 SV
4586 *perl_exception,
4587 *reference,
4588 *s;
4589
4590 PERL_UNUSED_VAR(ref);
4591 PERL_UNUSED_VAR(ix);
4592 exception=AcquireExceptionInfo();
4593 perl_exception=newSVpv("",0);
4594 if (sv_isobject(ST(0)) == 0)
4595 {
4596 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4597 PackageName);
4598 XSRETURN_EMPTY;
4599 }
4600 reference=SvRV(ST(0));
4601 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4602 if (image == (Image *) NULL && !info)
4603 XSRETURN_EMPTY;
4604 EXTEND(sp,items);
4605 for (i=1; i < items; i++)
4606 {
4607 attribute=(char *) SvPV(ST(i),na);
4608 s=NULL;
4609 switch (*attribute)
4610 {
4611 case 'A':
4612 case 'a':
4613 {
4614 if (LocaleCompare(attribute,"adjoin") == 0)
4615 {
4616 if (info)
4617 s=newSViv((ssize_t) info->image_info->adjoin);
4618 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4619 continue;
4620 }
4621 if (LocaleCompare(attribute,"antialias") == 0)
4622 {
4623 if (info)
4624 s=newSViv((ssize_t) info->image_info->antialias);
4625 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4626 continue;
4627 }
4628 if (LocaleCompare(attribute,"area") == 0)
4629 {
4630 s=newSViv(GetMagickResource(AreaResource));
4631 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4632 continue;
4633 }
4634 if (LocaleCompare(attribute,"attenuate") == 0)
4635 {
4636 const char
4637 *value;
4638
4639 value=GetImageProperty(image,attribute,exception);
4640 if (value != (const char *) NULL)
4641 s=newSVpv(value,0);
4642 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4643 continue;
4644 }
4645 if (LocaleCompare(attribute,"authenticate") == 0)
4646 {
4647 if (info)
4648 {
4649 const char
4650 *option;
4651
4652 option=GetImageOption(info->image_info,attribute);
4653 if (option != (const char *) NULL)
4654 s=newSVpv(option,0);
4655 }
4656 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4657 continue;
4658 }
4659 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4660 attribute);
4661 break;
4662 }
4663 case 'B':
4664 case 'b':
4665 {
4666 if (LocaleCompare(attribute,"background") == 0)
4667 {
4668 if (image == (Image *) NULL)
4669 break;
cristy151b66d2015-04-15 10:50:31 +00004670 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004671 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4672 (double) image->background_color.green,
4673 (double) image->background_color.blue,
4674 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004675 s=newSVpv(color,0);
4676 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4677 continue;
4678 }
4679 if (LocaleCompare(attribute,"base-columns") == 0)
4680 {
4681 if (image != (Image *) NULL)
4682 s=newSViv((ssize_t) image->magick_columns);
4683 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4684 continue;
4685 }
4686 if (LocaleCompare(attribute,"base-filename") == 0)
4687 {
4688 if (image != (Image *) NULL)
4689 s=newSVpv(image->magick_filename,0);
4690 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4691 continue;
4692 }
4693 if (LocaleCompare(attribute,"base-height") == 0)
4694 {
4695 if (image != (Image *) NULL)
4696 s=newSViv((ssize_t) image->magick_rows);
4697 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4698 continue;
4699 }
4700 if (LocaleCompare(attribute,"base-rows") == 0)
4701 {
4702 if (image != (Image *) NULL)
4703 s=newSViv((ssize_t) image->magick_rows);
4704 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4705 continue;
4706 }
4707 if (LocaleCompare(attribute,"base-width") == 0)
4708 {
4709 if (image != (Image *) NULL)
4710 s=newSViv((ssize_t) image->magick_columns);
4711 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4712 continue;
4713 }
4714 if (LocaleCompare(attribute,"blue-primary") == 0)
4715 {
4716 if (image == (Image *) NULL)
4717 break;
cristy151b66d2015-04-15 10:50:31 +00004718 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00004719 image->chromaticity.blue_primary.x,
4720 image->chromaticity.blue_primary.y);
4721 s=newSVpv(color,0);
4722 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4723 continue;
4724 }
4725 if (LocaleCompare(attribute,"bordercolor") == 0)
4726 {
4727 if (image == (Image *) NULL)
4728 break;
cristy151b66d2015-04-15 10:50:31 +00004729 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004730 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4731 (double) image->border_color.green,
4732 (double) image->border_color.blue,
4733 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004734 s=newSVpv(color,0);
4735 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4736 continue;
4737 }
4738 if (LocaleCompare(attribute,"bounding-box") == 0)
4739 {
4740 char
cristy151b66d2015-04-15 10:50:31 +00004741 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004742
4743 RectangleInfo
4744 page;
4745
4746 if (image == (Image *) NULL)
4747 break;
4748 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004749 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004750 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4751 page.height,(double) page.x,(double) page.y);
4752 s=newSVpv(geometry,0);
4753 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4754 continue;
4755 }
4756 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4757 attribute);
4758 break;
4759 }
4760 case 'C':
4761 case 'c':
4762 {
4763 if (LocaleCompare(attribute,"class") == 0)
4764 {
4765 if (image == (Image *) NULL)
4766 break;
4767 s=newSViv(image->storage_class);
4768 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4769 image->storage_class));
4770 SvIOK_on(s);
4771 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4772 continue;
4773 }
4774 if (LocaleCompare(attribute,"clip-mask") == 0)
4775 {
4776 if (image != (Image *) NULL)
4777 {
4778 Image
4779 *mask_image;
4780
4781 SV
4782 *sv;
4783
4784 sv=NULL;
4785 if (image->read_mask == MagickFalse)
4786 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004787 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004788 if (mask_image != (Image *) NULL)
4789 {
4790 AddImageToRegistry(sv,mask_image);
4791 s=sv_bless(newRV(sv),SvSTASH(reference));
4792 }
4793 }
4794 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4795 continue;
4796 }
4797 if (LocaleCompare(attribute,"clip-path") == 0)
4798 {
4799 if (image != (Image *) NULL)
4800 {
4801 Image
4802 *mask_image;
4803
4804 SV
4805 *sv;
4806
4807 sv=NULL;
4808 if (image->read_mask != MagickFalse)
4809 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004810 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004811 if (mask_image != (Image *) NULL)
4812 {
4813 AddImageToRegistry(sv,mask_image);
4814 s=sv_bless(newRV(sv),SvSTASH(reference));
4815 }
4816 }
4817 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4818 continue;
4819 }
4820 if (LocaleCompare(attribute,"compression") == 0)
4821 {
4822 j=info ? info->image_info->compression : image ?
4823 image->compression : UndefinedCompression;
4824 if (info)
4825 if (info->image_info->compression == UndefinedCompression)
4826 j=image->compression;
4827 s=newSViv(j);
4828 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4829 j));
4830 SvIOK_on(s);
4831 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4832 continue;
4833 }
4834 if (LocaleCompare(attribute,"colorspace") == 0)
4835 {
4836 j=image ? image->colorspace : RGBColorspace;
4837 s=newSViv(j);
4838 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4839 j));
4840 SvIOK_on(s);
4841 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4842 continue;
4843 }
4844 if (LocaleCompare(attribute,"colors") == 0)
4845 {
4846 if (image != (Image *) NULL)
4847 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4848 exception));
4849 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4850 continue;
4851 }
4852 if (LocaleNCompare(attribute,"colormap",8) == 0)
4853 {
4854 int
4855 items;
4856
4857 if (image == (Image *) NULL || !image->colormap)
4858 break;
4859 j=0;
4860 items=sscanf(attribute,"%*[^[][%ld",&j);
4861 (void) items;
4862 if (j > (ssize_t) image->colors)
4863 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004864 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004865 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4866 (double) image->colormap[j].green,
4867 (double) image->colormap[j].blue,
4868 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004869 s=newSVpv(color,0);
4870 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4871 continue;
4872 }
4873 if (LocaleCompare(attribute,"columns") == 0)
4874 {
4875 if (image != (Image *) NULL)
4876 s=newSViv((ssize_t) image->columns);
4877 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4878 continue;
4879 }
4880 if (LocaleCompare(attribute,"comment") == 0)
4881 {
4882 const char
4883 *value;
4884
4885 value=GetImageProperty(image,attribute,exception);
4886 if (value != (const char *) NULL)
4887 s=newSVpv(value,0);
4888 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4889 continue;
4890 }
4891 if (LocaleCompare(attribute,"copyright") == 0)
4892 {
4893 s=newSVpv(GetMagickCopyright(),0);
4894 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4895 continue;
4896 }
4897 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4898 attribute);
4899 break;
4900 }
4901 case 'D':
4902 case 'd':
4903 {
4904 if (LocaleCompare(attribute,"density") == 0)
4905 {
4906 char
cristy151b66d2015-04-15 10:50:31 +00004907 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004908
4909 if (image == (Image *) NULL)
4910 break;
cristy151b66d2015-04-15 10:50:31 +00004911 (void) FormatLocaleString(geometry,MagickPathExtent,"%.15gx%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00004912 image->resolution.x,image->resolution.y);
4913 s=newSVpv(geometry,0);
4914 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4915 continue;
4916 }
4917 if (LocaleCompare(attribute,"delay") == 0)
4918 {
4919 if (image != (Image *) NULL)
4920 s=newSViv((ssize_t) image->delay);
4921 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4922 continue;
4923 }
4924 if (LocaleCompare(attribute,"depth") == 0)
4925 {
4926 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4927 if (image != (Image *) NULL)
4928 s=newSViv((ssize_t) GetImageDepth(image,exception));
4929 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4930 continue;
4931 }
4932 if (LocaleCompare(attribute,"directory") == 0)
4933 {
4934 if (image && image->directory)
4935 s=newSVpv(image->directory,0);
4936 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4937 continue;
4938 }
4939 if (LocaleCompare(attribute,"dispose") == 0)
4940 {
4941 if (image == (Image *) NULL)
4942 break;
4943
4944 s=newSViv(image->dispose);
4945 (void) sv_setpv(s,
4946 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
4947 SvIOK_on(s);
4948 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4949 continue;
4950 }
4951 if (LocaleCompare(attribute,"disk") == 0)
4952 {
4953 s=newSViv(GetMagickResource(DiskResource));
4954 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4955 continue;
4956 }
4957 if (LocaleCompare(attribute,"dither") == 0)
4958 {
4959 if (info)
4960 s=newSViv((ssize_t) info->image_info->dither);
4961 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4962 continue;
4963 }
4964 if (LocaleCompare(attribute,"display") == 0) /* same as server */
4965 {
4966 if (info && info->image_info->server_name)
4967 s=newSVpv(info->image_info->server_name,0);
4968 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4969 continue;
4970 }
4971 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4972 attribute);
4973 break;
4974 }
4975 case 'E':
4976 case 'e':
4977 {
4978 if (LocaleCompare(attribute,"elapsed-time") == 0)
4979 {
4980 if (image != (Image *) NULL)
4981 s=newSVnv(GetElapsedTime(&image->timer));
4982 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4983 continue;
4984 }
4985 if (LocaleCompare(attribute,"endian") == 0)
4986 {
4987 j=info ? info->image_info->endian : image ? image->endian :
4988 UndefinedEndian;
4989 s=newSViv(j);
4990 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
4991 SvIOK_on(s);
4992 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4993 continue;
4994 }
4995 if (LocaleCompare(attribute,"error") == 0)
4996 {
4997 if (image != (Image *) NULL)
4998 s=newSVnv(image->error.mean_error_per_pixel);
4999 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5000 continue;
5001 }
5002 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5003 attribute);
5004 break;
5005 }
5006 case 'F':
5007 case 'f':
5008 {
5009 if (LocaleCompare(attribute,"filesize") == 0)
5010 {
5011 if (image != (Image *) NULL)
5012 s=newSViv((ssize_t) GetBlobSize(image));
5013 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5014 continue;
5015 }
5016 if (LocaleCompare(attribute,"filename") == 0)
5017 {
5018 if (info && info->image_info->filename &&
5019 *info->image_info->filename)
5020 s=newSVpv(info->image_info->filename,0);
5021 if (image != (Image *) NULL)
5022 s=newSVpv(image->filename,0);
5023 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5024 continue;
5025 }
5026 if (LocaleCompare(attribute,"filter") == 0)
5027 {
5028 s=image ? newSViv(image->filter) : newSViv(0);
5029 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5030 image->filter));
5031 SvIOK_on(s);
5032 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5033 continue;
5034 }
5035 if (LocaleCompare(attribute,"font") == 0)
5036 {
5037 if (info && info->image_info->font)
5038 s=newSVpv(info->image_info->font,0);
5039 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5040 continue;
5041 }
5042 if (LocaleCompare(attribute,"foreground") == 0)
5043 continue;
5044 if (LocaleCompare(attribute,"format") == 0)
5045 {
5046 const MagickInfo
5047 *magick_info;
5048
5049 magick_info=(const MagickInfo *) NULL;
5050 if (info && (*info->image_info->magick != '\0'))
5051 magick_info=GetMagickInfo(info->image_info->magick,exception);
5052 if (image != (Image *) NULL)
5053 magick_info=GetMagickInfo(image->magick,exception);
5054 if ((magick_info != (const MagickInfo *) NULL) &&
5055 (*magick_info->description != '\0'))
5056 s=newSVpv((char *) magick_info->description,0);
5057 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5058 continue;
5059 }
5060 if (LocaleCompare(attribute,"fuzz") == 0)
5061 {
5062 if (info)
5063 s=newSVnv(info->image_info->fuzz);
5064 if (image != (Image *) NULL)
5065 s=newSVnv(image->fuzz);
5066 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5067 continue;
5068 }
5069 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5070 attribute);
5071 break;
5072 }
5073 case 'G':
5074 case 'g':
5075 {
5076 if (LocaleCompare(attribute,"gamma") == 0)
5077 {
5078 if (image != (Image *) NULL)
5079 s=newSVnv(image->gamma);
5080 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5081 continue;
5082 }
5083 if (LocaleCompare(attribute,"geometry") == 0)
5084 {
5085 if (image && image->geometry)
5086 s=newSVpv(image->geometry,0);
5087 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5088 continue;
5089 }
5090 if (LocaleCompare(attribute,"gravity") == 0)
5091 {
5092 s=image ? newSViv(image->gravity) : newSViv(0);
5093 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5094 image->gravity));
5095 SvIOK_on(s);
5096 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5097 continue;
5098 }
5099 if (LocaleCompare(attribute,"green-primary") == 0)
5100 {
5101 if (image == (Image *) NULL)
5102 break;
cristy151b66d2015-04-15 10:50:31 +00005103 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005104 image->chromaticity.green_primary.x,
5105 image->chromaticity.green_primary.y);
5106 s=newSVpv(color,0);
5107 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5108 continue;
5109 }
5110 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5111 attribute);
5112 break;
5113 }
5114 case 'H':
5115 case 'h':
5116 {
5117 if (LocaleCompare(attribute,"height") == 0)
5118 {
5119 if (image != (Image *) NULL)
5120 s=newSViv((ssize_t) image->rows);
5121 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5122 continue;
5123 }
5124 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5125 attribute);
5126 break;
5127 }
5128 case 'I':
5129 case 'i':
5130 {
5131 if (LocaleCompare(attribute,"icc") == 0)
5132 {
5133 if (image != (Image *) NULL)
5134 {
5135 const StringInfo
5136 *profile;
5137
5138 profile=GetImageProfile(image,"icc");
5139 if (profile != (StringInfo *) NULL)
5140 s=newSVpv((const char *) GetStringInfoDatum(profile),
5141 GetStringInfoLength(profile));
5142 }
5143 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5144 continue;
5145 }
5146 if (LocaleCompare(attribute,"icm") == 0)
5147 {
5148 if (image != (Image *) NULL)
5149 {
5150 const StringInfo
5151 *profile;
5152
5153 profile=GetImageProfile(image,"icm");
5154 if (profile != (const StringInfo *) NULL)
5155 s=newSVpv((const char *) GetStringInfoDatum(profile),
5156 GetStringInfoLength(profile));
5157 }
5158 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5159 continue;
5160 }
5161 if (LocaleCompare(attribute,"id") == 0)
5162 {
5163 if (image != (Image *) NULL)
5164 {
5165 char
cristy151b66d2015-04-15 10:50:31 +00005166 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005167
5168 MagickBooleanType
5169 status;
5170
5171 static ssize_t
5172 id = 0;
5173
cristy151b66d2015-04-15 10:50:31 +00005174 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005175 id);
5176 status=SetImageRegistry(ImageRegistryType,key,image,
5177 exception);
5178 (void) status;
5179 s=newSViv(id++);
5180 }
5181 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5182 continue;
5183 }
5184 if (LocaleNCompare(attribute,"index",5) == 0)
5185 {
5186 char
cristy151b66d2015-04-15 10:50:31 +00005187 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005188
5189 int
5190 items;
5191
5192 long
5193 x,
5194 y;
5195
5196 register const Quantum
5197 *p;
5198
5199 CacheView
5200 *image_view;
5201
5202 if (image == (Image *) NULL)
5203 break;
5204 if (image->storage_class != PseudoClass)
5205 break;
5206 x=0;
5207 y=0;
5208 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5209 (void) items;
5210 image_view=AcquireVirtualCacheView(image,exception);
5211 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5212 if (p != (const Quantum *) NULL)
5213 {
cristy151b66d2015-04-15 10:50:31 +00005214 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005215 GetPixelIndex(image,p));
5216 s=newSVpv(name,0);
5217 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5218 }
5219 image_view=DestroyCacheView(image_view);
5220 continue;
5221 }
5222 if (LocaleCompare(attribute,"iptc") == 0)
5223 {
5224 if (image != (Image *) NULL)
5225 {
5226 const StringInfo
5227 *profile;
5228
5229 profile=GetImageProfile(image,"iptc");
5230 if (profile != (const StringInfo *) NULL)
5231 s=newSVpv((const char *) GetStringInfoDatum(profile),
5232 GetStringInfoLength(profile));
5233 }
5234 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5235 continue;
5236 }
5237 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5238 {
5239 if (image != (Image *) NULL)
5240 s=newSViv((ssize_t) image->iterations);
5241 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5242 continue;
5243 }
5244 if (LocaleCompare(attribute,"interlace") == 0)
5245 {
5246 j=info ? info->image_info->interlace : image ? image->interlace :
5247 UndefinedInterlace;
5248 s=newSViv(j);
5249 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5250 j));
5251 SvIOK_on(s);
5252 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5253 continue;
5254 }
5255 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5256 attribute);
5257 break;
5258 }
5259 case 'L':
5260 case 'l':
5261 {
5262 if (LocaleCompare(attribute,"label") == 0)
5263 {
5264 const char
5265 *value;
5266
5267 if (image == (Image *) NULL)
5268 break;
5269 value=GetImageProperty(image,"Label",exception);
5270 if (value != (const char *) NULL)
5271 s=newSVpv(value,0);
5272 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5273 continue;
5274 }
5275 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5276 {
5277 if (image != (Image *) NULL)
5278 s=newSViv((ssize_t) image->iterations);
5279 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5280 continue;
5281 }
5282 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5283 attribute);
5284 break;
5285 }
5286 case 'M':
5287 case 'm':
5288 {
5289 if (LocaleCompare(attribute,"magick") == 0)
5290 {
5291 if (info && *info->image_info->magick)
5292 s=newSVpv(info->image_info->magick,0);
5293 if (image != (Image *) NULL)
5294 s=newSVpv(image->magick,0);
5295 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5296 continue;
5297 }
5298 if (LocaleCompare(attribute,"map") == 0)
5299 {
5300 s=newSViv(GetMagickResource(MapResource));
5301 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5302 continue;
5303 }
5304 if (LocaleCompare(attribute,"maximum-error") == 0)
5305 {
5306 if (image != (Image *) NULL)
5307 s=newSVnv(image->error.normalized_maximum_error);
5308 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5309 continue;
5310 }
5311 if (LocaleCompare(attribute,"memory") == 0)
5312 {
5313 s=newSViv(GetMagickResource(MemoryResource));
5314 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5315 continue;
5316 }
5317 if (LocaleCompare(attribute,"mean-error") == 0)
5318 {
5319 if (image != (Image *) NULL)
5320 s=newSVnv(image->error.normalized_mean_error);
5321 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5322 continue;
5323 }
5324 if (LocaleCompare(attribute,"mime") == 0)
5325 {
5326 if (info && *info->image_info->magick)
5327 s=newSVpv(MagickToMime(info->image_info->magick),0);
5328 if (image != (Image *) NULL)
5329 s=newSVpv(MagickToMime(image->magick),0);
5330 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5331 continue;
5332 }
5333 if (LocaleCompare(attribute,"mattecolor") == 0)
5334 {
5335 if (image == (Image *) NULL)
5336 break;
cristy151b66d2015-04-15 10:50:31 +00005337 (void) FormatLocaleString(color,MagickPathExtent,
Cristy8645e042016-02-03 16:35:29 -05005338 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5339 (double) image->alpha_color.green,
5340 (double) image->alpha_color.blue,
5341 (double) image->alpha_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005342 s=newSVpv(color,0);
5343 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5344 continue;
5345 }
5346 if (LocaleCompare(attribute,"matte") == 0)
5347 {
5348 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005349 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005350 1 : 0);
5351 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5352 continue;
5353 }
5354 if (LocaleCompare(attribute,"mime") == 0)
5355 {
5356 const char
5357 *magick;
5358
5359 magick=NULL;
5360 if (info && *info->image_info->magick)
5361 magick=info->image_info->magick;
5362 if (image != (Image *) NULL)
5363 magick=image->magick;
5364 if (magick)
5365 {
5366 char
5367 *mime;
5368
5369 mime=MagickToMime(magick);
5370 s=newSVpv(mime,0);
5371 mime=(char *) RelinquishMagickMemory(mime);
5372 }
5373 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5374 continue;
5375 }
5376 if (LocaleCompare(attribute,"monochrome") == 0)
5377 {
5378 if (image == (Image *) NULL)
5379 continue;
5380 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005381 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005382 s=newSViv(j);
5383 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5384 continue;
5385 }
5386 if (LocaleCompare(attribute,"montage") == 0)
5387 {
5388 if (image && image->montage)
5389 s=newSVpv(image->montage,0);
5390 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5391 continue;
5392 }
5393 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5394 attribute);
5395 break;
5396 }
5397 case 'O':
5398 case 'o':
5399 {
5400 if (LocaleCompare(attribute,"orientation") == 0)
5401 {
5402 j=info ? info->image_info->orientation : image ?
5403 image->orientation : UndefinedOrientation;
5404 s=newSViv(j);
5405 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5406 j));
5407 SvIOK_on(s);
5408 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5409 continue;
5410 }
5411 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5412 attribute);
5413 break;
5414 }
5415 case 'P':
5416 case 'p':
5417 {
5418 if (LocaleCompare(attribute,"page") == 0)
5419 {
5420 if (info && info->image_info->page)
5421 s=newSVpv(info->image_info->page,0);
5422 if (image != (Image *) NULL)
5423 {
5424 char
cristy151b66d2015-04-15 10:50:31 +00005425 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005426
cristy151b66d2015-04-15 10:50:31 +00005427 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005428 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5429 (double) image->page.height,(double) image->page.x,(double)
5430 image->page.y);
5431 s=newSVpv(geometry,0);
5432 }
5433 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5434 continue;
5435 }
5436 if (LocaleCompare(attribute,"page.x") == 0)
5437 {
5438 if (image != (Image *) NULL)
5439 s=newSViv((ssize_t) image->page.x);
5440 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5441 continue;
5442 }
5443 if (LocaleCompare(attribute,"page.y") == 0)
5444 {
5445 if (image != (Image *) NULL)
5446 s=newSViv((ssize_t) image->page.y);
5447 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5448 continue;
5449 }
5450 if (LocaleNCompare(attribute,"pixel",5) == 0)
5451 {
5452 char
cristy151b66d2015-04-15 10:50:31 +00005453 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005454
5455 int
5456 items;
5457
5458 long
5459 x,
5460 y;
5461
5462 register const Quantum
5463 *p;
5464
5465 if (image == (Image *) NULL)
5466 break;
5467 x=0;
5468 y=0;
5469 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5470 (void) items;
5471 p=GetVirtualPixels(image,x,y,1,1,exception);
5472 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005473 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005474 QuantumFormat "," QuantumFormat "," QuantumFormat,
5475 GetPixelRed(image,p),GetPixelGreen(image,p),
5476 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5477 else
cristy151b66d2015-04-15 10:50:31 +00005478 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005479 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5480 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5481 GetPixelBlue(image,p),GetPixelBlack(image,p),
5482 GetPixelAlpha(image,p));
5483 s=newSVpv(tuple,0);
5484 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5485 continue;
5486 }
5487 if (LocaleCompare(attribute,"pointsize") == 0)
5488 {
5489 if (info)
5490 s=newSViv((ssize_t) info->image_info->pointsize);
5491 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5492 continue;
5493 }
5494 if (LocaleCompare(attribute,"preview") == 0)
5495 {
5496 s=newSViv(info->image_info->preview_type);
5497 (void) sv_setpv(s,CommandOptionToMnemonic(MagickPreviewOptions,
5498 info->image_info->preview_type));
5499 SvIOK_on(s);
5500 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5501 continue;
5502 }
5503 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5504 attribute);
5505 break;
5506 }
5507 case 'Q':
5508 case 'q':
5509 {
5510 if (LocaleCompare(attribute,"quality") == 0)
5511 {
5512 if (info)
5513 s=newSViv((ssize_t) info->image_info->quality);
5514 if (image != (Image *) NULL)
5515 s=newSViv((ssize_t) image->quality);
5516 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5517 continue;
5518 }
5519 if (LocaleCompare(attribute,"quantum") == 0)
5520 {
5521 if (info)
5522 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5523 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5524 continue;
5525 }
5526 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5527 attribute);
5528 break;
5529 }
5530 case 'R':
5531 case 'r':
5532 {
5533 if (LocaleCompare(attribute,"rendering-intent") == 0)
5534 {
5535 s=newSViv(image->rendering_intent);
5536 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5537 image->rendering_intent));
5538 SvIOK_on(s);
5539 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5540 continue;
5541 }
5542 if (LocaleCompare(attribute,"red-primary") == 0)
5543 {
5544 if (image == (Image *) NULL)
5545 break;
cristy151b66d2015-04-15 10:50:31 +00005546 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005547 image->chromaticity.red_primary.x,
5548 image->chromaticity.red_primary.y);
5549 s=newSVpv(color,0);
5550 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5551 continue;
5552 }
5553 if (LocaleCompare(attribute,"rows") == 0)
5554 {
5555 if (image != (Image *) NULL)
5556 s=newSViv((ssize_t) image->rows);
5557 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5558 continue;
5559 }
5560 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5561 attribute);
5562 break;
5563 }
5564 case 'S':
5565 case 's':
5566 {
5567 if (LocaleCompare(attribute,"sampling-factor") == 0)
5568 {
5569 if (info && info->image_info->sampling_factor)
5570 s=newSVpv(info->image_info->sampling_factor,0);
5571 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5572 continue;
5573 }
5574 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5575 {
5576 if (info && info->image_info->server_name)
5577 s=newSVpv(info->image_info->server_name,0);
5578 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5579 continue;
5580 }
5581 if (LocaleCompare(attribute,"size") == 0)
5582 {
5583 if (info && info->image_info->size)
5584 s=newSVpv(info->image_info->size,0);
5585 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5586 continue;
5587 }
5588 if (LocaleCompare(attribute,"scene") == 0)
5589 {
5590 if (image != (Image *) NULL)
5591 s=newSViv((ssize_t) image->scene);
5592 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5593 continue;
5594 }
5595 if (LocaleCompare(attribute,"scenes") == 0)
5596 {
5597 if (image != (Image *) NULL)
5598 s=newSViv((ssize_t) info->image_info->number_scenes);
5599 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5600 continue;
5601 }
5602 if (LocaleCompare(attribute,"signature") == 0)
5603 {
5604 const char
5605 *value;
5606
5607 if (image == (Image *) NULL)
5608 break;
5609 (void) SignatureImage(image,exception);
5610 value=GetImageProperty(image,"Signature",exception);
5611 if (value != (const char *) NULL)
5612 s=newSVpv(value,0);
5613 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5614 continue;
5615 }
5616 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5617 attribute);
5618 break;
5619 }
5620 case 'T':
5621 case 't':
5622 {
5623 if (LocaleCompare(attribute,"taint") == 0)
5624 {
5625 if (image != (Image *) NULL)
5626 s=newSViv((ssize_t) IsTaintImage(image));
5627 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5628 continue;
5629 }
5630 if (LocaleCompare(attribute,"texture") == 0)
5631 {
5632 if (info && info->image_info->texture)
5633 s=newSVpv(info->image_info->texture,0);
5634 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5635 continue;
5636 }
5637 if (LocaleCompare(attribute,"total-ink-density") == 0)
5638 {
5639 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5640 if (image != (Image *) NULL)
5641 s=newSVnv(GetImageTotalInkDensity(image,exception));
5642 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5643 continue;
5644 }
5645 if (LocaleCompare(attribute,"transparent-color") == 0)
5646 {
5647 if (image == (Image *) NULL)
5648 break;
cristy151b66d2015-04-15 10:50:31 +00005649 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005650 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5651 (double) image->transparent_color.green,
5652 (double) image->transparent_color.blue,
5653 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005654 s=newSVpv(color,0);
5655 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5656 continue;
5657 }
5658 if (LocaleCompare(attribute,"type") == 0)
5659 {
5660 if (image == (Image *) NULL)
5661 break;
cristya26f54c2015-07-29 12:26:12 +00005662 j=(ssize_t) GetImageType(image);
cristy4a3ce0a2013-08-03 20:06:59 +00005663 s=newSViv(j);
5664 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5665 SvIOK_on(s);
5666 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5667 continue;
5668 }
5669 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5670 attribute);
5671 break;
5672 }
5673 case 'U':
5674 case 'u':
5675 {
5676 if (LocaleCompare(attribute,"units") == 0)
5677 {
5678 j=info ? info->image_info->units : image ? image->units :
5679 UndefinedResolution;
5680 if (info && (info->image_info->units == UndefinedResolution))
5681 if (image)
5682 j=image->units;
5683 if (j == UndefinedResolution)
5684 s=newSVpv("undefined units",0);
5685 else
5686 if (j == PixelsPerInchResolution)
5687 s=newSVpv("pixels / inch",0);
5688 else
5689 s=newSVpv("pixels / centimeter",0);
5690 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5691 continue;
5692 }
5693 if (LocaleCompare(attribute,"user-time") == 0)
5694 {
5695 if (image != (Image *) NULL)
5696 s=newSVnv(GetUserTime(&image->timer));
5697 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5698 continue;
5699 }
5700 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5701 attribute);
5702 break;
5703 }
5704 case 'V':
5705 case 'v':
5706 {
5707 if (LocaleCompare(attribute,"verbose") == 0)
5708 {
5709 if (info)
5710 s=newSViv((ssize_t) info->image_info->verbose);
5711 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5712 continue;
5713 }
5714 if (LocaleCompare(attribute,"version") == 0)
5715 {
5716 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5717 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5718 continue;
5719 }
cristy4a3ce0a2013-08-03 20:06:59 +00005720 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5721 {
5722 if (image == (Image *) NULL)
5723 break;
5724 j=(ssize_t) GetImageVirtualPixelMethod(image);
5725 s=newSViv(j);
5726 (void) sv_setpv(s,CommandOptionToMnemonic(
5727 MagickVirtualPixelOptions,j));
5728 SvIOK_on(s);
5729 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5730 continue;
5731 }
5732 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5733 attribute);
5734 break;
5735 }
5736 case 'W':
5737 case 'w':
5738 {
5739 if (LocaleCompare(attribute,"white-point") == 0)
5740 {
5741 if (image == (Image *) NULL)
5742 break;
cristy151b66d2015-04-15 10:50:31 +00005743 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005744 image->chromaticity.white_point.x,
5745 image->chromaticity.white_point.y);
5746 s=newSVpv(color,0);
5747 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5748 continue;
5749 }
5750 if (LocaleCompare(attribute,"width") == 0)
5751 {
5752 if (image != (Image *) NULL)
5753 s=newSViv((ssize_t) image->columns);
5754 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5755 continue;
5756 }
5757 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5758 attribute);
5759 break;
5760 }
5761 case 'X':
5762 case 'x':
5763 {
Cristyc1f9f9f2016-01-05 08:19:28 -05005764 if (LocaleCompare(attribute,"xmp") == 0)
5765 {
5766 if (image != (Image *) NULL)
5767 {
5768 const StringInfo
5769 *profile;
5770
5771 profile=GetImageProfile(image,"xmp");
5772 if (profile != (StringInfo *) NULL)
5773 s=newSVpv((const char *) GetStringInfoDatum(profile),
5774 GetStringInfoLength(profile));
5775 }
5776 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5777 continue;
5778 }
cristy4a3ce0a2013-08-03 20:06:59 +00005779 if (LocaleCompare(attribute,"x-resolution") == 0)
5780 {
5781 if (image != (Image *) NULL)
5782 s=newSVnv(image->resolution.x);
5783 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5784 continue;
5785 }
5786 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5787 attribute);
5788 break;
5789 }
5790 case 'Y':
5791 case 'y':
5792 {
5793 if (LocaleCompare(attribute,"y-resolution") == 0)
5794 {
5795 if (image != (Image *) NULL)
5796 s=newSVnv(image->resolution.y);
5797 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5798 continue;
5799 }
5800 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5801 attribute);
5802 break;
5803 }
5804 default:
5805 break;
5806 }
5807 if (image == (Image *) NULL)
5808 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5809 attribute)
5810 else
5811 {
5812 value=GetImageProperty(image,attribute,exception);
5813 if (value != (const char *) NULL)
5814 {
5815 s=newSVpv(value,0);
5816 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5817 }
5818 else
5819 if (*attribute != '%')
5820 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5821 attribute)
5822 else
5823 {
5824 char
5825 *meta;
5826
5827 meta=InterpretImageProperties(info ? info->image_info :
5828 (ImageInfo *) NULL,image,attribute,exception);
5829 s=newSVpv(meta,0);
5830 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5831 meta=(char *) RelinquishMagickMemory(meta);
5832 }
5833 }
5834 }
5835 exception=DestroyExceptionInfo(exception);
5836 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5837 }
5838
5839#
5840###############################################################################
5841# #
5842# #
5843# #
5844# G e t A u t h e n t i c P i x e l s #
5845# #
5846# #
5847# #
5848###############################################################################
5849#
5850#
5851void *
5852GetAuthenticPixels(ref,...)
5853 Image::Magick ref = NO_INIT
5854 ALIAS:
5855 getauthenticpixels = 1
5856 GetImagePixels = 2
5857 getimagepixels = 3
5858 CODE:
5859 {
5860 char
5861 *attribute;
5862
5863 ExceptionInfo
5864 *exception;
5865
5866 Image
5867 *image;
5868
5869 RectangleInfo
5870 region;
5871
5872 ssize_t
5873 i;
5874
5875 struct PackageInfo
5876 *info;
5877
5878 SV
5879 *perl_exception,
5880 *reference;
5881
5882 void
5883 *blob = NULL;
5884
5885 PERL_UNUSED_VAR(ref);
5886 PERL_UNUSED_VAR(ix);
5887 exception=AcquireExceptionInfo();
5888 perl_exception=newSVpv("",0);
5889 if (sv_isobject(ST(0)) == 0)
5890 {
5891 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5892 PackageName);
5893 goto PerlException;
5894 }
5895 reference=SvRV(ST(0));
5896
5897 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5898 if (image == (Image *) NULL)
5899 {
5900 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5901 PackageName);
5902 goto PerlException;
5903 }
5904
5905 region.x=0;
5906 region.y=0;
5907 region.width=image->columns;
5908 region.height=1;
5909 if (items == 1)
5910 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5911 for (i=2; i < items; i+=2)
5912 {
5913 attribute=(char *) SvPV(ST(i-1),na);
5914 switch (*attribute)
5915 {
5916 case 'g':
5917 case 'G':
5918 {
5919 if (LocaleCompare(attribute,"geometry") == 0)
5920 {
5921 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5922 break;
5923 }
5924 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5925 attribute);
5926 break;
5927 }
5928 case 'H':
5929 case 'h':
5930 {
5931 if (LocaleCompare(attribute,"height") == 0)
5932 {
5933 region.height=SvIV(ST(i));
5934 continue;
5935 }
5936 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5937 attribute);
5938 break;
5939 }
5940 case 'X':
5941 case 'x':
5942 {
5943 if (LocaleCompare(attribute,"x") == 0)
5944 {
5945 region.x=SvIV(ST(i));
5946 continue;
5947 }
5948 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5949 attribute);
5950 break;
5951 }
5952 case 'Y':
5953 case 'y':
5954 {
5955 if (LocaleCompare(attribute,"y") == 0)
5956 {
5957 region.y=SvIV(ST(i));
5958 continue;
5959 }
5960 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5961 attribute);
5962 break;
5963 }
5964 case 'W':
5965 case 'w':
5966 {
5967 if (LocaleCompare(attribute,"width") == 0)
5968 {
5969 region.width=SvIV(ST(i));
5970 continue;
5971 }
5972 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5973 attribute);
5974 break;
5975 }
5976 }
5977 }
5978 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5979 region.height,exception);
5980 if (blob != (void *) NULL)
5981 goto PerlEnd;
5982
5983 PerlException:
5984 InheritPerlException(exception,perl_exception);
5985 exception=DestroyExceptionInfo(exception);
5986 SvREFCNT_dec(perl_exception); /* throw away all errors */
5987
5988 PerlEnd:
5989 RETVAL = blob;
5990 }
5991 OUTPUT:
5992 RETVAL
5993
5994#
5995###############################################################################
5996# #
5997# #
5998# #
5999# G e t V i r t u a l P i x e l s #
6000# #
6001# #
6002# #
6003###############################################################################
6004#
6005#
6006void *
6007GetVirtualPixels(ref,...)
6008 Image::Magick ref = NO_INIT
6009 ALIAS:
6010 getvirtualpixels = 1
6011 AcquireImagePixels = 2
6012 acquireimagepixels = 3
6013 CODE:
6014 {
6015 char
6016 *attribute;
6017
6018 const void
6019 *blob = NULL;
6020
6021 ExceptionInfo
6022 *exception;
6023
6024 Image
6025 *image;
6026
6027 RectangleInfo
6028 region;
6029
6030 ssize_t
6031 i;
6032
6033 struct PackageInfo
6034 *info;
6035
6036 SV
6037 *perl_exception,
6038 *reference;
6039
6040 PERL_UNUSED_VAR(ref);
6041 PERL_UNUSED_VAR(ix);
6042 exception=AcquireExceptionInfo();
6043 perl_exception=newSVpv("",0);
6044 if (sv_isobject(ST(0)) == 0)
6045 {
6046 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6047 PackageName);
6048 goto PerlException;
6049 }
6050 reference=SvRV(ST(0));
6051
6052 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6053 if (image == (Image *) NULL)
6054 {
6055 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6056 PackageName);
6057 goto PerlException;
6058 }
6059
6060 region.x=0;
6061 region.y=0;
6062 region.width=image->columns;
6063 region.height=1;
6064 if (items == 1)
6065 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6066 for (i=2; i < items; i+=2)
6067 {
6068 attribute=(char *) SvPV(ST(i-1),na);
6069 switch (*attribute)
6070 {
6071 case 'g':
6072 case 'G':
6073 {
6074 if (LocaleCompare(attribute,"geometry") == 0)
6075 {
6076 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6077 break;
6078 }
6079 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6080 attribute);
6081 break;
6082 }
6083 case 'H':
6084 case 'h':
6085 {
6086 if (LocaleCompare(attribute,"height") == 0)
6087 {
6088 region.height=SvIV(ST(i));
6089 continue;
6090 }
6091 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6092 attribute);
6093 break;
6094 }
6095 case 'X':
6096 case 'x':
6097 {
6098 if (LocaleCompare(attribute,"x") == 0)
6099 {
6100 region.x=SvIV(ST(i));
6101 continue;
6102 }
6103 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6104 attribute);
6105 break;
6106 }
6107 case 'Y':
6108 case 'y':
6109 {
6110 if (LocaleCompare(attribute,"y") == 0)
6111 {
6112 region.y=SvIV(ST(i));
6113 continue;
6114 }
6115 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6116 attribute);
6117 break;
6118 }
6119 case 'W':
6120 case 'w':
6121 {
6122 if (LocaleCompare(attribute,"width") == 0)
6123 {
6124 region.width=SvIV(ST(i));
6125 continue;
6126 }
6127 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6128 attribute);
6129 break;
6130 }
6131 }
6132 }
6133 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6134 region.height,exception);
6135 if (blob != (void *) NULL)
6136 goto PerlEnd;
6137
6138 PerlException:
6139 InheritPerlException(exception,perl_exception);
6140 exception=DestroyExceptionInfo(exception);
6141 SvREFCNT_dec(perl_exception); /* throw away all errors */
6142
6143 PerlEnd:
6144 RETVAL = (void *) blob;
6145 }
6146 OUTPUT:
6147 RETVAL
6148
6149#
6150###############################################################################
6151# #
6152# #
6153# #
6154# G e t A u t h e n t i c M e t a c o n t e n t #
6155# #
6156# #
6157# #
6158###############################################################################
6159#
6160#
6161void *
6162GetAuthenticMetacontent(ref,...)
6163 Image::Magick ref = NO_INIT
6164 ALIAS:
6165 getauthenticmetacontent = 1
6166 GetMetacontent = 2
6167 getmetacontent = 3
6168 CODE:
6169 {
6170 ExceptionInfo
6171 *exception;
6172
6173 Image
6174 *image;
6175
6176 struct PackageInfo
6177 *info;
6178
6179 SV
6180 *perl_exception,
6181 *reference;
6182
6183 void
6184 *blob = NULL;
6185
6186 PERL_UNUSED_VAR(ref);
6187 PERL_UNUSED_VAR(ix);
6188 exception=AcquireExceptionInfo();
6189 perl_exception=newSVpv("",0);
6190 if (sv_isobject(ST(0)) == 0)
6191 {
6192 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6193 PackageName);
6194 goto PerlException;
6195 }
6196 reference=SvRV(ST(0));
6197
6198 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6199 if (image == (Image *) NULL)
6200 {
6201 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6202 PackageName);
6203 goto PerlException;
6204 }
6205
6206 blob=(void *) GetAuthenticMetacontent(image);
6207 if (blob != (void *) NULL)
6208 goto PerlEnd;
6209
6210 PerlException:
6211 InheritPerlException(exception,perl_exception);
6212 exception=DestroyExceptionInfo(exception);
6213 SvREFCNT_dec(perl_exception); /* throw away all errors */
6214
6215 PerlEnd:
6216 RETVAL = blob;
6217 }
6218 OUTPUT:
6219 RETVAL
6220
6221#
6222###############################################################################
6223# #
6224# #
6225# #
6226# G e t V i r t u a l M e t a c o n t e n t #
6227# #
6228# #
6229# #
6230###############################################################################
6231#
6232#
6233void *
6234GetVirtualMetacontent(ref,...)
6235 Image::Magick ref = NO_INIT
6236 ALIAS:
6237 getvirtualmetacontent = 1
6238 CODE:
6239 {
6240 ExceptionInfo
6241 *exception;
6242
6243 Image
6244 *image;
6245
6246 struct PackageInfo
6247 *info;
6248
6249 SV
6250 *perl_exception,
6251 *reference;
6252
6253 void
6254 *blob = NULL;
6255
6256 PERL_UNUSED_VAR(ref);
6257 PERL_UNUSED_VAR(ix);
6258 exception=AcquireExceptionInfo();
6259 perl_exception=newSVpv("",0);
6260 if (sv_isobject(ST(0)) == 0)
6261 {
6262 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6263 PackageName);
6264 goto PerlException;
6265 }
6266 reference=SvRV(ST(0));
6267
6268 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6269 if (image == (Image *) NULL)
6270 {
6271 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6272 PackageName);
6273 goto PerlException;
6274 }
6275
6276 blob=(void *) GetVirtualMetacontent(image);
6277 if (blob != (void *) NULL)
6278 goto PerlEnd;
6279
6280 PerlException:
6281 InheritPerlException(exception,perl_exception);
6282 exception=DestroyExceptionInfo(exception);
6283 SvREFCNT_dec(perl_exception); /* throw away all errors */
6284
6285 PerlEnd:
6286 RETVAL = blob;
6287 }
6288 OUTPUT:
6289 RETVAL
6290
6291#
6292###############################################################################
6293# #
6294# #
6295# #
6296# H i s t o g r a m #
6297# #
6298# #
6299# #
6300###############################################################################
6301#
6302#
6303void
6304Histogram(ref,...)
6305 Image::Magick ref=NO_INIT
6306 ALIAS:
6307 HistogramImage = 1
6308 histogram = 2
6309 histogramimage = 3
6310 PPCODE:
6311 {
6312 AV
6313 *av;
6314
6315 char
cristy151b66d2015-04-15 10:50:31 +00006316 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006317
6318 PixelInfo
6319 *histogram;
6320
6321 ExceptionInfo
6322 *exception;
6323
6324 Image
6325 *image;
6326
6327 register ssize_t
6328 i;
6329
6330 ssize_t
6331 count;
6332
6333 struct PackageInfo
6334 *info;
6335
6336 SV
6337 *perl_exception,
6338 *reference;
6339
6340 size_t
6341 number_colors;
6342
6343 PERL_UNUSED_VAR(ref);
6344 PERL_UNUSED_VAR(ix);
6345 exception=AcquireExceptionInfo();
6346 perl_exception=newSVpv("",0);
6347 av=NULL;
6348 if (sv_isobject(ST(0)) == 0)
6349 {
6350 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6351 PackageName);
6352 goto PerlException;
6353 }
6354 reference=SvRV(ST(0));
6355 av=newAV();
6356 SvREFCNT_dec(av);
6357 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6358 if (image == (Image *) NULL)
6359 {
6360 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6361 PackageName);
6362 goto PerlException;
6363 }
cristy4a3ce0a2013-08-03 20:06:59 +00006364 count=0;
6365 for ( ; image; image=image->next)
6366 {
6367 histogram=GetImageHistogram(image,&number_colors,exception);
6368 if (histogram == (PixelInfo *) NULL)
6369 continue;
6370 count+=(ssize_t) number_colors;
6371 EXTEND(sp,6*count);
6372 for (i=0; i < (ssize_t) number_colors; i++)
6373 {
cristy151b66d2015-04-15 10:50:31 +00006374 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006375 histogram[i].red);
6376 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006377 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006378 histogram[i].green);
6379 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006380 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006381 histogram[i].blue);
6382 PUSHs(sv_2mortal(newSVpv(message,0)));
6383 if (image->colorspace == CMYKColorspace)
6384 {
cristy151b66d2015-04-15 10:50:31 +00006385 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006386 histogram[i].black);
6387 PUSHs(sv_2mortal(newSVpv(message,0)));
6388 }
cristy151b66d2015-04-15 10:50:31 +00006389 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006390 histogram[i].alpha);
6391 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006392 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006393 histogram[i].count);
6394 PUSHs(sv_2mortal(newSVpv(message,0)));
6395 }
6396 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6397 }
6398
6399 PerlException:
6400 InheritPerlException(exception,perl_exception);
6401 exception=DestroyExceptionInfo(exception);
6402 SvREFCNT_dec(perl_exception);
6403 }
6404
6405#
6406###############################################################################
6407# #
6408# #
6409# #
6410# G e t P i x e l #
6411# #
6412# #
6413# #
6414###############################################################################
6415#
6416#
6417void
6418GetPixel(ref,...)
6419 Image::Magick ref=NO_INIT
6420 ALIAS:
6421 getpixel = 1
6422 getPixel = 2
6423 PPCODE:
6424 {
6425 AV
6426 *av;
6427
6428 char
6429 *attribute;
6430
6431 ExceptionInfo
6432 *exception;
6433
6434 Image
6435 *image;
6436
6437 MagickBooleanType
6438 normalize;
6439
6440 RectangleInfo
6441 region;
6442
6443 register const Quantum
6444 *p;
6445
6446 register ssize_t
6447 i;
6448
6449 ssize_t
6450 option;
6451
6452 struct PackageInfo
6453 *info;
6454
6455 SV
6456 *perl_exception,
6457 *reference; /* reference is the SV* of ref=SvIV(reference) */
6458
6459 PERL_UNUSED_VAR(ref);
6460 PERL_UNUSED_VAR(ix);
6461 exception=AcquireExceptionInfo();
6462 perl_exception=newSVpv("",0);
6463 reference=SvRV(ST(0));
6464 av=(AV *) reference;
6465 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6466 exception);
6467 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6468 if (image == (Image *) NULL)
6469 {
6470 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6471 PackageName);
6472 goto PerlException;
6473 }
6474 normalize=MagickTrue;
6475 region.x=0;
6476 region.y=0;
6477 region.width=image->columns;
6478 region.height=1;
6479 if (items == 1)
6480 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6481 for (i=2; i < items; i+=2)
6482 {
6483 attribute=(char *) SvPV(ST(i-1),na);
6484 switch (*attribute)
6485 {
6486 case 'C':
6487 case 'c':
6488 {
6489 if (LocaleCompare(attribute,"channel") == 0)
6490 {
6491 ssize_t
6492 option;
6493
6494 option=ParseChannelOption(SvPV(ST(i),na));
6495 if (option < 0)
6496 {
6497 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6498 SvPV(ST(i),na));
6499 return;
6500 }
cristybcd59342015-06-07 14:07:19 +00006501 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00006502 break;
6503 }
6504 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6505 attribute);
6506 break;
6507 }
6508 case 'g':
6509 case 'G':
6510 {
6511 if (LocaleCompare(attribute,"geometry") == 0)
6512 {
6513 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6514 break;
6515 }
6516 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6517 attribute);
6518 break;
6519 }
6520 case 'N':
6521 case 'n':
6522 {
6523 if (LocaleCompare(attribute,"normalize") == 0)
6524 {
6525 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6526 SvPV(ST(i),na));
6527 if (option < 0)
6528 {
6529 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6530 SvPV(ST(i),na));
6531 break;
6532 }
6533 normalize=option != 0 ? MagickTrue : MagickFalse;
6534 break;
6535 }
6536 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6537 attribute);
6538 break;
6539 }
6540 case 'x':
6541 case 'X':
6542 {
6543 if (LocaleCompare(attribute,"x") == 0)
6544 {
6545 region.x=SvIV(ST(i));
6546 break;
6547 }
6548 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6549 attribute);
6550 break;
6551 }
6552 case 'y':
6553 case 'Y':
6554 {
6555 if (LocaleCompare(attribute,"y") == 0)
6556 {
6557 region.y=SvIV(ST(i));
6558 break;
6559 }
6560 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6561 attribute);
6562 break;
6563 }
6564 default:
6565 {
6566 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6567 attribute);
6568 break;
6569 }
6570 }
6571 }
6572 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6573 if (p == (const Quantum *) NULL)
6574 PUSHs(&sv_undef);
6575 else
6576 {
6577 double
6578 scale;
6579
6580 scale=1.0;
6581 if (normalize != MagickFalse)
6582 scale=1.0/QuantumRange;
6583 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6584 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6585 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6586 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6587 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6588 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6589 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6590 (image->colorspace == CMYKColorspace))
6591 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6592 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6593 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6594 }
6595
6596 PerlException:
6597 InheritPerlException(exception,perl_exception);
6598 exception=DestroyExceptionInfo(exception);
6599 SvREFCNT_dec(perl_exception);
6600 }
6601
6602#
6603###############################################################################
6604# #
6605# #
6606# #
6607# G e t P i x e l s #
6608# #
6609# #
6610# #
6611###############################################################################
6612#
6613#
6614void
6615GetPixels(ref,...)
6616 Image::Magick ref=NO_INIT
6617 ALIAS:
6618 getpixels = 1
6619 getPixels = 2
6620 PPCODE:
6621 {
6622 AV
6623 *av;
6624
6625 char
6626 *attribute;
6627
6628 const char
6629 *map;
6630
6631 ExceptionInfo
6632 *exception;
6633
6634 Image
6635 *image;
6636
6637 MagickBooleanType
6638 normalize,
6639 status;
6640
6641 RectangleInfo
6642 region;
6643
6644 register ssize_t
6645 i;
6646
6647 ssize_t
6648 option;
6649
6650 struct PackageInfo
6651 *info;
6652
6653 SV
6654 *perl_exception,
6655 *reference; /* reference is the SV* of ref=SvIV(reference) */
6656
6657 PERL_UNUSED_VAR(ref);
6658 PERL_UNUSED_VAR(ix);
6659 exception=AcquireExceptionInfo();
6660 perl_exception=newSVpv("",0);
6661 reference=SvRV(ST(0));
6662 av=(AV *) reference;
6663 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6664 exception);
6665 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6666 if (image == (Image *) NULL)
6667 {
6668 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6669 PackageName);
6670 goto PerlException;
6671 }
6672 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006673 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006674 map="RGBA";
6675 if (image->colorspace == CMYKColorspace)
6676 {
6677 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006678 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006679 map="CMYKA";
6680 }
6681 normalize=MagickFalse;
6682 region.x=0;
6683 region.y=0;
6684 region.width=image->columns;
6685 region.height=1;
6686 if (items == 1)
6687 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6688 for (i=2; i < items; i+=2)
6689 {
6690 attribute=(char *) SvPV(ST(i-1),na);
6691 switch (*attribute)
6692 {
6693 case 'g':
6694 case 'G':
6695 {
6696 if (LocaleCompare(attribute,"geometry") == 0)
6697 {
6698 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6699 break;
6700 }
6701 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6702 attribute);
6703 break;
6704 }
6705 case 'H':
6706 case 'h':
6707 {
6708 if (LocaleCompare(attribute,"height") == 0)
6709 {
6710 region.height=SvIV(ST(i));
6711 break;
6712 }
6713 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6714 attribute);
6715 break;
6716 }
6717 case 'M':
6718 case 'm':
6719 {
6720 if (LocaleCompare(attribute,"map") == 0)
6721 {
6722 map=SvPV(ST(i),na);
6723 break;
6724 }
6725 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6726 attribute);
6727 break;
6728 }
6729 case 'N':
6730 case 'n':
6731 {
6732 if (LocaleCompare(attribute,"normalize") == 0)
6733 {
6734 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6735 SvPV(ST(i),na));
6736 if (option < 0)
6737 {
6738 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6739 SvPV(ST(i),na));
6740 break;
6741 }
6742 normalize=option != 0 ? MagickTrue : MagickFalse;
6743 break;
6744 }
6745 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6746 attribute);
6747 break;
6748 }
6749 case 'W':
6750 case 'w':
6751 {
6752 if (LocaleCompare(attribute,"width") == 0)
6753 {
6754 region.width=SvIV(ST(i));
6755 break;
6756 }
6757 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6758 attribute);
6759 break;
6760 }
6761 case 'x':
6762 case 'X':
6763 {
6764 if (LocaleCompare(attribute,"x") == 0)
6765 {
6766 region.x=SvIV(ST(i));
6767 break;
6768 }
6769 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6770 attribute);
6771 break;
6772 }
6773 case 'y':
6774 case 'Y':
6775 {
6776 if (LocaleCompare(attribute,"y") == 0)
6777 {
6778 region.y=SvIV(ST(i));
6779 break;
6780 }
6781 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6782 attribute);
6783 break;
6784 }
6785 default:
6786 {
6787 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6788 attribute);
6789 break;
6790 }
6791 }
6792 }
6793 if (normalize != MagickFalse)
6794 {
6795 float
6796 *pixels;
6797
6798 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6799 region.height*sizeof(*pixels));
6800 if (pixels == (float *) NULL)
6801 {
6802 ThrowPerlException(exception,ResourceLimitError,
6803 "MemoryAllocationFailed",PackageName);
6804 goto PerlException;
6805 }
6806 status=ExportImagePixels(image,region.x,region.y,region.width,
6807 region.height,map,FloatPixel,pixels,exception);
6808 if (status == MagickFalse)
6809 PUSHs(&sv_undef);
6810 else
6811 {
6812 EXTEND(sp,strlen(map)*region.width*region.height);
6813 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6814 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6815 }
6816 pixels=(float *) RelinquishMagickMemory(pixels);
6817 }
6818 else
6819 {
6820 Quantum
6821 *pixels;
6822
6823 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6824 region.height*sizeof(*pixels));
6825 if (pixels == (Quantum *) NULL)
6826 {
6827 ThrowPerlException(exception,ResourceLimitError,
6828 "MemoryAllocationFailed",PackageName);
6829 goto PerlException;
6830 }
6831 status=ExportImagePixels(image,region.x,region.y,region.width,
6832 region.height,map,QuantumPixel,pixels,exception);
6833 if (status == MagickFalse)
6834 PUSHs(&sv_undef);
6835 else
6836 {
6837 EXTEND(sp,strlen(map)*region.width*region.height);
6838 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6839 PUSHs(sv_2mortal(newSViv(pixels[i])));
6840 }
6841 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6842 }
6843
6844 PerlException:
6845 InheritPerlException(exception,perl_exception);
6846 exception=DestroyExceptionInfo(exception);
6847 SvREFCNT_dec(perl_exception);
6848 }
6849
6850#
6851###############################################################################
6852# #
6853# #
6854# #
6855# I m a g e T o B l o b #
6856# #
6857# #
6858# #
6859###############################################################################
6860#
6861#
6862void
6863ImageToBlob(ref,...)
6864 Image::Magick ref=NO_INIT
6865 ALIAS:
6866 ImageToBlob = 1
6867 imagetoblob = 2
6868 toblob = 3
6869 blob = 4
6870 PPCODE:
6871 {
6872 char
cristy151b66d2015-04-15 10:50:31 +00006873 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006874
6875 ExceptionInfo
6876 *exception;
6877
6878 Image
6879 *image,
6880 *next;
6881
6882 register ssize_t
6883 i;
6884
6885 struct PackageInfo
6886 *info,
6887 *package_info;
6888
6889 size_t
6890 length;
6891
6892 ssize_t
6893 scene;
6894
6895 SV
6896 *perl_exception,
6897 *reference;
6898
6899 void
6900 *blob;
6901
6902 PERL_UNUSED_VAR(ref);
6903 PERL_UNUSED_VAR(ix);
6904 exception=AcquireExceptionInfo();
6905 perl_exception=newSVpv("",0);
6906 package_info=(struct PackageInfo *) NULL;
6907 if (sv_isobject(ST(0)) == 0)
6908 {
6909 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6910 PackageName);
6911 goto PerlException;
6912 }
6913 reference=SvRV(ST(0));
6914 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6915 if (image == (Image *) NULL)
6916 {
6917 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6918 PackageName);
6919 goto PerlException;
6920 }
6921 package_info=ClonePackageInfo(info,exception);
6922 for (i=2; i < items; i+=2)
6923 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6924 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006925 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006926 scene=0;
6927 for (next=image; next; next=next->next)
6928 {
cristy151b66d2015-04-15 10:50:31 +00006929 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006930 next->scene=scene++;
6931 }
6932 SetImageInfo(package_info->image_info,(unsigned int)
6933 GetImageListLength(image),exception);
6934 EXTEND(sp,(ssize_t) GetImageListLength(image));
6935 for ( ; image; image=image->next)
6936 {
6937 length=0;
6938 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6939 if (blob != (char *) NULL)
6940 {
6941 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6942 blob=(unsigned char *) RelinquishMagickMemory(blob);
6943 }
6944 if (package_info->image_info->adjoin)
6945 break;
6946 }
6947
6948 PerlException:
6949 if (package_info != (struct PackageInfo *) NULL)
6950 DestroyPackageInfo(package_info);
6951 InheritPerlException(exception,perl_exception);
6952 exception=DestroyExceptionInfo(exception);
6953 SvREFCNT_dec(perl_exception); /* throw away all errors */
6954 }
6955
6956#
6957###############################################################################
6958# #
6959# #
6960# #
6961# L a y e r s #
6962# #
6963# #
6964# #
6965###############################################################################
6966#
6967#
6968void
6969Layers(ref,...)
6970 Image::Magick ref=NO_INIT
6971 ALIAS:
6972 Layers = 1
6973 layers = 2
6974 OptimizeImageLayers = 3
6975 optimizelayers = 4
6976 optimizeimagelayers = 5
6977 PPCODE:
6978 {
6979 AV
6980 *av;
6981
6982 char
6983 *attribute;
6984
6985 CompositeOperator
6986 compose;
6987
6988 ExceptionInfo
6989 *exception;
6990
6991 HV
6992 *hv;
6993
6994 Image
6995 *image,
6996 *layers;
6997
6998 LayerMethod
6999 method;
7000
7001 register ssize_t
7002 i;
7003
7004 ssize_t
7005 option,
7006 sp;
7007
7008 struct PackageInfo
7009 *info;
7010
7011 SV
7012 *av_reference,
7013 *perl_exception,
7014 *reference,
7015 *rv,
7016 *sv;
7017
7018 PERL_UNUSED_VAR(ref);
7019 PERL_UNUSED_VAR(ix);
7020 exception=AcquireExceptionInfo();
7021 perl_exception=newSVpv("",0);
7022 sv=NULL;
7023 if (sv_isobject(ST(0)) == 0)
7024 {
7025 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7026 PackageName);
7027 goto PerlException;
7028 }
7029 reference=SvRV(ST(0));
7030 hv=SvSTASH(reference);
7031 av=newAV();
7032 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7033 SvREFCNT_dec(av);
7034 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7035 if (image == (Image *) NULL)
7036 {
7037 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7038 PackageName);
7039 goto PerlException;
7040 }
7041 compose=image->compose;
7042 method=OptimizeLayer;
7043 for (i=2; i < items; i+=2)
7044 {
7045 attribute=(char *) SvPV(ST(i-1),na);
7046 switch (*attribute)
7047 {
7048 case 'C':
7049 case 'c':
7050 {
7051 if (LocaleCompare(attribute,"compose") == 0)
7052 {
7053 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7054 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7055 if (sp < 0)
7056 {
7057 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7058 SvPV(ST(i),na));
7059 break;
7060 }
7061 compose=(CompositeOperator) sp;
7062 break;
7063 }
7064 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7065 attribute);
7066 break;
7067 }
7068 case 'M':
7069 case 'm':
7070 {
7071 if (LocaleCompare(attribute,"method") == 0)
7072 {
7073 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7074 SvPV(ST(i),na));
7075 if (option < 0)
7076 {
7077 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7078 SvPV(ST(i),na));
7079 break;
7080 }
7081 method=(LayerMethod) option;
7082 break;
7083 }
7084 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7085 attribute);
7086 break;
7087 }
7088 default:
7089 {
7090 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7091 attribute);
7092 break;
7093 }
7094 }
7095 }
7096 layers=(Image *) NULL;
7097 switch (method)
7098 {
7099 case CompareAnyLayer:
7100 case CompareClearLayer:
7101 case CompareOverlayLayer:
7102 default:
7103 {
7104 layers=CompareImagesLayers(image,method,exception);
7105 break;
7106 }
7107 case MergeLayer:
7108 case FlattenLayer:
7109 case MosaicLayer:
7110 {
7111 layers=MergeImageLayers(image,method,exception);
7112 break;
7113 }
7114 case DisposeLayer:
7115 {
7116 layers=DisposeImages(image,exception);
7117 break;
7118 }
7119 case OptimizeImageLayer:
7120 {
7121 layers=OptimizeImageLayers(image,exception);
7122 break;
7123 }
7124 case OptimizePlusLayer:
7125 {
7126 layers=OptimizePlusImageLayers(image,exception);
7127 break;
7128 }
7129 case OptimizeTransLayer:
7130 {
7131 OptimizeImageTransparency(image,exception);
7132 break;
7133 }
7134 case RemoveDupsLayer:
7135 {
7136 RemoveDuplicateLayers(&image,exception);
7137 break;
7138 }
7139 case RemoveZeroLayer:
7140 {
7141 RemoveZeroDelayLayers(&image,exception);
7142 break;
7143 }
7144 case OptimizeLayer:
7145 {
7146 QuantizeInfo
7147 *quantize_info;
7148
7149 /*
7150 General Purpose, GIF Animation Optimizer.
7151 */
7152 layers=CoalesceImages(image,exception);
7153 if (layers == (Image *) NULL)
7154 break;
7155 image=layers;
7156 layers=OptimizeImageLayers(image,exception);
7157 if (layers == (Image *) NULL)
7158 break;
7159 image=DestroyImageList(image);
7160 image=layers;
7161 layers=(Image *) NULL;
7162 OptimizeImageTransparency(image,exception);
7163 quantize_info=AcquireQuantizeInfo(info->image_info);
7164 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7165 quantize_info=DestroyQuantizeInfo(quantize_info);
7166 break;
7167 }
7168 case CompositeLayer:
7169 {
7170 Image
7171 *source;
7172
7173 RectangleInfo
7174 geometry;
7175
7176 /*
7177 Split image sequence at the first 'NULL:' image.
7178 */
7179 source=image;
7180 while (source != (Image *) NULL)
7181 {
7182 source=GetNextImageInList(source);
7183 if ((source != (Image *) NULL) &&
7184 (LocaleCompare(source->magick,"NULL") == 0))
7185 break;
7186 }
7187 if (source != (Image *) NULL)
7188 {
7189 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7190 (GetNextImageInList(source) == (Image *) NULL))
7191 source=(Image *) NULL;
7192 else
7193 {
7194 /*
7195 Separate the two lists, junk the null: image.
7196 */
7197 source=SplitImageList(source->previous);
7198 DeleteImageFromList(&source);
7199 }
7200 }
7201 if (source == (Image *) NULL)
7202 {
7203 (void) ThrowMagickException(exception,GetMagickModule(),
7204 OptionError,"MissingNullSeparator","layers Composite");
7205 break;
7206 }
7207 /*
7208 Adjust offset with gravity and virtual canvas.
7209 */
7210 SetGeometry(image,&geometry);
7211 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7212 geometry.width=source->page.width != 0 ? source->page.width :
7213 source->columns;
7214 geometry.height=source->page.height != 0 ? source->page.height :
7215 source->rows;
7216 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7217 image->columns,image->page.height != 0 ? image->page.height :
7218 image->rows,image->gravity,&geometry);
7219 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7220 source=DestroyImageList(source);
7221 break;
7222 }
7223 }
7224 if (layers != (Image *) NULL)
7225 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007226 else
7227 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007228 if (image == (Image *) NULL)
7229 goto PerlException;
7230 for ( ; image; image=image->next)
7231 {
7232 AddImageToRegistry(sv,image);
7233 rv=newRV(sv);
7234 av_push(av,sv_bless(rv,hv));
7235 SvREFCNT_dec(sv);
7236 }
7237 exception=DestroyExceptionInfo(exception);
7238 ST(0)=av_reference;
7239 SvREFCNT_dec(perl_exception);
7240 XSRETURN(1);
7241
7242 PerlException:
7243 InheritPerlException(exception,perl_exception);
7244 exception=DestroyExceptionInfo(exception);
7245 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7246 SvPOK_on(perl_exception);
7247 ST(0)=sv_2mortal(perl_exception);
7248 XSRETURN(1);
7249 }
7250
7251#
7252###############################################################################
7253# #
7254# #
7255# #
7256# M a g i c k T o M i m e #
7257# #
7258# #
7259# #
7260###############################################################################
7261#
7262#
7263SV *
7264MagickToMime(ref,name)
7265 Image::Magick ref=NO_INIT
7266 char *name
7267 ALIAS:
7268 magicktomime = 1
7269 CODE:
7270 {
7271 char
7272 *mime;
7273
7274 PERL_UNUSED_VAR(ref);
7275 PERL_UNUSED_VAR(ix);
7276 mime=MagickToMime(name);
7277 RETVAL=newSVpv(mime,0);
7278 mime=(char *) RelinquishMagickMemory(mime);
7279 }
7280 OUTPUT:
7281 RETVAL
7282
7283#
7284###############################################################################
7285# #
7286# #
7287# #
7288# M o g r i f y #
7289# #
7290# #
7291# #
7292###############################################################################
7293#
7294#
7295void
7296Mogrify(ref,...)
7297 Image::Magick ref=NO_INIT
7298 ALIAS:
7299 Comment = 1
7300 CommentImage = 2
7301 Label = 3
7302 LabelImage = 4
7303 AddNoise = 5
7304 AddNoiseImage = 6
7305 Colorize = 7
7306 ColorizeImage = 8
7307 Border = 9
7308 BorderImage = 10
7309 Blur = 11
7310 BlurImage = 12
7311 Chop = 13
7312 ChopImage = 14
7313 Crop = 15
7314 CropImage = 16
7315 Despeckle = 17
7316 DespeckleImage = 18
7317 Edge = 19
7318 EdgeImage = 20
7319 Emboss = 21
7320 EmbossImage = 22
7321 Enhance = 23
7322 EnhanceImage = 24
7323 Flip = 25
7324 FlipImage = 26
7325 Flop = 27
7326 FlopImage = 28
7327 Frame = 29
7328 FrameImage = 30
7329 Implode = 31
7330 ImplodeImage = 32
7331 Magnify = 33
7332 MagnifyImage = 34
7333 MedianFilter = 35
7334 MedianConvolveImage = 36
7335 Minify = 37
7336 MinifyImage = 38
7337 OilPaint = 39
7338 OilPaintImage = 40
7339 ReduceNoise = 41
7340 ReduceNoiseImage = 42
7341 Roll = 43
7342 RollImage = 44
7343 Rotate = 45
7344 RotateImage = 46
7345 Sample = 47
7346 SampleImage = 48
7347 Scale = 49
7348 ScaleImage = 50
7349 Shade = 51
7350 ShadeImage = 52
7351 Sharpen = 53
7352 SharpenImage = 54
7353 Shear = 55
7354 ShearImage = 56
7355 Spread = 57
7356 SpreadImage = 58
7357 Swirl = 59
7358 SwirlImage = 60
7359 Resize = 61
7360 ResizeImage = 62
7361 Zoom = 63
7362 ZoomImage = 64
7363 Annotate = 65
7364 AnnotateImage = 66
7365 ColorFloodfill = 67
7366 ColorFloodfillImage= 68
7367 Composite = 69
7368 CompositeImage = 70
7369 Contrast = 71
7370 ContrastImage = 72
7371 CycleColormap = 73
7372 CycleColormapImage = 74
7373 Draw = 75
7374 DrawImage = 76
7375 Equalize = 77
7376 EqualizeImage = 78
7377 Gamma = 79
7378 GammaImage = 80
7379 Map = 81
7380 MapImage = 82
7381 MatteFloodfill = 83
7382 MatteFloodfillImage= 84
7383 Modulate = 85
7384 ModulateImage = 86
7385 Negate = 87
7386 NegateImage = 88
7387 Normalize = 89
7388 NormalizeImage = 90
7389 NumberColors = 91
7390 NumberColorsImage = 92
7391 Opaque = 93
7392 OpaqueImage = 94
7393 Quantize = 95
7394 QuantizeImage = 96
7395 Raise = 97
7396 RaiseImage = 98
7397 Segment = 99
7398 SegmentImage = 100
7399 Signature = 101
7400 SignatureImage = 102
7401 Solarize = 103
7402 SolarizeImage = 104
7403 Sync = 105
7404 SyncImage = 106
7405 Texture = 107
7406 TextureImage = 108
7407 Evaluate = 109
7408 EvaluateImage = 110
7409 Transparent = 111
7410 TransparentImage = 112
7411 Threshold = 113
7412 ThresholdImage = 114
7413 Charcoal = 115
7414 CharcoalImage = 116
7415 Trim = 117
7416 TrimImage = 118
7417 Wave = 119
7418 WaveImage = 120
7419 Separate = 121
7420 SeparateImage = 122
7421 Stereo = 125
7422 StereoImage = 126
7423 Stegano = 127
7424 SteganoImage = 128
7425 Deconstruct = 129
7426 DeconstructImage = 130
7427 GaussianBlur = 131
7428 GaussianBlurImage = 132
7429 Convolve = 133
7430 ConvolveImage = 134
7431 Profile = 135
7432 ProfileImage = 136
7433 UnsharpMask = 137
7434 UnsharpMaskImage = 138
7435 MotionBlur = 139
7436 MotionBlurImage = 140
7437 OrderedDither = 141
7438 OrderedDitherImage = 142
7439 Shave = 143
7440 ShaveImage = 144
7441 Level = 145
7442 LevelImage = 146
7443 Clip = 147
7444 ClipImage = 148
7445 AffineTransform = 149
7446 AffineTransformImage = 150
7447 Difference = 151
7448 DifferenceImage = 152
7449 AdaptiveThreshold = 153
7450 AdaptiveThresholdImage = 154
7451 Resample = 155
7452 ResampleImage = 156
7453 Describe = 157
7454 DescribeImage = 158
7455 BlackThreshold = 159
7456 BlackThresholdImage= 160
7457 WhiteThreshold = 161
7458 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007459 RotationalBlur = 163
7460 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007461 Thumbnail = 165
7462 ThumbnailImage = 166
7463 Strip = 167
7464 StripImage = 168
7465 Tint = 169
7466 TintImage = 170
7467 Channel = 171
7468 ChannelImage = 172
7469 Splice = 173
7470 SpliceImage = 174
7471 Posterize = 175
7472 PosterizeImage = 176
7473 Shadow = 177
7474 ShadowImage = 178
7475 Identify = 179
7476 IdentifyImage = 180
7477 SepiaTone = 181
7478 SepiaToneImage = 182
7479 SigmoidalContrast = 183
7480 SigmoidalContrastImage = 184
7481 Extent = 185
7482 ExtentImage = 186
7483 Vignette = 187
7484 VignetteImage = 188
7485 ContrastStretch = 189
7486 ContrastStretchImage = 190
7487 Sans0 = 191
7488 Sans0Image = 192
7489 Sans1 = 193
7490 Sans1Image = 194
7491 AdaptiveSharpen = 195
7492 AdaptiveSharpenImage = 196
7493 Transpose = 197
7494 TransposeImage = 198
7495 Transverse = 199
7496 TransverseImage = 200
7497 AutoOrient = 201
7498 AutoOrientImage = 202
7499 AdaptiveBlur = 203
7500 AdaptiveBlurImage = 204
7501 Sketch = 205
7502 SketchImage = 206
7503 UniqueColors = 207
7504 UniqueColorsImage = 208
7505 AdaptiveResize = 209
7506 AdaptiveResizeImage= 210
7507 ClipMask = 211
7508 ClipMaskImage = 212
7509 LinearStretch = 213
7510 LinearStretchImage = 214
7511 ColorMatrix = 215
7512 ColorMatrixImage = 216
7513 Mask = 217
7514 MaskImage = 218
7515 Polaroid = 219
7516 PolaroidImage = 220
7517 FloodfillPaint = 221
7518 FloodfillPaintImage= 222
7519 Distort = 223
7520 DistortImage = 224
7521 Clut = 225
7522 ClutImage = 226
7523 LiquidRescale = 227
7524 LiquidRescaleImage = 228
7525 Encipher = 229
7526 EncipherImage = 230
7527 Decipher = 231
7528 DecipherImage = 232
7529 Deskew = 233
7530 DeskewImage = 234
7531 Remap = 235
7532 RemapImage = 236
7533 SparseColor = 237
7534 SparseColorImage = 238
7535 Function = 239
7536 FunctionImage = 240
7537 SelectiveBlur = 241
7538 SelectiveBlurImage = 242
7539 HaldClut = 243
7540 HaldClutImage = 244
7541 BlueShift = 245
7542 BlueShiftImage = 246
7543 ForwardFourierTransform = 247
7544 ForwardFourierTransformImage = 248
7545 InverseFourierTransform = 249
7546 InverseFourierTransformImage = 250
7547 ColorDecisionList = 251
7548 ColorDecisionListImage = 252
7549 AutoGamma = 253
7550 AutoGammaImage = 254
7551 AutoLevel = 255
7552 AutoLevelImage = 256
7553 LevelColors = 257
7554 LevelImageColors = 258
7555 Clamp = 259
7556 ClampImage = 260
7557 BrightnessContrast = 261
7558 BrightnessContrastImage = 262
7559 Morphology = 263
7560 MorphologyImage = 264
Cristy3ca633e2016-02-13 12:49:01 -05007561 Mode = 265
7562 ModeImage = 266
7563 Statistic = 267
7564 StatisticImage = 268
7565 Perceptible = 269
7566 PerceptibleImage = 270
7567 Poly = 271
7568 PolyImage = 272
7569 Grayscale = 273
7570 GrayscaleImage = 274
7571 CannyEdge = 275
7572 CannyEdgeImage = 276
7573 HoughLine = 277
7574 HoughLineImage = 278
7575 MeanShift = 279
7576 MeanShiftImage = 280
7577 Kuwahara = 281
7578 KuwaharaImage = 282
7579 ConnectedComponent = 283
7580 ConnectedComponentImage = 284
7581 CopyPixels = 285
7582 CopyImagePixels = 286
Cristy5488c982016-02-13 14:07:50 -05007583 Color = 287
7584 ColorImage = 288
cristy4a3ce0a2013-08-03 20:06:59 +00007585 MogrifyRegion = 666
7586 PPCODE:
7587 {
7588 AffineMatrix
7589 affine,
7590 current;
7591
7592 char
7593 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007594 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007595
7596 ChannelType
7597 channel,
7598 channel_mask;
7599
7600 CompositeOperator
7601 compose;
7602
7603 const char
7604 *attribute,
7605 *value;
7606
7607 double
7608 angle;
7609
7610 ExceptionInfo
7611 *exception;
7612
7613 GeometryInfo
7614 geometry_info;
7615
7616 Image
7617 *image,
7618 *next,
7619 *region_image;
7620
7621 MagickBooleanType
7622 status;
7623
7624 MagickStatusType
7625 flags;
7626
7627 PixelInfo
7628 fill_color;
7629
7630 RectangleInfo
7631 geometry,
7632 region_info;
7633
7634 register ssize_t
7635 i;
7636
7637 ssize_t
7638 base,
7639 j,
7640 number_images;
7641
7642 struct Methods
7643 *rp;
7644
7645 struct PackageInfo
7646 *info;
7647
7648 SV
7649 *perl_exception,
7650 **pv,
7651 *reference,
7652 **reference_vector;
7653
7654 struct ArgumentList
7655 argument_list[MaxArguments];
7656
7657 PERL_UNUSED_VAR(ref);
7658 PERL_UNUSED_VAR(ix);
7659 exception=AcquireExceptionInfo();
7660 perl_exception=newSVpv("",0);
7661 reference_vector=NULL;
7662 region_image=NULL;
7663 number_images=0;
7664 base=2;
7665 if (sv_isobject(ST(0)) == 0)
7666 {
7667 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7668 PackageName);
7669 goto PerlException;
7670 }
7671 reference=SvRV(ST(0));
7672 region_info.width=0;
7673 region_info.height=0;
7674 region_info.x=0;
7675 region_info.y=0;
7676 region_image=(Image *) NULL;
7677 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7678 if (ix && (ix != 666))
7679 {
7680 /*
7681 Called as Method(...)
7682 */
7683 ix=(ix+1)/2;
7684 rp=(&Methods[ix-1]);
7685 attribute=rp->name;
7686 }
7687 else
7688 {
7689 /*
7690 Called as Mogrify("Method",...)
7691 */
7692 attribute=(char *) SvPV(ST(1),na);
7693 if (ix)
7694 {
7695 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7696 attribute=(char *) SvPV(ST(2),na);
7697 base++;
7698 }
7699 for (rp=Methods; ; rp++)
7700 {
7701 if (rp >= EndOf(Methods))
7702 {
7703 ThrowPerlException(exception,OptionError,
7704 "UnrecognizedPerlMagickMethod",attribute);
7705 goto PerlException;
7706 }
7707 if (strEQcase(attribute,rp->name))
7708 break;
7709 }
7710 ix=rp-Methods+1;
7711 base++;
7712 }
7713 if (image == (Image *) NULL)
7714 {
7715 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7716 goto PerlException;
7717 }
7718 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7719 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7720 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7721 {
7722 Arguments
7723 *pp,
7724 *qq;
7725
7726 ssize_t
7727 ssize_test;
7728
7729 struct ArgumentList
7730 *al;
7731
7732 SV
7733 *sv;
7734
7735 sv=NULL;
7736 ssize_test=0;
7737 pp=(Arguments *) NULL;
7738 qq=rp->arguments;
7739 if (i == items)
7740 {
7741 pp=rp->arguments,
7742 sv=ST(i-1);
7743 }
7744 else
7745 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7746 {
7747 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7748 break;
7749 if (strEQcase(attribute,qq->method) > ssize_test)
7750 {
7751 pp=qq;
7752 ssize_test=strEQcase(attribute,qq->method);
7753 }
7754 }
7755 if (pp == (Arguments *) NULL)
7756 {
7757 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7758 attribute);
7759 goto continue_outer_loop;
7760 }
7761 al=(&argument_list[pp-rp->arguments]);
7762 switch (pp->type)
7763 {
7764 case ArrayReference:
7765 {
7766 if (SvTYPE(sv) != SVt_RV)
7767 {
cristy151b66d2015-04-15 10:50:31 +00007768 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007769 "invalid %.60s value",pp->method);
7770 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7771 goto continue_outer_loop;
7772 }
7773 al->array_reference=SvRV(sv);
7774 break;
7775 }
7776 case RealReference:
7777 {
7778 al->real_reference=SvNV(sv);
7779 break;
7780 }
7781 case FileReference:
7782 {
7783 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7784 break;
7785 }
7786 case ImageReference:
7787 {
7788 if (!sv_isobject(sv) ||
7789 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7790 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7791 {
7792 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7793 PackageName);
7794 goto PerlException;
7795 }
7796 break;
7797 }
7798 case IntegerReference:
7799 {
7800 al->integer_reference=SvIV(sv);
7801 break;
7802 }
7803 case StringReference:
7804 {
7805 al->string_reference=(char *) SvPV(sv,al->length);
7806 if (sv_isobject(sv))
7807 al->image_reference=SetupList(aTHX_ SvRV(sv),
7808 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7809 break;
7810 }
7811 default:
7812 {
7813 /*
7814 Is a string; look up name.
7815 */
7816 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7817 {
7818 al->string_reference=(char *) SvPV(sv,al->length);
7819 al->integer_reference=(-1);
7820 break;
7821 }
7822 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7823 MagickFalse,SvPV(sv,na));
7824 if (pp->type == MagickChannelOptions)
7825 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7826 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7827 {
cristy151b66d2015-04-15 10:50:31 +00007828 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007829 "invalid %.60s value",pp->method);
7830 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7831 goto continue_outer_loop;
7832 }
7833 break;
7834 }
7835 }
7836 attribute_flag[pp-rp->arguments]++;
7837 continue_outer_loop: ;
7838 }
7839 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7840 pv=reference_vector;
7841 SetGeometryInfo(&geometry_info);
7842 channel=DefaultChannels;
7843 for (next=image; next; next=next->next)
7844 {
7845 image=next;
7846 SetGeometry(image,&geometry);
7847 if ((region_info.width*region_info.height) != 0)
7848 {
7849 region_image=image;
7850 image=CropImage(image,&region_info,exception);
7851 }
7852 switch (ix)
7853 {
7854 default:
7855 {
cristy151b66d2015-04-15 10:50:31 +00007856 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007857 ThrowPerlException(exception,OptionError,
7858 "UnrecognizedPerlMagickMethod",message);
7859 goto PerlException;
7860 }
7861 case 1: /* Comment */
7862 {
7863 if (attribute_flag[0] == 0)
7864 argument_list[0].string_reference=(char *) NULL;
7865 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7866 info ? info->image_info : (ImageInfo *) NULL,image,
7867 argument_list[0].string_reference,exception),exception);
7868 break;
7869 }
7870 case 2: /* Label */
7871 {
7872 if (attribute_flag[0] == 0)
7873 argument_list[0].string_reference=(char *) NULL;
7874 (void) SetImageProperty(image,"label",InterpretImageProperties(
7875 info ? info->image_info : (ImageInfo *) NULL,image,
7876 argument_list[0].string_reference,exception),exception);
7877 break;
7878 }
7879 case 3: /* AddNoise */
7880 {
7881 double
7882 attenuate;
7883
7884 if (attribute_flag[0] == 0)
7885 argument_list[0].integer_reference=UniformNoise;
7886 attenuate=1.0;
7887 if (attribute_flag[1] != 0)
7888 attenuate=argument_list[1].real_reference;
7889 if (attribute_flag[2] != 0)
7890 channel=(ChannelType) argument_list[2].integer_reference;
7891 channel_mask=SetImageChannelMask(image,channel);
7892 image=AddNoiseImage(image,(NoiseType)
7893 argument_list[0].integer_reference,attenuate,exception);
7894 if (image != (Image *) NULL)
7895 (void) SetImageChannelMask(image,channel_mask);
7896 break;
7897 }
7898 case 4: /* Colorize */
7899 {
7900 PixelInfo
7901 target;
7902
7903 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7904 0,0,&target,exception);
7905 if (attribute_flag[0] != 0)
7906 (void) QueryColorCompliance(argument_list[0].string_reference,
7907 AllCompliance,&target,exception);
7908 if (attribute_flag[1] == 0)
7909 argument_list[1].string_reference="100%";
7910 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7911 exception);
7912 break;
7913 }
7914 case 5: /* Border */
7915 {
7916 CompositeOperator
7917 compose;
7918
7919 geometry.width=0;
7920 geometry.height=0;
7921 if (attribute_flag[0] != 0)
7922 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7923 &geometry,exception);
7924 if (attribute_flag[1] != 0)
7925 geometry.width=argument_list[1].integer_reference;
7926 if (attribute_flag[2] != 0)
7927 geometry.height=argument_list[2].integer_reference;
7928 if (attribute_flag[3] != 0)
7929 QueryColorCompliance(argument_list[3].string_reference,
7930 AllCompliance,&image->border_color,exception);
7931 if (attribute_flag[4] != 0)
7932 QueryColorCompliance(argument_list[4].string_reference,
7933 AllCompliance,&image->border_color,exception);
7934 if (attribute_flag[5] != 0)
7935 QueryColorCompliance(argument_list[5].string_reference,
7936 AllCompliance,&image->border_color,exception);
7937 compose=image->compose;
7938 if (attribute_flag[6] != 0)
7939 compose=(CompositeOperator) argument_list[6].integer_reference;
7940 image=BorderImage(image,&geometry,compose,exception);
7941 break;
7942 }
7943 case 6: /* Blur */
7944 {
7945 if (attribute_flag[0] != 0)
7946 {
7947 flags=ParseGeometry(argument_list[0].string_reference,
7948 &geometry_info);
7949 if ((flags & SigmaValue) == 0)
7950 geometry_info.sigma=1.0;
7951 }
7952 if (attribute_flag[1] != 0)
7953 geometry_info.rho=argument_list[1].real_reference;
7954 if (attribute_flag[2] != 0)
7955 geometry_info.sigma=argument_list[2].real_reference;
7956 if (attribute_flag[3] != 0)
7957 channel=(ChannelType) argument_list[3].integer_reference;
7958 channel_mask=SetImageChannelMask(image,channel);
7959 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
7960 exception);
7961 if (image != (Image *) NULL)
7962 (void) SetImageChannelMask(image,channel_mask);
7963 break;
7964 }
7965 case 7: /* Chop */
7966 {
cristy260bd762014-08-15 12:46:34 +00007967 if (attribute_flag[5] != 0)
7968 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00007969 if (attribute_flag[0] != 0)
7970 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7971 &geometry,exception);
7972 if (attribute_flag[1] != 0)
7973 geometry.width=argument_list[1].integer_reference;
7974 if (attribute_flag[2] != 0)
7975 geometry.height=argument_list[2].integer_reference;
7976 if (attribute_flag[3] != 0)
7977 geometry.x=argument_list[3].integer_reference;
7978 if (attribute_flag[4] != 0)
7979 geometry.y=argument_list[4].integer_reference;
7980 image=ChopImage(image,&geometry,exception);
7981 break;
7982 }
7983 case 8: /* Crop */
7984 {
7985 if (attribute_flag[6] != 0)
7986 image->gravity=(GravityType) argument_list[6].integer_reference;
7987 if (attribute_flag[0] != 0)
7988 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7989 &geometry,exception);
7990 if (attribute_flag[1] != 0)
7991 geometry.width=argument_list[1].integer_reference;
7992 if (attribute_flag[2] != 0)
7993 geometry.height=argument_list[2].integer_reference;
7994 if (attribute_flag[3] != 0)
7995 geometry.x=argument_list[3].integer_reference;
7996 if (attribute_flag[4] != 0)
7997 geometry.y=argument_list[4].integer_reference;
7998 if (attribute_flag[5] != 0)
7999 image->fuzz=StringToDoubleInterval(
8000 argument_list[5].string_reference,(double) QuantumRange+1.0);
8001 image=CropImage(image,&geometry,exception);
8002 break;
8003 }
8004 case 9: /* Despeckle */
8005 {
8006 image=DespeckleImage(image,exception);
8007 break;
8008 }
8009 case 10: /* Edge */
8010 {
8011 if (attribute_flag[0] != 0)
8012 geometry_info.rho=argument_list[0].real_reference;
8013 image=EdgeImage(image,geometry_info.rho,exception);
8014 break;
8015 }
8016 case 11: /* Emboss */
8017 {
8018 if (attribute_flag[0] != 0)
8019 {
8020 flags=ParseGeometry(argument_list[0].string_reference,
8021 &geometry_info);
8022 if ((flags & SigmaValue) == 0)
8023 geometry_info.sigma=1.0;
8024 }
8025 if (attribute_flag[1] != 0)
8026 geometry_info.rho=argument_list[1].real_reference;
8027 if (attribute_flag[2] != 0)
8028 geometry_info.sigma=argument_list[2].real_reference;
8029 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8030 exception);
8031 break;
8032 }
8033 case 12: /* Enhance */
8034 {
8035 image=EnhanceImage(image,exception);
8036 break;
8037 }
8038 case 13: /* Flip */
8039 {
8040 image=FlipImage(image,exception);
8041 break;
8042 }
8043 case 14: /* Flop */
8044 {
8045 image=FlopImage(image,exception);
8046 break;
8047 }
8048 case 15: /* Frame */
8049 {
8050 CompositeOperator
8051 compose;
8052
8053 FrameInfo
8054 frame_info;
8055
8056 if (attribute_flag[0] != 0)
8057 {
8058 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8059 &geometry,exception);
8060 frame_info.width=geometry.width;
8061 frame_info.height=geometry.height;
8062 frame_info.outer_bevel=geometry.x;
8063 frame_info.inner_bevel=geometry.y;
8064 }
8065 if (attribute_flag[1] != 0)
8066 frame_info.width=argument_list[1].integer_reference;
8067 if (attribute_flag[2] != 0)
8068 frame_info.height=argument_list[2].integer_reference;
8069 if (attribute_flag[3] != 0)
8070 frame_info.inner_bevel=argument_list[3].integer_reference;
8071 if (attribute_flag[4] != 0)
8072 frame_info.outer_bevel=argument_list[4].integer_reference;
8073 if (attribute_flag[5] != 0)
8074 QueryColorCompliance(argument_list[5].string_reference,
8075 AllCompliance,&fill_color,exception);
8076 if (attribute_flag[6] != 0)
8077 QueryColorCompliance(argument_list[6].string_reference,
8078 AllCompliance,&fill_color,exception);
8079 frame_info.x=(ssize_t) frame_info.width;
8080 frame_info.y=(ssize_t) frame_info.height;
8081 frame_info.width=image->columns+2*frame_info.x;
8082 frame_info.height=image->rows+2*frame_info.y;
8083 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
Cristy8645e042016-02-03 16:35:29 -05008084 image->alpha_color=fill_color;
cristy4a3ce0a2013-08-03 20:06:59 +00008085 compose=image->compose;
8086 if (attribute_flag[7] != 0)
8087 compose=(CompositeOperator) argument_list[7].integer_reference;
8088 image=FrameImage(image,&frame_info,compose,exception);
8089 break;
8090 }
8091 case 16: /* Implode */
8092 {
8093 PixelInterpolateMethod
8094 method;
8095
8096 if (attribute_flag[0] == 0)
8097 argument_list[0].real_reference=0.5;
8098 method=UndefinedInterpolatePixel;
8099 if (attribute_flag[1] != 0)
8100 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8101 image=ImplodeImage(image,argument_list[0].real_reference,
8102 method,exception);
8103 break;
8104 }
8105 case 17: /* Magnify */
8106 {
8107 image=MagnifyImage(image,exception);
8108 break;
8109 }
8110 case 18: /* MedianFilter */
8111 {
8112 if (attribute_flag[0] != 0)
8113 {
8114 flags=ParseGeometry(argument_list[0].string_reference,
8115 &geometry_info);
8116 if ((flags & SigmaValue) == 0)
8117 geometry_info.sigma=geometry_info.rho;
8118 }
8119 if (attribute_flag[1] != 0)
8120 geometry_info.rho=argument_list[1].real_reference;
8121 if (attribute_flag[2] != 0)
8122 geometry_info.sigma=argument_list[2].real_reference;
8123 if (attribute_flag[3] != 0)
8124 channel=(ChannelType) argument_list[3].integer_reference;
8125 channel_mask=SetImageChannelMask(image,channel);
8126 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8127 (size_t) geometry_info.sigma,exception);
8128 if (image != (Image *) NULL)
8129 (void) SetImageChannelMask(image,channel_mask);
8130 break;
8131 }
8132 case 19: /* Minify */
8133 {
8134 image=MinifyImage(image,exception);
8135 break;
8136 }
8137 case 20: /* OilPaint */
8138 {
8139 if (attribute_flag[0] == 0)
8140 argument_list[0].real_reference=0.0;
8141 if (attribute_flag[1] == 0)
8142 argument_list[1].real_reference=1.0;
8143 image=OilPaintImage(image,argument_list[0].real_reference,
8144 argument_list[1].real_reference,exception);
8145 break;
8146 }
8147 case 21: /* ReduceNoise */
8148 {
8149 if (attribute_flag[0] != 0)
8150 {
8151 flags=ParseGeometry(argument_list[0].string_reference,
8152 &geometry_info);
8153 if ((flags & SigmaValue) == 0)
8154 geometry_info.sigma=1.0;
8155 }
8156 if (attribute_flag[1] != 0)
8157 geometry_info.rho=argument_list[1].real_reference;
8158 if (attribute_flag[2] != 0)
8159 geometry_info.sigma=argument_list[2].real_reference;
8160 if (attribute_flag[3] != 0)
8161 channel=(ChannelType) argument_list[3].integer_reference;
8162 channel_mask=SetImageChannelMask(image,channel);
8163 image=StatisticImage(image,NonpeakStatistic,(size_t)
8164 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8165 if (image != (Image *) NULL)
8166 (void) SetImageChannelMask(image,channel_mask);
8167 break;
8168 }
8169 case 22: /* Roll */
8170 {
8171 if (attribute_flag[0] != 0)
8172 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8173 &geometry,exception);
8174 if (attribute_flag[1] != 0)
8175 geometry.x=argument_list[1].integer_reference;
8176 if (attribute_flag[2] != 0)
8177 geometry.y=argument_list[2].integer_reference;
8178 image=RollImage(image,geometry.x,geometry.y,exception);
8179 break;
8180 }
8181 case 23: /* Rotate */
8182 {
8183 if (attribute_flag[0] == 0)
8184 argument_list[0].real_reference=90.0;
8185 if (attribute_flag[1] != 0)
8186 {
8187 QueryColorCompliance(argument_list[1].string_reference,
8188 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008189 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8190 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008191 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8192 }
8193 image=RotateImage(image,argument_list[0].real_reference,exception);
8194 break;
8195 }
8196 case 24: /* Sample */
8197 {
8198 if (attribute_flag[0] != 0)
8199 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8200 &geometry,exception);
8201 if (attribute_flag[1] != 0)
8202 geometry.width=argument_list[1].integer_reference;
8203 if (attribute_flag[2] != 0)
8204 geometry.height=argument_list[2].integer_reference;
8205 image=SampleImage(image,geometry.width,geometry.height,exception);
8206 break;
8207 }
8208 case 25: /* Scale */
8209 {
8210 if (attribute_flag[0] != 0)
8211 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8212 &geometry,exception);
8213 if (attribute_flag[1] != 0)
8214 geometry.width=argument_list[1].integer_reference;
8215 if (attribute_flag[2] != 0)
8216 geometry.height=argument_list[2].integer_reference;
8217 image=ScaleImage(image,geometry.width,geometry.height,exception);
8218 break;
8219 }
8220 case 26: /* Shade */
8221 {
8222 if (attribute_flag[0] != 0)
8223 {
8224 flags=ParseGeometry(argument_list[0].string_reference,
8225 &geometry_info);
8226 if ((flags & SigmaValue) == 0)
8227 geometry_info.sigma=0.0;
8228 }
8229 if (attribute_flag[1] != 0)
8230 geometry_info.rho=argument_list[1].real_reference;
8231 if (attribute_flag[2] != 0)
8232 geometry_info.sigma=argument_list[2].real_reference;
8233 image=ShadeImage(image,
8234 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8235 geometry_info.rho,geometry_info.sigma,exception);
8236 break;
8237 }
8238 case 27: /* Sharpen */
8239 {
8240 if (attribute_flag[0] != 0)
8241 {
8242 flags=ParseGeometry(argument_list[0].string_reference,
8243 &geometry_info);
8244 if ((flags & SigmaValue) == 0)
8245 geometry_info.sigma=1.0;
8246 }
8247 if (attribute_flag[1] != 0)
8248 geometry_info.rho=argument_list[1].real_reference;
8249 if (attribute_flag[2] != 0)
8250 geometry_info.sigma=argument_list[2].real_reference;
8251 if (attribute_flag[3] != 0)
8252 channel=(ChannelType) argument_list[3].integer_reference;
8253 channel_mask=SetImageChannelMask(image,channel);
8254 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8255 exception);
8256 if (image != (Image *) NULL)
8257 (void) SetImageChannelMask(image,channel_mask);
8258 break;
8259 }
8260 case 28: /* Shear */
8261 {
8262 if (attribute_flag[0] != 0)
8263 {
8264 flags=ParseGeometry(argument_list[0].string_reference,
8265 &geometry_info);
8266 if ((flags & SigmaValue) == 0)
8267 geometry_info.sigma=geometry_info.rho;
8268 }
8269 if (attribute_flag[1] != 0)
8270 geometry_info.rho=argument_list[1].real_reference;
8271 if (attribute_flag[2] != 0)
8272 geometry_info.sigma=argument_list[2].real_reference;
8273 if (attribute_flag[3] != 0)
8274 QueryColorCompliance(argument_list[3].string_reference,
8275 AllCompliance,&image->background_color,exception);
8276 if (attribute_flag[4] != 0)
8277 QueryColorCompliance(argument_list[4].string_reference,
8278 AllCompliance,&image->background_color,exception);
8279 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8280 exception);
8281 break;
8282 }
8283 case 29: /* Spread */
8284 {
Cristye3319c12015-08-24 07:11:48 -04008285 PixelInterpolateMethod
8286 method;
8287
cristy4a3ce0a2013-08-03 20:06:59 +00008288 if (attribute_flag[0] == 0)
8289 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008290 method=UndefinedInterpolatePixel;
8291 if (attribute_flag[1] != 0)
8292 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8293 image=SpreadImage(image,method,argument_list[0].real_reference,
8294 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008295 break;
8296 }
8297 case 30: /* Swirl */
8298 {
8299 PixelInterpolateMethod
8300 method;
8301
8302 if (attribute_flag[0] == 0)
8303 argument_list[0].real_reference=50.0;
8304 method=UndefinedInterpolatePixel;
8305 if (attribute_flag[1] != 0)
8306 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8307 image=SwirlImage(image,argument_list[0].real_reference,
8308 method,exception);
8309 break;
8310 }
8311 case 31: /* Resize */
8312 case 32: /* Zoom */
8313 {
8314 if (attribute_flag[0] != 0)
8315 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8316 &geometry,exception);
8317 if (attribute_flag[1] != 0)
8318 geometry.width=argument_list[1].integer_reference;
8319 if (attribute_flag[2] != 0)
8320 geometry.height=argument_list[2].integer_reference;
8321 if (attribute_flag[3] == 0)
8322 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8323 if (attribute_flag[4] != 0)
8324 SetImageArtifact(image,"filter:support",
8325 argument_list[4].string_reference);
8326 image=ResizeImage(image,geometry.width,geometry.height,
Cristy8645e042016-02-03 16:35:29 -05008327 (FilterType) argument_list[3].integer_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00008328 exception);
8329 break;
8330 }
8331 case 33: /* Annotate */
8332 {
8333 DrawInfo
8334 *draw_info;
8335
8336 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8337 (DrawInfo *) NULL);
8338 if (attribute_flag[0] != 0)
8339 {
8340 char
8341 *text;
8342
8343 text=InterpretImageProperties(info ? info->image_info :
8344 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8345 exception);
8346 (void) CloneString(&draw_info->text,text);
8347 text=DestroyString(text);
8348 }
8349 if (attribute_flag[1] != 0)
8350 (void) CloneString(&draw_info->font,
8351 argument_list[1].string_reference);
8352 if (attribute_flag[2] != 0)
8353 draw_info->pointsize=argument_list[2].real_reference;
8354 if (attribute_flag[3] != 0)
8355 (void) CloneString(&draw_info->density,
8356 argument_list[3].string_reference);
8357 if (attribute_flag[4] != 0)
8358 (void) QueryColorCompliance(argument_list[4].string_reference,
8359 AllCompliance,&draw_info->undercolor,exception);
8360 if (attribute_flag[5] != 0)
8361 {
8362 (void) QueryColorCompliance(argument_list[5].string_reference,
8363 AllCompliance,&draw_info->stroke,exception);
8364 if (argument_list[5].image_reference != (Image *) NULL)
8365 draw_info->stroke_pattern=CloneImage(
8366 argument_list[5].image_reference,0,0,MagickTrue,exception);
8367 }
8368 if (attribute_flag[6] != 0)
8369 {
8370 (void) QueryColorCompliance(argument_list[6].string_reference,
8371 AllCompliance,&draw_info->fill,exception);
8372 if (argument_list[6].image_reference != (Image *) NULL)
8373 draw_info->fill_pattern=CloneImage(
8374 argument_list[6].image_reference,0,0,MagickTrue,exception);
8375 }
8376 if (attribute_flag[7] != 0)
8377 {
8378 (void) CloneString(&draw_info->geometry,
8379 argument_list[7].string_reference);
8380 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8381 &geometry,exception);
8382 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8383 geometry_info.sigma=geometry_info.xi;
8384 }
8385 if (attribute_flag[8] != 0)
8386 (void) QueryColorCompliance(argument_list[8].string_reference,
8387 AllCompliance,&draw_info->fill,exception);
8388 if (attribute_flag[11] != 0)
8389 draw_info->gravity=(GravityType)
8390 argument_list[11].integer_reference;
8391 if (attribute_flag[25] != 0)
8392 {
8393 AV
8394 *av;
8395
8396 av=(AV *) argument_list[25].array_reference;
8397 if ((av_len(av) != 3) && (av_len(av) != 5))
8398 {
8399 ThrowPerlException(exception,OptionError,
8400 "affine matrix must have 4 or 6 elements",PackageName);
8401 goto PerlException;
8402 }
8403 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8404 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8405 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8406 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8407 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8408 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8409 {
8410 ThrowPerlException(exception,OptionError,
8411 "affine matrix is singular",PackageName);
8412 goto PerlException;
8413 }
8414 if (av_len(av) == 5)
8415 {
8416 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8417 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8418 }
8419 }
8420 for (j=12; j < 17; j++)
8421 {
8422 if (attribute_flag[j] == 0)
8423 continue;
8424 value=argument_list[j].string_reference;
8425 angle=argument_list[j].real_reference;
8426 current=draw_info->affine;
8427 GetAffineMatrix(&affine);
8428 switch (j)
8429 {
8430 case 12:
8431 {
8432 /*
8433 Translate.
8434 */
8435 flags=ParseGeometry(value,&geometry_info);
8436 affine.tx=geometry_info.xi;
8437 affine.ty=geometry_info.psi;
8438 if ((flags & PsiValue) == 0)
8439 affine.ty=affine.tx;
8440 break;
8441 }
8442 case 13:
8443 {
8444 /*
8445 Scale.
8446 */
8447 flags=ParseGeometry(value,&geometry_info);
8448 affine.sx=geometry_info.rho;
8449 affine.sy=geometry_info.sigma;
8450 if ((flags & SigmaValue) == 0)
8451 affine.sy=affine.sx;
8452 break;
8453 }
8454 case 14:
8455 {
8456 /*
8457 Rotate.
8458 */
8459 if (angle == 0.0)
8460 break;
8461 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8462 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8463 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8464 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8465 break;
8466 }
8467 case 15:
8468 {
8469 /*
8470 SkewX.
8471 */
8472 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8473 break;
8474 }
8475 case 16:
8476 {
8477 /*
8478 SkewY.
8479 */
8480 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8481 break;
8482 }
8483 }
8484 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8485 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8486 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8487 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8488 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8489 current.tx;
8490 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8491 current.ty;
8492 }
8493 if (attribute_flag[9] == 0)
8494 argument_list[9].real_reference=0.0;
8495 if (attribute_flag[10] == 0)
8496 argument_list[10].real_reference=0.0;
8497 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8498 {
8499 char
cristy151b66d2015-04-15 10:50:31 +00008500 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008501
cristy151b66d2015-04-15 10:50:31 +00008502 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008503 (double) argument_list[9].real_reference+draw_info->affine.tx,
8504 (double) argument_list[10].real_reference+draw_info->affine.ty);
8505 (void) CloneString(&draw_info->geometry,geometry);
8506 }
8507 if (attribute_flag[17] != 0)
8508 draw_info->stroke_width=argument_list[17].real_reference;
8509 if (attribute_flag[18] != 0)
8510 {
8511 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8512 MagickTrue : MagickFalse;
8513 draw_info->stroke_antialias=draw_info->text_antialias;
8514 }
8515 if (attribute_flag[19] != 0)
8516 (void) CloneString(&draw_info->family,
8517 argument_list[19].string_reference);
8518 if (attribute_flag[20] != 0)
8519 draw_info->style=(StyleType) argument_list[20].integer_reference;
8520 if (attribute_flag[21] != 0)
8521 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8522 if (attribute_flag[22] != 0)
8523 draw_info->weight=argument_list[22].integer_reference;
8524 if (attribute_flag[23] != 0)
8525 draw_info->align=(AlignType) argument_list[23].integer_reference;
8526 if (attribute_flag[24] != 0)
8527 (void) CloneString(&draw_info->encoding,
8528 argument_list[24].string_reference);
8529 if (attribute_flag[25] != 0)
8530 draw_info->fill_pattern=CloneImage(
8531 argument_list[25].image_reference,0,0,MagickTrue,exception);
8532 if (attribute_flag[26] != 0)
8533 draw_info->fill_pattern=CloneImage(
8534 argument_list[26].image_reference,0,0,MagickTrue,exception);
8535 if (attribute_flag[27] != 0)
8536 draw_info->stroke_pattern=CloneImage(
8537 argument_list[27].image_reference,0,0,MagickTrue,exception);
8538 if (attribute_flag[29] != 0)
8539 draw_info->kerning=argument_list[29].real_reference;
8540 if (attribute_flag[30] != 0)
8541 draw_info->interline_spacing=argument_list[30].real_reference;
8542 if (attribute_flag[31] != 0)
8543 draw_info->interword_spacing=argument_list[31].real_reference;
8544 if (attribute_flag[32] != 0)
8545 draw_info->direction=(DirectionType)
8546 argument_list[32].integer_reference;
8547 (void) AnnotateImage(image,draw_info,exception);
8548 draw_info=DestroyDrawInfo(draw_info);
8549 break;
8550 }
8551 case 34: /* ColorFloodfill */
8552 {
8553 DrawInfo
8554 *draw_info;
8555
8556 MagickBooleanType
8557 invert;
8558
8559 PixelInfo
8560 target;
8561
8562 draw_info=CloneDrawInfo(info ? info->image_info :
8563 (ImageInfo *) NULL,(DrawInfo *) NULL);
8564 if (attribute_flag[0] != 0)
8565 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8566 &geometry,exception);
8567 if (attribute_flag[1] != 0)
8568 geometry.x=argument_list[1].integer_reference;
8569 if (attribute_flag[2] != 0)
8570 geometry.y=argument_list[2].integer_reference;
8571 if (attribute_flag[3] != 0)
8572 (void) QueryColorCompliance(argument_list[3].string_reference,
8573 AllCompliance,&draw_info->fill,exception);
8574 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8575 geometry.x,geometry.y,&target,exception);
8576 invert=MagickFalse;
8577 if (attribute_flag[4] != 0)
8578 {
8579 QueryColorCompliance(argument_list[4].string_reference,
8580 AllCompliance,&target,exception);
8581 invert=MagickTrue;
8582 }
8583 if (attribute_flag[5] != 0)
8584 image->fuzz=StringToDoubleInterval(
8585 argument_list[5].string_reference,(double) QuantumRange+1.0);
8586 if (attribute_flag[6] != 0)
8587 invert=(MagickBooleanType) argument_list[6].integer_reference;
8588 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8589 geometry.y,invert,exception);
8590 draw_info=DestroyDrawInfo(draw_info);
8591 break;
8592 }
8593 case 35: /* Composite */
8594 {
8595 char
cristy151b66d2015-04-15 10:50:31 +00008596 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008597
8598 Image
8599 *composite_image,
8600 *rotate_image;
8601
8602 MagickBooleanType
8603 clip_to_self;
8604
8605 compose=OverCompositeOp;
8606 if (attribute_flag[0] != 0)
8607 composite_image=argument_list[0].image_reference;
8608 else
8609 {
8610 ThrowPerlException(exception,OptionError,
8611 "CompositeImageRequired",PackageName);
8612 goto PerlException;
8613 }
8614 /*
8615 Parameter Handling used for BOTH normal and tiled composition.
8616 */
8617 if (attribute_flag[1] != 0) /* compose */
8618 compose=(CompositeOperator) argument_list[1].integer_reference;
8619 if (attribute_flag[6] != 0) /* opacity */
8620 {
8621 if (compose != DissolveCompositeOp)
8622 (void) SetImageAlpha(composite_image,(Quantum)
8623 StringToDoubleInterval(argument_list[6].string_reference,
8624 (double) QuantumRange+1.0),exception);
8625 else
8626 {
8627 CacheView
8628 *composite_view;
8629
8630 double
8631 opacity;
8632
8633 MagickBooleanType
8634 sync;
8635
8636 register ssize_t
8637 x;
8638
8639 register Quantum
8640 *q;
8641
8642 ssize_t
8643 y;
8644
8645 /*
8646 Handle dissolve composite operator (patch by
8647 Kevin A. McGrail).
8648 */
8649 (void) CloneString(&image->geometry,
8650 argument_list[6].string_reference);
8651 opacity=(Quantum) StringToDoubleInterval(
8652 argument_list[6].string_reference,(double) QuantumRange+
8653 1.0);
cristy17f11b02014-12-20 19:37:04 +00008654 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008655 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8656 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8657 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8658 {
8659 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8660 composite_image->columns,1,exception);
8661 for (x=0; x < (ssize_t) composite_image->columns; x++)
8662 {
8663 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8664 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8665 q);
8666 q+=GetPixelChannels(composite_image);
8667 }
8668 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8669 if (sync == MagickFalse)
8670 break;
8671 }
8672 composite_view=DestroyCacheView(composite_view);
8673 }
8674 }
8675 if (attribute_flag[9] != 0) /* "color=>" */
8676 QueryColorCompliance(argument_list[9].string_reference,
8677 AllCompliance,&composite_image->background_color,exception);
8678 if (attribute_flag[12] != 0) /* "interpolate=>" */
8679 image->interpolate=(PixelInterpolateMethod)
8680 argument_list[12].integer_reference;
8681 if (attribute_flag[13] != 0) /* "args=>" */
8682 (void) SetImageArtifact(composite_image,"compose:args",
8683 argument_list[13].string_reference);
8684 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8685 (void) SetImageArtifact(composite_image,"compose:args",
8686 argument_list[14].string_reference);
8687 clip_to_self=MagickTrue;
8688 if (attribute_flag[15] != 0)
8689 clip_to_self=(MagickBooleanType)
8690 argument_list[15].integer_reference;
8691 /*
8692 Tiling Composition (with orthogonal rotate).
8693 */
8694 rotate_image=(Image *) NULL;
8695 if (attribute_flag[8] != 0) /* "rotate=>" */
8696 {
8697 /*
8698 Rotate image.
8699 */
8700 rotate_image=RotateImage(composite_image,
8701 argument_list[8].real_reference,exception);
8702 if (rotate_image == (Image *) NULL)
8703 break;
8704 }
8705 if ((attribute_flag[7] != 0) &&
8706 (argument_list[7].integer_reference != 0)) /* tile */
8707 {
8708 ssize_t
8709 x,
8710 y;
8711
8712 /*
8713 Tile the composite image.
8714 */
8715 if (attribute_flag[8] != 0) /* "tile=>" */
8716 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8717 "false");
8718 else
8719 (void) SetImageArtifact(composite_image,
8720 "compose:outside-overlay","false");
8721 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8722 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8723 {
8724 if (attribute_flag[8] != 0) /* rotate */
8725 (void) CompositeImage(image,rotate_image,compose,
8726 MagickTrue,x,y,exception);
8727 else
8728 (void) CompositeImage(image,composite_image,compose,
8729 MagickTrue,x,y,exception);
8730 }
8731 if (attribute_flag[8] != 0) /* rotate */
8732 rotate_image=DestroyImage(rotate_image);
8733 break;
8734 }
8735 /*
8736 Parameter Handling used used ONLY for normal composition.
8737 */
8738 if (attribute_flag[5] != 0) /* gravity */
8739 image->gravity=(GravityType) argument_list[5].integer_reference;
8740 if (attribute_flag[2] != 0) /* geometry offset */
8741 {
8742 SetGeometry(image,&geometry);
8743 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8744 &geometry);
8745 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8746 &geometry);
8747 }
8748 if (attribute_flag[3] != 0) /* x offset */
8749 geometry.x=argument_list[3].integer_reference;
8750 if (attribute_flag[4] != 0) /* y offset */
8751 geometry.y=argument_list[4].integer_reference;
8752 if (attribute_flag[10] != 0) /* mask */
8753 {
8754 if ((image->compose == DisplaceCompositeOp) ||
8755 (image->compose == DistortCompositeOp))
8756 {
8757 /*
8758 Merge Y displacement into X displacement image.
8759 */
8760 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8761 exception);
8762 (void) CompositeImage(composite_image,
8763 argument_list[10].image_reference,CopyGreenCompositeOp,
8764 MagickTrue,0,0,exception);
8765 }
8766 else
8767 {
8768 Image
8769 *mask_image;
8770
8771 /*
8772 Set a blending mask for the composition.
8773 */
8774 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8775 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008776 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008777 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008778 mask_image=DestroyImage(mask_image);
8779 }
8780 }
8781 if (attribute_flag[11] != 0) /* channel */
8782 channel=(ChannelType) argument_list[11].integer_reference;
8783 /*
8784 Composite two images (normal composition).
8785 */
cristy151b66d2015-04-15 10:50:31 +00008786 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008787 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8788 (double) composite_image->rows,(double) geometry.x,(double)
8789 geometry.y);
8790 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8791 exception);
8792 channel_mask=SetImageChannelMask(image,channel);
8793 if (attribute_flag[8] == 0) /* no rotate */
8794 CompositeImage(image,composite_image,compose,clip_to_self,
8795 geometry.x,geometry.y,exception);
8796 else
8797 {
8798 /*
8799 Position adjust rotated image then composite.
8800 */
8801 geometry.x-=(ssize_t) (rotate_image->columns-
8802 composite_image->columns)/2;
8803 geometry.y-=(ssize_t) (rotate_image->rows-
8804 composite_image->rows)/2;
8805 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8806 geometry.y,exception);
8807 rotate_image=DestroyImage(rotate_image);
8808 }
8809 if (attribute_flag[10] != 0) /* mask */
8810 {
8811 if ((image->compose == DisplaceCompositeOp) ||
8812 (image->compose == DistortCompositeOp))
8813 composite_image=DestroyImage(composite_image);
8814 else
cristy1f7ffb72015-07-29 11:07:03 +00008815 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008816 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008817 }
8818 (void) SetImageChannelMask(image,channel_mask);
8819 break;
8820 }
8821 case 36: /* Contrast */
8822 {
8823 if (attribute_flag[0] == 0)
8824 argument_list[0].integer_reference=0;
8825 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8826 MagickTrue : MagickFalse,exception);
8827 break;
8828 }
8829 case 37: /* CycleColormap */
8830 {
8831 if (attribute_flag[0] == 0)
8832 argument_list[0].integer_reference=6;
8833 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8834 exception);
8835 break;
8836 }
8837 case 38: /* Draw */
8838 {
8839 DrawInfo
8840 *draw_info;
8841
8842 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8843 (DrawInfo *) NULL);
8844 (void) CloneString(&draw_info->primitive,"point");
8845 if (attribute_flag[0] != 0)
8846 {
8847 if (argument_list[0].integer_reference < 0)
8848 (void) CloneString(&draw_info->primitive,
8849 argument_list[0].string_reference);
8850 else
8851 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8852 MagickPrimitiveOptions,argument_list[0].integer_reference));
8853 }
8854 if (attribute_flag[1] != 0)
8855 {
8856 if (LocaleCompare(draw_info->primitive,"path") == 0)
8857 {
8858 (void) ConcatenateString(&draw_info->primitive," '");
8859 ConcatenateString(&draw_info->primitive,
8860 argument_list[1].string_reference);
8861 (void) ConcatenateString(&draw_info->primitive,"'");
8862 }
8863 else
8864 {
8865 (void) ConcatenateString(&draw_info->primitive," ");
8866 ConcatenateString(&draw_info->primitive,
8867 argument_list[1].string_reference);
8868 }
8869 }
8870 if (attribute_flag[2] != 0)
8871 {
8872 (void) ConcatenateString(&draw_info->primitive," ");
8873 (void) ConcatenateString(&draw_info->primitive,
8874 CommandOptionToMnemonic(MagickMethodOptions,
8875 argument_list[2].integer_reference));
8876 }
8877 if (attribute_flag[3] != 0)
8878 {
8879 (void) QueryColorCompliance(argument_list[3].string_reference,
8880 AllCompliance,&draw_info->stroke,exception);
8881 if (argument_list[3].image_reference != (Image *) NULL)
8882 draw_info->stroke_pattern=CloneImage(
8883 argument_list[3].image_reference,0,0,MagickTrue,exception);
8884 }
8885 if (attribute_flag[4] != 0)
8886 {
8887 (void) QueryColorCompliance(argument_list[4].string_reference,
8888 AllCompliance,&draw_info->fill,exception);
8889 if (argument_list[4].image_reference != (Image *) NULL)
8890 draw_info->fill_pattern=CloneImage(
8891 argument_list[4].image_reference,0,0,MagickTrue,exception);
8892 }
8893 if (attribute_flag[5] != 0)
8894 draw_info->stroke_width=argument_list[5].real_reference;
8895 if (attribute_flag[6] != 0)
8896 (void) CloneString(&draw_info->font,
8897 argument_list[6].string_reference);
8898 if (attribute_flag[7] != 0)
8899 (void) QueryColorCompliance(argument_list[7].string_reference,
8900 AllCompliance,&draw_info->border_color,exception);
8901 if (attribute_flag[8] != 0)
8902 draw_info->affine.tx=argument_list[8].real_reference;
8903 if (attribute_flag[9] != 0)
8904 draw_info->affine.ty=argument_list[9].real_reference;
8905 if (attribute_flag[20] != 0)
8906 {
8907 AV
8908 *av;
8909
8910 av=(AV *) argument_list[20].array_reference;
8911 if ((av_len(av) != 3) && (av_len(av) != 5))
8912 {
8913 ThrowPerlException(exception,OptionError,
8914 "affine matrix must have 4 or 6 elements",PackageName);
8915 goto PerlException;
8916 }
8917 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8918 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8919 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8920 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8921 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8922 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8923 {
8924 ThrowPerlException(exception,OptionError,
8925 "affine matrix is singular",PackageName);
8926 goto PerlException;
8927 }
8928 if (av_len(av) == 5)
8929 {
8930 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8931 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8932 }
8933 }
8934 for (j=10; j < 15; j++)
8935 {
8936 if (attribute_flag[j] == 0)
8937 continue;
8938 value=argument_list[j].string_reference;
8939 angle=argument_list[j].real_reference;
8940 current=draw_info->affine;
8941 GetAffineMatrix(&affine);
8942 switch (j)
8943 {
8944 case 10:
8945 {
8946 /*
8947 Translate.
8948 */
8949 flags=ParseGeometry(value,&geometry_info);
8950 affine.tx=geometry_info.xi;
8951 affine.ty=geometry_info.psi;
8952 if ((flags & PsiValue) == 0)
8953 affine.ty=affine.tx;
8954 break;
8955 }
8956 case 11:
8957 {
8958 /*
8959 Scale.
8960 */
8961 flags=ParseGeometry(value,&geometry_info);
8962 affine.sx=geometry_info.rho;
8963 affine.sy=geometry_info.sigma;
8964 if ((flags & SigmaValue) == 0)
8965 affine.sy=affine.sx;
8966 break;
8967 }
8968 case 12:
8969 {
8970 /*
8971 Rotate.
8972 */
8973 if (angle == 0.0)
8974 break;
8975 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8976 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8977 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8978 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8979 break;
8980 }
8981 case 13:
8982 {
8983 /*
8984 SkewX.
8985 */
8986 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8987 break;
8988 }
8989 case 14:
8990 {
8991 /*
8992 SkewY.
8993 */
8994 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8995 break;
8996 }
8997 }
8998 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8999 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9000 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9001 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9002 draw_info->affine.tx=
9003 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9004 draw_info->affine.ty=
9005 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9006 }
9007 if (attribute_flag[15] != 0)
9008 draw_info->fill_pattern=CloneImage(
9009 argument_list[15].image_reference,0,0,MagickTrue,exception);
9010 if (attribute_flag[16] != 0)
9011 draw_info->pointsize=argument_list[16].real_reference;
9012 if (attribute_flag[17] != 0)
9013 {
9014 draw_info->stroke_antialias=argument_list[17].integer_reference != 0
9015 ? MagickTrue : MagickFalse;
9016 draw_info->text_antialias=draw_info->stroke_antialias;
9017 }
9018 if (attribute_flag[18] != 0)
9019 (void) CloneString(&draw_info->density,
9020 argument_list[18].string_reference);
9021 if (attribute_flag[19] != 0)
9022 draw_info->stroke_width=argument_list[19].real_reference;
9023 if (attribute_flag[21] != 0)
9024 draw_info->dash_offset=argument_list[21].real_reference;
9025 if (attribute_flag[22] != 0)
9026 {
9027 AV
9028 *av;
9029
9030 av=(AV *) argument_list[22].array_reference;
9031 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9032 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9033 if (draw_info->dash_pattern != (double *) NULL)
9034 {
9035 for (i=0; i <= av_len(av); i++)
9036 draw_info->dash_pattern[i]=(double)
9037 SvNV(*(av_fetch(av,i,0)));
9038 draw_info->dash_pattern[i]=0.0;
9039 }
9040 }
9041 if (attribute_flag[23] != 0)
9042 image->interpolate=(PixelInterpolateMethod)
9043 argument_list[23].integer_reference;
9044 if ((attribute_flag[24] != 0) &&
9045 (draw_info->fill_pattern != (Image *) NULL))
9046 flags=ParsePageGeometry(draw_info->fill_pattern,
9047 argument_list[24].string_reference,
9048 &draw_info->fill_pattern->tile_offset,exception);
9049 if (attribute_flag[25] != 0)
9050 {
9051 (void) ConcatenateString(&draw_info->primitive," '");
9052 (void) ConcatenateString(&draw_info->primitive,
9053 argument_list[25].string_reference);
9054 (void) ConcatenateString(&draw_info->primitive,"'");
9055 }
9056 if (attribute_flag[26] != 0)
9057 draw_info->fill_pattern=CloneImage(
9058 argument_list[26].image_reference,0,0,MagickTrue,exception);
9059 if (attribute_flag[27] != 0)
9060 draw_info->stroke_pattern=CloneImage(
9061 argument_list[27].image_reference,0,0,MagickTrue,exception);
9062 if (attribute_flag[28] != 0)
9063 (void) CloneString(&draw_info->primitive,
9064 argument_list[28].string_reference);
9065 if (attribute_flag[29] != 0)
9066 draw_info->kerning=argument_list[29].real_reference;
9067 if (attribute_flag[30] != 0)
9068 draw_info->interline_spacing=argument_list[30].real_reference;
9069 if (attribute_flag[31] != 0)
9070 draw_info->interword_spacing=argument_list[31].real_reference;
9071 if (attribute_flag[32] != 0)
9072 draw_info->direction=(DirectionType)
9073 argument_list[32].integer_reference;
9074 DrawImage(image,draw_info,exception);
9075 draw_info=DestroyDrawInfo(draw_info);
9076 break;
9077 }
9078 case 39: /* Equalize */
9079 {
9080 if (attribute_flag[0] != 0)
9081 channel=(ChannelType) argument_list[0].integer_reference;
9082 channel_mask=SetImageChannelMask(image,channel);
9083 EqualizeImage(image,exception);
9084 (void) SetImageChannelMask(image,channel_mask);
9085 break;
9086 }
9087 case 40: /* Gamma */
9088 {
9089 if (attribute_flag[1] != 0)
9090 channel=(ChannelType) argument_list[1].integer_reference;
9091 if (attribute_flag[2] == 0)
9092 argument_list[2].real_reference=1.0;
9093 if (attribute_flag[3] == 0)
9094 argument_list[3].real_reference=1.0;
9095 if (attribute_flag[4] == 0)
9096 argument_list[4].real_reference=1.0;
9097 if (attribute_flag[0] == 0)
9098 {
cristy151b66d2015-04-15 10:50:31 +00009099 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00009100 "%.15g,%.15g,%.15g",(double) argument_list[2].real_reference,
9101 (double) argument_list[3].real_reference,
9102 (double) argument_list[4].real_reference);
9103 argument_list[0].string_reference=message;
9104 }
9105 (void) GammaImage(image,StringToDouble(
9106 argument_list[0].string_reference,(char **) NULL),exception);
9107 break;
9108 }
9109 case 41: /* Map */
9110 {
9111 QuantizeInfo
9112 *quantize_info;
9113
9114 if (attribute_flag[0] == 0)
9115 {
9116 ThrowPerlException(exception,OptionError,"MapImageRequired",
9117 PackageName);
9118 goto PerlException;
9119 }
9120 quantize_info=AcquireQuantizeInfo(info->image_info);
9121 if (attribute_flag[1] != 0)
9122 quantize_info->dither_method=(DitherMethod)
9123 argument_list[1].integer_reference;
9124 (void) RemapImages(quantize_info,image,
9125 argument_list[0].image_reference,exception);
9126 quantize_info=DestroyQuantizeInfo(quantize_info);
9127 break;
9128 }
9129 case 42: /* MatteFloodfill */
9130 {
9131 DrawInfo
9132 *draw_info;
9133
9134 MagickBooleanType
9135 invert;
9136
9137 PixelInfo
9138 target;
9139
9140 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9141 (DrawInfo *) NULL);
9142 if (attribute_flag[0] != 0)
9143 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9144 &geometry,exception);
9145 if (attribute_flag[1] != 0)
9146 geometry.x=argument_list[1].integer_reference;
9147 if (attribute_flag[2] != 0)
9148 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009149 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009150 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9151 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9152 geometry.x,geometry.y,&target,exception);
9153 if (attribute_flag[4] != 0)
9154 QueryColorCompliance(argument_list[4].string_reference,
9155 AllCompliance,&target,exception);
9156 if (attribute_flag[3] != 0)
9157 target.alpha=StringToDoubleInterval(
9158 argument_list[3].string_reference,(double) (double) QuantumRange+
9159 1.0);
9160 if (attribute_flag[5] != 0)
9161 image->fuzz=StringToDoubleInterval(
9162 argument_list[5].string_reference,(double) QuantumRange+1.0);
9163 invert=MagickFalse;
9164 if (attribute_flag[6] != 0)
9165 invert=(MagickBooleanType) argument_list[6].integer_reference;
9166 channel_mask=SetImageChannelMask(image,AlphaChannel);
9167 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9168 geometry.y,invert,exception);
9169 (void) SetImageChannelMask(image,channel_mask);
9170 draw_info=DestroyDrawInfo(draw_info);
9171 break;
9172 }
9173 case 43: /* Modulate */
9174 {
9175 char
cristy151b66d2015-04-15 10:50:31 +00009176 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009177
9178 geometry_info.rho=100.0;
9179 geometry_info.sigma=100.0;
9180 geometry_info.xi=100.0;
9181 if (attribute_flag[0] != 0)
9182 (void)ParseGeometry(argument_list[0].string_reference,
9183 &geometry_info);
9184 if (attribute_flag[1] != 0)
9185 geometry_info.xi=argument_list[1].real_reference;
9186 if (attribute_flag[2] != 0)
9187 geometry_info.sigma=argument_list[2].real_reference;
9188 if (attribute_flag[3] != 0)
9189 {
9190 geometry_info.sigma=argument_list[3].real_reference;
9191 SetImageArtifact(image,"modulate:colorspace","HWB");
9192 }
9193 if (attribute_flag[4] != 0)
9194 {
9195 geometry_info.rho=argument_list[4].real_reference;
9196 SetImageArtifact(image,"modulate:colorspace","HSB");
9197 }
9198 if (attribute_flag[5] != 0)
9199 {
9200 geometry_info.sigma=argument_list[5].real_reference;
9201 SetImageArtifact(image,"modulate:colorspace","HSL");
9202 }
9203 if (attribute_flag[6] != 0)
9204 {
9205 geometry_info.rho=argument_list[6].real_reference;
9206 SetImageArtifact(image,"modulate:colorspace","HWB");
9207 }
cristy151b66d2015-04-15 10:50:31 +00009208 (void) FormatLocaleString(modulate,MagickPathExtent,"%.15g,%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00009209 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
9210 (void) ModulateImage(image,modulate,exception);
9211 break;
9212 }
9213 case 44: /* Negate */
9214 {
9215 if (attribute_flag[0] == 0)
9216 argument_list[0].integer_reference=0;
9217 if (attribute_flag[1] != 0)
9218 channel=(ChannelType) argument_list[1].integer_reference;
9219 channel_mask=SetImageChannelMask(image,channel);
9220 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9221 MagickTrue : MagickFalse,exception);
9222 (void) SetImageChannelMask(image,channel_mask);
9223 break;
9224 }
9225 case 45: /* Normalize */
9226 {
9227 if (attribute_flag[0] != 0)
9228 channel=(ChannelType) argument_list[0].integer_reference;
9229 channel_mask=SetImageChannelMask(image,channel);
9230 NormalizeImage(image,exception);
9231 (void) SetImageChannelMask(image,channel_mask);
9232 break;
9233 }
9234 case 46: /* NumberColors */
9235 break;
9236 case 47: /* Opaque */
9237 {
9238 MagickBooleanType
9239 invert;
9240
9241 PixelInfo
9242 fill_color,
9243 target;
9244
9245 (void) QueryColorCompliance("none",AllCompliance,&target,
9246 exception);
9247 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9248 exception);
9249 if (attribute_flag[0] != 0)
9250 (void) QueryColorCompliance(argument_list[0].string_reference,
9251 AllCompliance,&target,exception);
9252 if (attribute_flag[1] != 0)
9253 (void) QueryColorCompliance(argument_list[1].string_reference,
9254 AllCompliance,&fill_color,exception);
9255 if (attribute_flag[2] != 0)
9256 image->fuzz=StringToDoubleInterval(
9257 argument_list[2].string_reference,(double) QuantumRange+1.0);
9258 if (attribute_flag[3] != 0)
9259 channel=(ChannelType) argument_list[3].integer_reference;
9260 invert=MagickFalse;
9261 if (attribute_flag[4] != 0)
9262 invert=(MagickBooleanType) argument_list[4].integer_reference;
9263 channel_mask=SetImageChannelMask(image,channel);
9264 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9265 (void) SetImageChannelMask(image,channel_mask);
9266 break;
9267 }
9268 case 48: /* Quantize */
9269 {
9270 QuantizeInfo
9271 *quantize_info;
9272
9273 quantize_info=AcquireQuantizeInfo(info->image_info);
9274 if (attribute_flag[0] != 0)
9275 quantize_info->number_colors=(size_t)
9276 argument_list[0].integer_reference;
9277 if (attribute_flag[1] != 0)
9278 quantize_info->tree_depth=(size_t)
9279 argument_list[1].integer_reference;
9280 if (attribute_flag[2] != 0)
9281 quantize_info->colorspace=(ColorspaceType)
9282 argument_list[2].integer_reference;
9283 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009284 quantize_info->dither_method=(DitherMethod)
9285 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009286 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009287 quantize_info->measure_error=
9288 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009289 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009290 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009291 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009292 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009293 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009294 argument_list[7].integer_reference;
9295 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009296 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009297 else
cristyf7563392014-03-25 13:54:04 +00009298 if ((image->storage_class == DirectClass) ||
9299 (image->colors > quantize_info->number_colors) ||
9300 (quantize_info->colorspace == GRAYColorspace))
9301 (void) QuantizeImage(quantize_info,image,exception);
9302 else
9303 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009304 quantize_info=DestroyQuantizeInfo(quantize_info);
9305 break;
9306 }
9307 case 49: /* Raise */
9308 {
9309 if (attribute_flag[0] != 0)
9310 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9311 &geometry,exception);
9312 if (attribute_flag[1] != 0)
9313 geometry.width=argument_list[1].integer_reference;
9314 if (attribute_flag[2] != 0)
9315 geometry.height=argument_list[2].integer_reference;
9316 if (attribute_flag[3] == 0)
9317 argument_list[3].integer_reference=1;
9318 (void) RaiseImage(image,&geometry,
9319 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9320 exception);
9321 break;
9322 }
9323 case 50: /* Segment */
9324 {
9325 ColorspaceType
9326 colorspace;
9327
9328 double
9329 cluster_threshold,
9330 smoothing_threshold;
9331
9332 MagickBooleanType
9333 verbose;
9334
9335 cluster_threshold=1.0;
9336 smoothing_threshold=1.5;
9337 colorspace=sRGBColorspace;
9338 verbose=MagickFalse;
9339 if (attribute_flag[0] != 0)
9340 {
9341 flags=ParseGeometry(argument_list[0].string_reference,
9342 &geometry_info);
9343 cluster_threshold=geometry_info.rho;
9344 if (flags & SigmaValue)
9345 smoothing_threshold=geometry_info.sigma;
9346 }
9347 if (attribute_flag[1] != 0)
9348 cluster_threshold=argument_list[1].real_reference;
9349 if (attribute_flag[2] != 0)
9350 smoothing_threshold=argument_list[2].real_reference;
9351 if (attribute_flag[3] != 0)
9352 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9353 if (attribute_flag[4] != 0)
9354 verbose=argument_list[4].integer_reference != 0 ?
9355 MagickTrue : MagickFalse;
9356 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9357 smoothing_threshold,exception);
9358 break;
9359 }
9360 case 51: /* Signature */
9361 {
9362 (void) SignatureImage(image,exception);
9363 break;
9364 }
9365 case 52: /* Solarize */
9366 {
9367 geometry_info.rho=QuantumRange/2.0;
9368 if (attribute_flag[0] != 0)
9369 flags=ParseGeometry(argument_list[0].string_reference,
9370 &geometry_info);
9371 if (attribute_flag[1] != 0)
9372 geometry_info.rho=StringToDoubleInterval(
9373 argument_list[1].string_reference,(double) QuantumRange+1.0);
9374 (void) SolarizeImage(image,geometry_info.rho,exception);
9375 break;
9376 }
9377 case 53: /* Sync */
9378 {
9379 (void) SyncImage(image,exception);
9380 break;
9381 }
9382 case 54: /* Texture */
9383 {
9384 if (attribute_flag[0] == 0)
9385 break;
9386 TextureImage(image,argument_list[0].image_reference,exception);
9387 break;
9388 }
9389 case 55: /* Evalute */
9390 {
9391 MagickEvaluateOperator
9392 op;
9393
9394 op=SetEvaluateOperator;
9395 if (attribute_flag[0] == MagickFalse)
9396 argument_list[0].real_reference=0.0;
9397 if (attribute_flag[1] != MagickFalse)
9398 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9399 if (attribute_flag[2] != MagickFalse)
9400 channel=(ChannelType) argument_list[2].integer_reference;
9401 channel_mask=SetImageChannelMask(image,channel);
9402 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9403 exception);
9404 (void) SetImageChannelMask(image,channel_mask);
9405 break;
9406 }
9407 case 56: /* Transparent */
9408 {
9409 double
9410 opacity;
9411
9412 MagickBooleanType
9413 invert;
9414
9415 PixelInfo
9416 target;
9417
9418 (void) QueryColorCompliance("none",AllCompliance,&target,
9419 exception);
9420 if (attribute_flag[0] != 0)
9421 (void) QueryColorCompliance(argument_list[0].string_reference,
9422 AllCompliance,&target,exception);
9423 opacity=TransparentAlpha;
9424 if (attribute_flag[1] != 0)
9425 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9426 (double) QuantumRange+1.0);
9427 if (attribute_flag[2] != 0)
9428 image->fuzz=StringToDoubleInterval(
9429 argument_list[2].string_reference,(double) QuantumRange+1.0);
9430 if (attribute_flag[3] == 0)
9431 argument_list[3].integer_reference=0;
9432 invert=MagickFalse;
9433 if (attribute_flag[3] != 0)
9434 invert=(MagickBooleanType) argument_list[3].integer_reference;
9435 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9436 invert,exception);
9437 break;
9438 }
9439 case 57: /* Threshold */
9440 {
9441 double
9442 threshold;
9443
9444 if (attribute_flag[0] == 0)
9445 argument_list[0].string_reference="50%";
9446 if (attribute_flag[1] != 0)
9447 channel=(ChannelType) argument_list[1].integer_reference;
9448 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9449 (double) QuantumRange+1.0);
9450 channel_mask=SetImageChannelMask(image,channel);
9451 (void) BilevelImage(image,threshold,exception);
9452 (void) SetImageChannelMask(image,channel_mask);
9453 break;
9454 }
9455 case 58: /* Charcoal */
9456 {
9457 if (attribute_flag[0] != 0)
9458 {
9459 flags=ParseGeometry(argument_list[0].string_reference,
9460 &geometry_info);
9461 if ((flags & SigmaValue) == 0)
9462 geometry_info.sigma=1.0;
9463 }
9464 if (attribute_flag[1] != 0)
9465 geometry_info.rho=argument_list[1].real_reference;
9466 if (attribute_flag[2] != 0)
9467 geometry_info.sigma=argument_list[2].real_reference;
9468 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9469 exception);
9470 break;
9471 }
9472 case 59: /* Trim */
9473 {
9474 if (attribute_flag[0] != 0)
9475 image->fuzz=StringToDoubleInterval(
9476 argument_list[0].string_reference,(double) QuantumRange+1.0);
9477 image=TrimImage(image,exception);
9478 break;
9479 }
9480 case 60: /* Wave */
9481 {
9482 PixelInterpolateMethod
9483 method;
9484
9485 if (attribute_flag[0] != 0)
9486 {
9487 flags=ParseGeometry(argument_list[0].string_reference,
9488 &geometry_info);
9489 if ((flags & SigmaValue) == 0)
9490 geometry_info.sigma=1.0;
9491 }
9492 if (attribute_flag[1] != 0)
9493 geometry_info.rho=argument_list[1].real_reference;
9494 if (attribute_flag[2] != 0)
9495 geometry_info.sigma=argument_list[2].real_reference;
9496 method=UndefinedInterpolatePixel;
9497 if (attribute_flag[3] != 0)
9498 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9499 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9500 method,exception);
9501 break;
9502 }
9503 case 61: /* Separate */
9504 {
9505 if (attribute_flag[0] != 0)
9506 channel=(ChannelType) argument_list[0].integer_reference;
9507 image=SeparateImage(image,channel,exception);
9508 break;
9509 }
9510 case 63: /* Stereo */
9511 {
9512 if (attribute_flag[0] == 0)
9513 {
9514 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9515 PackageName);
9516 goto PerlException;
9517 }
9518 if (attribute_flag[1] != 0)
9519 geometry.x=argument_list[1].integer_reference;
9520 if (attribute_flag[2] != 0)
9521 geometry.y=argument_list[2].integer_reference;
9522 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9523 geometry.x,geometry.y,exception);
9524 break;
9525 }
9526 case 64: /* Stegano */
9527 {
9528 if (attribute_flag[0] == 0)
9529 {
9530 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9531 PackageName);
9532 goto PerlException;
9533 }
9534 if (attribute_flag[1] == 0)
9535 argument_list[1].integer_reference=0;
9536 image->offset=argument_list[1].integer_reference;
9537 image=SteganoImage(image,argument_list[0].image_reference,exception);
9538 break;
9539 }
9540 case 65: /* Deconstruct */
9541 {
9542 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9543 break;
9544 }
9545 case 66: /* GaussianBlur */
9546 {
9547 if (attribute_flag[0] != 0)
9548 {
9549 flags=ParseGeometry(argument_list[0].string_reference,
9550 &geometry_info);
9551 if ((flags & SigmaValue) == 0)
9552 geometry_info.sigma=1.0;
9553 }
9554 if (attribute_flag[1] != 0)
9555 geometry_info.rho=argument_list[1].real_reference;
9556 if (attribute_flag[2] != 0)
9557 geometry_info.sigma=argument_list[2].real_reference;
9558 if (attribute_flag[3] != 0)
9559 channel=(ChannelType) argument_list[3].integer_reference;
9560 channel_mask=SetImageChannelMask(image,channel);
9561 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9562 exception);
9563 if (image != (Image *) NULL)
9564 (void) SetImageChannelMask(image,channel_mask);
9565 break;
9566 }
9567 case 67: /* Convolve */
9568 {
9569 KernelInfo
9570 *kernel;
9571
9572 kernel=(KernelInfo *) NULL;
9573 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9574 break;
9575 if (attribute_flag[0] != 0)
9576 {
9577 AV
9578 *av;
9579
9580 size_t
9581 order;
9582
cristy2c57b742014-10-31 00:40:34 +00009583 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009584 if (kernel == (KernelInfo *) NULL)
9585 break;
9586 av=(AV *) argument_list[0].array_reference;
9587 order=(size_t) sqrt(av_len(av)+1);
9588 kernel->width=order;
9589 kernel->height=order;
9590 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9591 order*sizeof(*kernel->values));
9592 if (kernel->values == (MagickRealType *) NULL)
9593 {
9594 kernel=DestroyKernelInfo(kernel);
9595 ThrowPerlException(exception,ResourceLimitFatalError,
9596 "MemoryAllocationFailed",PackageName);
9597 goto PerlException;
9598 }
9599 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9600 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9601 for ( ; j < (ssize_t) (order*order); j++)
9602 kernel->values[j]=0.0;
9603 }
9604 if (attribute_flag[1] != 0)
9605 channel=(ChannelType) argument_list[1].integer_reference;
9606 if (attribute_flag[2] != 0)
9607 SetImageArtifact(image,"filter:blur",
9608 argument_list[2].string_reference);
9609 if (attribute_flag[3] != 0)
9610 {
cristy2c57b742014-10-31 00:40:34 +00009611 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9612 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009613 if (kernel == (KernelInfo *) NULL)
9614 break;
9615 }
9616 channel_mask=SetImageChannelMask(image,channel);
9617 image=ConvolveImage(image,kernel,exception);
9618 if (image != (Image *) NULL)
9619 (void) SetImageChannelMask(image,channel_mask);
9620 kernel=DestroyKernelInfo(kernel);
9621 break;
9622 }
9623 case 68: /* Profile */
9624 {
9625 const char
9626 *name;
9627
9628 Image
9629 *profile_image;
9630
9631 ImageInfo
9632 *profile_info;
9633
9634 StringInfo
9635 *profile;
9636
9637 name="*";
9638 if (attribute_flag[0] != 0)
9639 name=argument_list[0].string_reference;
9640 if (attribute_flag[2] != 0)
9641 image->rendering_intent=(RenderingIntent)
9642 argument_list[2].integer_reference;
9643 if (attribute_flag[3] != 0)
9644 image->black_point_compensation=
9645 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9646 if (attribute_flag[1] != 0)
9647 {
9648 if (argument_list[1].length == 0)
9649 {
9650 /*
9651 Remove a profile from the image.
9652 */
9653 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9654 exception);
9655 break;
9656 }
9657 /*
9658 Associate user supplied profile with the image.
9659 */
9660 profile=AcquireStringInfo(argument_list[1].length);
9661 SetStringInfoDatum(profile,(const unsigned char *)
9662 argument_list[1].string_reference);
9663 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9664 (size_t) GetStringInfoLength(profile),exception);
9665 profile=DestroyStringInfo(profile);
9666 break;
9667 }
9668 /*
9669 Associate a profile with the image.
9670 */
9671 profile_info=CloneImageInfo(info ? info->image_info :
9672 (ImageInfo *) NULL);
9673 profile_image=ReadImages(profile_info,name,exception);
9674 if (profile_image == (Image *) NULL)
9675 break;
9676 ResetImageProfileIterator(profile_image);
9677 name=GetNextImageProfile(profile_image);
9678 while (name != (const char *) NULL)
9679 {
9680 const StringInfo
9681 *profile;
9682
9683 profile=GetImageProfile(profile_image,name);
9684 if (profile != (const StringInfo *) NULL)
9685 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9686 (size_t) GetStringInfoLength(profile),exception);
9687 name=GetNextImageProfile(profile_image);
9688 }
9689 profile_image=DestroyImage(profile_image);
9690 profile_info=DestroyImageInfo(profile_info);
9691 break;
9692 }
9693 case 69: /* UnsharpMask */
9694 {
9695 if (attribute_flag[0] != 0)
9696 {
9697 flags=ParseGeometry(argument_list[0].string_reference,
9698 &geometry_info);
9699 if ((flags & SigmaValue) == 0)
9700 geometry_info.sigma=1.0;
9701 if ((flags & XiValue) == 0)
9702 geometry_info.xi=1.0;
9703 if ((flags & PsiValue) == 0)
9704 geometry_info.psi=0.5;
9705 }
9706 if (attribute_flag[1] != 0)
9707 geometry_info.rho=argument_list[1].real_reference;
9708 if (attribute_flag[2] != 0)
9709 geometry_info.sigma=argument_list[2].real_reference;
9710 if (attribute_flag[3] != 0)
9711 geometry_info.xi=argument_list[3].real_reference;
9712 if (attribute_flag[4] != 0)
9713 geometry_info.psi=argument_list[4].real_reference;
9714 if (attribute_flag[5] != 0)
9715 channel=(ChannelType) argument_list[5].integer_reference;
9716 channel_mask=SetImageChannelMask(image,channel);
9717 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9718 geometry_info.xi,geometry_info.psi,exception);
9719 if (image != (Image *) NULL)
9720 (void) SetImageChannelMask(image,channel_mask);
9721 break;
9722 }
9723 case 70: /* MotionBlur */
9724 {
9725 if (attribute_flag[0] != 0)
9726 {
9727 flags=ParseGeometry(argument_list[0].string_reference,
9728 &geometry_info);
9729 if ((flags & SigmaValue) == 0)
9730 geometry_info.sigma=1.0;
9731 if ((flags & XiValue) == 0)
9732 geometry_info.xi=1.0;
9733 }
9734 if (attribute_flag[1] != 0)
9735 geometry_info.rho=argument_list[1].real_reference;
9736 if (attribute_flag[2] != 0)
9737 geometry_info.sigma=argument_list[2].real_reference;
9738 if (attribute_flag[3] != 0)
9739 geometry_info.xi=argument_list[3].real_reference;
9740 if (attribute_flag[4] != 0)
9741 channel=(ChannelType) argument_list[4].integer_reference;
9742 channel_mask=SetImageChannelMask(image,channel);
9743 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9744 geometry_info.xi,exception);
9745 if (image != (Image *) NULL)
9746 (void) SetImageChannelMask(image,channel_mask);
9747 break;
9748 }
9749 case 71: /* OrderedDither */
9750 {
9751 if (attribute_flag[0] == 0)
9752 argument_list[0].string_reference="o8x8";
9753 if (attribute_flag[1] != 0)
9754 channel=(ChannelType) argument_list[1].integer_reference;
9755 channel_mask=SetImageChannelMask(image,channel);
Cristy6b93c072016-02-04 07:45:48 -05009756 (void) OrderedDitherImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009757 exception);
9758 (void) SetImageChannelMask(image,channel_mask);
9759 break;
9760 }
9761 case 72: /* Shave */
9762 {
9763 if (attribute_flag[0] != 0)
9764 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9765 &geometry,exception);
9766 if (attribute_flag[1] != 0)
9767 geometry.width=argument_list[1].integer_reference;
9768 if (attribute_flag[2] != 0)
9769 geometry.height=argument_list[2].integer_reference;
9770 image=ShaveImage(image,&geometry,exception);
9771 break;
9772 }
9773 case 73: /* Level */
9774 {
9775 double
9776 black_point,
9777 gamma,
9778 white_point;
9779
9780 black_point=0.0;
9781 white_point=(double) image->columns*image->rows;
9782 gamma=1.0;
9783 if (attribute_flag[0] != 0)
9784 {
9785 flags=ParseGeometry(argument_list[0].string_reference,
9786 &geometry_info);
9787 black_point=geometry_info.rho;
9788 if ((flags & SigmaValue) != 0)
9789 white_point=geometry_info.sigma;
9790 if ((flags & XiValue) != 0)
9791 gamma=geometry_info.xi;
9792 if ((flags & PercentValue) != 0)
9793 {
9794 black_point*=(double) (QuantumRange/100.0);
9795 white_point*=(double) (QuantumRange/100.0);
9796 }
9797 if ((flags & SigmaValue) == 0)
9798 white_point=(double) QuantumRange-black_point;
9799 }
9800 if (attribute_flag[1] != 0)
9801 black_point=argument_list[1].real_reference;
9802 if (attribute_flag[2] != 0)
9803 white_point=argument_list[2].real_reference;
9804 if (attribute_flag[3] != 0)
9805 gamma=argument_list[3].real_reference;
9806 if (attribute_flag[4] != 0)
9807 channel=(ChannelType) argument_list[4].integer_reference;
9808 if (attribute_flag[5] != 0)
9809 {
9810 argument_list[0].real_reference=argument_list[5].real_reference;
9811 attribute_flag[0]=attribute_flag[5];
9812 }
9813 channel_mask=SetImageChannelMask(image,channel);
9814 (void) LevelImage(image,black_point,white_point,gamma,exception);
9815 (void) SetImageChannelMask(image,channel_mask);
9816 break;
9817 }
9818 case 74: /* Clip */
9819 {
9820 if (attribute_flag[0] == 0)
9821 argument_list[0].string_reference="#1";
9822 if (attribute_flag[1] == 0)
9823 argument_list[1].integer_reference=MagickTrue;
9824 (void) ClipImagePath(image,argument_list[0].string_reference,
9825 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9826 exception);
9827 break;
9828 }
9829 case 75: /* AffineTransform */
9830 {
9831 DrawInfo
9832 *draw_info;
9833
9834 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9835 (DrawInfo *) NULL);
9836 if (attribute_flag[0] != 0)
9837 {
9838 AV
9839 *av;
9840
9841 av=(AV *) argument_list[0].array_reference;
9842 if ((av_len(av) != 3) && (av_len(av) != 5))
9843 {
9844 ThrowPerlException(exception,OptionError,
9845 "affine matrix must have 4 or 6 elements",PackageName);
9846 goto PerlException;
9847 }
9848 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9849 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9850 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9851 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9852 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9853 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9854 {
9855 ThrowPerlException(exception,OptionError,
9856 "affine matrix is singular",PackageName);
9857 goto PerlException;
9858 }
9859 if (av_len(av) == 5)
9860 {
9861 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9862 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9863 }
9864 }
9865 for (j=1; j < 6; j++)
9866 {
9867 if (attribute_flag[j] == 0)
9868 continue;
9869 value=argument_list[j].string_reference;
9870 angle=argument_list[j].real_reference;
9871 current=draw_info->affine;
9872 GetAffineMatrix(&affine);
9873 switch (j)
9874 {
9875 case 1:
9876 {
9877 /*
9878 Translate.
9879 */
9880 flags=ParseGeometry(value,&geometry_info);
9881 affine.tx=geometry_info.xi;
9882 affine.ty=geometry_info.psi;
9883 if ((flags & PsiValue) == 0)
9884 affine.ty=affine.tx;
9885 break;
9886 }
9887 case 2:
9888 {
9889 /*
9890 Scale.
9891 */
9892 flags=ParseGeometry(value,&geometry_info);
9893 affine.sx=geometry_info.rho;
9894 affine.sy=geometry_info.sigma;
9895 if ((flags & SigmaValue) == 0)
9896 affine.sy=affine.sx;
9897 break;
9898 }
9899 case 3:
9900 {
9901 /*
9902 Rotate.
9903 */
9904 if (angle == 0.0)
9905 break;
9906 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9907 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9908 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9909 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9910 break;
9911 }
9912 case 4:
9913 {
9914 /*
9915 SkewX.
9916 */
9917 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9918 break;
9919 }
9920 case 5:
9921 {
9922 /*
9923 SkewY.
9924 */
9925 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9926 break;
9927 }
9928 }
9929 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9930 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9931 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9932 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9933 draw_info->affine.tx=
9934 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9935 draw_info->affine.ty=
9936 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9937 }
9938 if (attribute_flag[6] != 0)
9939 image->interpolate=(PixelInterpolateMethod)
9940 argument_list[6].integer_reference;
9941 if (attribute_flag[7] != 0)
9942 QueryColorCompliance(argument_list[7].string_reference,
9943 AllCompliance,&image->background_color,exception);
9944 image=AffineTransformImage(image,&draw_info->affine,exception);
9945 draw_info=DestroyDrawInfo(draw_info);
9946 break;
9947 }
9948 case 76: /* Difference */
9949 {
9950 if (attribute_flag[0] == 0)
9951 {
9952 ThrowPerlException(exception,OptionError,
9953 "ReferenceImageRequired",PackageName);
9954 goto PerlException;
9955 }
9956 if (attribute_flag[1] != 0)
9957 image->fuzz=StringToDoubleInterval(
9958 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -05009959 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009960 exception);
9961 break;
9962 }
9963 case 77: /* AdaptiveThreshold */
9964 {
9965 if (attribute_flag[0] != 0)
9966 {
9967 flags=ParseGeometry(argument_list[0].string_reference,
9968 &geometry_info);
9969 if ((flags & PercentValue) != 0)
9970 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9971 }
9972 if (attribute_flag[1] != 0)
9973 geometry_info.rho=argument_list[1].integer_reference;
9974 if (attribute_flag[2] != 0)
9975 geometry_info.sigma=argument_list[2].integer_reference;
9976 if (attribute_flag[3] != 0)
9977 geometry_info.xi=argument_list[3].integer_reference;;
9978 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9979 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9980 break;
9981 }
9982 case 78: /* Resample */
9983 {
9984 size_t
9985 height,
9986 width;
9987
9988 if (attribute_flag[0] != 0)
9989 {
9990 flags=ParseGeometry(argument_list[0].string_reference,
9991 &geometry_info);
9992 if ((flags & SigmaValue) == 0)
9993 geometry_info.sigma=geometry_info.rho;
9994 }
9995 if (attribute_flag[1] != 0)
9996 geometry_info.rho=argument_list[1].real_reference;
9997 if (attribute_flag[2] != 0)
9998 geometry_info.sigma=argument_list[2].real_reference;
9999 if (attribute_flag[3] == 0)
10000 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10001 if (attribute_flag[4] == 0)
10002 SetImageArtifact(image,"filter:support",
10003 argument_list[4].string_reference);
10004 width=(size_t) (geometry_info.rho*image->columns/
10005 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10006 height=(size_t) (geometry_info.sigma*image->rows/
10007 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
Cristy8645e042016-02-03 16:35:29 -050010008 image=ResizeImage(image,width,height,(FilterType)
cristy4a3ce0a2013-08-03 20:06:59 +000010009 argument_list[3].integer_reference,exception);
10010 if (image != (Image *) NULL)
10011 {
10012 image->resolution.x=geometry_info.rho;
10013 image->resolution.y=geometry_info.sigma;
10014 }
10015 break;
10016 }
10017 case 79: /* Describe */
10018 {
10019 if (attribute_flag[0] == 0)
10020 argument_list[0].file_reference=(FILE *) NULL;
10021 if (attribute_flag[1] != 0)
10022 (void) SetImageArtifact(image,"identify:features",
10023 argument_list[1].string_reference);
10024 (void) IdentifyImage(image,argument_list[0].file_reference,
10025 MagickTrue,exception);
10026 break;
10027 }
10028 case 80: /* BlackThreshold */
10029 {
10030 if (attribute_flag[0] == 0)
10031 argument_list[0].string_reference="50%";
10032 if (attribute_flag[2] != 0)
10033 channel=(ChannelType) argument_list[2].integer_reference;
10034 channel_mask=SetImageChannelMask(image,channel);
10035 BlackThresholdImage(image,argument_list[0].string_reference,
10036 exception);
10037 (void) SetImageChannelMask(image,channel_mask);
10038 break;
10039 }
10040 case 81: /* WhiteThreshold */
10041 {
10042 if (attribute_flag[0] == 0)
10043 argument_list[0].string_reference="50%";
10044 if (attribute_flag[2] != 0)
10045 channel=(ChannelType) argument_list[2].integer_reference;
10046 channel_mask=SetImageChannelMask(image,channel);
10047 WhiteThresholdImage(image,argument_list[0].string_reference,
10048 exception);
10049 (void) SetImageChannelMask(image,channel_mask);
10050 break;
10051 }
cristy60c73c02014-03-25 12:09:58 +000010052 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010053 {
10054 if (attribute_flag[0] != 0)
10055 {
10056 flags=ParseGeometry(argument_list[0].string_reference,
10057 &geometry_info);
10058 }
10059 if (attribute_flag[1] != 0)
10060 geometry_info.rho=argument_list[1].real_reference;
10061 if (attribute_flag[2] != 0)
10062 channel=(ChannelType) argument_list[2].integer_reference;
10063 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010064 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010065 if (image != (Image *) NULL)
10066 (void) SetImageChannelMask(image,channel_mask);
10067 break;
10068 }
10069 case 83: /* Thumbnail */
10070 {
10071 if (attribute_flag[0] != 0)
10072 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10073 &geometry,exception);
10074 if (attribute_flag[1] != 0)
10075 geometry.width=argument_list[1].integer_reference;
10076 if (attribute_flag[2] != 0)
10077 geometry.height=argument_list[2].integer_reference;
10078 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10079 break;
10080 }
10081 case 84: /* Strip */
10082 {
10083 (void) StripImage(image,exception);
10084 break;
10085 }
10086 case 85: /* Tint */
10087 {
10088 PixelInfo
10089 tint;
10090
10091 GetPixelInfo(image,&tint);
10092 if (attribute_flag[0] != 0)
10093 (void) QueryColorCompliance(argument_list[0].string_reference,
10094 AllCompliance,&tint,exception);
10095 if (attribute_flag[1] == 0)
10096 argument_list[1].string_reference="100";
10097 image=TintImage(image,argument_list[1].string_reference,&tint,
10098 exception);
10099 break;
10100 }
10101 case 86: /* Channel */
10102 {
10103 if (attribute_flag[0] != 0)
10104 channel=(ChannelType) argument_list[0].integer_reference;
10105 image=SeparateImage(image,channel,exception);
10106 break;
10107 }
10108 case 87: /* Splice */
10109 {
cristy260bd762014-08-15 12:46:34 +000010110 if (attribute_flag[7] != 0)
10111 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010112 if (attribute_flag[0] != 0)
10113 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10114 &geometry,exception);
10115 if (attribute_flag[1] != 0)
10116 geometry.width=argument_list[1].integer_reference;
10117 if (attribute_flag[2] != 0)
10118 geometry.height=argument_list[2].integer_reference;
10119 if (attribute_flag[3] != 0)
10120 geometry.x=argument_list[3].integer_reference;
10121 if (attribute_flag[4] != 0)
10122 geometry.y=argument_list[4].integer_reference;
10123 if (attribute_flag[5] != 0)
10124 image->fuzz=StringToDoubleInterval(
10125 argument_list[5].string_reference,(double) QuantumRange+1.0);
10126 if (attribute_flag[6] != 0)
10127 (void) QueryColorCompliance(argument_list[6].string_reference,
10128 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010129 image=SpliceImage(image,&geometry,exception);
10130 break;
10131 }
10132 case 88: /* Posterize */
10133 {
10134 if (attribute_flag[0] == 0)
10135 argument_list[0].integer_reference=3;
10136 if (attribute_flag[1] == 0)
10137 argument_list[1].integer_reference=0;
10138 (void) PosterizeImage(image,argument_list[0].integer_reference,
10139 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10140 NoDitherMethod,exception);
10141 break;
10142 }
10143 case 89: /* Shadow */
10144 {
10145 if (attribute_flag[0] != 0)
10146 {
10147 flags=ParseGeometry(argument_list[0].string_reference,
10148 &geometry_info);
10149 if ((flags & SigmaValue) == 0)
10150 geometry_info.sigma=1.0;
10151 if ((flags & XiValue) == 0)
10152 geometry_info.xi=4.0;
10153 if ((flags & PsiValue) == 0)
10154 geometry_info.psi=4.0;
10155 }
10156 if (attribute_flag[1] != 0)
10157 geometry_info.rho=argument_list[1].real_reference;
10158 if (attribute_flag[2] != 0)
10159 geometry_info.sigma=argument_list[2].real_reference;
10160 if (attribute_flag[3] != 0)
10161 geometry_info.xi=argument_list[3].integer_reference;
10162 if (attribute_flag[4] != 0)
10163 geometry_info.psi=argument_list[4].integer_reference;
10164 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10165 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10166 ceil(geometry_info.psi-0.5),exception);
10167 break;
10168 }
10169 case 90: /* Identify */
10170 {
10171 if (attribute_flag[0] == 0)
10172 argument_list[0].file_reference=(FILE *) NULL;
10173 if (attribute_flag[1] != 0)
10174 (void) SetImageArtifact(image,"identify:features",
10175 argument_list[1].string_reference);
10176 if ((attribute_flag[2] != 0) &&
10177 (argument_list[2].integer_reference != 0))
10178 (void) SetImageArtifact(image,"identify:unique","true");
10179 (void) IdentifyImage(image,argument_list[0].file_reference,
10180 MagickTrue,exception);
10181 break;
10182 }
10183 case 91: /* SepiaTone */
10184 {
10185 if (attribute_flag[0] == 0)
10186 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10187 image=SepiaToneImage(image,argument_list[0].real_reference,
10188 exception);
10189 break;
10190 }
10191 case 92: /* SigmoidalContrast */
10192 {
10193 MagickBooleanType
10194 sharpen;
10195
10196 if (attribute_flag[0] != 0)
10197 {
10198 flags=ParseGeometry(argument_list[0].string_reference,
10199 &geometry_info);
10200 if ((flags & SigmaValue) == 0)
10201 geometry_info.sigma=QuantumRange/2.0;
10202 if ((flags & PercentValue) != 0)
10203 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10204 }
10205 if (attribute_flag[1] != 0)
10206 geometry_info.rho=argument_list[1].real_reference;
10207 if (attribute_flag[2] != 0)
10208 geometry_info.sigma=argument_list[2].real_reference;
10209 if (attribute_flag[3] != 0)
10210 channel=(ChannelType) argument_list[3].integer_reference;
10211 sharpen=MagickTrue;
10212 if (attribute_flag[4] != 0)
10213 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10214 MagickFalse;
10215 channel_mask=SetImageChannelMask(image,channel);
10216 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10217 geometry_info.sigma,exception);
10218 (void) SetImageChannelMask(image,channel_mask);
10219 break;
10220 }
10221 case 93: /* Extent */
10222 {
10223 if (attribute_flag[7] != 0)
10224 image->gravity=(GravityType) argument_list[7].integer_reference;
10225 if (attribute_flag[0] != 0)
10226 {
10227 int
10228 flags;
10229
10230 flags=ParseGravityGeometry(image,
10231 argument_list[0].string_reference,&geometry,exception);
10232 (void) flags;
10233 if (geometry.width == 0)
10234 geometry.width=image->columns;
10235 if (geometry.height == 0)
10236 geometry.height=image->rows;
10237 }
10238 if (attribute_flag[1] != 0)
10239 geometry.width=argument_list[1].integer_reference;
10240 if (attribute_flag[2] != 0)
10241 geometry.height=argument_list[2].integer_reference;
10242 if (attribute_flag[3] != 0)
10243 geometry.x=argument_list[3].integer_reference;
10244 if (attribute_flag[4] != 0)
10245 geometry.y=argument_list[4].integer_reference;
10246 if (attribute_flag[5] != 0)
10247 image->fuzz=StringToDoubleInterval(
10248 argument_list[5].string_reference,(double) QuantumRange+1.0);
10249 if (attribute_flag[6] != 0)
10250 (void) QueryColorCompliance(argument_list[6].string_reference,
10251 AllCompliance,&image->background_color,exception);
10252 image=ExtentImage(image,&geometry,exception);
10253 break;
10254 }
10255 case 94: /* Vignette */
10256 {
10257 if (attribute_flag[0] != 0)
10258 {
10259 flags=ParseGeometry(argument_list[0].string_reference,
10260 &geometry_info);
10261 if ((flags & SigmaValue) == 0)
10262 geometry_info.sigma=1.0;
10263 if ((flags & XiValue) == 0)
10264 geometry_info.xi=0.1*image->columns;
10265 if ((flags & PsiValue) == 0)
10266 geometry_info.psi=0.1*image->rows;
10267 }
10268 if (attribute_flag[1] != 0)
10269 geometry_info.rho=argument_list[1].real_reference;
10270 if (attribute_flag[2] != 0)
10271 geometry_info.sigma=argument_list[2].real_reference;
10272 if (attribute_flag[3] != 0)
10273 geometry_info.xi=argument_list[3].integer_reference;
10274 if (attribute_flag[4] != 0)
10275 geometry_info.psi=argument_list[4].integer_reference;
10276 if (attribute_flag[5] != 0)
10277 (void) QueryColorCompliance(argument_list[5].string_reference,
10278 AllCompliance,&image->background_color,exception);
10279 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10280 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10281 ceil(geometry_info.psi-0.5),exception);
10282 break;
10283 }
10284 case 95: /* ContrastStretch */
10285 {
10286 double
10287 black_point,
10288 white_point;
10289
10290 black_point=0.0;
10291 white_point=(double) image->columns*image->rows;
10292 if (attribute_flag[0] != 0)
10293 {
10294 flags=ParseGeometry(argument_list[0].string_reference,
10295 &geometry_info);
10296 black_point=geometry_info.rho;
10297 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10298 black_point;
10299 if ((flags & PercentValue) != 0)
10300 {
10301 black_point*=(double) image->columns*image->rows/100.0;
10302 white_point*=(double) image->columns*image->rows/100.0;
10303 }
10304 white_point=(double) image->columns*image->rows-
10305 white_point;
10306 }
10307 if (attribute_flag[1] != 0)
10308 black_point=argument_list[1].real_reference;
10309 if (attribute_flag[2] != 0)
10310 white_point=argument_list[2].real_reference;
10311 if (attribute_flag[4] != 0)
10312 channel=(ChannelType) argument_list[4].integer_reference;
10313 channel_mask=SetImageChannelMask(image,channel);
10314 (void) ContrastStretchImage(image,black_point,white_point,exception);
10315 (void) SetImageChannelMask(image,channel_mask);
10316 break;
10317 }
10318 case 96: /* Sans0 */
10319 {
10320 break;
10321 }
10322 case 97: /* Sans1 */
10323 {
10324 break;
10325 }
10326 case 98: /* AdaptiveSharpen */
10327 {
10328 if (attribute_flag[0] != 0)
10329 {
10330 flags=ParseGeometry(argument_list[0].string_reference,
10331 &geometry_info);
10332 if ((flags & SigmaValue) == 0)
10333 geometry_info.sigma=1.0;
10334 if ((flags & XiValue) == 0)
10335 geometry_info.xi=0.0;
10336 }
10337 if (attribute_flag[1] != 0)
10338 geometry_info.rho=argument_list[1].real_reference;
10339 if (attribute_flag[2] != 0)
10340 geometry_info.sigma=argument_list[2].real_reference;
10341 if (attribute_flag[3] != 0)
10342 geometry_info.xi=argument_list[3].real_reference;
10343 if (attribute_flag[4] != 0)
10344 channel=(ChannelType) argument_list[4].integer_reference;
10345 channel_mask=SetImageChannelMask(image,channel);
10346 image=AdaptiveSharpenImage(image,geometry_info.rho,
10347 geometry_info.sigma,exception);
10348 if (image != (Image *) NULL)
10349 (void) SetImageChannelMask(image,channel_mask);
10350 break;
10351 }
10352 case 99: /* Transpose */
10353 {
10354 image=TransposeImage(image,exception);
10355 break;
10356 }
10357 case 100: /* Tranverse */
10358 {
10359 image=TransverseImage(image,exception);
10360 break;
10361 }
10362 case 101: /* AutoOrient */
10363 {
10364 image=AutoOrientImage(image,image->orientation,exception);
10365 break;
10366 }
10367 case 102: /* AdaptiveBlur */
10368 {
10369 if (attribute_flag[0] != 0)
10370 {
10371 flags=ParseGeometry(argument_list[0].string_reference,
10372 &geometry_info);
10373 if ((flags & SigmaValue) == 0)
10374 geometry_info.sigma=1.0;
10375 if ((flags & XiValue) == 0)
10376 geometry_info.xi=0.0;
10377 }
10378 if (attribute_flag[1] != 0)
10379 geometry_info.rho=argument_list[1].real_reference;
10380 if (attribute_flag[2] != 0)
10381 geometry_info.sigma=argument_list[2].real_reference;
10382 if (attribute_flag[3] != 0)
10383 channel=(ChannelType) argument_list[3].integer_reference;
10384 channel_mask=SetImageChannelMask(image,channel);
10385 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10386 exception);
10387 if (image != (Image *) NULL)
10388 (void) SetImageChannelMask(image,channel_mask);
10389 break;
10390 }
10391 case 103: /* Sketch */
10392 {
10393 if (attribute_flag[0] != 0)
10394 {
10395 flags=ParseGeometry(argument_list[0].string_reference,
10396 &geometry_info);
10397 if ((flags & SigmaValue) == 0)
10398 geometry_info.sigma=1.0;
10399 if ((flags & XiValue) == 0)
10400 geometry_info.xi=1.0;
10401 }
10402 if (attribute_flag[1] != 0)
10403 geometry_info.rho=argument_list[1].real_reference;
10404 if (attribute_flag[2] != 0)
10405 geometry_info.sigma=argument_list[2].real_reference;
10406 if (attribute_flag[3] != 0)
10407 geometry_info.xi=argument_list[3].real_reference;
10408 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10409 geometry_info.xi,exception);
10410 break;
10411 }
10412 case 104: /* UniqueColors */
10413 {
10414 image=UniqueImageColors(image,exception);
10415 break;
10416 }
10417 case 105: /* AdaptiveResize */
10418 {
10419 if (attribute_flag[0] != 0)
10420 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10421 &geometry,exception);
10422 if (attribute_flag[1] != 0)
10423 geometry.width=argument_list[1].integer_reference;
10424 if (attribute_flag[2] != 0)
10425 geometry.height=argument_list[2].integer_reference;
10426 if (attribute_flag[3] != 0)
Cristy8645e042016-02-03 16:35:29 -050010427 image->filter=(FilterType) argument_list[4].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010428 if (attribute_flag[4] != 0)
10429 SetImageArtifact(image,"filter:support",
10430 argument_list[4].string_reference);
10431 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10432 exception);
10433 break;
10434 }
10435 case 106: /* ClipMask */
10436 {
10437 Image
10438 *mask_image;
10439
10440 if (attribute_flag[0] == 0)
10441 {
10442 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10443 PackageName);
10444 goto PerlException;
10445 }
10446 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10447 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010448 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010449 mask_image=DestroyImage(mask_image);
10450 break;
10451 }
10452 case 107: /* LinearStretch */
10453 {
10454 double
10455 black_point,
10456 white_point;
10457
10458 black_point=0.0;
10459 white_point=(double) image->columns*image->rows;
10460 if (attribute_flag[0] != 0)
10461 {
10462 flags=ParseGeometry(argument_list[0].string_reference,
10463 &geometry_info);
10464 if ((flags & SigmaValue) != 0)
10465 white_point=geometry_info.sigma;
10466 if ((flags & PercentValue) != 0)
10467 {
10468 black_point*=(double) image->columns*image->rows/100.0;
10469 white_point*=(double) image->columns*image->rows/100.0;
10470 }
10471 if ((flags & SigmaValue) == 0)
10472 white_point=(double) image->columns*image->rows-black_point;
10473 }
10474 if (attribute_flag[1] != 0)
10475 black_point=argument_list[1].real_reference;
10476 if (attribute_flag[2] != 0)
10477 white_point=argument_list[2].real_reference;
10478 (void) LinearStretchImage(image,black_point,white_point,exception);
10479 break;
10480 }
10481 case 108: /* ColorMatrix */
10482 {
10483 AV
10484 *av;
10485
10486 double
10487 *color_matrix;
10488
10489 KernelInfo
10490 *kernel_info;
10491
10492 size_t
10493 order;
10494
10495 if (attribute_flag[0] == 0)
10496 break;
10497 av=(AV *) argument_list[0].array_reference;
10498 order=(size_t) sqrt(av_len(av)+1);
10499 color_matrix=(double *) AcquireQuantumMemory(order,order*
10500 sizeof(*color_matrix));
10501 if (color_matrix == (double *) NULL)
10502 {
10503 ThrowPerlException(exception,ResourceLimitFatalError,
10504 "MemoryAllocationFailed",PackageName);
10505 goto PerlException;
10506 }
10507 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10508 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10509 for ( ; j < (ssize_t) (order*order); j++)
10510 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010511 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010512 if (kernel_info == (KernelInfo *) NULL)
10513 break;
10514 kernel_info->width=order;
10515 kernel_info->height=order;
10516 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10517 order*sizeof(*kernel_info->values));
10518 if (kernel_info->values != (MagickRealType *) NULL)
10519 {
10520 for (i=0; i < (ssize_t) (order*order); i++)
10521 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10522 image=ColorMatrixImage(image,kernel_info,exception);
10523 }
10524 kernel_info=DestroyKernelInfo(kernel_info);
10525 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10526 break;
10527 }
10528 case 109: /* Mask */
10529 {
10530 Image
10531 *mask_image;
10532
10533 if (attribute_flag[0] == 0)
10534 {
10535 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10536 PackageName);
10537 goto PerlException;
10538 }
10539 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10540 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010541 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010542 mask_image=DestroyImage(mask_image);
10543 break;
10544 }
10545 case 110: /* Polaroid */
10546 {
10547 char
10548 *caption;
10549
10550 DrawInfo
10551 *draw_info;
10552
10553 double
10554 angle;
10555
10556 PixelInterpolateMethod
10557 method;
10558
10559 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10560 (DrawInfo *) NULL);
10561 caption=(char *) NULL;
10562 if (attribute_flag[0] != 0)
10563 caption=InterpretImageProperties(info ? info->image_info :
10564 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10565 exception);
10566 angle=0.0;
10567 if (attribute_flag[1] != 0)
10568 angle=argument_list[1].real_reference;
10569 if (attribute_flag[2] != 0)
10570 (void) CloneString(&draw_info->font,
10571 argument_list[2].string_reference);
10572 if (attribute_flag[3] != 0)
10573 (void) QueryColorCompliance(argument_list[3].string_reference,
10574 AllCompliance,&draw_info->stroke,exception);
10575 if (attribute_flag[4] != 0)
10576 (void) QueryColorCompliance(argument_list[4].string_reference,
10577 AllCompliance,&draw_info->fill,exception);
10578 if (attribute_flag[5] != 0)
10579 draw_info->stroke_width=argument_list[5].real_reference;
10580 if (attribute_flag[6] != 0)
10581 draw_info->pointsize=argument_list[6].real_reference;
10582 if (attribute_flag[7] != 0)
10583 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10584 if (attribute_flag[8] != 0)
10585 (void) QueryColorCompliance(argument_list[8].string_reference,
10586 AllCompliance,&image->background_color,exception);
10587 method=UndefinedInterpolatePixel;
10588 if (attribute_flag[9] != 0)
10589 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10590 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10591 draw_info=DestroyDrawInfo(draw_info);
10592 if (caption != (char *) NULL)
10593 caption=DestroyString(caption);
10594 break;
10595 }
10596 case 111: /* FloodfillPaint */
10597 {
10598 DrawInfo
10599 *draw_info;
10600
10601 MagickBooleanType
10602 invert;
10603
10604 PixelInfo
10605 target;
10606
10607 draw_info=CloneDrawInfo(info ? info->image_info :
10608 (ImageInfo *) NULL,(DrawInfo *) NULL);
10609 if (attribute_flag[0] != 0)
10610 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10611 &geometry,exception);
10612 if (attribute_flag[1] != 0)
10613 geometry.x=argument_list[1].integer_reference;
10614 if (attribute_flag[2] != 0)
10615 geometry.y=argument_list[2].integer_reference;
10616 if (attribute_flag[3] != 0)
10617 (void) QueryColorCompliance(argument_list[3].string_reference,
10618 AllCompliance,&draw_info->fill,exception);
10619 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10620 geometry.x,geometry.y,&target,exception);
10621 if (attribute_flag[4] != 0)
10622 QueryColorCompliance(argument_list[4].string_reference,
10623 AllCompliance,&target,exception);
10624 if (attribute_flag[5] != 0)
10625 image->fuzz=StringToDoubleInterval(
10626 argument_list[5].string_reference,(double) QuantumRange+1.0);
10627 if (attribute_flag[6] != 0)
10628 channel=(ChannelType) argument_list[6].integer_reference;
10629 invert=MagickFalse;
10630 if (attribute_flag[7] != 0)
10631 invert=(MagickBooleanType) argument_list[7].integer_reference;
10632 channel_mask=SetImageChannelMask(image,channel);
10633 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10634 geometry.y,invert,exception);
10635 (void) SetImageChannelMask(image,channel_mask);
10636 draw_info=DestroyDrawInfo(draw_info);
10637 break;
10638 }
10639 case 112: /* Distort */
10640 {
10641 AV
10642 *av;
10643
10644 double
10645 *coordinates;
10646
Cristy8645e042016-02-03 16:35:29 -050010647 DistortMethod
cristy4a3ce0a2013-08-03 20:06:59 +000010648 method;
10649
10650 size_t
10651 number_coordinates;
10652
10653 VirtualPixelMethod
10654 virtual_pixel;
10655
10656 if (attribute_flag[0] == 0)
10657 break;
10658 method=UndefinedDistortion;
10659 if (attribute_flag[1] != 0)
Cristy8645e042016-02-03 16:35:29 -050010660 method=(DistortMethod) argument_list[1].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010661 av=(AV *) argument_list[0].array_reference;
10662 number_coordinates=(size_t) av_len(av)+1;
10663 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10664 sizeof(*coordinates));
10665 if (coordinates == (double *) NULL)
10666 {
10667 ThrowPerlException(exception,ResourceLimitFatalError,
10668 "MemoryAllocationFailed",PackageName);
10669 goto PerlException;
10670 }
10671 for (j=0; j < (ssize_t) number_coordinates; j++)
10672 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10673 virtual_pixel=UndefinedVirtualPixelMethod;
10674 if (attribute_flag[2] != 0)
10675 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10676 argument_list[2].integer_reference,exception);
10677 image=DistortImage(image,method,number_coordinates,coordinates,
10678 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10679 exception);
10680 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10681 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10682 exception);
10683 coordinates=(double *) RelinquishMagickMemory(coordinates);
10684 break;
10685 }
10686 case 113: /* Clut */
10687 {
10688 PixelInterpolateMethod
10689 method;
10690
10691 if (attribute_flag[0] == 0)
10692 {
10693 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10694 PackageName);
10695 goto PerlException;
10696 }
10697 method=UndefinedInterpolatePixel;
10698 if (attribute_flag[1] != 0)
10699 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10700 if (attribute_flag[2] != 0)
10701 channel=(ChannelType) argument_list[2].integer_reference;
10702 channel_mask=SetImageChannelMask(image,channel);
10703 (void) ClutImage(image,argument_list[0].image_reference,method,
10704 exception);
10705 (void) SetImageChannelMask(image,channel_mask);
10706 break;
10707 }
10708 case 114: /* LiquidRescale */
10709 {
10710 if (attribute_flag[0] != 0)
10711 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10712 &geometry,exception);
10713 if (attribute_flag[1] != 0)
10714 geometry.width=argument_list[1].integer_reference;
10715 if (attribute_flag[2] != 0)
10716 geometry.height=argument_list[2].integer_reference;
10717 if (attribute_flag[3] == 0)
10718 argument_list[3].real_reference=1.0;
10719 if (attribute_flag[4] == 0)
10720 argument_list[4].real_reference=0.0;
10721 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10722 argument_list[3].real_reference,argument_list[4].real_reference,
10723 exception);
10724 break;
10725 }
10726 case 115: /* EncipherImage */
10727 {
10728 (void) EncipherImage(image,argument_list[0].string_reference,
10729 exception);
10730 break;
10731 }
10732 case 116: /* DecipherImage */
10733 {
10734 (void) DecipherImage(image,argument_list[0].string_reference,
10735 exception);
10736 break;
10737 }
10738 case 117: /* Deskew */
10739 {
10740 geometry_info.rho=QuantumRange/2.0;
10741 if (attribute_flag[0] != 0)
10742 flags=ParseGeometry(argument_list[0].string_reference,
10743 &geometry_info);
10744 if (attribute_flag[1] != 0)
10745 geometry_info.rho=StringToDoubleInterval(
10746 argument_list[1].string_reference,(double) QuantumRange+1.0);
10747 image=DeskewImage(image,geometry_info.rho,exception);
10748 break;
10749 }
10750 case 118: /* Remap */
10751 {
10752 QuantizeInfo
10753 *quantize_info;
10754
10755 if (attribute_flag[0] == 0)
10756 {
10757 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10758 PackageName);
10759 goto PerlException;
10760 }
10761 quantize_info=AcquireQuantizeInfo(info->image_info);
10762 if (attribute_flag[1] != 0)
10763 quantize_info->dither_method=(DitherMethod)
10764 argument_list[1].integer_reference;
10765 (void) RemapImages(quantize_info,image,
10766 argument_list[0].image_reference,exception);
10767 quantize_info=DestroyQuantizeInfo(quantize_info);
10768 break;
10769 }
10770 case 119: /* SparseColor */
10771 {
10772 AV
10773 *av;
10774
10775 double
10776 *coordinates;
10777
10778 SparseColorMethod
10779 method;
10780
10781 size_t
10782 number_coordinates;
10783
10784 VirtualPixelMethod
10785 virtual_pixel;
10786
10787 if (attribute_flag[0] == 0)
10788 break;
10789 method=UndefinedColorInterpolate;
10790 if (attribute_flag[1] != 0)
10791 method=(SparseColorMethod) argument_list[1].integer_reference;
10792 av=(AV *) argument_list[0].array_reference;
10793 number_coordinates=(size_t) av_len(av)+1;
10794 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10795 sizeof(*coordinates));
10796 if (coordinates == (double *) NULL)
10797 {
10798 ThrowPerlException(exception,ResourceLimitFatalError,
10799 "MemoryAllocationFailed",PackageName);
10800 goto PerlException;
10801 }
10802 for (j=0; j < (ssize_t) number_coordinates; j++)
10803 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10804 virtual_pixel=UndefinedVirtualPixelMethod;
10805 if (attribute_flag[2] != 0)
10806 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10807 argument_list[2].integer_reference,exception);
10808 if (attribute_flag[3] != 0)
10809 channel=(ChannelType) argument_list[3].integer_reference;
10810 channel_mask=SetImageChannelMask(image,channel);
10811 image=SparseColorImage(image,method,number_coordinates,coordinates,
10812 exception);
10813 if (image != (Image *) NULL)
10814 (void) SetImageChannelMask(image,channel_mask);
10815 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10816 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10817 exception);
10818 coordinates=(double *) RelinquishMagickMemory(coordinates);
10819 break;
10820 }
10821 case 120: /* Function */
10822 {
10823 AV
10824 *av;
10825
10826 double
10827 *parameters;
10828
10829 MagickFunction
10830 function;
10831
10832 size_t
10833 number_parameters;
10834
10835 VirtualPixelMethod
10836 virtual_pixel;
10837
10838 if (attribute_flag[0] == 0)
10839 break;
10840 function=UndefinedFunction;
10841 if (attribute_flag[1] != 0)
10842 function=(MagickFunction) argument_list[1].integer_reference;
10843 av=(AV *) argument_list[0].array_reference;
10844 number_parameters=(size_t) av_len(av)+1;
10845 parameters=(double *) AcquireQuantumMemory(number_parameters,
10846 sizeof(*parameters));
10847 if (parameters == (double *) NULL)
10848 {
10849 ThrowPerlException(exception,ResourceLimitFatalError,
10850 "MemoryAllocationFailed",PackageName);
10851 goto PerlException;
10852 }
10853 for (j=0; j < (ssize_t) number_parameters; j++)
10854 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10855 virtual_pixel=UndefinedVirtualPixelMethod;
10856 if (attribute_flag[2] != 0)
10857 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10858 argument_list[2].integer_reference,exception);
10859 (void) FunctionImage(image,function,number_parameters,parameters,
10860 exception);
10861 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10862 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10863 exception);
10864 parameters=(double *) RelinquishMagickMemory(parameters);
10865 break;
10866 }
10867 case 121: /* SelectiveBlur */
10868 {
10869 if (attribute_flag[0] != 0)
10870 {
10871 flags=ParseGeometry(argument_list[0].string_reference,
10872 &geometry_info);
10873 if ((flags & SigmaValue) == 0)
10874 geometry_info.sigma=1.0;
10875 if ((flags & PercentValue) != 0)
10876 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10877 }
10878 if (attribute_flag[1] != 0)
10879 geometry_info.rho=argument_list[1].real_reference;
10880 if (attribute_flag[2] != 0)
10881 geometry_info.sigma=argument_list[2].real_reference;
10882 if (attribute_flag[3] != 0)
10883 geometry_info.xi=argument_list[3].integer_reference;;
10884 if (attribute_flag[5] != 0)
10885 channel=(ChannelType) argument_list[5].integer_reference;
10886 channel_mask=SetImageChannelMask(image,channel);
10887 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10888 geometry_info.xi,exception);
10889 if (image != (Image *) NULL)
10890 (void) SetImageChannelMask(image,channel_mask);
10891 break;
10892 }
10893 case 122: /* HaldClut */
10894 {
10895 if (attribute_flag[0] == 0)
10896 {
10897 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10898 PackageName);
10899 goto PerlException;
10900 }
10901 if (attribute_flag[1] != 0)
10902 channel=(ChannelType) argument_list[1].integer_reference;
10903 channel_mask=SetImageChannelMask(image,channel);
10904 (void) HaldClutImage(image,argument_list[0].image_reference,
10905 exception);
10906 (void) SetImageChannelMask(image,channel_mask);
10907 break;
10908 }
10909 case 123: /* BlueShift */
10910 {
10911 if (attribute_flag[0] != 0)
10912 (void) ParseGeometry(argument_list[0].string_reference,
10913 &geometry_info);
10914 image=BlueShiftImage(image,geometry_info.rho,exception);
10915 break;
10916 }
10917 case 124: /* ForwardFourierTransformImage */
10918 {
10919 image=ForwardFourierTransformImage(image,
10920 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10921 exception);
10922 break;
10923 }
10924 case 125: /* InverseFourierTransformImage */
10925 {
10926 image=InverseFourierTransformImage(image,image->next,
10927 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10928 exception);
10929 break;
10930 }
10931 case 126: /* ColorDecisionList */
10932 {
10933 if (attribute_flag[0] == 0)
10934 argument_list[0].string_reference=(char *) NULL;
10935 (void) ColorDecisionListImage(image,
10936 argument_list[0].string_reference,exception);
10937 break;
10938 }
10939 case 127: /* AutoGamma */
10940 {
10941 if (attribute_flag[0] != 0)
10942 channel=(ChannelType) argument_list[0].integer_reference;
10943 channel_mask=SetImageChannelMask(image,channel);
10944 (void) AutoGammaImage(image,exception);
10945 (void) SetImageChannelMask(image,channel_mask);
10946 break;
10947 }
10948 case 128: /* AutoLevel */
10949 {
10950 if (attribute_flag[0] != 0)
10951 channel=(ChannelType) argument_list[0].integer_reference;
10952 channel_mask=SetImageChannelMask(image,channel);
10953 (void) AutoLevelImage(image,exception);
10954 (void) SetImageChannelMask(image,channel_mask);
10955 break;
10956 }
10957 case 129: /* LevelColors */
10958 {
10959 PixelInfo
10960 black_point,
10961 white_point;
10962
10963 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10964 exception);
10965 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10966 exception);
10967 if (attribute_flag[1] != 0)
10968 (void) QueryColorCompliance(
10969 argument_list[1].string_reference,AllCompliance,&black_point,
10970 exception);
10971 if (attribute_flag[2] != 0)
10972 (void) QueryColorCompliance(
10973 argument_list[2].string_reference,AllCompliance,&white_point,
10974 exception);
10975 if (attribute_flag[3] != 0)
10976 channel=(ChannelType) argument_list[3].integer_reference;
10977 channel_mask=SetImageChannelMask(image,channel);
10978 (void) LevelImageColors(image,&black_point,&white_point,
10979 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10980 exception);
10981 (void) SetImageChannelMask(image,channel_mask);
10982 break;
10983 }
10984 case 130: /* Clamp */
10985 {
10986 if (attribute_flag[0] != 0)
10987 channel=(ChannelType) argument_list[0].integer_reference;
10988 channel_mask=SetImageChannelMask(image,channel);
10989 (void) ClampImage(image,exception);
10990 (void) SetImageChannelMask(image,channel_mask);
10991 break;
10992 }
10993 case 131: /* BrightnessContrast */
10994 {
10995 double
10996 brightness,
10997 contrast;
10998
10999 brightness=0.0;
11000 contrast=0.0;
11001 if (attribute_flag[0] != 0)
11002 {
11003 flags=ParseGeometry(argument_list[0].string_reference,
11004 &geometry_info);
11005 brightness=geometry_info.rho;
11006 if ((flags & SigmaValue) == 0)
11007 contrast=geometry_info.sigma;
11008 }
11009 if (attribute_flag[1] != 0)
11010 brightness=argument_list[1].real_reference;
11011 if (attribute_flag[2] != 0)
11012 contrast=argument_list[2].real_reference;
11013 if (attribute_flag[4] != 0)
11014 channel=(ChannelType) argument_list[4].integer_reference;
11015 channel_mask=SetImageChannelMask(image,channel);
11016 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11017 (void) SetImageChannelMask(image,channel_mask);
11018 break;
11019 }
11020 case 132: /* Morphology */
11021 {
11022 KernelInfo
11023 *kernel;
11024
11025 MorphologyMethod
11026 method;
11027
11028 ssize_t
11029 iterations;
11030
11031 if (attribute_flag[0] == 0)
11032 break;
cristy2c57b742014-10-31 00:40:34 +000011033 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011034 if (kernel == (KernelInfo *) NULL)
11035 break;
11036 if (attribute_flag[1] != 0)
11037 channel=(ChannelType) argument_list[1].integer_reference;
11038 method=UndefinedMorphology;
11039 if (attribute_flag[2] != 0)
11040 method=argument_list[2].integer_reference;
11041 iterations=1;
11042 if (attribute_flag[3] != 0)
11043 iterations=argument_list[3].integer_reference;
11044 channel_mask=SetImageChannelMask(image,channel);
11045 image=MorphologyImage(image,method,iterations,kernel,exception);
11046 if (image != (Image *) NULL)
11047 (void) SetImageChannelMask(image,channel_mask);
11048 kernel=DestroyKernelInfo(kernel);
11049 break;
11050 }
11051 case 133: /* Mode */
11052 {
11053 if (attribute_flag[0] != 0)
11054 {
11055 flags=ParseGeometry(argument_list[0].string_reference,
11056 &geometry_info);
11057 if ((flags & SigmaValue) == 0)
11058 geometry_info.sigma=1.0;
11059 }
11060 if (attribute_flag[1] != 0)
11061 geometry_info.rho=argument_list[1].real_reference;
11062 if (attribute_flag[2] != 0)
11063 geometry_info.sigma=argument_list[2].real_reference;
11064 if (attribute_flag[3] != 0)
11065 channel=(ChannelType) argument_list[3].integer_reference;
11066 channel_mask=SetImageChannelMask(image,channel);
11067 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11068 (size_t) geometry_info.sigma,exception);
11069 if (image != (Image *) NULL)
11070 (void) SetImageChannelMask(image,channel_mask);
11071 break;
11072 }
11073 case 134: /* Statistic */
11074 {
11075 StatisticType
11076 statistic;
11077
11078 statistic=UndefinedStatistic;
11079 if (attribute_flag[0] != 0)
11080 {
11081 flags=ParseGeometry(argument_list[0].string_reference,
11082 &geometry_info);
11083 if ((flags & SigmaValue) == 0)
11084 geometry_info.sigma=1.0;
11085 }
11086 if (attribute_flag[1] != 0)
11087 geometry_info.rho=argument_list[1].real_reference;
11088 if (attribute_flag[2] != 0)
11089 geometry_info.sigma=argument_list[2].real_reference;
11090 if (attribute_flag[3] != 0)
11091 channel=(ChannelType) argument_list[3].integer_reference;
11092 if (attribute_flag[4] != 0)
11093 statistic=(StatisticType) argument_list[4].integer_reference;
11094 channel_mask=SetImageChannelMask(image,channel);
11095 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11096 (size_t) geometry_info.sigma,exception);
11097 if (image != (Image *) NULL)
11098 (void) SetImageChannelMask(image,channel_mask);
11099 break;
11100 }
11101 case 135: /* Perceptible */
11102 {
11103 double
11104 epsilon;
11105
11106 epsilon=MagickEpsilon;
11107 if (attribute_flag[0] != 0)
11108 epsilon=argument_list[0].real_reference;
11109 if (attribute_flag[1] != 0)
11110 channel=(ChannelType) argument_list[1].integer_reference;
11111 channel_mask=SetImageChannelMask(image,channel);
11112 (void) PerceptibleImage(image,epsilon,exception);
11113 (void) SetImageChannelMask(image,channel_mask);
11114 break;
11115 }
11116 case 136: /* Poly */
11117 {
11118 AV
11119 *av;
11120
11121 double
11122 *terms;
11123
11124 size_t
11125 number_terms;
11126
11127 if (attribute_flag[0] == 0)
11128 break;
11129 if (attribute_flag[1] != 0)
11130 channel=(ChannelType) argument_list[1].integer_reference;
11131 av=(AV *) argument_list[0].array_reference;
11132 number_terms=(size_t) av_len(av);
11133 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11134 if (terms == (double *) NULL)
11135 {
11136 ThrowPerlException(exception,ResourceLimitFatalError,
11137 "MemoryAllocationFailed",PackageName);
11138 goto PerlException;
11139 }
11140 for (j=0; j < av_len(av); j++)
11141 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11142 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11143 terms=(double *) RelinquishMagickMemory(terms);
11144 break;
11145 }
11146 case 137: /* Grayscale */
11147 {
11148 PixelIntensityMethod
11149 method;
11150
11151 method=UndefinedPixelIntensityMethod;
11152 if (attribute_flag[0] != 0)
11153 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11154 (void) GrayscaleImage(image,method,exception);
11155 break;
11156 }
cristy4ceadb82014-03-29 15:30:43 +000011157 case 138: /* Canny */
11158 {
11159 if (attribute_flag[0] != 0)
11160 {
11161 flags=ParseGeometry(argument_list[0].string_reference,
11162 &geometry_info);
11163 if ((flags & SigmaValue) == 0)
11164 geometry_info.sigma=1.0;
11165 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011166 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011167 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011168 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011169 if ((flags & PercentValue) != 0)
11170 {
11171 geometry_info.xi/=100.0;
11172 geometry_info.psi/=100.0;
11173 }
cristy4ceadb82014-03-29 15:30:43 +000011174 }
11175 if (attribute_flag[1] != 0)
11176 geometry_info.rho=argument_list[1].real_reference;
11177 if (attribute_flag[2] != 0)
11178 geometry_info.sigma=argument_list[2].real_reference;
11179 if (attribute_flag[3] != 0)
11180 geometry_info.xi=argument_list[3].real_reference;
11181 if (attribute_flag[4] != 0)
11182 geometry_info.psi=argument_list[4].real_reference;
11183 if (attribute_flag[5] != 0)
11184 channel=(ChannelType) argument_list[5].integer_reference;
11185 channel_mask=SetImageChannelMask(image,channel);
11186 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11187 geometry_info.xi,geometry_info.psi,exception);
11188 if (image != (Image *) NULL)
11189 (void) SetImageChannelMask(image,channel_mask);
11190 break;
11191 }
cristy2fc10e52014-04-26 14:13:53 +000011192 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011193 {
11194 if (attribute_flag[0] != 0)
11195 {
11196 flags=ParseGeometry(argument_list[0].string_reference,
11197 &geometry_info);
11198 if ((flags & SigmaValue) == 0)
11199 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011200 if ((flags & XiValue) == 0)
11201 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011202 }
11203 if (attribute_flag[1] != 0)
11204 geometry_info.rho=(double) argument_list[1].integer_reference;
11205 if (attribute_flag[2] != 0)
11206 geometry_info.sigma=(double) argument_list[2].integer_reference;
11207 if (attribute_flag[3] != 0)
11208 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011209 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11210 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11211 break;
11212 }
11213 case 140: /* MeanShift */
11214 {
11215 if (attribute_flag[0] != 0)
11216 {
11217 flags=ParseGeometry(argument_list[0].string_reference,
11218 &geometry_info);
11219 if ((flags & SigmaValue) == 0)
11220 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011221 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011222 geometry_info.xi=0.10*QuantumRange;
11223 if ((flags & PercentValue) != 0)
11224 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011225 }
11226 if (attribute_flag[1] != 0)
11227 geometry_info.rho=(double) argument_list[1].integer_reference;
11228 if (attribute_flag[2] != 0)
11229 geometry_info.sigma=(double) argument_list[2].integer_reference;
11230 if (attribute_flag[3] != 0)
11231 geometry_info.xi=(double) argument_list[3].integer_reference;
11232 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011233 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011234 break;
11235 }
cristy3b207f82014-09-27 14:21:20 +000011236 case 141: /* Kuwahara */
11237 {
11238 if (attribute_flag[0] != 0)
11239 {
11240 flags=ParseGeometry(argument_list[0].string_reference,
11241 &geometry_info);
11242 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011243 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011244 }
11245 if (attribute_flag[1] != 0)
11246 geometry_info.rho=argument_list[1].real_reference;
11247 if (attribute_flag[2] != 0)
11248 geometry_info.sigma=argument_list[2].real_reference;
11249 if (attribute_flag[3] != 0)
11250 channel=(ChannelType) argument_list[3].integer_reference;
11251 channel_mask=SetImageChannelMask(image,channel);
11252 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11253 exception);
11254 if (image != (Image *) NULL)
11255 (void) SetImageChannelMask(image,channel_mask);
11256 break;
11257 }
cristy6e0b3bc2014-10-19 17:51:42 +000011258 case 142: /* ConnectedComponent */
11259 {
11260 size_t
11261 connectivity;
11262
11263 connectivity=4;
11264 if (attribute_flag[0] != 0)
11265 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011266 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011267 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011268 break;
11269 }
cristy0b94b392015-06-22 18:56:37 +000011270 case 143: /* Copy */
11271 {
11272 Image
11273 *source_image;
11274
11275 OffsetInfo
11276 offset;
11277
cristy2ffdb092015-06-25 14:31:20 +000011278 RectangleInfo
11279 offset_geometry;
11280
cristyf3a724a2015-06-25 13:02:53 +000011281 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011282 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011283 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011284 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011285 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011286 flags=ParseGravityGeometry(source_image,
11287 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011288 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011289 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011290 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011291 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011292 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011293 geometry.x=argument_list[4].integer_reference;
11294 if (attribute_flag[5] != 0)
11295 geometry.y=argument_list[5].integer_reference;
11296 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011297 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011298 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011299 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011300 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11301 &offset_geometry,exception);
11302 offset.x=offset_geometry.x;
11303 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011304 if (attribute_flag[8] != 0)
11305 offset.x=argument_list[8].integer_reference;
11306 if (attribute_flag[9] != 0)
11307 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011308 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11309 exception);
cristy0b94b392015-06-22 18:56:37 +000011310 break;
11311 }
Cristy5488c982016-02-13 14:07:50 -050011312 case 144: /* Color */
11313 {
11314 PixelInfo
11315 color;
11316
Cristyf20e3562016-02-14 09:08:15 -050011317 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011318 if (attribute_flag[0] != 0)
Cristyf20e3562016-02-14 09:08:15 -050011319 (void) QueryColorCompliance(argument_list[0].string_reference,
11320 AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011321 (void) SetImageColor(image,&color,exception);
11322 break;
11323 }
cristy4a3ce0a2013-08-03 20:06:59 +000011324 }
11325 if (next != (Image *) NULL)
11326 (void) CatchImageException(next);
11327 if (region_image != (Image *) NULL)
11328 {
11329 /*
11330 Composite region.
cristy83a28a02013-08-03 20:25:48 +000011331 */
cristy4a3ce0a2013-08-03 20:06:59 +000011332 status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11333 region_info.x,region_info.y,exception);
11334 (void) status;
11335 (void) CatchImageException(region_image);
11336 image=DestroyImage(image);
11337 image=region_image;
11338 }
11339 if (image != (Image *) NULL)
11340 {
11341 number_images++;
11342 if (next && (next != image))
11343 {
11344 image->next=next->next;
11345 if (image->next != (Image *) NULL)
11346 image->next->previous=image;
11347 DeleteImageFromRegistry(*pv,next);
11348 }
11349 sv_setiv(*pv,PTR2IV(image));
11350 next=image;
11351 }
11352 if (*pv)
11353 pv++;
11354 }
11355
11356 PerlException:
11357 if (reference_vector)
11358 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11359 InheritPerlException(exception,perl_exception);
11360 exception=DestroyExceptionInfo(exception);
11361 sv_setiv(perl_exception,(IV) number_images);
11362 SvPOK_on(perl_exception);
11363 ST(0)=sv_2mortal(perl_exception);
11364 XSRETURN(1);
11365 }
11366
11367#
11368###############################################################################
11369# #
11370# #
11371# #
11372# M o n t a g e #
11373# #
11374# #
11375# #
11376###############################################################################
11377#
11378#
11379void
11380Montage(ref,...)
11381 Image::Magick ref=NO_INIT
11382 ALIAS:
11383 MontageImage = 1
11384 montage = 2
11385 montageimage = 3
11386 PPCODE:
11387 {
11388 AV
11389 *av;
11390
11391 char
11392 *attribute;
11393
11394 ExceptionInfo
11395 *exception;
11396
11397 HV
11398 *hv;
11399
11400 Image
11401 *image,
11402 *next;
11403
11404 PixelInfo
11405 transparent_color;
11406
11407 MontageInfo
11408 *montage_info;
11409
11410 register ssize_t
11411 i;
11412
11413 ssize_t
11414 sp;
11415
11416 struct PackageInfo
11417 *info;
11418
11419 SV
11420 *av_reference,
11421 *perl_exception,
11422 *reference,
11423 *rv,
11424 *sv;
11425
11426 PERL_UNUSED_VAR(ref);
11427 PERL_UNUSED_VAR(ix);
11428 exception=AcquireExceptionInfo();
11429 perl_exception=newSVpv("",0);
11430 sv=NULL;
11431 attribute=NULL;
11432 if (sv_isobject(ST(0)) == 0)
11433 {
11434 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11435 PackageName);
11436 goto PerlException;
11437 }
11438 reference=SvRV(ST(0));
11439 hv=SvSTASH(reference);
11440 av=newAV();
11441 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11442 SvREFCNT_dec(av);
11443 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11444 if (image == (Image *) NULL)
11445 {
11446 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11447 PackageName);
11448 goto PerlException;
11449 }
11450 /*
11451 Get options.
11452 */
11453 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11454 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11455 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11456 exception);
11457 for (i=2; i < items; i+=2)
11458 {
11459 attribute=(char *) SvPV(ST(i-1),na);
11460 switch (*attribute)
11461 {
11462 case 'B':
11463 case 'b':
11464 {
11465 if (LocaleCompare(attribute,"background") == 0)
11466 {
11467 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11468 &montage_info->background_color,exception);
11469 for (next=image; next; next=next->next)
11470 next->background_color=montage_info->background_color;
11471 break;
11472 }
11473 if (LocaleCompare(attribute,"border") == 0)
11474 {
11475 montage_info->border_width=SvIV(ST(i));
11476 break;
11477 }
11478 if (LocaleCompare(attribute,"bordercolor") == 0)
11479 {
11480 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11481 &montage_info->border_color,exception);
11482 for (next=image; next; next=next->next)
11483 next->border_color=montage_info->border_color;
11484 break;
11485 }
11486 if (LocaleCompare(attribute,"borderwidth") == 0)
11487 {
11488 montage_info->border_width=SvIV(ST(i));
11489 break;
11490 }
11491 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11492 attribute);
11493 break;
11494 }
11495 case 'C':
11496 case 'c':
11497 {
11498 if (LocaleCompare(attribute,"compose") == 0)
11499 {
11500 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11501 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11502 if (sp < 0)
11503 {
11504 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11505 SvPV(ST(i),na));
11506 break;
11507 }
11508 for (next=image; next; next=next->next)
11509 next->compose=(CompositeOperator) sp;
11510 break;
11511 }
11512 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11513 attribute);
11514 break;
11515 }
11516 case 'F':
11517 case 'f':
11518 {
11519 if (LocaleCompare(attribute,"fill") == 0)
11520 {
11521 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11522 &montage_info->fill,exception);
11523 break;
11524 }
11525 if (LocaleCompare(attribute,"font") == 0)
11526 {
11527 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11528 break;
11529 }
11530 if (LocaleCompare(attribute,"frame") == 0)
11531 {
11532 char
11533 *p;
11534
11535 p=SvPV(ST(i),na);
11536 if (IsGeometry(p) == MagickFalse)
11537 {
11538 ThrowPerlException(exception,OptionError,"MissingGeometry",
11539 p);
11540 break;
11541 }
11542 (void) CloneString(&montage_info->frame,p);
11543 if (*p == '\0')
11544 montage_info->frame=(char *) NULL;
11545 break;
11546 }
11547 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11548 attribute);
11549 break;
11550 }
11551 case 'G':
11552 case 'g':
11553 {
11554 if (LocaleCompare(attribute,"geometry") == 0)
11555 {
11556 char
11557 *p;
11558
11559 p=SvPV(ST(i),na);
11560 if (IsGeometry(p) == MagickFalse)
11561 {
11562 ThrowPerlException(exception,OptionError,"MissingGeometry",
11563 p);
11564 break;
11565 }
11566 (void) CloneString(&montage_info->geometry,p);
11567 if (*p == '\0')
11568 montage_info->geometry=(char *) NULL;
11569 break;
11570 }
11571 if (LocaleCompare(attribute,"gravity") == 0)
11572 {
11573 ssize_t
11574 in;
11575
11576 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11577 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11578 if (in < 0)
11579 {
11580 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11581 SvPV(ST(i),na));
11582 return;
11583 }
11584 montage_info->gravity=(GravityType) in;
11585 for (next=image; next; next=next->next)
11586 next->gravity=(GravityType) in;
11587 break;
11588 }
11589 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11590 attribute);
11591 break;
11592 }
11593 case 'L':
11594 case 'l':
11595 {
11596 if (LocaleCompare(attribute,"label") == 0)
11597 {
11598 for (next=image; next; next=next->next)
11599 (void) SetImageProperty(next,"label",InterpretImageProperties(
11600 info ? info->image_info : (ImageInfo *) NULL,next,
11601 SvPV(ST(i),na),exception),exception);
11602 break;
11603 }
11604 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11605 attribute);
11606 break;
11607 }
11608 case 'M':
11609 case 'm':
11610 {
11611 if (LocaleCompare(attribute,"mattecolor") == 0)
11612 {
11613 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
Cristy8645e042016-02-03 16:35:29 -050011614 &montage_info->alpha_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011615 for (next=image; next; next=next->next)
Cristy8645e042016-02-03 16:35:29 -050011616 next->alpha_color=montage_info->alpha_color;
cristy4a3ce0a2013-08-03 20:06:59 +000011617 break;
11618 }
11619 if (LocaleCompare(attribute,"mode") == 0)
11620 {
11621 ssize_t
11622 in;
11623
11624 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11625 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11626 switch (in)
11627 {
11628 default:
11629 {
11630 ThrowPerlException(exception,OptionError,
11631 "UnrecognizedModeType",SvPV(ST(i),na));
11632 break;
11633 }
11634 case FrameMode:
11635 {
11636 (void) CloneString(&montage_info->frame,"15x15+3+3");
11637 montage_info->shadow=MagickTrue;
11638 break;
11639 }
11640 case UnframeMode:
11641 {
11642 montage_info->frame=(char *) NULL;
11643 montage_info->shadow=MagickFalse;
11644 montage_info->border_width=0;
11645 break;
11646 }
11647 case ConcatenateMode:
11648 {
11649 montage_info->frame=(char *) NULL;
11650 montage_info->shadow=MagickFalse;
11651 (void) CloneString(&montage_info->geometry,"+0+0");
11652 montage_info->border_width=0;
11653 }
11654 }
11655 break;
11656 }
11657 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11658 attribute);
11659 break;
11660 }
11661 case 'P':
11662 case 'p':
11663 {
11664 if (LocaleCompare(attribute,"pointsize") == 0)
11665 {
11666 montage_info->pointsize=SvIV(ST(i));
11667 break;
11668 }
11669 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11670 attribute);
11671 break;
11672 }
11673 case 'S':
11674 case 's':
11675 {
11676 if (LocaleCompare(attribute,"shadow") == 0)
11677 {
11678 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11679 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11680 if (sp < 0)
11681 {
11682 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11683 SvPV(ST(i),na));
11684 break;
11685 }
11686 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11687 break;
11688 }
11689 if (LocaleCompare(attribute,"stroke") == 0)
11690 {
11691 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11692 &montage_info->stroke,exception);
11693 break;
11694 }
11695 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11696 attribute);
11697 break;
11698 }
11699 case 'T':
11700 case 't':
11701 {
11702 if (LocaleCompare(attribute,"texture") == 0)
11703 {
11704 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11705 break;
11706 }
11707 if (LocaleCompare(attribute,"tile") == 0)
11708 {
11709 char *p=SvPV(ST(i),na);
11710 if (IsGeometry(p) == MagickFalse)
11711 {
11712 ThrowPerlException(exception,OptionError,"MissingGeometry",
11713 p);
11714 break;
11715 }
11716 (void) CloneString(&montage_info->tile,p);
11717 if (*p == '\0')
11718 montage_info->tile=(char *) NULL;
11719 break;
11720 }
11721 if (LocaleCompare(attribute,"title") == 0)
11722 {
11723 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11724 break;
11725 }
11726 if (LocaleCompare(attribute,"transparent") == 0)
11727 {
11728 PixelInfo
11729 transparent_color;
11730
11731 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11732 &transparent_color,exception);
11733 for (next=image; next; next=next->next)
11734 (void) TransparentPaintImage(next,&transparent_color,
11735 TransparentAlpha,MagickFalse,exception);
11736 break;
11737 }
11738 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11739 attribute);
11740 break;
11741 }
11742 default:
11743 {
11744 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11745 attribute);
11746 break;
11747 }
11748 }
11749 }
11750 image=MontageImageList(info->image_info,montage_info,image,exception);
11751 montage_info=DestroyMontageInfo(montage_info);
11752 if (image == (Image *) NULL)
11753 goto PerlException;
11754 if (transparent_color.alpha != TransparentAlpha)
11755 for (next=image; next; next=next->next)
11756 (void) TransparentPaintImage(next,&transparent_color,
11757 TransparentAlpha,MagickFalse,exception);
11758 for ( ; image; image=image->next)
11759 {
11760 AddImageToRegistry(sv,image);
11761 rv=newRV(sv);
11762 av_push(av,sv_bless(rv,hv));
11763 SvREFCNT_dec(sv);
11764 }
11765 exception=DestroyExceptionInfo(exception);
11766 ST(0)=av_reference;
11767 SvREFCNT_dec(perl_exception);
11768 XSRETURN(1);
11769
11770 PerlException:
11771 InheritPerlException(exception,perl_exception);
11772 exception=DestroyExceptionInfo(exception);
11773 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11774 SvPOK_on(perl_exception);
11775 ST(0)=sv_2mortal(perl_exception);
11776 XSRETURN(1);
11777 }
11778
11779#
11780###############################################################################
11781# #
11782# #
11783# #
11784# M o r p h #
11785# #
11786# #
11787# #
11788###############################################################################
11789#
11790#
11791void
11792Morph(ref,...)
11793 Image::Magick ref=NO_INIT
11794 ALIAS:
11795 MorphImage = 1
11796 morph = 2
11797 morphimage = 3
11798 PPCODE:
11799 {
11800 AV
11801 *av;
11802
11803 char
11804 *attribute;
11805
11806 ExceptionInfo
11807 *exception;
11808
11809 HV
11810 *hv;
11811
11812 Image
11813 *image;
11814
11815 register ssize_t
11816 i;
11817
11818 ssize_t
11819 number_frames;
11820
11821 struct PackageInfo
11822 *info;
11823
11824 SV
11825 *av_reference,
11826 *perl_exception,
11827 *reference,
11828 *rv,
11829 *sv;
11830
11831 PERL_UNUSED_VAR(ref);
11832 PERL_UNUSED_VAR(ix);
11833 exception=AcquireExceptionInfo();
11834 perl_exception=newSVpv("",0);
11835 sv=NULL;
11836 av=NULL;
11837 attribute=NULL;
11838 if (sv_isobject(ST(0)) == 0)
11839 {
11840 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11841 PackageName);
11842 goto PerlException;
11843 }
11844 reference=SvRV(ST(0));
11845 hv=SvSTASH(reference);
11846 av=newAV();
11847 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11848 SvREFCNT_dec(av);
11849 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11850 if (image == (Image *) NULL)
11851 {
11852 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11853 PackageName);
11854 goto PerlException;
11855 }
11856 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11857 /*
11858 Get attribute.
11859 */
11860 number_frames=30;
11861 for (i=2; i < items; i+=2)
11862 {
11863 attribute=(char *) SvPV(ST(i-1),na);
11864 switch (*attribute)
11865 {
11866 case 'F':
11867 case 'f':
11868 {
11869 if (LocaleCompare(attribute,"frames") == 0)
11870 {
11871 number_frames=SvIV(ST(i));
11872 break;
11873 }
11874 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11875 attribute);
11876 break;
11877 }
11878 default:
11879 {
11880 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11881 attribute);
11882 break;
11883 }
11884 }
11885 }
11886 image=MorphImages(image,number_frames,exception);
11887 if (image == (Image *) NULL)
11888 goto PerlException;
11889 for ( ; image; image=image->next)
11890 {
11891 AddImageToRegistry(sv,image);
11892 rv=newRV(sv);
11893 av_push(av,sv_bless(rv,hv));
11894 SvREFCNT_dec(sv);
11895 }
11896 exception=DestroyExceptionInfo(exception);
11897 ST(0)=av_reference;
11898 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11899 XSRETURN(1);
11900
11901 PerlException:
11902 InheritPerlException(exception,perl_exception);
11903 exception=DestroyExceptionInfo(exception);
11904 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11905 SvPOK_on(perl_exception);
11906 ST(0)=sv_2mortal(perl_exception);
11907 XSRETURN(1);
11908 }
11909
11910#
11911###############################################################################
11912# #
11913# #
11914# #
11915# M o s a i c #
11916# #
11917# #
11918# #
11919###############################################################################
11920#
11921#
11922void
11923Mosaic(ref)
11924 Image::Magick ref=NO_INIT
11925 ALIAS:
11926 MosaicImage = 1
11927 mosaic = 2
11928 mosaicimage = 3
11929 PPCODE:
11930 {
11931 AV
11932 *av;
11933
11934 ExceptionInfo
11935 *exception;
11936
11937 HV
11938 *hv;
11939
11940 Image
11941 *image;
11942
11943 struct PackageInfo
11944 *info;
11945
11946 SV
11947 *perl_exception,
11948 *reference,
11949 *rv,
11950 *sv;
11951
11952 PERL_UNUSED_VAR(ref);
11953 PERL_UNUSED_VAR(ix);
11954 exception=AcquireExceptionInfo();
11955 perl_exception=newSVpv("",0);
11956 sv=NULL;
11957 if (sv_isobject(ST(0)) == 0)
11958 {
11959 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11960 PackageName);
11961 goto PerlException;
11962 }
11963 reference=SvRV(ST(0));
11964 hv=SvSTASH(reference);
11965 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11966 if (image == (Image *) NULL)
11967 {
11968 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11969 PackageName);
11970 goto PerlException;
11971 }
11972 image=MergeImageLayers(image,MosaicLayer,exception);
11973 /*
11974 Create blessed Perl array for the returned image.
11975 */
11976 av=newAV();
11977 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11978 SvREFCNT_dec(av);
11979 AddImageToRegistry(sv,image);
11980 rv=newRV(sv);
11981 av_push(av,sv_bless(rv,hv));
11982 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000011983 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000011984 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000011985 SetImageInfo(info->image_info,0,exception);
11986 exception=DestroyExceptionInfo(exception);
11987 SvREFCNT_dec(perl_exception);
11988 XSRETURN(1);
11989
11990 PerlException:
11991 InheritPerlException(exception,perl_exception);
11992 exception=DestroyExceptionInfo(exception);
11993 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11994 SvPOK_on(perl_exception); /* return messages in string context */
11995 ST(0)=sv_2mortal(perl_exception);
11996 XSRETURN(1);
11997 }
11998
11999#
12000###############################################################################
12001# #
12002# #
12003# #
12004# P i n g #
12005# #
12006# #
12007# #
12008###############################################################################
12009#
12010#
12011void
12012Ping(ref,...)
12013 Image::Magick ref=NO_INIT
12014 ALIAS:
12015 PingImage = 1
12016 ping = 2
12017 pingimage = 3
12018 PPCODE:
12019 {
12020 AV
12021 *av;
12022
12023 char
12024 **keep,
12025 **list;
12026
12027 ExceptionInfo
12028 *exception;
12029
12030 Image
12031 *image,
12032 *next;
12033
12034 int
12035 n;
12036
12037 MagickBooleanType
12038 status;
12039
12040 register char
12041 **p;
12042
12043 register ssize_t
12044 i;
12045
12046 ssize_t
12047 ac;
12048
12049 STRLEN
12050 *length;
12051
12052 struct PackageInfo
12053 *info,
12054 *package_info;
12055
12056 SV
12057 *perl_exception,
12058 *reference;
12059
12060 size_t
12061 count;
12062
12063 PERL_UNUSED_VAR(ref);
12064 PERL_UNUSED_VAR(ix);
12065 exception=AcquireExceptionInfo();
12066 perl_exception=newSVpv("",0);
12067 package_info=(struct PackageInfo *) NULL;
12068 ac=(items < 2) ? 1 : items-1;
12069 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12070 keep=list;
12071 length=(STRLEN *) NULL;
12072 if (list == (char **) NULL)
12073 {
12074 ThrowPerlException(exception,ResourceLimitError,
12075 "MemoryAllocationFailed",PackageName);
12076 goto PerlException;
12077 }
12078 keep=list;
12079 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12080 if (length == (STRLEN *) NULL)
12081 {
12082 ThrowPerlException(exception,ResourceLimitError,
12083 "MemoryAllocationFailed",PackageName);
12084 goto PerlException;
12085 }
12086 if (sv_isobject(ST(0)) == 0)
12087 {
12088 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12089 PackageName);
12090 goto PerlException;
12091 }
12092 reference=SvRV(ST(0));
12093 if (SvTYPE(reference) != SVt_PVAV)
12094 {
12095 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12096 PackageName);
12097 goto PerlException;
12098 }
12099 av=(AV *) reference;
12100 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12101 exception);
12102 package_info=ClonePackageInfo(info,exception);
12103 n=1;
12104 if (items <= 1)
12105 *list=(char *) (*package_info->image_info->filename ?
12106 package_info->image_info->filename : "XC:black");
12107 else
12108 for (n=0, i=0; i < ac; i++)
12109 {
12110 list[n]=(char *) SvPV(ST(i+1),length[n]);
12111 if ((items >= 3) && strEQcase(list[n],"blob"))
12112 {
12113 void
12114 *blob;
12115
12116 i++;
12117 blob=(void *) (SvPV(ST(i+1),length[n]));
12118 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12119 }
12120 if ((items >= 3) && strEQcase(list[n],"filename"))
12121 continue;
12122 if ((items >= 3) && strEQcase(list[n],"file"))
12123 {
12124 FILE
12125 *file;
12126
12127 PerlIO
12128 *io_info;
12129
12130 i++;
12131 io_info=IoIFP(sv_2io(ST(i+1)));
12132 if (io_info == (PerlIO *) NULL)
12133 {
12134 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12135 PackageName);
12136 continue;
12137 }
12138 file=PerlIO_findFILE(io_info);
12139 if (file == (FILE *) NULL)
12140 {
12141 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12142 PackageName);
12143 continue;
12144 }
12145 SetImageInfoFile(package_info->image_info,file);
12146 }
12147 if ((items >= 3) && strEQcase(list[n],"magick"))
12148 continue;
12149 n++;
12150 }
12151 list[n]=(char *) NULL;
12152 keep=list;
12153 status=ExpandFilenames(&n,&list);
12154 if (status == MagickFalse)
12155 {
12156 ThrowPerlException(exception,ResourceLimitError,
12157 "MemoryAllocationFailed",PackageName);
12158 goto PerlException;
12159 }
12160 count=0;
12161 for (i=0; i < n; i++)
12162 {
12163 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012164 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012165 image=PingImage(package_info->image_info,exception);
12166 if (image == (Image *) NULL)
12167 break;
12168 if ((package_info->image_info->file != (FILE *) NULL) ||
12169 (package_info->image_info->blob != (void *) NULL))
12170 DisassociateImageStream(image);
12171 count+=GetImageListLength(image);
12172 EXTEND(sp,4*count);
12173 for (next=image; next; next=next->next)
12174 {
12175 PUSHs(sv_2mortal(newSViv(next->columns)));
12176 PUSHs(sv_2mortal(newSViv(next->rows)));
12177 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12178 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12179 }
12180 image=DestroyImageList(image);
12181 }
12182 /*
12183 Free resources.
12184 */
12185 for (i=0; i < n; i++)
12186 if (list[i] != (char *) NULL)
12187 for (p=keep; list[i] != *p++; )
12188 if (*p == NULL)
12189 {
12190 list[i]=(char *) RelinquishMagickMemory(list[i]);
12191 break;
12192 }
12193
12194 PerlException:
12195 if (package_info != (struct PackageInfo *) NULL)
12196 DestroyPackageInfo(package_info);
12197 if (list && (list != keep))
12198 list=(char **) RelinquishMagickMemory(list);
12199 if (keep)
12200 keep=(char **) RelinquishMagickMemory(keep);
12201 if (length)
12202 length=(STRLEN *) RelinquishMagickMemory(length);
12203 InheritPerlException(exception,perl_exception);
12204 exception=DestroyExceptionInfo(exception);
12205 SvREFCNT_dec(perl_exception); /* throw away all errors */
12206 }
12207
12208#
12209###############################################################################
12210# #
12211# #
12212# #
12213# P r e v i e w #
12214# #
12215# #
12216# #
12217###############################################################################
12218#
12219#
12220void
12221Preview(ref,...)
12222 Image::Magick ref=NO_INIT
12223 ALIAS:
12224 PreviewImage = 1
12225 preview = 2
12226 previewimage = 3
12227 PPCODE:
12228 {
12229 AV
12230 *av;
12231
12232 ExceptionInfo
12233 *exception;
12234
12235 HV
12236 *hv;
12237
12238 Image
12239 *image,
12240 *preview_image;
12241
12242 PreviewType
12243 preview_type;
12244
12245 struct PackageInfo
12246 *info;
12247
12248 SV
12249 *av_reference,
12250 *perl_exception,
12251 *reference,
12252 *rv,
12253 *sv;
12254
12255 PERL_UNUSED_VAR(ref);
12256 PERL_UNUSED_VAR(ix);
12257 exception=AcquireExceptionInfo();
12258 perl_exception=newSVpv("",0);
12259 sv=NULL;
12260 av=NULL;
12261 if (sv_isobject(ST(0)) == 0)
12262 {
12263 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12264 PackageName);
12265 goto PerlException;
12266 }
12267 reference=SvRV(ST(0));
12268 hv=SvSTASH(reference);
12269 av=newAV();
12270 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12271 SvREFCNT_dec(av);
12272 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12273 if (image == (Image *) NULL)
12274 {
12275 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12276 PackageName);
12277 goto PerlException;
12278 }
12279 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12280 preview_type=GammaPreview;
12281 if (items > 1)
12282 preview_type=(PreviewType)
12283 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12284 for ( ; image; image=image->next)
12285 {
12286 preview_image=PreviewImage(image,preview_type,exception);
12287 if (preview_image == (Image *) NULL)
12288 goto PerlException;
12289 AddImageToRegistry(sv,preview_image);
12290 rv=newRV(sv);
12291 av_push(av,sv_bless(rv,hv));
12292 SvREFCNT_dec(sv);
12293 }
12294 exception=DestroyExceptionInfo(exception);
12295 ST(0)=av_reference;
12296 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12297 XSRETURN(1);
12298
12299 PerlException:
12300 InheritPerlException(exception,perl_exception);
12301 exception=DestroyExceptionInfo(exception);
12302 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12303 SvPOK_on(perl_exception);
12304 ST(0)=sv_2mortal(perl_exception);
12305 XSRETURN(1);
12306 }
12307
12308#
12309###############################################################################
12310# #
12311# #
12312# #
12313# Q u e r y C o l o r #
12314# #
12315# #
12316# #
12317###############################################################################
12318#
12319#
12320void
12321QueryColor(ref,...)
12322 Image::Magick ref=NO_INIT
12323 ALIAS:
12324 querycolor = 1
12325 PPCODE:
12326 {
12327 char
12328 *name;
12329
12330 ExceptionInfo
12331 *exception;
12332
12333 PixelInfo
12334 color;
12335
12336 register ssize_t
12337 i;
12338
12339 SV
12340 *perl_exception;
12341
12342 PERL_UNUSED_VAR(ref);
12343 PERL_UNUSED_VAR(ix);
12344 exception=AcquireExceptionInfo();
12345 perl_exception=newSVpv("",0);
12346 if (items == 1)
12347 {
12348 const ColorInfo
12349 **colorlist;
12350
12351 size_t
12352 colors;
12353
12354 colorlist=GetColorInfoList("*",&colors,exception);
12355 EXTEND(sp,colors);
12356 for (i=0; i < (ssize_t) colors; i++)
12357 {
12358 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12359 }
12360 colorlist=(const ColorInfo **)
12361 RelinquishMagickMemory((ColorInfo **) colorlist);
12362 goto PerlException;
12363 }
12364 EXTEND(sp,5*items);
12365 for (i=1; i < items; i++)
12366 {
12367 name=(char *) SvPV(ST(i),na);
12368 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12369 {
12370 PUSHs(&sv_undef);
12371 continue;
12372 }
12373 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12374 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12375 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12376 if (color.colorspace == CMYKColorspace)
12377 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012378 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012379 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12380 }
12381
12382 PerlException:
12383 InheritPerlException(exception,perl_exception);
12384 exception=DestroyExceptionInfo(exception);
12385 SvREFCNT_dec(perl_exception);
12386 }
12387
12388#
12389###############################################################################
12390# #
12391# #
12392# #
12393# Q u e r y C o l o r N a m e #
12394# #
12395# #
12396# #
12397###############################################################################
12398#
12399#
12400void
12401QueryColorname(ref,...)
12402 Image::Magick ref=NO_INIT
12403 ALIAS:
12404 querycolorname = 1
12405 PPCODE:
12406 {
12407 AV
12408 *av;
12409
12410 char
cristy151b66d2015-04-15 10:50:31 +000012411 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012412
12413 ExceptionInfo
12414 *exception;
12415
12416 Image
12417 *image;
12418
12419 PixelInfo
12420 target_color;
12421
12422 register ssize_t
12423 i;
12424
12425 struct PackageInfo
12426 *info;
12427
12428 SV
12429 *perl_exception,
12430 *reference; /* reference is the SV* of ref=SvIV(reference) */
12431
12432 PERL_UNUSED_VAR(ref);
12433 PERL_UNUSED_VAR(ix);
12434 exception=AcquireExceptionInfo();
12435 perl_exception=newSVpv("",0);
12436 reference=SvRV(ST(0));
12437 av=(AV *) reference;
12438 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12439 exception);
12440 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12441 if (image == (Image *) NULL)
12442 {
12443 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12444 PackageName);
12445 goto PerlException;
12446 }
12447 EXTEND(sp,items);
12448 for (i=1; i < items; i++)
12449 {
12450 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12451 exception);
12452 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12453 exception);
12454 PUSHs(sv_2mortal(newSVpv(message,0)));
12455 }
12456
12457 PerlException:
12458 InheritPerlException(exception,perl_exception);
12459 exception=DestroyExceptionInfo(exception);
12460 SvREFCNT_dec(perl_exception);
12461 }
12462
12463#
12464###############################################################################
12465# #
12466# #
12467# #
12468# Q u e r y F o n t #
12469# #
12470# #
12471# #
12472###############################################################################
12473#
12474#
12475void
12476QueryFont(ref,...)
12477 Image::Magick ref=NO_INIT
12478 ALIAS:
12479 queryfont = 1
12480 PPCODE:
12481 {
12482 char
12483 *name,
cristy151b66d2015-04-15 10:50:31 +000012484 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012485
12486 ExceptionInfo
12487 *exception;
12488
12489 register ssize_t
12490 i;
12491
12492 SV
12493 *perl_exception;
12494
12495 volatile const TypeInfo
12496 *type_info;
12497
12498 PERL_UNUSED_VAR(ref);
12499 PERL_UNUSED_VAR(ix);
12500 exception=AcquireExceptionInfo();
12501 perl_exception=newSVpv("",0);
12502 if (items == 1)
12503 {
12504 const TypeInfo
12505 **typelist;
12506
12507 size_t
12508 types;
12509
12510 typelist=GetTypeInfoList("*",&types,exception);
12511 EXTEND(sp,types);
12512 for (i=0; i < (ssize_t) types; i++)
12513 {
12514 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12515 }
12516 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12517 typelist);
12518 goto PerlException;
12519 }
12520 EXTEND(sp,10*items);
12521 for (i=1; i < items; i++)
12522 {
12523 name=(char *) SvPV(ST(i),na);
12524 type_info=GetTypeInfo(name,exception);
12525 if (type_info == (TypeInfo *) NULL)
12526 {
12527 PUSHs(&sv_undef);
12528 continue;
12529 }
12530 if (type_info->name == (char *) NULL)
12531 PUSHs(&sv_undef);
12532 else
12533 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12534 if (type_info->description == (char *) NULL)
12535 PUSHs(&sv_undef);
12536 else
12537 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12538 if (type_info->family == (char *) NULL)
12539 PUSHs(&sv_undef);
12540 else
12541 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12542 if (type_info->style == UndefinedStyle)
12543 PUSHs(&sv_undef);
12544 else
12545 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12546 type_info->style),0)));
12547 if (type_info->stretch == UndefinedStretch)
12548 PUSHs(&sv_undef);
12549 else
12550 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12551 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012552 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012553 type_info->weight);
12554 PUSHs(sv_2mortal(newSVpv(message,0)));
12555 if (type_info->encoding == (char *) NULL)
12556 PUSHs(&sv_undef);
12557 else
12558 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12559 if (type_info->foundry == (char *) NULL)
12560 PUSHs(&sv_undef);
12561 else
12562 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12563 if (type_info->format == (char *) NULL)
12564 PUSHs(&sv_undef);
12565 else
12566 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12567 if (type_info->metrics == (char *) NULL)
12568 PUSHs(&sv_undef);
12569 else
12570 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12571 if (type_info->glyphs == (char *) NULL)
12572 PUSHs(&sv_undef);
12573 else
12574 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12575 }
12576
12577 PerlException:
12578 InheritPerlException(exception,perl_exception);
12579 exception=DestroyExceptionInfo(exception);
12580 SvREFCNT_dec(perl_exception);
12581 }
12582
12583#
12584###############################################################################
12585# #
12586# #
12587# #
12588# Q u e r y F o n t M e t r i c s #
12589# #
12590# #
12591# #
12592###############################################################################
12593#
12594#
12595void
12596QueryFontMetrics(ref,...)
12597 Image::Magick ref=NO_INIT
12598 ALIAS:
12599 queryfontmetrics = 1
12600 PPCODE:
12601 {
12602 AffineMatrix
12603 affine,
12604 current;
12605
12606 AV
12607 *av;
12608
12609 char
12610 *attribute;
12611
12612 double
12613 x,
12614 y;
12615
12616 DrawInfo
12617 *draw_info;
12618
12619 ExceptionInfo
12620 *exception;
12621
12622 GeometryInfo
12623 geometry_info;
12624
12625 Image
12626 *image;
12627
12628 MagickBooleanType
12629 status;
12630
12631 MagickStatusType
12632 flags;
12633
12634 register ssize_t
12635 i;
12636
12637 ssize_t
12638 type;
12639
12640 struct PackageInfo
12641 *info,
12642 *package_info;
12643
12644 SV
12645 *perl_exception,
12646 *reference; /* reference is the SV* of ref=SvIV(reference) */
12647
12648 TypeMetric
12649 metrics;
12650
12651 PERL_UNUSED_VAR(ref);
12652 PERL_UNUSED_VAR(ix);
12653 exception=AcquireExceptionInfo();
12654 package_info=(struct PackageInfo *) NULL;
12655 perl_exception=newSVpv("",0);
12656 reference=SvRV(ST(0));
12657 av=(AV *) reference;
12658 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12659 exception);
12660 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12661 if (image == (Image *) NULL)
12662 {
12663 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12664 PackageName);
12665 goto PerlException;
12666 }
12667 package_info=ClonePackageInfo(info,exception);
12668 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12669 CloneString(&draw_info->text,"");
12670 current=draw_info->affine;
12671 GetAffineMatrix(&affine);
12672 x=0.0;
12673 y=0.0;
12674 EXTEND(sp,7*items);
12675 for (i=2; i < items; i+=2)
12676 {
12677 attribute=(char *) SvPV(ST(i-1),na);
12678 switch (*attribute)
12679 {
12680 case 'A':
12681 case 'a':
12682 {
12683 if (LocaleCompare(attribute,"antialias") == 0)
12684 {
12685 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12686 SvPV(ST(i),na));
12687 if (type < 0)
12688 {
12689 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12690 SvPV(ST(i),na));
12691 break;
12692 }
12693 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12694 break;
12695 }
12696 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12697 attribute);
12698 break;
12699 }
12700 case 'd':
12701 case 'D':
12702 {
12703 if (LocaleCompare(attribute,"density") == 0)
12704 {
12705 CloneString(&draw_info->density,SvPV(ST(i),na));
12706 break;
12707 }
12708 if (LocaleCompare(attribute,"direction") == 0)
12709 {
12710 draw_info->direction=(DirectionType) ParseCommandOption(
12711 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12712 break;
12713 }
12714 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12715 attribute);
12716 break;
12717 }
12718 case 'e':
12719 case 'E':
12720 {
12721 if (LocaleCompare(attribute,"encoding") == 0)
12722 {
12723 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12724 break;
12725 }
12726 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12727 attribute);
12728 break;
12729 }
12730 case 'f':
12731 case 'F':
12732 {
12733 if (LocaleCompare(attribute,"family") == 0)
12734 {
12735 CloneString(&draw_info->family,SvPV(ST(i),na));
12736 break;
12737 }
12738 if (LocaleCompare(attribute,"fill") == 0)
12739 {
12740 if (info)
12741 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12742 &draw_info->fill,exception);
12743 break;
12744 }
12745 if (LocaleCompare(attribute,"font") == 0)
12746 {
12747 CloneString(&draw_info->font,SvPV(ST(i),na));
12748 break;
12749 }
12750 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12751 attribute);
12752 break;
12753 }
12754 case 'g':
12755 case 'G':
12756 {
12757 if (LocaleCompare(attribute,"geometry") == 0)
12758 {
12759 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12760 break;
12761 }
12762 if (LocaleCompare(attribute,"gravity") == 0)
12763 {
12764 draw_info->gravity=(GravityType) ParseCommandOption(
12765 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12766 break;
12767 }
12768 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12769 attribute);
12770 break;
12771 }
12772 case 'i':
12773 case 'I':
12774 {
12775 if (LocaleCompare(attribute,"interline-spacing") == 0)
12776 {
12777 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12778 draw_info->interline_spacing=geometry_info.rho;
12779 break;
12780 }
12781 if (LocaleCompare(attribute,"interword-spacing") == 0)
12782 {
12783 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12784 draw_info->interword_spacing=geometry_info.rho;
12785 break;
12786 }
12787 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12788 attribute);
12789 break;
12790 }
12791 case 'k':
12792 case 'K':
12793 {
12794 if (LocaleCompare(attribute,"kerning") == 0)
12795 {
12796 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12797 draw_info->kerning=geometry_info.rho;
12798 break;
12799 }
12800 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12801 attribute);
12802 break;
12803 }
12804 case 'p':
12805 case 'P':
12806 {
12807 if (LocaleCompare(attribute,"pointsize") == 0)
12808 {
12809 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12810 draw_info->pointsize=geometry_info.rho;
12811 break;
12812 }
12813 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12814 attribute);
12815 break;
12816 }
12817 case 'r':
12818 case 'R':
12819 {
12820 if (LocaleCompare(attribute,"rotate") == 0)
12821 {
12822 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12823 affine.rx=geometry_info.rho;
12824 affine.ry=geometry_info.sigma;
12825 if ((flags & SigmaValue) == 0)
12826 affine.ry=affine.rx;
12827 break;
12828 }
12829 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12830 attribute);
12831 break;
12832 }
12833 case 's':
12834 case 'S':
12835 {
12836 if (LocaleCompare(attribute,"scale") == 0)
12837 {
12838 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12839 affine.sx=geometry_info.rho;
12840 affine.sy=geometry_info.sigma;
12841 if ((flags & SigmaValue) == 0)
12842 affine.sy=affine.sx;
12843 break;
12844 }
12845 if (LocaleCompare(attribute,"skew") == 0)
12846 {
12847 double
12848 x_angle,
12849 y_angle;
12850
12851 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12852 x_angle=geometry_info.rho;
12853 y_angle=geometry_info.sigma;
12854 if ((flags & SigmaValue) == 0)
12855 y_angle=x_angle;
12856 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12857 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12858 break;
12859 }
12860 if (LocaleCompare(attribute,"stroke") == 0)
12861 {
12862 if (info)
12863 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12864 &draw_info->stroke,exception);
12865 break;
12866 }
12867 if (LocaleCompare(attribute,"style") == 0)
12868 {
12869 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12870 SvPV(ST(i),na));
12871 if (type < 0)
12872 {
12873 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12874 SvPV(ST(i),na));
12875 break;
12876 }
12877 draw_info->style=(StyleType) type;
12878 break;
12879 }
12880 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12881 attribute);
12882 break;
12883 }
12884 case 't':
12885 case 'T':
12886 {
12887 if (LocaleCompare(attribute,"text") == 0)
12888 {
12889 CloneString(&draw_info->text,SvPV(ST(i),na));
12890 break;
12891 }
12892 if (LocaleCompare(attribute,"translate") == 0)
12893 {
12894 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12895 affine.tx=geometry_info.rho;
12896 affine.ty=geometry_info.sigma;
12897 if ((flags & SigmaValue) == 0)
12898 affine.ty=affine.tx;
12899 break;
12900 }
12901 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12902 attribute);
12903 break;
12904 }
12905 case 'w':
12906 case 'W':
12907 {
12908 if (LocaleCompare(attribute,"weight") == 0)
12909 {
12910 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12911 draw_info->weight=(size_t) geometry_info.rho;
12912 break;
12913 }
12914 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12915 attribute);
12916 break;
12917 }
12918 case 'x':
12919 case 'X':
12920 {
12921 if (LocaleCompare(attribute,"x") == 0)
12922 {
12923 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12924 x=geometry_info.rho;
12925 break;
12926 }
12927 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12928 attribute);
12929 break;
12930 }
12931 case 'y':
12932 case 'Y':
12933 {
12934 if (LocaleCompare(attribute,"y") == 0)
12935 {
12936 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12937 y=geometry_info.rho;
12938 break;
12939 }
12940 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12941 attribute);
12942 break;
12943 }
12944 default:
12945 {
12946 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12947 attribute);
12948 break;
12949 }
12950 }
12951 }
12952 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12953 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12954 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12955 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12956 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12957 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12958 if (draw_info->geometry == (char *) NULL)
12959 {
12960 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000012961 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000012962 "%.15g,%.15g",x,y);
12963 }
12964 status=GetTypeMetrics(image,draw_info,&metrics,exception);
12965 (void) CatchImageException(image);
12966 if (status == MagickFalse)
12967 PUSHs(&sv_undef);
12968 else
12969 {
12970 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12971 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12972 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12973 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12974 PUSHs(sv_2mortal(newSVnv(metrics.width)));
12975 PUSHs(sv_2mortal(newSVnv(metrics.height)));
12976 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12977 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
12978 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
12979 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
12980 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
12981 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
12982 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
12983 }
12984 draw_info=DestroyDrawInfo(draw_info);
12985
12986 PerlException:
12987 if (package_info != (struct PackageInfo *) NULL)
12988 DestroyPackageInfo(package_info);
12989 InheritPerlException(exception,perl_exception);
12990 exception=DestroyExceptionInfo(exception);
12991 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12992 }
12993
12994#
12995###############################################################################
12996# #
12997# #
12998# #
12999# 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 #
13000# #
13001# #
13002# #
13003###############################################################################
13004#
13005#
13006void
13007QueryMultilineFontMetrics(ref,...)
13008 Image::Magick ref=NO_INIT
13009 ALIAS:
13010 querymultilinefontmetrics = 1
13011 PPCODE:
13012 {
13013 AffineMatrix
13014 affine,
13015 current;
13016
13017 AV
13018 *av;
13019
13020 char
13021 *attribute;
13022
13023 double
13024 x,
13025 y;
13026
13027 DrawInfo
13028 *draw_info;
13029
13030 ExceptionInfo
13031 *exception;
13032
13033 GeometryInfo
13034 geometry_info;
13035
13036 Image
13037 *image;
13038
13039 MagickBooleanType
13040 status;
13041
13042 MagickStatusType
13043 flags;
13044
13045 register ssize_t
13046 i;
13047
13048 ssize_t
13049 type;
13050
13051 struct PackageInfo
13052 *info,
13053 *package_info;
13054
13055 SV
13056 *perl_exception,
13057 *reference; /* reference is the SV* of ref=SvIV(reference) */
13058
13059 TypeMetric
13060 metrics;
13061
13062 PERL_UNUSED_VAR(ref);
13063 PERL_UNUSED_VAR(ix);
13064 exception=AcquireExceptionInfo();
13065 package_info=(struct PackageInfo *) NULL;
13066 perl_exception=newSVpv("",0);
13067 reference=SvRV(ST(0));
13068 av=(AV *) reference;
13069 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13070 exception);
13071 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13072 if (image == (Image *) NULL)
13073 {
13074 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13075 PackageName);
13076 goto PerlException;
13077 }
13078 package_info=ClonePackageInfo(info,exception);
13079 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13080 CloneString(&draw_info->text,"");
13081 current=draw_info->affine;
13082 GetAffineMatrix(&affine);
13083 x=0.0;
13084 y=0.0;
13085 EXTEND(sp,7*items);
13086 for (i=2; i < items; i+=2)
13087 {
13088 attribute=(char *) SvPV(ST(i-1),na);
13089 switch (*attribute)
13090 {
13091 case 'A':
13092 case 'a':
13093 {
13094 if (LocaleCompare(attribute,"antialias") == 0)
13095 {
13096 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13097 SvPV(ST(i),na));
13098 if (type < 0)
13099 {
13100 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13101 SvPV(ST(i),na));
13102 break;
13103 }
13104 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13105 break;
13106 }
13107 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13108 attribute);
13109 break;
13110 }
13111 case 'd':
13112 case 'D':
13113 {
13114 if (LocaleCompare(attribute,"density") == 0)
13115 {
13116 CloneString(&draw_info->density,SvPV(ST(i),na));
13117 break;
13118 }
13119 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13120 attribute);
13121 break;
13122 }
13123 case 'e':
13124 case 'E':
13125 {
13126 if (LocaleCompare(attribute,"encoding") == 0)
13127 {
13128 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13129 break;
13130 }
13131 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13132 attribute);
13133 break;
13134 }
13135 case 'f':
13136 case 'F':
13137 {
13138 if (LocaleCompare(attribute,"family") == 0)
13139 {
13140 CloneString(&draw_info->family,SvPV(ST(i),na));
13141 break;
13142 }
13143 if (LocaleCompare(attribute,"fill") == 0)
13144 {
13145 if (info)
13146 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13147 &draw_info->fill,exception);
13148 break;
13149 }
13150 if (LocaleCompare(attribute,"font") == 0)
13151 {
13152 CloneString(&draw_info->font,SvPV(ST(i),na));
13153 break;
13154 }
13155 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13156 attribute);
13157 break;
13158 }
13159 case 'g':
13160 case 'G':
13161 {
13162 if (LocaleCompare(attribute,"geometry") == 0)
13163 {
13164 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13165 break;
13166 }
13167 if (LocaleCompare(attribute,"gravity") == 0)
13168 {
13169 draw_info->gravity=(GravityType) ParseCommandOption(
13170 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13171 break;
13172 }
13173 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13174 attribute);
13175 break;
13176 }
13177 case 'p':
13178 case 'P':
13179 {
13180 if (LocaleCompare(attribute,"pointsize") == 0)
13181 {
13182 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13183 draw_info->pointsize=geometry_info.rho;
13184 break;
13185 }
13186 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13187 attribute);
13188 break;
13189 }
13190 case 'r':
13191 case 'R':
13192 {
13193 if (LocaleCompare(attribute,"rotate") == 0)
13194 {
13195 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13196 affine.rx=geometry_info.rho;
13197 affine.ry=geometry_info.sigma;
13198 if ((flags & SigmaValue) == 0)
13199 affine.ry=affine.rx;
13200 break;
13201 }
13202 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13203 attribute);
13204 break;
13205 }
13206 case 's':
13207 case 'S':
13208 {
13209 if (LocaleCompare(attribute,"scale") == 0)
13210 {
13211 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13212 affine.sx=geometry_info.rho;
13213 affine.sy=geometry_info.sigma;
13214 if ((flags & SigmaValue) == 0)
13215 affine.sy=affine.sx;
13216 break;
13217 }
13218 if (LocaleCompare(attribute,"skew") == 0)
13219 {
13220 double
13221 x_angle,
13222 y_angle;
13223
13224 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13225 x_angle=geometry_info.rho;
13226 y_angle=geometry_info.sigma;
13227 if ((flags & SigmaValue) == 0)
13228 y_angle=x_angle;
13229 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13230 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13231 break;
13232 }
13233 if (LocaleCompare(attribute,"stroke") == 0)
13234 {
13235 if (info)
13236 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13237 &draw_info->stroke,exception);
13238 break;
13239 }
13240 if (LocaleCompare(attribute,"style") == 0)
13241 {
13242 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13243 SvPV(ST(i),na));
13244 if (type < 0)
13245 {
13246 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13247 SvPV(ST(i),na));
13248 break;
13249 }
13250 draw_info->style=(StyleType) type;
13251 break;
13252 }
13253 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13254 attribute);
13255 break;
13256 }
13257 case 't':
13258 case 'T':
13259 {
13260 if (LocaleCompare(attribute,"text") == 0)
13261 {
13262 CloneString(&draw_info->text,SvPV(ST(i),na));
13263 break;
13264 }
13265 if (LocaleCompare(attribute,"translate") == 0)
13266 {
13267 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13268 affine.tx=geometry_info.rho;
13269 affine.ty=geometry_info.sigma;
13270 if ((flags & SigmaValue) == 0)
13271 affine.ty=affine.tx;
13272 break;
13273 }
13274 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13275 attribute);
13276 break;
13277 }
13278 case 'w':
13279 case 'W':
13280 {
13281 if (LocaleCompare(attribute,"weight") == 0)
13282 {
13283 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13284 draw_info->weight=(size_t) geometry_info.rho;
13285 break;
13286 }
13287 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13288 attribute);
13289 break;
13290 }
13291 case 'x':
13292 case 'X':
13293 {
13294 if (LocaleCompare(attribute,"x") == 0)
13295 {
13296 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13297 x=geometry_info.rho;
13298 break;
13299 }
13300 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13301 attribute);
13302 break;
13303 }
13304 case 'y':
13305 case 'Y':
13306 {
13307 if (LocaleCompare(attribute,"y") == 0)
13308 {
13309 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13310 y=geometry_info.rho;
13311 break;
13312 }
13313 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13314 attribute);
13315 break;
13316 }
13317 default:
13318 {
13319 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13320 attribute);
13321 break;
13322 }
13323 }
13324 }
13325 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13326 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13327 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13328 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13329 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13330 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13331 if (draw_info->geometry == (char *) NULL)
13332 {
13333 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013334 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013335 "%.15g,%.15g",x,y);
13336 }
13337 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13338 (void) CatchException(exception);
13339 if (status == MagickFalse)
13340 PUSHs(&sv_undef);
13341 else
13342 {
13343 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13344 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13345 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13346 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13347 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13348 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13349 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13350 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13351 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13352 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13353 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13354 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13355 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13356 }
13357 draw_info=DestroyDrawInfo(draw_info);
13358
13359 PerlException:
13360 if (package_info != (struct PackageInfo *) NULL)
13361 DestroyPackageInfo(package_info);
13362 InheritPerlException(exception,perl_exception);
13363 exception=DestroyExceptionInfo(exception);
13364 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13365 }
13366
13367#
13368###############################################################################
13369# #
13370# #
13371# #
13372# Q u e r y F o r m a t #
13373# #
13374# #
13375# #
13376###############################################################################
13377#
13378#
13379void
13380QueryFormat(ref,...)
13381 Image::Magick ref=NO_INIT
13382 ALIAS:
13383 queryformat = 1
13384 PPCODE:
13385 {
13386 char
13387 *name;
13388
13389 ExceptionInfo
13390 *exception;
13391
13392 register ssize_t
13393 i;
13394
13395 SV
13396 *perl_exception;
13397
13398 volatile const MagickInfo
13399 *magick_info;
13400
13401 PERL_UNUSED_VAR(ref);
13402 PERL_UNUSED_VAR(ix);
13403 exception=AcquireExceptionInfo();
13404 perl_exception=newSVpv("",0);
13405 if (items == 1)
13406 {
13407 char
cristy151b66d2015-04-15 10:50:31 +000013408 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013409
13410 const MagickInfo
13411 **format_list;
13412
13413 size_t
13414 types;
13415
13416 format_list=GetMagickInfoList("*",&types,exception);
13417 EXTEND(sp,types);
13418 for (i=0; i < (ssize_t) types; i++)
13419 {
cristy151b66d2015-04-15 10:50:31 +000013420 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013421 LocaleLower(format);
13422 PUSHs(sv_2mortal(newSVpv(format,0)));
13423 }
13424 format_list=(const MagickInfo **)
13425 RelinquishMagickMemory((MagickInfo *) format_list);
13426 goto PerlException;
13427 }
13428 EXTEND(sp,8*items);
13429 for (i=1; i < items; i++)
13430 {
13431 name=(char *) SvPV(ST(i),na);
13432 magick_info=GetMagickInfo(name,exception);
13433 if (magick_info == (const MagickInfo *) NULL)
13434 {
13435 PUSHs(&sv_undef);
13436 continue;
13437 }
cristy4a3ce0a2013-08-03 20:06:59 +000013438 if (magick_info->description == (char *) NULL)
13439 PUSHs(&sv_undef);
13440 else
13441 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13442 if (magick_info->module == (char *) NULL)
13443 PUSHs(&sv_undef);
13444 else
13445 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13446 }
13447
13448 PerlException:
13449 InheritPerlException(exception,perl_exception);
13450 exception=DestroyExceptionInfo(exception);
13451 SvREFCNT_dec(perl_exception);
13452 }
13453
13454#
13455###############################################################################
13456# #
13457# #
13458# #
13459# Q u e r y O p t i o n #
13460# #
13461# #
13462# #
13463###############################################################################
13464#
13465#
13466void
13467QueryOption(ref,...)
13468 Image::Magick ref=NO_INIT
13469 ALIAS:
13470 queryoption = 1
13471 PPCODE:
13472 {
13473 char
13474 **options;
13475
13476 ExceptionInfo
13477 *exception;
13478
13479 register ssize_t
13480 i;
13481
13482 ssize_t
13483 j,
13484 option;
13485
13486 SV
13487 *perl_exception;
13488
13489 PERL_UNUSED_VAR(ref);
13490 PERL_UNUSED_VAR(ix);
13491 exception=AcquireExceptionInfo();
13492 perl_exception=newSVpv("",0);
13493 EXTEND(sp,8*items);
13494 for (i=1; i < items; i++)
13495 {
13496 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13497 SvPV(ST(i),na));
13498 options=GetCommandOptions((CommandOption) option);
13499 if (options == (char **) NULL)
13500 PUSHs(&sv_undef);
13501 else
13502 {
13503 for (j=0; options[j] != (char *) NULL; j++)
13504 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13505 options=DestroyStringList(options);
13506 }
13507 }
13508
13509 InheritPerlException(exception,perl_exception);
13510 exception=DestroyExceptionInfo(exception);
13511 SvREFCNT_dec(perl_exception);
13512 }
13513
13514#
13515###############################################################################
13516# #
13517# #
13518# #
13519# R e a d #
13520# #
13521# #
13522# #
13523###############################################################################
13524#
13525#
13526void
13527Read(ref,...)
13528 Image::Magick ref=NO_INIT
13529 ALIAS:
13530 ReadImage = 1
13531 read = 2
13532 readimage = 3
13533 PPCODE:
13534 {
13535 AV
13536 *av;
13537
13538 char
13539 **keep,
13540 **list;
13541
13542 ExceptionInfo
13543 *exception;
13544
13545 HV
13546 *hv;
13547
13548 Image
13549 *image;
13550
13551 int
13552 n;
13553
13554 MagickBooleanType
13555 status;
13556
13557 register char
13558 **p;
13559
13560 register ssize_t
13561 i;
13562
13563 ssize_t
13564 ac,
13565 number_images;
13566
13567 STRLEN
13568 *length;
13569
13570 struct PackageInfo
13571 *info,
13572 *package_info;
13573
13574 SV
13575 *perl_exception, /* Perl variable for storing messages */
13576 *reference,
13577 *rv,
13578 *sv;
13579
13580 PERL_UNUSED_VAR(ref);
13581 PERL_UNUSED_VAR(ix);
13582 exception=AcquireExceptionInfo();
13583 perl_exception=newSVpv("",0);
13584 sv=NULL;
13585 package_info=(struct PackageInfo *) NULL;
13586 number_images=0;
13587 ac=(items < 2) ? 1 : items-1;
13588 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13589 keep=list;
13590 length=(STRLEN *) NULL;
13591 if (list == (char **) NULL)
13592 {
13593 ThrowPerlException(exception,ResourceLimitError,
13594 "MemoryAllocationFailed",PackageName);
13595 goto PerlException;
13596 }
13597 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13598 if (length == (STRLEN *) NULL)
13599 {
13600 ThrowPerlException(exception,ResourceLimitError,
13601 "MemoryAllocationFailed",PackageName);
13602 goto PerlException;
13603 }
13604 if (sv_isobject(ST(0)) == 0)
13605 {
13606 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13607 PackageName);
13608 goto PerlException;
13609 }
13610 reference=SvRV(ST(0));
13611 hv=SvSTASH(reference);
13612 if (SvTYPE(reference) != SVt_PVAV)
13613 {
13614 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13615 PackageName);
13616 goto PerlException;
13617 }
13618 av=(AV *) reference;
13619 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13620 exception);
13621 package_info=ClonePackageInfo(info,exception);
13622 n=1;
13623 if (items <= 1)
13624 *list=(char *) (*package_info->image_info->filename ?
13625 package_info->image_info->filename : "XC:black");
13626 else
13627 for (n=0, i=0; i < ac; i++)
13628 {
13629 list[n]=(char *) SvPV(ST(i+1),length[n]);
13630 if ((items >= 3) && strEQcase(list[n],"blob"))
13631 {
13632 void
13633 *blob;
13634
13635 i++;
13636 blob=(void *) (SvPV(ST(i+1),length[n]));
13637 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13638 }
13639 if ((items >= 3) && strEQcase(list[n],"filename"))
13640 continue;
13641 if ((items >= 3) && strEQcase(list[n],"file"))
13642 {
13643 FILE
13644 *file;
13645
13646 PerlIO
13647 *io_info;
13648
13649 i++;
13650 io_info=IoIFP(sv_2io(ST(i+1)));
13651 if (io_info == (PerlIO *) NULL)
13652 {
13653 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13654 PackageName);
13655 continue;
13656 }
13657 file=PerlIO_findFILE(io_info);
13658 if (file == (FILE *) NULL)
13659 {
13660 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13661 PackageName);
13662 continue;
13663 }
13664 SetImageInfoFile(package_info->image_info,file);
13665 }
13666 if ((items >= 3) && strEQcase(list[n],"magick"))
13667 continue;
13668 n++;
13669 }
13670 list[n]=(char *) NULL;
13671 keep=list;
13672 status=ExpandFilenames(&n,&list);
13673 if (status == MagickFalse)
13674 {
13675 ThrowPerlException(exception,ResourceLimitError,
13676 "MemoryAllocationFailed",PackageName);
13677 goto PerlException;
13678 }
13679 number_images=0;
13680 for (i=0; i < n; i++)
13681 {
13682 if ((package_info->image_info->file == (FILE *) NULL) &&
13683 (package_info->image_info->blob == (void *) NULL))
13684 image=ReadImages(package_info->image_info,list[i],exception);
13685 else
13686 {
13687 image=ReadImages(package_info->image_info,
13688 package_info->image_info->filename,exception);
13689 if (image != (Image *) NULL)
13690 DisassociateImageStream(image);
13691 }
13692 if (image == (Image *) NULL)
13693 break;
13694 for ( ; image; image=image->next)
13695 {
13696 AddImageToRegistry(sv,image);
13697 rv=newRV(sv);
13698 av_push(av,sv_bless(rv,hv));
13699 SvREFCNT_dec(sv);
13700 number_images++;
13701 }
13702 }
13703 /*
13704 Free resources.
13705 */
13706 for (i=0; i < n; i++)
13707 if (list[i] != (char *) NULL)
13708 for (p=keep; list[i] != *p++; )
13709 if (*p == (char *) NULL)
13710 {
13711 list[i]=(char *) RelinquishMagickMemory(list[i]);
13712 break;
13713 }
13714
13715 PerlException:
13716 if (package_info != (struct PackageInfo *) NULL)
13717 DestroyPackageInfo(package_info);
13718 if (list && (list != keep))
13719 list=(char **) RelinquishMagickMemory(list);
13720 if (keep)
13721 keep=(char **) RelinquishMagickMemory(keep);
13722 if (length)
13723 length=(STRLEN *) RelinquishMagickMemory(length);
13724 InheritPerlException(exception,perl_exception);
13725 exception=DestroyExceptionInfo(exception);
13726 sv_setiv(perl_exception,(IV) number_images);
13727 SvPOK_on(perl_exception);
13728 ST(0)=sv_2mortal(perl_exception);
13729 XSRETURN(1);
13730 }
13731
13732#
13733###############################################################################
13734# #
13735# #
13736# #
13737# R e m o t e #
13738# #
13739# #
13740# #
13741###############################################################################
13742#
13743#
13744void
13745Remote(ref,...)
13746 Image::Magick ref=NO_INIT
13747 ALIAS:
13748 RemoteCommand = 1
13749 remote = 2
13750 remoteCommand = 3
13751 PPCODE:
13752 {
13753 AV
13754 *av;
13755
13756 ExceptionInfo
13757 *exception;
13758
13759 register ssize_t
13760 i;
13761
13762 SV
13763 *perl_exception,
13764 *reference;
13765
13766 struct PackageInfo
13767 *info;
13768
13769 PERL_UNUSED_VAR(ref);
13770 PERL_UNUSED_VAR(ix);
13771 exception=AcquireExceptionInfo();
13772 perl_exception=newSVpv("",0);
13773 reference=SvRV(ST(0));
13774 av=(AV *) reference;
13775 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13776 exception);
13777 for (i=1; i < items; i++)
13778 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13779 SvPV(ST(i),na),exception);
13780 InheritPerlException(exception,perl_exception);
13781 exception=DestroyExceptionInfo(exception);
13782 SvREFCNT_dec(perl_exception); /* throw away all errors */
13783 }
13784
13785#
13786###############################################################################
13787# #
13788# #
13789# #
13790# S e t #
13791# #
13792# #
13793# #
13794###############################################################################
13795#
13796#
13797void
13798Set(ref,...)
13799 Image::Magick ref=NO_INIT
13800 ALIAS:
13801 SetAttributes = 1
13802 SetAttribute = 2
13803 set = 3
13804 setattributes = 4
13805 setattribute = 5
13806 PPCODE:
13807 {
13808 ExceptionInfo
13809 *exception;
13810
13811 Image
13812 *image;
13813
13814 register ssize_t
13815 i;
13816
13817 struct PackageInfo
13818 *info;
13819
13820 SV
13821 *perl_exception,
13822 *reference; /* reference is the SV* of ref=SvIV(reference) */
13823
13824 PERL_UNUSED_VAR(ref);
13825 PERL_UNUSED_VAR(ix);
13826 exception=AcquireExceptionInfo();
13827 perl_exception=newSVpv("",0);
13828 if (sv_isobject(ST(0)) == 0)
13829 {
13830 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13831 PackageName);
13832 goto PerlException;
13833 }
13834 reference=SvRV(ST(0));
13835 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13836 if (items == 2)
13837 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13838 else
13839 for (i=2; i < items; i+=2)
13840 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13841
13842 PerlException:
13843 InheritPerlException(exception,perl_exception);
13844 exception=DestroyExceptionInfo(exception);
13845 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13846 SvPOK_on(perl_exception);
13847 ST(0)=sv_2mortal(perl_exception);
13848 XSRETURN(1);
13849 }
13850
13851#
13852###############################################################################
13853# #
13854# #
13855# #
13856# S e t P i x e l #
13857# #
13858# #
13859# #
13860###############################################################################
13861#
13862#
13863void
13864SetPixel(ref,...)
13865 Image::Magick ref=NO_INIT
13866 ALIAS:
13867 setpixel = 1
13868 setPixel = 2
13869 PPCODE:
13870 {
13871 AV
13872 *av;
13873
13874 char
13875 *attribute;
13876
13877 ChannelType
13878 channel,
13879 channel_mask;
13880
13881 ExceptionInfo
13882 *exception;
13883
13884 Image
13885 *image;
13886
13887 MagickBooleanType
13888 normalize;
13889
13890 RectangleInfo
13891 region;
13892
13893 register ssize_t
13894 i;
13895
13896 register Quantum
13897 *q;
13898
13899 ssize_t
13900 option;
13901
13902 struct PackageInfo
13903 *info;
13904
13905 SV
13906 *perl_exception,
13907 *reference; /* reference is the SV* of ref=SvIV(reference) */
13908
13909 PERL_UNUSED_VAR(ref);
13910 PERL_UNUSED_VAR(ix);
13911 exception=AcquireExceptionInfo();
13912 perl_exception=newSVpv("",0);
13913 reference=SvRV(ST(0));
13914 av=(AV *) reference;
13915 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13916 exception);
13917 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13918 if (image == (Image *) NULL)
13919 {
13920 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13921 PackageName);
13922 goto PerlException;
13923 }
13924 av=(AV *) NULL;
13925 normalize=MagickTrue;
13926 region.x=0;
13927 region.y=0;
13928 region.width=image->columns;
13929 region.height=1;
13930 if (items == 1)
13931 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
13932 channel=DefaultChannels;
13933 for (i=2; i < items; i+=2)
13934 {
13935 attribute=(char *) SvPV(ST(i-1),na);
13936 switch (*attribute)
13937 {
13938 case 'C':
13939 case 'c':
13940 {
13941 if (LocaleCompare(attribute,"channel") == 0)
13942 {
13943 ssize_t
13944 option;
13945
13946 option=ParseChannelOption(SvPV(ST(i),na));
13947 if (option < 0)
13948 {
13949 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13950 SvPV(ST(i),na));
13951 return;
13952 }
13953 channel=(ChannelType) option;
13954 break;
13955 }
13956 if (LocaleCompare(attribute,"color") == 0)
13957 {
13958 if (SvTYPE(ST(i)) != SVt_RV)
13959 {
13960 char
cristy151b66d2015-04-15 10:50:31 +000013961 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013962
cristy151b66d2015-04-15 10:50:31 +000013963 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013964 "invalid %.60s value",attribute);
13965 ThrowPerlException(exception,OptionError,message,
13966 SvPV(ST(i),na));
13967 }
13968 av=(AV *) SvRV(ST(i));
13969 break;
13970 }
13971 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13972 attribute);
13973 break;
13974 }
13975 case 'g':
13976 case 'G':
13977 {
13978 if (LocaleCompare(attribute,"geometry") == 0)
13979 {
13980 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
13981 break;
13982 }
13983 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13984 attribute);
13985 break;
13986 }
13987 case 'N':
13988 case 'n':
13989 {
13990 if (LocaleCompare(attribute,"normalize") == 0)
13991 {
13992 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13993 SvPV(ST(i),na));
13994 if (option < 0)
13995 {
13996 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13997 SvPV(ST(i),na));
13998 break;
13999 }
14000 normalize=option != 0 ? MagickTrue : MagickFalse;
14001 break;
14002 }
14003 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14004 attribute);
14005 break;
14006 }
14007 case 'x':
14008 case 'X':
14009 {
14010 if (LocaleCompare(attribute,"x") == 0)
14011 {
14012 region.x=SvIV(ST(i));
14013 break;
14014 }
14015 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14016 attribute);
14017 break;
14018 }
14019 case 'y':
14020 case 'Y':
14021 {
14022 if (LocaleCompare(attribute,"y") == 0)
14023 {
14024 region.y=SvIV(ST(i));
14025 break;
14026 }
14027 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14028 attribute);
14029 break;
14030 }
14031 default:
14032 {
14033 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14034 attribute);
14035 break;
14036 }
14037 }
14038 }
14039 (void) SetImageStorageClass(image,DirectClass,exception);
14040 channel_mask=SetImageChannelMask(image,channel);
14041 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14042 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14043 (SvTYPE(av) != SVt_PVAV))
14044 PUSHs(&sv_undef);
14045 else
14046 {
14047 double
14048 scale;
14049
14050 register ssize_t
14051 i;
14052
14053 i=0;
14054 scale=1.0;
14055 if (normalize != MagickFalse)
14056 scale=QuantumRange;
14057 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14058 (i <= av_len(av)))
14059 {
14060 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14061 av_fetch(av,i,0)))),q);
14062 i++;
14063 }
14064 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14065 (i <= av_len(av)))
14066 {
14067 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14068 av_fetch(av,i,0)))),q);
14069 i++;
14070 }
14071 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14072 (i <= av_len(av)))
14073 {
14074 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14075 av_fetch(av,i,0)))),q);
14076 i++;
14077 }
14078 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14079 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14080 {
14081 SetPixelBlack(image,ClampToQuantum(scale*
14082 SvNV(*(av_fetch(av,i,0)))),q);
14083 i++;
14084 }
14085 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14086 (i <= av_len(av)))
14087 {
14088 SetPixelAlpha(image,ClampToQuantum(scale*
14089 SvNV(*(av_fetch(av,i,0)))),q);
14090 i++;
14091 }
14092 (void) SyncAuthenticPixels(image,exception);
14093 }
14094 (void) SetImageChannelMask(image,channel_mask);
14095
14096 PerlException:
14097 InheritPerlException(exception,perl_exception);
14098 exception=DestroyExceptionInfo(exception);
14099 SvREFCNT_dec(perl_exception);
14100 }
14101
14102#
14103###############################################################################
14104# #
14105# #
14106# #
14107# S m u s h #
14108# #
14109# #
14110# #
14111###############################################################################
14112#
14113#
14114void
14115Smush(ref,...)
14116 Image::Magick ref=NO_INIT
14117 ALIAS:
14118 SmushImage = 1
14119 smush = 2
14120 smushimage = 3
14121 PPCODE:
14122 {
14123 AV
14124 *av;
14125
14126 char
14127 *attribute;
14128
14129 ExceptionInfo
14130 *exception;
14131
14132 HV
14133 *hv;
14134
14135 Image
14136 *image;
14137
14138 register ssize_t
14139 i;
14140
14141 ssize_t
14142 offset,
14143 stack;
14144
14145 struct PackageInfo
14146 *info;
14147
14148 SV
14149 *av_reference,
14150 *perl_exception,
14151 *reference,
14152 *rv,
14153 *sv;
14154
14155 PERL_UNUSED_VAR(ref);
14156 PERL_UNUSED_VAR(ix);
14157 exception=AcquireExceptionInfo();
14158 perl_exception=newSVpv("",0);
14159 sv=NULL;
14160 attribute=NULL;
14161 av=NULL;
14162 if (sv_isobject(ST(0)) == 0)
14163 {
14164 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14165 PackageName);
14166 goto PerlException;
14167 }
14168 reference=SvRV(ST(0));
14169 hv=SvSTASH(reference);
14170 av=newAV();
14171 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14172 SvREFCNT_dec(av);
14173 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14174 if (image == (Image *) NULL)
14175 {
14176 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14177 PackageName);
14178 goto PerlException;
14179 }
14180 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14181 /*
14182 Get options.
14183 */
14184 offset=0;
14185 stack=MagickTrue;
14186 for (i=2; i < items; i+=2)
14187 {
14188 attribute=(char *) SvPV(ST(i-1),na);
14189 switch (*attribute)
14190 {
14191 case 'O':
14192 case 'o':
14193 {
14194 if (LocaleCompare(attribute,"offset") == 0)
14195 {
14196 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14197 break;
14198 }
14199 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14200 attribute);
14201 break;
14202 }
14203 case 'S':
14204 case 's':
14205 {
14206 if (LocaleCompare(attribute,"stack") == 0)
14207 {
14208 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14209 SvPV(ST(i),na));
14210 if (stack < 0)
14211 {
14212 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14213 SvPV(ST(i),na));
14214 return;
14215 }
14216 break;
14217 }
14218 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14219 attribute);
14220 break;
14221 }
14222 default:
14223 {
14224 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14225 attribute);
14226 break;
14227 }
14228 }
14229 }
14230 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14231 exception);
14232 if (image == (Image *) NULL)
14233 goto PerlException;
14234 for ( ; image; image=image->next)
14235 {
14236 AddImageToRegistry(sv,image);
14237 rv=newRV(sv);
14238 av_push(av,sv_bless(rv,hv));
14239 SvREFCNT_dec(sv);
14240 }
14241 exception=DestroyExceptionInfo(exception);
14242 ST(0)=av_reference;
14243 SvREFCNT_dec(perl_exception);
14244 XSRETURN(1);
14245
14246 PerlException:
14247 InheritPerlException(exception,perl_exception);
14248 exception=DestroyExceptionInfo(exception);
14249 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14250 SvPOK_on(perl_exception);
14251 ST(0)=sv_2mortal(perl_exception);
14252 XSRETURN(1);
14253 }
14254
14255#
14256###############################################################################
14257# #
14258# #
14259# #
14260# S t a t i s t i c s #
14261# #
14262# #
14263# #
14264###############################################################################
14265#
14266#
14267void
14268Statistics(ref,...)
14269 Image::Magick ref=NO_INIT
14270 ALIAS:
14271 StatisticsImage = 1
14272 statistics = 2
14273 statisticsimage = 3
14274 PPCODE:
14275 {
14276#define ChannelStatistics(channel) \
14277{ \
cristy151b66d2015-04-15 10:50:31 +000014278 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014279 (double) channel_statistics[channel].depth); \
14280 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014281 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014282 channel_statistics[channel].minima/scale); \
14283 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014284 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014285 channel_statistics[channel].maxima/scale); \
14286 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014287 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014288 channel_statistics[channel].mean/scale); \
14289 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014290 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014291 channel_statistics[channel].standard_deviation/scale); \
14292 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014293 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014294 channel_statistics[channel].kurtosis); \
14295 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014296 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014297 channel_statistics[channel].skewness); \
14298 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014299 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy275bdd92014-11-08 23:45:03 +000014300 channel_statistics[channel].entropy); \
14301 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014302}
14303
14304 AV
14305 *av;
14306
14307 char
cristy151b66d2015-04-15 10:50:31 +000014308 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014309
14310 ChannelStatistics
14311 *channel_statistics;
14312
14313 double
14314 scale;
14315
14316 ExceptionInfo
14317 *exception;
14318
14319 Image
14320 *image;
14321
14322 ssize_t
14323 count;
14324
14325 struct PackageInfo
14326 *info;
14327
14328 SV
14329 *perl_exception,
14330 *reference;
14331
14332 PERL_UNUSED_VAR(ref);
14333 PERL_UNUSED_VAR(ix);
14334 exception=AcquireExceptionInfo();
14335 perl_exception=newSVpv("",0);
14336 av=NULL;
14337 if (sv_isobject(ST(0)) == 0)
14338 {
14339 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14340 PackageName);
14341 goto PerlException;
14342 }
14343 reference=SvRV(ST(0));
14344 av=newAV();
14345 SvREFCNT_dec(av);
14346 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14347 if (image == (Image *) NULL)
14348 {
14349 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14350 PackageName);
14351 goto PerlException;
14352 }
cristy4a3ce0a2013-08-03 20:06:59 +000014353 count=0;
14354 for ( ; image; image=image->next)
14355 {
14356 channel_statistics=GetImageStatistics(image,exception);
14357 if (channel_statistics == (ChannelStatistics *) NULL)
14358 continue;
14359 count++;
14360 EXTEND(sp,35*count);
14361 scale=(double) QuantumRange;
14362 ChannelStatistics(RedChannel);
14363 ChannelStatistics(GreenChannel);
14364 ChannelStatistics(BlueChannel);
14365 if (image->colorspace == CMYKColorspace)
14366 ChannelStatistics(BlackChannel);
cristy17f11b02014-12-20 19:37:04 +000014367 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000014368 ChannelStatistics(AlphaChannel);
14369 channel_statistics=(ChannelStatistics *)
14370 RelinquishMagickMemory(channel_statistics);
14371 }
14372
14373 PerlException:
14374 InheritPerlException(exception,perl_exception);
14375 exception=DestroyExceptionInfo(exception);
14376 SvREFCNT_dec(perl_exception);
14377 }
14378
14379#
14380###############################################################################
14381# #
14382# #
14383# #
14384# S y n c A u t h e n t i c P i x e l s #
14385# #
14386# #
14387# #
14388###############################################################################
14389#
14390#
14391void
14392SyncAuthenticPixels(ref,...)
14393 Image::Magick ref = NO_INIT
14394 ALIAS:
14395 Syncauthenticpixels = 1
14396 SyncImagePixels = 2
14397 syncimagepixels = 3
14398 CODE:
14399 {
14400 ExceptionInfo
14401 *exception;
14402
14403 Image
14404 *image;
14405
14406 MagickBooleanType
14407 status;
14408
14409 struct PackageInfo
14410 *info;
14411
14412 SV
14413 *perl_exception,
14414 *reference;
14415
14416 PERL_UNUSED_VAR(ref);
14417 PERL_UNUSED_VAR(ix);
14418 exception=AcquireExceptionInfo();
14419 perl_exception=newSVpv("",0);
14420 if (sv_isobject(ST(0)) == 0)
14421 {
14422 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14423 PackageName);
14424 goto PerlException;
14425 }
14426
14427 reference=SvRV(ST(0));
14428 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14429 if (image == (Image *) NULL)
14430 {
14431 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14432 PackageName);
14433 goto PerlException;
14434 }
14435
14436 status=SyncAuthenticPixels(image,exception);
14437 if (status != MagickFalse)
14438 return;
14439
14440 PerlException:
14441 InheritPerlException(exception,perl_exception);
14442 exception=DestroyExceptionInfo(exception);
14443 SvREFCNT_dec(perl_exception); /* throw away all errors */
14444 }
14445
14446#
14447###############################################################################
14448# #
14449# #
14450# #
14451# T r a n s f o r m #
14452# #
14453# #
14454# #
14455###############################################################################
14456#
14457#
14458void
14459Transform(ref,...)
14460 Image::Magick ref=NO_INIT
14461 ALIAS:
14462 TransformImage = 1
14463 transform = 2
14464 transformimage = 3
14465 PPCODE:
14466 {
14467 AV
14468 *av;
14469
14470 char
14471 *attribute,
14472 *crop_geometry,
14473 *geometry;
14474
14475 ExceptionInfo
14476 *exception;
14477
14478 HV
14479 *hv;
14480
14481 Image
14482 *clone,
14483 *image;
14484
14485 register ssize_t
14486 i;
14487
14488 struct PackageInfo
14489 *info;
14490
14491 SV
14492 *av_reference,
14493 *perl_exception,
14494 *reference,
14495 *rv,
14496 *sv;
14497
14498 PERL_UNUSED_VAR(ref);
14499 PERL_UNUSED_VAR(ix);
14500 exception=AcquireExceptionInfo();
14501 perl_exception=newSVpv("",0);
14502 sv=NULL;
14503 av=NULL;
14504 attribute=NULL;
14505 if (sv_isobject(ST(0)) == 0)
14506 {
14507 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14508 PackageName);
14509 goto PerlException;
14510 }
14511 reference=SvRV(ST(0));
14512 hv=SvSTASH(reference);
14513 av=newAV();
14514 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14515 SvREFCNT_dec(av);
14516 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14517 if (image == (Image *) NULL)
14518 {
14519 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14520 PackageName);
14521 goto PerlException;
14522 }
14523 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14524 /*
14525 Get attribute.
14526 */
14527 crop_geometry=(char *) NULL;
14528 geometry=(char *) NULL;
14529 for (i=2; i < items; i+=2)
14530 {
14531 attribute=(char *) SvPV(ST(i-1),na);
14532 switch (*attribute)
14533 {
14534 case 'c':
14535 case 'C':
14536 {
14537 if (LocaleCompare(attribute,"crop") == 0)
14538 {
14539 crop_geometry=SvPV(ST(i),na);
14540 break;
14541 }
14542 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14543 attribute);
14544 break;
14545 }
14546 case 'g':
14547 case 'G':
14548 {
14549 if (LocaleCompare(attribute,"geometry") == 0)
14550 {
14551 geometry=SvPV(ST(i),na);
14552 break;
14553 }
14554 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14555 attribute);
14556 break;
14557 }
14558 default:
14559 {
14560 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14561 attribute);
14562 break;
14563 }
14564 }
14565 }
14566 for ( ; image; image=image->next)
14567 {
14568 clone=CloneImage(image,0,0,MagickTrue,exception);
14569 if (clone == (Image *) NULL)
14570 goto PerlException;
14571 TransformImage(&clone,crop_geometry,geometry,exception);
14572 for ( ; clone; clone=clone->next)
14573 {
14574 AddImageToRegistry(sv,clone);
14575 rv=newRV(sv);
14576 av_push(av,sv_bless(rv,hv));
14577 SvREFCNT_dec(sv);
14578 }
14579 }
14580 exception=DestroyExceptionInfo(exception);
14581 ST(0)=av_reference;
14582 SvREFCNT_dec(perl_exception); /* can't return warning messages */
14583 XSRETURN(1);
14584
14585 PerlException:
14586 InheritPerlException(exception,perl_exception);
14587 exception=DestroyExceptionInfo(exception);
14588 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14589 SvPOK_on(perl_exception);
14590 ST(0)=sv_2mortal(perl_exception);
14591 XSRETURN(1);
14592 }
14593
14594#
14595###############################################################################
14596# #
14597# #
14598# #
14599# W r i t e #
14600# #
14601# #
14602# #
14603###############################################################################
14604#
14605#
14606void
14607Write(ref,...)
14608 Image::Magick ref=NO_INIT
14609 ALIAS:
14610 WriteImage = 1
14611 write = 2
14612 writeimage = 3
14613 PPCODE:
14614 {
14615 char
cristy151b66d2015-04-15 10:50:31 +000014616 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014617
14618 ExceptionInfo
14619 *exception;
14620
14621 Image
14622 *image,
14623 *next;
14624
14625 register ssize_t
14626 i;
14627
14628 ssize_t
14629 number_images,
14630 scene;
14631
14632 struct PackageInfo
14633 *info,
14634 *package_info;
14635
14636 SV
14637 *perl_exception,
14638 *reference;
14639
14640 PERL_UNUSED_VAR(ref);
14641 PERL_UNUSED_VAR(ix);
14642 exception=AcquireExceptionInfo();
14643 perl_exception=newSVpv("",0);
14644 number_images=0;
14645 package_info=(struct PackageInfo *) NULL;
14646 if (sv_isobject(ST(0)) == 0)
14647 {
14648 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14649 PackageName);
14650 goto PerlException;
14651 }
14652 reference=SvRV(ST(0));
14653 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14654 if (image == (Image *) NULL)
14655 {
14656 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14657 PackageName);
14658 goto PerlException;
14659 }
14660 package_info=ClonePackageInfo(info,exception);
14661 if (items == 2)
14662 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14663 else
14664 if (items > 2)
14665 for (i=2; i < items; i+=2)
14666 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14667 exception);
14668 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014669 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014670 scene=0;
14671 for (next=image; next; next=next->next)
14672 {
cristy151b66d2015-04-15 10:50:31 +000014673 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014674 next->scene=scene++;
14675 }
cristy68bd79a2015-02-25 12:23:36 +000014676 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014677 SetImageInfo(package_info->image_info,(unsigned int)
14678 GetImageListLength(image),exception);
14679 for (next=image; next; next=next->next)
14680 {
14681 (void) WriteImage(package_info->image_info,next,exception);
14682 number_images++;
14683 if (package_info->image_info->adjoin)
14684 break;
14685 }
14686
14687 PerlException:
14688 if (package_info != (struct PackageInfo *) NULL)
14689 DestroyPackageInfo(package_info);
14690 InheritPerlException(exception,perl_exception);
14691 exception=DestroyExceptionInfo(exception);
14692 sv_setiv(perl_exception,(IV) number_images);
14693 SvPOK_on(perl_exception);
14694 ST(0)=sv_2mortal(perl_exception);
14695 XSRETURN(1);
14696 }