blob: b2fb4b5abd537bcc4134a8de69667872f92612a7 [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} } },
534 { "Sans", { {"matrix", ArrayReference} } },
535 { "Color", { {"color", StringReference} } },
536 { "Mode", { {"geometry", StringReference},
537 {"width", IntegerReference},{"height", IntegerReference},
538 {"channel", MagickChannelOptions} } },
539 { "Statistic", { {"geometry", StringReference},
540 {"width", IntegerReference},{"height", IntegerReference},
541 {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
542 { "Perceptible", { {"epsilon", RealReference},
543 {"channel", MagickChannelOptions} } },
544 { "Poly", { {"terms", ArrayReference},
545 {"channel", MagickChannelOptions} } },
546 { "Grayscale", { {"method", MagickNoiseOptions} } },
cristy4ceadb82014-03-29 15:30:43 +0000547 { "CannyEdge", { {"geometry", StringReference},
548 {"radius", RealReference}, {"sigma", RealReference},
cristycfe7bf02014-04-04 15:31:52 +0000549 {"lower-percent", RealReference}, {"upper-percent", RealReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000550 { "HoughLine", { {"geometry", StringReference},
cristy4e215022014-04-19 18:02:35 +0000551 {"width", IntegerReference}, {"height", IntegerReference},
552 {"threshold", IntegerReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000553 { "MeanShift", { {"geometry", StringReference},
554 {"width", IntegerReference}, {"height", IntegerReference},
cristy1309fc32014-04-26 18:48:37 +0000555 {"distance", RealReference} } },
cristy3b207f82014-09-27 14:21:20 +0000556 { "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
557 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
Cristy2ca0e9a2016-01-01 08:36:14 -0500558 { "ConnectedComponents", { {"connectivity", IntegerReference} } },
cristyf3a724a2015-06-25 13:02:53 +0000559 { "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
560 {"width", IntegerReference}, {"height", IntegerReference},
561 {"x", IntegerReference}, {"y", IntegerReference},
562 {"gravity", MagickGravityOptions}, {"offset", StringReference},
563 {"dx", IntegerReference}, {"dy", IntegerReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000564 };
565
566static SplayTreeInfo
567 *magick_registry = (SplayTreeInfo *) NULL;
568
569/*
570 Forward declarations.
571*/
572static Image
573 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
574
575static ssize_t
576 strEQcase(const char *,const char *);
577
578/*
579%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
580% %
581% %
582% %
583% C l o n e P a c k a g e I n f o %
584% %
585% %
586% %
587%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
588%
589% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
590% a new one.
591%
592% The format of the ClonePackageInfo routine is:
593%
594% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
595% exception)
596%
597% A description of each parameter follows:
598%
599% o info: a structure of type info.
600%
601% o exception: Return any errors or warnings in this structure.
602%
603*/
604static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
605 ExceptionInfo *exception)
606{
607 struct PackageInfo
608 *clone_info;
609
610 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
611 if (clone_info == (struct PackageInfo *) NULL)
612 {
613 ThrowPerlException(exception,ResourceLimitError,
614 "UnableToClonePackageInfo",PackageName);
615 return((struct PackageInfo *) NULL);
616 }
617 if (info == (struct PackageInfo *) NULL)
618 {
619 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
620 return(clone_info);
621 }
622 *clone_info=(*info);
623 clone_info->image_info=CloneImageInfo(info->image_info);
624 return(clone_info);
625}
626
627/*
628%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
629% %
630% %
631% %
632% c o n s t a n t %
633% %
634% %
635% %
636%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
637%
638% constant() returns a double value for the specified name.
639%
640% The format of the constant routine is:
641%
642% double constant(char *name,ssize_t sans)
643%
644% A description of each parameter follows:
645%
646% o value: Method constant returns a double value for the specified name.
647%
648% o name: The name of the constant.
649%
650% o sans: This integer value is not used.
651%
652*/
653static double constant(char *name,ssize_t sans)
654{
655 (void) sans;
656 errno=0;
657 switch (*name)
658 {
659 case 'B':
660 {
661 if (strEQ(name,"BlobError"))
662 return(BlobError);
663 if (strEQ(name,"BlobWarning"))
664 return(BlobWarning);
665 break;
666 }
667 case 'C':
668 {
669 if (strEQ(name,"CacheError"))
670 return(CacheError);
671 if (strEQ(name,"CacheWarning"))
672 return(CacheWarning);
673 if (strEQ(name,"CoderError"))
674 return(CoderError);
675 if (strEQ(name,"CoderWarning"))
676 return(CoderWarning);
677 if (strEQ(name,"ConfigureError"))
678 return(ConfigureError);
679 if (strEQ(name,"ConfigureWarning"))
680 return(ConfigureWarning);
681 if (strEQ(name,"CorruptImageError"))
682 return(CorruptImageError);
683 if (strEQ(name,"CorruptImageWarning"))
684 return(CorruptImageWarning);
685 break;
686 }
687 case 'D':
688 {
689 if (strEQ(name,"DelegateError"))
690 return(DelegateError);
691 if (strEQ(name,"DelegateWarning"))
692 return(DelegateWarning);
693 if (strEQ(name,"DrawError"))
694 return(DrawError);
695 if (strEQ(name,"DrawWarning"))
696 return(DrawWarning);
697 break;
698 }
699 case 'E':
700 {
701 if (strEQ(name,"ErrorException"))
702 return(ErrorException);
703 if (strEQ(name,"ExceptionError"))
704 return(CoderError);
705 if (strEQ(name,"ExceptionWarning"))
706 return(CoderWarning);
707 break;
708 }
709 case 'F':
710 {
711 if (strEQ(name,"FatalErrorException"))
712 return(FatalErrorException);
713 if (strEQ(name,"FileOpenError"))
714 return(FileOpenError);
715 if (strEQ(name,"FileOpenWarning"))
716 return(FileOpenWarning);
717 break;
718 }
719 case 'I':
720 {
721 if (strEQ(name,"ImageError"))
722 return(ImageError);
723 if (strEQ(name,"ImageWarning"))
724 return(ImageWarning);
725 break;
726 }
727 case 'M':
728 {
729 if (strEQ(name,"MaxRGB"))
730 return(QuantumRange);
731 if (strEQ(name,"MissingDelegateError"))
732 return(MissingDelegateError);
733 if (strEQ(name,"MissingDelegateWarning"))
734 return(MissingDelegateWarning);
735 if (strEQ(name,"ModuleError"))
736 return(ModuleError);
737 if (strEQ(name,"ModuleWarning"))
738 return(ModuleWarning);
739 break;
740 }
741 case 'O':
742 {
743 if (strEQ(name,"Opaque"))
744 return(OpaqueAlpha);
745 if (strEQ(name,"OptionError"))
746 return(OptionError);
747 if (strEQ(name,"OptionWarning"))
748 return(OptionWarning);
749 break;
750 }
751 case 'Q':
752 {
753 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
754 return(MAGICKCORE_QUANTUM_DEPTH);
755 if (strEQ(name,"QuantumDepth"))
756 return(MAGICKCORE_QUANTUM_DEPTH);
757 if (strEQ(name,"QuantumRange"))
758 return(QuantumRange);
759 break;
760 }
761 case 'R':
762 {
763 if (strEQ(name,"ResourceLimitError"))
764 return(ResourceLimitError);
765 if (strEQ(name,"ResourceLimitWarning"))
766 return(ResourceLimitWarning);
767 if (strEQ(name,"RegistryError"))
768 return(RegistryError);
769 if (strEQ(name,"RegistryWarning"))
770 return(RegistryWarning);
771 break;
772 }
773 case 'S':
774 {
775 if (strEQ(name,"StreamError"))
776 return(StreamError);
777 if (strEQ(name,"StreamWarning"))
778 return(StreamWarning);
779 if (strEQ(name,"Success"))
780 return(0);
781 break;
782 }
783 case 'T':
784 {
785 if (strEQ(name,"Transparent"))
786 return(TransparentAlpha);
787 if (strEQ(name,"TypeError"))
788 return(TypeError);
789 if (strEQ(name,"TypeWarning"))
790 return(TypeWarning);
791 break;
792 }
793 case 'W':
794 {
795 if (strEQ(name,"WarningException"))
796 return(WarningException);
797 break;
798 }
799 case 'X':
800 {
801 if (strEQ(name,"XServerError"))
802 return(XServerError);
803 if (strEQ(name,"XServerWarning"))
804 return(XServerWarning);
805 break;
806 }
807 }
808 errno=EINVAL;
809 return(0);
810}
811
812/*
813%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
814% %
815% %
816% %
817% D e s t r o y P a c k a g e I n f o %
818% %
819% %
820% %
821%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
822%
823% Method DestroyPackageInfo frees a previously created info structure.
824%
825% The format of the DestroyPackageInfo routine is:
826%
827% DestroyPackageInfo(struct PackageInfo *info)
828%
829% A description of each parameter follows:
830%
831% o info: a structure of type info.
832%
833*/
834static void DestroyPackageInfo(struct PackageInfo *info)
835{
836 info->image_info=DestroyImageInfo(info->image_info);
837 info=(struct PackageInfo *) RelinquishMagickMemory(info);
838}
839
840/*
841%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
842% %
843% %
844% %
845% G e t L i s t %
846% %
847% %
848% %
849%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
850%
851% Method GetList is recursively called by SetupList to traverse the
852% Image__Magick reference. If building an reference_vector (see SetupList),
853% *current is the current position in *reference_vector and *last is the final
854% entry in *reference_vector.
855%
856% The format of the GetList routine is:
857%
858% GetList(info)
859%
860% A description of each parameter follows:
861%
862% o info: a structure of type info.
863%
864*/
865static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
866 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
867{
868 Image
869 *image;
870
871 if (reference == (SV *) NULL)
872 return(NULL);
873 switch (SvTYPE(reference))
874 {
875 case SVt_PVAV:
876 {
877 AV
878 *av;
879
880 Image
881 *head,
882 *previous;
883
884 register ssize_t
885 i;
886
887 ssize_t
888 n;
889
890 /*
891 Array of images.
892 */
893 previous=(Image *) NULL;
894 head=(Image *) NULL;
895 av=(AV *) reference;
896 n=av_len(av);
897 for (i=0; i <= n; i++)
898 {
899 SV
900 **rv;
901
902 rv=av_fetch(av,i,0);
903 if (rv && *rv && sv_isobject(*rv))
904 {
905 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
906 exception);
907 if (image == (Image *) NULL)
908 continue;
909 if (image == previous)
910 {
911 image=CloneImage(image,0,0,MagickTrue,exception);
912 if (image == (Image *) NULL)
913 return(NULL);
914 }
915 image->previous=previous;
916 *(previous ? &previous->next : &head)=image;
917 for (previous=image; previous->next; previous=previous->next) ;
918 }
919 }
920 return(head);
921 }
922 case SVt_PVMG:
923 {
924 /*
925 Blessed scalar, one image.
926 */
927 image=INT2PTR(Image *,SvIV(reference));
928 if (image == (Image *) NULL)
929 return(NULL);
930 image->previous=(Image *) NULL;
931 image->next=(Image *) NULL;
932 if (reference_vector)
933 {
934 if (*current == *last)
935 {
936 *last+=256;
937 if (*reference_vector == (SV **) NULL)
938 *reference_vector=(SV **) AcquireQuantumMemory(*last,
939 sizeof(*reference_vector));
940 else
941 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
942 *last,sizeof(*reference_vector));
943 }
944 if (*reference_vector == (SV **) NULL)
945 {
946 ThrowPerlException(exception,ResourceLimitError,
947 "MemoryAllocationFailed",PackageName);
948 return((Image *) NULL);
949 }
950 (*reference_vector)[*current]=reference;
951 (*reference_vector)[++(*current)]=NULL;
952 }
953 return(image);
954 }
955 default:
956 break;
957 }
958 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
959 (double) SvTYPE(reference));
960 return((Image *) NULL);
961}
962
963/*
964%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
965% %
966% %
967% %
968% G e t P a c k a g e I n f o %
969% %
970% %
971% %
972%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
973%
974% Method GetPackageInfo looks up or creates an info structure for the given
975% Image__Magick reference. If it does create a new one, the information in
976% package_info is used to initialize it.
977%
978% The format of the GetPackageInfo routine is:
979%
980% struct PackageInfo *GetPackageInfo(void *reference,
981% struct PackageInfo *package_info,ExceptionInfo *exception)
982%
983% A description of each parameter follows:
984%
985% o info: a structure of type info.
986%
987% o exception: Return any errors or warnings in this structure.
988%
989*/
990static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
991 struct PackageInfo *package_info,ExceptionInfo *exception)
992{
993 char
cristy151b66d2015-04-15 10:50:31 +0000994 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +0000995
996 struct PackageInfo
997 *clone_info;
998
999 SV
1000 *sv;
1001
cristy151b66d2015-04-15 10:50:31 +00001002 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00001003 PackageName,XS_VERSION,reference);
1004 sv=perl_get_sv(message,(TRUE | 0x02));
1005 if (sv == (SV *) NULL)
1006 {
1007 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1008 message);
1009 return(package_info);
1010 }
1011 if (SvREFCNT(sv) == 0)
1012 (void) SvREFCNT_inc(sv);
1013 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1014 return(clone_info);
1015 clone_info=ClonePackageInfo(package_info,exception);
1016 sv_setiv(sv,PTR2IV(clone_info));
1017 return(clone_info);
1018}
1019
1020/*
1021%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1022% %
1023% %
1024% %
1025% S e t A t t r i b u t e %
1026% %
1027% %
1028% %
1029%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1030%
1031% SetAttribute() sets the attribute to the value in sval. This can change
1032% either or both of image or info.
1033%
1034% The format of the SetAttribute routine is:
1035%
1036% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1037% SV *sval,ExceptionInfo *exception)
1038%
1039% A description of each parameter follows:
1040%
1041% o list: a list of strings.
1042%
1043% o string: a character string.
1044%
1045*/
1046
1047static double SiPrefixToDoubleInterval(const char *string,const double interval)
1048{
1049 char
1050 *q;
1051
1052 double
1053 value;
1054
1055 value=InterpretSiPrefixValue(string,&q);
1056 if (*q == '%')
1057 value*=interval/100.0;
1058 return(value);
1059}
1060
1061static inline double StringToDouble(const char *string,char **sentinal)
1062{
1063 return(InterpretLocaleValue(string,sentinal));
1064}
1065
1066static double StringToDoubleInterval(const char *string,const double interval)
1067{
1068 char
1069 *q;
1070
1071 double
1072 value;
1073
1074 value=InterpretLocaleValue(string,&q);
1075 if (*q == '%')
1076 value*=interval/100.0;
1077 return(value);
1078}
1079
1080static inline ssize_t StringToLong(const char *value)
1081{
1082 return(strtol(value,(char **) NULL,10));
1083}
1084
1085static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1086 const char *attribute,SV *sval,ExceptionInfo *exception)
1087{
1088 GeometryInfo
1089 geometry_info;
1090
1091 long
1092 x,
1093 y;
1094
1095 PixelInfo
1096 pixel;
1097
1098 MagickStatusType
1099 flags;
1100
1101 PixelInfo
1102 *color,
1103 target_color;
1104
1105 ssize_t
1106 sp;
1107
1108 switch (*attribute)
1109 {
1110 case 'A':
1111 case 'a':
1112 {
1113 if (LocaleCompare(attribute,"adjoin") == 0)
1114 {
1115 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1116 SvPV(sval,na)) : SvIV(sval);
1117 if (sp < 0)
1118 {
1119 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1120 SvPV(sval,na));
1121 break;
1122 }
1123 if (info)
1124 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1125 break;
1126 }
1127 if (LocaleCompare(attribute,"alpha") == 0)
1128 {
1129 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1130 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1131 if (sp < 0)
1132 {
1133 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1134 SvPV(sval,na));
1135 break;
1136 }
1137 for ( ; image; image=image->next)
1138 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1139 exception);
1140 break;
1141 }
1142 if (LocaleCompare(attribute,"antialias") == 0)
1143 {
1144 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1145 SvPV(sval,na)) : SvIV(sval);
1146 if (sp < 0)
1147 {
1148 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1149 SvPV(sval,na));
1150 break;
1151 }
1152 if (info)
1153 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1154 break;
1155 }
1156 if (LocaleCompare(attribute,"area-limit") == 0)
1157 {
1158 MagickSizeType
1159 limit;
1160
1161 limit=MagickResourceInfinity;
1162 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1163 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1164 100.0);
1165 (void) SetMagickResourceLimit(AreaResource,limit);
1166 break;
1167 }
1168 if (LocaleCompare(attribute,"attenuate") == 0)
1169 {
1170 if (info)
1171 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1172 break;
1173 }
1174 if (LocaleCompare(attribute,"authenticate") == 0)
1175 {
1176 if (info)
1177 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1178 break;
1179 }
1180 if (info)
1181 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1182 for ( ; image; image=image->next)
1183 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1184 break;
1185 }
1186 case 'B':
1187 case 'b':
1188 {
1189 if (LocaleCompare(attribute,"background") == 0)
1190 {
1191 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1192 exception);
1193 if (info)
1194 info->image_info->background_color=target_color;
1195 for ( ; image; image=image->next)
1196 image->background_color=target_color;
1197 break;
1198 }
1199 if (LocaleCompare(attribute,"blue-primary") == 0)
1200 {
1201 for ( ; image; image=image->next)
1202 {
1203 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1204 image->chromaticity.blue_primary.x=geometry_info.rho;
1205 image->chromaticity.blue_primary.y=geometry_info.sigma;
1206 if ((flags & SigmaValue) == 0)
1207 image->chromaticity.blue_primary.y=
1208 image->chromaticity.blue_primary.x;
1209 }
1210 break;
1211 }
1212 if (LocaleCompare(attribute,"bordercolor") == 0)
1213 {
1214 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1215 exception);
1216 if (info)
1217 info->image_info->border_color=target_color;
1218 for ( ; image; image=image->next)
1219 image->border_color=target_color;
1220 break;
1221 }
1222 if (info)
1223 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1224 for ( ; image; image=image->next)
1225 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1226 break;
1227 }
1228 case 'C':
1229 case 'c':
1230 {
1231 if (LocaleCompare(attribute,"cache-threshold") == 0)
1232 {
1233 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1234 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1235 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1236 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1237 break;
1238 }
1239 if (LocaleCompare(attribute,"clip-mask") == 0)
1240 {
1241 Image
1242 *clip_mask;
1243
1244 clip_mask=(Image *) NULL;
1245 if (SvPOK(sval))
1246 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1247 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001248 SetImageMask(image,ReadPixelMask,clip_mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001249 break;
1250 }
1251 if (LocaleNCompare(attribute,"colormap",8) == 0)
1252 {
1253 for ( ; image; image=image->next)
1254 {
1255 int
1256 items;
1257
1258 long
1259 i;
1260
1261 if (image->storage_class == DirectClass)
1262 continue;
1263 i=0;
1264 items=sscanf(attribute,"%*[^[][%ld",&i);
1265 (void) items;
1266 if (i > (ssize_t) image->colors)
1267 i%=image->colors;
1268 if ((strchr(SvPV(sval,na),',') == 0) ||
1269 (strchr(SvPV(sval,na),')') != 0))
1270 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1271 image->colormap+i,exception);
1272 else
1273 {
1274 color=image->colormap+i;
1275 pixel.red=color->red;
1276 pixel.green=color->green;
1277 pixel.blue=color->blue;
1278 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1279 pixel.red=geometry_info.rho;
1280 pixel.green=geometry_info.sigma;
1281 pixel.blue=geometry_info.xi;
1282 color->red=ClampToQuantum(pixel.red);
1283 color->green=ClampToQuantum(pixel.green);
1284 color->blue=ClampToQuantum(pixel.blue);
1285 }
1286 }
1287 break;
1288 }
1289 if (LocaleCompare(attribute,"colorspace") == 0)
1290 {
1291 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1292 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1293 if (sp < 0)
1294 {
1295 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1296 SvPV(sval,na));
1297 break;
1298 }
1299 for ( ; image; image=image->next)
1300 (void) TransformImageColorspace(image,(ColorspaceType) sp,
1301 exception);
1302 break;
1303 }
1304 if (LocaleCompare(attribute,"comment") == 0)
1305 {
1306 for ( ; image; image=image->next)
1307 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1308 info ? info->image_info : (ImageInfo *) NULL,image,
1309 SvPV(sval,na),exception),exception);
1310 break;
1311 }
1312 if (LocaleCompare(attribute,"compression") == 0)
1313 {
1314 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1315 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1316 if (sp < 0)
1317 {
1318 ThrowPerlException(exception,OptionError,
1319 "UnrecognizedImageCompression",SvPV(sval,na));
1320 break;
1321 }
1322 if (info)
1323 info->image_info->compression=(CompressionType) sp;
1324 for ( ; image; image=image->next)
1325 image->compression=(CompressionType) sp;
1326 break;
1327 }
1328 if (info)
1329 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1330 for ( ; image; image=image->next)
1331 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1332 break;
1333 }
1334 case 'D':
1335 case 'd':
1336 {
1337 if (LocaleCompare(attribute,"debug") == 0)
1338 {
1339 SetLogEventMask(SvPV(sval,na));
1340 break;
1341 }
1342 if (LocaleCompare(attribute,"delay") == 0)
1343 {
1344 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1345 for ( ; image; image=image->next)
1346 {
1347 image->delay=(size_t) floor(geometry_info.rho+0.5);
1348 if ((flags & SigmaValue) != 0)
1349 image->ticks_per_second=(ssize_t)
1350 floor(geometry_info.sigma+0.5);
1351 }
1352 break;
1353 }
1354 if (LocaleCompare(attribute,"disk-limit") == 0)
1355 {
1356 MagickSizeType
1357 limit;
1358
1359 limit=MagickResourceInfinity;
1360 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1361 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1362 100.0);
1363 (void) SetMagickResourceLimit(DiskResource,limit);
1364 break;
1365 }
1366 if (LocaleCompare(attribute,"density") == 0)
1367 {
1368 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1369 {
1370 ThrowPerlException(exception,OptionError,"MissingGeometry",
1371 SvPV(sval,na));
1372 break;
1373 }
1374 if (info)
1375 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1376 for ( ; image; image=image->next)
1377 {
1378 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1379 image->resolution.x=geometry_info.rho;
1380 image->resolution.y=geometry_info.sigma;
1381 if ((flags & SigmaValue) == 0)
1382 image->resolution.y=image->resolution.x;
1383 }
1384 break;
1385 }
1386 if (LocaleCompare(attribute,"depth") == 0)
1387 {
1388 if (info)
1389 info->image_info->depth=SvIV(sval);
1390 for ( ; image; image=image->next)
1391 (void) SetImageDepth(image,SvIV(sval),exception);
1392 break;
1393 }
1394 if (LocaleCompare(attribute,"dispose") == 0)
1395 {
1396 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1397 SvPV(sval,na)) : SvIV(sval);
1398 if (sp < 0)
1399 {
1400 ThrowPerlException(exception,OptionError,
1401 "UnrecognizedDisposeMethod",SvPV(sval,na));
1402 break;
1403 }
1404 for ( ; image; image=image->next)
1405 image->dispose=(DisposeType) sp;
1406 break;
1407 }
1408 if (LocaleCompare(attribute,"dither") == 0)
1409 {
1410 if (info)
1411 {
1412 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1413 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1414 if (sp < 0)
1415 {
1416 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1417 SvPV(sval,na));
1418 break;
1419 }
1420 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1421 }
1422 break;
1423 }
1424 if (LocaleCompare(attribute,"display") == 0)
1425 {
1426 display:
1427 if (info)
1428 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1429 break;
1430 }
1431 if (info)
1432 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1433 for ( ; image; image=image->next)
1434 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1435 break;
1436 }
1437 case 'E':
1438 case 'e':
1439 {
1440 if (LocaleCompare(attribute,"endian") == 0)
1441 {
1442 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1443 SvPV(sval,na)) : SvIV(sval);
1444 if (sp < 0)
1445 {
1446 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1447 SvPV(sval,na));
1448 break;
1449 }
1450 if (info)
1451 info->image_info->endian=(EndianType) sp;
1452 for ( ; image; image=image->next)
1453 image->endian=(EndianType) sp;
1454 break;
1455 }
1456 if (LocaleCompare(attribute,"extract") == 0)
1457 {
1458 /*
1459 Set image extract geometry.
1460 */
1461 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1462 break;
1463 }
1464 if (info)
1465 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1466 for ( ; image; image=image->next)
1467 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1468 break;
1469 }
1470 case 'F':
1471 case 'f':
1472 {
1473 if (LocaleCompare(attribute,"filename") == 0)
1474 {
1475 if (info)
1476 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001477 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001478 for ( ; image; image=image->next)
1479 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001480 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001481 break;
1482 }
1483 if (LocaleCompare(attribute,"file") == 0)
1484 {
1485 FILE
1486 *file;
1487
1488 PerlIO
1489 *io_info;
1490
1491 if (info == (struct PackageInfo *) NULL)
1492 break;
1493 io_info=IoIFP(sv_2io(sval));
1494 if (io_info == (PerlIO *) NULL)
1495 {
1496 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1497 PackageName);
1498 break;
1499 }
1500 file=PerlIO_findFILE(io_info);
1501 if (file == (FILE *) NULL)
1502 {
1503 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1504 PackageName);
1505 break;
1506 }
1507 SetImageInfoFile(info->image_info,file);
1508 break;
1509 }
1510 if (LocaleCompare(attribute,"fill") == 0)
1511 {
1512 if (info)
1513 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1514 break;
1515 }
1516 if (LocaleCompare(attribute,"font") == 0)
1517 {
1518 if (info)
1519 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1520 break;
1521 }
1522 if (LocaleCompare(attribute,"foreground") == 0)
1523 break;
1524 if (LocaleCompare(attribute,"fuzz") == 0)
1525 {
1526 if (info)
1527 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1528 QuantumRange+1.0);
1529 for ( ; image; image=image->next)
1530 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1531 QuantumRange+1.0);
1532 break;
1533 }
1534 if (info)
1535 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1536 for ( ; image; image=image->next)
1537 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1538 break;
1539 }
1540 case 'G':
1541 case 'g':
1542 {
1543 if (LocaleCompare(attribute,"gamma") == 0)
1544 {
1545 for ( ; image; image=image->next)
1546 image->gamma=SvNV(sval);
1547 break;
1548 }
1549 if (LocaleCompare(attribute,"gravity") == 0)
1550 {
1551 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1552 SvPV(sval,na)) : SvIV(sval);
1553 if (sp < 0)
1554 {
1555 ThrowPerlException(exception,OptionError,
1556 "UnrecognizedGravityType",SvPV(sval,na));
1557 break;
1558 }
1559 if (info)
1560 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1561 for ( ; image; image=image->next)
1562 image->gravity=(GravityType) sp;
1563 break;
1564 }
1565 if (LocaleCompare(attribute,"green-primary") == 0)
1566 {
1567 for ( ; image; image=image->next)
1568 {
1569 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1570 image->chromaticity.green_primary.x=geometry_info.rho;
1571 image->chromaticity.green_primary.y=geometry_info.sigma;
1572 if ((flags & SigmaValue) == 0)
1573 image->chromaticity.green_primary.y=
1574 image->chromaticity.green_primary.x;
1575 }
1576 break;
1577 }
1578 if (info)
1579 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1580 for ( ; image; image=image->next)
1581 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1582 break;
1583 }
1584 case 'I':
1585 case 'i':
1586 {
1587 if (LocaleNCompare(attribute,"index",5) == 0)
1588 {
1589 int
1590 items;
1591
1592 long
1593 index;
1594
1595 register Quantum
1596 *q;
1597
1598 CacheView
1599 *image_view;
1600
1601 for ( ; image; image=image->next)
1602 {
1603 if (image->storage_class != PseudoClass)
1604 continue;
1605 x=0;
1606 y=0;
1607 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1608 (void) items;
1609 image_view=AcquireAuthenticCacheView(image,exception);
1610 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1611 if (q != (Quantum *) NULL)
1612 {
1613 items=sscanf(SvPV(sval,na),"%ld",&index);
1614 if ((index >= 0) && (index < (ssize_t) image->colors))
1615 SetPixelIndex(image,index,q);
1616 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1617 }
1618 image_view=DestroyCacheView(image_view);
1619 }
1620 break;
1621 }
1622 if (LocaleCompare(attribute,"iterations") == 0)
1623 {
1624 iterations:
1625 for ( ; image; image=image->next)
1626 image->iterations=SvIV(sval);
1627 break;
1628 }
1629 if (LocaleCompare(attribute,"interlace") == 0)
1630 {
1631 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1632 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1633 if (sp < 0)
1634 {
1635 ThrowPerlException(exception,OptionError,
1636 "UnrecognizedInterlaceType",SvPV(sval,na));
1637 break;
1638 }
1639 if (info)
1640 info->image_info->interlace=(InterlaceType) sp;
1641 for ( ; image; image=image->next)
1642 image->interlace=(InterlaceType) sp;
1643 break;
1644 }
1645 if (info)
1646 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1647 for ( ; image; image=image->next)
1648 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1649 break;
1650 }
1651 case 'L':
1652 case 'l':
1653 {
1654 if (LocaleCompare(attribute,"label") == 0)
1655 {
1656 for ( ; image; image=image->next)
1657 (void) SetImageProperty(image,"label",InterpretImageProperties(
1658 info ? info->image_info : (ImageInfo *) NULL,image,
1659 SvPV(sval,na),exception),exception);
1660 break;
1661 }
1662 if (LocaleCompare(attribute,"loop") == 0)
1663 goto iterations;
1664 if (info)
1665 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1666 for ( ; image; image=image->next)
1667 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1668 break;
1669 }
1670 case 'M':
1671 case 'm':
1672 {
1673 if (LocaleCompare(attribute,"magick") == 0)
1674 {
1675 if (info)
cristy151b66d2015-04-15 10:50:31 +00001676 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00001677 "%s:",SvPV(sval,na));
1678 for ( ; image; image=image->next)
cristy151b66d2015-04-15 10:50:31 +00001679 (void) CopyMagickString(image->magick,SvPV(sval,na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001680 break;
1681 }
1682 if (LocaleCompare(attribute,"map-limit") == 0)
1683 {
1684 MagickSizeType
1685 limit;
1686
1687 limit=MagickResourceInfinity;
1688 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1689 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1690 100.0);
1691 (void) SetMagickResourceLimit(MapResource,limit);
1692 break;
1693 }
1694 if (LocaleCompare(attribute,"mask") == 0)
1695 {
1696 Image
1697 *mask;
1698
1699 mask=(Image *) NULL;
1700 if (SvPOK(sval))
1701 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1702 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001703 SetImageMask(image,ReadPixelMask,mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001704 break;
1705 }
1706 if (LocaleCompare(attribute,"mattecolor") == 0)
1707 {
1708 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1709 exception);
1710 if (info)
Cristy8645e042016-02-03 16:35:29 -05001711 info->image_info->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001712 for ( ; image; image=image->next)
Cristy8645e042016-02-03 16:35:29 -05001713 image->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001714 break;
1715 }
1716 if (LocaleCompare(attribute,"matte") == 0)
1717 {
1718 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1719 SvPV(sval,na)) : SvIV(sval);
1720 if (sp < 0)
1721 {
1722 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1723 SvPV(sval,na));
1724 break;
1725 }
1726 for ( ; image; image=image->next)
1727 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1728 break;
1729 }
1730 if (LocaleCompare(attribute,"memory-limit") == 0)
1731 {
1732 MagickSizeType
1733 limit;
1734
1735 limit=MagickResourceInfinity;
1736 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1737 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1738 100.0);
1739 (void) SetMagickResourceLimit(MemoryResource,limit);
1740 break;
1741 }
1742 if (LocaleCompare(attribute,"monochrome") == 0)
1743 {
1744 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1745 SvPV(sval,na)) : SvIV(sval);
1746 if (sp < 0)
1747 {
1748 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1749 SvPV(sval,na));
1750 break;
1751 }
1752 if (info)
1753 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1754 for ( ; image; image=image->next)
1755 (void) SetImageType(image,BilevelType,exception);
1756 break;
1757 }
1758 if (info)
1759 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1760 for ( ; image; image=image->next)
1761 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1762 break;
1763 }
1764 case 'O':
1765 case 'o':
1766 {
1767 if (LocaleCompare(attribute,"option") == 0)
1768 {
1769 if (info)
1770 DefineImageOption(info->image_info,SvPV(sval,na));
1771 break;
1772 }
1773 if (LocaleCompare(attribute,"orientation") == 0)
1774 {
1775 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1776 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1777 if (sp < 0)
1778 {
1779 ThrowPerlException(exception,OptionError,
1780 "UnrecognizedOrientationType",SvPV(sval,na));
1781 break;
1782 }
1783 if (info)
1784 info->image_info->orientation=(OrientationType) sp;
1785 for ( ; image; image=image->next)
1786 image->orientation=(OrientationType) sp;
1787 break;
1788 }
1789 if (info)
1790 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1791 for ( ; image; image=image->next)
1792 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1793 break;
1794 }
1795 case 'P':
1796 case 'p':
1797 {
1798 if (LocaleCompare(attribute,"page") == 0)
1799 {
1800 char
1801 *geometry;
1802
1803 geometry=GetPageGeometry(SvPV(sval,na));
1804 if (info)
1805 (void) CloneString(&info->image_info->page,geometry);
1806 for ( ; image; image=image->next)
1807 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1808 geometry=(char *) RelinquishMagickMemory(geometry);
1809 break;
1810 }
1811 if (LocaleNCompare(attribute,"pixel",5) == 0)
1812 {
1813 int
1814 items;
1815
1816 PixelInfo
1817 pixel;
1818
1819 register Quantum
1820 *q;
1821
1822 CacheView
1823 *image_view;
1824
1825 for ( ; image; image=image->next)
1826 {
1827 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1828 break;
1829 x=0;
1830 y=0;
1831 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1832 (void) items;
1833 image_view=AcquireVirtualCacheView(image,exception);
1834 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1835 if (q != (Quantum *) NULL)
1836 {
1837 if ((strchr(SvPV(sval,na),',') == 0) ||
1838 (strchr(SvPV(sval,na),')') != 0))
1839 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1840 &pixel,exception);
1841 else
1842 {
1843 GetPixelInfo(image,&pixel);
1844 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1845 pixel.red=geometry_info.rho;
1846 if ((flags & SigmaValue) != 0)
1847 pixel.green=geometry_info.sigma;
1848 if ((flags & XiValue) != 0)
1849 pixel.blue=geometry_info.xi;
1850 if ((flags & PsiValue) != 0)
1851 pixel.alpha=geometry_info.psi;
1852 if ((flags & ChiValue) != 0)
1853 pixel.black=geometry_info.chi;
1854 }
1855 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1856 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1857 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1858 if (image->colorspace == CMYKColorspace)
1859 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1860 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1861 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1862 }
1863 image_view=DestroyCacheView(image_view);
1864 }
1865 break;
1866 }
1867 if (LocaleCompare(attribute,"pointsize") == 0)
1868 {
1869 if (info)
1870 {
1871 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1872 info->image_info->pointsize=geometry_info.rho;
1873 }
1874 break;
1875 }
1876 if (LocaleCompare(attribute,"preview") == 0)
1877 {
1878 sp=SvPOK(sval) ? ParseCommandOption(MagickPreviewOptions,MagickFalse,
1879 SvPV(sval,na)) : SvIV(sval);
1880 if (sp < 0)
1881 {
1882 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1883 SvPV(sval,na));
1884 break;
1885 }
1886 if (info)
1887 info->image_info->preview_type=(PreviewType) sp;
1888 break;
1889 }
1890 if (info)
1891 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1892 for ( ; image; image=image->next)
1893 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1894 break;
1895 }
1896 case 'Q':
1897 case 'q':
1898 {
1899 if (LocaleCompare(attribute,"quality") == 0)
1900 {
1901 if (info)
1902 info->image_info->quality=SvIV(sval);
1903 for ( ; image; image=image->next)
1904 image->quality=SvIV(sval);
1905 break;
1906 }
1907 if (info)
1908 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1909 for ( ; image; image=image->next)
1910 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1911 break;
1912 }
1913 case 'R':
1914 case 'r':
1915 {
cristyc0fe4752015-07-27 18:02:39 +00001916 if (LocaleCompare(attribute,"read-mask") == 0)
1917 {
1918 Image
1919 *mask;
1920
1921 mask=(Image *) NULL;
1922 if (SvPOK(sval))
1923 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1924 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001925 SetImageMask(image,ReadPixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00001926 break;
1927 }
cristy4a3ce0a2013-08-03 20:06:59 +00001928 if (LocaleCompare(attribute,"red-primary") == 0)
1929 {
1930 for ( ; image; image=image->next)
1931 {
1932 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1933 image->chromaticity.red_primary.x=geometry_info.rho;
1934 image->chromaticity.red_primary.y=geometry_info.sigma;
1935 if ((flags & SigmaValue) == 0)
1936 image->chromaticity.red_primary.y=
1937 image->chromaticity.red_primary.x;
1938 }
1939 break;
1940 }
1941 if (LocaleCompare(attribute,"render") == 0)
1942 {
1943 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1944 SvPV(sval,na)) : SvIV(sval);
1945 if (sp < 0)
1946 {
1947 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1948 SvPV(sval,na));
1949 break;
1950 }
1951 for ( ; image; image=image->next)
1952 image->rendering_intent=(RenderingIntent) sp;
1953 break;
1954 }
1955 if (LocaleCompare(attribute,"repage") == 0)
1956 {
1957 RectangleInfo
1958 geometry;
1959
1960 for ( ; image; image=image->next)
1961 {
1962 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1963 if ((flags & WidthValue) != 0)
1964 {
1965 if ((flags & HeightValue) == 0)
1966 geometry.height=geometry.width;
1967 image->page.width=geometry.width;
1968 image->page.height=geometry.height;
1969 }
1970 if ((flags & AspectValue) != 0)
1971 {
1972 if ((flags & XValue) != 0)
1973 image->page.x+=geometry.x;
1974 if ((flags & YValue) != 0)
1975 image->page.y+=geometry.y;
1976 }
1977 else
1978 {
1979 if ((flags & XValue) != 0)
1980 {
1981 image->page.x=geometry.x;
1982 if (((flags & WidthValue) != 0) && (geometry.x > 0))
1983 image->page.width=image->columns+geometry.x;
1984 }
1985 if ((flags & YValue) != 0)
1986 {
1987 image->page.y=geometry.y;
1988 if (((flags & HeightValue) != 0) && (geometry.y > 0))
1989 image->page.height=image->rows+geometry.y;
1990 }
1991 }
1992 }
1993 break;
1994 }
1995 if (info)
1996 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1997 for ( ; image; image=image->next)
1998 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1999 break;
2000 }
2001 case 'S':
2002 case 's':
2003 {
2004 if (LocaleCompare(attribute,"sampling-factor") == 0)
2005 {
2006 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2007 {
2008 ThrowPerlException(exception,OptionError,"MissingGeometry",
2009 SvPV(sval,na));
2010 break;
2011 }
2012 if (info)
2013 (void) CloneString(&info->image_info->sampling_factor,
2014 SvPV(sval,na));
2015 break;
2016 }
2017 if (LocaleCompare(attribute,"scene") == 0)
2018 {
2019 for ( ; image; image=image->next)
2020 image->scene=SvIV(sval);
2021 break;
2022 }
2023 if (LocaleCompare(attribute,"server") == 0)
2024 goto display;
2025 if (LocaleCompare(attribute,"size") == 0)
2026 {
2027 if (info)
2028 {
2029 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2030 {
2031 ThrowPerlException(exception,OptionError,"MissingGeometry",
2032 SvPV(sval,na));
2033 break;
2034 }
2035 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2036 }
2037 break;
2038 }
2039 if (LocaleCompare(attribute,"stroke") == 0)
2040 {
2041 if (info)
2042 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2043 break;
2044 }
2045 if (info)
2046 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2047 for ( ; image; image=image->next)
2048 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2049 break;
2050 }
2051 case 'T':
2052 case 't':
2053 {
2054 if (LocaleCompare(attribute,"texture") == 0)
2055 {
2056 if (info)
2057 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2058 break;
2059 }
2060 if (LocaleCompare(attribute,"thread-limit") == 0)
2061 {
2062 MagickSizeType
2063 limit;
2064
2065 limit=MagickResourceInfinity;
2066 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2067 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2068 100.0);
2069 (void) SetMagickResourceLimit(ThreadResource,limit);
2070 break;
2071 }
2072 if (LocaleCompare(attribute,"tile-offset") == 0)
2073 {
2074 char
2075 *geometry;
2076
2077 geometry=GetPageGeometry(SvPV(sval,na));
2078 if (info)
2079 (void) CloneString(&info->image_info->page,geometry);
2080 for ( ; image; image=image->next)
2081 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2082 exception);
2083 geometry=(char *) RelinquishMagickMemory(geometry);
2084 break;
2085 }
2086 if (LocaleCompare(attribute,"time-limit") == 0)
2087 {
2088 MagickSizeType
2089 limit;
2090
2091 limit=MagickResourceInfinity;
2092 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2093 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2094 100.0);
2095 (void) SetMagickResourceLimit(TimeResource,limit);
2096 break;
2097 }
2098 if (LocaleCompare(attribute,"transparent-color") == 0)
2099 {
2100 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2101 exception);
2102 if (info)
2103 info->image_info->transparent_color=target_color;
2104 for ( ; image; image=image->next)
2105 image->transparent_color=target_color;
2106 break;
2107 }
2108 if (LocaleCompare(attribute,"type") == 0)
2109 {
2110 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2111 SvPV(sval,na)) : SvIV(sval);
2112 if (sp < 0)
2113 {
2114 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2115 SvPV(sval,na));
2116 break;
2117 }
2118 if (info)
2119 info->image_info->type=(ImageType) sp;
2120 for ( ; image; image=image->next)
2121 SetImageType(image,(ImageType) sp,exception);
2122 break;
2123 }
2124 if (info)
2125 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2126 for ( ; image; image=image->next)
2127 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2128 break;
2129 }
2130 case 'U':
2131 case 'u':
2132 {
2133 if (LocaleCompare(attribute,"units") == 0)
2134 {
2135 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2136 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2137 if (sp < 0)
2138 {
2139 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2140 SvPV(sval,na));
2141 break;
2142 }
2143 if (info)
2144 info->image_info->units=(ResolutionType) sp;
2145 for ( ; image; image=image->next)
2146 {
2147 ResolutionType
2148 units;
2149
2150 units=(ResolutionType) sp;
2151 if (image->units != units)
2152 switch (image->units)
2153 {
2154 case UndefinedResolution:
2155 case PixelsPerInchResolution:
2156 {
2157 if (units == PixelsPerCentimeterResolution)
2158 {
2159 image->resolution.x*=2.54;
2160 image->resolution.y*=2.54;
2161 }
2162 break;
2163 }
2164 case PixelsPerCentimeterResolution:
2165 {
2166 if (units == PixelsPerInchResolution)
2167 {
2168 image->resolution.x/=2.54;
2169 image->resolution.y/=2.54;
2170 }
2171 break;
2172 }
2173 }
2174 image->units=units;
2175 }
2176 break;
2177 }
2178 if (info)
2179 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2180 for ( ; image; image=image->next)
2181 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2182 break;
2183 }
2184 case 'V':
2185 case 'v':
2186 {
2187 if (LocaleCompare(attribute,"verbose") == 0)
2188 {
2189 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2190 SvPV(sval,na)) : SvIV(sval);
2191 if (sp < 0)
2192 {
2193 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2194 SvPV(sval,na));
2195 break;
2196 }
2197 if (info)
2198 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2199 break;
2200 }
cristy4a3ce0a2013-08-03 20:06:59 +00002201 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2202 {
2203 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2204 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2205 if (sp < 0)
2206 {
2207 ThrowPerlException(exception,OptionError,
2208 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2209 break;
2210 }
2211 for ( ; image; image=image->next)
2212 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2213 break;
2214 }
2215 if (info)
2216 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2217 for ( ; image; image=image->next)
2218 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2219 break;
2220 }
2221 case 'W':
2222 case 'w':
2223 {
2224 if (LocaleCompare(attribute,"white-point") == 0)
2225 {
2226 for ( ; image; image=image->next)
2227 {
2228 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2229 image->chromaticity.white_point.x=geometry_info.rho;
2230 image->chromaticity.white_point.y=geometry_info.sigma;
2231 if ((flags & SigmaValue) == 0)
2232 image->chromaticity.white_point.y=
2233 image->chromaticity.white_point.x;
2234 }
2235 break;
2236 }
cristyc0fe4752015-07-27 18:02:39 +00002237 if (LocaleCompare(attribute,"write-mask") == 0)
2238 {
2239 Image
2240 *mask;
2241
2242 mask=(Image *) NULL;
2243 if (SvPOK(sval))
2244 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2245 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002246 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002247 break;
2248 }
cristy4a3ce0a2013-08-03 20:06:59 +00002249 if (info)
2250 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2251 for ( ; image; image=image->next)
2252 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2253 break;
2254 }
2255 default:
2256 {
2257 if (info)
2258 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2259 for ( ; image; image=image->next)
2260 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2261 break;
2262 }
2263 }
2264}
2265
2266/*
2267%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2268% %
2269% %
2270% %
2271% S e t u p L i s t %
2272% %
2273% %
2274% %
2275%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2276%
2277% Method SetupList returns the list of all the images linked by their
2278% image->next and image->previous link lists for use with ImageMagick. If
2279% info is non-NULL, an info structure is returned in *info. If
2280% reference_vector is non-NULL,an array of SV* are returned in
2281% *reference_vector. Reference_vector is used when the images are going to be
2282% replaced with new Image*'s.
2283%
2284% The format of the SetupList routine is:
2285%
2286% Image *SetupList(SV *reference,struct PackageInfo **info,
2287% SV ***reference_vector,ExceptionInfo *exception)
2288%
2289% A description of each parameter follows:
2290%
2291% o list: a list of strings.
2292%
2293% o string: a character string.
2294%
2295% o exception: Return any errors or warnings in this structure.
2296%
2297*/
2298static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2299 SV ***reference_vector,ExceptionInfo *exception)
2300{
2301 Image
2302 *image;
2303
2304 ssize_t
2305 current,
2306 last;
2307
2308 if (reference_vector)
2309 *reference_vector=NULL;
2310 if (info)
2311 *info=NULL;
2312 current=0;
2313 last=0;
2314 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2315 if (info && (SvTYPE(reference) == SVt_PVAV))
2316 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2317 exception);
2318 return(image);
2319}
2320
2321/*
2322%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2323% %
2324% %
2325% %
2326% s t r E Q c a s e %
2327% %
2328% %
2329% %
2330%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2331%
2332% strEQcase() compares two strings and returns 0 if they are the
2333% same or if the second string runs out first. The comparison is case
2334% insensitive.
2335%
2336% The format of the strEQcase routine is:
2337%
2338% ssize_t strEQcase(const char *p,const char *q)
2339%
2340% A description of each parameter follows:
2341%
2342% o p: a character string.
2343%
2344% o q: a character string.
2345%
2346%
2347*/
2348static ssize_t strEQcase(const char *p,const char *q)
2349{
2350 char
2351 c;
2352
2353 register ssize_t
2354 i;
2355
2356 for (i=0 ; (c=(*q)) != 0; i++)
2357 {
2358 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2359 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2360 return(0);
2361 p++;
2362 q++;
2363 }
2364 return(((*q == 0) && (*p == 0)) ? i : 0);
2365}
2366
2367/*
2368%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2369% %
2370% %
2371% %
2372% I m a g e : : M a g i c k %
2373% %
2374% %
2375% %
2376%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2377%
2378%
2379*/
2380MODULE = Image::Magick PACKAGE = Image::Magick
2381
2382PROTOTYPES: ENABLE
2383
2384BOOT:
2385 MagickCoreGenesis("PerlMagick",MagickFalse);
2386 SetWarningHandler(NULL);
2387 SetErrorHandler(NULL);
2388 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2389 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2390
2391void
2392UNLOAD()
2393 PPCODE:
2394 {
2395 if (magick_registry != (SplayTreeInfo *) NULL)
2396 magick_registry=DestroySplayTree(magick_registry);
2397 MagickCoreTerminus();
2398 }
2399
2400double
2401constant(name,argument)
2402 char *name
2403 ssize_t argument
2404
2405#
2406###############################################################################
2407# #
2408# #
2409# #
2410# A n i m a t e #
2411# #
2412# #
2413# #
2414###############################################################################
2415#
2416#
2417void
2418Animate(ref,...)
2419 Image::Magick ref=NO_INIT
2420 ALIAS:
2421 AnimateImage = 1
2422 animate = 2
2423 animateimage = 3
2424 PPCODE:
2425 {
2426 ExceptionInfo
2427 *exception;
2428
2429 Image
2430 *image;
2431
2432 register ssize_t
2433 i;
2434
2435 struct PackageInfo
2436 *info,
2437 *package_info;
2438
2439 SV
2440 *perl_exception,
2441 *reference;
2442
2443 PERL_UNUSED_VAR(ref);
2444 PERL_UNUSED_VAR(ix);
2445 exception=AcquireExceptionInfo();
2446 perl_exception=newSVpv("",0);
2447 package_info=(struct PackageInfo *) NULL;
2448 if (sv_isobject(ST(0)) == 0)
2449 {
2450 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2451 PackageName);
2452 goto PerlException;
2453 }
2454 reference=SvRV(ST(0));
2455 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2456 if (image == (Image *) NULL)
2457 {
2458 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2459 PackageName);
2460 goto PerlException;
2461 }
2462 package_info=ClonePackageInfo(info,exception);
2463 if (items == 2)
2464 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2465 else
2466 if (items > 2)
2467 for (i=2; i < items; i+=2)
2468 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2469 exception);
2470 (void) AnimateImages(package_info->image_info,image,exception);
2471 (void) CatchImageException(image);
2472
2473 PerlException:
2474 if (package_info != (struct PackageInfo *) NULL)
2475 DestroyPackageInfo(package_info);
2476 InheritPerlException(exception,perl_exception);
2477 exception=DestroyExceptionInfo(exception);
2478 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2479 SvPOK_on(perl_exception);
2480 ST(0)=sv_2mortal(perl_exception);
2481 XSRETURN(1);
2482 }
2483
2484#
2485###############################################################################
2486# #
2487# #
2488# #
2489# A p p e n d #
2490# #
2491# #
2492# #
2493###############################################################################
2494#
2495#
2496void
2497Append(ref,...)
2498 Image::Magick ref=NO_INIT
2499 ALIAS:
2500 AppendImage = 1
2501 append = 2
2502 appendimage = 3
2503 PPCODE:
2504 {
2505 AV
2506 *av;
2507
2508 char
2509 *attribute;
2510
2511 ExceptionInfo
2512 *exception;
2513
2514 HV
2515 *hv;
2516
2517 Image
2518 *image;
2519
2520 register ssize_t
2521 i;
2522
2523 ssize_t
2524 stack;
2525
2526 struct PackageInfo
2527 *info;
2528
2529 SV
2530 *av_reference,
2531 *perl_exception,
2532 *reference,
2533 *rv,
2534 *sv;
2535
2536 PERL_UNUSED_VAR(ref);
2537 PERL_UNUSED_VAR(ix);
2538 exception=AcquireExceptionInfo();
2539 perl_exception=newSVpv("",0);
2540 sv=NULL;
2541 attribute=NULL;
2542 av=NULL;
2543 if (sv_isobject(ST(0)) == 0)
2544 {
2545 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2546 PackageName);
2547 goto PerlException;
2548 }
2549 reference=SvRV(ST(0));
2550 hv=SvSTASH(reference);
2551 av=newAV();
2552 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2553 SvREFCNT_dec(av);
2554 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2555 if (image == (Image *) NULL)
2556 {
2557 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2558 PackageName);
2559 goto PerlException;
2560 }
2561 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2562 /*
2563 Get options.
2564 */
2565 stack=MagickTrue;
2566 for (i=2; i < items; i+=2)
2567 {
2568 attribute=(char *) SvPV(ST(i-1),na);
2569 switch (*attribute)
2570 {
2571 case 'S':
2572 case 's':
2573 {
2574 if (LocaleCompare(attribute,"stack") == 0)
2575 {
2576 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2577 SvPV(ST(i),na));
2578 if (stack < 0)
2579 {
2580 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2581 SvPV(ST(i),na));
2582 return;
2583 }
2584 break;
2585 }
2586 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2587 attribute);
2588 break;
2589 }
2590 default:
2591 {
2592 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2593 attribute);
2594 break;
2595 }
2596 }
2597 }
2598 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2599 if (image == (Image *) NULL)
2600 goto PerlException;
2601 for ( ; image; image=image->next)
2602 {
2603 AddImageToRegistry(sv,image);
2604 rv=newRV(sv);
2605 av_push(av,sv_bless(rv,hv));
2606 SvREFCNT_dec(sv);
2607 }
2608 exception=DestroyExceptionInfo(exception);
2609 ST(0)=av_reference;
2610 SvREFCNT_dec(perl_exception);
2611 XSRETURN(1);
2612
2613 PerlException:
2614 InheritPerlException(exception,perl_exception);
2615 exception=DestroyExceptionInfo(exception);
2616 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2617 SvPOK_on(perl_exception);
2618 ST(0)=sv_2mortal(perl_exception);
2619 XSRETURN(1);
2620 }
2621
2622#
2623###############################################################################
2624# #
2625# #
2626# #
2627# A v e r a g e #
2628# #
2629# #
2630# #
2631###############################################################################
2632#
2633#
2634void
2635Average(ref)
2636 Image::Magick ref=NO_INIT
2637 ALIAS:
2638 AverageImage = 1
2639 average = 2
2640 averageimage = 3
2641 PPCODE:
2642 {
2643 AV
2644 *av;
2645
2646 char
2647 *p;
2648
2649 ExceptionInfo
2650 *exception;
2651
2652 HV
2653 *hv;
2654
2655 Image
2656 *image;
2657
2658 struct PackageInfo
2659 *info;
2660
2661 SV
2662 *perl_exception,
2663 *reference,
2664 *rv,
2665 *sv;
2666
2667 PERL_UNUSED_VAR(ref);
2668 PERL_UNUSED_VAR(ix);
2669 exception=AcquireExceptionInfo();
2670 perl_exception=newSVpv("",0);
2671 sv=NULL;
2672 if (sv_isobject(ST(0)) == 0)
2673 {
2674 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2675 PackageName);
2676 goto PerlException;
2677 }
2678 reference=SvRV(ST(0));
2679 hv=SvSTASH(reference);
2680 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2681 if (image == (Image *) NULL)
2682 {
2683 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2684 PackageName);
2685 goto PerlException;
2686 }
2687 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2688 if (image == (Image *) NULL)
2689 goto PerlException;
2690 /*
2691 Create blessed Perl array for the returned image.
2692 */
2693 av=newAV();
2694 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2695 SvREFCNT_dec(av);
2696 AddImageToRegistry(sv,image);
2697 rv=newRV(sv);
2698 av_push(av,sv_bless(rv,hv));
2699 SvREFCNT_dec(sv);
2700 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002701 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2702 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002703 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2704 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002705 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002706 SetImageInfo(info->image_info,0,exception);
2707 exception=DestroyExceptionInfo(exception);
2708 SvREFCNT_dec(perl_exception);
2709 XSRETURN(1);
2710
2711 PerlException:
2712 InheritPerlException(exception,perl_exception);
2713 exception=DestroyExceptionInfo(exception);
2714 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2715 SvPOK_on(perl_exception);
2716 ST(0)=sv_2mortal(perl_exception);
2717 XSRETURN(1);
2718 }
2719
2720#
2721###############################################################################
2722# #
2723# #
2724# #
2725# B l o b T o I m a g e #
2726# #
2727# #
2728# #
2729###############################################################################
2730#
2731#
2732void
2733BlobToImage(ref,...)
2734 Image::Magick ref=NO_INIT
2735 ALIAS:
2736 BlobToImage = 1
2737 blobtoimage = 2
2738 blobto = 3
2739 PPCODE:
2740 {
2741 AV
2742 *av;
2743
2744 char
2745 **keep,
2746 **list;
2747
2748 ExceptionInfo
2749 *exception;
2750
2751 HV
2752 *hv;
2753
2754 Image
2755 *image;
2756
2757 register char
2758 **p;
2759
2760 register ssize_t
2761 i;
2762
2763 ssize_t
2764 ac,
2765 n,
2766 number_images;
2767
2768 STRLEN
2769 *length;
2770
2771 struct PackageInfo
2772 *info;
2773
2774 SV
2775 *perl_exception,
2776 *reference,
2777 *rv,
2778 *sv;
2779
2780 PERL_UNUSED_VAR(ref);
2781 PERL_UNUSED_VAR(ix);
2782 exception=AcquireExceptionInfo();
2783 perl_exception=newSVpv("",0);
2784 sv=NULL;
2785 number_images=0;
2786 ac=(items < 2) ? 1 : items-1;
2787 length=(STRLEN *) NULL;
2788 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2789 if (list == (char **) NULL)
2790 {
2791 ThrowPerlException(exception,ResourceLimitError,
2792 "MemoryAllocationFailed",PackageName);
2793 goto PerlException;
2794 }
2795 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2796 if (length == (STRLEN *) NULL)
2797 {
2798 ThrowPerlException(exception,ResourceLimitError,
2799 "MemoryAllocationFailed",PackageName);
2800 goto PerlException;
2801 }
2802 if (sv_isobject(ST(0)) == 0)
2803 {
2804 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2805 PackageName);
2806 goto PerlException;
2807 }
2808 reference=SvRV(ST(0));
2809 hv=SvSTASH(reference);
2810 if (SvTYPE(reference) != SVt_PVAV)
2811 {
2812 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2813 PackageName);
2814 goto PerlException;
2815 }
2816 av=(AV *) reference;
2817 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2818 exception);
2819 n=1;
2820 if (items <= 1)
2821 {
2822 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2823 goto PerlException;
2824 }
2825 for (n=0, i=0; i < ac; i++)
2826 {
2827 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2828 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2829 {
2830 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2831 continue;
2832 }
2833 n++;
2834 }
2835 list[n]=(char *) NULL;
2836 keep=list;
2837 for (i=number_images=0; i < n; i++)
2838 {
2839 image=BlobToImage(info->image_info,list[i],length[i],exception);
2840 if (image == (Image *) NULL)
2841 break;
2842 for ( ; image; image=image->next)
2843 {
2844 AddImageToRegistry(sv,image);
2845 rv=newRV(sv);
2846 av_push(av,sv_bless(rv,hv));
2847 SvREFCNT_dec(sv);
2848 number_images++;
2849 }
2850 }
2851 /*
2852 Free resources.
2853 */
2854 for (i=0; i < n; i++)
2855 if (list[i] != (char *) NULL)
2856 for (p=keep; list[i] != *p++; )
2857 if (*p == (char *) NULL)
2858 {
2859 list[i]=(char *) RelinquishMagickMemory(list[i]);
2860 break;
2861 }
2862
2863 PerlException:
2864 if (list)
2865 list=(char **) RelinquishMagickMemory(list);
2866 if (length)
2867 length=(STRLEN *) RelinquishMagickMemory(length);
2868 InheritPerlException(exception,perl_exception);
2869 exception=DestroyExceptionInfo(exception);
2870 sv_setiv(perl_exception,(IV) number_images);
2871 SvPOK_on(perl_exception);
2872 ST(0)=sv_2mortal(perl_exception);
2873 XSRETURN(1);
2874 }
2875
2876#
2877###############################################################################
2878# #
2879# #
2880# #
2881# C h a n n e l F x #
2882# #
2883# #
2884# #
2885###############################################################################
2886#
2887#
2888void
2889ChannelFx(ref,...)
2890 Image::Magick ref=NO_INIT
2891 ALIAS:
2892 ChannelFxImage = 1
2893 channelfx = 2
2894 channelfximage = 3
2895 PPCODE:
2896 {
2897 AV
2898 *av;
2899
2900 char
2901 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002902 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002903
2904 ChannelType
2905 channel,
2906 channel_mask;
2907
2908 ExceptionInfo
2909 *exception;
2910
2911 HV
2912 *hv;
2913
2914 Image
2915 *image;
2916
2917 register ssize_t
2918 i;
2919
2920 struct PackageInfo
2921 *info;
2922
2923 SV
2924 *av_reference,
2925 *perl_exception,
2926 *reference,
2927 *rv,
2928 *sv;
2929
2930 PERL_UNUSED_VAR(ref);
2931 PERL_UNUSED_VAR(ix);
2932 exception=AcquireExceptionInfo();
2933 perl_exception=newSVpv("",0);
2934 sv=NULL;
2935 attribute=NULL;
2936 av=NULL;
2937 if (sv_isobject(ST(0)) == 0)
2938 {
2939 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2940 PackageName);
2941 goto PerlException;
2942 }
2943 reference=SvRV(ST(0));
2944 hv=SvSTASH(reference);
2945 av=newAV();
2946 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2947 SvREFCNT_dec(av);
2948 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2949 if (image == (Image *) NULL)
2950 {
2951 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2952 PackageName);
2953 goto PerlException;
2954 }
2955 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2956 /*
2957 Get options.
2958 */
2959 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00002960 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002961 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00002962 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002963 else
2964 for (i=2; i < items; i+=2)
2965 {
2966 attribute=(char *) SvPV(ST(i-1),na);
2967 switch (*attribute)
2968 {
2969 case 'C':
2970 case 'c':
2971 {
2972 if (LocaleCompare(attribute,"channel") == 0)
2973 {
2974 ssize_t
2975 option;
2976
2977 option=ParseChannelOption(SvPV(ST(i),na));
2978 if (option < 0)
2979 {
2980 ThrowPerlException(exception,OptionError,
2981 "UnrecognizedType",SvPV(ST(i),na));
2982 return;
2983 }
2984 channel=(ChannelType) option;
2985 break;
2986 }
2987 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2988 attribute);
2989 break;
2990 }
2991 case 'E':
2992 case 'e':
2993 {
2994 if (LocaleCompare(attribute,"expression") == 0)
2995 {
2996 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00002997 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002998 break;
2999 }
3000 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3001 attribute);
3002 break;
3003 }
3004 default:
3005 {
3006 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3007 attribute);
3008 break;
3009 }
3010 }
3011 }
3012 channel_mask=SetImageChannelMask(image,channel);
3013 image=ChannelFxImage(image,expression,exception);
3014 if (image != (Image *) NULL)
3015 (void) SetImageChannelMask(image,channel_mask);
3016 if (image == (Image *) NULL)
3017 goto PerlException;
3018 for ( ; image; image=image->next)
3019 {
3020 AddImageToRegistry(sv,image);
3021 rv=newRV(sv);
3022 av_push(av,sv_bless(rv,hv));
3023 SvREFCNT_dec(sv);
3024 }
3025 exception=DestroyExceptionInfo(exception);
3026 ST(0)=av_reference;
3027 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3028 XSRETURN(1);
3029
3030 PerlException:
3031 InheritPerlException(exception,perl_exception);
3032 exception=DestroyExceptionInfo(exception);
3033 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3034 SvPOK_on(perl_exception);
3035 ST(0)=sv_2mortal(perl_exception);
3036 XSRETURN(1);
3037 }
3038
3039#
3040###############################################################################
3041# #
3042# #
3043# #
3044# C l o n e #
3045# #
3046# #
3047# #
3048###############################################################################
3049#
3050#
3051void
3052Clone(ref)
3053 Image::Magick ref=NO_INIT
3054 ALIAS:
3055 CopyImage = 1
3056 copy = 2
3057 copyimage = 3
3058 CloneImage = 4
3059 clone = 5
3060 cloneimage = 6
3061 Clone = 7
3062 PPCODE:
3063 {
3064 AV
3065 *av;
3066
3067 ExceptionInfo
3068 *exception;
3069
3070 HV
3071 *hv;
3072
3073 Image
3074 *clone,
3075 *image;
3076
3077 struct PackageInfo
3078 *info;
3079
3080 SV
3081 *perl_exception,
3082 *reference,
3083 *rv,
3084 *sv;
3085
3086 PERL_UNUSED_VAR(ref);
3087 PERL_UNUSED_VAR(ix);
3088 exception=AcquireExceptionInfo();
3089 perl_exception=newSVpv("",0);
3090 sv=NULL;
3091 if (sv_isobject(ST(0)) == 0)
3092 {
3093 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3094 PackageName);
3095 goto PerlException;
3096 }
3097 reference=SvRV(ST(0));
3098 hv=SvSTASH(reference);
3099 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3100 if (image == (Image *) NULL)
3101 {
3102 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3103 PackageName);
3104 goto PerlException;
3105 }
3106 /*
3107 Create blessed Perl array for the returned image.
3108 */
3109 av=newAV();
3110 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3111 SvREFCNT_dec(av);
3112 for ( ; image; image=image->next)
3113 {
3114 clone=CloneImage(image,0,0,MagickTrue,exception);
3115 if (clone == (Image *) NULL)
3116 break;
3117 AddImageToRegistry(sv,clone);
3118 rv=newRV(sv);
3119 av_push(av,sv_bless(rv,hv));
3120 SvREFCNT_dec(sv);
3121 }
3122 exception=DestroyExceptionInfo(exception);
3123 SvREFCNT_dec(perl_exception);
3124 XSRETURN(1);
3125
3126 PerlException:
3127 InheritPerlException(exception,perl_exception);
3128 exception=DestroyExceptionInfo(exception);
3129 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3130 SvPOK_on(perl_exception);
3131 ST(0)=sv_2mortal(perl_exception);
3132 XSRETURN(1);
3133 }
3134
3135#
3136###############################################################################
3137# #
3138# #
3139# #
3140# C L O N E #
3141# #
3142# #
3143# #
3144###############################################################################
3145#
3146#
3147void
3148CLONE(ref,...)
3149 SV *ref;
3150 CODE:
3151 {
3152 PERL_UNUSED_VAR(ref);
3153 if (magick_registry != (SplayTreeInfo *) NULL)
3154 {
3155 register Image
3156 *p;
3157
3158 ResetSplayTreeIterator(magick_registry);
3159 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3160 while (p != (Image *) NULL)
3161 {
3162 ReferenceImage(p);
3163 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3164 }
3165 }
3166 }
3167
3168#
3169###############################################################################
3170# #
3171# #
3172# #
3173# C o a l e s c e #
3174# #
3175# #
3176# #
3177###############################################################################
3178#
3179#
3180void
3181Coalesce(ref)
3182 Image::Magick ref=NO_INIT
3183 ALIAS:
3184 CoalesceImage = 1
3185 coalesce = 2
3186 coalesceimage = 3
3187 PPCODE:
3188 {
3189 AV
3190 *av;
3191
3192 ExceptionInfo
3193 *exception;
3194
3195 HV
3196 *hv;
3197
3198 Image
3199 *image;
3200
3201 struct PackageInfo
3202 *info;
3203
3204 SV
3205 *av_reference,
3206 *perl_exception,
3207 *reference,
3208 *rv,
3209 *sv;
3210
3211 PERL_UNUSED_VAR(ref);
3212 PERL_UNUSED_VAR(ix);
3213 exception=AcquireExceptionInfo();
3214 perl_exception=newSVpv("",0);
3215 sv=NULL;
3216 if (sv_isobject(ST(0)) == 0)
3217 {
3218 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3219 PackageName);
3220 goto PerlException;
3221 }
3222 reference=SvRV(ST(0));
3223 hv=SvSTASH(reference);
3224 av=newAV();
3225 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3226 SvREFCNT_dec(av);
3227 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3228 if (image == (Image *) NULL)
3229 {
3230 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3231 PackageName);
3232 goto PerlException;
3233 }
3234 image=CoalesceImages(image,exception);
3235 if (image == (Image *) NULL)
3236 goto PerlException;
3237 for ( ; image; image=image->next)
3238 {
3239 AddImageToRegistry(sv,image);
3240 rv=newRV(sv);
3241 av_push(av,sv_bless(rv,hv));
3242 SvREFCNT_dec(sv);
3243 }
3244 exception=DestroyExceptionInfo(exception);
3245 ST(0)=av_reference;
3246 SvREFCNT_dec(perl_exception);
3247 XSRETURN(1);
3248
3249 PerlException:
3250 InheritPerlException(exception,perl_exception);
3251 exception=DestroyExceptionInfo(exception);
3252 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3253 SvPOK_on(perl_exception);
3254 ST(0)=sv_2mortal(perl_exception);
3255 XSRETURN(1);
3256 }
3257
3258#
3259###############################################################################
3260# #
3261# #
3262# #
3263# C o m p a r e #
3264# #
3265# #
3266# #
3267###############################################################################
3268#
3269#
3270void
3271Compare(ref,...)
3272 Image::Magick ref=NO_INIT
3273 ALIAS:
3274 CompareImages = 1
3275 compare = 2
3276 compareimage = 3
3277 PPCODE:
3278 {
3279 AV
3280 *av;
3281
3282 char
3283 *attribute;
3284
3285 double
3286 distortion;
3287
3288 ExceptionInfo
3289 *exception;
3290
3291 HV
3292 *hv;
3293
3294 Image
3295 *difference_image,
3296 *image,
3297 *reconstruct_image;
3298
3299 MetricType
3300 metric;
3301
3302 register ssize_t
3303 i;
3304
3305 ssize_t
3306 option;
3307
3308 struct PackageInfo
3309 *info;
3310
3311 SV
3312 *av_reference,
3313 *perl_exception,
3314 *reference,
3315 *rv,
3316 *sv;
3317
3318 PERL_UNUSED_VAR(ref);
3319 PERL_UNUSED_VAR(ix);
3320 exception=AcquireExceptionInfo();
3321 perl_exception=newSVpv("",0);
3322 sv=NULL;
3323 av=NULL;
3324 attribute=NULL;
3325 if (sv_isobject(ST(0)) == 0)
3326 {
3327 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3328 PackageName);
3329 goto PerlException;
3330 }
3331 reference=SvRV(ST(0));
3332 hv=SvSTASH(reference);
3333 av=newAV();
3334 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3335 SvREFCNT_dec(av);
3336 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3337 if (image == (Image *) NULL)
3338 {
3339 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3340 PackageName);
3341 goto PerlException;
3342 }
3343 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3344 /*
3345 Get attribute.
3346 */
3347 reconstruct_image=image;
3348 metric=RootMeanSquaredErrorMetric;
3349 for (i=2; i < items; i+=2)
3350 {
3351 attribute=(char *) SvPV(ST(i-1),na);
3352 switch (*attribute)
3353 {
3354 case 'C':
3355 case 'c':
3356 {
3357 if (LocaleCompare(attribute,"channel") == 0)
3358 {
3359 ssize_t
3360 option;
3361
3362 option=ParseChannelOption(SvPV(ST(i),na));
3363 if (option < 0)
3364 {
3365 ThrowPerlException(exception,OptionError,
3366 "UnrecognizedType",SvPV(ST(i),na));
3367 return;
3368 }
cristybcd59342015-06-07 14:07:19 +00003369 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003370 break;
3371 }
3372 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3373 attribute);
3374 break;
3375 }
3376 case 'F':
3377 case 'f':
3378 {
3379 if (LocaleCompare(attribute,"fuzz") == 0)
3380 {
3381 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3382 break;
3383 }
3384 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3385 attribute);
3386 break;
3387 }
3388 case 'I':
3389 case 'i':
3390 {
3391 if (LocaleCompare(attribute,"image") == 0)
3392 {
3393 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3394 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3395 break;
3396 }
3397 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3398 attribute);
3399 break;
3400 }
3401 case 'M':
3402 case 'm':
3403 {
3404 if (LocaleCompare(attribute,"metric") == 0)
3405 {
3406 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3407 SvPV(ST(i),na));
3408 if (option < 0)
3409 {
3410 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3411 SvPV(ST(i),na));
3412 break;
3413 }
3414 metric=(MetricType) option;
3415 break;
3416 }
3417 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3418 attribute);
3419 break;
3420 }
3421 default:
3422 {
3423 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3424 attribute);
3425 break;
3426 }
3427 }
3428 }
3429 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3430 exception);
3431 if (difference_image != (Image *) NULL)
3432 {
3433 difference_image->error.mean_error_per_pixel=distortion;
3434 AddImageToRegistry(sv,difference_image);
3435 rv=newRV(sv);
3436 av_push(av,sv_bless(rv,hv));
3437 SvREFCNT_dec(sv);
3438 }
3439 exception=DestroyExceptionInfo(exception);
3440 ST(0)=av_reference;
3441 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3442 XSRETURN(1);
3443
3444 PerlException:
3445 InheritPerlException(exception,perl_exception);
3446 exception=DestroyExceptionInfo(exception);
3447 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3448 SvPOK_on(perl_exception);
3449 ST(0)=sv_2mortal(perl_exception);
3450 XSRETURN(1);
3451 }
3452
3453#
3454###############################################################################
3455# #
3456# #
3457# #
cristy15655332013-10-06 00:27:33 +00003458# C o m p l e x I m a g e s #
3459# #
3460# #
3461# #
3462###############################################################################
3463#
3464#
3465void
3466ComplexImages(ref)
3467 Image::Magick ref=NO_INIT
3468 ALIAS:
3469 ComplexImages = 1
3470 compleximages = 2
3471 PPCODE:
3472 {
3473 AV
3474 *av;
3475
3476 char
3477 *attribute,
3478 *p;
3479
cristyfa21e9e2013-10-07 10:37:38 +00003480 ComplexOperator
3481 op;
3482
cristy15655332013-10-06 00:27:33 +00003483 ExceptionInfo
3484 *exception;
3485
3486 HV
3487 *hv;
3488
3489 Image
3490 *image;
3491
cristy15655332013-10-06 00:27:33 +00003492 register ssize_t
3493 i;
3494
3495 struct PackageInfo
3496 *info;
3497
3498 SV
3499 *perl_exception,
3500 *reference,
3501 *rv,
3502 *sv;
3503
3504 PERL_UNUSED_VAR(ref);
3505 PERL_UNUSED_VAR(ix);
3506 exception=AcquireExceptionInfo();
3507 perl_exception=newSVpv("",0);
3508 sv=NULL;
3509 if (sv_isobject(ST(0)) == 0)
3510 {
3511 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3512 PackageName);
3513 goto PerlException;
3514 }
3515 reference=SvRV(ST(0));
3516 hv=SvSTASH(reference);
3517 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3518 if (image == (Image *) NULL)
3519 {
3520 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3521 PackageName);
3522 goto PerlException;
3523 }
cristyfd168722013-10-07 15:59:31 +00003524 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003525 if (items == 2)
3526 {
3527 ssize_t
3528 in;
3529
3530 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3531 SvPV(ST(1),na));
3532 if (in < 0)
3533 {
3534 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3535 SvPV(ST(1),na));
3536 return;
3537 }
cristyfa21e9e2013-10-07 10:37:38 +00003538 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003539 }
3540 else
3541 for (i=2; i < items; i+=2)
3542 {
3543 attribute=(char *) SvPV(ST(i-1),na);
3544 switch (*attribute)
3545 {
3546 case 'O':
3547 case 'o':
3548 {
3549 if (LocaleCompare(attribute,"operator") == 0)
3550 {
3551 ssize_t
3552 in;
3553
3554 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3555 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3556 if (in < 0)
3557 {
3558 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3559 SvPV(ST(i),na));
3560 return;
3561 }
cristyfa21e9e2013-10-07 10:37:38 +00003562 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003563 break;
3564 }
3565 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3566 attribute);
3567 break;
3568 }
3569 default:
3570 {
3571 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3572 attribute);
3573 break;
3574 }
3575 }
3576 }
3577 image=ComplexImages(image,op,exception);
3578 if (image == (Image *) NULL)
3579 goto PerlException;
3580 /*
3581 Create blessed Perl array for the returned image.
3582 */
3583 av=newAV();
3584 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3585 SvREFCNT_dec(av);
3586 AddImageToRegistry(sv,image);
3587 rv=newRV(sv);
3588 av_push(av,sv_bless(rv,hv));
3589 SvREFCNT_dec(sv);
3590 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003591 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3592 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003593 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3594 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003595 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003596 SetImageInfo(info->image_info,0,exception);
3597 exception=DestroyExceptionInfo(exception);
3598 SvREFCNT_dec(perl_exception);
3599 XSRETURN(1);
3600
3601 PerlException:
3602 InheritPerlException(exception,perl_exception);
3603 exception=DestroyExceptionInfo(exception);
3604 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3605 SvPOK_on(perl_exception);
3606 ST(0)=sv_2mortal(perl_exception);
3607 XSRETURN(1);
3608 }
3609
3610#
3611###############################################################################
3612# #
3613# #
3614# #
cristy4a3ce0a2013-08-03 20:06:59 +00003615# C o m p a r e L a y e r s #
3616# #
3617# #
3618# #
3619###############################################################################
3620#
3621#
3622void
3623CompareLayers(ref)
3624 Image::Magick ref=NO_INIT
3625 ALIAS:
3626 CompareImagesLayers = 1
3627 comparelayers = 2
3628 compareimagelayers = 3
3629 PPCODE:
3630 {
3631 AV
3632 *av;
3633
3634 char
3635 *attribute;
3636
3637 ExceptionInfo
3638 *exception;
3639
3640 HV
3641 *hv;
3642
3643 Image
3644 *image;
3645
3646 LayerMethod
3647 method;
3648
3649 register ssize_t
3650 i;
3651
3652 ssize_t
3653 option;
3654
3655 struct PackageInfo
3656 *info;
3657
3658 SV
3659 *av_reference,
3660 *perl_exception,
3661 *reference,
3662 *rv,
3663 *sv;
3664
3665 PERL_UNUSED_VAR(ref);
3666 PERL_UNUSED_VAR(ix);
3667 exception=AcquireExceptionInfo();
3668 perl_exception=newSVpv("",0);
3669 sv=NULL;
3670 if (sv_isobject(ST(0)) == 0)
3671 {
3672 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3673 PackageName);
3674 goto PerlException;
3675 }
3676 reference=SvRV(ST(0));
3677 hv=SvSTASH(reference);
3678 av=newAV();
3679 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3680 SvREFCNT_dec(av);
3681 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3682 if (image == (Image *) NULL)
3683 {
3684 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3685 PackageName);
3686 goto PerlException;
3687 }
3688 method=CompareAnyLayer;
3689 for (i=2; i < items; i+=2)
3690 {
3691 attribute=(char *) SvPV(ST(i-1),na);
3692 switch (*attribute)
3693 {
3694 case 'M':
3695 case 'm':
3696 {
3697 if (LocaleCompare(attribute,"method") == 0)
3698 {
3699 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3700 SvPV(ST(i),na));
3701 if (option < 0)
3702 {
3703 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3704 SvPV(ST(i),na));
3705 break;
3706 }
3707 method=(LayerMethod) option;
3708 break;
3709 }
3710 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3711 attribute);
3712 break;
3713 }
3714 default:
3715 {
3716 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3717 attribute);
3718 break;
3719 }
3720 }
3721 }
3722 image=CompareImagesLayers(image,method,exception);
3723 if (image == (Image *) NULL)
3724 goto PerlException;
3725 for ( ; image; image=image->next)
3726 {
3727 AddImageToRegistry(sv,image);
3728 rv=newRV(sv);
3729 av_push(av,sv_bless(rv,hv));
3730 SvREFCNT_dec(sv);
3731 }
3732 exception=DestroyExceptionInfo(exception);
3733 ST(0)=av_reference;
3734 SvREFCNT_dec(perl_exception);
3735 XSRETURN(1);
3736
3737 PerlException:
3738 InheritPerlException(exception,perl_exception);
3739 exception=DestroyExceptionInfo(exception);
3740 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3741 SvPOK_on(perl_exception);
3742 ST(0)=sv_2mortal(perl_exception);
3743 XSRETURN(1);
3744 }
3745
3746#
3747###############################################################################
3748# #
3749# #
3750# #
3751# D e s t r o y #
3752# #
3753# #
3754# #
3755###############################################################################
3756#
3757#
3758void
3759DESTROY(ref)
3760 Image::Magick ref=NO_INIT
3761 PPCODE:
3762 {
3763 SV
3764 *reference;
3765
3766 PERL_UNUSED_VAR(ref);
3767 if (sv_isobject(ST(0)) == 0)
3768 croak("ReferenceIsNotMyType");
3769 reference=SvRV(ST(0));
3770 switch (SvTYPE(reference))
3771 {
3772 case SVt_PVAV:
3773 {
3774 char
cristy151b66d2015-04-15 10:50:31 +00003775 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003776
3777 const SV
3778 *key;
3779
3780 HV
3781 *hv;
3782
3783 GV
3784 **gvp;
3785
3786 struct PackageInfo
3787 *info;
3788
3789 SV
3790 *sv;
3791
3792 /*
3793 Array (AV *) reference
3794 */
cristy151b66d2015-04-15 10:50:31 +00003795 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003796 XS_VERSION,reference);
3797 hv=gv_stashpv(PackageName, FALSE);
3798 if (!hv)
3799 break;
3800 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3801 if (!gvp)
3802 break;
3803 sv=GvSV(*gvp);
3804 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3805 {
3806 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3807 DestroyPackageInfo(info);
3808 }
3809 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3810 (void) key;
3811 break;
3812 }
3813 case SVt_PVMG:
3814 {
3815 Image
3816 *image;
3817
3818 /*
3819 Blessed scalar = (Image *) SvIV(reference)
3820 */
3821 image=INT2PTR(Image *,SvIV(reference));
3822 if (image != (Image *) NULL)
3823 DeleteImageFromRegistry(reference,image);
3824 break;
3825 }
3826 default:
3827 break;
3828 }
3829 }
3830
3831#
3832###############################################################################
3833# #
3834# #
3835# #
3836# D i s p l a y #
3837# #
3838# #
3839# #
3840###############################################################################
3841#
3842#
3843void
3844Display(ref,...)
3845 Image::Magick ref=NO_INIT
3846 ALIAS:
3847 DisplayImage = 1
3848 display = 2
3849 displayimage = 3
3850 PPCODE:
3851 {
3852 ExceptionInfo
3853 *exception;
3854
3855 Image
3856 *image;
3857
3858 register ssize_t
3859 i;
3860
3861 struct PackageInfo
3862 *info,
3863 *package_info;
3864
3865 SV
3866 *perl_exception,
3867 *reference;
3868
3869 PERL_UNUSED_VAR(ref);
3870 PERL_UNUSED_VAR(ix);
3871 exception=AcquireExceptionInfo();
3872 perl_exception=newSVpv("",0);
3873 package_info=(struct PackageInfo *) NULL;
3874 if (sv_isobject(ST(0)) == 0)
3875 {
3876 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3877 PackageName);
3878 goto PerlException;
3879 }
3880 reference=SvRV(ST(0));
3881 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3882 if (image == (Image *) NULL)
3883 {
3884 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3885 PackageName);
3886 goto PerlException;
3887 }
3888 package_info=ClonePackageInfo(info,exception);
3889 if (items == 2)
3890 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3891 else
3892 if (items > 2)
3893 for (i=2; i < items; i+=2)
3894 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3895 exception);
3896 (void) DisplayImages(package_info->image_info,image,exception);
3897 (void) CatchImageException(image);
3898
3899 PerlException:
3900 if (package_info != (struct PackageInfo *) NULL)
3901 DestroyPackageInfo(package_info);
3902 InheritPerlException(exception,perl_exception);
3903 exception=DestroyExceptionInfo(exception);
3904 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3905 SvPOK_on(perl_exception);
3906 ST(0)=sv_2mortal(perl_exception);
3907 XSRETURN(1);
3908 }
3909
3910#
3911###############################################################################
3912# #
3913# #
3914# #
3915# E v a l u a t e I m a g e s #
3916# #
3917# #
3918# #
3919###############################################################################
3920#
3921#
3922void
3923EvaluateImages(ref)
3924 Image::Magick ref=NO_INIT
3925 ALIAS:
3926 EvaluateImages = 1
3927 evaluateimages = 2
3928 PPCODE:
3929 {
3930 AV
3931 *av;
3932
3933 char
3934 *attribute,
3935 *p;
3936
3937 ExceptionInfo
3938 *exception;
3939
3940 HV
3941 *hv;
3942
3943 Image
3944 *image;
3945
3946 MagickEvaluateOperator
3947 op;
3948
3949 register ssize_t
3950 i;
3951
3952 struct PackageInfo
3953 *info;
3954
3955 SV
3956 *perl_exception,
3957 *reference,
3958 *rv,
3959 *sv;
3960
3961 PERL_UNUSED_VAR(ref);
3962 PERL_UNUSED_VAR(ix);
3963 exception=AcquireExceptionInfo();
3964 perl_exception=newSVpv("",0);
3965 sv=NULL;
3966 if (sv_isobject(ST(0)) == 0)
3967 {
3968 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3969 PackageName);
3970 goto PerlException;
3971 }
3972 reference=SvRV(ST(0));
3973 hv=SvSTASH(reference);
3974 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3975 if (image == (Image *) NULL)
3976 {
3977 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3978 PackageName);
3979 goto PerlException;
3980 }
3981 op=MeanEvaluateOperator;
3982 if (items == 2)
3983 {
3984 ssize_t
3985 in;
3986
3987 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
3988 SvPV(ST(1),na));
3989 if (in < 0)
3990 {
3991 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3992 SvPV(ST(1),na));
3993 return;
3994 }
3995 op=(MagickEvaluateOperator) in;
3996 }
3997 else
3998 for (i=2; i < items; i+=2)
3999 {
4000 attribute=(char *) SvPV(ST(i-1),na);
4001 switch (*attribute)
4002 {
4003 case 'O':
4004 case 'o':
4005 {
4006 if (LocaleCompare(attribute,"operator") == 0)
4007 {
4008 ssize_t
4009 in;
4010
4011 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4012 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4013 if (in < 0)
4014 {
4015 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4016 SvPV(ST(i),na));
4017 return;
4018 }
4019 op=(MagickEvaluateOperator) in;
4020 break;
4021 }
4022 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4023 attribute);
4024 break;
4025 }
4026 default:
4027 {
4028 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4029 attribute);
4030 break;
4031 }
4032 }
4033 }
4034 image=EvaluateImages(image,op,exception);
4035 if (image == (Image *) NULL)
4036 goto PerlException;
4037 /*
4038 Create blessed Perl array for the returned image.
4039 */
4040 av=newAV();
4041 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4042 SvREFCNT_dec(av);
4043 AddImageToRegistry(sv,image);
4044 rv=newRV(sv);
4045 av_push(av,sv_bless(rv,hv));
4046 SvREFCNT_dec(sv);
4047 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004048 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4049 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004050 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4051 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004052 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004053 SetImageInfo(info->image_info,0,exception);
4054 exception=DestroyExceptionInfo(exception);
4055 SvREFCNT_dec(perl_exception);
4056 XSRETURN(1);
4057
4058 PerlException:
4059 InheritPerlException(exception,perl_exception);
4060 exception=DestroyExceptionInfo(exception);
4061 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4062 SvPOK_on(perl_exception);
4063 ST(0)=sv_2mortal(perl_exception);
4064 XSRETURN(1);
4065 }
4066
4067#
4068###############################################################################
4069# #
4070# #
4071# #
4072# F e a t u r e s #
4073# #
4074# #
4075# #
4076###############################################################################
4077#
4078#
4079void
4080Features(ref,...)
4081 Image::Magick ref=NO_INIT
4082 ALIAS:
4083 FeaturesImage = 1
4084 features = 2
4085 featuresimage = 3
4086 PPCODE:
4087 {
4088#define ChannelFeatures(channel,direction) \
4089{ \
cristy151b66d2015-04-15 10:50:31 +00004090 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004091 channel_features[channel].angular_second_moment[direction]); \
4092 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004093 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004094 channel_features[channel].contrast[direction]); \
4095 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004096 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004097 channel_features[channel].contrast[direction]); \
4098 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004099 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004100 channel_features[channel].variance_sum_of_squares[direction]); \
4101 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004102 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004103 channel_features[channel].inverse_difference_moment[direction]); \
4104 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004105 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004106 channel_features[channel].sum_average[direction]); \
4107 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004108 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004109 channel_features[channel].sum_variance[direction]); \
4110 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004111 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004112 channel_features[channel].sum_entropy[direction]); \
4113 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004114 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004115 channel_features[channel].entropy[direction]); \
4116 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004117 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004118 channel_features[channel].difference_variance[direction]); \
4119 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004120 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004121 channel_features[channel].difference_entropy[direction]); \
4122 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004123 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004124 channel_features[channel].measure_of_correlation_1[direction]); \
4125 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004126 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004127 channel_features[channel].measure_of_correlation_2[direction]); \
4128 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004129 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004130 channel_features[channel].maximum_correlation_coefficient[direction]); \
4131 PUSHs(sv_2mortal(newSVpv(message,0))); \
4132}
4133
4134 AV
4135 *av;
4136
4137 char
4138 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004139 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004140
4141 ChannelFeatures
4142 *channel_features;
4143
4144 double
4145 distance;
4146
4147 ExceptionInfo
4148 *exception;
4149
4150 Image
4151 *image;
4152
4153 register ssize_t
4154 i;
4155
4156 ssize_t
4157 count;
4158
4159 struct PackageInfo
4160 *info;
4161
4162 SV
4163 *perl_exception,
4164 *reference;
4165
4166 PERL_UNUSED_VAR(ref);
4167 PERL_UNUSED_VAR(ix);
4168 exception=AcquireExceptionInfo();
4169 perl_exception=newSVpv("",0);
4170 av=NULL;
4171 if (sv_isobject(ST(0)) == 0)
4172 {
4173 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4174 PackageName);
4175 goto PerlException;
4176 }
4177 reference=SvRV(ST(0));
4178 av=newAV();
4179 SvREFCNT_dec(av);
4180 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4181 if (image == (Image *) NULL)
4182 {
4183 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4184 PackageName);
4185 goto PerlException;
4186 }
cristy7dbd9262014-07-02 17:53:42 +00004187 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004188 for (i=2; i < items; i+=2)
4189 {
4190 attribute=(char *) SvPV(ST(i-1),na);
4191 switch (*attribute)
4192 {
4193 case 'D':
4194 case 'd':
4195 {
4196 if (LocaleCompare(attribute,"distance") == 0)
4197 {
4198 distance=StringToLong((char *) SvPV(ST(1),na));
4199 break;
4200 }
4201 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4202 attribute);
4203 break;
4204 }
4205 default:
4206 {
4207 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4208 attribute);
4209 break;
4210 }
4211 }
4212 }
4213 count=0;
4214 for ( ; image; image=image->next)
4215 {
4216 channel_features=GetImageFeatures(image,distance,exception);
4217 if (channel_features == (ChannelFeatures *) NULL)
4218 continue;
4219 count++;
cristyfcf3bdf2014-07-02 14:35:58 +00004220 EXTEND(sp,280*count);
cristy4a3ce0a2013-08-03 20:06:59 +00004221 for (i=0; i < 4; i++)
4222 {
4223 ChannelFeatures(RedChannel,i);
4224 ChannelFeatures(GreenChannel,i);
4225 ChannelFeatures(BlueChannel,i);
4226 if (image->colorspace == CMYKColorspace)
4227 ChannelFeatures(BlackChannel,i);
cristy17f11b02014-12-20 19:37:04 +00004228 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00004229 ChannelFeatures(AlphaChannel,i);
4230 }
4231 channel_features=(ChannelFeatures *)
4232 RelinquishMagickMemory(channel_features);
4233 }
4234
4235 PerlException:
4236 InheritPerlException(exception,perl_exception);
4237 exception=DestroyExceptionInfo(exception);
4238 SvREFCNT_dec(perl_exception);
4239 }
4240
4241#
4242###############################################################################
4243# #
4244# #
4245# #
4246# F l a t t e n #
4247# #
4248# #
4249# #
4250###############################################################################
4251#
4252#
4253void
4254Flatten(ref)
4255 Image::Magick ref=NO_INIT
4256 ALIAS:
4257 FlattenImage = 1
4258 flatten = 2
4259 flattenimage = 3
4260 PPCODE:
4261 {
4262 AV
4263 *av;
4264
4265 char
4266 *attribute,
4267 *p;
4268
4269 ExceptionInfo
4270 *exception;
4271
4272 HV
4273 *hv;
4274
4275 Image
4276 *image;
4277
4278 PixelInfo
4279 background_color;
4280
4281 register ssize_t
4282 i;
4283
4284 struct PackageInfo
4285 *info;
4286
4287 SV
4288 *perl_exception,
4289 *reference,
4290 *rv,
4291 *sv;
4292
4293 PERL_UNUSED_VAR(ref);
4294 PERL_UNUSED_VAR(ix);
4295 exception=AcquireExceptionInfo();
4296 perl_exception=newSVpv("",0);
4297 sv=NULL;
4298 if (sv_isobject(ST(0)) == 0)
4299 {
4300 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4301 PackageName);
4302 goto PerlException;
4303 }
4304 reference=SvRV(ST(0));
4305 hv=SvSTASH(reference);
4306 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4307 if (image == (Image *) NULL)
4308 {
4309 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4310 PackageName);
4311 goto PerlException;
4312 }
4313 background_color=image->background_color;
4314 if (items == 2)
4315 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4316 &background_color,exception);
4317 else
4318 for (i=2; i < items; i+=2)
4319 {
4320 attribute=(char *) SvPV(ST(i-1),na);
4321 switch (*attribute)
4322 {
4323 case 'B':
4324 case 'b':
4325 {
4326 if (LocaleCompare(attribute,"background") == 0)
4327 {
4328 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4329 AllCompliance,&background_color,exception);
4330 break;
4331 }
4332 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4333 attribute);
4334 break;
4335 }
4336 default:
4337 {
4338 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4339 attribute);
4340 break;
4341 }
4342 }
4343 }
4344 image->background_color=background_color;
4345 image=MergeImageLayers(image,FlattenLayer,exception);
4346 if (image == (Image *) NULL)
4347 goto PerlException;
4348 /*
4349 Create blessed Perl array for the returned image.
4350 */
4351 av=newAV();
4352 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4353 SvREFCNT_dec(av);
4354 AddImageToRegistry(sv,image);
4355 rv=newRV(sv);
4356 av_push(av,sv_bless(rv,hv));
4357 SvREFCNT_dec(sv);
4358 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004359 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4360 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004361 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4362 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004363 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004364 SetImageInfo(info->image_info,0,exception);
4365 exception=DestroyExceptionInfo(exception);
4366 SvREFCNT_dec(perl_exception);
4367 XSRETURN(1);
4368
4369 PerlException:
4370 InheritPerlException(exception,perl_exception);
4371 exception=DestroyExceptionInfo(exception);
4372 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4373 SvPOK_on(perl_exception); /* return messages in string context */
4374 ST(0)=sv_2mortal(perl_exception);
4375 XSRETURN(1);
4376 }
4377
4378#
4379###############################################################################
4380# #
4381# #
4382# #
4383# F x #
4384# #
4385# #
4386# #
4387###############################################################################
4388#
4389#
4390void
4391Fx(ref,...)
4392 Image::Magick ref=NO_INIT
4393 ALIAS:
4394 FxImage = 1
4395 fx = 2
4396 fximage = 3
4397 PPCODE:
4398 {
4399 AV
4400 *av;
4401
4402 char
4403 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004404 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004405
4406 ChannelType
4407 channel,
4408 channel_mask;
4409
4410 ExceptionInfo
4411 *exception;
4412
4413 HV
4414 *hv;
4415
4416 Image
4417 *image;
4418
4419 register ssize_t
4420 i;
4421
4422 struct PackageInfo
4423 *info;
4424
4425 SV
4426 *av_reference,
4427 *perl_exception,
4428 *reference,
4429 *rv,
4430 *sv;
4431
4432 PERL_UNUSED_VAR(ref);
4433 PERL_UNUSED_VAR(ix);
4434 exception=AcquireExceptionInfo();
4435 perl_exception=newSVpv("",0);
4436 sv=NULL;
4437 attribute=NULL;
4438 av=NULL;
4439 if (sv_isobject(ST(0)) == 0)
4440 {
4441 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4442 PackageName);
4443 goto PerlException;
4444 }
4445 reference=SvRV(ST(0));
4446 hv=SvSTASH(reference);
4447 av=newAV();
4448 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4449 SvREFCNT_dec(av);
4450 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4451 if (image == (Image *) NULL)
4452 {
4453 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4454 PackageName);
4455 goto PerlException;
4456 }
4457 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4458 /*
4459 Get options.
4460 */
4461 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004462 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004463 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004464 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004465 else
4466 for (i=2; i < items; i+=2)
4467 {
4468 attribute=(char *) SvPV(ST(i-1),na);
4469 switch (*attribute)
4470 {
4471 case 'C':
4472 case 'c':
4473 {
4474 if (LocaleCompare(attribute,"channel") == 0)
4475 {
4476 ssize_t
4477 option;
4478
4479 option=ParseChannelOption(SvPV(ST(i),na));
4480 if (option < 0)
4481 {
4482 ThrowPerlException(exception,OptionError,
4483 "UnrecognizedType",SvPV(ST(i),na));
4484 return;
4485 }
4486 channel=(ChannelType) option;
4487 break;
4488 }
4489 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4490 attribute);
4491 break;
4492 }
4493 case 'E':
4494 case 'e':
4495 {
4496 if (LocaleCompare(attribute,"expression") == 0)
4497 {
4498 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004499 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004500 break;
4501 }
4502 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4503 attribute);
4504 break;
4505 }
4506 default:
4507 {
4508 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4509 attribute);
4510 break;
4511 }
4512 }
4513 }
4514 channel_mask=SetImageChannelMask(image,channel);
4515 image=FxImage(image,expression,exception);
4516 if (image != (Image *) NULL)
4517 (void) SetImageChannelMask(image,channel_mask);
4518 if (image == (Image *) NULL)
4519 goto PerlException;
4520 for ( ; image; image=image->next)
4521 {
4522 AddImageToRegistry(sv,image);
4523 rv=newRV(sv);
4524 av_push(av,sv_bless(rv,hv));
4525 SvREFCNT_dec(sv);
4526 }
4527 exception=DestroyExceptionInfo(exception);
4528 ST(0)=av_reference;
4529 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4530 XSRETURN(1);
4531
4532 PerlException:
4533 InheritPerlException(exception,perl_exception);
4534 exception=DestroyExceptionInfo(exception);
4535 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4536 SvPOK_on(perl_exception);
4537 ST(0)=sv_2mortal(perl_exception);
4538 XSRETURN(1);
4539 }
4540
4541#
4542###############################################################################
4543# #
4544# #
4545# #
4546# G e t #
4547# #
4548# #
4549# #
4550###############################################################################
4551#
4552#
4553void
4554Get(ref,...)
4555 Image::Magick ref=NO_INIT
4556 ALIAS:
4557 GetAttributes = 1
4558 GetAttribute = 2
4559 get = 3
4560 getattributes = 4
4561 getattribute = 5
4562 PPCODE:
4563 {
4564 char
4565 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004566 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004567
4568 const char
4569 *value;
4570
4571 ExceptionInfo
4572 *exception;
4573
4574 Image
4575 *image;
4576
4577 long
4578 j;
4579
4580 register ssize_t
4581 i;
4582
4583 struct PackageInfo
4584 *info;
4585
4586 SV
4587 *perl_exception,
4588 *reference,
4589 *s;
4590
4591 PERL_UNUSED_VAR(ref);
4592 PERL_UNUSED_VAR(ix);
4593 exception=AcquireExceptionInfo();
4594 perl_exception=newSVpv("",0);
4595 if (sv_isobject(ST(0)) == 0)
4596 {
4597 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4598 PackageName);
4599 XSRETURN_EMPTY;
4600 }
4601 reference=SvRV(ST(0));
4602 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4603 if (image == (Image *) NULL && !info)
4604 XSRETURN_EMPTY;
4605 EXTEND(sp,items);
4606 for (i=1; i < items; i++)
4607 {
4608 attribute=(char *) SvPV(ST(i),na);
4609 s=NULL;
4610 switch (*attribute)
4611 {
4612 case 'A':
4613 case 'a':
4614 {
4615 if (LocaleCompare(attribute,"adjoin") == 0)
4616 {
4617 if (info)
4618 s=newSViv((ssize_t) info->image_info->adjoin);
4619 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4620 continue;
4621 }
4622 if (LocaleCompare(attribute,"antialias") == 0)
4623 {
4624 if (info)
4625 s=newSViv((ssize_t) info->image_info->antialias);
4626 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4627 continue;
4628 }
4629 if (LocaleCompare(attribute,"area") == 0)
4630 {
4631 s=newSViv(GetMagickResource(AreaResource));
4632 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4633 continue;
4634 }
4635 if (LocaleCompare(attribute,"attenuate") == 0)
4636 {
4637 const char
4638 *value;
4639
4640 value=GetImageProperty(image,attribute,exception);
4641 if (value != (const char *) NULL)
4642 s=newSVpv(value,0);
4643 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4644 continue;
4645 }
4646 if (LocaleCompare(attribute,"authenticate") == 0)
4647 {
4648 if (info)
4649 {
4650 const char
4651 *option;
4652
4653 option=GetImageOption(info->image_info,attribute);
4654 if (option != (const char *) NULL)
4655 s=newSVpv(option,0);
4656 }
4657 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4658 continue;
4659 }
4660 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4661 attribute);
4662 break;
4663 }
4664 case 'B':
4665 case 'b':
4666 {
4667 if (LocaleCompare(attribute,"background") == 0)
4668 {
4669 if (image == (Image *) NULL)
4670 break;
cristy151b66d2015-04-15 10:50:31 +00004671 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004672 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4673 (double) image->background_color.green,
4674 (double) image->background_color.blue,
4675 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004676 s=newSVpv(color,0);
4677 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4678 continue;
4679 }
4680 if (LocaleCompare(attribute,"base-columns") == 0)
4681 {
4682 if (image != (Image *) NULL)
4683 s=newSViv((ssize_t) image->magick_columns);
4684 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4685 continue;
4686 }
4687 if (LocaleCompare(attribute,"base-filename") == 0)
4688 {
4689 if (image != (Image *) NULL)
4690 s=newSVpv(image->magick_filename,0);
4691 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4692 continue;
4693 }
4694 if (LocaleCompare(attribute,"base-height") == 0)
4695 {
4696 if (image != (Image *) NULL)
4697 s=newSViv((ssize_t) image->magick_rows);
4698 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4699 continue;
4700 }
4701 if (LocaleCompare(attribute,"base-rows") == 0)
4702 {
4703 if (image != (Image *) NULL)
4704 s=newSViv((ssize_t) image->magick_rows);
4705 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4706 continue;
4707 }
4708 if (LocaleCompare(attribute,"base-width") == 0)
4709 {
4710 if (image != (Image *) NULL)
4711 s=newSViv((ssize_t) image->magick_columns);
4712 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4713 continue;
4714 }
4715 if (LocaleCompare(attribute,"blue-primary") == 0)
4716 {
4717 if (image == (Image *) NULL)
4718 break;
cristy151b66d2015-04-15 10:50:31 +00004719 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00004720 image->chromaticity.blue_primary.x,
4721 image->chromaticity.blue_primary.y);
4722 s=newSVpv(color,0);
4723 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4724 continue;
4725 }
4726 if (LocaleCompare(attribute,"bordercolor") == 0)
4727 {
4728 if (image == (Image *) NULL)
4729 break;
cristy151b66d2015-04-15 10:50:31 +00004730 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004731 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4732 (double) image->border_color.green,
4733 (double) image->border_color.blue,
4734 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004735 s=newSVpv(color,0);
4736 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4737 continue;
4738 }
4739 if (LocaleCompare(attribute,"bounding-box") == 0)
4740 {
4741 char
cristy151b66d2015-04-15 10:50:31 +00004742 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004743
4744 RectangleInfo
4745 page;
4746
4747 if (image == (Image *) NULL)
4748 break;
4749 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004750 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004751 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4752 page.height,(double) page.x,(double) page.y);
4753 s=newSVpv(geometry,0);
4754 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4755 continue;
4756 }
4757 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4758 attribute);
4759 break;
4760 }
4761 case 'C':
4762 case 'c':
4763 {
4764 if (LocaleCompare(attribute,"class") == 0)
4765 {
4766 if (image == (Image *) NULL)
4767 break;
4768 s=newSViv(image->storage_class);
4769 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4770 image->storage_class));
4771 SvIOK_on(s);
4772 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4773 continue;
4774 }
4775 if (LocaleCompare(attribute,"clip-mask") == 0)
4776 {
4777 if (image != (Image *) NULL)
4778 {
4779 Image
4780 *mask_image;
4781
4782 SV
4783 *sv;
4784
4785 sv=NULL;
4786 if (image->read_mask == MagickFalse)
4787 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004788 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004789 if (mask_image != (Image *) NULL)
4790 {
4791 AddImageToRegistry(sv,mask_image);
4792 s=sv_bless(newRV(sv),SvSTASH(reference));
4793 }
4794 }
4795 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4796 continue;
4797 }
4798 if (LocaleCompare(attribute,"clip-path") == 0)
4799 {
4800 if (image != (Image *) NULL)
4801 {
4802 Image
4803 *mask_image;
4804
4805 SV
4806 *sv;
4807
4808 sv=NULL;
4809 if (image->read_mask != MagickFalse)
4810 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004811 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004812 if (mask_image != (Image *) NULL)
4813 {
4814 AddImageToRegistry(sv,mask_image);
4815 s=sv_bless(newRV(sv),SvSTASH(reference));
4816 }
4817 }
4818 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4819 continue;
4820 }
4821 if (LocaleCompare(attribute,"compression") == 0)
4822 {
4823 j=info ? info->image_info->compression : image ?
4824 image->compression : UndefinedCompression;
4825 if (info)
4826 if (info->image_info->compression == UndefinedCompression)
4827 j=image->compression;
4828 s=newSViv(j);
4829 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4830 j));
4831 SvIOK_on(s);
4832 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4833 continue;
4834 }
4835 if (LocaleCompare(attribute,"colorspace") == 0)
4836 {
4837 j=image ? image->colorspace : RGBColorspace;
4838 s=newSViv(j);
4839 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4840 j));
4841 SvIOK_on(s);
4842 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4843 continue;
4844 }
4845 if (LocaleCompare(attribute,"colors") == 0)
4846 {
4847 if (image != (Image *) NULL)
4848 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4849 exception));
4850 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4851 continue;
4852 }
4853 if (LocaleNCompare(attribute,"colormap",8) == 0)
4854 {
4855 int
4856 items;
4857
4858 if (image == (Image *) NULL || !image->colormap)
4859 break;
4860 j=0;
4861 items=sscanf(attribute,"%*[^[][%ld",&j);
4862 (void) items;
4863 if (j > (ssize_t) image->colors)
4864 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004865 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004866 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4867 (double) image->colormap[j].green,
4868 (double) image->colormap[j].blue,
4869 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004870 s=newSVpv(color,0);
4871 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4872 continue;
4873 }
4874 if (LocaleCompare(attribute,"columns") == 0)
4875 {
4876 if (image != (Image *) NULL)
4877 s=newSViv((ssize_t) image->columns);
4878 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4879 continue;
4880 }
4881 if (LocaleCompare(attribute,"comment") == 0)
4882 {
4883 const char
4884 *value;
4885
4886 value=GetImageProperty(image,attribute,exception);
4887 if (value != (const char *) NULL)
4888 s=newSVpv(value,0);
4889 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4890 continue;
4891 }
4892 if (LocaleCompare(attribute,"copyright") == 0)
4893 {
4894 s=newSVpv(GetMagickCopyright(),0);
4895 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4896 continue;
4897 }
4898 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4899 attribute);
4900 break;
4901 }
4902 case 'D':
4903 case 'd':
4904 {
4905 if (LocaleCompare(attribute,"density") == 0)
4906 {
4907 char
cristy151b66d2015-04-15 10:50:31 +00004908 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004909
4910 if (image == (Image *) NULL)
4911 break;
cristy151b66d2015-04-15 10:50:31 +00004912 (void) FormatLocaleString(geometry,MagickPathExtent,"%.15gx%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00004913 image->resolution.x,image->resolution.y);
4914 s=newSVpv(geometry,0);
4915 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4916 continue;
4917 }
4918 if (LocaleCompare(attribute,"delay") == 0)
4919 {
4920 if (image != (Image *) NULL)
4921 s=newSViv((ssize_t) image->delay);
4922 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4923 continue;
4924 }
4925 if (LocaleCompare(attribute,"depth") == 0)
4926 {
4927 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4928 if (image != (Image *) NULL)
4929 s=newSViv((ssize_t) GetImageDepth(image,exception));
4930 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4931 continue;
4932 }
4933 if (LocaleCompare(attribute,"directory") == 0)
4934 {
4935 if (image && image->directory)
4936 s=newSVpv(image->directory,0);
4937 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4938 continue;
4939 }
4940 if (LocaleCompare(attribute,"dispose") == 0)
4941 {
4942 if (image == (Image *) NULL)
4943 break;
4944
4945 s=newSViv(image->dispose);
4946 (void) sv_setpv(s,
4947 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
4948 SvIOK_on(s);
4949 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4950 continue;
4951 }
4952 if (LocaleCompare(attribute,"disk") == 0)
4953 {
4954 s=newSViv(GetMagickResource(DiskResource));
4955 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4956 continue;
4957 }
4958 if (LocaleCompare(attribute,"dither") == 0)
4959 {
4960 if (info)
4961 s=newSViv((ssize_t) info->image_info->dither);
4962 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4963 continue;
4964 }
4965 if (LocaleCompare(attribute,"display") == 0) /* same as server */
4966 {
4967 if (info && info->image_info->server_name)
4968 s=newSVpv(info->image_info->server_name,0);
4969 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4970 continue;
4971 }
4972 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4973 attribute);
4974 break;
4975 }
4976 case 'E':
4977 case 'e':
4978 {
4979 if (LocaleCompare(attribute,"elapsed-time") == 0)
4980 {
4981 if (image != (Image *) NULL)
4982 s=newSVnv(GetElapsedTime(&image->timer));
4983 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4984 continue;
4985 }
4986 if (LocaleCompare(attribute,"endian") == 0)
4987 {
4988 j=info ? info->image_info->endian : image ? image->endian :
4989 UndefinedEndian;
4990 s=newSViv(j);
4991 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
4992 SvIOK_on(s);
4993 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4994 continue;
4995 }
4996 if (LocaleCompare(attribute,"error") == 0)
4997 {
4998 if (image != (Image *) NULL)
4999 s=newSVnv(image->error.mean_error_per_pixel);
5000 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5001 continue;
5002 }
5003 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5004 attribute);
5005 break;
5006 }
5007 case 'F':
5008 case 'f':
5009 {
5010 if (LocaleCompare(attribute,"filesize") == 0)
5011 {
5012 if (image != (Image *) NULL)
5013 s=newSViv((ssize_t) GetBlobSize(image));
5014 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5015 continue;
5016 }
5017 if (LocaleCompare(attribute,"filename") == 0)
5018 {
5019 if (info && info->image_info->filename &&
5020 *info->image_info->filename)
5021 s=newSVpv(info->image_info->filename,0);
5022 if (image != (Image *) NULL)
5023 s=newSVpv(image->filename,0);
5024 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5025 continue;
5026 }
5027 if (LocaleCompare(attribute,"filter") == 0)
5028 {
5029 s=image ? newSViv(image->filter) : newSViv(0);
5030 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5031 image->filter));
5032 SvIOK_on(s);
5033 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5034 continue;
5035 }
5036 if (LocaleCompare(attribute,"font") == 0)
5037 {
5038 if (info && info->image_info->font)
5039 s=newSVpv(info->image_info->font,0);
5040 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5041 continue;
5042 }
5043 if (LocaleCompare(attribute,"foreground") == 0)
5044 continue;
5045 if (LocaleCompare(attribute,"format") == 0)
5046 {
5047 const MagickInfo
5048 *magick_info;
5049
5050 magick_info=(const MagickInfo *) NULL;
5051 if (info && (*info->image_info->magick != '\0'))
5052 magick_info=GetMagickInfo(info->image_info->magick,exception);
5053 if (image != (Image *) NULL)
5054 magick_info=GetMagickInfo(image->magick,exception);
5055 if ((magick_info != (const MagickInfo *) NULL) &&
5056 (*magick_info->description != '\0'))
5057 s=newSVpv((char *) magick_info->description,0);
5058 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5059 continue;
5060 }
5061 if (LocaleCompare(attribute,"fuzz") == 0)
5062 {
5063 if (info)
5064 s=newSVnv(info->image_info->fuzz);
5065 if (image != (Image *) NULL)
5066 s=newSVnv(image->fuzz);
5067 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5068 continue;
5069 }
5070 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5071 attribute);
5072 break;
5073 }
5074 case 'G':
5075 case 'g':
5076 {
5077 if (LocaleCompare(attribute,"gamma") == 0)
5078 {
5079 if (image != (Image *) NULL)
5080 s=newSVnv(image->gamma);
5081 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5082 continue;
5083 }
5084 if (LocaleCompare(attribute,"geometry") == 0)
5085 {
5086 if (image && image->geometry)
5087 s=newSVpv(image->geometry,0);
5088 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5089 continue;
5090 }
5091 if (LocaleCompare(attribute,"gravity") == 0)
5092 {
5093 s=image ? newSViv(image->gravity) : newSViv(0);
5094 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5095 image->gravity));
5096 SvIOK_on(s);
5097 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5098 continue;
5099 }
5100 if (LocaleCompare(attribute,"green-primary") == 0)
5101 {
5102 if (image == (Image *) NULL)
5103 break;
cristy151b66d2015-04-15 10:50:31 +00005104 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005105 image->chromaticity.green_primary.x,
5106 image->chromaticity.green_primary.y);
5107 s=newSVpv(color,0);
5108 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5109 continue;
5110 }
5111 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5112 attribute);
5113 break;
5114 }
5115 case 'H':
5116 case 'h':
5117 {
5118 if (LocaleCompare(attribute,"height") == 0)
5119 {
5120 if (image != (Image *) NULL)
5121 s=newSViv((ssize_t) image->rows);
5122 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5123 continue;
5124 }
5125 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5126 attribute);
5127 break;
5128 }
5129 case 'I':
5130 case 'i':
5131 {
5132 if (LocaleCompare(attribute,"icc") == 0)
5133 {
5134 if (image != (Image *) NULL)
5135 {
5136 const StringInfo
5137 *profile;
5138
5139 profile=GetImageProfile(image,"icc");
5140 if (profile != (StringInfo *) NULL)
5141 s=newSVpv((const char *) GetStringInfoDatum(profile),
5142 GetStringInfoLength(profile));
5143 }
5144 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5145 continue;
5146 }
5147 if (LocaleCompare(attribute,"icm") == 0)
5148 {
5149 if (image != (Image *) NULL)
5150 {
5151 const StringInfo
5152 *profile;
5153
5154 profile=GetImageProfile(image,"icm");
5155 if (profile != (const StringInfo *) NULL)
5156 s=newSVpv((const char *) GetStringInfoDatum(profile),
5157 GetStringInfoLength(profile));
5158 }
5159 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5160 continue;
5161 }
5162 if (LocaleCompare(attribute,"id") == 0)
5163 {
5164 if (image != (Image *) NULL)
5165 {
5166 char
cristy151b66d2015-04-15 10:50:31 +00005167 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005168
5169 MagickBooleanType
5170 status;
5171
5172 static ssize_t
5173 id = 0;
5174
cristy151b66d2015-04-15 10:50:31 +00005175 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005176 id);
5177 status=SetImageRegistry(ImageRegistryType,key,image,
5178 exception);
5179 (void) status;
5180 s=newSViv(id++);
5181 }
5182 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5183 continue;
5184 }
5185 if (LocaleNCompare(attribute,"index",5) == 0)
5186 {
5187 char
cristy151b66d2015-04-15 10:50:31 +00005188 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005189
5190 int
5191 items;
5192
5193 long
5194 x,
5195 y;
5196
5197 register const Quantum
5198 *p;
5199
5200 CacheView
5201 *image_view;
5202
5203 if (image == (Image *) NULL)
5204 break;
5205 if (image->storage_class != PseudoClass)
5206 break;
5207 x=0;
5208 y=0;
5209 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5210 (void) items;
5211 image_view=AcquireVirtualCacheView(image,exception);
5212 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5213 if (p != (const Quantum *) NULL)
5214 {
cristy151b66d2015-04-15 10:50:31 +00005215 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005216 GetPixelIndex(image,p));
5217 s=newSVpv(name,0);
5218 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5219 }
5220 image_view=DestroyCacheView(image_view);
5221 continue;
5222 }
5223 if (LocaleCompare(attribute,"iptc") == 0)
5224 {
5225 if (image != (Image *) NULL)
5226 {
5227 const StringInfo
5228 *profile;
5229
5230 profile=GetImageProfile(image,"iptc");
5231 if (profile != (const StringInfo *) NULL)
5232 s=newSVpv((const char *) GetStringInfoDatum(profile),
5233 GetStringInfoLength(profile));
5234 }
5235 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5236 continue;
5237 }
5238 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5239 {
5240 if (image != (Image *) NULL)
5241 s=newSViv((ssize_t) image->iterations);
5242 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5243 continue;
5244 }
5245 if (LocaleCompare(attribute,"interlace") == 0)
5246 {
5247 j=info ? info->image_info->interlace : image ? image->interlace :
5248 UndefinedInterlace;
5249 s=newSViv(j);
5250 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5251 j));
5252 SvIOK_on(s);
5253 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5254 continue;
5255 }
5256 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5257 attribute);
5258 break;
5259 }
5260 case 'L':
5261 case 'l':
5262 {
5263 if (LocaleCompare(attribute,"label") == 0)
5264 {
5265 const char
5266 *value;
5267
5268 if (image == (Image *) NULL)
5269 break;
5270 value=GetImageProperty(image,"Label",exception);
5271 if (value != (const char *) NULL)
5272 s=newSVpv(value,0);
5273 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5274 continue;
5275 }
5276 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5277 {
5278 if (image != (Image *) NULL)
5279 s=newSViv((ssize_t) image->iterations);
5280 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5281 continue;
5282 }
5283 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5284 attribute);
5285 break;
5286 }
5287 case 'M':
5288 case 'm':
5289 {
5290 if (LocaleCompare(attribute,"magick") == 0)
5291 {
5292 if (info && *info->image_info->magick)
5293 s=newSVpv(info->image_info->magick,0);
5294 if (image != (Image *) NULL)
5295 s=newSVpv(image->magick,0);
5296 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5297 continue;
5298 }
5299 if (LocaleCompare(attribute,"map") == 0)
5300 {
5301 s=newSViv(GetMagickResource(MapResource));
5302 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5303 continue;
5304 }
5305 if (LocaleCompare(attribute,"maximum-error") == 0)
5306 {
5307 if (image != (Image *) NULL)
5308 s=newSVnv(image->error.normalized_maximum_error);
5309 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5310 continue;
5311 }
5312 if (LocaleCompare(attribute,"memory") == 0)
5313 {
5314 s=newSViv(GetMagickResource(MemoryResource));
5315 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5316 continue;
5317 }
5318 if (LocaleCompare(attribute,"mean-error") == 0)
5319 {
5320 if (image != (Image *) NULL)
5321 s=newSVnv(image->error.normalized_mean_error);
5322 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5323 continue;
5324 }
5325 if (LocaleCompare(attribute,"mime") == 0)
5326 {
5327 if (info && *info->image_info->magick)
5328 s=newSVpv(MagickToMime(info->image_info->magick),0);
5329 if (image != (Image *) NULL)
5330 s=newSVpv(MagickToMime(image->magick),0);
5331 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5332 continue;
5333 }
5334 if (LocaleCompare(attribute,"mattecolor") == 0)
5335 {
5336 if (image == (Image *) NULL)
5337 break;
cristy151b66d2015-04-15 10:50:31 +00005338 (void) FormatLocaleString(color,MagickPathExtent,
Cristy8645e042016-02-03 16:35:29 -05005339 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5340 (double) image->alpha_color.green,
5341 (double) image->alpha_color.blue,
5342 (double) image->alpha_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005343 s=newSVpv(color,0);
5344 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5345 continue;
5346 }
5347 if (LocaleCompare(attribute,"matte") == 0)
5348 {
5349 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005350 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005351 1 : 0);
5352 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5353 continue;
5354 }
5355 if (LocaleCompare(attribute,"mime") == 0)
5356 {
5357 const char
5358 *magick;
5359
5360 magick=NULL;
5361 if (info && *info->image_info->magick)
5362 magick=info->image_info->magick;
5363 if (image != (Image *) NULL)
5364 magick=image->magick;
5365 if (magick)
5366 {
5367 char
5368 *mime;
5369
5370 mime=MagickToMime(magick);
5371 s=newSVpv(mime,0);
5372 mime=(char *) RelinquishMagickMemory(mime);
5373 }
5374 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5375 continue;
5376 }
5377 if (LocaleCompare(attribute,"monochrome") == 0)
5378 {
5379 if (image == (Image *) NULL)
5380 continue;
5381 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005382 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005383 s=newSViv(j);
5384 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5385 continue;
5386 }
5387 if (LocaleCompare(attribute,"montage") == 0)
5388 {
5389 if (image && image->montage)
5390 s=newSVpv(image->montage,0);
5391 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5392 continue;
5393 }
5394 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5395 attribute);
5396 break;
5397 }
5398 case 'O':
5399 case 'o':
5400 {
5401 if (LocaleCompare(attribute,"orientation") == 0)
5402 {
5403 j=info ? info->image_info->orientation : image ?
5404 image->orientation : UndefinedOrientation;
5405 s=newSViv(j);
5406 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5407 j));
5408 SvIOK_on(s);
5409 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5410 continue;
5411 }
5412 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5413 attribute);
5414 break;
5415 }
5416 case 'P':
5417 case 'p':
5418 {
5419 if (LocaleCompare(attribute,"page") == 0)
5420 {
5421 if (info && info->image_info->page)
5422 s=newSVpv(info->image_info->page,0);
5423 if (image != (Image *) NULL)
5424 {
5425 char
cristy151b66d2015-04-15 10:50:31 +00005426 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005427
cristy151b66d2015-04-15 10:50:31 +00005428 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005429 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5430 (double) image->page.height,(double) image->page.x,(double)
5431 image->page.y);
5432 s=newSVpv(geometry,0);
5433 }
5434 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5435 continue;
5436 }
5437 if (LocaleCompare(attribute,"page.x") == 0)
5438 {
5439 if (image != (Image *) NULL)
5440 s=newSViv((ssize_t) image->page.x);
5441 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5442 continue;
5443 }
5444 if (LocaleCompare(attribute,"page.y") == 0)
5445 {
5446 if (image != (Image *) NULL)
5447 s=newSViv((ssize_t) image->page.y);
5448 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5449 continue;
5450 }
5451 if (LocaleNCompare(attribute,"pixel",5) == 0)
5452 {
5453 char
cristy151b66d2015-04-15 10:50:31 +00005454 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005455
5456 int
5457 items;
5458
5459 long
5460 x,
5461 y;
5462
5463 register const Quantum
5464 *p;
5465
5466 if (image == (Image *) NULL)
5467 break;
5468 x=0;
5469 y=0;
5470 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5471 (void) items;
5472 p=GetVirtualPixels(image,x,y,1,1,exception);
5473 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005474 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005475 QuantumFormat "," QuantumFormat "," QuantumFormat,
5476 GetPixelRed(image,p),GetPixelGreen(image,p),
5477 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5478 else
cristy151b66d2015-04-15 10:50:31 +00005479 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005480 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5481 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5482 GetPixelBlue(image,p),GetPixelBlack(image,p),
5483 GetPixelAlpha(image,p));
5484 s=newSVpv(tuple,0);
5485 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5486 continue;
5487 }
5488 if (LocaleCompare(attribute,"pointsize") == 0)
5489 {
5490 if (info)
5491 s=newSViv((ssize_t) info->image_info->pointsize);
5492 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5493 continue;
5494 }
5495 if (LocaleCompare(attribute,"preview") == 0)
5496 {
5497 s=newSViv(info->image_info->preview_type);
5498 (void) sv_setpv(s,CommandOptionToMnemonic(MagickPreviewOptions,
5499 info->image_info->preview_type));
5500 SvIOK_on(s);
5501 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5502 continue;
5503 }
5504 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5505 attribute);
5506 break;
5507 }
5508 case 'Q':
5509 case 'q':
5510 {
5511 if (LocaleCompare(attribute,"quality") == 0)
5512 {
5513 if (info)
5514 s=newSViv((ssize_t) info->image_info->quality);
5515 if (image != (Image *) NULL)
5516 s=newSViv((ssize_t) image->quality);
5517 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5518 continue;
5519 }
5520 if (LocaleCompare(attribute,"quantum") == 0)
5521 {
5522 if (info)
5523 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5524 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5525 continue;
5526 }
5527 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5528 attribute);
5529 break;
5530 }
5531 case 'R':
5532 case 'r':
5533 {
5534 if (LocaleCompare(attribute,"rendering-intent") == 0)
5535 {
5536 s=newSViv(image->rendering_intent);
5537 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5538 image->rendering_intent));
5539 SvIOK_on(s);
5540 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5541 continue;
5542 }
5543 if (LocaleCompare(attribute,"red-primary") == 0)
5544 {
5545 if (image == (Image *) NULL)
5546 break;
cristy151b66d2015-04-15 10:50:31 +00005547 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005548 image->chromaticity.red_primary.x,
5549 image->chromaticity.red_primary.y);
5550 s=newSVpv(color,0);
5551 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5552 continue;
5553 }
5554 if (LocaleCompare(attribute,"rows") == 0)
5555 {
5556 if (image != (Image *) NULL)
5557 s=newSViv((ssize_t) image->rows);
5558 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5559 continue;
5560 }
5561 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5562 attribute);
5563 break;
5564 }
5565 case 'S':
5566 case 's':
5567 {
5568 if (LocaleCompare(attribute,"sampling-factor") == 0)
5569 {
5570 if (info && info->image_info->sampling_factor)
5571 s=newSVpv(info->image_info->sampling_factor,0);
5572 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5573 continue;
5574 }
5575 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5576 {
5577 if (info && info->image_info->server_name)
5578 s=newSVpv(info->image_info->server_name,0);
5579 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5580 continue;
5581 }
5582 if (LocaleCompare(attribute,"size") == 0)
5583 {
5584 if (info && info->image_info->size)
5585 s=newSVpv(info->image_info->size,0);
5586 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5587 continue;
5588 }
5589 if (LocaleCompare(attribute,"scene") == 0)
5590 {
5591 if (image != (Image *) NULL)
5592 s=newSViv((ssize_t) image->scene);
5593 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5594 continue;
5595 }
5596 if (LocaleCompare(attribute,"scenes") == 0)
5597 {
5598 if (image != (Image *) NULL)
5599 s=newSViv((ssize_t) info->image_info->number_scenes);
5600 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5601 continue;
5602 }
5603 if (LocaleCompare(attribute,"signature") == 0)
5604 {
5605 const char
5606 *value;
5607
5608 if (image == (Image *) NULL)
5609 break;
5610 (void) SignatureImage(image,exception);
5611 value=GetImageProperty(image,"Signature",exception);
5612 if (value != (const char *) NULL)
5613 s=newSVpv(value,0);
5614 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5615 continue;
5616 }
5617 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5618 attribute);
5619 break;
5620 }
5621 case 'T':
5622 case 't':
5623 {
5624 if (LocaleCompare(attribute,"taint") == 0)
5625 {
5626 if (image != (Image *) NULL)
5627 s=newSViv((ssize_t) IsTaintImage(image));
5628 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5629 continue;
5630 }
5631 if (LocaleCompare(attribute,"texture") == 0)
5632 {
5633 if (info && info->image_info->texture)
5634 s=newSVpv(info->image_info->texture,0);
5635 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5636 continue;
5637 }
5638 if (LocaleCompare(attribute,"total-ink-density") == 0)
5639 {
5640 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5641 if (image != (Image *) NULL)
5642 s=newSVnv(GetImageTotalInkDensity(image,exception));
5643 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5644 continue;
5645 }
5646 if (LocaleCompare(attribute,"transparent-color") == 0)
5647 {
5648 if (image == (Image *) NULL)
5649 break;
cristy151b66d2015-04-15 10:50:31 +00005650 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005651 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5652 (double) image->transparent_color.green,
5653 (double) image->transparent_color.blue,
5654 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005655 s=newSVpv(color,0);
5656 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5657 continue;
5658 }
5659 if (LocaleCompare(attribute,"type") == 0)
5660 {
5661 if (image == (Image *) NULL)
5662 break;
cristya26f54c2015-07-29 12:26:12 +00005663 j=(ssize_t) GetImageType(image);
cristy4a3ce0a2013-08-03 20:06:59 +00005664 s=newSViv(j);
5665 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5666 SvIOK_on(s);
5667 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5668 continue;
5669 }
5670 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5671 attribute);
5672 break;
5673 }
5674 case 'U':
5675 case 'u':
5676 {
5677 if (LocaleCompare(attribute,"units") == 0)
5678 {
5679 j=info ? info->image_info->units : image ? image->units :
5680 UndefinedResolution;
5681 if (info && (info->image_info->units == UndefinedResolution))
5682 if (image)
5683 j=image->units;
5684 if (j == UndefinedResolution)
5685 s=newSVpv("undefined units",0);
5686 else
5687 if (j == PixelsPerInchResolution)
5688 s=newSVpv("pixels / inch",0);
5689 else
5690 s=newSVpv("pixels / centimeter",0);
5691 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5692 continue;
5693 }
5694 if (LocaleCompare(attribute,"user-time") == 0)
5695 {
5696 if (image != (Image *) NULL)
5697 s=newSVnv(GetUserTime(&image->timer));
5698 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5699 continue;
5700 }
5701 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5702 attribute);
5703 break;
5704 }
5705 case 'V':
5706 case 'v':
5707 {
5708 if (LocaleCompare(attribute,"verbose") == 0)
5709 {
5710 if (info)
5711 s=newSViv((ssize_t) info->image_info->verbose);
5712 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5713 continue;
5714 }
5715 if (LocaleCompare(attribute,"version") == 0)
5716 {
5717 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5718 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5719 continue;
5720 }
cristy4a3ce0a2013-08-03 20:06:59 +00005721 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5722 {
5723 if (image == (Image *) NULL)
5724 break;
5725 j=(ssize_t) GetImageVirtualPixelMethod(image);
5726 s=newSViv(j);
5727 (void) sv_setpv(s,CommandOptionToMnemonic(
5728 MagickVirtualPixelOptions,j));
5729 SvIOK_on(s);
5730 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5731 continue;
5732 }
5733 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5734 attribute);
5735 break;
5736 }
5737 case 'W':
5738 case 'w':
5739 {
5740 if (LocaleCompare(attribute,"white-point") == 0)
5741 {
5742 if (image == (Image *) NULL)
5743 break;
cristy151b66d2015-04-15 10:50:31 +00005744 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005745 image->chromaticity.white_point.x,
5746 image->chromaticity.white_point.y);
5747 s=newSVpv(color,0);
5748 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5749 continue;
5750 }
5751 if (LocaleCompare(attribute,"width") == 0)
5752 {
5753 if (image != (Image *) NULL)
5754 s=newSViv((ssize_t) image->columns);
5755 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5756 continue;
5757 }
5758 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5759 attribute);
5760 break;
5761 }
5762 case 'X':
5763 case 'x':
5764 {
Cristyc1f9f9f2016-01-05 08:19:28 -05005765 if (LocaleCompare(attribute,"xmp") == 0)
5766 {
5767 if (image != (Image *) NULL)
5768 {
5769 const StringInfo
5770 *profile;
5771
5772 profile=GetImageProfile(image,"xmp");
5773 if (profile != (StringInfo *) NULL)
5774 s=newSVpv((const char *) GetStringInfoDatum(profile),
5775 GetStringInfoLength(profile));
5776 }
5777 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5778 continue;
5779 }
cristy4a3ce0a2013-08-03 20:06:59 +00005780 if (LocaleCompare(attribute,"x-resolution") == 0)
5781 {
5782 if (image != (Image *) NULL)
5783 s=newSVnv(image->resolution.x);
5784 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5785 continue;
5786 }
5787 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5788 attribute);
5789 break;
5790 }
5791 case 'Y':
5792 case 'y':
5793 {
5794 if (LocaleCompare(attribute,"y-resolution") == 0)
5795 {
5796 if (image != (Image *) NULL)
5797 s=newSVnv(image->resolution.y);
5798 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5799 continue;
5800 }
5801 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5802 attribute);
5803 break;
5804 }
5805 default:
5806 break;
5807 }
5808 if (image == (Image *) NULL)
5809 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5810 attribute)
5811 else
5812 {
5813 value=GetImageProperty(image,attribute,exception);
5814 if (value != (const char *) NULL)
5815 {
5816 s=newSVpv(value,0);
5817 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5818 }
5819 else
5820 if (*attribute != '%')
5821 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5822 attribute)
5823 else
5824 {
5825 char
5826 *meta;
5827
5828 meta=InterpretImageProperties(info ? info->image_info :
5829 (ImageInfo *) NULL,image,attribute,exception);
5830 s=newSVpv(meta,0);
5831 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5832 meta=(char *) RelinquishMagickMemory(meta);
5833 }
5834 }
5835 }
5836 exception=DestroyExceptionInfo(exception);
5837 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5838 }
5839
5840#
5841###############################################################################
5842# #
5843# #
5844# #
5845# G e t A u t h e n t i c P i x e l s #
5846# #
5847# #
5848# #
5849###############################################################################
5850#
5851#
5852void *
5853GetAuthenticPixels(ref,...)
5854 Image::Magick ref = NO_INIT
5855 ALIAS:
5856 getauthenticpixels = 1
5857 GetImagePixels = 2
5858 getimagepixels = 3
5859 CODE:
5860 {
5861 char
5862 *attribute;
5863
5864 ExceptionInfo
5865 *exception;
5866
5867 Image
5868 *image;
5869
5870 RectangleInfo
5871 region;
5872
5873 ssize_t
5874 i;
5875
5876 struct PackageInfo
5877 *info;
5878
5879 SV
5880 *perl_exception,
5881 *reference;
5882
5883 void
5884 *blob = NULL;
5885
5886 PERL_UNUSED_VAR(ref);
5887 PERL_UNUSED_VAR(ix);
5888 exception=AcquireExceptionInfo();
5889 perl_exception=newSVpv("",0);
5890 if (sv_isobject(ST(0)) == 0)
5891 {
5892 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5893 PackageName);
5894 goto PerlException;
5895 }
5896 reference=SvRV(ST(0));
5897
5898 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5899 if (image == (Image *) NULL)
5900 {
5901 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5902 PackageName);
5903 goto PerlException;
5904 }
5905
5906 region.x=0;
5907 region.y=0;
5908 region.width=image->columns;
5909 region.height=1;
5910 if (items == 1)
5911 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5912 for (i=2; i < items; i+=2)
5913 {
5914 attribute=(char *) SvPV(ST(i-1),na);
5915 switch (*attribute)
5916 {
5917 case 'g':
5918 case 'G':
5919 {
5920 if (LocaleCompare(attribute,"geometry") == 0)
5921 {
5922 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5923 break;
5924 }
5925 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5926 attribute);
5927 break;
5928 }
5929 case 'H':
5930 case 'h':
5931 {
5932 if (LocaleCompare(attribute,"height") == 0)
5933 {
5934 region.height=SvIV(ST(i));
5935 continue;
5936 }
5937 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5938 attribute);
5939 break;
5940 }
5941 case 'X':
5942 case 'x':
5943 {
5944 if (LocaleCompare(attribute,"x") == 0)
5945 {
5946 region.x=SvIV(ST(i));
5947 continue;
5948 }
5949 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5950 attribute);
5951 break;
5952 }
5953 case 'Y':
5954 case 'y':
5955 {
5956 if (LocaleCompare(attribute,"y") == 0)
5957 {
5958 region.y=SvIV(ST(i));
5959 continue;
5960 }
5961 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5962 attribute);
5963 break;
5964 }
5965 case 'W':
5966 case 'w':
5967 {
5968 if (LocaleCompare(attribute,"width") == 0)
5969 {
5970 region.width=SvIV(ST(i));
5971 continue;
5972 }
5973 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5974 attribute);
5975 break;
5976 }
5977 }
5978 }
5979 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5980 region.height,exception);
5981 if (blob != (void *) NULL)
5982 goto PerlEnd;
5983
5984 PerlException:
5985 InheritPerlException(exception,perl_exception);
5986 exception=DestroyExceptionInfo(exception);
5987 SvREFCNT_dec(perl_exception); /* throw away all errors */
5988
5989 PerlEnd:
5990 RETVAL = blob;
5991 }
5992 OUTPUT:
5993 RETVAL
5994
5995#
5996###############################################################################
5997# #
5998# #
5999# #
6000# G e t V i r t u a l P i x e l s #
6001# #
6002# #
6003# #
6004###############################################################################
6005#
6006#
6007void *
6008GetVirtualPixels(ref,...)
6009 Image::Magick ref = NO_INIT
6010 ALIAS:
6011 getvirtualpixels = 1
6012 AcquireImagePixels = 2
6013 acquireimagepixels = 3
6014 CODE:
6015 {
6016 char
6017 *attribute;
6018
6019 const void
6020 *blob = NULL;
6021
6022 ExceptionInfo
6023 *exception;
6024
6025 Image
6026 *image;
6027
6028 RectangleInfo
6029 region;
6030
6031 ssize_t
6032 i;
6033
6034 struct PackageInfo
6035 *info;
6036
6037 SV
6038 *perl_exception,
6039 *reference;
6040
6041 PERL_UNUSED_VAR(ref);
6042 PERL_UNUSED_VAR(ix);
6043 exception=AcquireExceptionInfo();
6044 perl_exception=newSVpv("",0);
6045 if (sv_isobject(ST(0)) == 0)
6046 {
6047 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6048 PackageName);
6049 goto PerlException;
6050 }
6051 reference=SvRV(ST(0));
6052
6053 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6054 if (image == (Image *) NULL)
6055 {
6056 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6057 PackageName);
6058 goto PerlException;
6059 }
6060
6061 region.x=0;
6062 region.y=0;
6063 region.width=image->columns;
6064 region.height=1;
6065 if (items == 1)
6066 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6067 for (i=2; i < items; i+=2)
6068 {
6069 attribute=(char *) SvPV(ST(i-1),na);
6070 switch (*attribute)
6071 {
6072 case 'g':
6073 case 'G':
6074 {
6075 if (LocaleCompare(attribute,"geometry") == 0)
6076 {
6077 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6078 break;
6079 }
6080 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6081 attribute);
6082 break;
6083 }
6084 case 'H':
6085 case 'h':
6086 {
6087 if (LocaleCompare(attribute,"height") == 0)
6088 {
6089 region.height=SvIV(ST(i));
6090 continue;
6091 }
6092 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6093 attribute);
6094 break;
6095 }
6096 case 'X':
6097 case 'x':
6098 {
6099 if (LocaleCompare(attribute,"x") == 0)
6100 {
6101 region.x=SvIV(ST(i));
6102 continue;
6103 }
6104 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6105 attribute);
6106 break;
6107 }
6108 case 'Y':
6109 case 'y':
6110 {
6111 if (LocaleCompare(attribute,"y") == 0)
6112 {
6113 region.y=SvIV(ST(i));
6114 continue;
6115 }
6116 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6117 attribute);
6118 break;
6119 }
6120 case 'W':
6121 case 'w':
6122 {
6123 if (LocaleCompare(attribute,"width") == 0)
6124 {
6125 region.width=SvIV(ST(i));
6126 continue;
6127 }
6128 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6129 attribute);
6130 break;
6131 }
6132 }
6133 }
6134 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6135 region.height,exception);
6136 if (blob != (void *) NULL)
6137 goto PerlEnd;
6138
6139 PerlException:
6140 InheritPerlException(exception,perl_exception);
6141 exception=DestroyExceptionInfo(exception);
6142 SvREFCNT_dec(perl_exception); /* throw away all errors */
6143
6144 PerlEnd:
6145 RETVAL = (void *) blob;
6146 }
6147 OUTPUT:
6148 RETVAL
6149
6150#
6151###############################################################################
6152# #
6153# #
6154# #
6155# G e t A u t h e n t i c M e t a c o n t e n t #
6156# #
6157# #
6158# #
6159###############################################################################
6160#
6161#
6162void *
6163GetAuthenticMetacontent(ref,...)
6164 Image::Magick ref = NO_INIT
6165 ALIAS:
6166 getauthenticmetacontent = 1
6167 GetMetacontent = 2
6168 getmetacontent = 3
6169 CODE:
6170 {
6171 ExceptionInfo
6172 *exception;
6173
6174 Image
6175 *image;
6176
6177 struct PackageInfo
6178 *info;
6179
6180 SV
6181 *perl_exception,
6182 *reference;
6183
6184 void
6185 *blob = NULL;
6186
6187 PERL_UNUSED_VAR(ref);
6188 PERL_UNUSED_VAR(ix);
6189 exception=AcquireExceptionInfo();
6190 perl_exception=newSVpv("",0);
6191 if (sv_isobject(ST(0)) == 0)
6192 {
6193 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6194 PackageName);
6195 goto PerlException;
6196 }
6197 reference=SvRV(ST(0));
6198
6199 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6200 if (image == (Image *) NULL)
6201 {
6202 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6203 PackageName);
6204 goto PerlException;
6205 }
6206
6207 blob=(void *) GetAuthenticMetacontent(image);
6208 if (blob != (void *) NULL)
6209 goto PerlEnd;
6210
6211 PerlException:
6212 InheritPerlException(exception,perl_exception);
6213 exception=DestroyExceptionInfo(exception);
6214 SvREFCNT_dec(perl_exception); /* throw away all errors */
6215
6216 PerlEnd:
6217 RETVAL = blob;
6218 }
6219 OUTPUT:
6220 RETVAL
6221
6222#
6223###############################################################################
6224# #
6225# #
6226# #
6227# G e t V i r t u a l M e t a c o n t e n t #
6228# #
6229# #
6230# #
6231###############################################################################
6232#
6233#
6234void *
6235GetVirtualMetacontent(ref,...)
6236 Image::Magick ref = NO_INIT
6237 ALIAS:
6238 getvirtualmetacontent = 1
6239 CODE:
6240 {
6241 ExceptionInfo
6242 *exception;
6243
6244 Image
6245 *image;
6246
6247 struct PackageInfo
6248 *info;
6249
6250 SV
6251 *perl_exception,
6252 *reference;
6253
6254 void
6255 *blob = NULL;
6256
6257 PERL_UNUSED_VAR(ref);
6258 PERL_UNUSED_VAR(ix);
6259 exception=AcquireExceptionInfo();
6260 perl_exception=newSVpv("",0);
6261 if (sv_isobject(ST(0)) == 0)
6262 {
6263 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6264 PackageName);
6265 goto PerlException;
6266 }
6267 reference=SvRV(ST(0));
6268
6269 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6270 if (image == (Image *) NULL)
6271 {
6272 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6273 PackageName);
6274 goto PerlException;
6275 }
6276
6277 blob=(void *) GetVirtualMetacontent(image);
6278 if (blob != (void *) NULL)
6279 goto PerlEnd;
6280
6281 PerlException:
6282 InheritPerlException(exception,perl_exception);
6283 exception=DestroyExceptionInfo(exception);
6284 SvREFCNT_dec(perl_exception); /* throw away all errors */
6285
6286 PerlEnd:
6287 RETVAL = blob;
6288 }
6289 OUTPUT:
6290 RETVAL
6291
6292#
6293###############################################################################
6294# #
6295# #
6296# #
6297# H i s t o g r a m #
6298# #
6299# #
6300# #
6301###############################################################################
6302#
6303#
6304void
6305Histogram(ref,...)
6306 Image::Magick ref=NO_INIT
6307 ALIAS:
6308 HistogramImage = 1
6309 histogram = 2
6310 histogramimage = 3
6311 PPCODE:
6312 {
6313 AV
6314 *av;
6315
6316 char
cristy151b66d2015-04-15 10:50:31 +00006317 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006318
6319 PixelInfo
6320 *histogram;
6321
6322 ExceptionInfo
6323 *exception;
6324
6325 Image
6326 *image;
6327
6328 register ssize_t
6329 i;
6330
6331 ssize_t
6332 count;
6333
6334 struct PackageInfo
6335 *info;
6336
6337 SV
6338 *perl_exception,
6339 *reference;
6340
6341 size_t
6342 number_colors;
6343
6344 PERL_UNUSED_VAR(ref);
6345 PERL_UNUSED_VAR(ix);
6346 exception=AcquireExceptionInfo();
6347 perl_exception=newSVpv("",0);
6348 av=NULL;
6349 if (sv_isobject(ST(0)) == 0)
6350 {
6351 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6352 PackageName);
6353 goto PerlException;
6354 }
6355 reference=SvRV(ST(0));
6356 av=newAV();
6357 SvREFCNT_dec(av);
6358 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6359 if (image == (Image *) NULL)
6360 {
6361 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6362 PackageName);
6363 goto PerlException;
6364 }
cristy4a3ce0a2013-08-03 20:06:59 +00006365 count=0;
6366 for ( ; image; image=image->next)
6367 {
6368 histogram=GetImageHistogram(image,&number_colors,exception);
6369 if (histogram == (PixelInfo *) NULL)
6370 continue;
6371 count+=(ssize_t) number_colors;
6372 EXTEND(sp,6*count);
6373 for (i=0; i < (ssize_t) number_colors; i++)
6374 {
cristy151b66d2015-04-15 10:50:31 +00006375 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006376 histogram[i].red);
6377 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006378 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006379 histogram[i].green);
6380 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006381 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006382 histogram[i].blue);
6383 PUSHs(sv_2mortal(newSVpv(message,0)));
6384 if (image->colorspace == CMYKColorspace)
6385 {
cristy151b66d2015-04-15 10:50:31 +00006386 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006387 histogram[i].black);
6388 PUSHs(sv_2mortal(newSVpv(message,0)));
6389 }
cristy151b66d2015-04-15 10:50:31 +00006390 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006391 histogram[i].alpha);
6392 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006393 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006394 histogram[i].count);
6395 PUSHs(sv_2mortal(newSVpv(message,0)));
6396 }
6397 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6398 }
6399
6400 PerlException:
6401 InheritPerlException(exception,perl_exception);
6402 exception=DestroyExceptionInfo(exception);
6403 SvREFCNT_dec(perl_exception);
6404 }
6405
6406#
6407###############################################################################
6408# #
6409# #
6410# #
6411# G e t P i x e l #
6412# #
6413# #
6414# #
6415###############################################################################
6416#
6417#
6418void
6419GetPixel(ref,...)
6420 Image::Magick ref=NO_INIT
6421 ALIAS:
6422 getpixel = 1
6423 getPixel = 2
6424 PPCODE:
6425 {
6426 AV
6427 *av;
6428
6429 char
6430 *attribute;
6431
6432 ExceptionInfo
6433 *exception;
6434
6435 Image
6436 *image;
6437
6438 MagickBooleanType
6439 normalize;
6440
6441 RectangleInfo
6442 region;
6443
6444 register const Quantum
6445 *p;
6446
6447 register ssize_t
6448 i;
6449
6450 ssize_t
6451 option;
6452
6453 struct PackageInfo
6454 *info;
6455
6456 SV
6457 *perl_exception,
6458 *reference; /* reference is the SV* of ref=SvIV(reference) */
6459
6460 PERL_UNUSED_VAR(ref);
6461 PERL_UNUSED_VAR(ix);
6462 exception=AcquireExceptionInfo();
6463 perl_exception=newSVpv("",0);
6464 reference=SvRV(ST(0));
6465 av=(AV *) reference;
6466 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6467 exception);
6468 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6469 if (image == (Image *) NULL)
6470 {
6471 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6472 PackageName);
6473 goto PerlException;
6474 }
6475 normalize=MagickTrue;
6476 region.x=0;
6477 region.y=0;
6478 region.width=image->columns;
6479 region.height=1;
6480 if (items == 1)
6481 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6482 for (i=2; i < items; i+=2)
6483 {
6484 attribute=(char *) SvPV(ST(i-1),na);
6485 switch (*attribute)
6486 {
6487 case 'C':
6488 case 'c':
6489 {
6490 if (LocaleCompare(attribute,"channel") == 0)
6491 {
6492 ssize_t
6493 option;
6494
6495 option=ParseChannelOption(SvPV(ST(i),na));
6496 if (option < 0)
6497 {
6498 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6499 SvPV(ST(i),na));
6500 return;
6501 }
cristybcd59342015-06-07 14:07:19 +00006502 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00006503 break;
6504 }
6505 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6506 attribute);
6507 break;
6508 }
6509 case 'g':
6510 case 'G':
6511 {
6512 if (LocaleCompare(attribute,"geometry") == 0)
6513 {
6514 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6515 break;
6516 }
6517 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6518 attribute);
6519 break;
6520 }
6521 case 'N':
6522 case 'n':
6523 {
6524 if (LocaleCompare(attribute,"normalize") == 0)
6525 {
6526 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6527 SvPV(ST(i),na));
6528 if (option < 0)
6529 {
6530 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6531 SvPV(ST(i),na));
6532 break;
6533 }
6534 normalize=option != 0 ? MagickTrue : MagickFalse;
6535 break;
6536 }
6537 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6538 attribute);
6539 break;
6540 }
6541 case 'x':
6542 case 'X':
6543 {
6544 if (LocaleCompare(attribute,"x") == 0)
6545 {
6546 region.x=SvIV(ST(i));
6547 break;
6548 }
6549 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6550 attribute);
6551 break;
6552 }
6553 case 'y':
6554 case 'Y':
6555 {
6556 if (LocaleCompare(attribute,"y") == 0)
6557 {
6558 region.y=SvIV(ST(i));
6559 break;
6560 }
6561 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6562 attribute);
6563 break;
6564 }
6565 default:
6566 {
6567 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6568 attribute);
6569 break;
6570 }
6571 }
6572 }
6573 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6574 if (p == (const Quantum *) NULL)
6575 PUSHs(&sv_undef);
6576 else
6577 {
6578 double
6579 scale;
6580
6581 scale=1.0;
6582 if (normalize != MagickFalse)
6583 scale=1.0/QuantumRange;
6584 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6585 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6586 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6587 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6588 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6589 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6590 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6591 (image->colorspace == CMYKColorspace))
6592 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6593 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6594 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6595 }
6596
6597 PerlException:
6598 InheritPerlException(exception,perl_exception);
6599 exception=DestroyExceptionInfo(exception);
6600 SvREFCNT_dec(perl_exception);
6601 }
6602
6603#
6604###############################################################################
6605# #
6606# #
6607# #
6608# G e t P i x e l s #
6609# #
6610# #
6611# #
6612###############################################################################
6613#
6614#
6615void
6616GetPixels(ref,...)
6617 Image::Magick ref=NO_INIT
6618 ALIAS:
6619 getpixels = 1
6620 getPixels = 2
6621 PPCODE:
6622 {
6623 AV
6624 *av;
6625
6626 char
6627 *attribute;
6628
6629 const char
6630 *map;
6631
6632 ExceptionInfo
6633 *exception;
6634
6635 Image
6636 *image;
6637
6638 MagickBooleanType
6639 normalize,
6640 status;
6641
6642 RectangleInfo
6643 region;
6644
6645 register ssize_t
6646 i;
6647
6648 ssize_t
6649 option;
6650
6651 struct PackageInfo
6652 *info;
6653
6654 SV
6655 *perl_exception,
6656 *reference; /* reference is the SV* of ref=SvIV(reference) */
6657
6658 PERL_UNUSED_VAR(ref);
6659 PERL_UNUSED_VAR(ix);
6660 exception=AcquireExceptionInfo();
6661 perl_exception=newSVpv("",0);
6662 reference=SvRV(ST(0));
6663 av=(AV *) reference;
6664 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6665 exception);
6666 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6667 if (image == (Image *) NULL)
6668 {
6669 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6670 PackageName);
6671 goto PerlException;
6672 }
6673 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006674 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006675 map="RGBA";
6676 if (image->colorspace == CMYKColorspace)
6677 {
6678 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006679 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006680 map="CMYKA";
6681 }
6682 normalize=MagickFalse;
6683 region.x=0;
6684 region.y=0;
6685 region.width=image->columns;
6686 region.height=1;
6687 if (items == 1)
6688 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6689 for (i=2; i < items; i+=2)
6690 {
6691 attribute=(char *) SvPV(ST(i-1),na);
6692 switch (*attribute)
6693 {
6694 case 'g':
6695 case 'G':
6696 {
6697 if (LocaleCompare(attribute,"geometry") == 0)
6698 {
6699 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6700 break;
6701 }
6702 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6703 attribute);
6704 break;
6705 }
6706 case 'H':
6707 case 'h':
6708 {
6709 if (LocaleCompare(attribute,"height") == 0)
6710 {
6711 region.height=SvIV(ST(i));
6712 break;
6713 }
6714 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6715 attribute);
6716 break;
6717 }
6718 case 'M':
6719 case 'm':
6720 {
6721 if (LocaleCompare(attribute,"map") == 0)
6722 {
6723 map=SvPV(ST(i),na);
6724 break;
6725 }
6726 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6727 attribute);
6728 break;
6729 }
6730 case 'N':
6731 case 'n':
6732 {
6733 if (LocaleCompare(attribute,"normalize") == 0)
6734 {
6735 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6736 SvPV(ST(i),na));
6737 if (option < 0)
6738 {
6739 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6740 SvPV(ST(i),na));
6741 break;
6742 }
6743 normalize=option != 0 ? MagickTrue : MagickFalse;
6744 break;
6745 }
6746 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6747 attribute);
6748 break;
6749 }
6750 case 'W':
6751 case 'w':
6752 {
6753 if (LocaleCompare(attribute,"width") == 0)
6754 {
6755 region.width=SvIV(ST(i));
6756 break;
6757 }
6758 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6759 attribute);
6760 break;
6761 }
6762 case 'x':
6763 case 'X':
6764 {
6765 if (LocaleCompare(attribute,"x") == 0)
6766 {
6767 region.x=SvIV(ST(i));
6768 break;
6769 }
6770 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6771 attribute);
6772 break;
6773 }
6774 case 'y':
6775 case 'Y':
6776 {
6777 if (LocaleCompare(attribute,"y") == 0)
6778 {
6779 region.y=SvIV(ST(i));
6780 break;
6781 }
6782 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6783 attribute);
6784 break;
6785 }
6786 default:
6787 {
6788 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6789 attribute);
6790 break;
6791 }
6792 }
6793 }
6794 if (normalize != MagickFalse)
6795 {
6796 float
6797 *pixels;
6798
6799 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6800 region.height*sizeof(*pixels));
6801 if (pixels == (float *) NULL)
6802 {
6803 ThrowPerlException(exception,ResourceLimitError,
6804 "MemoryAllocationFailed",PackageName);
6805 goto PerlException;
6806 }
6807 status=ExportImagePixels(image,region.x,region.y,region.width,
6808 region.height,map,FloatPixel,pixels,exception);
6809 if (status == MagickFalse)
6810 PUSHs(&sv_undef);
6811 else
6812 {
6813 EXTEND(sp,strlen(map)*region.width*region.height);
6814 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6815 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6816 }
6817 pixels=(float *) RelinquishMagickMemory(pixels);
6818 }
6819 else
6820 {
6821 Quantum
6822 *pixels;
6823
6824 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6825 region.height*sizeof(*pixels));
6826 if (pixels == (Quantum *) NULL)
6827 {
6828 ThrowPerlException(exception,ResourceLimitError,
6829 "MemoryAllocationFailed",PackageName);
6830 goto PerlException;
6831 }
6832 status=ExportImagePixels(image,region.x,region.y,region.width,
6833 region.height,map,QuantumPixel,pixels,exception);
6834 if (status == MagickFalse)
6835 PUSHs(&sv_undef);
6836 else
6837 {
6838 EXTEND(sp,strlen(map)*region.width*region.height);
6839 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6840 PUSHs(sv_2mortal(newSViv(pixels[i])));
6841 }
6842 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6843 }
6844
6845 PerlException:
6846 InheritPerlException(exception,perl_exception);
6847 exception=DestroyExceptionInfo(exception);
6848 SvREFCNT_dec(perl_exception);
6849 }
6850
6851#
6852###############################################################################
6853# #
6854# #
6855# #
6856# I m a g e T o B l o b #
6857# #
6858# #
6859# #
6860###############################################################################
6861#
6862#
6863void
6864ImageToBlob(ref,...)
6865 Image::Magick ref=NO_INIT
6866 ALIAS:
6867 ImageToBlob = 1
6868 imagetoblob = 2
6869 toblob = 3
6870 blob = 4
6871 PPCODE:
6872 {
6873 char
cristy151b66d2015-04-15 10:50:31 +00006874 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006875
6876 ExceptionInfo
6877 *exception;
6878
6879 Image
6880 *image,
6881 *next;
6882
6883 register ssize_t
6884 i;
6885
6886 struct PackageInfo
6887 *info,
6888 *package_info;
6889
6890 size_t
6891 length;
6892
6893 ssize_t
6894 scene;
6895
6896 SV
6897 *perl_exception,
6898 *reference;
6899
6900 void
6901 *blob;
6902
6903 PERL_UNUSED_VAR(ref);
6904 PERL_UNUSED_VAR(ix);
6905 exception=AcquireExceptionInfo();
6906 perl_exception=newSVpv("",0);
6907 package_info=(struct PackageInfo *) NULL;
6908 if (sv_isobject(ST(0)) == 0)
6909 {
6910 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6911 PackageName);
6912 goto PerlException;
6913 }
6914 reference=SvRV(ST(0));
6915 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6916 if (image == (Image *) NULL)
6917 {
6918 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6919 PackageName);
6920 goto PerlException;
6921 }
6922 package_info=ClonePackageInfo(info,exception);
6923 for (i=2; i < items; i+=2)
6924 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6925 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006926 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006927 scene=0;
6928 for (next=image; next; next=next->next)
6929 {
cristy151b66d2015-04-15 10:50:31 +00006930 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006931 next->scene=scene++;
6932 }
6933 SetImageInfo(package_info->image_info,(unsigned int)
6934 GetImageListLength(image),exception);
6935 EXTEND(sp,(ssize_t) GetImageListLength(image));
6936 for ( ; image; image=image->next)
6937 {
6938 length=0;
6939 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6940 if (blob != (char *) NULL)
6941 {
6942 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6943 blob=(unsigned char *) RelinquishMagickMemory(blob);
6944 }
6945 if (package_info->image_info->adjoin)
6946 break;
6947 }
6948
6949 PerlException:
6950 if (package_info != (struct PackageInfo *) NULL)
6951 DestroyPackageInfo(package_info);
6952 InheritPerlException(exception,perl_exception);
6953 exception=DestroyExceptionInfo(exception);
6954 SvREFCNT_dec(perl_exception); /* throw away all errors */
6955 }
6956
6957#
6958###############################################################################
6959# #
6960# #
6961# #
6962# L a y e r s #
6963# #
6964# #
6965# #
6966###############################################################################
6967#
6968#
6969void
6970Layers(ref,...)
6971 Image::Magick ref=NO_INIT
6972 ALIAS:
6973 Layers = 1
6974 layers = 2
6975 OptimizeImageLayers = 3
6976 optimizelayers = 4
6977 optimizeimagelayers = 5
6978 PPCODE:
6979 {
6980 AV
6981 *av;
6982
6983 char
6984 *attribute;
6985
6986 CompositeOperator
6987 compose;
6988
6989 ExceptionInfo
6990 *exception;
6991
6992 HV
6993 *hv;
6994
6995 Image
6996 *image,
6997 *layers;
6998
6999 LayerMethod
7000 method;
7001
7002 register ssize_t
7003 i;
7004
7005 ssize_t
7006 option,
7007 sp;
7008
7009 struct PackageInfo
7010 *info;
7011
7012 SV
7013 *av_reference,
7014 *perl_exception,
7015 *reference,
7016 *rv,
7017 *sv;
7018
7019 PERL_UNUSED_VAR(ref);
7020 PERL_UNUSED_VAR(ix);
7021 exception=AcquireExceptionInfo();
7022 perl_exception=newSVpv("",0);
7023 sv=NULL;
7024 if (sv_isobject(ST(0)) == 0)
7025 {
7026 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7027 PackageName);
7028 goto PerlException;
7029 }
7030 reference=SvRV(ST(0));
7031 hv=SvSTASH(reference);
7032 av=newAV();
7033 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7034 SvREFCNT_dec(av);
7035 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7036 if (image == (Image *) NULL)
7037 {
7038 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7039 PackageName);
7040 goto PerlException;
7041 }
7042 compose=image->compose;
7043 method=OptimizeLayer;
7044 for (i=2; i < items; i+=2)
7045 {
7046 attribute=(char *) SvPV(ST(i-1),na);
7047 switch (*attribute)
7048 {
7049 case 'C':
7050 case 'c':
7051 {
7052 if (LocaleCompare(attribute,"compose") == 0)
7053 {
7054 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7055 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7056 if (sp < 0)
7057 {
7058 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7059 SvPV(ST(i),na));
7060 break;
7061 }
7062 compose=(CompositeOperator) sp;
7063 break;
7064 }
7065 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7066 attribute);
7067 break;
7068 }
7069 case 'M':
7070 case 'm':
7071 {
7072 if (LocaleCompare(attribute,"method") == 0)
7073 {
7074 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7075 SvPV(ST(i),na));
7076 if (option < 0)
7077 {
7078 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7079 SvPV(ST(i),na));
7080 break;
7081 }
7082 method=(LayerMethod) option;
7083 break;
7084 }
7085 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7086 attribute);
7087 break;
7088 }
7089 default:
7090 {
7091 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7092 attribute);
7093 break;
7094 }
7095 }
7096 }
7097 layers=(Image *) NULL;
7098 switch (method)
7099 {
7100 case CompareAnyLayer:
7101 case CompareClearLayer:
7102 case CompareOverlayLayer:
7103 default:
7104 {
7105 layers=CompareImagesLayers(image,method,exception);
7106 break;
7107 }
7108 case MergeLayer:
7109 case FlattenLayer:
7110 case MosaicLayer:
7111 {
7112 layers=MergeImageLayers(image,method,exception);
7113 break;
7114 }
7115 case DisposeLayer:
7116 {
7117 layers=DisposeImages(image,exception);
7118 break;
7119 }
7120 case OptimizeImageLayer:
7121 {
7122 layers=OptimizeImageLayers(image,exception);
7123 break;
7124 }
7125 case OptimizePlusLayer:
7126 {
7127 layers=OptimizePlusImageLayers(image,exception);
7128 break;
7129 }
7130 case OptimizeTransLayer:
7131 {
7132 OptimizeImageTransparency(image,exception);
7133 break;
7134 }
7135 case RemoveDupsLayer:
7136 {
7137 RemoveDuplicateLayers(&image,exception);
7138 break;
7139 }
7140 case RemoveZeroLayer:
7141 {
7142 RemoveZeroDelayLayers(&image,exception);
7143 break;
7144 }
7145 case OptimizeLayer:
7146 {
7147 QuantizeInfo
7148 *quantize_info;
7149
7150 /*
7151 General Purpose, GIF Animation Optimizer.
7152 */
7153 layers=CoalesceImages(image,exception);
7154 if (layers == (Image *) NULL)
7155 break;
7156 image=layers;
7157 layers=OptimizeImageLayers(image,exception);
7158 if (layers == (Image *) NULL)
7159 break;
7160 image=DestroyImageList(image);
7161 image=layers;
7162 layers=(Image *) NULL;
7163 OptimizeImageTransparency(image,exception);
7164 quantize_info=AcquireQuantizeInfo(info->image_info);
7165 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7166 quantize_info=DestroyQuantizeInfo(quantize_info);
7167 break;
7168 }
7169 case CompositeLayer:
7170 {
7171 Image
7172 *source;
7173
7174 RectangleInfo
7175 geometry;
7176
7177 /*
7178 Split image sequence at the first 'NULL:' image.
7179 */
7180 source=image;
7181 while (source != (Image *) NULL)
7182 {
7183 source=GetNextImageInList(source);
7184 if ((source != (Image *) NULL) &&
7185 (LocaleCompare(source->magick,"NULL") == 0))
7186 break;
7187 }
7188 if (source != (Image *) NULL)
7189 {
7190 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7191 (GetNextImageInList(source) == (Image *) NULL))
7192 source=(Image *) NULL;
7193 else
7194 {
7195 /*
7196 Separate the two lists, junk the null: image.
7197 */
7198 source=SplitImageList(source->previous);
7199 DeleteImageFromList(&source);
7200 }
7201 }
7202 if (source == (Image *) NULL)
7203 {
7204 (void) ThrowMagickException(exception,GetMagickModule(),
7205 OptionError,"MissingNullSeparator","layers Composite");
7206 break;
7207 }
7208 /*
7209 Adjust offset with gravity and virtual canvas.
7210 */
7211 SetGeometry(image,&geometry);
7212 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7213 geometry.width=source->page.width != 0 ? source->page.width :
7214 source->columns;
7215 geometry.height=source->page.height != 0 ? source->page.height :
7216 source->rows;
7217 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7218 image->columns,image->page.height != 0 ? image->page.height :
7219 image->rows,image->gravity,&geometry);
7220 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7221 source=DestroyImageList(source);
7222 break;
7223 }
7224 }
7225 if (layers != (Image *) NULL)
7226 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007227 else
7228 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007229 if (image == (Image *) NULL)
7230 goto PerlException;
7231 for ( ; image; image=image->next)
7232 {
7233 AddImageToRegistry(sv,image);
7234 rv=newRV(sv);
7235 av_push(av,sv_bless(rv,hv));
7236 SvREFCNT_dec(sv);
7237 }
7238 exception=DestroyExceptionInfo(exception);
7239 ST(0)=av_reference;
7240 SvREFCNT_dec(perl_exception);
7241 XSRETURN(1);
7242
7243 PerlException:
7244 InheritPerlException(exception,perl_exception);
7245 exception=DestroyExceptionInfo(exception);
7246 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7247 SvPOK_on(perl_exception);
7248 ST(0)=sv_2mortal(perl_exception);
7249 XSRETURN(1);
7250 }
7251
7252#
7253###############################################################################
7254# #
7255# #
7256# #
7257# M a g i c k T o M i m e #
7258# #
7259# #
7260# #
7261###############################################################################
7262#
7263#
7264SV *
7265MagickToMime(ref,name)
7266 Image::Magick ref=NO_INIT
7267 char *name
7268 ALIAS:
7269 magicktomime = 1
7270 CODE:
7271 {
7272 char
7273 *mime;
7274
7275 PERL_UNUSED_VAR(ref);
7276 PERL_UNUSED_VAR(ix);
7277 mime=MagickToMime(name);
7278 RETVAL=newSVpv(mime,0);
7279 mime=(char *) RelinquishMagickMemory(mime);
7280 }
7281 OUTPUT:
7282 RETVAL
7283
7284#
7285###############################################################################
7286# #
7287# #
7288# #
7289# M o g r i f y #
7290# #
7291# #
7292# #
7293###############################################################################
7294#
7295#
7296void
7297Mogrify(ref,...)
7298 Image::Magick ref=NO_INIT
7299 ALIAS:
7300 Comment = 1
7301 CommentImage = 2
7302 Label = 3
7303 LabelImage = 4
7304 AddNoise = 5
7305 AddNoiseImage = 6
7306 Colorize = 7
7307 ColorizeImage = 8
7308 Border = 9
7309 BorderImage = 10
7310 Blur = 11
7311 BlurImage = 12
7312 Chop = 13
7313 ChopImage = 14
7314 Crop = 15
7315 CropImage = 16
7316 Despeckle = 17
7317 DespeckleImage = 18
7318 Edge = 19
7319 EdgeImage = 20
7320 Emboss = 21
7321 EmbossImage = 22
7322 Enhance = 23
7323 EnhanceImage = 24
7324 Flip = 25
7325 FlipImage = 26
7326 Flop = 27
7327 FlopImage = 28
7328 Frame = 29
7329 FrameImage = 30
7330 Implode = 31
7331 ImplodeImage = 32
7332 Magnify = 33
7333 MagnifyImage = 34
7334 MedianFilter = 35
7335 MedianConvolveImage = 36
7336 Minify = 37
7337 MinifyImage = 38
7338 OilPaint = 39
7339 OilPaintImage = 40
7340 ReduceNoise = 41
7341 ReduceNoiseImage = 42
7342 Roll = 43
7343 RollImage = 44
7344 Rotate = 45
7345 RotateImage = 46
7346 Sample = 47
7347 SampleImage = 48
7348 Scale = 49
7349 ScaleImage = 50
7350 Shade = 51
7351 ShadeImage = 52
7352 Sharpen = 53
7353 SharpenImage = 54
7354 Shear = 55
7355 ShearImage = 56
7356 Spread = 57
7357 SpreadImage = 58
7358 Swirl = 59
7359 SwirlImage = 60
7360 Resize = 61
7361 ResizeImage = 62
7362 Zoom = 63
7363 ZoomImage = 64
7364 Annotate = 65
7365 AnnotateImage = 66
7366 ColorFloodfill = 67
7367 ColorFloodfillImage= 68
7368 Composite = 69
7369 CompositeImage = 70
7370 Contrast = 71
7371 ContrastImage = 72
7372 CycleColormap = 73
7373 CycleColormapImage = 74
7374 Draw = 75
7375 DrawImage = 76
7376 Equalize = 77
7377 EqualizeImage = 78
7378 Gamma = 79
7379 GammaImage = 80
7380 Map = 81
7381 MapImage = 82
7382 MatteFloodfill = 83
7383 MatteFloodfillImage= 84
7384 Modulate = 85
7385 ModulateImage = 86
7386 Negate = 87
7387 NegateImage = 88
7388 Normalize = 89
7389 NormalizeImage = 90
7390 NumberColors = 91
7391 NumberColorsImage = 92
7392 Opaque = 93
7393 OpaqueImage = 94
7394 Quantize = 95
7395 QuantizeImage = 96
7396 Raise = 97
7397 RaiseImage = 98
7398 Segment = 99
7399 SegmentImage = 100
7400 Signature = 101
7401 SignatureImage = 102
7402 Solarize = 103
7403 SolarizeImage = 104
7404 Sync = 105
7405 SyncImage = 106
7406 Texture = 107
7407 TextureImage = 108
7408 Evaluate = 109
7409 EvaluateImage = 110
7410 Transparent = 111
7411 TransparentImage = 112
7412 Threshold = 113
7413 ThresholdImage = 114
7414 Charcoal = 115
7415 CharcoalImage = 116
7416 Trim = 117
7417 TrimImage = 118
7418 Wave = 119
7419 WaveImage = 120
7420 Separate = 121
7421 SeparateImage = 122
7422 Stereo = 125
7423 StereoImage = 126
7424 Stegano = 127
7425 SteganoImage = 128
7426 Deconstruct = 129
7427 DeconstructImage = 130
7428 GaussianBlur = 131
7429 GaussianBlurImage = 132
7430 Convolve = 133
7431 ConvolveImage = 134
7432 Profile = 135
7433 ProfileImage = 136
7434 UnsharpMask = 137
7435 UnsharpMaskImage = 138
7436 MotionBlur = 139
7437 MotionBlurImage = 140
7438 OrderedDither = 141
7439 OrderedDitherImage = 142
7440 Shave = 143
7441 ShaveImage = 144
7442 Level = 145
7443 LevelImage = 146
7444 Clip = 147
7445 ClipImage = 148
7446 AffineTransform = 149
7447 AffineTransformImage = 150
7448 Difference = 151
7449 DifferenceImage = 152
7450 AdaptiveThreshold = 153
7451 AdaptiveThresholdImage = 154
7452 Resample = 155
7453 ResampleImage = 156
7454 Describe = 157
7455 DescribeImage = 158
7456 BlackThreshold = 159
7457 BlackThresholdImage= 160
7458 WhiteThreshold = 161
7459 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007460 RotationalBlur = 163
7461 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007462 Thumbnail = 165
7463 ThumbnailImage = 166
7464 Strip = 167
7465 StripImage = 168
7466 Tint = 169
7467 TintImage = 170
7468 Channel = 171
7469 ChannelImage = 172
7470 Splice = 173
7471 SpliceImage = 174
7472 Posterize = 175
7473 PosterizeImage = 176
7474 Shadow = 177
7475 ShadowImage = 178
7476 Identify = 179
7477 IdentifyImage = 180
7478 SepiaTone = 181
7479 SepiaToneImage = 182
7480 SigmoidalContrast = 183
7481 SigmoidalContrastImage = 184
7482 Extent = 185
7483 ExtentImage = 186
7484 Vignette = 187
7485 VignetteImage = 188
7486 ContrastStretch = 189
7487 ContrastStretchImage = 190
7488 Sans0 = 191
7489 Sans0Image = 192
7490 Sans1 = 193
7491 Sans1Image = 194
7492 AdaptiveSharpen = 195
7493 AdaptiveSharpenImage = 196
7494 Transpose = 197
7495 TransposeImage = 198
7496 Transverse = 199
7497 TransverseImage = 200
7498 AutoOrient = 201
7499 AutoOrientImage = 202
7500 AdaptiveBlur = 203
7501 AdaptiveBlurImage = 204
7502 Sketch = 205
7503 SketchImage = 206
7504 UniqueColors = 207
7505 UniqueColorsImage = 208
7506 AdaptiveResize = 209
7507 AdaptiveResizeImage= 210
7508 ClipMask = 211
7509 ClipMaskImage = 212
7510 LinearStretch = 213
7511 LinearStretchImage = 214
7512 ColorMatrix = 215
7513 ColorMatrixImage = 216
7514 Mask = 217
7515 MaskImage = 218
7516 Polaroid = 219
7517 PolaroidImage = 220
7518 FloodfillPaint = 221
7519 FloodfillPaintImage= 222
7520 Distort = 223
7521 DistortImage = 224
7522 Clut = 225
7523 ClutImage = 226
7524 LiquidRescale = 227
7525 LiquidRescaleImage = 228
7526 Encipher = 229
7527 EncipherImage = 230
7528 Decipher = 231
7529 DecipherImage = 232
7530 Deskew = 233
7531 DeskewImage = 234
7532 Remap = 235
7533 RemapImage = 236
7534 SparseColor = 237
7535 SparseColorImage = 238
7536 Function = 239
7537 FunctionImage = 240
7538 SelectiveBlur = 241
7539 SelectiveBlurImage = 242
7540 HaldClut = 243
7541 HaldClutImage = 244
7542 BlueShift = 245
7543 BlueShiftImage = 246
7544 ForwardFourierTransform = 247
7545 ForwardFourierTransformImage = 248
7546 InverseFourierTransform = 249
7547 InverseFourierTransformImage = 250
7548 ColorDecisionList = 251
7549 ColorDecisionListImage = 252
7550 AutoGamma = 253
7551 AutoGammaImage = 254
7552 AutoLevel = 255
7553 AutoLevelImage = 256
7554 LevelColors = 257
7555 LevelImageColors = 258
7556 Clamp = 259
7557 ClampImage = 260
7558 BrightnessContrast = 261
7559 BrightnessContrastImage = 262
7560 Morphology = 263
7561 MorphologyImage = 264
Cristy3ca633e2016-02-13 12:49:01 -05007562 Mode = 265
7563 ModeImage = 266
7564 Statistic = 267
7565 StatisticImage = 268
7566 Perceptible = 269
7567 PerceptibleImage = 270
7568 Poly = 271
7569 PolyImage = 272
7570 Grayscale = 273
7571 GrayscaleImage = 274
7572 CannyEdge = 275
7573 CannyEdgeImage = 276
7574 HoughLine = 277
7575 HoughLineImage = 278
7576 MeanShift = 279
7577 MeanShiftImage = 280
7578 Kuwahara = 281
7579 KuwaharaImage = 282
7580 ConnectedComponent = 283
7581 ConnectedComponentImage = 284
7582 CopyPixels = 285
7583 CopyImagePixels = 286
cristy4a3ce0a2013-08-03 20:06:59 +00007584 MogrifyRegion = 666
7585 PPCODE:
7586 {
7587 AffineMatrix
7588 affine,
7589 current;
7590
7591 char
7592 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007593 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007594
7595 ChannelType
7596 channel,
7597 channel_mask;
7598
7599 CompositeOperator
7600 compose;
7601
7602 const char
7603 *attribute,
7604 *value;
7605
7606 double
7607 angle;
7608
7609 ExceptionInfo
7610 *exception;
7611
7612 GeometryInfo
7613 geometry_info;
7614
7615 Image
7616 *image,
7617 *next,
7618 *region_image;
7619
7620 MagickBooleanType
7621 status;
7622
7623 MagickStatusType
7624 flags;
7625
7626 PixelInfo
7627 fill_color;
7628
7629 RectangleInfo
7630 geometry,
7631 region_info;
7632
7633 register ssize_t
7634 i;
7635
7636 ssize_t
7637 base,
7638 j,
7639 number_images;
7640
7641 struct Methods
7642 *rp;
7643
7644 struct PackageInfo
7645 *info;
7646
7647 SV
7648 *perl_exception,
7649 **pv,
7650 *reference,
7651 **reference_vector;
7652
7653 struct ArgumentList
7654 argument_list[MaxArguments];
7655
7656 PERL_UNUSED_VAR(ref);
7657 PERL_UNUSED_VAR(ix);
7658 exception=AcquireExceptionInfo();
7659 perl_exception=newSVpv("",0);
7660 reference_vector=NULL;
7661 region_image=NULL;
7662 number_images=0;
7663 base=2;
7664 if (sv_isobject(ST(0)) == 0)
7665 {
7666 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7667 PackageName);
7668 goto PerlException;
7669 }
7670 reference=SvRV(ST(0));
7671 region_info.width=0;
7672 region_info.height=0;
7673 region_info.x=0;
7674 region_info.y=0;
7675 region_image=(Image *) NULL;
7676 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7677 if (ix && (ix != 666))
7678 {
7679 /*
7680 Called as Method(...)
7681 */
7682 ix=(ix+1)/2;
7683 rp=(&Methods[ix-1]);
7684 attribute=rp->name;
7685 }
7686 else
7687 {
7688 /*
7689 Called as Mogrify("Method",...)
7690 */
7691 attribute=(char *) SvPV(ST(1),na);
7692 if (ix)
7693 {
7694 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7695 attribute=(char *) SvPV(ST(2),na);
7696 base++;
7697 }
7698 for (rp=Methods; ; rp++)
7699 {
7700 if (rp >= EndOf(Methods))
7701 {
7702 ThrowPerlException(exception,OptionError,
7703 "UnrecognizedPerlMagickMethod",attribute);
7704 goto PerlException;
7705 }
7706 if (strEQcase(attribute,rp->name))
7707 break;
7708 }
7709 ix=rp-Methods+1;
7710 base++;
7711 }
7712 if (image == (Image *) NULL)
7713 {
7714 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7715 goto PerlException;
7716 }
7717 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7718 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7719 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7720 {
7721 Arguments
7722 *pp,
7723 *qq;
7724
7725 ssize_t
7726 ssize_test;
7727
7728 struct ArgumentList
7729 *al;
7730
7731 SV
7732 *sv;
7733
7734 sv=NULL;
7735 ssize_test=0;
7736 pp=(Arguments *) NULL;
7737 qq=rp->arguments;
7738 if (i == items)
7739 {
7740 pp=rp->arguments,
7741 sv=ST(i-1);
7742 }
7743 else
7744 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7745 {
7746 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7747 break;
7748 if (strEQcase(attribute,qq->method) > ssize_test)
7749 {
7750 pp=qq;
7751 ssize_test=strEQcase(attribute,qq->method);
7752 }
7753 }
7754 if (pp == (Arguments *) NULL)
7755 {
7756 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7757 attribute);
7758 goto continue_outer_loop;
7759 }
7760 al=(&argument_list[pp-rp->arguments]);
7761 switch (pp->type)
7762 {
7763 case ArrayReference:
7764 {
7765 if (SvTYPE(sv) != SVt_RV)
7766 {
cristy151b66d2015-04-15 10:50:31 +00007767 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007768 "invalid %.60s value",pp->method);
7769 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7770 goto continue_outer_loop;
7771 }
7772 al->array_reference=SvRV(sv);
7773 break;
7774 }
7775 case RealReference:
7776 {
7777 al->real_reference=SvNV(sv);
7778 break;
7779 }
7780 case FileReference:
7781 {
7782 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7783 break;
7784 }
7785 case ImageReference:
7786 {
7787 if (!sv_isobject(sv) ||
7788 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7789 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7790 {
7791 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7792 PackageName);
7793 goto PerlException;
7794 }
7795 break;
7796 }
7797 case IntegerReference:
7798 {
7799 al->integer_reference=SvIV(sv);
7800 break;
7801 }
7802 case StringReference:
7803 {
7804 al->string_reference=(char *) SvPV(sv,al->length);
7805 if (sv_isobject(sv))
7806 al->image_reference=SetupList(aTHX_ SvRV(sv),
7807 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7808 break;
7809 }
7810 default:
7811 {
7812 /*
7813 Is a string; look up name.
7814 */
7815 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7816 {
7817 al->string_reference=(char *) SvPV(sv,al->length);
7818 al->integer_reference=(-1);
7819 break;
7820 }
7821 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7822 MagickFalse,SvPV(sv,na));
7823 if (pp->type == MagickChannelOptions)
7824 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7825 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7826 {
cristy151b66d2015-04-15 10:50:31 +00007827 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007828 "invalid %.60s value",pp->method);
7829 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7830 goto continue_outer_loop;
7831 }
7832 break;
7833 }
7834 }
7835 attribute_flag[pp-rp->arguments]++;
7836 continue_outer_loop: ;
7837 }
7838 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7839 pv=reference_vector;
7840 SetGeometryInfo(&geometry_info);
7841 channel=DefaultChannels;
7842 for (next=image; next; next=next->next)
7843 {
7844 image=next;
7845 SetGeometry(image,&geometry);
7846 if ((region_info.width*region_info.height) != 0)
7847 {
7848 region_image=image;
7849 image=CropImage(image,&region_info,exception);
7850 }
7851 switch (ix)
7852 {
7853 default:
7854 {
cristy151b66d2015-04-15 10:50:31 +00007855 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007856 ThrowPerlException(exception,OptionError,
7857 "UnrecognizedPerlMagickMethod",message);
7858 goto PerlException;
7859 }
7860 case 1: /* Comment */
7861 {
7862 if (attribute_flag[0] == 0)
7863 argument_list[0].string_reference=(char *) NULL;
7864 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7865 info ? info->image_info : (ImageInfo *) NULL,image,
7866 argument_list[0].string_reference,exception),exception);
7867 break;
7868 }
7869 case 2: /* Label */
7870 {
7871 if (attribute_flag[0] == 0)
7872 argument_list[0].string_reference=(char *) NULL;
7873 (void) SetImageProperty(image,"label",InterpretImageProperties(
7874 info ? info->image_info : (ImageInfo *) NULL,image,
7875 argument_list[0].string_reference,exception),exception);
7876 break;
7877 }
7878 case 3: /* AddNoise */
7879 {
7880 double
7881 attenuate;
7882
7883 if (attribute_flag[0] == 0)
7884 argument_list[0].integer_reference=UniformNoise;
7885 attenuate=1.0;
7886 if (attribute_flag[1] != 0)
7887 attenuate=argument_list[1].real_reference;
7888 if (attribute_flag[2] != 0)
7889 channel=(ChannelType) argument_list[2].integer_reference;
7890 channel_mask=SetImageChannelMask(image,channel);
7891 image=AddNoiseImage(image,(NoiseType)
7892 argument_list[0].integer_reference,attenuate,exception);
7893 if (image != (Image *) NULL)
7894 (void) SetImageChannelMask(image,channel_mask);
7895 break;
7896 }
7897 case 4: /* Colorize */
7898 {
7899 PixelInfo
7900 target;
7901
7902 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7903 0,0,&target,exception);
7904 if (attribute_flag[0] != 0)
7905 (void) QueryColorCompliance(argument_list[0].string_reference,
7906 AllCompliance,&target,exception);
7907 if (attribute_flag[1] == 0)
7908 argument_list[1].string_reference="100%";
7909 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7910 exception);
7911 break;
7912 }
7913 case 5: /* Border */
7914 {
7915 CompositeOperator
7916 compose;
7917
7918 geometry.width=0;
7919 geometry.height=0;
7920 if (attribute_flag[0] != 0)
7921 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7922 &geometry,exception);
7923 if (attribute_flag[1] != 0)
7924 geometry.width=argument_list[1].integer_reference;
7925 if (attribute_flag[2] != 0)
7926 geometry.height=argument_list[2].integer_reference;
7927 if (attribute_flag[3] != 0)
7928 QueryColorCompliance(argument_list[3].string_reference,
7929 AllCompliance,&image->border_color,exception);
7930 if (attribute_flag[4] != 0)
7931 QueryColorCompliance(argument_list[4].string_reference,
7932 AllCompliance,&image->border_color,exception);
7933 if (attribute_flag[5] != 0)
7934 QueryColorCompliance(argument_list[5].string_reference,
7935 AllCompliance,&image->border_color,exception);
7936 compose=image->compose;
7937 if (attribute_flag[6] != 0)
7938 compose=(CompositeOperator) argument_list[6].integer_reference;
7939 image=BorderImage(image,&geometry,compose,exception);
7940 break;
7941 }
7942 case 6: /* Blur */
7943 {
7944 if (attribute_flag[0] != 0)
7945 {
7946 flags=ParseGeometry(argument_list[0].string_reference,
7947 &geometry_info);
7948 if ((flags & SigmaValue) == 0)
7949 geometry_info.sigma=1.0;
7950 }
7951 if (attribute_flag[1] != 0)
7952 geometry_info.rho=argument_list[1].real_reference;
7953 if (attribute_flag[2] != 0)
7954 geometry_info.sigma=argument_list[2].real_reference;
7955 if (attribute_flag[3] != 0)
7956 channel=(ChannelType) argument_list[3].integer_reference;
7957 channel_mask=SetImageChannelMask(image,channel);
7958 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
7959 exception);
7960 if (image != (Image *) NULL)
7961 (void) SetImageChannelMask(image,channel_mask);
7962 break;
7963 }
7964 case 7: /* Chop */
7965 {
cristy260bd762014-08-15 12:46:34 +00007966 if (attribute_flag[5] != 0)
7967 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00007968 if (attribute_flag[0] != 0)
7969 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7970 &geometry,exception);
7971 if (attribute_flag[1] != 0)
7972 geometry.width=argument_list[1].integer_reference;
7973 if (attribute_flag[2] != 0)
7974 geometry.height=argument_list[2].integer_reference;
7975 if (attribute_flag[3] != 0)
7976 geometry.x=argument_list[3].integer_reference;
7977 if (attribute_flag[4] != 0)
7978 geometry.y=argument_list[4].integer_reference;
7979 image=ChopImage(image,&geometry,exception);
7980 break;
7981 }
7982 case 8: /* Crop */
7983 {
7984 if (attribute_flag[6] != 0)
7985 image->gravity=(GravityType) argument_list[6].integer_reference;
7986 if (attribute_flag[0] != 0)
7987 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7988 &geometry,exception);
7989 if (attribute_flag[1] != 0)
7990 geometry.width=argument_list[1].integer_reference;
7991 if (attribute_flag[2] != 0)
7992 geometry.height=argument_list[2].integer_reference;
7993 if (attribute_flag[3] != 0)
7994 geometry.x=argument_list[3].integer_reference;
7995 if (attribute_flag[4] != 0)
7996 geometry.y=argument_list[4].integer_reference;
7997 if (attribute_flag[5] != 0)
7998 image->fuzz=StringToDoubleInterval(
7999 argument_list[5].string_reference,(double) QuantumRange+1.0);
8000 image=CropImage(image,&geometry,exception);
8001 break;
8002 }
8003 case 9: /* Despeckle */
8004 {
8005 image=DespeckleImage(image,exception);
8006 break;
8007 }
8008 case 10: /* Edge */
8009 {
8010 if (attribute_flag[0] != 0)
8011 geometry_info.rho=argument_list[0].real_reference;
8012 image=EdgeImage(image,geometry_info.rho,exception);
8013 break;
8014 }
8015 case 11: /* Emboss */
8016 {
8017 if (attribute_flag[0] != 0)
8018 {
8019 flags=ParseGeometry(argument_list[0].string_reference,
8020 &geometry_info);
8021 if ((flags & SigmaValue) == 0)
8022 geometry_info.sigma=1.0;
8023 }
8024 if (attribute_flag[1] != 0)
8025 geometry_info.rho=argument_list[1].real_reference;
8026 if (attribute_flag[2] != 0)
8027 geometry_info.sigma=argument_list[2].real_reference;
8028 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8029 exception);
8030 break;
8031 }
8032 case 12: /* Enhance */
8033 {
8034 image=EnhanceImage(image,exception);
8035 break;
8036 }
8037 case 13: /* Flip */
8038 {
8039 image=FlipImage(image,exception);
8040 break;
8041 }
8042 case 14: /* Flop */
8043 {
8044 image=FlopImage(image,exception);
8045 break;
8046 }
8047 case 15: /* Frame */
8048 {
8049 CompositeOperator
8050 compose;
8051
8052 FrameInfo
8053 frame_info;
8054
8055 if (attribute_flag[0] != 0)
8056 {
8057 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8058 &geometry,exception);
8059 frame_info.width=geometry.width;
8060 frame_info.height=geometry.height;
8061 frame_info.outer_bevel=geometry.x;
8062 frame_info.inner_bevel=geometry.y;
8063 }
8064 if (attribute_flag[1] != 0)
8065 frame_info.width=argument_list[1].integer_reference;
8066 if (attribute_flag[2] != 0)
8067 frame_info.height=argument_list[2].integer_reference;
8068 if (attribute_flag[3] != 0)
8069 frame_info.inner_bevel=argument_list[3].integer_reference;
8070 if (attribute_flag[4] != 0)
8071 frame_info.outer_bevel=argument_list[4].integer_reference;
8072 if (attribute_flag[5] != 0)
8073 QueryColorCompliance(argument_list[5].string_reference,
8074 AllCompliance,&fill_color,exception);
8075 if (attribute_flag[6] != 0)
8076 QueryColorCompliance(argument_list[6].string_reference,
8077 AllCompliance,&fill_color,exception);
8078 frame_info.x=(ssize_t) frame_info.width;
8079 frame_info.y=(ssize_t) frame_info.height;
8080 frame_info.width=image->columns+2*frame_info.x;
8081 frame_info.height=image->rows+2*frame_info.y;
8082 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
Cristy8645e042016-02-03 16:35:29 -05008083 image->alpha_color=fill_color;
cristy4a3ce0a2013-08-03 20:06:59 +00008084 compose=image->compose;
8085 if (attribute_flag[7] != 0)
8086 compose=(CompositeOperator) argument_list[7].integer_reference;
8087 image=FrameImage(image,&frame_info,compose,exception);
8088 break;
8089 }
8090 case 16: /* Implode */
8091 {
8092 PixelInterpolateMethod
8093 method;
8094
8095 if (attribute_flag[0] == 0)
8096 argument_list[0].real_reference=0.5;
8097 method=UndefinedInterpolatePixel;
8098 if (attribute_flag[1] != 0)
8099 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8100 image=ImplodeImage(image,argument_list[0].real_reference,
8101 method,exception);
8102 break;
8103 }
8104 case 17: /* Magnify */
8105 {
8106 image=MagnifyImage(image,exception);
8107 break;
8108 }
8109 case 18: /* MedianFilter */
8110 {
8111 if (attribute_flag[0] != 0)
8112 {
8113 flags=ParseGeometry(argument_list[0].string_reference,
8114 &geometry_info);
8115 if ((flags & SigmaValue) == 0)
8116 geometry_info.sigma=geometry_info.rho;
8117 }
8118 if (attribute_flag[1] != 0)
8119 geometry_info.rho=argument_list[1].real_reference;
8120 if (attribute_flag[2] != 0)
8121 geometry_info.sigma=argument_list[2].real_reference;
8122 if (attribute_flag[3] != 0)
8123 channel=(ChannelType) argument_list[3].integer_reference;
8124 channel_mask=SetImageChannelMask(image,channel);
8125 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8126 (size_t) geometry_info.sigma,exception);
8127 if (image != (Image *) NULL)
8128 (void) SetImageChannelMask(image,channel_mask);
8129 break;
8130 }
8131 case 19: /* Minify */
8132 {
8133 image=MinifyImage(image,exception);
8134 break;
8135 }
8136 case 20: /* OilPaint */
8137 {
8138 if (attribute_flag[0] == 0)
8139 argument_list[0].real_reference=0.0;
8140 if (attribute_flag[1] == 0)
8141 argument_list[1].real_reference=1.0;
8142 image=OilPaintImage(image,argument_list[0].real_reference,
8143 argument_list[1].real_reference,exception);
8144 break;
8145 }
8146 case 21: /* ReduceNoise */
8147 {
8148 if (attribute_flag[0] != 0)
8149 {
8150 flags=ParseGeometry(argument_list[0].string_reference,
8151 &geometry_info);
8152 if ((flags & SigmaValue) == 0)
8153 geometry_info.sigma=1.0;
8154 }
8155 if (attribute_flag[1] != 0)
8156 geometry_info.rho=argument_list[1].real_reference;
8157 if (attribute_flag[2] != 0)
8158 geometry_info.sigma=argument_list[2].real_reference;
8159 if (attribute_flag[3] != 0)
8160 channel=(ChannelType) argument_list[3].integer_reference;
8161 channel_mask=SetImageChannelMask(image,channel);
8162 image=StatisticImage(image,NonpeakStatistic,(size_t)
8163 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8164 if (image != (Image *) NULL)
8165 (void) SetImageChannelMask(image,channel_mask);
8166 break;
8167 }
8168 case 22: /* Roll */
8169 {
8170 if (attribute_flag[0] != 0)
8171 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8172 &geometry,exception);
8173 if (attribute_flag[1] != 0)
8174 geometry.x=argument_list[1].integer_reference;
8175 if (attribute_flag[2] != 0)
8176 geometry.y=argument_list[2].integer_reference;
8177 image=RollImage(image,geometry.x,geometry.y,exception);
8178 break;
8179 }
8180 case 23: /* Rotate */
8181 {
8182 if (attribute_flag[0] == 0)
8183 argument_list[0].real_reference=90.0;
8184 if (attribute_flag[1] != 0)
8185 {
8186 QueryColorCompliance(argument_list[1].string_reference,
8187 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008188 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8189 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008190 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8191 }
8192 image=RotateImage(image,argument_list[0].real_reference,exception);
8193 break;
8194 }
8195 case 24: /* Sample */
8196 {
8197 if (attribute_flag[0] != 0)
8198 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8199 &geometry,exception);
8200 if (attribute_flag[1] != 0)
8201 geometry.width=argument_list[1].integer_reference;
8202 if (attribute_flag[2] != 0)
8203 geometry.height=argument_list[2].integer_reference;
8204 image=SampleImage(image,geometry.width,geometry.height,exception);
8205 break;
8206 }
8207 case 25: /* Scale */
8208 {
8209 if (attribute_flag[0] != 0)
8210 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8211 &geometry,exception);
8212 if (attribute_flag[1] != 0)
8213 geometry.width=argument_list[1].integer_reference;
8214 if (attribute_flag[2] != 0)
8215 geometry.height=argument_list[2].integer_reference;
8216 image=ScaleImage(image,geometry.width,geometry.height,exception);
8217 break;
8218 }
8219 case 26: /* Shade */
8220 {
8221 if (attribute_flag[0] != 0)
8222 {
8223 flags=ParseGeometry(argument_list[0].string_reference,
8224 &geometry_info);
8225 if ((flags & SigmaValue) == 0)
8226 geometry_info.sigma=0.0;
8227 }
8228 if (attribute_flag[1] != 0)
8229 geometry_info.rho=argument_list[1].real_reference;
8230 if (attribute_flag[2] != 0)
8231 geometry_info.sigma=argument_list[2].real_reference;
8232 image=ShadeImage(image,
8233 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8234 geometry_info.rho,geometry_info.sigma,exception);
8235 break;
8236 }
8237 case 27: /* Sharpen */
8238 {
8239 if (attribute_flag[0] != 0)
8240 {
8241 flags=ParseGeometry(argument_list[0].string_reference,
8242 &geometry_info);
8243 if ((flags & SigmaValue) == 0)
8244 geometry_info.sigma=1.0;
8245 }
8246 if (attribute_flag[1] != 0)
8247 geometry_info.rho=argument_list[1].real_reference;
8248 if (attribute_flag[2] != 0)
8249 geometry_info.sigma=argument_list[2].real_reference;
8250 if (attribute_flag[3] != 0)
8251 channel=(ChannelType) argument_list[3].integer_reference;
8252 channel_mask=SetImageChannelMask(image,channel);
8253 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8254 exception);
8255 if (image != (Image *) NULL)
8256 (void) SetImageChannelMask(image,channel_mask);
8257 break;
8258 }
8259 case 28: /* Shear */
8260 {
8261 if (attribute_flag[0] != 0)
8262 {
8263 flags=ParseGeometry(argument_list[0].string_reference,
8264 &geometry_info);
8265 if ((flags & SigmaValue) == 0)
8266 geometry_info.sigma=geometry_info.rho;
8267 }
8268 if (attribute_flag[1] != 0)
8269 geometry_info.rho=argument_list[1].real_reference;
8270 if (attribute_flag[2] != 0)
8271 geometry_info.sigma=argument_list[2].real_reference;
8272 if (attribute_flag[3] != 0)
8273 QueryColorCompliance(argument_list[3].string_reference,
8274 AllCompliance,&image->background_color,exception);
8275 if (attribute_flag[4] != 0)
8276 QueryColorCompliance(argument_list[4].string_reference,
8277 AllCompliance,&image->background_color,exception);
8278 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8279 exception);
8280 break;
8281 }
8282 case 29: /* Spread */
8283 {
Cristye3319c12015-08-24 07:11:48 -04008284 PixelInterpolateMethod
8285 method;
8286
cristy4a3ce0a2013-08-03 20:06:59 +00008287 if (attribute_flag[0] == 0)
8288 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008289 method=UndefinedInterpolatePixel;
8290 if (attribute_flag[1] != 0)
8291 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8292 image=SpreadImage(image,method,argument_list[0].real_reference,
8293 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008294 break;
8295 }
8296 case 30: /* Swirl */
8297 {
8298 PixelInterpolateMethod
8299 method;
8300
8301 if (attribute_flag[0] == 0)
8302 argument_list[0].real_reference=50.0;
8303 method=UndefinedInterpolatePixel;
8304 if (attribute_flag[1] != 0)
8305 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8306 image=SwirlImage(image,argument_list[0].real_reference,
8307 method,exception);
8308 break;
8309 }
8310 case 31: /* Resize */
8311 case 32: /* Zoom */
8312 {
8313 if (attribute_flag[0] != 0)
8314 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8315 &geometry,exception);
8316 if (attribute_flag[1] != 0)
8317 geometry.width=argument_list[1].integer_reference;
8318 if (attribute_flag[2] != 0)
8319 geometry.height=argument_list[2].integer_reference;
8320 if (attribute_flag[3] == 0)
8321 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8322 if (attribute_flag[4] != 0)
8323 SetImageArtifact(image,"filter:support",
8324 argument_list[4].string_reference);
8325 image=ResizeImage(image,geometry.width,geometry.height,
Cristy8645e042016-02-03 16:35:29 -05008326 (FilterType) argument_list[3].integer_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00008327 exception);
8328 break;
8329 }
8330 case 33: /* Annotate */
8331 {
8332 DrawInfo
8333 *draw_info;
8334
8335 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8336 (DrawInfo *) NULL);
8337 if (attribute_flag[0] != 0)
8338 {
8339 char
8340 *text;
8341
8342 text=InterpretImageProperties(info ? info->image_info :
8343 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8344 exception);
8345 (void) CloneString(&draw_info->text,text);
8346 text=DestroyString(text);
8347 }
8348 if (attribute_flag[1] != 0)
8349 (void) CloneString(&draw_info->font,
8350 argument_list[1].string_reference);
8351 if (attribute_flag[2] != 0)
8352 draw_info->pointsize=argument_list[2].real_reference;
8353 if (attribute_flag[3] != 0)
8354 (void) CloneString(&draw_info->density,
8355 argument_list[3].string_reference);
8356 if (attribute_flag[4] != 0)
8357 (void) QueryColorCompliance(argument_list[4].string_reference,
8358 AllCompliance,&draw_info->undercolor,exception);
8359 if (attribute_flag[5] != 0)
8360 {
8361 (void) QueryColorCompliance(argument_list[5].string_reference,
8362 AllCompliance,&draw_info->stroke,exception);
8363 if (argument_list[5].image_reference != (Image *) NULL)
8364 draw_info->stroke_pattern=CloneImage(
8365 argument_list[5].image_reference,0,0,MagickTrue,exception);
8366 }
8367 if (attribute_flag[6] != 0)
8368 {
8369 (void) QueryColorCompliance(argument_list[6].string_reference,
8370 AllCompliance,&draw_info->fill,exception);
8371 if (argument_list[6].image_reference != (Image *) NULL)
8372 draw_info->fill_pattern=CloneImage(
8373 argument_list[6].image_reference,0,0,MagickTrue,exception);
8374 }
8375 if (attribute_flag[7] != 0)
8376 {
8377 (void) CloneString(&draw_info->geometry,
8378 argument_list[7].string_reference);
8379 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8380 &geometry,exception);
8381 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8382 geometry_info.sigma=geometry_info.xi;
8383 }
8384 if (attribute_flag[8] != 0)
8385 (void) QueryColorCompliance(argument_list[8].string_reference,
8386 AllCompliance,&draw_info->fill,exception);
8387 if (attribute_flag[11] != 0)
8388 draw_info->gravity=(GravityType)
8389 argument_list[11].integer_reference;
8390 if (attribute_flag[25] != 0)
8391 {
8392 AV
8393 *av;
8394
8395 av=(AV *) argument_list[25].array_reference;
8396 if ((av_len(av) != 3) && (av_len(av) != 5))
8397 {
8398 ThrowPerlException(exception,OptionError,
8399 "affine matrix must have 4 or 6 elements",PackageName);
8400 goto PerlException;
8401 }
8402 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8403 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8404 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8405 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8406 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8407 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8408 {
8409 ThrowPerlException(exception,OptionError,
8410 "affine matrix is singular",PackageName);
8411 goto PerlException;
8412 }
8413 if (av_len(av) == 5)
8414 {
8415 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8416 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8417 }
8418 }
8419 for (j=12; j < 17; j++)
8420 {
8421 if (attribute_flag[j] == 0)
8422 continue;
8423 value=argument_list[j].string_reference;
8424 angle=argument_list[j].real_reference;
8425 current=draw_info->affine;
8426 GetAffineMatrix(&affine);
8427 switch (j)
8428 {
8429 case 12:
8430 {
8431 /*
8432 Translate.
8433 */
8434 flags=ParseGeometry(value,&geometry_info);
8435 affine.tx=geometry_info.xi;
8436 affine.ty=geometry_info.psi;
8437 if ((flags & PsiValue) == 0)
8438 affine.ty=affine.tx;
8439 break;
8440 }
8441 case 13:
8442 {
8443 /*
8444 Scale.
8445 */
8446 flags=ParseGeometry(value,&geometry_info);
8447 affine.sx=geometry_info.rho;
8448 affine.sy=geometry_info.sigma;
8449 if ((flags & SigmaValue) == 0)
8450 affine.sy=affine.sx;
8451 break;
8452 }
8453 case 14:
8454 {
8455 /*
8456 Rotate.
8457 */
8458 if (angle == 0.0)
8459 break;
8460 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8461 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8462 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8463 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8464 break;
8465 }
8466 case 15:
8467 {
8468 /*
8469 SkewX.
8470 */
8471 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8472 break;
8473 }
8474 case 16:
8475 {
8476 /*
8477 SkewY.
8478 */
8479 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8480 break;
8481 }
8482 }
8483 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8484 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8485 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8486 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8487 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8488 current.tx;
8489 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8490 current.ty;
8491 }
8492 if (attribute_flag[9] == 0)
8493 argument_list[9].real_reference=0.0;
8494 if (attribute_flag[10] == 0)
8495 argument_list[10].real_reference=0.0;
8496 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8497 {
8498 char
cristy151b66d2015-04-15 10:50:31 +00008499 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008500
cristy151b66d2015-04-15 10:50:31 +00008501 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008502 (double) argument_list[9].real_reference+draw_info->affine.tx,
8503 (double) argument_list[10].real_reference+draw_info->affine.ty);
8504 (void) CloneString(&draw_info->geometry,geometry);
8505 }
8506 if (attribute_flag[17] != 0)
8507 draw_info->stroke_width=argument_list[17].real_reference;
8508 if (attribute_flag[18] != 0)
8509 {
8510 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8511 MagickTrue : MagickFalse;
8512 draw_info->stroke_antialias=draw_info->text_antialias;
8513 }
8514 if (attribute_flag[19] != 0)
8515 (void) CloneString(&draw_info->family,
8516 argument_list[19].string_reference);
8517 if (attribute_flag[20] != 0)
8518 draw_info->style=(StyleType) argument_list[20].integer_reference;
8519 if (attribute_flag[21] != 0)
8520 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8521 if (attribute_flag[22] != 0)
8522 draw_info->weight=argument_list[22].integer_reference;
8523 if (attribute_flag[23] != 0)
8524 draw_info->align=(AlignType) argument_list[23].integer_reference;
8525 if (attribute_flag[24] != 0)
8526 (void) CloneString(&draw_info->encoding,
8527 argument_list[24].string_reference);
8528 if (attribute_flag[25] != 0)
8529 draw_info->fill_pattern=CloneImage(
8530 argument_list[25].image_reference,0,0,MagickTrue,exception);
8531 if (attribute_flag[26] != 0)
8532 draw_info->fill_pattern=CloneImage(
8533 argument_list[26].image_reference,0,0,MagickTrue,exception);
8534 if (attribute_flag[27] != 0)
8535 draw_info->stroke_pattern=CloneImage(
8536 argument_list[27].image_reference,0,0,MagickTrue,exception);
8537 if (attribute_flag[29] != 0)
8538 draw_info->kerning=argument_list[29].real_reference;
8539 if (attribute_flag[30] != 0)
8540 draw_info->interline_spacing=argument_list[30].real_reference;
8541 if (attribute_flag[31] != 0)
8542 draw_info->interword_spacing=argument_list[31].real_reference;
8543 if (attribute_flag[32] != 0)
8544 draw_info->direction=(DirectionType)
8545 argument_list[32].integer_reference;
8546 (void) AnnotateImage(image,draw_info,exception);
8547 draw_info=DestroyDrawInfo(draw_info);
8548 break;
8549 }
8550 case 34: /* ColorFloodfill */
8551 {
8552 DrawInfo
8553 *draw_info;
8554
8555 MagickBooleanType
8556 invert;
8557
8558 PixelInfo
8559 target;
8560
8561 draw_info=CloneDrawInfo(info ? info->image_info :
8562 (ImageInfo *) NULL,(DrawInfo *) NULL);
8563 if (attribute_flag[0] != 0)
8564 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8565 &geometry,exception);
8566 if (attribute_flag[1] != 0)
8567 geometry.x=argument_list[1].integer_reference;
8568 if (attribute_flag[2] != 0)
8569 geometry.y=argument_list[2].integer_reference;
8570 if (attribute_flag[3] != 0)
8571 (void) QueryColorCompliance(argument_list[3].string_reference,
8572 AllCompliance,&draw_info->fill,exception);
8573 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8574 geometry.x,geometry.y,&target,exception);
8575 invert=MagickFalse;
8576 if (attribute_flag[4] != 0)
8577 {
8578 QueryColorCompliance(argument_list[4].string_reference,
8579 AllCompliance,&target,exception);
8580 invert=MagickTrue;
8581 }
8582 if (attribute_flag[5] != 0)
8583 image->fuzz=StringToDoubleInterval(
8584 argument_list[5].string_reference,(double) QuantumRange+1.0);
8585 if (attribute_flag[6] != 0)
8586 invert=(MagickBooleanType) argument_list[6].integer_reference;
8587 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8588 geometry.y,invert,exception);
8589 draw_info=DestroyDrawInfo(draw_info);
8590 break;
8591 }
8592 case 35: /* Composite */
8593 {
8594 char
cristy151b66d2015-04-15 10:50:31 +00008595 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008596
8597 Image
8598 *composite_image,
8599 *rotate_image;
8600
8601 MagickBooleanType
8602 clip_to_self;
8603
8604 compose=OverCompositeOp;
8605 if (attribute_flag[0] != 0)
8606 composite_image=argument_list[0].image_reference;
8607 else
8608 {
8609 ThrowPerlException(exception,OptionError,
8610 "CompositeImageRequired",PackageName);
8611 goto PerlException;
8612 }
8613 /*
8614 Parameter Handling used for BOTH normal and tiled composition.
8615 */
8616 if (attribute_flag[1] != 0) /* compose */
8617 compose=(CompositeOperator) argument_list[1].integer_reference;
8618 if (attribute_flag[6] != 0) /* opacity */
8619 {
8620 if (compose != DissolveCompositeOp)
8621 (void) SetImageAlpha(composite_image,(Quantum)
8622 StringToDoubleInterval(argument_list[6].string_reference,
8623 (double) QuantumRange+1.0),exception);
8624 else
8625 {
8626 CacheView
8627 *composite_view;
8628
8629 double
8630 opacity;
8631
8632 MagickBooleanType
8633 sync;
8634
8635 register ssize_t
8636 x;
8637
8638 register Quantum
8639 *q;
8640
8641 ssize_t
8642 y;
8643
8644 /*
8645 Handle dissolve composite operator (patch by
8646 Kevin A. McGrail).
8647 */
8648 (void) CloneString(&image->geometry,
8649 argument_list[6].string_reference);
8650 opacity=(Quantum) StringToDoubleInterval(
8651 argument_list[6].string_reference,(double) QuantumRange+
8652 1.0);
cristy17f11b02014-12-20 19:37:04 +00008653 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008654 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8655 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8656 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8657 {
8658 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8659 composite_image->columns,1,exception);
8660 for (x=0; x < (ssize_t) composite_image->columns; x++)
8661 {
8662 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8663 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8664 q);
8665 q+=GetPixelChannels(composite_image);
8666 }
8667 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8668 if (sync == MagickFalse)
8669 break;
8670 }
8671 composite_view=DestroyCacheView(composite_view);
8672 }
8673 }
8674 if (attribute_flag[9] != 0) /* "color=>" */
8675 QueryColorCompliance(argument_list[9].string_reference,
8676 AllCompliance,&composite_image->background_color,exception);
8677 if (attribute_flag[12] != 0) /* "interpolate=>" */
8678 image->interpolate=(PixelInterpolateMethod)
8679 argument_list[12].integer_reference;
8680 if (attribute_flag[13] != 0) /* "args=>" */
8681 (void) SetImageArtifact(composite_image,"compose:args",
8682 argument_list[13].string_reference);
8683 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8684 (void) SetImageArtifact(composite_image,"compose:args",
8685 argument_list[14].string_reference);
8686 clip_to_self=MagickTrue;
8687 if (attribute_flag[15] != 0)
8688 clip_to_self=(MagickBooleanType)
8689 argument_list[15].integer_reference;
8690 /*
8691 Tiling Composition (with orthogonal rotate).
8692 */
8693 rotate_image=(Image *) NULL;
8694 if (attribute_flag[8] != 0) /* "rotate=>" */
8695 {
8696 /*
8697 Rotate image.
8698 */
8699 rotate_image=RotateImage(composite_image,
8700 argument_list[8].real_reference,exception);
8701 if (rotate_image == (Image *) NULL)
8702 break;
8703 }
8704 if ((attribute_flag[7] != 0) &&
8705 (argument_list[7].integer_reference != 0)) /* tile */
8706 {
8707 ssize_t
8708 x,
8709 y;
8710
8711 /*
8712 Tile the composite image.
8713 */
8714 if (attribute_flag[8] != 0) /* "tile=>" */
8715 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8716 "false");
8717 else
8718 (void) SetImageArtifact(composite_image,
8719 "compose:outside-overlay","false");
8720 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8721 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8722 {
8723 if (attribute_flag[8] != 0) /* rotate */
8724 (void) CompositeImage(image,rotate_image,compose,
8725 MagickTrue,x,y,exception);
8726 else
8727 (void) CompositeImage(image,composite_image,compose,
8728 MagickTrue,x,y,exception);
8729 }
8730 if (attribute_flag[8] != 0) /* rotate */
8731 rotate_image=DestroyImage(rotate_image);
8732 break;
8733 }
8734 /*
8735 Parameter Handling used used ONLY for normal composition.
8736 */
8737 if (attribute_flag[5] != 0) /* gravity */
8738 image->gravity=(GravityType) argument_list[5].integer_reference;
8739 if (attribute_flag[2] != 0) /* geometry offset */
8740 {
8741 SetGeometry(image,&geometry);
8742 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8743 &geometry);
8744 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8745 &geometry);
8746 }
8747 if (attribute_flag[3] != 0) /* x offset */
8748 geometry.x=argument_list[3].integer_reference;
8749 if (attribute_flag[4] != 0) /* y offset */
8750 geometry.y=argument_list[4].integer_reference;
8751 if (attribute_flag[10] != 0) /* mask */
8752 {
8753 if ((image->compose == DisplaceCompositeOp) ||
8754 (image->compose == DistortCompositeOp))
8755 {
8756 /*
8757 Merge Y displacement into X displacement image.
8758 */
8759 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8760 exception);
8761 (void) CompositeImage(composite_image,
8762 argument_list[10].image_reference,CopyGreenCompositeOp,
8763 MagickTrue,0,0,exception);
8764 }
8765 else
8766 {
8767 Image
8768 *mask_image;
8769
8770 /*
8771 Set a blending mask for the composition.
8772 */
8773 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8774 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008775 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008776 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008777 mask_image=DestroyImage(mask_image);
8778 }
8779 }
8780 if (attribute_flag[11] != 0) /* channel */
8781 channel=(ChannelType) argument_list[11].integer_reference;
8782 /*
8783 Composite two images (normal composition).
8784 */
cristy151b66d2015-04-15 10:50:31 +00008785 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008786 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8787 (double) composite_image->rows,(double) geometry.x,(double)
8788 geometry.y);
8789 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8790 exception);
8791 channel_mask=SetImageChannelMask(image,channel);
8792 if (attribute_flag[8] == 0) /* no rotate */
8793 CompositeImage(image,composite_image,compose,clip_to_self,
8794 geometry.x,geometry.y,exception);
8795 else
8796 {
8797 /*
8798 Position adjust rotated image then composite.
8799 */
8800 geometry.x-=(ssize_t) (rotate_image->columns-
8801 composite_image->columns)/2;
8802 geometry.y-=(ssize_t) (rotate_image->rows-
8803 composite_image->rows)/2;
8804 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8805 geometry.y,exception);
8806 rotate_image=DestroyImage(rotate_image);
8807 }
8808 if (attribute_flag[10] != 0) /* mask */
8809 {
8810 if ((image->compose == DisplaceCompositeOp) ||
8811 (image->compose == DistortCompositeOp))
8812 composite_image=DestroyImage(composite_image);
8813 else
cristy1f7ffb72015-07-29 11:07:03 +00008814 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008815 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008816 }
8817 (void) SetImageChannelMask(image,channel_mask);
8818 break;
8819 }
8820 case 36: /* Contrast */
8821 {
8822 if (attribute_flag[0] == 0)
8823 argument_list[0].integer_reference=0;
8824 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8825 MagickTrue : MagickFalse,exception);
8826 break;
8827 }
8828 case 37: /* CycleColormap */
8829 {
8830 if (attribute_flag[0] == 0)
8831 argument_list[0].integer_reference=6;
8832 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8833 exception);
8834 break;
8835 }
8836 case 38: /* Draw */
8837 {
8838 DrawInfo
8839 *draw_info;
8840
8841 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8842 (DrawInfo *) NULL);
8843 (void) CloneString(&draw_info->primitive,"point");
8844 if (attribute_flag[0] != 0)
8845 {
8846 if (argument_list[0].integer_reference < 0)
8847 (void) CloneString(&draw_info->primitive,
8848 argument_list[0].string_reference);
8849 else
8850 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8851 MagickPrimitiveOptions,argument_list[0].integer_reference));
8852 }
8853 if (attribute_flag[1] != 0)
8854 {
8855 if (LocaleCompare(draw_info->primitive,"path") == 0)
8856 {
8857 (void) ConcatenateString(&draw_info->primitive," '");
8858 ConcatenateString(&draw_info->primitive,
8859 argument_list[1].string_reference);
8860 (void) ConcatenateString(&draw_info->primitive,"'");
8861 }
8862 else
8863 {
8864 (void) ConcatenateString(&draw_info->primitive," ");
8865 ConcatenateString(&draw_info->primitive,
8866 argument_list[1].string_reference);
8867 }
8868 }
8869 if (attribute_flag[2] != 0)
8870 {
8871 (void) ConcatenateString(&draw_info->primitive," ");
8872 (void) ConcatenateString(&draw_info->primitive,
8873 CommandOptionToMnemonic(MagickMethodOptions,
8874 argument_list[2].integer_reference));
8875 }
8876 if (attribute_flag[3] != 0)
8877 {
8878 (void) QueryColorCompliance(argument_list[3].string_reference,
8879 AllCompliance,&draw_info->stroke,exception);
8880 if (argument_list[3].image_reference != (Image *) NULL)
8881 draw_info->stroke_pattern=CloneImage(
8882 argument_list[3].image_reference,0,0,MagickTrue,exception);
8883 }
8884 if (attribute_flag[4] != 0)
8885 {
8886 (void) QueryColorCompliance(argument_list[4].string_reference,
8887 AllCompliance,&draw_info->fill,exception);
8888 if (argument_list[4].image_reference != (Image *) NULL)
8889 draw_info->fill_pattern=CloneImage(
8890 argument_list[4].image_reference,0,0,MagickTrue,exception);
8891 }
8892 if (attribute_flag[5] != 0)
8893 draw_info->stroke_width=argument_list[5].real_reference;
8894 if (attribute_flag[6] != 0)
8895 (void) CloneString(&draw_info->font,
8896 argument_list[6].string_reference);
8897 if (attribute_flag[7] != 0)
8898 (void) QueryColorCompliance(argument_list[7].string_reference,
8899 AllCompliance,&draw_info->border_color,exception);
8900 if (attribute_flag[8] != 0)
8901 draw_info->affine.tx=argument_list[8].real_reference;
8902 if (attribute_flag[9] != 0)
8903 draw_info->affine.ty=argument_list[9].real_reference;
8904 if (attribute_flag[20] != 0)
8905 {
8906 AV
8907 *av;
8908
8909 av=(AV *) argument_list[20].array_reference;
8910 if ((av_len(av) != 3) && (av_len(av) != 5))
8911 {
8912 ThrowPerlException(exception,OptionError,
8913 "affine matrix must have 4 or 6 elements",PackageName);
8914 goto PerlException;
8915 }
8916 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8917 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8918 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8919 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8920 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8921 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8922 {
8923 ThrowPerlException(exception,OptionError,
8924 "affine matrix is singular",PackageName);
8925 goto PerlException;
8926 }
8927 if (av_len(av) == 5)
8928 {
8929 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8930 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8931 }
8932 }
8933 for (j=10; j < 15; j++)
8934 {
8935 if (attribute_flag[j] == 0)
8936 continue;
8937 value=argument_list[j].string_reference;
8938 angle=argument_list[j].real_reference;
8939 current=draw_info->affine;
8940 GetAffineMatrix(&affine);
8941 switch (j)
8942 {
8943 case 10:
8944 {
8945 /*
8946 Translate.
8947 */
8948 flags=ParseGeometry(value,&geometry_info);
8949 affine.tx=geometry_info.xi;
8950 affine.ty=geometry_info.psi;
8951 if ((flags & PsiValue) == 0)
8952 affine.ty=affine.tx;
8953 break;
8954 }
8955 case 11:
8956 {
8957 /*
8958 Scale.
8959 */
8960 flags=ParseGeometry(value,&geometry_info);
8961 affine.sx=geometry_info.rho;
8962 affine.sy=geometry_info.sigma;
8963 if ((flags & SigmaValue) == 0)
8964 affine.sy=affine.sx;
8965 break;
8966 }
8967 case 12:
8968 {
8969 /*
8970 Rotate.
8971 */
8972 if (angle == 0.0)
8973 break;
8974 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8975 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8976 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8977 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8978 break;
8979 }
8980 case 13:
8981 {
8982 /*
8983 SkewX.
8984 */
8985 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8986 break;
8987 }
8988 case 14:
8989 {
8990 /*
8991 SkewY.
8992 */
8993 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8994 break;
8995 }
8996 }
8997 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8998 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8999 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9000 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9001 draw_info->affine.tx=
9002 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9003 draw_info->affine.ty=
9004 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9005 }
9006 if (attribute_flag[15] != 0)
9007 draw_info->fill_pattern=CloneImage(
9008 argument_list[15].image_reference,0,0,MagickTrue,exception);
9009 if (attribute_flag[16] != 0)
9010 draw_info->pointsize=argument_list[16].real_reference;
9011 if (attribute_flag[17] != 0)
9012 {
9013 draw_info->stroke_antialias=argument_list[17].integer_reference != 0
9014 ? MagickTrue : MagickFalse;
9015 draw_info->text_antialias=draw_info->stroke_antialias;
9016 }
9017 if (attribute_flag[18] != 0)
9018 (void) CloneString(&draw_info->density,
9019 argument_list[18].string_reference);
9020 if (attribute_flag[19] != 0)
9021 draw_info->stroke_width=argument_list[19].real_reference;
9022 if (attribute_flag[21] != 0)
9023 draw_info->dash_offset=argument_list[21].real_reference;
9024 if (attribute_flag[22] != 0)
9025 {
9026 AV
9027 *av;
9028
9029 av=(AV *) argument_list[22].array_reference;
9030 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9031 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9032 if (draw_info->dash_pattern != (double *) NULL)
9033 {
9034 for (i=0; i <= av_len(av); i++)
9035 draw_info->dash_pattern[i]=(double)
9036 SvNV(*(av_fetch(av,i,0)));
9037 draw_info->dash_pattern[i]=0.0;
9038 }
9039 }
9040 if (attribute_flag[23] != 0)
9041 image->interpolate=(PixelInterpolateMethod)
9042 argument_list[23].integer_reference;
9043 if ((attribute_flag[24] != 0) &&
9044 (draw_info->fill_pattern != (Image *) NULL))
9045 flags=ParsePageGeometry(draw_info->fill_pattern,
9046 argument_list[24].string_reference,
9047 &draw_info->fill_pattern->tile_offset,exception);
9048 if (attribute_flag[25] != 0)
9049 {
9050 (void) ConcatenateString(&draw_info->primitive," '");
9051 (void) ConcatenateString(&draw_info->primitive,
9052 argument_list[25].string_reference);
9053 (void) ConcatenateString(&draw_info->primitive,"'");
9054 }
9055 if (attribute_flag[26] != 0)
9056 draw_info->fill_pattern=CloneImage(
9057 argument_list[26].image_reference,0,0,MagickTrue,exception);
9058 if (attribute_flag[27] != 0)
9059 draw_info->stroke_pattern=CloneImage(
9060 argument_list[27].image_reference,0,0,MagickTrue,exception);
9061 if (attribute_flag[28] != 0)
9062 (void) CloneString(&draw_info->primitive,
9063 argument_list[28].string_reference);
9064 if (attribute_flag[29] != 0)
9065 draw_info->kerning=argument_list[29].real_reference;
9066 if (attribute_flag[30] != 0)
9067 draw_info->interline_spacing=argument_list[30].real_reference;
9068 if (attribute_flag[31] != 0)
9069 draw_info->interword_spacing=argument_list[31].real_reference;
9070 if (attribute_flag[32] != 0)
9071 draw_info->direction=(DirectionType)
9072 argument_list[32].integer_reference;
9073 DrawImage(image,draw_info,exception);
9074 draw_info=DestroyDrawInfo(draw_info);
9075 break;
9076 }
9077 case 39: /* Equalize */
9078 {
9079 if (attribute_flag[0] != 0)
9080 channel=(ChannelType) argument_list[0].integer_reference;
9081 channel_mask=SetImageChannelMask(image,channel);
9082 EqualizeImage(image,exception);
9083 (void) SetImageChannelMask(image,channel_mask);
9084 break;
9085 }
9086 case 40: /* Gamma */
9087 {
9088 if (attribute_flag[1] != 0)
9089 channel=(ChannelType) argument_list[1].integer_reference;
9090 if (attribute_flag[2] == 0)
9091 argument_list[2].real_reference=1.0;
9092 if (attribute_flag[3] == 0)
9093 argument_list[3].real_reference=1.0;
9094 if (attribute_flag[4] == 0)
9095 argument_list[4].real_reference=1.0;
9096 if (attribute_flag[0] == 0)
9097 {
cristy151b66d2015-04-15 10:50:31 +00009098 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00009099 "%.15g,%.15g,%.15g",(double) argument_list[2].real_reference,
9100 (double) argument_list[3].real_reference,
9101 (double) argument_list[4].real_reference);
9102 argument_list[0].string_reference=message;
9103 }
9104 (void) GammaImage(image,StringToDouble(
9105 argument_list[0].string_reference,(char **) NULL),exception);
9106 break;
9107 }
9108 case 41: /* Map */
9109 {
9110 QuantizeInfo
9111 *quantize_info;
9112
9113 if (attribute_flag[0] == 0)
9114 {
9115 ThrowPerlException(exception,OptionError,"MapImageRequired",
9116 PackageName);
9117 goto PerlException;
9118 }
9119 quantize_info=AcquireQuantizeInfo(info->image_info);
9120 if (attribute_flag[1] != 0)
9121 quantize_info->dither_method=(DitherMethod)
9122 argument_list[1].integer_reference;
9123 (void) RemapImages(quantize_info,image,
9124 argument_list[0].image_reference,exception);
9125 quantize_info=DestroyQuantizeInfo(quantize_info);
9126 break;
9127 }
9128 case 42: /* MatteFloodfill */
9129 {
9130 DrawInfo
9131 *draw_info;
9132
9133 MagickBooleanType
9134 invert;
9135
9136 PixelInfo
9137 target;
9138
9139 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9140 (DrawInfo *) NULL);
9141 if (attribute_flag[0] != 0)
9142 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9143 &geometry,exception);
9144 if (attribute_flag[1] != 0)
9145 geometry.x=argument_list[1].integer_reference;
9146 if (attribute_flag[2] != 0)
9147 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009148 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009149 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9150 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9151 geometry.x,geometry.y,&target,exception);
9152 if (attribute_flag[4] != 0)
9153 QueryColorCompliance(argument_list[4].string_reference,
9154 AllCompliance,&target,exception);
9155 if (attribute_flag[3] != 0)
9156 target.alpha=StringToDoubleInterval(
9157 argument_list[3].string_reference,(double) (double) QuantumRange+
9158 1.0);
9159 if (attribute_flag[5] != 0)
9160 image->fuzz=StringToDoubleInterval(
9161 argument_list[5].string_reference,(double) QuantumRange+1.0);
9162 invert=MagickFalse;
9163 if (attribute_flag[6] != 0)
9164 invert=(MagickBooleanType) argument_list[6].integer_reference;
9165 channel_mask=SetImageChannelMask(image,AlphaChannel);
9166 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9167 geometry.y,invert,exception);
9168 (void) SetImageChannelMask(image,channel_mask);
9169 draw_info=DestroyDrawInfo(draw_info);
9170 break;
9171 }
9172 case 43: /* Modulate */
9173 {
9174 char
cristy151b66d2015-04-15 10:50:31 +00009175 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009176
9177 geometry_info.rho=100.0;
9178 geometry_info.sigma=100.0;
9179 geometry_info.xi=100.0;
9180 if (attribute_flag[0] != 0)
9181 (void)ParseGeometry(argument_list[0].string_reference,
9182 &geometry_info);
9183 if (attribute_flag[1] != 0)
9184 geometry_info.xi=argument_list[1].real_reference;
9185 if (attribute_flag[2] != 0)
9186 geometry_info.sigma=argument_list[2].real_reference;
9187 if (attribute_flag[3] != 0)
9188 {
9189 geometry_info.sigma=argument_list[3].real_reference;
9190 SetImageArtifact(image,"modulate:colorspace","HWB");
9191 }
9192 if (attribute_flag[4] != 0)
9193 {
9194 geometry_info.rho=argument_list[4].real_reference;
9195 SetImageArtifact(image,"modulate:colorspace","HSB");
9196 }
9197 if (attribute_flag[5] != 0)
9198 {
9199 geometry_info.sigma=argument_list[5].real_reference;
9200 SetImageArtifact(image,"modulate:colorspace","HSL");
9201 }
9202 if (attribute_flag[6] != 0)
9203 {
9204 geometry_info.rho=argument_list[6].real_reference;
9205 SetImageArtifact(image,"modulate:colorspace","HWB");
9206 }
cristy151b66d2015-04-15 10:50:31 +00009207 (void) FormatLocaleString(modulate,MagickPathExtent,"%.15g,%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00009208 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
9209 (void) ModulateImage(image,modulate,exception);
9210 break;
9211 }
9212 case 44: /* Negate */
9213 {
9214 if (attribute_flag[0] == 0)
9215 argument_list[0].integer_reference=0;
9216 if (attribute_flag[1] != 0)
9217 channel=(ChannelType) argument_list[1].integer_reference;
9218 channel_mask=SetImageChannelMask(image,channel);
9219 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9220 MagickTrue : MagickFalse,exception);
9221 (void) SetImageChannelMask(image,channel_mask);
9222 break;
9223 }
9224 case 45: /* Normalize */
9225 {
9226 if (attribute_flag[0] != 0)
9227 channel=(ChannelType) argument_list[0].integer_reference;
9228 channel_mask=SetImageChannelMask(image,channel);
9229 NormalizeImage(image,exception);
9230 (void) SetImageChannelMask(image,channel_mask);
9231 break;
9232 }
9233 case 46: /* NumberColors */
9234 break;
9235 case 47: /* Opaque */
9236 {
9237 MagickBooleanType
9238 invert;
9239
9240 PixelInfo
9241 fill_color,
9242 target;
9243
9244 (void) QueryColorCompliance("none",AllCompliance,&target,
9245 exception);
9246 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9247 exception);
9248 if (attribute_flag[0] != 0)
9249 (void) QueryColorCompliance(argument_list[0].string_reference,
9250 AllCompliance,&target,exception);
9251 if (attribute_flag[1] != 0)
9252 (void) QueryColorCompliance(argument_list[1].string_reference,
9253 AllCompliance,&fill_color,exception);
9254 if (attribute_flag[2] != 0)
9255 image->fuzz=StringToDoubleInterval(
9256 argument_list[2].string_reference,(double) QuantumRange+1.0);
9257 if (attribute_flag[3] != 0)
9258 channel=(ChannelType) argument_list[3].integer_reference;
9259 invert=MagickFalse;
9260 if (attribute_flag[4] != 0)
9261 invert=(MagickBooleanType) argument_list[4].integer_reference;
9262 channel_mask=SetImageChannelMask(image,channel);
9263 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9264 (void) SetImageChannelMask(image,channel_mask);
9265 break;
9266 }
9267 case 48: /* Quantize */
9268 {
9269 QuantizeInfo
9270 *quantize_info;
9271
9272 quantize_info=AcquireQuantizeInfo(info->image_info);
9273 if (attribute_flag[0] != 0)
9274 quantize_info->number_colors=(size_t)
9275 argument_list[0].integer_reference;
9276 if (attribute_flag[1] != 0)
9277 quantize_info->tree_depth=(size_t)
9278 argument_list[1].integer_reference;
9279 if (attribute_flag[2] != 0)
9280 quantize_info->colorspace=(ColorspaceType)
9281 argument_list[2].integer_reference;
9282 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009283 quantize_info->dither_method=(DitherMethod)
9284 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009285 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009286 quantize_info->measure_error=
9287 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009288 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009289 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009290 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009291 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009292 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009293 argument_list[7].integer_reference;
9294 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009295 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009296 else
cristyf7563392014-03-25 13:54:04 +00009297 if ((image->storage_class == DirectClass) ||
9298 (image->colors > quantize_info->number_colors) ||
9299 (quantize_info->colorspace == GRAYColorspace))
9300 (void) QuantizeImage(quantize_info,image,exception);
9301 else
9302 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009303 quantize_info=DestroyQuantizeInfo(quantize_info);
9304 break;
9305 }
9306 case 49: /* Raise */
9307 {
9308 if (attribute_flag[0] != 0)
9309 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9310 &geometry,exception);
9311 if (attribute_flag[1] != 0)
9312 geometry.width=argument_list[1].integer_reference;
9313 if (attribute_flag[2] != 0)
9314 geometry.height=argument_list[2].integer_reference;
9315 if (attribute_flag[3] == 0)
9316 argument_list[3].integer_reference=1;
9317 (void) RaiseImage(image,&geometry,
9318 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9319 exception);
9320 break;
9321 }
9322 case 50: /* Segment */
9323 {
9324 ColorspaceType
9325 colorspace;
9326
9327 double
9328 cluster_threshold,
9329 smoothing_threshold;
9330
9331 MagickBooleanType
9332 verbose;
9333
9334 cluster_threshold=1.0;
9335 smoothing_threshold=1.5;
9336 colorspace=sRGBColorspace;
9337 verbose=MagickFalse;
9338 if (attribute_flag[0] != 0)
9339 {
9340 flags=ParseGeometry(argument_list[0].string_reference,
9341 &geometry_info);
9342 cluster_threshold=geometry_info.rho;
9343 if (flags & SigmaValue)
9344 smoothing_threshold=geometry_info.sigma;
9345 }
9346 if (attribute_flag[1] != 0)
9347 cluster_threshold=argument_list[1].real_reference;
9348 if (attribute_flag[2] != 0)
9349 smoothing_threshold=argument_list[2].real_reference;
9350 if (attribute_flag[3] != 0)
9351 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9352 if (attribute_flag[4] != 0)
9353 verbose=argument_list[4].integer_reference != 0 ?
9354 MagickTrue : MagickFalse;
9355 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9356 smoothing_threshold,exception);
9357 break;
9358 }
9359 case 51: /* Signature */
9360 {
9361 (void) SignatureImage(image,exception);
9362 break;
9363 }
9364 case 52: /* Solarize */
9365 {
9366 geometry_info.rho=QuantumRange/2.0;
9367 if (attribute_flag[0] != 0)
9368 flags=ParseGeometry(argument_list[0].string_reference,
9369 &geometry_info);
9370 if (attribute_flag[1] != 0)
9371 geometry_info.rho=StringToDoubleInterval(
9372 argument_list[1].string_reference,(double) QuantumRange+1.0);
9373 (void) SolarizeImage(image,geometry_info.rho,exception);
9374 break;
9375 }
9376 case 53: /* Sync */
9377 {
9378 (void) SyncImage(image,exception);
9379 break;
9380 }
9381 case 54: /* Texture */
9382 {
9383 if (attribute_flag[0] == 0)
9384 break;
9385 TextureImage(image,argument_list[0].image_reference,exception);
9386 break;
9387 }
9388 case 55: /* Evalute */
9389 {
9390 MagickEvaluateOperator
9391 op;
9392
9393 op=SetEvaluateOperator;
9394 if (attribute_flag[0] == MagickFalse)
9395 argument_list[0].real_reference=0.0;
9396 if (attribute_flag[1] != MagickFalse)
9397 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9398 if (attribute_flag[2] != MagickFalse)
9399 channel=(ChannelType) argument_list[2].integer_reference;
9400 channel_mask=SetImageChannelMask(image,channel);
9401 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9402 exception);
9403 (void) SetImageChannelMask(image,channel_mask);
9404 break;
9405 }
9406 case 56: /* Transparent */
9407 {
9408 double
9409 opacity;
9410
9411 MagickBooleanType
9412 invert;
9413
9414 PixelInfo
9415 target;
9416
9417 (void) QueryColorCompliance("none",AllCompliance,&target,
9418 exception);
9419 if (attribute_flag[0] != 0)
9420 (void) QueryColorCompliance(argument_list[0].string_reference,
9421 AllCompliance,&target,exception);
9422 opacity=TransparentAlpha;
9423 if (attribute_flag[1] != 0)
9424 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9425 (double) QuantumRange+1.0);
9426 if (attribute_flag[2] != 0)
9427 image->fuzz=StringToDoubleInterval(
9428 argument_list[2].string_reference,(double) QuantumRange+1.0);
9429 if (attribute_flag[3] == 0)
9430 argument_list[3].integer_reference=0;
9431 invert=MagickFalse;
9432 if (attribute_flag[3] != 0)
9433 invert=(MagickBooleanType) argument_list[3].integer_reference;
9434 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9435 invert,exception);
9436 break;
9437 }
9438 case 57: /* Threshold */
9439 {
9440 double
9441 threshold;
9442
9443 if (attribute_flag[0] == 0)
9444 argument_list[0].string_reference="50%";
9445 if (attribute_flag[1] != 0)
9446 channel=(ChannelType) argument_list[1].integer_reference;
9447 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9448 (double) QuantumRange+1.0);
9449 channel_mask=SetImageChannelMask(image,channel);
9450 (void) BilevelImage(image,threshold,exception);
9451 (void) SetImageChannelMask(image,channel_mask);
9452 break;
9453 }
9454 case 58: /* Charcoal */
9455 {
9456 if (attribute_flag[0] != 0)
9457 {
9458 flags=ParseGeometry(argument_list[0].string_reference,
9459 &geometry_info);
9460 if ((flags & SigmaValue) == 0)
9461 geometry_info.sigma=1.0;
9462 }
9463 if (attribute_flag[1] != 0)
9464 geometry_info.rho=argument_list[1].real_reference;
9465 if (attribute_flag[2] != 0)
9466 geometry_info.sigma=argument_list[2].real_reference;
9467 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9468 exception);
9469 break;
9470 }
9471 case 59: /* Trim */
9472 {
9473 if (attribute_flag[0] != 0)
9474 image->fuzz=StringToDoubleInterval(
9475 argument_list[0].string_reference,(double) QuantumRange+1.0);
9476 image=TrimImage(image,exception);
9477 break;
9478 }
9479 case 60: /* Wave */
9480 {
9481 PixelInterpolateMethod
9482 method;
9483
9484 if (attribute_flag[0] != 0)
9485 {
9486 flags=ParseGeometry(argument_list[0].string_reference,
9487 &geometry_info);
9488 if ((flags & SigmaValue) == 0)
9489 geometry_info.sigma=1.0;
9490 }
9491 if (attribute_flag[1] != 0)
9492 geometry_info.rho=argument_list[1].real_reference;
9493 if (attribute_flag[2] != 0)
9494 geometry_info.sigma=argument_list[2].real_reference;
9495 method=UndefinedInterpolatePixel;
9496 if (attribute_flag[3] != 0)
9497 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9498 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9499 method,exception);
9500 break;
9501 }
9502 case 61: /* Separate */
9503 {
9504 if (attribute_flag[0] != 0)
9505 channel=(ChannelType) argument_list[0].integer_reference;
9506 image=SeparateImage(image,channel,exception);
9507 break;
9508 }
9509 case 63: /* Stereo */
9510 {
9511 if (attribute_flag[0] == 0)
9512 {
9513 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9514 PackageName);
9515 goto PerlException;
9516 }
9517 if (attribute_flag[1] != 0)
9518 geometry.x=argument_list[1].integer_reference;
9519 if (attribute_flag[2] != 0)
9520 geometry.y=argument_list[2].integer_reference;
9521 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9522 geometry.x,geometry.y,exception);
9523 break;
9524 }
9525 case 64: /* Stegano */
9526 {
9527 if (attribute_flag[0] == 0)
9528 {
9529 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9530 PackageName);
9531 goto PerlException;
9532 }
9533 if (attribute_flag[1] == 0)
9534 argument_list[1].integer_reference=0;
9535 image->offset=argument_list[1].integer_reference;
9536 image=SteganoImage(image,argument_list[0].image_reference,exception);
9537 break;
9538 }
9539 case 65: /* Deconstruct */
9540 {
9541 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9542 break;
9543 }
9544 case 66: /* GaussianBlur */
9545 {
9546 if (attribute_flag[0] != 0)
9547 {
9548 flags=ParseGeometry(argument_list[0].string_reference,
9549 &geometry_info);
9550 if ((flags & SigmaValue) == 0)
9551 geometry_info.sigma=1.0;
9552 }
9553 if (attribute_flag[1] != 0)
9554 geometry_info.rho=argument_list[1].real_reference;
9555 if (attribute_flag[2] != 0)
9556 geometry_info.sigma=argument_list[2].real_reference;
9557 if (attribute_flag[3] != 0)
9558 channel=(ChannelType) argument_list[3].integer_reference;
9559 channel_mask=SetImageChannelMask(image,channel);
9560 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9561 exception);
9562 if (image != (Image *) NULL)
9563 (void) SetImageChannelMask(image,channel_mask);
9564 break;
9565 }
9566 case 67: /* Convolve */
9567 {
9568 KernelInfo
9569 *kernel;
9570
9571 kernel=(KernelInfo *) NULL;
9572 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9573 break;
9574 if (attribute_flag[0] != 0)
9575 {
9576 AV
9577 *av;
9578
9579 size_t
9580 order;
9581
cristy2c57b742014-10-31 00:40:34 +00009582 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009583 if (kernel == (KernelInfo *) NULL)
9584 break;
9585 av=(AV *) argument_list[0].array_reference;
9586 order=(size_t) sqrt(av_len(av)+1);
9587 kernel->width=order;
9588 kernel->height=order;
9589 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9590 order*sizeof(*kernel->values));
9591 if (kernel->values == (MagickRealType *) NULL)
9592 {
9593 kernel=DestroyKernelInfo(kernel);
9594 ThrowPerlException(exception,ResourceLimitFatalError,
9595 "MemoryAllocationFailed",PackageName);
9596 goto PerlException;
9597 }
9598 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9599 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9600 for ( ; j < (ssize_t) (order*order); j++)
9601 kernel->values[j]=0.0;
9602 }
9603 if (attribute_flag[1] != 0)
9604 channel=(ChannelType) argument_list[1].integer_reference;
9605 if (attribute_flag[2] != 0)
9606 SetImageArtifact(image,"filter:blur",
9607 argument_list[2].string_reference);
9608 if (attribute_flag[3] != 0)
9609 {
cristy2c57b742014-10-31 00:40:34 +00009610 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9611 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009612 if (kernel == (KernelInfo *) NULL)
9613 break;
9614 }
9615 channel_mask=SetImageChannelMask(image,channel);
9616 image=ConvolveImage(image,kernel,exception);
9617 if (image != (Image *) NULL)
9618 (void) SetImageChannelMask(image,channel_mask);
9619 kernel=DestroyKernelInfo(kernel);
9620 break;
9621 }
9622 case 68: /* Profile */
9623 {
9624 const char
9625 *name;
9626
9627 Image
9628 *profile_image;
9629
9630 ImageInfo
9631 *profile_info;
9632
9633 StringInfo
9634 *profile;
9635
9636 name="*";
9637 if (attribute_flag[0] != 0)
9638 name=argument_list[0].string_reference;
9639 if (attribute_flag[2] != 0)
9640 image->rendering_intent=(RenderingIntent)
9641 argument_list[2].integer_reference;
9642 if (attribute_flag[3] != 0)
9643 image->black_point_compensation=
9644 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9645 if (attribute_flag[1] != 0)
9646 {
9647 if (argument_list[1].length == 0)
9648 {
9649 /*
9650 Remove a profile from the image.
9651 */
9652 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9653 exception);
9654 break;
9655 }
9656 /*
9657 Associate user supplied profile with the image.
9658 */
9659 profile=AcquireStringInfo(argument_list[1].length);
9660 SetStringInfoDatum(profile,(const unsigned char *)
9661 argument_list[1].string_reference);
9662 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9663 (size_t) GetStringInfoLength(profile),exception);
9664 profile=DestroyStringInfo(profile);
9665 break;
9666 }
9667 /*
9668 Associate a profile with the image.
9669 */
9670 profile_info=CloneImageInfo(info ? info->image_info :
9671 (ImageInfo *) NULL);
9672 profile_image=ReadImages(profile_info,name,exception);
9673 if (profile_image == (Image *) NULL)
9674 break;
9675 ResetImageProfileIterator(profile_image);
9676 name=GetNextImageProfile(profile_image);
9677 while (name != (const char *) NULL)
9678 {
9679 const StringInfo
9680 *profile;
9681
9682 profile=GetImageProfile(profile_image,name);
9683 if (profile != (const StringInfo *) NULL)
9684 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9685 (size_t) GetStringInfoLength(profile),exception);
9686 name=GetNextImageProfile(profile_image);
9687 }
9688 profile_image=DestroyImage(profile_image);
9689 profile_info=DestroyImageInfo(profile_info);
9690 break;
9691 }
9692 case 69: /* UnsharpMask */
9693 {
9694 if (attribute_flag[0] != 0)
9695 {
9696 flags=ParseGeometry(argument_list[0].string_reference,
9697 &geometry_info);
9698 if ((flags & SigmaValue) == 0)
9699 geometry_info.sigma=1.0;
9700 if ((flags & XiValue) == 0)
9701 geometry_info.xi=1.0;
9702 if ((flags & PsiValue) == 0)
9703 geometry_info.psi=0.5;
9704 }
9705 if (attribute_flag[1] != 0)
9706 geometry_info.rho=argument_list[1].real_reference;
9707 if (attribute_flag[2] != 0)
9708 geometry_info.sigma=argument_list[2].real_reference;
9709 if (attribute_flag[3] != 0)
9710 geometry_info.xi=argument_list[3].real_reference;
9711 if (attribute_flag[4] != 0)
9712 geometry_info.psi=argument_list[4].real_reference;
9713 if (attribute_flag[5] != 0)
9714 channel=(ChannelType) argument_list[5].integer_reference;
9715 channel_mask=SetImageChannelMask(image,channel);
9716 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9717 geometry_info.xi,geometry_info.psi,exception);
9718 if (image != (Image *) NULL)
9719 (void) SetImageChannelMask(image,channel_mask);
9720 break;
9721 }
9722 case 70: /* MotionBlur */
9723 {
9724 if (attribute_flag[0] != 0)
9725 {
9726 flags=ParseGeometry(argument_list[0].string_reference,
9727 &geometry_info);
9728 if ((flags & SigmaValue) == 0)
9729 geometry_info.sigma=1.0;
9730 if ((flags & XiValue) == 0)
9731 geometry_info.xi=1.0;
9732 }
9733 if (attribute_flag[1] != 0)
9734 geometry_info.rho=argument_list[1].real_reference;
9735 if (attribute_flag[2] != 0)
9736 geometry_info.sigma=argument_list[2].real_reference;
9737 if (attribute_flag[3] != 0)
9738 geometry_info.xi=argument_list[3].real_reference;
9739 if (attribute_flag[4] != 0)
9740 channel=(ChannelType) argument_list[4].integer_reference;
9741 channel_mask=SetImageChannelMask(image,channel);
9742 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9743 geometry_info.xi,exception);
9744 if (image != (Image *) NULL)
9745 (void) SetImageChannelMask(image,channel_mask);
9746 break;
9747 }
9748 case 71: /* OrderedDither */
9749 {
9750 if (attribute_flag[0] == 0)
9751 argument_list[0].string_reference="o8x8";
9752 if (attribute_flag[1] != 0)
9753 channel=(ChannelType) argument_list[1].integer_reference;
9754 channel_mask=SetImageChannelMask(image,channel);
Cristy6b93c072016-02-04 07:45:48 -05009755 (void) OrderedDitherImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009756 exception);
9757 (void) SetImageChannelMask(image,channel_mask);
9758 break;
9759 }
9760 case 72: /* Shave */
9761 {
9762 if (attribute_flag[0] != 0)
9763 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9764 &geometry,exception);
9765 if (attribute_flag[1] != 0)
9766 geometry.width=argument_list[1].integer_reference;
9767 if (attribute_flag[2] != 0)
9768 geometry.height=argument_list[2].integer_reference;
9769 image=ShaveImage(image,&geometry,exception);
9770 break;
9771 }
9772 case 73: /* Level */
9773 {
9774 double
9775 black_point,
9776 gamma,
9777 white_point;
9778
9779 black_point=0.0;
9780 white_point=(double) image->columns*image->rows;
9781 gamma=1.0;
9782 if (attribute_flag[0] != 0)
9783 {
9784 flags=ParseGeometry(argument_list[0].string_reference,
9785 &geometry_info);
9786 black_point=geometry_info.rho;
9787 if ((flags & SigmaValue) != 0)
9788 white_point=geometry_info.sigma;
9789 if ((flags & XiValue) != 0)
9790 gamma=geometry_info.xi;
9791 if ((flags & PercentValue) != 0)
9792 {
9793 black_point*=(double) (QuantumRange/100.0);
9794 white_point*=(double) (QuantumRange/100.0);
9795 }
9796 if ((flags & SigmaValue) == 0)
9797 white_point=(double) QuantumRange-black_point;
9798 }
9799 if (attribute_flag[1] != 0)
9800 black_point=argument_list[1].real_reference;
9801 if (attribute_flag[2] != 0)
9802 white_point=argument_list[2].real_reference;
9803 if (attribute_flag[3] != 0)
9804 gamma=argument_list[3].real_reference;
9805 if (attribute_flag[4] != 0)
9806 channel=(ChannelType) argument_list[4].integer_reference;
9807 if (attribute_flag[5] != 0)
9808 {
9809 argument_list[0].real_reference=argument_list[5].real_reference;
9810 attribute_flag[0]=attribute_flag[5];
9811 }
9812 channel_mask=SetImageChannelMask(image,channel);
9813 (void) LevelImage(image,black_point,white_point,gamma,exception);
9814 (void) SetImageChannelMask(image,channel_mask);
9815 break;
9816 }
9817 case 74: /* Clip */
9818 {
9819 if (attribute_flag[0] == 0)
9820 argument_list[0].string_reference="#1";
9821 if (attribute_flag[1] == 0)
9822 argument_list[1].integer_reference=MagickTrue;
9823 (void) ClipImagePath(image,argument_list[0].string_reference,
9824 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9825 exception);
9826 break;
9827 }
9828 case 75: /* AffineTransform */
9829 {
9830 DrawInfo
9831 *draw_info;
9832
9833 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9834 (DrawInfo *) NULL);
9835 if (attribute_flag[0] != 0)
9836 {
9837 AV
9838 *av;
9839
9840 av=(AV *) argument_list[0].array_reference;
9841 if ((av_len(av) != 3) && (av_len(av) != 5))
9842 {
9843 ThrowPerlException(exception,OptionError,
9844 "affine matrix must have 4 or 6 elements",PackageName);
9845 goto PerlException;
9846 }
9847 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9848 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9849 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9850 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9851 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9852 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9853 {
9854 ThrowPerlException(exception,OptionError,
9855 "affine matrix is singular",PackageName);
9856 goto PerlException;
9857 }
9858 if (av_len(av) == 5)
9859 {
9860 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9861 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9862 }
9863 }
9864 for (j=1; j < 6; j++)
9865 {
9866 if (attribute_flag[j] == 0)
9867 continue;
9868 value=argument_list[j].string_reference;
9869 angle=argument_list[j].real_reference;
9870 current=draw_info->affine;
9871 GetAffineMatrix(&affine);
9872 switch (j)
9873 {
9874 case 1:
9875 {
9876 /*
9877 Translate.
9878 */
9879 flags=ParseGeometry(value,&geometry_info);
9880 affine.tx=geometry_info.xi;
9881 affine.ty=geometry_info.psi;
9882 if ((flags & PsiValue) == 0)
9883 affine.ty=affine.tx;
9884 break;
9885 }
9886 case 2:
9887 {
9888 /*
9889 Scale.
9890 */
9891 flags=ParseGeometry(value,&geometry_info);
9892 affine.sx=geometry_info.rho;
9893 affine.sy=geometry_info.sigma;
9894 if ((flags & SigmaValue) == 0)
9895 affine.sy=affine.sx;
9896 break;
9897 }
9898 case 3:
9899 {
9900 /*
9901 Rotate.
9902 */
9903 if (angle == 0.0)
9904 break;
9905 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9906 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9907 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9908 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9909 break;
9910 }
9911 case 4:
9912 {
9913 /*
9914 SkewX.
9915 */
9916 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9917 break;
9918 }
9919 case 5:
9920 {
9921 /*
9922 SkewY.
9923 */
9924 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9925 break;
9926 }
9927 }
9928 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9929 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9930 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9931 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9932 draw_info->affine.tx=
9933 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9934 draw_info->affine.ty=
9935 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9936 }
9937 if (attribute_flag[6] != 0)
9938 image->interpolate=(PixelInterpolateMethod)
9939 argument_list[6].integer_reference;
9940 if (attribute_flag[7] != 0)
9941 QueryColorCompliance(argument_list[7].string_reference,
9942 AllCompliance,&image->background_color,exception);
9943 image=AffineTransformImage(image,&draw_info->affine,exception);
9944 draw_info=DestroyDrawInfo(draw_info);
9945 break;
9946 }
9947 case 76: /* Difference */
9948 {
9949 if (attribute_flag[0] == 0)
9950 {
9951 ThrowPerlException(exception,OptionError,
9952 "ReferenceImageRequired",PackageName);
9953 goto PerlException;
9954 }
9955 if (attribute_flag[1] != 0)
9956 image->fuzz=StringToDoubleInterval(
9957 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -05009958 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009959 exception);
9960 break;
9961 }
9962 case 77: /* AdaptiveThreshold */
9963 {
9964 if (attribute_flag[0] != 0)
9965 {
9966 flags=ParseGeometry(argument_list[0].string_reference,
9967 &geometry_info);
9968 if ((flags & PercentValue) != 0)
9969 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9970 }
9971 if (attribute_flag[1] != 0)
9972 geometry_info.rho=argument_list[1].integer_reference;
9973 if (attribute_flag[2] != 0)
9974 geometry_info.sigma=argument_list[2].integer_reference;
9975 if (attribute_flag[3] != 0)
9976 geometry_info.xi=argument_list[3].integer_reference;;
9977 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9978 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9979 break;
9980 }
9981 case 78: /* Resample */
9982 {
9983 size_t
9984 height,
9985 width;
9986
9987 if (attribute_flag[0] != 0)
9988 {
9989 flags=ParseGeometry(argument_list[0].string_reference,
9990 &geometry_info);
9991 if ((flags & SigmaValue) == 0)
9992 geometry_info.sigma=geometry_info.rho;
9993 }
9994 if (attribute_flag[1] != 0)
9995 geometry_info.rho=argument_list[1].real_reference;
9996 if (attribute_flag[2] != 0)
9997 geometry_info.sigma=argument_list[2].real_reference;
9998 if (attribute_flag[3] == 0)
9999 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10000 if (attribute_flag[4] == 0)
10001 SetImageArtifact(image,"filter:support",
10002 argument_list[4].string_reference);
10003 width=(size_t) (geometry_info.rho*image->columns/
10004 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10005 height=(size_t) (geometry_info.sigma*image->rows/
10006 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
Cristy8645e042016-02-03 16:35:29 -050010007 image=ResizeImage(image,width,height,(FilterType)
cristy4a3ce0a2013-08-03 20:06:59 +000010008 argument_list[3].integer_reference,exception);
10009 if (image != (Image *) NULL)
10010 {
10011 image->resolution.x=geometry_info.rho;
10012 image->resolution.y=geometry_info.sigma;
10013 }
10014 break;
10015 }
10016 case 79: /* Describe */
10017 {
10018 if (attribute_flag[0] == 0)
10019 argument_list[0].file_reference=(FILE *) NULL;
10020 if (attribute_flag[1] != 0)
10021 (void) SetImageArtifact(image,"identify:features",
10022 argument_list[1].string_reference);
10023 (void) IdentifyImage(image,argument_list[0].file_reference,
10024 MagickTrue,exception);
10025 break;
10026 }
10027 case 80: /* BlackThreshold */
10028 {
10029 if (attribute_flag[0] == 0)
10030 argument_list[0].string_reference="50%";
10031 if (attribute_flag[2] != 0)
10032 channel=(ChannelType) argument_list[2].integer_reference;
10033 channel_mask=SetImageChannelMask(image,channel);
10034 BlackThresholdImage(image,argument_list[0].string_reference,
10035 exception);
10036 (void) SetImageChannelMask(image,channel_mask);
10037 break;
10038 }
10039 case 81: /* WhiteThreshold */
10040 {
10041 if (attribute_flag[0] == 0)
10042 argument_list[0].string_reference="50%";
10043 if (attribute_flag[2] != 0)
10044 channel=(ChannelType) argument_list[2].integer_reference;
10045 channel_mask=SetImageChannelMask(image,channel);
10046 WhiteThresholdImage(image,argument_list[0].string_reference,
10047 exception);
10048 (void) SetImageChannelMask(image,channel_mask);
10049 break;
10050 }
cristy60c73c02014-03-25 12:09:58 +000010051 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010052 {
10053 if (attribute_flag[0] != 0)
10054 {
10055 flags=ParseGeometry(argument_list[0].string_reference,
10056 &geometry_info);
10057 }
10058 if (attribute_flag[1] != 0)
10059 geometry_info.rho=argument_list[1].real_reference;
10060 if (attribute_flag[2] != 0)
10061 channel=(ChannelType) argument_list[2].integer_reference;
10062 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010063 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010064 if (image != (Image *) NULL)
10065 (void) SetImageChannelMask(image,channel_mask);
10066 break;
10067 }
10068 case 83: /* Thumbnail */
10069 {
10070 if (attribute_flag[0] != 0)
10071 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10072 &geometry,exception);
10073 if (attribute_flag[1] != 0)
10074 geometry.width=argument_list[1].integer_reference;
10075 if (attribute_flag[2] != 0)
10076 geometry.height=argument_list[2].integer_reference;
10077 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10078 break;
10079 }
10080 case 84: /* Strip */
10081 {
10082 (void) StripImage(image,exception);
10083 break;
10084 }
10085 case 85: /* Tint */
10086 {
10087 PixelInfo
10088 tint;
10089
10090 GetPixelInfo(image,&tint);
10091 if (attribute_flag[0] != 0)
10092 (void) QueryColorCompliance(argument_list[0].string_reference,
10093 AllCompliance,&tint,exception);
10094 if (attribute_flag[1] == 0)
10095 argument_list[1].string_reference="100";
10096 image=TintImage(image,argument_list[1].string_reference,&tint,
10097 exception);
10098 break;
10099 }
10100 case 86: /* Channel */
10101 {
10102 if (attribute_flag[0] != 0)
10103 channel=(ChannelType) argument_list[0].integer_reference;
10104 image=SeparateImage(image,channel,exception);
10105 break;
10106 }
10107 case 87: /* Splice */
10108 {
cristy260bd762014-08-15 12:46:34 +000010109 if (attribute_flag[7] != 0)
10110 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010111 if (attribute_flag[0] != 0)
10112 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10113 &geometry,exception);
10114 if (attribute_flag[1] != 0)
10115 geometry.width=argument_list[1].integer_reference;
10116 if (attribute_flag[2] != 0)
10117 geometry.height=argument_list[2].integer_reference;
10118 if (attribute_flag[3] != 0)
10119 geometry.x=argument_list[3].integer_reference;
10120 if (attribute_flag[4] != 0)
10121 geometry.y=argument_list[4].integer_reference;
10122 if (attribute_flag[5] != 0)
10123 image->fuzz=StringToDoubleInterval(
10124 argument_list[5].string_reference,(double) QuantumRange+1.0);
10125 if (attribute_flag[6] != 0)
10126 (void) QueryColorCompliance(argument_list[6].string_reference,
10127 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010128 image=SpliceImage(image,&geometry,exception);
10129 break;
10130 }
10131 case 88: /* Posterize */
10132 {
10133 if (attribute_flag[0] == 0)
10134 argument_list[0].integer_reference=3;
10135 if (attribute_flag[1] == 0)
10136 argument_list[1].integer_reference=0;
10137 (void) PosterizeImage(image,argument_list[0].integer_reference,
10138 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10139 NoDitherMethod,exception);
10140 break;
10141 }
10142 case 89: /* Shadow */
10143 {
10144 if (attribute_flag[0] != 0)
10145 {
10146 flags=ParseGeometry(argument_list[0].string_reference,
10147 &geometry_info);
10148 if ((flags & SigmaValue) == 0)
10149 geometry_info.sigma=1.0;
10150 if ((flags & XiValue) == 0)
10151 geometry_info.xi=4.0;
10152 if ((flags & PsiValue) == 0)
10153 geometry_info.psi=4.0;
10154 }
10155 if (attribute_flag[1] != 0)
10156 geometry_info.rho=argument_list[1].real_reference;
10157 if (attribute_flag[2] != 0)
10158 geometry_info.sigma=argument_list[2].real_reference;
10159 if (attribute_flag[3] != 0)
10160 geometry_info.xi=argument_list[3].integer_reference;
10161 if (attribute_flag[4] != 0)
10162 geometry_info.psi=argument_list[4].integer_reference;
10163 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10164 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10165 ceil(geometry_info.psi-0.5),exception);
10166 break;
10167 }
10168 case 90: /* Identify */
10169 {
10170 if (attribute_flag[0] == 0)
10171 argument_list[0].file_reference=(FILE *) NULL;
10172 if (attribute_flag[1] != 0)
10173 (void) SetImageArtifact(image,"identify:features",
10174 argument_list[1].string_reference);
10175 if ((attribute_flag[2] != 0) &&
10176 (argument_list[2].integer_reference != 0))
10177 (void) SetImageArtifact(image,"identify:unique","true");
10178 (void) IdentifyImage(image,argument_list[0].file_reference,
10179 MagickTrue,exception);
10180 break;
10181 }
10182 case 91: /* SepiaTone */
10183 {
10184 if (attribute_flag[0] == 0)
10185 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10186 image=SepiaToneImage(image,argument_list[0].real_reference,
10187 exception);
10188 break;
10189 }
10190 case 92: /* SigmoidalContrast */
10191 {
10192 MagickBooleanType
10193 sharpen;
10194
10195 if (attribute_flag[0] != 0)
10196 {
10197 flags=ParseGeometry(argument_list[0].string_reference,
10198 &geometry_info);
10199 if ((flags & SigmaValue) == 0)
10200 geometry_info.sigma=QuantumRange/2.0;
10201 if ((flags & PercentValue) != 0)
10202 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10203 }
10204 if (attribute_flag[1] != 0)
10205 geometry_info.rho=argument_list[1].real_reference;
10206 if (attribute_flag[2] != 0)
10207 geometry_info.sigma=argument_list[2].real_reference;
10208 if (attribute_flag[3] != 0)
10209 channel=(ChannelType) argument_list[3].integer_reference;
10210 sharpen=MagickTrue;
10211 if (attribute_flag[4] != 0)
10212 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10213 MagickFalse;
10214 channel_mask=SetImageChannelMask(image,channel);
10215 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10216 geometry_info.sigma,exception);
10217 (void) SetImageChannelMask(image,channel_mask);
10218 break;
10219 }
10220 case 93: /* Extent */
10221 {
10222 if (attribute_flag[7] != 0)
10223 image->gravity=(GravityType) argument_list[7].integer_reference;
10224 if (attribute_flag[0] != 0)
10225 {
10226 int
10227 flags;
10228
10229 flags=ParseGravityGeometry(image,
10230 argument_list[0].string_reference,&geometry,exception);
10231 (void) flags;
10232 if (geometry.width == 0)
10233 geometry.width=image->columns;
10234 if (geometry.height == 0)
10235 geometry.height=image->rows;
10236 }
10237 if (attribute_flag[1] != 0)
10238 geometry.width=argument_list[1].integer_reference;
10239 if (attribute_flag[2] != 0)
10240 geometry.height=argument_list[2].integer_reference;
10241 if (attribute_flag[3] != 0)
10242 geometry.x=argument_list[3].integer_reference;
10243 if (attribute_flag[4] != 0)
10244 geometry.y=argument_list[4].integer_reference;
10245 if (attribute_flag[5] != 0)
10246 image->fuzz=StringToDoubleInterval(
10247 argument_list[5].string_reference,(double) QuantumRange+1.0);
10248 if (attribute_flag[6] != 0)
10249 (void) QueryColorCompliance(argument_list[6].string_reference,
10250 AllCompliance,&image->background_color,exception);
10251 image=ExtentImage(image,&geometry,exception);
10252 break;
10253 }
10254 case 94: /* Vignette */
10255 {
10256 if (attribute_flag[0] != 0)
10257 {
10258 flags=ParseGeometry(argument_list[0].string_reference,
10259 &geometry_info);
10260 if ((flags & SigmaValue) == 0)
10261 geometry_info.sigma=1.0;
10262 if ((flags & XiValue) == 0)
10263 geometry_info.xi=0.1*image->columns;
10264 if ((flags & PsiValue) == 0)
10265 geometry_info.psi=0.1*image->rows;
10266 }
10267 if (attribute_flag[1] != 0)
10268 geometry_info.rho=argument_list[1].real_reference;
10269 if (attribute_flag[2] != 0)
10270 geometry_info.sigma=argument_list[2].real_reference;
10271 if (attribute_flag[3] != 0)
10272 geometry_info.xi=argument_list[3].integer_reference;
10273 if (attribute_flag[4] != 0)
10274 geometry_info.psi=argument_list[4].integer_reference;
10275 if (attribute_flag[5] != 0)
10276 (void) QueryColorCompliance(argument_list[5].string_reference,
10277 AllCompliance,&image->background_color,exception);
10278 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10279 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10280 ceil(geometry_info.psi-0.5),exception);
10281 break;
10282 }
10283 case 95: /* ContrastStretch */
10284 {
10285 double
10286 black_point,
10287 white_point;
10288
10289 black_point=0.0;
10290 white_point=(double) image->columns*image->rows;
10291 if (attribute_flag[0] != 0)
10292 {
10293 flags=ParseGeometry(argument_list[0].string_reference,
10294 &geometry_info);
10295 black_point=geometry_info.rho;
10296 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10297 black_point;
10298 if ((flags & PercentValue) != 0)
10299 {
10300 black_point*=(double) image->columns*image->rows/100.0;
10301 white_point*=(double) image->columns*image->rows/100.0;
10302 }
10303 white_point=(double) image->columns*image->rows-
10304 white_point;
10305 }
10306 if (attribute_flag[1] != 0)
10307 black_point=argument_list[1].real_reference;
10308 if (attribute_flag[2] != 0)
10309 white_point=argument_list[2].real_reference;
10310 if (attribute_flag[4] != 0)
10311 channel=(ChannelType) argument_list[4].integer_reference;
10312 channel_mask=SetImageChannelMask(image,channel);
10313 (void) ContrastStretchImage(image,black_point,white_point,exception);
10314 (void) SetImageChannelMask(image,channel_mask);
10315 break;
10316 }
10317 case 96: /* Sans0 */
10318 {
10319 break;
10320 }
10321 case 97: /* Sans1 */
10322 {
10323 break;
10324 }
10325 case 98: /* AdaptiveSharpen */
10326 {
10327 if (attribute_flag[0] != 0)
10328 {
10329 flags=ParseGeometry(argument_list[0].string_reference,
10330 &geometry_info);
10331 if ((flags & SigmaValue) == 0)
10332 geometry_info.sigma=1.0;
10333 if ((flags & XiValue) == 0)
10334 geometry_info.xi=0.0;
10335 }
10336 if (attribute_flag[1] != 0)
10337 geometry_info.rho=argument_list[1].real_reference;
10338 if (attribute_flag[2] != 0)
10339 geometry_info.sigma=argument_list[2].real_reference;
10340 if (attribute_flag[3] != 0)
10341 geometry_info.xi=argument_list[3].real_reference;
10342 if (attribute_flag[4] != 0)
10343 channel=(ChannelType) argument_list[4].integer_reference;
10344 channel_mask=SetImageChannelMask(image,channel);
10345 image=AdaptiveSharpenImage(image,geometry_info.rho,
10346 geometry_info.sigma,exception);
10347 if (image != (Image *) NULL)
10348 (void) SetImageChannelMask(image,channel_mask);
10349 break;
10350 }
10351 case 99: /* Transpose */
10352 {
10353 image=TransposeImage(image,exception);
10354 break;
10355 }
10356 case 100: /* Tranverse */
10357 {
10358 image=TransverseImage(image,exception);
10359 break;
10360 }
10361 case 101: /* AutoOrient */
10362 {
10363 image=AutoOrientImage(image,image->orientation,exception);
10364 break;
10365 }
10366 case 102: /* AdaptiveBlur */
10367 {
10368 if (attribute_flag[0] != 0)
10369 {
10370 flags=ParseGeometry(argument_list[0].string_reference,
10371 &geometry_info);
10372 if ((flags & SigmaValue) == 0)
10373 geometry_info.sigma=1.0;
10374 if ((flags & XiValue) == 0)
10375 geometry_info.xi=0.0;
10376 }
10377 if (attribute_flag[1] != 0)
10378 geometry_info.rho=argument_list[1].real_reference;
10379 if (attribute_flag[2] != 0)
10380 geometry_info.sigma=argument_list[2].real_reference;
10381 if (attribute_flag[3] != 0)
10382 channel=(ChannelType) argument_list[3].integer_reference;
10383 channel_mask=SetImageChannelMask(image,channel);
10384 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10385 exception);
10386 if (image != (Image *) NULL)
10387 (void) SetImageChannelMask(image,channel_mask);
10388 break;
10389 }
10390 case 103: /* Sketch */
10391 {
10392 if (attribute_flag[0] != 0)
10393 {
10394 flags=ParseGeometry(argument_list[0].string_reference,
10395 &geometry_info);
10396 if ((flags & SigmaValue) == 0)
10397 geometry_info.sigma=1.0;
10398 if ((flags & XiValue) == 0)
10399 geometry_info.xi=1.0;
10400 }
10401 if (attribute_flag[1] != 0)
10402 geometry_info.rho=argument_list[1].real_reference;
10403 if (attribute_flag[2] != 0)
10404 geometry_info.sigma=argument_list[2].real_reference;
10405 if (attribute_flag[3] != 0)
10406 geometry_info.xi=argument_list[3].real_reference;
10407 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10408 geometry_info.xi,exception);
10409 break;
10410 }
10411 case 104: /* UniqueColors */
10412 {
10413 image=UniqueImageColors(image,exception);
10414 break;
10415 }
10416 case 105: /* AdaptiveResize */
10417 {
10418 if (attribute_flag[0] != 0)
10419 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10420 &geometry,exception);
10421 if (attribute_flag[1] != 0)
10422 geometry.width=argument_list[1].integer_reference;
10423 if (attribute_flag[2] != 0)
10424 geometry.height=argument_list[2].integer_reference;
10425 if (attribute_flag[3] != 0)
Cristy8645e042016-02-03 16:35:29 -050010426 image->filter=(FilterType) argument_list[4].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010427 if (attribute_flag[4] != 0)
10428 SetImageArtifact(image,"filter:support",
10429 argument_list[4].string_reference);
10430 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10431 exception);
10432 break;
10433 }
10434 case 106: /* ClipMask */
10435 {
10436 Image
10437 *mask_image;
10438
10439 if (attribute_flag[0] == 0)
10440 {
10441 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10442 PackageName);
10443 goto PerlException;
10444 }
10445 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10446 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010447 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010448 mask_image=DestroyImage(mask_image);
10449 break;
10450 }
10451 case 107: /* LinearStretch */
10452 {
10453 double
10454 black_point,
10455 white_point;
10456
10457 black_point=0.0;
10458 white_point=(double) image->columns*image->rows;
10459 if (attribute_flag[0] != 0)
10460 {
10461 flags=ParseGeometry(argument_list[0].string_reference,
10462 &geometry_info);
10463 if ((flags & SigmaValue) != 0)
10464 white_point=geometry_info.sigma;
10465 if ((flags & PercentValue) != 0)
10466 {
10467 black_point*=(double) image->columns*image->rows/100.0;
10468 white_point*=(double) image->columns*image->rows/100.0;
10469 }
10470 if ((flags & SigmaValue) == 0)
10471 white_point=(double) image->columns*image->rows-black_point;
10472 }
10473 if (attribute_flag[1] != 0)
10474 black_point=argument_list[1].real_reference;
10475 if (attribute_flag[2] != 0)
10476 white_point=argument_list[2].real_reference;
10477 (void) LinearStretchImage(image,black_point,white_point,exception);
10478 break;
10479 }
10480 case 108: /* ColorMatrix */
10481 {
10482 AV
10483 *av;
10484
10485 double
10486 *color_matrix;
10487
10488 KernelInfo
10489 *kernel_info;
10490
10491 size_t
10492 order;
10493
10494 if (attribute_flag[0] == 0)
10495 break;
10496 av=(AV *) argument_list[0].array_reference;
10497 order=(size_t) sqrt(av_len(av)+1);
10498 color_matrix=(double *) AcquireQuantumMemory(order,order*
10499 sizeof(*color_matrix));
10500 if (color_matrix == (double *) NULL)
10501 {
10502 ThrowPerlException(exception,ResourceLimitFatalError,
10503 "MemoryAllocationFailed",PackageName);
10504 goto PerlException;
10505 }
10506 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10507 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10508 for ( ; j < (ssize_t) (order*order); j++)
10509 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010510 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010511 if (kernel_info == (KernelInfo *) NULL)
10512 break;
10513 kernel_info->width=order;
10514 kernel_info->height=order;
10515 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10516 order*sizeof(*kernel_info->values));
10517 if (kernel_info->values != (MagickRealType *) NULL)
10518 {
10519 for (i=0; i < (ssize_t) (order*order); i++)
10520 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10521 image=ColorMatrixImage(image,kernel_info,exception);
10522 }
10523 kernel_info=DestroyKernelInfo(kernel_info);
10524 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10525 break;
10526 }
10527 case 109: /* Mask */
10528 {
10529 Image
10530 *mask_image;
10531
10532 if (attribute_flag[0] == 0)
10533 {
10534 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10535 PackageName);
10536 goto PerlException;
10537 }
10538 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10539 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010540 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010541 mask_image=DestroyImage(mask_image);
10542 break;
10543 }
10544 case 110: /* Polaroid */
10545 {
10546 char
10547 *caption;
10548
10549 DrawInfo
10550 *draw_info;
10551
10552 double
10553 angle;
10554
10555 PixelInterpolateMethod
10556 method;
10557
10558 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10559 (DrawInfo *) NULL);
10560 caption=(char *) NULL;
10561 if (attribute_flag[0] != 0)
10562 caption=InterpretImageProperties(info ? info->image_info :
10563 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10564 exception);
10565 angle=0.0;
10566 if (attribute_flag[1] != 0)
10567 angle=argument_list[1].real_reference;
10568 if (attribute_flag[2] != 0)
10569 (void) CloneString(&draw_info->font,
10570 argument_list[2].string_reference);
10571 if (attribute_flag[3] != 0)
10572 (void) QueryColorCompliance(argument_list[3].string_reference,
10573 AllCompliance,&draw_info->stroke,exception);
10574 if (attribute_flag[4] != 0)
10575 (void) QueryColorCompliance(argument_list[4].string_reference,
10576 AllCompliance,&draw_info->fill,exception);
10577 if (attribute_flag[5] != 0)
10578 draw_info->stroke_width=argument_list[5].real_reference;
10579 if (attribute_flag[6] != 0)
10580 draw_info->pointsize=argument_list[6].real_reference;
10581 if (attribute_flag[7] != 0)
10582 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10583 if (attribute_flag[8] != 0)
10584 (void) QueryColorCompliance(argument_list[8].string_reference,
10585 AllCompliance,&image->background_color,exception);
10586 method=UndefinedInterpolatePixel;
10587 if (attribute_flag[9] != 0)
10588 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10589 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10590 draw_info=DestroyDrawInfo(draw_info);
10591 if (caption != (char *) NULL)
10592 caption=DestroyString(caption);
10593 break;
10594 }
10595 case 111: /* FloodfillPaint */
10596 {
10597 DrawInfo
10598 *draw_info;
10599
10600 MagickBooleanType
10601 invert;
10602
10603 PixelInfo
10604 target;
10605
10606 draw_info=CloneDrawInfo(info ? info->image_info :
10607 (ImageInfo *) NULL,(DrawInfo *) NULL);
10608 if (attribute_flag[0] != 0)
10609 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10610 &geometry,exception);
10611 if (attribute_flag[1] != 0)
10612 geometry.x=argument_list[1].integer_reference;
10613 if (attribute_flag[2] != 0)
10614 geometry.y=argument_list[2].integer_reference;
10615 if (attribute_flag[3] != 0)
10616 (void) QueryColorCompliance(argument_list[3].string_reference,
10617 AllCompliance,&draw_info->fill,exception);
10618 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10619 geometry.x,geometry.y,&target,exception);
10620 if (attribute_flag[4] != 0)
10621 QueryColorCompliance(argument_list[4].string_reference,
10622 AllCompliance,&target,exception);
10623 if (attribute_flag[5] != 0)
10624 image->fuzz=StringToDoubleInterval(
10625 argument_list[5].string_reference,(double) QuantumRange+1.0);
10626 if (attribute_flag[6] != 0)
10627 channel=(ChannelType) argument_list[6].integer_reference;
10628 invert=MagickFalse;
10629 if (attribute_flag[7] != 0)
10630 invert=(MagickBooleanType) argument_list[7].integer_reference;
10631 channel_mask=SetImageChannelMask(image,channel);
10632 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10633 geometry.y,invert,exception);
10634 (void) SetImageChannelMask(image,channel_mask);
10635 draw_info=DestroyDrawInfo(draw_info);
10636 break;
10637 }
10638 case 112: /* Distort */
10639 {
10640 AV
10641 *av;
10642
10643 double
10644 *coordinates;
10645
Cristy8645e042016-02-03 16:35:29 -050010646 DistortMethod
cristy4a3ce0a2013-08-03 20:06:59 +000010647 method;
10648
10649 size_t
10650 number_coordinates;
10651
10652 VirtualPixelMethod
10653 virtual_pixel;
10654
10655 if (attribute_flag[0] == 0)
10656 break;
10657 method=UndefinedDistortion;
10658 if (attribute_flag[1] != 0)
Cristy8645e042016-02-03 16:35:29 -050010659 method=(DistortMethod) argument_list[1].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010660 av=(AV *) argument_list[0].array_reference;
10661 number_coordinates=(size_t) av_len(av)+1;
10662 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10663 sizeof(*coordinates));
10664 if (coordinates == (double *) NULL)
10665 {
10666 ThrowPerlException(exception,ResourceLimitFatalError,
10667 "MemoryAllocationFailed",PackageName);
10668 goto PerlException;
10669 }
10670 for (j=0; j < (ssize_t) number_coordinates; j++)
10671 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10672 virtual_pixel=UndefinedVirtualPixelMethod;
10673 if (attribute_flag[2] != 0)
10674 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10675 argument_list[2].integer_reference,exception);
10676 image=DistortImage(image,method,number_coordinates,coordinates,
10677 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10678 exception);
10679 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10680 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10681 exception);
10682 coordinates=(double *) RelinquishMagickMemory(coordinates);
10683 break;
10684 }
10685 case 113: /* Clut */
10686 {
10687 PixelInterpolateMethod
10688 method;
10689
10690 if (attribute_flag[0] == 0)
10691 {
10692 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10693 PackageName);
10694 goto PerlException;
10695 }
10696 method=UndefinedInterpolatePixel;
10697 if (attribute_flag[1] != 0)
10698 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10699 if (attribute_flag[2] != 0)
10700 channel=(ChannelType) argument_list[2].integer_reference;
10701 channel_mask=SetImageChannelMask(image,channel);
10702 (void) ClutImage(image,argument_list[0].image_reference,method,
10703 exception);
10704 (void) SetImageChannelMask(image,channel_mask);
10705 break;
10706 }
10707 case 114: /* LiquidRescale */
10708 {
10709 if (attribute_flag[0] != 0)
10710 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10711 &geometry,exception);
10712 if (attribute_flag[1] != 0)
10713 geometry.width=argument_list[1].integer_reference;
10714 if (attribute_flag[2] != 0)
10715 geometry.height=argument_list[2].integer_reference;
10716 if (attribute_flag[3] == 0)
10717 argument_list[3].real_reference=1.0;
10718 if (attribute_flag[4] == 0)
10719 argument_list[4].real_reference=0.0;
10720 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10721 argument_list[3].real_reference,argument_list[4].real_reference,
10722 exception);
10723 break;
10724 }
10725 case 115: /* EncipherImage */
10726 {
10727 (void) EncipherImage(image,argument_list[0].string_reference,
10728 exception);
10729 break;
10730 }
10731 case 116: /* DecipherImage */
10732 {
10733 (void) DecipherImage(image,argument_list[0].string_reference,
10734 exception);
10735 break;
10736 }
10737 case 117: /* Deskew */
10738 {
10739 geometry_info.rho=QuantumRange/2.0;
10740 if (attribute_flag[0] != 0)
10741 flags=ParseGeometry(argument_list[0].string_reference,
10742 &geometry_info);
10743 if (attribute_flag[1] != 0)
10744 geometry_info.rho=StringToDoubleInterval(
10745 argument_list[1].string_reference,(double) QuantumRange+1.0);
10746 image=DeskewImage(image,geometry_info.rho,exception);
10747 break;
10748 }
10749 case 118: /* Remap */
10750 {
10751 QuantizeInfo
10752 *quantize_info;
10753
10754 if (attribute_flag[0] == 0)
10755 {
10756 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10757 PackageName);
10758 goto PerlException;
10759 }
10760 quantize_info=AcquireQuantizeInfo(info->image_info);
10761 if (attribute_flag[1] != 0)
10762 quantize_info->dither_method=(DitherMethod)
10763 argument_list[1].integer_reference;
10764 (void) RemapImages(quantize_info,image,
10765 argument_list[0].image_reference,exception);
10766 quantize_info=DestroyQuantizeInfo(quantize_info);
10767 break;
10768 }
10769 case 119: /* SparseColor */
10770 {
10771 AV
10772 *av;
10773
10774 double
10775 *coordinates;
10776
10777 SparseColorMethod
10778 method;
10779
10780 size_t
10781 number_coordinates;
10782
10783 VirtualPixelMethod
10784 virtual_pixel;
10785
10786 if (attribute_flag[0] == 0)
10787 break;
10788 method=UndefinedColorInterpolate;
10789 if (attribute_flag[1] != 0)
10790 method=(SparseColorMethod) argument_list[1].integer_reference;
10791 av=(AV *) argument_list[0].array_reference;
10792 number_coordinates=(size_t) av_len(av)+1;
10793 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10794 sizeof(*coordinates));
10795 if (coordinates == (double *) NULL)
10796 {
10797 ThrowPerlException(exception,ResourceLimitFatalError,
10798 "MemoryAllocationFailed",PackageName);
10799 goto PerlException;
10800 }
10801 for (j=0; j < (ssize_t) number_coordinates; j++)
10802 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10803 virtual_pixel=UndefinedVirtualPixelMethod;
10804 if (attribute_flag[2] != 0)
10805 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10806 argument_list[2].integer_reference,exception);
10807 if (attribute_flag[3] != 0)
10808 channel=(ChannelType) argument_list[3].integer_reference;
10809 channel_mask=SetImageChannelMask(image,channel);
10810 image=SparseColorImage(image,method,number_coordinates,coordinates,
10811 exception);
10812 if (image != (Image *) NULL)
10813 (void) SetImageChannelMask(image,channel_mask);
10814 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10815 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10816 exception);
10817 coordinates=(double *) RelinquishMagickMemory(coordinates);
10818 break;
10819 }
10820 case 120: /* Function */
10821 {
10822 AV
10823 *av;
10824
10825 double
10826 *parameters;
10827
10828 MagickFunction
10829 function;
10830
10831 size_t
10832 number_parameters;
10833
10834 VirtualPixelMethod
10835 virtual_pixel;
10836
10837 if (attribute_flag[0] == 0)
10838 break;
10839 function=UndefinedFunction;
10840 if (attribute_flag[1] != 0)
10841 function=(MagickFunction) argument_list[1].integer_reference;
10842 av=(AV *) argument_list[0].array_reference;
10843 number_parameters=(size_t) av_len(av)+1;
10844 parameters=(double *) AcquireQuantumMemory(number_parameters,
10845 sizeof(*parameters));
10846 if (parameters == (double *) NULL)
10847 {
10848 ThrowPerlException(exception,ResourceLimitFatalError,
10849 "MemoryAllocationFailed",PackageName);
10850 goto PerlException;
10851 }
10852 for (j=0; j < (ssize_t) number_parameters; j++)
10853 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10854 virtual_pixel=UndefinedVirtualPixelMethod;
10855 if (attribute_flag[2] != 0)
10856 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10857 argument_list[2].integer_reference,exception);
10858 (void) FunctionImage(image,function,number_parameters,parameters,
10859 exception);
10860 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10861 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10862 exception);
10863 parameters=(double *) RelinquishMagickMemory(parameters);
10864 break;
10865 }
10866 case 121: /* SelectiveBlur */
10867 {
10868 if (attribute_flag[0] != 0)
10869 {
10870 flags=ParseGeometry(argument_list[0].string_reference,
10871 &geometry_info);
10872 if ((flags & SigmaValue) == 0)
10873 geometry_info.sigma=1.0;
10874 if ((flags & PercentValue) != 0)
10875 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10876 }
10877 if (attribute_flag[1] != 0)
10878 geometry_info.rho=argument_list[1].real_reference;
10879 if (attribute_flag[2] != 0)
10880 geometry_info.sigma=argument_list[2].real_reference;
10881 if (attribute_flag[3] != 0)
10882 geometry_info.xi=argument_list[3].integer_reference;;
10883 if (attribute_flag[5] != 0)
10884 channel=(ChannelType) argument_list[5].integer_reference;
10885 channel_mask=SetImageChannelMask(image,channel);
10886 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10887 geometry_info.xi,exception);
10888 if (image != (Image *) NULL)
10889 (void) SetImageChannelMask(image,channel_mask);
10890 break;
10891 }
10892 case 122: /* HaldClut */
10893 {
10894 if (attribute_flag[0] == 0)
10895 {
10896 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10897 PackageName);
10898 goto PerlException;
10899 }
10900 if (attribute_flag[1] != 0)
10901 channel=(ChannelType) argument_list[1].integer_reference;
10902 channel_mask=SetImageChannelMask(image,channel);
10903 (void) HaldClutImage(image,argument_list[0].image_reference,
10904 exception);
10905 (void) SetImageChannelMask(image,channel_mask);
10906 break;
10907 }
10908 case 123: /* BlueShift */
10909 {
10910 if (attribute_flag[0] != 0)
10911 (void) ParseGeometry(argument_list[0].string_reference,
10912 &geometry_info);
10913 image=BlueShiftImage(image,geometry_info.rho,exception);
10914 break;
10915 }
10916 case 124: /* ForwardFourierTransformImage */
10917 {
10918 image=ForwardFourierTransformImage(image,
10919 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10920 exception);
10921 break;
10922 }
10923 case 125: /* InverseFourierTransformImage */
10924 {
10925 image=InverseFourierTransformImage(image,image->next,
10926 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10927 exception);
10928 break;
10929 }
10930 case 126: /* ColorDecisionList */
10931 {
10932 if (attribute_flag[0] == 0)
10933 argument_list[0].string_reference=(char *) NULL;
10934 (void) ColorDecisionListImage(image,
10935 argument_list[0].string_reference,exception);
10936 break;
10937 }
10938 case 127: /* AutoGamma */
10939 {
10940 if (attribute_flag[0] != 0)
10941 channel=(ChannelType) argument_list[0].integer_reference;
10942 channel_mask=SetImageChannelMask(image,channel);
10943 (void) AutoGammaImage(image,exception);
10944 (void) SetImageChannelMask(image,channel_mask);
10945 break;
10946 }
10947 case 128: /* AutoLevel */
10948 {
10949 if (attribute_flag[0] != 0)
10950 channel=(ChannelType) argument_list[0].integer_reference;
10951 channel_mask=SetImageChannelMask(image,channel);
10952 (void) AutoLevelImage(image,exception);
10953 (void) SetImageChannelMask(image,channel_mask);
10954 break;
10955 }
10956 case 129: /* LevelColors */
10957 {
10958 PixelInfo
10959 black_point,
10960 white_point;
10961
10962 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10963 exception);
10964 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10965 exception);
10966 if (attribute_flag[1] != 0)
10967 (void) QueryColorCompliance(
10968 argument_list[1].string_reference,AllCompliance,&black_point,
10969 exception);
10970 if (attribute_flag[2] != 0)
10971 (void) QueryColorCompliance(
10972 argument_list[2].string_reference,AllCompliance,&white_point,
10973 exception);
10974 if (attribute_flag[3] != 0)
10975 channel=(ChannelType) argument_list[3].integer_reference;
10976 channel_mask=SetImageChannelMask(image,channel);
10977 (void) LevelImageColors(image,&black_point,&white_point,
10978 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10979 exception);
10980 (void) SetImageChannelMask(image,channel_mask);
10981 break;
10982 }
10983 case 130: /* Clamp */
10984 {
10985 if (attribute_flag[0] != 0)
10986 channel=(ChannelType) argument_list[0].integer_reference;
10987 channel_mask=SetImageChannelMask(image,channel);
10988 (void) ClampImage(image,exception);
10989 (void) SetImageChannelMask(image,channel_mask);
10990 break;
10991 }
10992 case 131: /* BrightnessContrast */
10993 {
10994 double
10995 brightness,
10996 contrast;
10997
10998 brightness=0.0;
10999 contrast=0.0;
11000 if (attribute_flag[0] != 0)
11001 {
11002 flags=ParseGeometry(argument_list[0].string_reference,
11003 &geometry_info);
11004 brightness=geometry_info.rho;
11005 if ((flags & SigmaValue) == 0)
11006 contrast=geometry_info.sigma;
11007 }
11008 if (attribute_flag[1] != 0)
11009 brightness=argument_list[1].real_reference;
11010 if (attribute_flag[2] != 0)
11011 contrast=argument_list[2].real_reference;
11012 if (attribute_flag[4] != 0)
11013 channel=(ChannelType) argument_list[4].integer_reference;
11014 channel_mask=SetImageChannelMask(image,channel);
11015 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11016 (void) SetImageChannelMask(image,channel_mask);
11017 break;
11018 }
11019 case 132: /* Morphology */
11020 {
11021 KernelInfo
11022 *kernel;
11023
11024 MorphologyMethod
11025 method;
11026
11027 ssize_t
11028 iterations;
11029
11030 if (attribute_flag[0] == 0)
11031 break;
cristy2c57b742014-10-31 00:40:34 +000011032 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011033 if (kernel == (KernelInfo *) NULL)
11034 break;
11035 if (attribute_flag[1] != 0)
11036 channel=(ChannelType) argument_list[1].integer_reference;
11037 method=UndefinedMorphology;
11038 if (attribute_flag[2] != 0)
11039 method=argument_list[2].integer_reference;
11040 iterations=1;
11041 if (attribute_flag[3] != 0)
11042 iterations=argument_list[3].integer_reference;
11043 channel_mask=SetImageChannelMask(image,channel);
11044 image=MorphologyImage(image,method,iterations,kernel,exception);
11045 if (image != (Image *) NULL)
11046 (void) SetImageChannelMask(image,channel_mask);
11047 kernel=DestroyKernelInfo(kernel);
11048 break;
11049 }
11050 case 133: /* Mode */
11051 {
11052 if (attribute_flag[0] != 0)
11053 {
11054 flags=ParseGeometry(argument_list[0].string_reference,
11055 &geometry_info);
11056 if ((flags & SigmaValue) == 0)
11057 geometry_info.sigma=1.0;
11058 }
11059 if (attribute_flag[1] != 0)
11060 geometry_info.rho=argument_list[1].real_reference;
11061 if (attribute_flag[2] != 0)
11062 geometry_info.sigma=argument_list[2].real_reference;
11063 if (attribute_flag[3] != 0)
11064 channel=(ChannelType) argument_list[3].integer_reference;
11065 channel_mask=SetImageChannelMask(image,channel);
11066 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11067 (size_t) geometry_info.sigma,exception);
11068 if (image != (Image *) NULL)
11069 (void) SetImageChannelMask(image,channel_mask);
11070 break;
11071 }
11072 case 134: /* Statistic */
11073 {
11074 StatisticType
11075 statistic;
11076
11077 statistic=UndefinedStatistic;
11078 if (attribute_flag[0] != 0)
11079 {
11080 flags=ParseGeometry(argument_list[0].string_reference,
11081 &geometry_info);
11082 if ((flags & SigmaValue) == 0)
11083 geometry_info.sigma=1.0;
11084 }
11085 if (attribute_flag[1] != 0)
11086 geometry_info.rho=argument_list[1].real_reference;
11087 if (attribute_flag[2] != 0)
11088 geometry_info.sigma=argument_list[2].real_reference;
11089 if (attribute_flag[3] != 0)
11090 channel=(ChannelType) argument_list[3].integer_reference;
11091 if (attribute_flag[4] != 0)
11092 statistic=(StatisticType) argument_list[4].integer_reference;
11093 channel_mask=SetImageChannelMask(image,channel);
11094 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11095 (size_t) geometry_info.sigma,exception);
11096 if (image != (Image *) NULL)
11097 (void) SetImageChannelMask(image,channel_mask);
11098 break;
11099 }
11100 case 135: /* Perceptible */
11101 {
11102 double
11103 epsilon;
11104
11105 epsilon=MagickEpsilon;
11106 if (attribute_flag[0] != 0)
11107 epsilon=argument_list[0].real_reference;
11108 if (attribute_flag[1] != 0)
11109 channel=(ChannelType) argument_list[1].integer_reference;
11110 channel_mask=SetImageChannelMask(image,channel);
11111 (void) PerceptibleImage(image,epsilon,exception);
11112 (void) SetImageChannelMask(image,channel_mask);
11113 break;
11114 }
11115 case 136: /* Poly */
11116 {
11117 AV
11118 *av;
11119
11120 double
11121 *terms;
11122
11123 size_t
11124 number_terms;
11125
11126 if (attribute_flag[0] == 0)
11127 break;
11128 if (attribute_flag[1] != 0)
11129 channel=(ChannelType) argument_list[1].integer_reference;
11130 av=(AV *) argument_list[0].array_reference;
11131 number_terms=(size_t) av_len(av);
11132 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11133 if (terms == (double *) NULL)
11134 {
11135 ThrowPerlException(exception,ResourceLimitFatalError,
11136 "MemoryAllocationFailed",PackageName);
11137 goto PerlException;
11138 }
11139 for (j=0; j < av_len(av); j++)
11140 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11141 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11142 terms=(double *) RelinquishMagickMemory(terms);
11143 break;
11144 }
11145 case 137: /* Grayscale */
11146 {
11147 PixelIntensityMethod
11148 method;
11149
11150 method=UndefinedPixelIntensityMethod;
11151 if (attribute_flag[0] != 0)
11152 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11153 (void) GrayscaleImage(image,method,exception);
11154 break;
11155 }
cristy4ceadb82014-03-29 15:30:43 +000011156 case 138: /* Canny */
11157 {
11158 if (attribute_flag[0] != 0)
11159 {
11160 flags=ParseGeometry(argument_list[0].string_reference,
11161 &geometry_info);
11162 if ((flags & SigmaValue) == 0)
11163 geometry_info.sigma=1.0;
11164 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011165 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011166 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011167 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011168 if ((flags & PercentValue) != 0)
11169 {
11170 geometry_info.xi/=100.0;
11171 geometry_info.psi/=100.0;
11172 }
cristy4ceadb82014-03-29 15:30:43 +000011173 }
11174 if (attribute_flag[1] != 0)
11175 geometry_info.rho=argument_list[1].real_reference;
11176 if (attribute_flag[2] != 0)
11177 geometry_info.sigma=argument_list[2].real_reference;
11178 if (attribute_flag[3] != 0)
11179 geometry_info.xi=argument_list[3].real_reference;
11180 if (attribute_flag[4] != 0)
11181 geometry_info.psi=argument_list[4].real_reference;
11182 if (attribute_flag[5] != 0)
11183 channel=(ChannelType) argument_list[5].integer_reference;
11184 channel_mask=SetImageChannelMask(image,channel);
11185 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11186 geometry_info.xi,geometry_info.psi,exception);
11187 if (image != (Image *) NULL)
11188 (void) SetImageChannelMask(image,channel_mask);
11189 break;
11190 }
cristy2fc10e52014-04-26 14:13:53 +000011191 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011192 {
11193 if (attribute_flag[0] != 0)
11194 {
11195 flags=ParseGeometry(argument_list[0].string_reference,
11196 &geometry_info);
11197 if ((flags & SigmaValue) == 0)
11198 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011199 if ((flags & XiValue) == 0)
11200 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011201 }
11202 if (attribute_flag[1] != 0)
11203 geometry_info.rho=(double) argument_list[1].integer_reference;
11204 if (attribute_flag[2] != 0)
11205 geometry_info.sigma=(double) argument_list[2].integer_reference;
11206 if (attribute_flag[3] != 0)
11207 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011208 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11209 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11210 break;
11211 }
11212 case 140: /* MeanShift */
11213 {
11214 if (attribute_flag[0] != 0)
11215 {
11216 flags=ParseGeometry(argument_list[0].string_reference,
11217 &geometry_info);
11218 if ((flags & SigmaValue) == 0)
11219 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011220 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011221 geometry_info.xi=0.10*QuantumRange;
11222 if ((flags & PercentValue) != 0)
11223 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011224 }
11225 if (attribute_flag[1] != 0)
11226 geometry_info.rho=(double) argument_list[1].integer_reference;
11227 if (attribute_flag[2] != 0)
11228 geometry_info.sigma=(double) argument_list[2].integer_reference;
11229 if (attribute_flag[3] != 0)
11230 geometry_info.xi=(double) argument_list[3].integer_reference;
11231 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011232 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011233 break;
11234 }
cristy3b207f82014-09-27 14:21:20 +000011235 case 141: /* Kuwahara */
11236 {
11237 if (attribute_flag[0] != 0)
11238 {
11239 flags=ParseGeometry(argument_list[0].string_reference,
11240 &geometry_info);
11241 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011242 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011243 }
11244 if (attribute_flag[1] != 0)
11245 geometry_info.rho=argument_list[1].real_reference;
11246 if (attribute_flag[2] != 0)
11247 geometry_info.sigma=argument_list[2].real_reference;
11248 if (attribute_flag[3] != 0)
11249 channel=(ChannelType) argument_list[3].integer_reference;
11250 channel_mask=SetImageChannelMask(image,channel);
11251 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11252 exception);
11253 if (image != (Image *) NULL)
11254 (void) SetImageChannelMask(image,channel_mask);
11255 break;
11256 }
cristy6e0b3bc2014-10-19 17:51:42 +000011257 case 142: /* ConnectedComponent */
11258 {
11259 size_t
11260 connectivity;
11261
11262 connectivity=4;
11263 if (attribute_flag[0] != 0)
11264 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011265 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011266 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011267 break;
11268 }
cristy0b94b392015-06-22 18:56:37 +000011269 case 143: /* Copy */
11270 {
11271 Image
11272 *source_image;
11273
11274 OffsetInfo
11275 offset;
11276
cristy2ffdb092015-06-25 14:31:20 +000011277 RectangleInfo
11278 offset_geometry;
11279
cristyf3a724a2015-06-25 13:02:53 +000011280 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011281 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011282 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011283 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011284 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011285 flags=ParseGravityGeometry(source_image,
11286 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011287 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011288 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011289 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011290 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011291 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011292 geometry.x=argument_list[4].integer_reference;
11293 if (attribute_flag[5] != 0)
11294 geometry.y=argument_list[5].integer_reference;
11295 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011296 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011297 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011298 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011299 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11300 &offset_geometry,exception);
11301 offset.x=offset_geometry.x;
11302 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011303 if (attribute_flag[8] != 0)
11304 offset.x=argument_list[8].integer_reference;
11305 if (attribute_flag[9] != 0)
11306 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011307 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11308 exception);
cristy0b94b392015-06-22 18:56:37 +000011309 break;
11310 }
cristy4a3ce0a2013-08-03 20:06:59 +000011311 }
11312 if (next != (Image *) NULL)
11313 (void) CatchImageException(next);
11314 if (region_image != (Image *) NULL)
11315 {
11316 /*
11317 Composite region.
cristy83a28a02013-08-03 20:25:48 +000011318 */
cristy4a3ce0a2013-08-03 20:06:59 +000011319 status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11320 region_info.x,region_info.y,exception);
11321 (void) status;
11322 (void) CatchImageException(region_image);
11323 image=DestroyImage(image);
11324 image=region_image;
11325 }
11326 if (image != (Image *) NULL)
11327 {
11328 number_images++;
11329 if (next && (next != image))
11330 {
11331 image->next=next->next;
11332 if (image->next != (Image *) NULL)
11333 image->next->previous=image;
11334 DeleteImageFromRegistry(*pv,next);
11335 }
11336 sv_setiv(*pv,PTR2IV(image));
11337 next=image;
11338 }
11339 if (*pv)
11340 pv++;
11341 }
11342
11343 PerlException:
11344 if (reference_vector)
11345 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11346 InheritPerlException(exception,perl_exception);
11347 exception=DestroyExceptionInfo(exception);
11348 sv_setiv(perl_exception,(IV) number_images);
11349 SvPOK_on(perl_exception);
11350 ST(0)=sv_2mortal(perl_exception);
11351 XSRETURN(1);
11352 }
11353
11354#
11355###############################################################################
11356# #
11357# #
11358# #
11359# M o n t a g e #
11360# #
11361# #
11362# #
11363###############################################################################
11364#
11365#
11366void
11367Montage(ref,...)
11368 Image::Magick ref=NO_INIT
11369 ALIAS:
11370 MontageImage = 1
11371 montage = 2
11372 montageimage = 3
11373 PPCODE:
11374 {
11375 AV
11376 *av;
11377
11378 char
11379 *attribute;
11380
11381 ExceptionInfo
11382 *exception;
11383
11384 HV
11385 *hv;
11386
11387 Image
11388 *image,
11389 *next;
11390
11391 PixelInfo
11392 transparent_color;
11393
11394 MontageInfo
11395 *montage_info;
11396
11397 register ssize_t
11398 i;
11399
11400 ssize_t
11401 sp;
11402
11403 struct PackageInfo
11404 *info;
11405
11406 SV
11407 *av_reference,
11408 *perl_exception,
11409 *reference,
11410 *rv,
11411 *sv;
11412
11413 PERL_UNUSED_VAR(ref);
11414 PERL_UNUSED_VAR(ix);
11415 exception=AcquireExceptionInfo();
11416 perl_exception=newSVpv("",0);
11417 sv=NULL;
11418 attribute=NULL;
11419 if (sv_isobject(ST(0)) == 0)
11420 {
11421 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11422 PackageName);
11423 goto PerlException;
11424 }
11425 reference=SvRV(ST(0));
11426 hv=SvSTASH(reference);
11427 av=newAV();
11428 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11429 SvREFCNT_dec(av);
11430 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11431 if (image == (Image *) NULL)
11432 {
11433 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11434 PackageName);
11435 goto PerlException;
11436 }
11437 /*
11438 Get options.
11439 */
11440 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11441 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11442 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11443 exception);
11444 for (i=2; i < items; i+=2)
11445 {
11446 attribute=(char *) SvPV(ST(i-1),na);
11447 switch (*attribute)
11448 {
11449 case 'B':
11450 case 'b':
11451 {
11452 if (LocaleCompare(attribute,"background") == 0)
11453 {
11454 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11455 &montage_info->background_color,exception);
11456 for (next=image; next; next=next->next)
11457 next->background_color=montage_info->background_color;
11458 break;
11459 }
11460 if (LocaleCompare(attribute,"border") == 0)
11461 {
11462 montage_info->border_width=SvIV(ST(i));
11463 break;
11464 }
11465 if (LocaleCompare(attribute,"bordercolor") == 0)
11466 {
11467 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11468 &montage_info->border_color,exception);
11469 for (next=image; next; next=next->next)
11470 next->border_color=montage_info->border_color;
11471 break;
11472 }
11473 if (LocaleCompare(attribute,"borderwidth") == 0)
11474 {
11475 montage_info->border_width=SvIV(ST(i));
11476 break;
11477 }
11478 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11479 attribute);
11480 break;
11481 }
11482 case 'C':
11483 case 'c':
11484 {
11485 if (LocaleCompare(attribute,"compose") == 0)
11486 {
11487 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11488 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11489 if (sp < 0)
11490 {
11491 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11492 SvPV(ST(i),na));
11493 break;
11494 }
11495 for (next=image; next; next=next->next)
11496 next->compose=(CompositeOperator) sp;
11497 break;
11498 }
11499 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11500 attribute);
11501 break;
11502 }
11503 case 'F':
11504 case 'f':
11505 {
11506 if (LocaleCompare(attribute,"fill") == 0)
11507 {
11508 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11509 &montage_info->fill,exception);
11510 break;
11511 }
11512 if (LocaleCompare(attribute,"font") == 0)
11513 {
11514 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11515 break;
11516 }
11517 if (LocaleCompare(attribute,"frame") == 0)
11518 {
11519 char
11520 *p;
11521
11522 p=SvPV(ST(i),na);
11523 if (IsGeometry(p) == MagickFalse)
11524 {
11525 ThrowPerlException(exception,OptionError,"MissingGeometry",
11526 p);
11527 break;
11528 }
11529 (void) CloneString(&montage_info->frame,p);
11530 if (*p == '\0')
11531 montage_info->frame=(char *) NULL;
11532 break;
11533 }
11534 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11535 attribute);
11536 break;
11537 }
11538 case 'G':
11539 case 'g':
11540 {
11541 if (LocaleCompare(attribute,"geometry") == 0)
11542 {
11543 char
11544 *p;
11545
11546 p=SvPV(ST(i),na);
11547 if (IsGeometry(p) == MagickFalse)
11548 {
11549 ThrowPerlException(exception,OptionError,"MissingGeometry",
11550 p);
11551 break;
11552 }
11553 (void) CloneString(&montage_info->geometry,p);
11554 if (*p == '\0')
11555 montage_info->geometry=(char *) NULL;
11556 break;
11557 }
11558 if (LocaleCompare(attribute,"gravity") == 0)
11559 {
11560 ssize_t
11561 in;
11562
11563 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11564 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11565 if (in < 0)
11566 {
11567 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11568 SvPV(ST(i),na));
11569 return;
11570 }
11571 montage_info->gravity=(GravityType) in;
11572 for (next=image; next; next=next->next)
11573 next->gravity=(GravityType) in;
11574 break;
11575 }
11576 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11577 attribute);
11578 break;
11579 }
11580 case 'L':
11581 case 'l':
11582 {
11583 if (LocaleCompare(attribute,"label") == 0)
11584 {
11585 for (next=image; next; next=next->next)
11586 (void) SetImageProperty(next,"label",InterpretImageProperties(
11587 info ? info->image_info : (ImageInfo *) NULL,next,
11588 SvPV(ST(i),na),exception),exception);
11589 break;
11590 }
11591 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11592 attribute);
11593 break;
11594 }
11595 case 'M':
11596 case 'm':
11597 {
11598 if (LocaleCompare(attribute,"mattecolor") == 0)
11599 {
11600 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
Cristy8645e042016-02-03 16:35:29 -050011601 &montage_info->alpha_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011602 for (next=image; next; next=next->next)
Cristy8645e042016-02-03 16:35:29 -050011603 next->alpha_color=montage_info->alpha_color;
cristy4a3ce0a2013-08-03 20:06:59 +000011604 break;
11605 }
11606 if (LocaleCompare(attribute,"mode") == 0)
11607 {
11608 ssize_t
11609 in;
11610
11611 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11612 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11613 switch (in)
11614 {
11615 default:
11616 {
11617 ThrowPerlException(exception,OptionError,
11618 "UnrecognizedModeType",SvPV(ST(i),na));
11619 break;
11620 }
11621 case FrameMode:
11622 {
11623 (void) CloneString(&montage_info->frame,"15x15+3+3");
11624 montage_info->shadow=MagickTrue;
11625 break;
11626 }
11627 case UnframeMode:
11628 {
11629 montage_info->frame=(char *) NULL;
11630 montage_info->shadow=MagickFalse;
11631 montage_info->border_width=0;
11632 break;
11633 }
11634 case ConcatenateMode:
11635 {
11636 montage_info->frame=(char *) NULL;
11637 montage_info->shadow=MagickFalse;
11638 (void) CloneString(&montage_info->geometry,"+0+0");
11639 montage_info->border_width=0;
11640 }
11641 }
11642 break;
11643 }
11644 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11645 attribute);
11646 break;
11647 }
11648 case 'P':
11649 case 'p':
11650 {
11651 if (LocaleCompare(attribute,"pointsize") == 0)
11652 {
11653 montage_info->pointsize=SvIV(ST(i));
11654 break;
11655 }
11656 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11657 attribute);
11658 break;
11659 }
11660 case 'S':
11661 case 's':
11662 {
11663 if (LocaleCompare(attribute,"shadow") == 0)
11664 {
11665 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11666 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11667 if (sp < 0)
11668 {
11669 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11670 SvPV(ST(i),na));
11671 break;
11672 }
11673 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11674 break;
11675 }
11676 if (LocaleCompare(attribute,"stroke") == 0)
11677 {
11678 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11679 &montage_info->stroke,exception);
11680 break;
11681 }
11682 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11683 attribute);
11684 break;
11685 }
11686 case 'T':
11687 case 't':
11688 {
11689 if (LocaleCompare(attribute,"texture") == 0)
11690 {
11691 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11692 break;
11693 }
11694 if (LocaleCompare(attribute,"tile") == 0)
11695 {
11696 char *p=SvPV(ST(i),na);
11697 if (IsGeometry(p) == MagickFalse)
11698 {
11699 ThrowPerlException(exception,OptionError,"MissingGeometry",
11700 p);
11701 break;
11702 }
11703 (void) CloneString(&montage_info->tile,p);
11704 if (*p == '\0')
11705 montage_info->tile=(char *) NULL;
11706 break;
11707 }
11708 if (LocaleCompare(attribute,"title") == 0)
11709 {
11710 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11711 break;
11712 }
11713 if (LocaleCompare(attribute,"transparent") == 0)
11714 {
11715 PixelInfo
11716 transparent_color;
11717
11718 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11719 &transparent_color,exception);
11720 for (next=image; next; next=next->next)
11721 (void) TransparentPaintImage(next,&transparent_color,
11722 TransparentAlpha,MagickFalse,exception);
11723 break;
11724 }
11725 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11726 attribute);
11727 break;
11728 }
11729 default:
11730 {
11731 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11732 attribute);
11733 break;
11734 }
11735 }
11736 }
11737 image=MontageImageList(info->image_info,montage_info,image,exception);
11738 montage_info=DestroyMontageInfo(montage_info);
11739 if (image == (Image *) NULL)
11740 goto PerlException;
11741 if (transparent_color.alpha != TransparentAlpha)
11742 for (next=image; next; next=next->next)
11743 (void) TransparentPaintImage(next,&transparent_color,
11744 TransparentAlpha,MagickFalse,exception);
11745 for ( ; image; image=image->next)
11746 {
11747 AddImageToRegistry(sv,image);
11748 rv=newRV(sv);
11749 av_push(av,sv_bless(rv,hv));
11750 SvREFCNT_dec(sv);
11751 }
11752 exception=DestroyExceptionInfo(exception);
11753 ST(0)=av_reference;
11754 SvREFCNT_dec(perl_exception);
11755 XSRETURN(1);
11756
11757 PerlException:
11758 InheritPerlException(exception,perl_exception);
11759 exception=DestroyExceptionInfo(exception);
11760 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11761 SvPOK_on(perl_exception);
11762 ST(0)=sv_2mortal(perl_exception);
11763 XSRETURN(1);
11764 }
11765
11766#
11767###############################################################################
11768# #
11769# #
11770# #
11771# M o r p h #
11772# #
11773# #
11774# #
11775###############################################################################
11776#
11777#
11778void
11779Morph(ref,...)
11780 Image::Magick ref=NO_INIT
11781 ALIAS:
11782 MorphImage = 1
11783 morph = 2
11784 morphimage = 3
11785 PPCODE:
11786 {
11787 AV
11788 *av;
11789
11790 char
11791 *attribute;
11792
11793 ExceptionInfo
11794 *exception;
11795
11796 HV
11797 *hv;
11798
11799 Image
11800 *image;
11801
11802 register ssize_t
11803 i;
11804
11805 ssize_t
11806 number_frames;
11807
11808 struct PackageInfo
11809 *info;
11810
11811 SV
11812 *av_reference,
11813 *perl_exception,
11814 *reference,
11815 *rv,
11816 *sv;
11817
11818 PERL_UNUSED_VAR(ref);
11819 PERL_UNUSED_VAR(ix);
11820 exception=AcquireExceptionInfo();
11821 perl_exception=newSVpv("",0);
11822 sv=NULL;
11823 av=NULL;
11824 attribute=NULL;
11825 if (sv_isobject(ST(0)) == 0)
11826 {
11827 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11828 PackageName);
11829 goto PerlException;
11830 }
11831 reference=SvRV(ST(0));
11832 hv=SvSTASH(reference);
11833 av=newAV();
11834 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11835 SvREFCNT_dec(av);
11836 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11837 if (image == (Image *) NULL)
11838 {
11839 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11840 PackageName);
11841 goto PerlException;
11842 }
11843 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11844 /*
11845 Get attribute.
11846 */
11847 number_frames=30;
11848 for (i=2; i < items; i+=2)
11849 {
11850 attribute=(char *) SvPV(ST(i-1),na);
11851 switch (*attribute)
11852 {
11853 case 'F':
11854 case 'f':
11855 {
11856 if (LocaleCompare(attribute,"frames") == 0)
11857 {
11858 number_frames=SvIV(ST(i));
11859 break;
11860 }
11861 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11862 attribute);
11863 break;
11864 }
11865 default:
11866 {
11867 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11868 attribute);
11869 break;
11870 }
11871 }
11872 }
11873 image=MorphImages(image,number_frames,exception);
11874 if (image == (Image *) NULL)
11875 goto PerlException;
11876 for ( ; image; image=image->next)
11877 {
11878 AddImageToRegistry(sv,image);
11879 rv=newRV(sv);
11880 av_push(av,sv_bless(rv,hv));
11881 SvREFCNT_dec(sv);
11882 }
11883 exception=DestroyExceptionInfo(exception);
11884 ST(0)=av_reference;
11885 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11886 XSRETURN(1);
11887
11888 PerlException:
11889 InheritPerlException(exception,perl_exception);
11890 exception=DestroyExceptionInfo(exception);
11891 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11892 SvPOK_on(perl_exception);
11893 ST(0)=sv_2mortal(perl_exception);
11894 XSRETURN(1);
11895 }
11896
11897#
11898###############################################################################
11899# #
11900# #
11901# #
11902# M o s a i c #
11903# #
11904# #
11905# #
11906###############################################################################
11907#
11908#
11909void
11910Mosaic(ref)
11911 Image::Magick ref=NO_INIT
11912 ALIAS:
11913 MosaicImage = 1
11914 mosaic = 2
11915 mosaicimage = 3
11916 PPCODE:
11917 {
11918 AV
11919 *av;
11920
11921 ExceptionInfo
11922 *exception;
11923
11924 HV
11925 *hv;
11926
11927 Image
11928 *image;
11929
11930 struct PackageInfo
11931 *info;
11932
11933 SV
11934 *perl_exception,
11935 *reference,
11936 *rv,
11937 *sv;
11938
11939 PERL_UNUSED_VAR(ref);
11940 PERL_UNUSED_VAR(ix);
11941 exception=AcquireExceptionInfo();
11942 perl_exception=newSVpv("",0);
11943 sv=NULL;
11944 if (sv_isobject(ST(0)) == 0)
11945 {
11946 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11947 PackageName);
11948 goto PerlException;
11949 }
11950 reference=SvRV(ST(0));
11951 hv=SvSTASH(reference);
11952 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11953 if (image == (Image *) NULL)
11954 {
11955 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11956 PackageName);
11957 goto PerlException;
11958 }
11959 image=MergeImageLayers(image,MosaicLayer,exception);
11960 /*
11961 Create blessed Perl array for the returned image.
11962 */
11963 av=newAV();
11964 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11965 SvREFCNT_dec(av);
11966 AddImageToRegistry(sv,image);
11967 rv=newRV(sv);
11968 av_push(av,sv_bless(rv,hv));
11969 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000011970 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000011971 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000011972 SetImageInfo(info->image_info,0,exception);
11973 exception=DestroyExceptionInfo(exception);
11974 SvREFCNT_dec(perl_exception);
11975 XSRETURN(1);
11976
11977 PerlException:
11978 InheritPerlException(exception,perl_exception);
11979 exception=DestroyExceptionInfo(exception);
11980 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11981 SvPOK_on(perl_exception); /* return messages in string context */
11982 ST(0)=sv_2mortal(perl_exception);
11983 XSRETURN(1);
11984 }
11985
11986#
11987###############################################################################
11988# #
11989# #
11990# #
11991# P i n g #
11992# #
11993# #
11994# #
11995###############################################################################
11996#
11997#
11998void
11999Ping(ref,...)
12000 Image::Magick ref=NO_INIT
12001 ALIAS:
12002 PingImage = 1
12003 ping = 2
12004 pingimage = 3
12005 PPCODE:
12006 {
12007 AV
12008 *av;
12009
12010 char
12011 **keep,
12012 **list;
12013
12014 ExceptionInfo
12015 *exception;
12016
12017 Image
12018 *image,
12019 *next;
12020
12021 int
12022 n;
12023
12024 MagickBooleanType
12025 status;
12026
12027 register char
12028 **p;
12029
12030 register ssize_t
12031 i;
12032
12033 ssize_t
12034 ac;
12035
12036 STRLEN
12037 *length;
12038
12039 struct PackageInfo
12040 *info,
12041 *package_info;
12042
12043 SV
12044 *perl_exception,
12045 *reference;
12046
12047 size_t
12048 count;
12049
12050 PERL_UNUSED_VAR(ref);
12051 PERL_UNUSED_VAR(ix);
12052 exception=AcquireExceptionInfo();
12053 perl_exception=newSVpv("",0);
12054 package_info=(struct PackageInfo *) NULL;
12055 ac=(items < 2) ? 1 : items-1;
12056 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12057 keep=list;
12058 length=(STRLEN *) NULL;
12059 if (list == (char **) NULL)
12060 {
12061 ThrowPerlException(exception,ResourceLimitError,
12062 "MemoryAllocationFailed",PackageName);
12063 goto PerlException;
12064 }
12065 keep=list;
12066 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12067 if (length == (STRLEN *) NULL)
12068 {
12069 ThrowPerlException(exception,ResourceLimitError,
12070 "MemoryAllocationFailed",PackageName);
12071 goto PerlException;
12072 }
12073 if (sv_isobject(ST(0)) == 0)
12074 {
12075 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12076 PackageName);
12077 goto PerlException;
12078 }
12079 reference=SvRV(ST(0));
12080 if (SvTYPE(reference) != SVt_PVAV)
12081 {
12082 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12083 PackageName);
12084 goto PerlException;
12085 }
12086 av=(AV *) reference;
12087 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12088 exception);
12089 package_info=ClonePackageInfo(info,exception);
12090 n=1;
12091 if (items <= 1)
12092 *list=(char *) (*package_info->image_info->filename ?
12093 package_info->image_info->filename : "XC:black");
12094 else
12095 for (n=0, i=0; i < ac; i++)
12096 {
12097 list[n]=(char *) SvPV(ST(i+1),length[n]);
12098 if ((items >= 3) && strEQcase(list[n],"blob"))
12099 {
12100 void
12101 *blob;
12102
12103 i++;
12104 blob=(void *) (SvPV(ST(i+1),length[n]));
12105 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12106 }
12107 if ((items >= 3) && strEQcase(list[n],"filename"))
12108 continue;
12109 if ((items >= 3) && strEQcase(list[n],"file"))
12110 {
12111 FILE
12112 *file;
12113
12114 PerlIO
12115 *io_info;
12116
12117 i++;
12118 io_info=IoIFP(sv_2io(ST(i+1)));
12119 if (io_info == (PerlIO *) NULL)
12120 {
12121 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12122 PackageName);
12123 continue;
12124 }
12125 file=PerlIO_findFILE(io_info);
12126 if (file == (FILE *) NULL)
12127 {
12128 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12129 PackageName);
12130 continue;
12131 }
12132 SetImageInfoFile(package_info->image_info,file);
12133 }
12134 if ((items >= 3) && strEQcase(list[n],"magick"))
12135 continue;
12136 n++;
12137 }
12138 list[n]=(char *) NULL;
12139 keep=list;
12140 status=ExpandFilenames(&n,&list);
12141 if (status == MagickFalse)
12142 {
12143 ThrowPerlException(exception,ResourceLimitError,
12144 "MemoryAllocationFailed",PackageName);
12145 goto PerlException;
12146 }
12147 count=0;
12148 for (i=0; i < n; i++)
12149 {
12150 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012151 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012152 image=PingImage(package_info->image_info,exception);
12153 if (image == (Image *) NULL)
12154 break;
12155 if ((package_info->image_info->file != (FILE *) NULL) ||
12156 (package_info->image_info->blob != (void *) NULL))
12157 DisassociateImageStream(image);
12158 count+=GetImageListLength(image);
12159 EXTEND(sp,4*count);
12160 for (next=image; next; next=next->next)
12161 {
12162 PUSHs(sv_2mortal(newSViv(next->columns)));
12163 PUSHs(sv_2mortal(newSViv(next->rows)));
12164 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12165 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12166 }
12167 image=DestroyImageList(image);
12168 }
12169 /*
12170 Free resources.
12171 */
12172 for (i=0; i < n; i++)
12173 if (list[i] != (char *) NULL)
12174 for (p=keep; list[i] != *p++; )
12175 if (*p == NULL)
12176 {
12177 list[i]=(char *) RelinquishMagickMemory(list[i]);
12178 break;
12179 }
12180
12181 PerlException:
12182 if (package_info != (struct PackageInfo *) NULL)
12183 DestroyPackageInfo(package_info);
12184 if (list && (list != keep))
12185 list=(char **) RelinquishMagickMemory(list);
12186 if (keep)
12187 keep=(char **) RelinquishMagickMemory(keep);
12188 if (length)
12189 length=(STRLEN *) RelinquishMagickMemory(length);
12190 InheritPerlException(exception,perl_exception);
12191 exception=DestroyExceptionInfo(exception);
12192 SvREFCNT_dec(perl_exception); /* throw away all errors */
12193 }
12194
12195#
12196###############################################################################
12197# #
12198# #
12199# #
12200# P r e v i e w #
12201# #
12202# #
12203# #
12204###############################################################################
12205#
12206#
12207void
12208Preview(ref,...)
12209 Image::Magick ref=NO_INIT
12210 ALIAS:
12211 PreviewImage = 1
12212 preview = 2
12213 previewimage = 3
12214 PPCODE:
12215 {
12216 AV
12217 *av;
12218
12219 ExceptionInfo
12220 *exception;
12221
12222 HV
12223 *hv;
12224
12225 Image
12226 *image,
12227 *preview_image;
12228
12229 PreviewType
12230 preview_type;
12231
12232 struct PackageInfo
12233 *info;
12234
12235 SV
12236 *av_reference,
12237 *perl_exception,
12238 *reference,
12239 *rv,
12240 *sv;
12241
12242 PERL_UNUSED_VAR(ref);
12243 PERL_UNUSED_VAR(ix);
12244 exception=AcquireExceptionInfo();
12245 perl_exception=newSVpv("",0);
12246 sv=NULL;
12247 av=NULL;
12248 if (sv_isobject(ST(0)) == 0)
12249 {
12250 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12251 PackageName);
12252 goto PerlException;
12253 }
12254 reference=SvRV(ST(0));
12255 hv=SvSTASH(reference);
12256 av=newAV();
12257 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12258 SvREFCNT_dec(av);
12259 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12260 if (image == (Image *) NULL)
12261 {
12262 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12263 PackageName);
12264 goto PerlException;
12265 }
12266 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12267 preview_type=GammaPreview;
12268 if (items > 1)
12269 preview_type=(PreviewType)
12270 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12271 for ( ; image; image=image->next)
12272 {
12273 preview_image=PreviewImage(image,preview_type,exception);
12274 if (preview_image == (Image *) NULL)
12275 goto PerlException;
12276 AddImageToRegistry(sv,preview_image);
12277 rv=newRV(sv);
12278 av_push(av,sv_bless(rv,hv));
12279 SvREFCNT_dec(sv);
12280 }
12281 exception=DestroyExceptionInfo(exception);
12282 ST(0)=av_reference;
12283 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12284 XSRETURN(1);
12285
12286 PerlException:
12287 InheritPerlException(exception,perl_exception);
12288 exception=DestroyExceptionInfo(exception);
12289 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12290 SvPOK_on(perl_exception);
12291 ST(0)=sv_2mortal(perl_exception);
12292 XSRETURN(1);
12293 }
12294
12295#
12296###############################################################################
12297# #
12298# #
12299# #
12300# Q u e r y C o l o r #
12301# #
12302# #
12303# #
12304###############################################################################
12305#
12306#
12307void
12308QueryColor(ref,...)
12309 Image::Magick ref=NO_INIT
12310 ALIAS:
12311 querycolor = 1
12312 PPCODE:
12313 {
12314 char
12315 *name;
12316
12317 ExceptionInfo
12318 *exception;
12319
12320 PixelInfo
12321 color;
12322
12323 register ssize_t
12324 i;
12325
12326 SV
12327 *perl_exception;
12328
12329 PERL_UNUSED_VAR(ref);
12330 PERL_UNUSED_VAR(ix);
12331 exception=AcquireExceptionInfo();
12332 perl_exception=newSVpv("",0);
12333 if (items == 1)
12334 {
12335 const ColorInfo
12336 **colorlist;
12337
12338 size_t
12339 colors;
12340
12341 colorlist=GetColorInfoList("*",&colors,exception);
12342 EXTEND(sp,colors);
12343 for (i=0; i < (ssize_t) colors; i++)
12344 {
12345 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12346 }
12347 colorlist=(const ColorInfo **)
12348 RelinquishMagickMemory((ColorInfo **) colorlist);
12349 goto PerlException;
12350 }
12351 EXTEND(sp,5*items);
12352 for (i=1; i < items; i++)
12353 {
12354 name=(char *) SvPV(ST(i),na);
12355 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12356 {
12357 PUSHs(&sv_undef);
12358 continue;
12359 }
12360 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12361 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12362 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12363 if (color.colorspace == CMYKColorspace)
12364 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012365 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012366 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12367 }
12368
12369 PerlException:
12370 InheritPerlException(exception,perl_exception);
12371 exception=DestroyExceptionInfo(exception);
12372 SvREFCNT_dec(perl_exception);
12373 }
12374
12375#
12376###############################################################################
12377# #
12378# #
12379# #
12380# Q u e r y C o l o r N a m e #
12381# #
12382# #
12383# #
12384###############################################################################
12385#
12386#
12387void
12388QueryColorname(ref,...)
12389 Image::Magick ref=NO_INIT
12390 ALIAS:
12391 querycolorname = 1
12392 PPCODE:
12393 {
12394 AV
12395 *av;
12396
12397 char
cristy151b66d2015-04-15 10:50:31 +000012398 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012399
12400 ExceptionInfo
12401 *exception;
12402
12403 Image
12404 *image;
12405
12406 PixelInfo
12407 target_color;
12408
12409 register ssize_t
12410 i;
12411
12412 struct PackageInfo
12413 *info;
12414
12415 SV
12416 *perl_exception,
12417 *reference; /* reference is the SV* of ref=SvIV(reference) */
12418
12419 PERL_UNUSED_VAR(ref);
12420 PERL_UNUSED_VAR(ix);
12421 exception=AcquireExceptionInfo();
12422 perl_exception=newSVpv("",0);
12423 reference=SvRV(ST(0));
12424 av=(AV *) reference;
12425 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12426 exception);
12427 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12428 if (image == (Image *) NULL)
12429 {
12430 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12431 PackageName);
12432 goto PerlException;
12433 }
12434 EXTEND(sp,items);
12435 for (i=1; i < items; i++)
12436 {
12437 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12438 exception);
12439 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12440 exception);
12441 PUSHs(sv_2mortal(newSVpv(message,0)));
12442 }
12443
12444 PerlException:
12445 InheritPerlException(exception,perl_exception);
12446 exception=DestroyExceptionInfo(exception);
12447 SvREFCNT_dec(perl_exception);
12448 }
12449
12450#
12451###############################################################################
12452# #
12453# #
12454# #
12455# Q u e r y F o n t #
12456# #
12457# #
12458# #
12459###############################################################################
12460#
12461#
12462void
12463QueryFont(ref,...)
12464 Image::Magick ref=NO_INIT
12465 ALIAS:
12466 queryfont = 1
12467 PPCODE:
12468 {
12469 char
12470 *name,
cristy151b66d2015-04-15 10:50:31 +000012471 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012472
12473 ExceptionInfo
12474 *exception;
12475
12476 register ssize_t
12477 i;
12478
12479 SV
12480 *perl_exception;
12481
12482 volatile const TypeInfo
12483 *type_info;
12484
12485 PERL_UNUSED_VAR(ref);
12486 PERL_UNUSED_VAR(ix);
12487 exception=AcquireExceptionInfo();
12488 perl_exception=newSVpv("",0);
12489 if (items == 1)
12490 {
12491 const TypeInfo
12492 **typelist;
12493
12494 size_t
12495 types;
12496
12497 typelist=GetTypeInfoList("*",&types,exception);
12498 EXTEND(sp,types);
12499 for (i=0; i < (ssize_t) types; i++)
12500 {
12501 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12502 }
12503 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12504 typelist);
12505 goto PerlException;
12506 }
12507 EXTEND(sp,10*items);
12508 for (i=1; i < items; i++)
12509 {
12510 name=(char *) SvPV(ST(i),na);
12511 type_info=GetTypeInfo(name,exception);
12512 if (type_info == (TypeInfo *) NULL)
12513 {
12514 PUSHs(&sv_undef);
12515 continue;
12516 }
12517 if (type_info->name == (char *) NULL)
12518 PUSHs(&sv_undef);
12519 else
12520 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12521 if (type_info->description == (char *) NULL)
12522 PUSHs(&sv_undef);
12523 else
12524 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12525 if (type_info->family == (char *) NULL)
12526 PUSHs(&sv_undef);
12527 else
12528 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12529 if (type_info->style == UndefinedStyle)
12530 PUSHs(&sv_undef);
12531 else
12532 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12533 type_info->style),0)));
12534 if (type_info->stretch == UndefinedStretch)
12535 PUSHs(&sv_undef);
12536 else
12537 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12538 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012539 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012540 type_info->weight);
12541 PUSHs(sv_2mortal(newSVpv(message,0)));
12542 if (type_info->encoding == (char *) NULL)
12543 PUSHs(&sv_undef);
12544 else
12545 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12546 if (type_info->foundry == (char *) NULL)
12547 PUSHs(&sv_undef);
12548 else
12549 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12550 if (type_info->format == (char *) NULL)
12551 PUSHs(&sv_undef);
12552 else
12553 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12554 if (type_info->metrics == (char *) NULL)
12555 PUSHs(&sv_undef);
12556 else
12557 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12558 if (type_info->glyphs == (char *) NULL)
12559 PUSHs(&sv_undef);
12560 else
12561 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12562 }
12563
12564 PerlException:
12565 InheritPerlException(exception,perl_exception);
12566 exception=DestroyExceptionInfo(exception);
12567 SvREFCNT_dec(perl_exception);
12568 }
12569
12570#
12571###############################################################################
12572# #
12573# #
12574# #
12575# Q u e r y F o n t M e t r i c s #
12576# #
12577# #
12578# #
12579###############################################################################
12580#
12581#
12582void
12583QueryFontMetrics(ref,...)
12584 Image::Magick ref=NO_INIT
12585 ALIAS:
12586 queryfontmetrics = 1
12587 PPCODE:
12588 {
12589 AffineMatrix
12590 affine,
12591 current;
12592
12593 AV
12594 *av;
12595
12596 char
12597 *attribute;
12598
12599 double
12600 x,
12601 y;
12602
12603 DrawInfo
12604 *draw_info;
12605
12606 ExceptionInfo
12607 *exception;
12608
12609 GeometryInfo
12610 geometry_info;
12611
12612 Image
12613 *image;
12614
12615 MagickBooleanType
12616 status;
12617
12618 MagickStatusType
12619 flags;
12620
12621 register ssize_t
12622 i;
12623
12624 ssize_t
12625 type;
12626
12627 struct PackageInfo
12628 *info,
12629 *package_info;
12630
12631 SV
12632 *perl_exception,
12633 *reference; /* reference is the SV* of ref=SvIV(reference) */
12634
12635 TypeMetric
12636 metrics;
12637
12638 PERL_UNUSED_VAR(ref);
12639 PERL_UNUSED_VAR(ix);
12640 exception=AcquireExceptionInfo();
12641 package_info=(struct PackageInfo *) NULL;
12642 perl_exception=newSVpv("",0);
12643 reference=SvRV(ST(0));
12644 av=(AV *) reference;
12645 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12646 exception);
12647 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12648 if (image == (Image *) NULL)
12649 {
12650 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12651 PackageName);
12652 goto PerlException;
12653 }
12654 package_info=ClonePackageInfo(info,exception);
12655 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12656 CloneString(&draw_info->text,"");
12657 current=draw_info->affine;
12658 GetAffineMatrix(&affine);
12659 x=0.0;
12660 y=0.0;
12661 EXTEND(sp,7*items);
12662 for (i=2; i < items; i+=2)
12663 {
12664 attribute=(char *) SvPV(ST(i-1),na);
12665 switch (*attribute)
12666 {
12667 case 'A':
12668 case 'a':
12669 {
12670 if (LocaleCompare(attribute,"antialias") == 0)
12671 {
12672 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12673 SvPV(ST(i),na));
12674 if (type < 0)
12675 {
12676 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12677 SvPV(ST(i),na));
12678 break;
12679 }
12680 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12681 break;
12682 }
12683 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12684 attribute);
12685 break;
12686 }
12687 case 'd':
12688 case 'D':
12689 {
12690 if (LocaleCompare(attribute,"density") == 0)
12691 {
12692 CloneString(&draw_info->density,SvPV(ST(i),na));
12693 break;
12694 }
12695 if (LocaleCompare(attribute,"direction") == 0)
12696 {
12697 draw_info->direction=(DirectionType) ParseCommandOption(
12698 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12699 break;
12700 }
12701 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12702 attribute);
12703 break;
12704 }
12705 case 'e':
12706 case 'E':
12707 {
12708 if (LocaleCompare(attribute,"encoding") == 0)
12709 {
12710 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12711 break;
12712 }
12713 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12714 attribute);
12715 break;
12716 }
12717 case 'f':
12718 case 'F':
12719 {
12720 if (LocaleCompare(attribute,"family") == 0)
12721 {
12722 CloneString(&draw_info->family,SvPV(ST(i),na));
12723 break;
12724 }
12725 if (LocaleCompare(attribute,"fill") == 0)
12726 {
12727 if (info)
12728 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12729 &draw_info->fill,exception);
12730 break;
12731 }
12732 if (LocaleCompare(attribute,"font") == 0)
12733 {
12734 CloneString(&draw_info->font,SvPV(ST(i),na));
12735 break;
12736 }
12737 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12738 attribute);
12739 break;
12740 }
12741 case 'g':
12742 case 'G':
12743 {
12744 if (LocaleCompare(attribute,"geometry") == 0)
12745 {
12746 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12747 break;
12748 }
12749 if (LocaleCompare(attribute,"gravity") == 0)
12750 {
12751 draw_info->gravity=(GravityType) ParseCommandOption(
12752 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12753 break;
12754 }
12755 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12756 attribute);
12757 break;
12758 }
12759 case 'i':
12760 case 'I':
12761 {
12762 if (LocaleCompare(attribute,"interline-spacing") == 0)
12763 {
12764 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12765 draw_info->interline_spacing=geometry_info.rho;
12766 break;
12767 }
12768 if (LocaleCompare(attribute,"interword-spacing") == 0)
12769 {
12770 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12771 draw_info->interword_spacing=geometry_info.rho;
12772 break;
12773 }
12774 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12775 attribute);
12776 break;
12777 }
12778 case 'k':
12779 case 'K':
12780 {
12781 if (LocaleCompare(attribute,"kerning") == 0)
12782 {
12783 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12784 draw_info->kerning=geometry_info.rho;
12785 break;
12786 }
12787 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12788 attribute);
12789 break;
12790 }
12791 case 'p':
12792 case 'P':
12793 {
12794 if (LocaleCompare(attribute,"pointsize") == 0)
12795 {
12796 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12797 draw_info->pointsize=geometry_info.rho;
12798 break;
12799 }
12800 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12801 attribute);
12802 break;
12803 }
12804 case 'r':
12805 case 'R':
12806 {
12807 if (LocaleCompare(attribute,"rotate") == 0)
12808 {
12809 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12810 affine.rx=geometry_info.rho;
12811 affine.ry=geometry_info.sigma;
12812 if ((flags & SigmaValue) == 0)
12813 affine.ry=affine.rx;
12814 break;
12815 }
12816 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12817 attribute);
12818 break;
12819 }
12820 case 's':
12821 case 'S':
12822 {
12823 if (LocaleCompare(attribute,"scale") == 0)
12824 {
12825 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12826 affine.sx=geometry_info.rho;
12827 affine.sy=geometry_info.sigma;
12828 if ((flags & SigmaValue) == 0)
12829 affine.sy=affine.sx;
12830 break;
12831 }
12832 if (LocaleCompare(attribute,"skew") == 0)
12833 {
12834 double
12835 x_angle,
12836 y_angle;
12837
12838 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12839 x_angle=geometry_info.rho;
12840 y_angle=geometry_info.sigma;
12841 if ((flags & SigmaValue) == 0)
12842 y_angle=x_angle;
12843 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12844 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12845 break;
12846 }
12847 if (LocaleCompare(attribute,"stroke") == 0)
12848 {
12849 if (info)
12850 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12851 &draw_info->stroke,exception);
12852 break;
12853 }
12854 if (LocaleCompare(attribute,"style") == 0)
12855 {
12856 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12857 SvPV(ST(i),na));
12858 if (type < 0)
12859 {
12860 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12861 SvPV(ST(i),na));
12862 break;
12863 }
12864 draw_info->style=(StyleType) type;
12865 break;
12866 }
12867 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12868 attribute);
12869 break;
12870 }
12871 case 't':
12872 case 'T':
12873 {
12874 if (LocaleCompare(attribute,"text") == 0)
12875 {
12876 CloneString(&draw_info->text,SvPV(ST(i),na));
12877 break;
12878 }
12879 if (LocaleCompare(attribute,"translate") == 0)
12880 {
12881 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12882 affine.tx=geometry_info.rho;
12883 affine.ty=geometry_info.sigma;
12884 if ((flags & SigmaValue) == 0)
12885 affine.ty=affine.tx;
12886 break;
12887 }
12888 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12889 attribute);
12890 break;
12891 }
12892 case 'w':
12893 case 'W':
12894 {
12895 if (LocaleCompare(attribute,"weight") == 0)
12896 {
12897 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12898 draw_info->weight=(size_t) geometry_info.rho;
12899 break;
12900 }
12901 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12902 attribute);
12903 break;
12904 }
12905 case 'x':
12906 case 'X':
12907 {
12908 if (LocaleCompare(attribute,"x") == 0)
12909 {
12910 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12911 x=geometry_info.rho;
12912 break;
12913 }
12914 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12915 attribute);
12916 break;
12917 }
12918 case 'y':
12919 case 'Y':
12920 {
12921 if (LocaleCompare(attribute,"y") == 0)
12922 {
12923 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12924 y=geometry_info.rho;
12925 break;
12926 }
12927 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12928 attribute);
12929 break;
12930 }
12931 default:
12932 {
12933 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12934 attribute);
12935 break;
12936 }
12937 }
12938 }
12939 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12940 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12941 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12942 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12943 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12944 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12945 if (draw_info->geometry == (char *) NULL)
12946 {
12947 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000012948 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000012949 "%.15g,%.15g",x,y);
12950 }
12951 status=GetTypeMetrics(image,draw_info,&metrics,exception);
12952 (void) CatchImageException(image);
12953 if (status == MagickFalse)
12954 PUSHs(&sv_undef);
12955 else
12956 {
12957 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12958 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12959 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12960 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12961 PUSHs(sv_2mortal(newSVnv(metrics.width)));
12962 PUSHs(sv_2mortal(newSVnv(metrics.height)));
12963 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12964 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
12965 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
12966 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
12967 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
12968 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
12969 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
12970 }
12971 draw_info=DestroyDrawInfo(draw_info);
12972
12973 PerlException:
12974 if (package_info != (struct PackageInfo *) NULL)
12975 DestroyPackageInfo(package_info);
12976 InheritPerlException(exception,perl_exception);
12977 exception=DestroyExceptionInfo(exception);
12978 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12979 }
12980
12981#
12982###############################################################################
12983# #
12984# #
12985# #
12986# 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 #
12987# #
12988# #
12989# #
12990###############################################################################
12991#
12992#
12993void
12994QueryMultilineFontMetrics(ref,...)
12995 Image::Magick ref=NO_INIT
12996 ALIAS:
12997 querymultilinefontmetrics = 1
12998 PPCODE:
12999 {
13000 AffineMatrix
13001 affine,
13002 current;
13003
13004 AV
13005 *av;
13006
13007 char
13008 *attribute;
13009
13010 double
13011 x,
13012 y;
13013
13014 DrawInfo
13015 *draw_info;
13016
13017 ExceptionInfo
13018 *exception;
13019
13020 GeometryInfo
13021 geometry_info;
13022
13023 Image
13024 *image;
13025
13026 MagickBooleanType
13027 status;
13028
13029 MagickStatusType
13030 flags;
13031
13032 register ssize_t
13033 i;
13034
13035 ssize_t
13036 type;
13037
13038 struct PackageInfo
13039 *info,
13040 *package_info;
13041
13042 SV
13043 *perl_exception,
13044 *reference; /* reference is the SV* of ref=SvIV(reference) */
13045
13046 TypeMetric
13047 metrics;
13048
13049 PERL_UNUSED_VAR(ref);
13050 PERL_UNUSED_VAR(ix);
13051 exception=AcquireExceptionInfo();
13052 package_info=(struct PackageInfo *) NULL;
13053 perl_exception=newSVpv("",0);
13054 reference=SvRV(ST(0));
13055 av=(AV *) reference;
13056 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13057 exception);
13058 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13059 if (image == (Image *) NULL)
13060 {
13061 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13062 PackageName);
13063 goto PerlException;
13064 }
13065 package_info=ClonePackageInfo(info,exception);
13066 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13067 CloneString(&draw_info->text,"");
13068 current=draw_info->affine;
13069 GetAffineMatrix(&affine);
13070 x=0.0;
13071 y=0.0;
13072 EXTEND(sp,7*items);
13073 for (i=2; i < items; i+=2)
13074 {
13075 attribute=(char *) SvPV(ST(i-1),na);
13076 switch (*attribute)
13077 {
13078 case 'A':
13079 case 'a':
13080 {
13081 if (LocaleCompare(attribute,"antialias") == 0)
13082 {
13083 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13084 SvPV(ST(i),na));
13085 if (type < 0)
13086 {
13087 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13088 SvPV(ST(i),na));
13089 break;
13090 }
13091 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13092 break;
13093 }
13094 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13095 attribute);
13096 break;
13097 }
13098 case 'd':
13099 case 'D':
13100 {
13101 if (LocaleCompare(attribute,"density") == 0)
13102 {
13103 CloneString(&draw_info->density,SvPV(ST(i),na));
13104 break;
13105 }
13106 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13107 attribute);
13108 break;
13109 }
13110 case 'e':
13111 case 'E':
13112 {
13113 if (LocaleCompare(attribute,"encoding") == 0)
13114 {
13115 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13116 break;
13117 }
13118 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13119 attribute);
13120 break;
13121 }
13122 case 'f':
13123 case 'F':
13124 {
13125 if (LocaleCompare(attribute,"family") == 0)
13126 {
13127 CloneString(&draw_info->family,SvPV(ST(i),na));
13128 break;
13129 }
13130 if (LocaleCompare(attribute,"fill") == 0)
13131 {
13132 if (info)
13133 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13134 &draw_info->fill,exception);
13135 break;
13136 }
13137 if (LocaleCompare(attribute,"font") == 0)
13138 {
13139 CloneString(&draw_info->font,SvPV(ST(i),na));
13140 break;
13141 }
13142 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13143 attribute);
13144 break;
13145 }
13146 case 'g':
13147 case 'G':
13148 {
13149 if (LocaleCompare(attribute,"geometry") == 0)
13150 {
13151 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13152 break;
13153 }
13154 if (LocaleCompare(attribute,"gravity") == 0)
13155 {
13156 draw_info->gravity=(GravityType) ParseCommandOption(
13157 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13158 break;
13159 }
13160 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13161 attribute);
13162 break;
13163 }
13164 case 'p':
13165 case 'P':
13166 {
13167 if (LocaleCompare(attribute,"pointsize") == 0)
13168 {
13169 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13170 draw_info->pointsize=geometry_info.rho;
13171 break;
13172 }
13173 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13174 attribute);
13175 break;
13176 }
13177 case 'r':
13178 case 'R':
13179 {
13180 if (LocaleCompare(attribute,"rotate") == 0)
13181 {
13182 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13183 affine.rx=geometry_info.rho;
13184 affine.ry=geometry_info.sigma;
13185 if ((flags & SigmaValue) == 0)
13186 affine.ry=affine.rx;
13187 break;
13188 }
13189 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13190 attribute);
13191 break;
13192 }
13193 case 's':
13194 case 'S':
13195 {
13196 if (LocaleCompare(attribute,"scale") == 0)
13197 {
13198 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13199 affine.sx=geometry_info.rho;
13200 affine.sy=geometry_info.sigma;
13201 if ((flags & SigmaValue) == 0)
13202 affine.sy=affine.sx;
13203 break;
13204 }
13205 if (LocaleCompare(attribute,"skew") == 0)
13206 {
13207 double
13208 x_angle,
13209 y_angle;
13210
13211 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13212 x_angle=geometry_info.rho;
13213 y_angle=geometry_info.sigma;
13214 if ((flags & SigmaValue) == 0)
13215 y_angle=x_angle;
13216 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13217 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13218 break;
13219 }
13220 if (LocaleCompare(attribute,"stroke") == 0)
13221 {
13222 if (info)
13223 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13224 &draw_info->stroke,exception);
13225 break;
13226 }
13227 if (LocaleCompare(attribute,"style") == 0)
13228 {
13229 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13230 SvPV(ST(i),na));
13231 if (type < 0)
13232 {
13233 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13234 SvPV(ST(i),na));
13235 break;
13236 }
13237 draw_info->style=(StyleType) type;
13238 break;
13239 }
13240 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13241 attribute);
13242 break;
13243 }
13244 case 't':
13245 case 'T':
13246 {
13247 if (LocaleCompare(attribute,"text") == 0)
13248 {
13249 CloneString(&draw_info->text,SvPV(ST(i),na));
13250 break;
13251 }
13252 if (LocaleCompare(attribute,"translate") == 0)
13253 {
13254 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13255 affine.tx=geometry_info.rho;
13256 affine.ty=geometry_info.sigma;
13257 if ((flags & SigmaValue) == 0)
13258 affine.ty=affine.tx;
13259 break;
13260 }
13261 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13262 attribute);
13263 break;
13264 }
13265 case 'w':
13266 case 'W':
13267 {
13268 if (LocaleCompare(attribute,"weight") == 0)
13269 {
13270 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13271 draw_info->weight=(size_t) geometry_info.rho;
13272 break;
13273 }
13274 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13275 attribute);
13276 break;
13277 }
13278 case 'x':
13279 case 'X':
13280 {
13281 if (LocaleCompare(attribute,"x") == 0)
13282 {
13283 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13284 x=geometry_info.rho;
13285 break;
13286 }
13287 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13288 attribute);
13289 break;
13290 }
13291 case 'y':
13292 case 'Y':
13293 {
13294 if (LocaleCompare(attribute,"y") == 0)
13295 {
13296 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13297 y=geometry_info.rho;
13298 break;
13299 }
13300 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13301 attribute);
13302 break;
13303 }
13304 default:
13305 {
13306 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13307 attribute);
13308 break;
13309 }
13310 }
13311 }
13312 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13313 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13314 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13315 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13316 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13317 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13318 if (draw_info->geometry == (char *) NULL)
13319 {
13320 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013321 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013322 "%.15g,%.15g",x,y);
13323 }
13324 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13325 (void) CatchException(exception);
13326 if (status == MagickFalse)
13327 PUSHs(&sv_undef);
13328 else
13329 {
13330 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13331 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13332 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13333 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13334 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13335 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13336 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13337 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13338 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13339 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13340 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13341 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13342 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13343 }
13344 draw_info=DestroyDrawInfo(draw_info);
13345
13346 PerlException:
13347 if (package_info != (struct PackageInfo *) NULL)
13348 DestroyPackageInfo(package_info);
13349 InheritPerlException(exception,perl_exception);
13350 exception=DestroyExceptionInfo(exception);
13351 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13352 }
13353
13354#
13355###############################################################################
13356# #
13357# #
13358# #
13359# Q u e r y F o r m a t #
13360# #
13361# #
13362# #
13363###############################################################################
13364#
13365#
13366void
13367QueryFormat(ref,...)
13368 Image::Magick ref=NO_INIT
13369 ALIAS:
13370 queryformat = 1
13371 PPCODE:
13372 {
13373 char
13374 *name;
13375
13376 ExceptionInfo
13377 *exception;
13378
13379 register ssize_t
13380 i;
13381
13382 SV
13383 *perl_exception;
13384
13385 volatile const MagickInfo
13386 *magick_info;
13387
13388 PERL_UNUSED_VAR(ref);
13389 PERL_UNUSED_VAR(ix);
13390 exception=AcquireExceptionInfo();
13391 perl_exception=newSVpv("",0);
13392 if (items == 1)
13393 {
13394 char
cristy151b66d2015-04-15 10:50:31 +000013395 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013396
13397 const MagickInfo
13398 **format_list;
13399
13400 size_t
13401 types;
13402
13403 format_list=GetMagickInfoList("*",&types,exception);
13404 EXTEND(sp,types);
13405 for (i=0; i < (ssize_t) types; i++)
13406 {
cristy151b66d2015-04-15 10:50:31 +000013407 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013408 LocaleLower(format);
13409 PUSHs(sv_2mortal(newSVpv(format,0)));
13410 }
13411 format_list=(const MagickInfo **)
13412 RelinquishMagickMemory((MagickInfo *) format_list);
13413 goto PerlException;
13414 }
13415 EXTEND(sp,8*items);
13416 for (i=1; i < items; i++)
13417 {
13418 name=(char *) SvPV(ST(i),na);
13419 magick_info=GetMagickInfo(name,exception);
13420 if (magick_info == (const MagickInfo *) NULL)
13421 {
13422 PUSHs(&sv_undef);
13423 continue;
13424 }
cristy4a3ce0a2013-08-03 20:06:59 +000013425 if (magick_info->description == (char *) NULL)
13426 PUSHs(&sv_undef);
13427 else
13428 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13429 if (magick_info->module == (char *) NULL)
13430 PUSHs(&sv_undef);
13431 else
13432 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13433 }
13434
13435 PerlException:
13436 InheritPerlException(exception,perl_exception);
13437 exception=DestroyExceptionInfo(exception);
13438 SvREFCNT_dec(perl_exception);
13439 }
13440
13441#
13442###############################################################################
13443# #
13444# #
13445# #
13446# Q u e r y O p t i o n #
13447# #
13448# #
13449# #
13450###############################################################################
13451#
13452#
13453void
13454QueryOption(ref,...)
13455 Image::Magick ref=NO_INIT
13456 ALIAS:
13457 queryoption = 1
13458 PPCODE:
13459 {
13460 char
13461 **options;
13462
13463 ExceptionInfo
13464 *exception;
13465
13466 register ssize_t
13467 i;
13468
13469 ssize_t
13470 j,
13471 option;
13472
13473 SV
13474 *perl_exception;
13475
13476 PERL_UNUSED_VAR(ref);
13477 PERL_UNUSED_VAR(ix);
13478 exception=AcquireExceptionInfo();
13479 perl_exception=newSVpv("",0);
13480 EXTEND(sp,8*items);
13481 for (i=1; i < items; i++)
13482 {
13483 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13484 SvPV(ST(i),na));
13485 options=GetCommandOptions((CommandOption) option);
13486 if (options == (char **) NULL)
13487 PUSHs(&sv_undef);
13488 else
13489 {
13490 for (j=0; options[j] != (char *) NULL; j++)
13491 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13492 options=DestroyStringList(options);
13493 }
13494 }
13495
13496 InheritPerlException(exception,perl_exception);
13497 exception=DestroyExceptionInfo(exception);
13498 SvREFCNT_dec(perl_exception);
13499 }
13500
13501#
13502###############################################################################
13503# #
13504# #
13505# #
13506# R e a d #
13507# #
13508# #
13509# #
13510###############################################################################
13511#
13512#
13513void
13514Read(ref,...)
13515 Image::Magick ref=NO_INIT
13516 ALIAS:
13517 ReadImage = 1
13518 read = 2
13519 readimage = 3
13520 PPCODE:
13521 {
13522 AV
13523 *av;
13524
13525 char
13526 **keep,
13527 **list;
13528
13529 ExceptionInfo
13530 *exception;
13531
13532 HV
13533 *hv;
13534
13535 Image
13536 *image;
13537
13538 int
13539 n;
13540
13541 MagickBooleanType
13542 status;
13543
13544 register char
13545 **p;
13546
13547 register ssize_t
13548 i;
13549
13550 ssize_t
13551 ac,
13552 number_images;
13553
13554 STRLEN
13555 *length;
13556
13557 struct PackageInfo
13558 *info,
13559 *package_info;
13560
13561 SV
13562 *perl_exception, /* Perl variable for storing messages */
13563 *reference,
13564 *rv,
13565 *sv;
13566
13567 PERL_UNUSED_VAR(ref);
13568 PERL_UNUSED_VAR(ix);
13569 exception=AcquireExceptionInfo();
13570 perl_exception=newSVpv("",0);
13571 sv=NULL;
13572 package_info=(struct PackageInfo *) NULL;
13573 number_images=0;
13574 ac=(items < 2) ? 1 : items-1;
13575 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13576 keep=list;
13577 length=(STRLEN *) NULL;
13578 if (list == (char **) NULL)
13579 {
13580 ThrowPerlException(exception,ResourceLimitError,
13581 "MemoryAllocationFailed",PackageName);
13582 goto PerlException;
13583 }
13584 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13585 if (length == (STRLEN *) NULL)
13586 {
13587 ThrowPerlException(exception,ResourceLimitError,
13588 "MemoryAllocationFailed",PackageName);
13589 goto PerlException;
13590 }
13591 if (sv_isobject(ST(0)) == 0)
13592 {
13593 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13594 PackageName);
13595 goto PerlException;
13596 }
13597 reference=SvRV(ST(0));
13598 hv=SvSTASH(reference);
13599 if (SvTYPE(reference) != SVt_PVAV)
13600 {
13601 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13602 PackageName);
13603 goto PerlException;
13604 }
13605 av=(AV *) reference;
13606 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13607 exception);
13608 package_info=ClonePackageInfo(info,exception);
13609 n=1;
13610 if (items <= 1)
13611 *list=(char *) (*package_info->image_info->filename ?
13612 package_info->image_info->filename : "XC:black");
13613 else
13614 for (n=0, i=0; i < ac; i++)
13615 {
13616 list[n]=(char *) SvPV(ST(i+1),length[n]);
13617 if ((items >= 3) && strEQcase(list[n],"blob"))
13618 {
13619 void
13620 *blob;
13621
13622 i++;
13623 blob=(void *) (SvPV(ST(i+1),length[n]));
13624 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13625 }
13626 if ((items >= 3) && strEQcase(list[n],"filename"))
13627 continue;
13628 if ((items >= 3) && strEQcase(list[n],"file"))
13629 {
13630 FILE
13631 *file;
13632
13633 PerlIO
13634 *io_info;
13635
13636 i++;
13637 io_info=IoIFP(sv_2io(ST(i+1)));
13638 if (io_info == (PerlIO *) NULL)
13639 {
13640 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13641 PackageName);
13642 continue;
13643 }
13644 file=PerlIO_findFILE(io_info);
13645 if (file == (FILE *) NULL)
13646 {
13647 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13648 PackageName);
13649 continue;
13650 }
13651 SetImageInfoFile(package_info->image_info,file);
13652 }
13653 if ((items >= 3) && strEQcase(list[n],"magick"))
13654 continue;
13655 n++;
13656 }
13657 list[n]=(char *) NULL;
13658 keep=list;
13659 status=ExpandFilenames(&n,&list);
13660 if (status == MagickFalse)
13661 {
13662 ThrowPerlException(exception,ResourceLimitError,
13663 "MemoryAllocationFailed",PackageName);
13664 goto PerlException;
13665 }
13666 number_images=0;
13667 for (i=0; i < n; i++)
13668 {
13669 if ((package_info->image_info->file == (FILE *) NULL) &&
13670 (package_info->image_info->blob == (void *) NULL))
13671 image=ReadImages(package_info->image_info,list[i],exception);
13672 else
13673 {
13674 image=ReadImages(package_info->image_info,
13675 package_info->image_info->filename,exception);
13676 if (image != (Image *) NULL)
13677 DisassociateImageStream(image);
13678 }
13679 if (image == (Image *) NULL)
13680 break;
13681 for ( ; image; image=image->next)
13682 {
13683 AddImageToRegistry(sv,image);
13684 rv=newRV(sv);
13685 av_push(av,sv_bless(rv,hv));
13686 SvREFCNT_dec(sv);
13687 number_images++;
13688 }
13689 }
13690 /*
13691 Free resources.
13692 */
13693 for (i=0; i < n; i++)
13694 if (list[i] != (char *) NULL)
13695 for (p=keep; list[i] != *p++; )
13696 if (*p == (char *) NULL)
13697 {
13698 list[i]=(char *) RelinquishMagickMemory(list[i]);
13699 break;
13700 }
13701
13702 PerlException:
13703 if (package_info != (struct PackageInfo *) NULL)
13704 DestroyPackageInfo(package_info);
13705 if (list && (list != keep))
13706 list=(char **) RelinquishMagickMemory(list);
13707 if (keep)
13708 keep=(char **) RelinquishMagickMemory(keep);
13709 if (length)
13710 length=(STRLEN *) RelinquishMagickMemory(length);
13711 InheritPerlException(exception,perl_exception);
13712 exception=DestroyExceptionInfo(exception);
13713 sv_setiv(perl_exception,(IV) number_images);
13714 SvPOK_on(perl_exception);
13715 ST(0)=sv_2mortal(perl_exception);
13716 XSRETURN(1);
13717 }
13718
13719#
13720###############################################################################
13721# #
13722# #
13723# #
13724# R e m o t e #
13725# #
13726# #
13727# #
13728###############################################################################
13729#
13730#
13731void
13732Remote(ref,...)
13733 Image::Magick ref=NO_INIT
13734 ALIAS:
13735 RemoteCommand = 1
13736 remote = 2
13737 remoteCommand = 3
13738 PPCODE:
13739 {
13740 AV
13741 *av;
13742
13743 ExceptionInfo
13744 *exception;
13745
13746 register ssize_t
13747 i;
13748
13749 SV
13750 *perl_exception,
13751 *reference;
13752
13753 struct PackageInfo
13754 *info;
13755
13756 PERL_UNUSED_VAR(ref);
13757 PERL_UNUSED_VAR(ix);
13758 exception=AcquireExceptionInfo();
13759 perl_exception=newSVpv("",0);
13760 reference=SvRV(ST(0));
13761 av=(AV *) reference;
13762 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13763 exception);
13764 for (i=1; i < items; i++)
13765 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13766 SvPV(ST(i),na),exception);
13767 InheritPerlException(exception,perl_exception);
13768 exception=DestroyExceptionInfo(exception);
13769 SvREFCNT_dec(perl_exception); /* throw away all errors */
13770 }
13771
13772#
13773###############################################################################
13774# #
13775# #
13776# #
13777# S e t #
13778# #
13779# #
13780# #
13781###############################################################################
13782#
13783#
13784void
13785Set(ref,...)
13786 Image::Magick ref=NO_INIT
13787 ALIAS:
13788 SetAttributes = 1
13789 SetAttribute = 2
13790 set = 3
13791 setattributes = 4
13792 setattribute = 5
13793 PPCODE:
13794 {
13795 ExceptionInfo
13796 *exception;
13797
13798 Image
13799 *image;
13800
13801 register ssize_t
13802 i;
13803
13804 struct PackageInfo
13805 *info;
13806
13807 SV
13808 *perl_exception,
13809 *reference; /* reference is the SV* of ref=SvIV(reference) */
13810
13811 PERL_UNUSED_VAR(ref);
13812 PERL_UNUSED_VAR(ix);
13813 exception=AcquireExceptionInfo();
13814 perl_exception=newSVpv("",0);
13815 if (sv_isobject(ST(0)) == 0)
13816 {
13817 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13818 PackageName);
13819 goto PerlException;
13820 }
13821 reference=SvRV(ST(0));
13822 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13823 if (items == 2)
13824 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13825 else
13826 for (i=2; i < items; i+=2)
13827 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13828
13829 PerlException:
13830 InheritPerlException(exception,perl_exception);
13831 exception=DestroyExceptionInfo(exception);
13832 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13833 SvPOK_on(perl_exception);
13834 ST(0)=sv_2mortal(perl_exception);
13835 XSRETURN(1);
13836 }
13837
13838#
13839###############################################################################
13840# #
13841# #
13842# #
13843# S e t P i x e l #
13844# #
13845# #
13846# #
13847###############################################################################
13848#
13849#
13850void
13851SetPixel(ref,...)
13852 Image::Magick ref=NO_INIT
13853 ALIAS:
13854 setpixel = 1
13855 setPixel = 2
13856 PPCODE:
13857 {
13858 AV
13859 *av;
13860
13861 char
13862 *attribute;
13863
13864 ChannelType
13865 channel,
13866 channel_mask;
13867
13868 ExceptionInfo
13869 *exception;
13870
13871 Image
13872 *image;
13873
13874 MagickBooleanType
13875 normalize;
13876
13877 RectangleInfo
13878 region;
13879
13880 register ssize_t
13881 i;
13882
13883 register Quantum
13884 *q;
13885
13886 ssize_t
13887 option;
13888
13889 struct PackageInfo
13890 *info;
13891
13892 SV
13893 *perl_exception,
13894 *reference; /* reference is the SV* of ref=SvIV(reference) */
13895
13896 PERL_UNUSED_VAR(ref);
13897 PERL_UNUSED_VAR(ix);
13898 exception=AcquireExceptionInfo();
13899 perl_exception=newSVpv("",0);
13900 reference=SvRV(ST(0));
13901 av=(AV *) reference;
13902 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13903 exception);
13904 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13905 if (image == (Image *) NULL)
13906 {
13907 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13908 PackageName);
13909 goto PerlException;
13910 }
13911 av=(AV *) NULL;
13912 normalize=MagickTrue;
13913 region.x=0;
13914 region.y=0;
13915 region.width=image->columns;
13916 region.height=1;
13917 if (items == 1)
13918 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
13919 channel=DefaultChannels;
13920 for (i=2; i < items; i+=2)
13921 {
13922 attribute=(char *) SvPV(ST(i-1),na);
13923 switch (*attribute)
13924 {
13925 case 'C':
13926 case 'c':
13927 {
13928 if (LocaleCompare(attribute,"channel") == 0)
13929 {
13930 ssize_t
13931 option;
13932
13933 option=ParseChannelOption(SvPV(ST(i),na));
13934 if (option < 0)
13935 {
13936 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13937 SvPV(ST(i),na));
13938 return;
13939 }
13940 channel=(ChannelType) option;
13941 break;
13942 }
13943 if (LocaleCompare(attribute,"color") == 0)
13944 {
13945 if (SvTYPE(ST(i)) != SVt_RV)
13946 {
13947 char
cristy151b66d2015-04-15 10:50:31 +000013948 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013949
cristy151b66d2015-04-15 10:50:31 +000013950 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013951 "invalid %.60s value",attribute);
13952 ThrowPerlException(exception,OptionError,message,
13953 SvPV(ST(i),na));
13954 }
13955 av=(AV *) SvRV(ST(i));
13956 break;
13957 }
13958 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13959 attribute);
13960 break;
13961 }
13962 case 'g':
13963 case 'G':
13964 {
13965 if (LocaleCompare(attribute,"geometry") == 0)
13966 {
13967 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
13968 break;
13969 }
13970 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13971 attribute);
13972 break;
13973 }
13974 case 'N':
13975 case 'n':
13976 {
13977 if (LocaleCompare(attribute,"normalize") == 0)
13978 {
13979 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13980 SvPV(ST(i),na));
13981 if (option < 0)
13982 {
13983 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13984 SvPV(ST(i),na));
13985 break;
13986 }
13987 normalize=option != 0 ? MagickTrue : MagickFalse;
13988 break;
13989 }
13990 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13991 attribute);
13992 break;
13993 }
13994 case 'x':
13995 case 'X':
13996 {
13997 if (LocaleCompare(attribute,"x") == 0)
13998 {
13999 region.x=SvIV(ST(i));
14000 break;
14001 }
14002 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14003 attribute);
14004 break;
14005 }
14006 case 'y':
14007 case 'Y':
14008 {
14009 if (LocaleCompare(attribute,"y") == 0)
14010 {
14011 region.y=SvIV(ST(i));
14012 break;
14013 }
14014 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14015 attribute);
14016 break;
14017 }
14018 default:
14019 {
14020 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14021 attribute);
14022 break;
14023 }
14024 }
14025 }
14026 (void) SetImageStorageClass(image,DirectClass,exception);
14027 channel_mask=SetImageChannelMask(image,channel);
14028 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14029 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14030 (SvTYPE(av) != SVt_PVAV))
14031 PUSHs(&sv_undef);
14032 else
14033 {
14034 double
14035 scale;
14036
14037 register ssize_t
14038 i;
14039
14040 i=0;
14041 scale=1.0;
14042 if (normalize != MagickFalse)
14043 scale=QuantumRange;
14044 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14045 (i <= av_len(av)))
14046 {
14047 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14048 av_fetch(av,i,0)))),q);
14049 i++;
14050 }
14051 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14052 (i <= av_len(av)))
14053 {
14054 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14055 av_fetch(av,i,0)))),q);
14056 i++;
14057 }
14058 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14059 (i <= av_len(av)))
14060 {
14061 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14062 av_fetch(av,i,0)))),q);
14063 i++;
14064 }
14065 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14066 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14067 {
14068 SetPixelBlack(image,ClampToQuantum(scale*
14069 SvNV(*(av_fetch(av,i,0)))),q);
14070 i++;
14071 }
14072 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14073 (i <= av_len(av)))
14074 {
14075 SetPixelAlpha(image,ClampToQuantum(scale*
14076 SvNV(*(av_fetch(av,i,0)))),q);
14077 i++;
14078 }
14079 (void) SyncAuthenticPixels(image,exception);
14080 }
14081 (void) SetImageChannelMask(image,channel_mask);
14082
14083 PerlException:
14084 InheritPerlException(exception,perl_exception);
14085 exception=DestroyExceptionInfo(exception);
14086 SvREFCNT_dec(perl_exception);
14087 }
14088
14089#
14090###############################################################################
14091# #
14092# #
14093# #
14094# S m u s h #
14095# #
14096# #
14097# #
14098###############################################################################
14099#
14100#
14101void
14102Smush(ref,...)
14103 Image::Magick ref=NO_INIT
14104 ALIAS:
14105 SmushImage = 1
14106 smush = 2
14107 smushimage = 3
14108 PPCODE:
14109 {
14110 AV
14111 *av;
14112
14113 char
14114 *attribute;
14115
14116 ExceptionInfo
14117 *exception;
14118
14119 HV
14120 *hv;
14121
14122 Image
14123 *image;
14124
14125 register ssize_t
14126 i;
14127
14128 ssize_t
14129 offset,
14130 stack;
14131
14132 struct PackageInfo
14133 *info;
14134
14135 SV
14136 *av_reference,
14137 *perl_exception,
14138 *reference,
14139 *rv,
14140 *sv;
14141
14142 PERL_UNUSED_VAR(ref);
14143 PERL_UNUSED_VAR(ix);
14144 exception=AcquireExceptionInfo();
14145 perl_exception=newSVpv("",0);
14146 sv=NULL;
14147 attribute=NULL;
14148 av=NULL;
14149 if (sv_isobject(ST(0)) == 0)
14150 {
14151 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14152 PackageName);
14153 goto PerlException;
14154 }
14155 reference=SvRV(ST(0));
14156 hv=SvSTASH(reference);
14157 av=newAV();
14158 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14159 SvREFCNT_dec(av);
14160 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14161 if (image == (Image *) NULL)
14162 {
14163 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14164 PackageName);
14165 goto PerlException;
14166 }
14167 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14168 /*
14169 Get options.
14170 */
14171 offset=0;
14172 stack=MagickTrue;
14173 for (i=2; i < items; i+=2)
14174 {
14175 attribute=(char *) SvPV(ST(i-1),na);
14176 switch (*attribute)
14177 {
14178 case 'O':
14179 case 'o':
14180 {
14181 if (LocaleCompare(attribute,"offset") == 0)
14182 {
14183 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14184 break;
14185 }
14186 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14187 attribute);
14188 break;
14189 }
14190 case 'S':
14191 case 's':
14192 {
14193 if (LocaleCompare(attribute,"stack") == 0)
14194 {
14195 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14196 SvPV(ST(i),na));
14197 if (stack < 0)
14198 {
14199 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14200 SvPV(ST(i),na));
14201 return;
14202 }
14203 break;
14204 }
14205 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14206 attribute);
14207 break;
14208 }
14209 default:
14210 {
14211 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14212 attribute);
14213 break;
14214 }
14215 }
14216 }
14217 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14218 exception);
14219 if (image == (Image *) NULL)
14220 goto PerlException;
14221 for ( ; image; image=image->next)
14222 {
14223 AddImageToRegistry(sv,image);
14224 rv=newRV(sv);
14225 av_push(av,sv_bless(rv,hv));
14226 SvREFCNT_dec(sv);
14227 }
14228 exception=DestroyExceptionInfo(exception);
14229 ST(0)=av_reference;
14230 SvREFCNT_dec(perl_exception);
14231 XSRETURN(1);
14232
14233 PerlException:
14234 InheritPerlException(exception,perl_exception);
14235 exception=DestroyExceptionInfo(exception);
14236 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14237 SvPOK_on(perl_exception);
14238 ST(0)=sv_2mortal(perl_exception);
14239 XSRETURN(1);
14240 }
14241
14242#
14243###############################################################################
14244# #
14245# #
14246# #
14247# S t a t i s t i c s #
14248# #
14249# #
14250# #
14251###############################################################################
14252#
14253#
14254void
14255Statistics(ref,...)
14256 Image::Magick ref=NO_INIT
14257 ALIAS:
14258 StatisticsImage = 1
14259 statistics = 2
14260 statisticsimage = 3
14261 PPCODE:
14262 {
14263#define ChannelStatistics(channel) \
14264{ \
cristy151b66d2015-04-15 10:50:31 +000014265 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014266 (double) channel_statistics[channel].depth); \
14267 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014268 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014269 channel_statistics[channel].minima/scale); \
14270 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014271 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014272 channel_statistics[channel].maxima/scale); \
14273 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014274 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014275 channel_statistics[channel].mean/scale); \
14276 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014277 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014278 channel_statistics[channel].standard_deviation/scale); \
14279 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014280 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014281 channel_statistics[channel].kurtosis); \
14282 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014283 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014284 channel_statistics[channel].skewness); \
14285 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014286 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy275bdd92014-11-08 23:45:03 +000014287 channel_statistics[channel].entropy); \
14288 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014289}
14290
14291 AV
14292 *av;
14293
14294 char
cristy151b66d2015-04-15 10:50:31 +000014295 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014296
14297 ChannelStatistics
14298 *channel_statistics;
14299
14300 double
14301 scale;
14302
14303 ExceptionInfo
14304 *exception;
14305
14306 Image
14307 *image;
14308
14309 ssize_t
14310 count;
14311
14312 struct PackageInfo
14313 *info;
14314
14315 SV
14316 *perl_exception,
14317 *reference;
14318
14319 PERL_UNUSED_VAR(ref);
14320 PERL_UNUSED_VAR(ix);
14321 exception=AcquireExceptionInfo();
14322 perl_exception=newSVpv("",0);
14323 av=NULL;
14324 if (sv_isobject(ST(0)) == 0)
14325 {
14326 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14327 PackageName);
14328 goto PerlException;
14329 }
14330 reference=SvRV(ST(0));
14331 av=newAV();
14332 SvREFCNT_dec(av);
14333 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14334 if (image == (Image *) NULL)
14335 {
14336 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14337 PackageName);
14338 goto PerlException;
14339 }
cristy4a3ce0a2013-08-03 20:06:59 +000014340 count=0;
14341 for ( ; image; image=image->next)
14342 {
14343 channel_statistics=GetImageStatistics(image,exception);
14344 if (channel_statistics == (ChannelStatistics *) NULL)
14345 continue;
14346 count++;
14347 EXTEND(sp,35*count);
14348 scale=(double) QuantumRange;
14349 ChannelStatistics(RedChannel);
14350 ChannelStatistics(GreenChannel);
14351 ChannelStatistics(BlueChannel);
14352 if (image->colorspace == CMYKColorspace)
14353 ChannelStatistics(BlackChannel);
cristy17f11b02014-12-20 19:37:04 +000014354 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000014355 ChannelStatistics(AlphaChannel);
14356 channel_statistics=(ChannelStatistics *)
14357 RelinquishMagickMemory(channel_statistics);
14358 }
14359
14360 PerlException:
14361 InheritPerlException(exception,perl_exception);
14362 exception=DestroyExceptionInfo(exception);
14363 SvREFCNT_dec(perl_exception);
14364 }
14365
14366#
14367###############################################################################
14368# #
14369# #
14370# #
14371# S y n c A u t h e n t i c P i x e l s #
14372# #
14373# #
14374# #
14375###############################################################################
14376#
14377#
14378void
14379SyncAuthenticPixels(ref,...)
14380 Image::Magick ref = NO_INIT
14381 ALIAS:
14382 Syncauthenticpixels = 1
14383 SyncImagePixels = 2
14384 syncimagepixels = 3
14385 CODE:
14386 {
14387 ExceptionInfo
14388 *exception;
14389
14390 Image
14391 *image;
14392
14393 MagickBooleanType
14394 status;
14395
14396 struct PackageInfo
14397 *info;
14398
14399 SV
14400 *perl_exception,
14401 *reference;
14402
14403 PERL_UNUSED_VAR(ref);
14404 PERL_UNUSED_VAR(ix);
14405 exception=AcquireExceptionInfo();
14406 perl_exception=newSVpv("",0);
14407 if (sv_isobject(ST(0)) == 0)
14408 {
14409 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14410 PackageName);
14411 goto PerlException;
14412 }
14413
14414 reference=SvRV(ST(0));
14415 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14416 if (image == (Image *) NULL)
14417 {
14418 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14419 PackageName);
14420 goto PerlException;
14421 }
14422
14423 status=SyncAuthenticPixels(image,exception);
14424 if (status != MagickFalse)
14425 return;
14426
14427 PerlException:
14428 InheritPerlException(exception,perl_exception);
14429 exception=DestroyExceptionInfo(exception);
14430 SvREFCNT_dec(perl_exception); /* throw away all errors */
14431 }
14432
14433#
14434###############################################################################
14435# #
14436# #
14437# #
14438# T r a n s f o r m #
14439# #
14440# #
14441# #
14442###############################################################################
14443#
14444#
14445void
14446Transform(ref,...)
14447 Image::Magick ref=NO_INIT
14448 ALIAS:
14449 TransformImage = 1
14450 transform = 2
14451 transformimage = 3
14452 PPCODE:
14453 {
14454 AV
14455 *av;
14456
14457 char
14458 *attribute,
14459 *crop_geometry,
14460 *geometry;
14461
14462 ExceptionInfo
14463 *exception;
14464
14465 HV
14466 *hv;
14467
14468 Image
14469 *clone,
14470 *image;
14471
14472 register ssize_t
14473 i;
14474
14475 struct PackageInfo
14476 *info;
14477
14478 SV
14479 *av_reference,
14480 *perl_exception,
14481 *reference,
14482 *rv,
14483 *sv;
14484
14485 PERL_UNUSED_VAR(ref);
14486 PERL_UNUSED_VAR(ix);
14487 exception=AcquireExceptionInfo();
14488 perl_exception=newSVpv("",0);
14489 sv=NULL;
14490 av=NULL;
14491 attribute=NULL;
14492 if (sv_isobject(ST(0)) == 0)
14493 {
14494 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14495 PackageName);
14496 goto PerlException;
14497 }
14498 reference=SvRV(ST(0));
14499 hv=SvSTASH(reference);
14500 av=newAV();
14501 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14502 SvREFCNT_dec(av);
14503 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14504 if (image == (Image *) NULL)
14505 {
14506 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14507 PackageName);
14508 goto PerlException;
14509 }
14510 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14511 /*
14512 Get attribute.
14513 */
14514 crop_geometry=(char *) NULL;
14515 geometry=(char *) NULL;
14516 for (i=2; i < items; i+=2)
14517 {
14518 attribute=(char *) SvPV(ST(i-1),na);
14519 switch (*attribute)
14520 {
14521 case 'c':
14522 case 'C':
14523 {
14524 if (LocaleCompare(attribute,"crop") == 0)
14525 {
14526 crop_geometry=SvPV(ST(i),na);
14527 break;
14528 }
14529 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14530 attribute);
14531 break;
14532 }
14533 case 'g':
14534 case 'G':
14535 {
14536 if (LocaleCompare(attribute,"geometry") == 0)
14537 {
14538 geometry=SvPV(ST(i),na);
14539 break;
14540 }
14541 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14542 attribute);
14543 break;
14544 }
14545 default:
14546 {
14547 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14548 attribute);
14549 break;
14550 }
14551 }
14552 }
14553 for ( ; image; image=image->next)
14554 {
14555 clone=CloneImage(image,0,0,MagickTrue,exception);
14556 if (clone == (Image *) NULL)
14557 goto PerlException;
14558 TransformImage(&clone,crop_geometry,geometry,exception);
14559 for ( ; clone; clone=clone->next)
14560 {
14561 AddImageToRegistry(sv,clone);
14562 rv=newRV(sv);
14563 av_push(av,sv_bless(rv,hv));
14564 SvREFCNT_dec(sv);
14565 }
14566 }
14567 exception=DestroyExceptionInfo(exception);
14568 ST(0)=av_reference;
14569 SvREFCNT_dec(perl_exception); /* can't return warning messages */
14570 XSRETURN(1);
14571
14572 PerlException:
14573 InheritPerlException(exception,perl_exception);
14574 exception=DestroyExceptionInfo(exception);
14575 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14576 SvPOK_on(perl_exception);
14577 ST(0)=sv_2mortal(perl_exception);
14578 XSRETURN(1);
14579 }
14580
14581#
14582###############################################################################
14583# #
14584# #
14585# #
14586# W r i t e #
14587# #
14588# #
14589# #
14590###############################################################################
14591#
14592#
14593void
14594Write(ref,...)
14595 Image::Magick ref=NO_INIT
14596 ALIAS:
14597 WriteImage = 1
14598 write = 2
14599 writeimage = 3
14600 PPCODE:
14601 {
14602 char
cristy151b66d2015-04-15 10:50:31 +000014603 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014604
14605 ExceptionInfo
14606 *exception;
14607
14608 Image
14609 *image,
14610 *next;
14611
14612 register ssize_t
14613 i;
14614
14615 ssize_t
14616 number_images,
14617 scene;
14618
14619 struct PackageInfo
14620 *info,
14621 *package_info;
14622
14623 SV
14624 *perl_exception,
14625 *reference;
14626
14627 PERL_UNUSED_VAR(ref);
14628 PERL_UNUSED_VAR(ix);
14629 exception=AcquireExceptionInfo();
14630 perl_exception=newSVpv("",0);
14631 number_images=0;
14632 package_info=(struct PackageInfo *) NULL;
14633 if (sv_isobject(ST(0)) == 0)
14634 {
14635 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14636 PackageName);
14637 goto PerlException;
14638 }
14639 reference=SvRV(ST(0));
14640 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14641 if (image == (Image *) NULL)
14642 {
14643 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14644 PackageName);
14645 goto PerlException;
14646 }
14647 package_info=ClonePackageInfo(info,exception);
14648 if (items == 2)
14649 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14650 else
14651 if (items > 2)
14652 for (i=2; i < items; i+=2)
14653 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14654 exception);
14655 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014656 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014657 scene=0;
14658 for (next=image; next; next=next->next)
14659 {
cristy151b66d2015-04-15 10:50:31 +000014660 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014661 next->scene=scene++;
14662 }
cristy68bd79a2015-02-25 12:23:36 +000014663 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014664 SetImageInfo(package_info->image_info,(unsigned int)
14665 GetImageListLength(image),exception);
14666 for (next=image; next; next=next->next)
14667 {
14668 (void) WriteImage(package_info->image_info,next,exception);
14669 number_images++;
14670 if (package_info->image_info->adjoin)
14671 break;
14672 }
14673
14674 PerlException:
14675 if (package_info != (struct PackageInfo *) NULL)
14676 DestroyPackageInfo(package_info);
14677 InheritPerlException(exception,perl_exception);
14678 exception=DestroyExceptionInfo(exception);
14679 sv_setiv(perl_exception,(IV) number_images);
14680 SvPOK_on(perl_exception);
14681 ST(0)=sv_2mortal(perl_exception);
14682 XSRETURN(1);
14683 }