blob: 0b56ee619be9471ca51cd4b13c087c24dcbf55dc [file] [log] [blame]
cristy4a3ce0a2013-08-03 20:06:59 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% PPPP EEEEE RRRR L %
6% P P E R R L %
7% PPPP EEE RRRR L %
8% P E R R L %
9% P EEEEE R R LLLLL %
10% %
11% M M AAA GGGG IIIII CCCC K K %
12% MM MM A A G I C K K %
13% M M M AAAAA G GGG I C KKK %
14% M M A A G G I C K K %
15% M M A A GGGG IIIII CCCC K K %
16% %
17% %
18% Object-oriented Perl interface to ImageMagick %
19% %
20% Software Design %
21% Kyle Shorter %
cristyde984cd2013-12-01 14:49:27 +000022% Cristy %
cristy4a3ce0a2013-08-03 20:06:59 +000023% February 1997 %
24% %
25% %
Cristy7ce65e72015-12-12 18:03:16 -050026% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization %
cristy4a3ce0a2013-08-03 20:06:59 +000027% dedicated to making software imaging solutions freely available. %
28% %
29% You may not use this file except in compliance with the License. You may %
30% obtain a copy of the License at %
31% %
32% http://www.imagemagick.org/script/license.php %
33% %
34% Unless required by applicable law or agreed to in writing, software %
35% distributed under the License is distributed on an "AS IS" BASIS, %
36% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
37% See the License for the specific language governing permissions and %
38% limitations under the License. %
39% %
40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41%
42% PerlMagick is an objected-oriented Perl interface to ImageMagick. Use
43% the module to read, manipulate, or write an image or image sequence from
44% within a Perl script. This makes PerlMagick suitable for Web CGI scripts.
45%
46*/
47
48/*
49 Include declarations.
50*/
51#if defined(__cplusplus) || defined(c_plusplus)
52extern "C" {
53#endif
54
55#define PERL_NO_GET_CONTEXT
dirk190cc1c2015-06-16 11:48:37 +000056#include <MagickCore/MagickCore.h>
cristy4a3ce0a2013-08-03 20:06:59 +000057#include "EXTERN.h"
58#include "perl.h"
59#include "XSUB.h"
60#include <math.h>
cristy4a3ce0a2013-08-03 20:06:59 +000061#undef tainted
62
63#if defined(__cplusplus) || defined(c_plusplus)
64}
65#endif
66
67/*
68 Define declarations.
69*/
70#ifndef aTHX_
71#define aTHX_
72#define pTHX_
73#define dTHX
74#endif
75#define DegreesToRadians(x) (MagickPI*(x)/180.0)
76#define EndOf(array) (&array[NumberOf(array)])
cristy3249b7b2014-02-09 21:43:14 +000077#define MagickPI 3.14159265358979323846264338327950288419716939937510
cristy4a3ce0a2013-08-03 20:06:59 +000078#define MaxArguments 33
79#ifndef na
80#define na PL_na
81#endif
82#define NumberOf(array) (sizeof(array)/sizeof(*array))
83#define PackageName "Image::Magick"
84#if PERL_VERSION <= 6
85#define PerlIO FILE
86#define PerlIO_importFILE(f, fl) (f)
87#define PerlIO_findFILE(f) NULL
88#endif
89#ifndef sv_undef
90#define sv_undef PL_sv_undef
91#endif
92
93#define AddImageToRegistry(sv,image) \
94{ \
95 if (magick_registry != (SplayTreeInfo *) NULL) \
96 { \
97 (void) AddValueToSplayTree(magick_registry,image,image); \
98 (sv)=newSViv(PTR2IV(image)); \
99 } \
100}
101
102#define DeleteImageFromRegistry(reference,image) \
103{ \
104 if (magick_registry != (SplayTreeInfo *) NULL) \
105 { \
106 if (GetImageReferenceCount(image) == 1) \
107 (void) DeleteNodeByValueFromSplayTree(magick_registry,image); \
108 image=DestroyImage(image); \
109 sv_setiv(reference,0); \
110 } \
111}
112
113#define InheritPerlException(exception,perl_exception) \
114{ \
115 char \
cristy151b66d2015-04-15 10:50:31 +0000116 message[MagickPathExtent]; \
cristy4a3ce0a2013-08-03 20:06:59 +0000117 \
118 if ((exception)->severity != UndefinedException) \
119 { \
cristy151b66d2015-04-15 10:50:31 +0000120 (void) FormatLocaleString(message,MagickPathExtent,"Exception %d: %s%s%s%s",\
cristy4a3ce0a2013-08-03 20:06:59 +0000121 (exception)->severity, (exception)->reason ? \
122 GetLocaleExceptionMessage((exception)->severity,(exception)->reason) : \
123 "Unknown", (exception)->description ? " (" : "", \
124 (exception)->description ? GetLocaleExceptionMessage( \
125 (exception)->severity,(exception)->description) : "", \
126 (exception)->description ? ")" : ""); \
127 if ((perl_exception) != (SV *) NULL) \
128 { \
129 if (SvCUR(perl_exception)) \
130 sv_catpv(perl_exception,"\n"); \
131 sv_catpv(perl_exception,message); \
132 } \
133 } \
134}
135
136#define ThrowPerlException(exception,severity,tag,reason) \
137 (void) ThrowMagickException(exception,GetMagickModule(),severity, \
138 tag,"`%s'",reason); \
139
140/*
141 Typedef and structure declarations.
142*/
143typedef enum
144{
145 ArrayReference = (~0),
146 RealReference = (~0)-1,
147 FileReference = (~0)-2,
148 ImageReference = (~0)-3,
149 IntegerReference = (~0)-4,
150 StringReference = (~0)-5
151} MagickReference;
152
153typedef struct _Arguments
154{
155 const char
156 *method;
157
158 ssize_t
159 type;
160} Arguments;
161
162struct ArgumentList
163{
164 ssize_t
165 integer_reference;
166
167 double
168 real_reference;
169
170 const char
171 *string_reference;
172
173 Image
174 *image_reference;
175
176 SV
177 *array_reference;
178
179 FILE
180 *file_reference;
181
182 size_t
183 length;
184};
185
186struct PackageInfo
187{
188 ImageInfo
189 *image_info;
190};
191
192typedef void
193 *Image__Magick; /* data type for the Image::Magick package */
194
195/*
196 Static declarations.
197*/
198static struct
199 Methods
200 {
201 const char
202 *name;
203
204 Arguments
205 arguments[MaxArguments];
206 } Methods[] =
207 {
208 { "Comment", { {"comment", StringReference} } },
209 { "Label", { {"label", StringReference} } },
210 { "AddNoise", { {"noise", MagickNoiseOptions}, {"attenuate", RealReference},
211 {"channel", MagickChannelOptions} } },
212 { "Colorize", { {"fill", StringReference}, {"blend", StringReference} } },
213 { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
214 {"height", IntegerReference}, {"fill", StringReference},
215 {"bordercolor", StringReference}, {"color", StringReference},
216 {"compose", MagickComposeOptions} } },
217 { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
218 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
219 { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
220 {"height", IntegerReference}, {"x", IntegerReference},
cristy260bd762014-08-15 12:46:34 +0000221 {"y", IntegerReference}, {"gravity", MagickGravityOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000222 { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
223 {"height", IntegerReference}, {"x", IntegerReference},
224 {"y", IntegerReference}, {"fuzz", StringReference},
225 {"gravity", MagickGravityOptions} } },
226 { "Despeckle", },
227 { "Edge", { {"radius", RealReference} } },
228 { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
229 {"sigma", RealReference} } },
230 { "Enhance", },
231 { "Flip", },
232 { "Flop", },
233 { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
234 {"height", IntegerReference}, {"inner", IntegerReference},
235 {"outer", IntegerReference}, {"fill", StringReference},
236 {"color", StringReference}, {"compose", MagickComposeOptions} } },
237 { "Implode", { {"amount", RealReference},
238 {"interpolate", MagickInterpolateOptions} } },
239 { "Magnify", },
240 { "MedianFilter", { {"geometry", StringReference},
241 {"width", IntegerReference}, {"height", IntegerReference},
242 {"channel", MagickChannelOptions} } },
243 { "Minify", },
244 { "OilPaint", { {"radius", RealReference}, {"sigma", RealReference} } },
245 { "ReduceNoise", { {"geometry", StringReference},
246 {"width", IntegerReference},{"height", IntegerReference},
247 {"channel", MagickChannelOptions} } },
248 { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
249 {"y", IntegerReference} } },
cristy83a28a02013-08-03 20:25:48 +0000250 { "Rotate", { {"degrees", RealReference},
cristy4a3ce0a2013-08-03 20:06:59 +0000251 {"background", StringReference} } },
252 { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
253 {"height", IntegerReference} } },
254 { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
255 {"height", IntegerReference} } },
256 { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
257 {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
258 { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
259 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
260 { "Shear", { {"geometry", StringReference}, {"x", RealReference},
261 {"y", RealReference}, { "fill", StringReference},
262 {"color", StringReference} } },
Cristye3319c12015-08-24 07:11:48 -0400263 { "Spread", { {"radius", RealReference},
Cristy3ca633e2016-02-13 12:49:01 -0500264 {"interpolate", MagickInterpolateOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000265 { "Swirl", { {"degrees", RealReference},
266 {"interpolate", MagickInterpolateOptions} } },
267 { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
268 {"height", IntegerReference}, {"filter", MagickFilterOptions},
269 {"support", StringReference } } },
270 { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
271 {"height", IntegerReference}, {"filter", MagickFilterOptions},
272 {"support", RealReference } } },
273 { "Annotate", { {"text", StringReference}, {"font", StringReference},
274 {"pointsize", RealReference}, {"density", StringReference},
275 {"undercolor", StringReference}, {"stroke", StringReference},
276 {"fill", StringReference}, {"geometry", StringReference},
277 {"sans", StringReference}, {"x", RealReference},
278 {"y", RealReference}, {"gravity", MagickGravityOptions},
279 {"translate", StringReference}, {"scale", StringReference},
280 {"rotate", RealReference}, {"skewX", RealReference},
281 {"skewY", RealReference}, {"strokewidth", RealReference},
282 {"antialias", MagickBooleanOptions}, {"family", StringReference},
283 {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
284 {"weight", IntegerReference}, {"align", MagickAlignOptions},
285 {"encoding", StringReference}, {"affine", ArrayReference},
286 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
287 {"tile", ImageReference}, {"kerning", RealReference},
288 {"interline-spacing", RealReference},
289 {"interword-spacing", RealReference},
290 {"direction", MagickDirectionOptions} } },
291 { "ColorFloodfill", { {"geometry", StringReference},
292 {"x", IntegerReference}, {"y", IntegerReference},
293 {"fill", StringReference}, {"bordercolor", StringReference},
294 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
295 { "Composite", { {"image", ImageReference},
296 {"compose", MagickComposeOptions}, {"geometry", StringReference},
297 {"x", IntegerReference}, {"y", IntegerReference},
298 {"gravity", MagickGravityOptions}, {"opacity", StringReference},
299 {"tile", MagickBooleanOptions}, {"rotate", RealReference},
300 {"color", StringReference}, {"mask", ImageReference},
301 {"channel", MagickChannelOptions},
302 {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
303 {"blend", StringReference}, {"crop-to-self", MagickBooleanOptions} } },
304 { "Contrast", { {"sharpen", MagickBooleanOptions} } },
305 { "CycleColormap", { {"display", IntegerReference} } },
306 { "Draw", { {"primitive", MagickPrimitiveOptions},
307 {"points", StringReference}, {"method", MagickMethodOptions},
308 {"stroke", StringReference}, {"fill", StringReference},
309 {"strokewidth", RealReference}, {"font", StringReference},
310 {"bordercolor", StringReference}, {"x", RealReference},
311 {"y", RealReference}, {"translate", StringReference},
312 {"scale", StringReference}, {"rotate", RealReference},
313 {"skewX", RealReference}, {"skewY", RealReference},
314 {"tile", ImageReference}, {"pointsize", RealReference},
315 {"antialias", MagickBooleanOptions}, {"density", StringReference},
316 {"linewidth", RealReference}, {"affine", ArrayReference},
317 {"stroke-dashoffset", RealReference},
318 {"stroke-dasharray", ArrayReference},
319 {"interpolate", MagickInterpolateOptions},
320 {"origin", StringReference}, {"text", StringReference},
321 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
322 {"vector-graphics", StringReference}, {"kerning", RealReference},
323 {"interline-spacing", RealReference},
324 {"interword-spacing", RealReference},
325 {"direction", MagickDirectionOptions} } },
326 { "Equalize", { {"channel", MagickChannelOptions} } },
327 { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
328 {"red", RealReference}, {"green", RealReference},
329 {"blue", RealReference} } },
330 { "Map", { {"image", ImageReference},
331 {"dither-method", MagickDitherOptions} } },
332 { "MatteFloodfill", { {"geometry", StringReference},
333 {"x", IntegerReference}, {"y", IntegerReference},
334 {"opacity", StringReference}, {"bordercolor", StringReference},
335 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
336 { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
337 {"saturation", RealReference}, {"whiteness", RealReference},
338 {"brightness", RealReference}, {"lightness", RealReference},
339 {"blackness", RealReference} } },
340 { "Negate", { {"gray", MagickBooleanOptions},
341 {"channel", MagickChannelOptions} } },
342 { "Normalize", { {"channel", MagickChannelOptions} } },
343 { "NumberColors", },
344 { "Opaque", { {"color", StringReference}, {"fill", StringReference},
345 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
346 {"invert", MagickBooleanOptions} } },
347 { "Quantize", { {"colors", IntegerReference},
348 {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
349 {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
350 {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
351 {"dither-method", MagickDitherOptions} } },
352 { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
353 {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
354 { "Segment", { {"geometry", StringReference},
355 {"cluster-threshold", RealReference},
356 {"smoothing-threshold", RealReference},
357 {"colorspace", MagickColorspaceOptions},
358 {"verbose", MagickBooleanOptions} } },
359 { "Signature", },
360 { "Solarize", { {"geometry", StringReference},
361 {"threshold", StringReference} } },
362 { "Sync", },
363 { "Texture", { {"texture", ImageReference} } },
364 { "Evaluate", { {"value", RealReference},
365 {"operator", MagickEvaluateOptions},
366 {"channel", MagickChannelOptions} } },
367 { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
368 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
369 { "Threshold", { {"threshold", StringReference},
370 {"channel", MagickChannelOptions} } },
371 { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
372 {"sigma", RealReference} } },
373 { "Trim", { {"fuzz", StringReference} } },
374 { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
375 {"wavelength", RealReference},
376 {"interpolate", MagickInterpolateOptions} } },
377 { "Separate", { {"channel", MagickChannelOptions} } },
378 { "Condense", },
379 { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
380 {"y", IntegerReference} } },
381 { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
382 { "Deconstruct", },
383 { "GaussianBlur", { {"geometry", StringReference},
384 {"radius", RealReference}, {"sigma", RealReference},
385 {"channel", MagickChannelOptions} } },
386 { "Convolve", { {"coefficients", ArrayReference},
387 {"channel", MagickChannelOptions}, {"bias", StringReference},
388 {"kernel", StringReference} } },
389 { "Profile", { {"name", StringReference}, {"profile", StringReference},
390 { "rendering-intent", MagickIntentOptions},
391 { "black-point-compensation", MagickBooleanOptions} } },
392 { "UnsharpMask", { {"geometry", StringReference},
393 {"radius", RealReference}, {"sigma", RealReference},
394 {"gain", RealReference}, {"threshold", RealReference},
395 {"channel", MagickChannelOptions} } },
396 { "MotionBlur", { {"geometry", StringReference},
397 {"radius", RealReference}, {"sigma", RealReference},
398 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
399 { "OrderedDither", { {"threshold", StringReference},
400 {"channel", MagickChannelOptions} } },
401 { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
402 {"height", IntegerReference} } },
403 { "Level", { {"levels", StringReference}, {"black-point", RealReference},
404 {"white-point", RealReference}, {"gamma", RealReference},
405 {"channel", MagickChannelOptions}, {"level", StringReference} } },
406 { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
407 { "AffineTransform", { {"affine", ArrayReference},
408 {"translate", StringReference}, {"scale", StringReference},
409 {"rotate", RealReference}, {"skewX", RealReference},
410 {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
411 {"background", StringReference} } },
412 { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
413 { "AdaptiveThreshold", { {"geometry", StringReference},
414 {"width", IntegerReference}, {"height", IntegerReference} } },
415 { "Resample", { {"density", StringReference}, {"x", RealReference},
416 {"y", RealReference}, {"filter", MagickFilterOptions},
417 {"support", RealReference } } },
418 { "Describe", { {"file", FileReference} } },
419 { "BlackThreshold", { {"threshold", StringReference},
420 {"channel", MagickChannelOptions} } },
421 { "WhiteThreshold", { {"threshold", StringReference},
422 {"channel", MagickChannelOptions} } },
cristy60c73c02014-03-25 12:09:58 +0000423 { "RotationalBlur", { {"geometry", StringReference},
424 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000425 { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
426 {"height", IntegerReference} } },
427 { "Strip", },
428 { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
429 { "Channel", { {"channel", MagickChannelOptions} } },
430 { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
431 {"height", IntegerReference}, {"x", IntegerReference},
432 {"y", IntegerReference}, {"fuzz", StringReference},
433 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
434 { "Posterize", { {"levels", IntegerReference},
435 {"dither", MagickBooleanOptions} } },
436 { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
437 {"sigma", RealReference}, {"x", IntegerReference},
438 {"y", IntegerReference} } },
439 { "Identify", { {"file", FileReference}, {"features", StringReference},
440 {"unique", MagickBooleanOptions} } },
441 { "SepiaTone", { {"threshold", RealReference} } },
442 { "SigmoidalContrast", { {"geometry", StringReference},
443 {"contrast", RealReference}, {"mid-point", RealReference},
444 {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
445 { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
446 {"height", IntegerReference}, {"x", IntegerReference},
447 {"y", IntegerReference}, {"fuzz", StringReference},
448 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
449 { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
450 {"sigma", RealReference}, {"x", IntegerReference},
451 {"y", IntegerReference}, {"background", StringReference} } },
452 { "ContrastStretch", { {"levels", StringReference},
453 {"black-point", RealReference},{"white-point", RealReference},
454 {"channel", MagickChannelOptions} } },
455 { "Sans0", },
456 { "Sans1", },
457 { "AdaptiveSharpen", { {"geometry", StringReference},
458 {"radius", RealReference}, {"sigma", RealReference},
459 {"bias", RealReference}, {"channel", MagickChannelOptions} } },
460 { "Transpose", },
461 { "Transverse", },
462 { "AutoOrient", },
463 { "AdaptiveBlur", { {"geometry", StringReference},
464 {"radius", RealReference}, {"sigma", RealReference},
465 {"channel", MagickChannelOptions} } },
466 { "Sketch", { {"geometry", StringReference},
467 {"radius", RealReference}, {"sigma", RealReference},
468 {"angle", RealReference} } },
469 { "UniqueColors", },
470 { "AdaptiveResize", { {"geometry", StringReference},
471 {"width", IntegerReference}, {"height", IntegerReference},
472 {"filter", MagickFilterOptions}, {"support", StringReference },
473 {"blur", RealReference } } },
474 { "ClipMask", { {"mask", ImageReference} } },
475 { "LinearStretch", { {"levels", StringReference},
476 {"black-point", RealReference},{"white-point", RealReference} } },
477 { "ColorMatrix", { {"matrix", ArrayReference} } },
478 { "Mask", { {"mask", ImageReference} } },
479 { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
480 {"font", StringReference}, {"stroke", StringReference},
481 {"fill", StringReference}, {"strokewidth", RealReference},
482 {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
483 {"background", StringReference},
484 {"interpolate", MagickInterpolateOptions} } },
485 { "FloodfillPaint", { {"geometry", StringReference},
486 {"x", IntegerReference}, {"y", IntegerReference},
487 {"fill", StringReference}, {"bordercolor", StringReference},
488 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
489 {"invert", MagickBooleanOptions} } },
490 { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
491 {"virtual-pixel", MagickVirtualPixelOptions},
492 {"best-fit", MagickBooleanOptions} } },
493 { "Clut", { {"image", ImageReference},
494 {"interpolate", MagickInterpolateOptions},
495 {"channel", MagickChannelOptions} } },
496 { "LiquidRescale", { {"geometry", StringReference},
497 {"width", IntegerReference}, {"height", IntegerReference},
498 {"delta-x", RealReference}, {"rigidity", RealReference } } },
499 { "Encipher", { {"passphrase", StringReference} } },
500 { "Decipher", { {"passphrase", StringReference} } },
501 { "Deskew", { {"geometry", StringReference},
502 {"threshold", StringReference} } },
503 { "Remap", { {"image", ImageReference},
504 {"dither-method", MagickDitherOptions} } },
505 { "SparseColor", { {"points", ArrayReference},
506 {"method", MagickSparseColorOptions},
507 {"virtual-pixel", MagickVirtualPixelOptions},
508 {"channel", MagickChannelOptions} } },
509 { "Function", { {"parameters", ArrayReference},
510 {"function", MagickFunctionOptions},
511 {"virtual-pixel", MagickVirtualPixelOptions} } },
512 { "SelectiveBlur", { {"geometry", StringReference},
513 {"radius", RealReference}, {"sigma", RealReference},
514 {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
515 { "HaldClut", { {"image", ImageReference},
516 {"channel", MagickChannelOptions} } },
517 { "BlueShift", { {"factor", StringReference} } },
518 { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
519 { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
520 { "ColorDecisionList", {
521 {"color-correction-collection", StringReference} } },
522 { "AutoGamma", { {"channel", MagickChannelOptions} } },
523 { "AutoLevel", { {"channel", MagickChannelOptions} } },
524 { "LevelColors", { {"invert", MagickBooleanOptions},
525 {"black-point", StringReference}, {"white-point", StringReference},
526 {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
527 { "Clamp", { {"channel", MagickChannelOptions} } },
528 { "BrightnessContrast", { {"levels", StringReference},
529 {"brightness", RealReference},{"contrast", RealReference},
530 {"channel", MagickChannelOptions} } },
531 { "Morphology", { {"kernel", StringReference},
532 {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
533 {"iterations", IntegerReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000534 { "Mode", { {"geometry", StringReference},
535 {"width", IntegerReference},{"height", IntegerReference},
536 {"channel", MagickChannelOptions} } },
537 { "Statistic", { {"geometry", StringReference},
538 {"width", IntegerReference},{"height", IntegerReference},
539 {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
540 { "Perceptible", { {"epsilon", RealReference},
541 {"channel", MagickChannelOptions} } },
542 { "Poly", { {"terms", ArrayReference},
543 {"channel", MagickChannelOptions} } },
544 { "Grayscale", { {"method", MagickNoiseOptions} } },
cristy4ceadb82014-03-29 15:30:43 +0000545 { "CannyEdge", { {"geometry", StringReference},
546 {"radius", RealReference}, {"sigma", RealReference},
cristycfe7bf02014-04-04 15:31:52 +0000547 {"lower-percent", RealReference}, {"upper-percent", RealReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000548 { "HoughLine", { {"geometry", StringReference},
cristy4e215022014-04-19 18:02:35 +0000549 {"width", IntegerReference}, {"height", IntegerReference},
550 {"threshold", IntegerReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000551 { "MeanShift", { {"geometry", StringReference},
552 {"width", IntegerReference}, {"height", IntegerReference},
cristy1309fc32014-04-26 18:48:37 +0000553 {"distance", RealReference} } },
cristy3b207f82014-09-27 14:21:20 +0000554 { "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
555 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
Cristy2ca0e9a2016-01-01 08:36:14 -0500556 { "ConnectedComponents", { {"connectivity", IntegerReference} } },
cristyf3a724a2015-06-25 13:02:53 +0000557 { "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
558 {"width", IntegerReference}, {"height", IntegerReference},
559 {"x", IntegerReference}, {"y", IntegerReference},
560 {"gravity", MagickGravityOptions}, {"offset", StringReference},
561 {"dx", IntegerReference}, {"dy", IntegerReference} } },
Cristy5488c982016-02-13 14:07:50 -0500562 { "Color", { {"color", StringReference} } },
Cristyc1759412016-02-27 12:17:58 -0500563 { "WaveletDenoise", { {"geometry", StringReference},
564 {"threshold", RealReference}, {"softness", RealReference},
Cristy2d830ed2016-02-21 10:54:16 -0500565 {"channel", MagickChannelOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000566 };
567
568static SplayTreeInfo
569 *magick_registry = (SplayTreeInfo *) NULL;
570
571/*
572 Forward declarations.
573*/
574static Image
575 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
576
577static ssize_t
578 strEQcase(const char *,const char *);
579
580/*
581%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582% %
583% %
584% %
585% C l o n e P a c k a g e I n f o %
586% %
587% %
588% %
589%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
590%
591% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
592% a new one.
593%
594% The format of the ClonePackageInfo routine is:
595%
596% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
597% exception)
598%
599% A description of each parameter follows:
600%
601% o info: a structure of type info.
602%
603% o exception: Return any errors or warnings in this structure.
604%
605*/
606static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
607 ExceptionInfo *exception)
608{
609 struct PackageInfo
610 *clone_info;
611
612 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
613 if (clone_info == (struct PackageInfo *) NULL)
614 {
615 ThrowPerlException(exception,ResourceLimitError,
616 "UnableToClonePackageInfo",PackageName);
617 return((struct PackageInfo *) NULL);
618 }
619 if (info == (struct PackageInfo *) NULL)
620 {
621 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
622 return(clone_info);
623 }
624 *clone_info=(*info);
625 clone_info->image_info=CloneImageInfo(info->image_info);
626 return(clone_info);
627}
628
629/*
630%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
631% %
632% %
633% %
634% c o n s t a n t %
635% %
636% %
637% %
638%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
639%
640% constant() returns a double value for the specified name.
641%
642% The format of the constant routine is:
643%
644% double constant(char *name,ssize_t sans)
645%
646% A description of each parameter follows:
647%
648% o value: Method constant returns a double value for the specified name.
649%
650% o name: The name of the constant.
651%
652% o sans: This integer value is not used.
653%
654*/
655static double constant(char *name,ssize_t sans)
656{
657 (void) sans;
658 errno=0;
659 switch (*name)
660 {
661 case 'B':
662 {
663 if (strEQ(name,"BlobError"))
664 return(BlobError);
665 if (strEQ(name,"BlobWarning"))
666 return(BlobWarning);
667 break;
668 }
669 case 'C':
670 {
671 if (strEQ(name,"CacheError"))
672 return(CacheError);
673 if (strEQ(name,"CacheWarning"))
674 return(CacheWarning);
675 if (strEQ(name,"CoderError"))
676 return(CoderError);
677 if (strEQ(name,"CoderWarning"))
678 return(CoderWarning);
679 if (strEQ(name,"ConfigureError"))
680 return(ConfigureError);
681 if (strEQ(name,"ConfigureWarning"))
682 return(ConfigureWarning);
683 if (strEQ(name,"CorruptImageError"))
684 return(CorruptImageError);
685 if (strEQ(name,"CorruptImageWarning"))
686 return(CorruptImageWarning);
687 break;
688 }
689 case 'D':
690 {
691 if (strEQ(name,"DelegateError"))
692 return(DelegateError);
693 if (strEQ(name,"DelegateWarning"))
694 return(DelegateWarning);
695 if (strEQ(name,"DrawError"))
696 return(DrawError);
697 if (strEQ(name,"DrawWarning"))
698 return(DrawWarning);
699 break;
700 }
701 case 'E':
702 {
703 if (strEQ(name,"ErrorException"))
704 return(ErrorException);
705 if (strEQ(name,"ExceptionError"))
706 return(CoderError);
707 if (strEQ(name,"ExceptionWarning"))
708 return(CoderWarning);
709 break;
710 }
711 case 'F':
712 {
713 if (strEQ(name,"FatalErrorException"))
714 return(FatalErrorException);
715 if (strEQ(name,"FileOpenError"))
716 return(FileOpenError);
717 if (strEQ(name,"FileOpenWarning"))
718 return(FileOpenWarning);
719 break;
720 }
721 case 'I':
722 {
723 if (strEQ(name,"ImageError"))
724 return(ImageError);
725 if (strEQ(name,"ImageWarning"))
726 return(ImageWarning);
727 break;
728 }
729 case 'M':
730 {
731 if (strEQ(name,"MaxRGB"))
732 return(QuantumRange);
733 if (strEQ(name,"MissingDelegateError"))
734 return(MissingDelegateError);
735 if (strEQ(name,"MissingDelegateWarning"))
736 return(MissingDelegateWarning);
737 if (strEQ(name,"ModuleError"))
738 return(ModuleError);
739 if (strEQ(name,"ModuleWarning"))
740 return(ModuleWarning);
741 break;
742 }
743 case 'O':
744 {
745 if (strEQ(name,"Opaque"))
746 return(OpaqueAlpha);
747 if (strEQ(name,"OptionError"))
748 return(OptionError);
749 if (strEQ(name,"OptionWarning"))
750 return(OptionWarning);
751 break;
752 }
753 case 'Q':
754 {
755 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
756 return(MAGICKCORE_QUANTUM_DEPTH);
757 if (strEQ(name,"QuantumDepth"))
758 return(MAGICKCORE_QUANTUM_DEPTH);
759 if (strEQ(name,"QuantumRange"))
760 return(QuantumRange);
761 break;
762 }
763 case 'R':
764 {
765 if (strEQ(name,"ResourceLimitError"))
766 return(ResourceLimitError);
767 if (strEQ(name,"ResourceLimitWarning"))
768 return(ResourceLimitWarning);
769 if (strEQ(name,"RegistryError"))
770 return(RegistryError);
771 if (strEQ(name,"RegistryWarning"))
772 return(RegistryWarning);
773 break;
774 }
775 case 'S':
776 {
777 if (strEQ(name,"StreamError"))
778 return(StreamError);
779 if (strEQ(name,"StreamWarning"))
780 return(StreamWarning);
781 if (strEQ(name,"Success"))
782 return(0);
783 break;
784 }
785 case 'T':
786 {
787 if (strEQ(name,"Transparent"))
788 return(TransparentAlpha);
789 if (strEQ(name,"TypeError"))
790 return(TypeError);
791 if (strEQ(name,"TypeWarning"))
792 return(TypeWarning);
793 break;
794 }
795 case 'W':
796 {
797 if (strEQ(name,"WarningException"))
798 return(WarningException);
799 break;
800 }
801 case 'X':
802 {
803 if (strEQ(name,"XServerError"))
804 return(XServerError);
805 if (strEQ(name,"XServerWarning"))
806 return(XServerWarning);
807 break;
808 }
809 }
810 errno=EINVAL;
811 return(0);
812}
813
814/*
815%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
816% %
817% %
818% %
819% D e s t r o y P a c k a g e I n f o %
820% %
821% %
822% %
823%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824%
825% Method DestroyPackageInfo frees a previously created info structure.
826%
827% The format of the DestroyPackageInfo routine is:
828%
829% DestroyPackageInfo(struct PackageInfo *info)
830%
831% A description of each parameter follows:
832%
833% o info: a structure of type info.
834%
835*/
836static void DestroyPackageInfo(struct PackageInfo *info)
837{
838 info->image_info=DestroyImageInfo(info->image_info);
839 info=(struct PackageInfo *) RelinquishMagickMemory(info);
840}
841
842/*
843%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
844% %
845% %
846% %
847% G e t L i s t %
848% %
849% %
850% %
851%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
852%
853% Method GetList is recursively called by SetupList to traverse the
854% Image__Magick reference. If building an reference_vector (see SetupList),
855% *current is the current position in *reference_vector and *last is the final
856% entry in *reference_vector.
857%
858% The format of the GetList routine is:
859%
860% GetList(info)
861%
862% A description of each parameter follows:
863%
864% o info: a structure of type info.
865%
866*/
867static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
868 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
869{
870 Image
871 *image;
872
873 if (reference == (SV *) NULL)
874 return(NULL);
875 switch (SvTYPE(reference))
876 {
877 case SVt_PVAV:
878 {
879 AV
880 *av;
881
882 Image
883 *head,
884 *previous;
885
886 register ssize_t
887 i;
888
889 ssize_t
890 n;
891
892 /*
893 Array of images.
894 */
895 previous=(Image *) NULL;
896 head=(Image *) NULL;
897 av=(AV *) reference;
898 n=av_len(av);
899 for (i=0; i <= n; i++)
900 {
901 SV
902 **rv;
903
904 rv=av_fetch(av,i,0);
905 if (rv && *rv && sv_isobject(*rv))
906 {
907 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
908 exception);
909 if (image == (Image *) NULL)
910 continue;
911 if (image == previous)
912 {
913 image=CloneImage(image,0,0,MagickTrue,exception);
914 if (image == (Image *) NULL)
915 return(NULL);
916 }
917 image->previous=previous;
918 *(previous ? &previous->next : &head)=image;
919 for (previous=image; previous->next; previous=previous->next) ;
920 }
921 }
922 return(head);
923 }
924 case SVt_PVMG:
925 {
926 /*
927 Blessed scalar, one image.
928 */
929 image=INT2PTR(Image *,SvIV(reference));
930 if (image == (Image *) NULL)
931 return(NULL);
932 image->previous=(Image *) NULL;
933 image->next=(Image *) NULL;
934 if (reference_vector)
935 {
936 if (*current == *last)
937 {
938 *last+=256;
939 if (*reference_vector == (SV **) NULL)
940 *reference_vector=(SV **) AcquireQuantumMemory(*last,
941 sizeof(*reference_vector));
942 else
943 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
944 *last,sizeof(*reference_vector));
945 }
946 if (*reference_vector == (SV **) NULL)
947 {
948 ThrowPerlException(exception,ResourceLimitError,
949 "MemoryAllocationFailed",PackageName);
950 return((Image *) NULL);
951 }
952 (*reference_vector)[*current]=reference;
953 (*reference_vector)[++(*current)]=NULL;
954 }
955 return(image);
956 }
957 default:
958 break;
959 }
960 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
961 (double) SvTYPE(reference));
962 return((Image *) NULL);
963}
964
965/*
966%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
967% %
968% %
969% %
970% G e t P a c k a g e I n f o %
971% %
972% %
973% %
974%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
975%
976% Method GetPackageInfo looks up or creates an info structure for the given
977% Image__Magick reference. If it does create a new one, the information in
978% package_info is used to initialize it.
979%
980% The format of the GetPackageInfo routine is:
981%
982% struct PackageInfo *GetPackageInfo(void *reference,
983% struct PackageInfo *package_info,ExceptionInfo *exception)
984%
985% A description of each parameter follows:
986%
987% o info: a structure of type info.
988%
989% o exception: Return any errors or warnings in this structure.
990%
991*/
992static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
993 struct PackageInfo *package_info,ExceptionInfo *exception)
994{
995 char
cristy151b66d2015-04-15 10:50:31 +0000996 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +0000997
998 struct PackageInfo
999 *clone_info;
1000
1001 SV
1002 *sv;
1003
cristy151b66d2015-04-15 10:50:31 +00001004 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00001005 PackageName,XS_VERSION,reference);
1006 sv=perl_get_sv(message,(TRUE | 0x02));
1007 if (sv == (SV *) NULL)
1008 {
1009 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1010 message);
1011 return(package_info);
1012 }
1013 if (SvREFCNT(sv) == 0)
1014 (void) SvREFCNT_inc(sv);
1015 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1016 return(clone_info);
1017 clone_info=ClonePackageInfo(package_info,exception);
1018 sv_setiv(sv,PTR2IV(clone_info));
1019 return(clone_info);
1020}
1021
1022/*
1023%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1024% %
1025% %
1026% %
1027% S e t A t t r i b u t e %
1028% %
1029% %
1030% %
1031%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1032%
1033% SetAttribute() sets the attribute to the value in sval. This can change
1034% either or both of image or info.
1035%
1036% The format of the SetAttribute routine is:
1037%
1038% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1039% SV *sval,ExceptionInfo *exception)
1040%
1041% A description of each parameter follows:
1042%
1043% o list: a list of strings.
1044%
1045% o string: a character string.
1046%
1047*/
1048
1049static double SiPrefixToDoubleInterval(const char *string,const double interval)
1050{
1051 char
1052 *q;
1053
1054 double
1055 value;
1056
1057 value=InterpretSiPrefixValue(string,&q);
1058 if (*q == '%')
1059 value*=interval/100.0;
1060 return(value);
1061}
1062
1063static inline double StringToDouble(const char *string,char **sentinal)
1064{
1065 return(InterpretLocaleValue(string,sentinal));
1066}
1067
1068static double StringToDoubleInterval(const char *string,const double interval)
1069{
1070 char
1071 *q;
1072
1073 double
1074 value;
1075
1076 value=InterpretLocaleValue(string,&q);
1077 if (*q == '%')
1078 value*=interval/100.0;
1079 return(value);
1080}
1081
1082static inline ssize_t StringToLong(const char *value)
1083{
1084 return(strtol(value,(char **) NULL,10));
1085}
1086
1087static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1088 const char *attribute,SV *sval,ExceptionInfo *exception)
1089{
1090 GeometryInfo
1091 geometry_info;
1092
1093 long
1094 x,
1095 y;
1096
1097 PixelInfo
1098 pixel;
1099
1100 MagickStatusType
1101 flags;
1102
1103 PixelInfo
1104 *color,
1105 target_color;
1106
1107 ssize_t
1108 sp;
1109
1110 switch (*attribute)
1111 {
1112 case 'A':
1113 case 'a':
1114 {
1115 if (LocaleCompare(attribute,"adjoin") == 0)
1116 {
1117 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1118 SvPV(sval,na)) : SvIV(sval);
1119 if (sp < 0)
1120 {
1121 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1122 SvPV(sval,na));
1123 break;
1124 }
1125 if (info)
1126 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1127 break;
1128 }
1129 if (LocaleCompare(attribute,"alpha") == 0)
1130 {
1131 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1132 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1133 if (sp < 0)
1134 {
1135 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1136 SvPV(sval,na));
1137 break;
1138 }
1139 for ( ; image; image=image->next)
1140 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1141 exception);
1142 break;
1143 }
1144 if (LocaleCompare(attribute,"antialias") == 0)
1145 {
1146 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1147 SvPV(sval,na)) : SvIV(sval);
1148 if (sp < 0)
1149 {
1150 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1151 SvPV(sval,na));
1152 break;
1153 }
1154 if (info)
1155 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1156 break;
1157 }
1158 if (LocaleCompare(attribute,"area-limit") == 0)
1159 {
1160 MagickSizeType
1161 limit;
1162
1163 limit=MagickResourceInfinity;
1164 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1165 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1166 100.0);
1167 (void) SetMagickResourceLimit(AreaResource,limit);
1168 break;
1169 }
1170 if (LocaleCompare(attribute,"attenuate") == 0)
1171 {
1172 if (info)
1173 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1174 break;
1175 }
1176 if (LocaleCompare(attribute,"authenticate") == 0)
1177 {
1178 if (info)
1179 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1180 break;
1181 }
1182 if (info)
1183 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1184 for ( ; image; image=image->next)
1185 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1186 break;
1187 }
1188 case 'B':
1189 case 'b':
1190 {
1191 if (LocaleCompare(attribute,"background") == 0)
1192 {
1193 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1194 exception);
1195 if (info)
1196 info->image_info->background_color=target_color;
1197 for ( ; image; image=image->next)
1198 image->background_color=target_color;
1199 break;
1200 }
1201 if (LocaleCompare(attribute,"blue-primary") == 0)
1202 {
1203 for ( ; image; image=image->next)
1204 {
1205 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1206 image->chromaticity.blue_primary.x=geometry_info.rho;
1207 image->chromaticity.blue_primary.y=geometry_info.sigma;
1208 if ((flags & SigmaValue) == 0)
1209 image->chromaticity.blue_primary.y=
1210 image->chromaticity.blue_primary.x;
1211 }
1212 break;
1213 }
1214 if (LocaleCompare(attribute,"bordercolor") == 0)
1215 {
1216 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1217 exception);
1218 if (info)
1219 info->image_info->border_color=target_color;
1220 for ( ; image; image=image->next)
1221 image->border_color=target_color;
1222 break;
1223 }
1224 if (info)
1225 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1226 for ( ; image; image=image->next)
1227 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1228 break;
1229 }
1230 case 'C':
1231 case 'c':
1232 {
1233 if (LocaleCompare(attribute,"cache-threshold") == 0)
1234 {
1235 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1236 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1237 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1238 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1239 break;
1240 }
1241 if (LocaleCompare(attribute,"clip-mask") == 0)
1242 {
1243 Image
1244 *clip_mask;
1245
1246 clip_mask=(Image *) NULL;
1247 if (SvPOK(sval))
1248 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1249 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001250 SetImageMask(image,ReadPixelMask,clip_mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001251 break;
1252 }
1253 if (LocaleNCompare(attribute,"colormap",8) == 0)
1254 {
1255 for ( ; image; image=image->next)
1256 {
1257 int
1258 items;
1259
1260 long
1261 i;
1262
1263 if (image->storage_class == DirectClass)
1264 continue;
1265 i=0;
1266 items=sscanf(attribute,"%*[^[][%ld",&i);
1267 (void) items;
1268 if (i > (ssize_t) image->colors)
1269 i%=image->colors;
1270 if ((strchr(SvPV(sval,na),',') == 0) ||
1271 (strchr(SvPV(sval,na),')') != 0))
1272 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1273 image->colormap+i,exception);
1274 else
1275 {
1276 color=image->colormap+i;
1277 pixel.red=color->red;
1278 pixel.green=color->green;
1279 pixel.blue=color->blue;
1280 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1281 pixel.red=geometry_info.rho;
1282 pixel.green=geometry_info.sigma;
1283 pixel.blue=geometry_info.xi;
1284 color->red=ClampToQuantum(pixel.red);
1285 color->green=ClampToQuantum(pixel.green);
1286 color->blue=ClampToQuantum(pixel.blue);
1287 }
1288 }
1289 break;
1290 }
1291 if (LocaleCompare(attribute,"colorspace") == 0)
1292 {
1293 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1294 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1295 if (sp < 0)
1296 {
1297 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1298 SvPV(sval,na));
1299 break;
1300 }
1301 for ( ; image; image=image->next)
1302 (void) TransformImageColorspace(image,(ColorspaceType) sp,
1303 exception);
1304 break;
1305 }
1306 if (LocaleCompare(attribute,"comment") == 0)
1307 {
1308 for ( ; image; image=image->next)
1309 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1310 info ? info->image_info : (ImageInfo *) NULL,image,
1311 SvPV(sval,na),exception),exception);
1312 break;
1313 }
1314 if (LocaleCompare(attribute,"compression") == 0)
1315 {
1316 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1317 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1318 if (sp < 0)
1319 {
1320 ThrowPerlException(exception,OptionError,
1321 "UnrecognizedImageCompression",SvPV(sval,na));
1322 break;
1323 }
1324 if (info)
1325 info->image_info->compression=(CompressionType) sp;
1326 for ( ; image; image=image->next)
1327 image->compression=(CompressionType) sp;
1328 break;
1329 }
1330 if (info)
1331 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1332 for ( ; image; image=image->next)
1333 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1334 break;
1335 }
1336 case 'D':
1337 case 'd':
1338 {
1339 if (LocaleCompare(attribute,"debug") == 0)
1340 {
1341 SetLogEventMask(SvPV(sval,na));
1342 break;
1343 }
1344 if (LocaleCompare(attribute,"delay") == 0)
1345 {
1346 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1347 for ( ; image; image=image->next)
1348 {
1349 image->delay=(size_t) floor(geometry_info.rho+0.5);
1350 if ((flags & SigmaValue) != 0)
1351 image->ticks_per_second=(ssize_t)
1352 floor(geometry_info.sigma+0.5);
1353 }
1354 break;
1355 }
1356 if (LocaleCompare(attribute,"disk-limit") == 0)
1357 {
1358 MagickSizeType
1359 limit;
1360
1361 limit=MagickResourceInfinity;
1362 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1363 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1364 100.0);
1365 (void) SetMagickResourceLimit(DiskResource,limit);
1366 break;
1367 }
1368 if (LocaleCompare(attribute,"density") == 0)
1369 {
1370 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1371 {
1372 ThrowPerlException(exception,OptionError,"MissingGeometry",
1373 SvPV(sval,na));
1374 break;
1375 }
1376 if (info)
1377 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1378 for ( ; image; image=image->next)
1379 {
1380 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1381 image->resolution.x=geometry_info.rho;
1382 image->resolution.y=geometry_info.sigma;
1383 if ((flags & SigmaValue) == 0)
1384 image->resolution.y=image->resolution.x;
1385 }
1386 break;
1387 }
1388 if (LocaleCompare(attribute,"depth") == 0)
1389 {
1390 if (info)
1391 info->image_info->depth=SvIV(sval);
1392 for ( ; image; image=image->next)
1393 (void) SetImageDepth(image,SvIV(sval),exception);
1394 break;
1395 }
1396 if (LocaleCompare(attribute,"dispose") == 0)
1397 {
1398 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1399 SvPV(sval,na)) : SvIV(sval);
1400 if (sp < 0)
1401 {
1402 ThrowPerlException(exception,OptionError,
1403 "UnrecognizedDisposeMethod",SvPV(sval,na));
1404 break;
1405 }
1406 for ( ; image; image=image->next)
1407 image->dispose=(DisposeType) sp;
1408 break;
1409 }
1410 if (LocaleCompare(attribute,"dither") == 0)
1411 {
1412 if (info)
1413 {
1414 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1415 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1416 if (sp < 0)
1417 {
1418 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1419 SvPV(sval,na));
1420 break;
1421 }
1422 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1423 }
1424 break;
1425 }
1426 if (LocaleCompare(attribute,"display") == 0)
1427 {
1428 display:
1429 if (info)
1430 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1431 break;
1432 }
1433 if (info)
1434 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1435 for ( ; image; image=image->next)
1436 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1437 break;
1438 }
1439 case 'E':
1440 case 'e':
1441 {
1442 if (LocaleCompare(attribute,"endian") == 0)
1443 {
1444 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1445 SvPV(sval,na)) : SvIV(sval);
1446 if (sp < 0)
1447 {
1448 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1449 SvPV(sval,na));
1450 break;
1451 }
1452 if (info)
1453 info->image_info->endian=(EndianType) sp;
1454 for ( ; image; image=image->next)
1455 image->endian=(EndianType) sp;
1456 break;
1457 }
1458 if (LocaleCompare(attribute,"extract") == 0)
1459 {
1460 /*
1461 Set image extract geometry.
1462 */
1463 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1464 break;
1465 }
1466 if (info)
1467 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1468 for ( ; image; image=image->next)
1469 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1470 break;
1471 }
1472 case 'F':
1473 case 'f':
1474 {
1475 if (LocaleCompare(attribute,"filename") == 0)
1476 {
1477 if (info)
1478 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001479 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001480 for ( ; image; image=image->next)
1481 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001482 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001483 break;
1484 }
1485 if (LocaleCompare(attribute,"file") == 0)
1486 {
1487 FILE
1488 *file;
1489
1490 PerlIO
1491 *io_info;
1492
1493 if (info == (struct PackageInfo *) NULL)
1494 break;
1495 io_info=IoIFP(sv_2io(sval));
1496 if (io_info == (PerlIO *) NULL)
1497 {
1498 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1499 PackageName);
1500 break;
1501 }
1502 file=PerlIO_findFILE(io_info);
1503 if (file == (FILE *) NULL)
1504 {
1505 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1506 PackageName);
1507 break;
1508 }
1509 SetImageInfoFile(info->image_info,file);
1510 break;
1511 }
1512 if (LocaleCompare(attribute,"fill") == 0)
1513 {
1514 if (info)
1515 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1516 break;
1517 }
1518 if (LocaleCompare(attribute,"font") == 0)
1519 {
1520 if (info)
1521 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1522 break;
1523 }
1524 if (LocaleCompare(attribute,"foreground") == 0)
1525 break;
1526 if (LocaleCompare(attribute,"fuzz") == 0)
1527 {
1528 if (info)
1529 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1530 QuantumRange+1.0);
1531 for ( ; image; image=image->next)
1532 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1533 QuantumRange+1.0);
1534 break;
1535 }
1536 if (info)
1537 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1538 for ( ; image; image=image->next)
1539 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1540 break;
1541 }
1542 case 'G':
1543 case 'g':
1544 {
1545 if (LocaleCompare(attribute,"gamma") == 0)
1546 {
1547 for ( ; image; image=image->next)
1548 image->gamma=SvNV(sval);
1549 break;
1550 }
1551 if (LocaleCompare(attribute,"gravity") == 0)
1552 {
1553 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1554 SvPV(sval,na)) : SvIV(sval);
1555 if (sp < 0)
1556 {
1557 ThrowPerlException(exception,OptionError,
1558 "UnrecognizedGravityType",SvPV(sval,na));
1559 break;
1560 }
1561 if (info)
1562 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1563 for ( ; image; image=image->next)
1564 image->gravity=(GravityType) sp;
1565 break;
1566 }
1567 if (LocaleCompare(attribute,"green-primary") == 0)
1568 {
1569 for ( ; image; image=image->next)
1570 {
1571 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1572 image->chromaticity.green_primary.x=geometry_info.rho;
1573 image->chromaticity.green_primary.y=geometry_info.sigma;
1574 if ((flags & SigmaValue) == 0)
1575 image->chromaticity.green_primary.y=
1576 image->chromaticity.green_primary.x;
1577 }
1578 break;
1579 }
1580 if (info)
1581 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1582 for ( ; image; image=image->next)
1583 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1584 break;
1585 }
1586 case 'I':
1587 case 'i':
1588 {
1589 if (LocaleNCompare(attribute,"index",5) == 0)
1590 {
1591 int
1592 items;
1593
1594 long
1595 index;
1596
1597 register Quantum
1598 *q;
1599
1600 CacheView
1601 *image_view;
1602
1603 for ( ; image; image=image->next)
1604 {
1605 if (image->storage_class != PseudoClass)
1606 continue;
1607 x=0;
1608 y=0;
1609 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1610 (void) items;
1611 image_view=AcquireAuthenticCacheView(image,exception);
1612 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1613 if (q != (Quantum *) NULL)
1614 {
1615 items=sscanf(SvPV(sval,na),"%ld",&index);
1616 if ((index >= 0) && (index < (ssize_t) image->colors))
1617 SetPixelIndex(image,index,q);
1618 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1619 }
1620 image_view=DestroyCacheView(image_view);
1621 }
1622 break;
1623 }
1624 if (LocaleCompare(attribute,"iterations") == 0)
1625 {
1626 iterations:
1627 for ( ; image; image=image->next)
1628 image->iterations=SvIV(sval);
1629 break;
1630 }
1631 if (LocaleCompare(attribute,"interlace") == 0)
1632 {
1633 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1634 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1635 if (sp < 0)
1636 {
1637 ThrowPerlException(exception,OptionError,
1638 "UnrecognizedInterlaceType",SvPV(sval,na));
1639 break;
1640 }
1641 if (info)
1642 info->image_info->interlace=(InterlaceType) sp;
1643 for ( ; image; image=image->next)
1644 image->interlace=(InterlaceType) sp;
1645 break;
1646 }
1647 if (info)
1648 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1649 for ( ; image; image=image->next)
1650 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1651 break;
1652 }
1653 case 'L':
1654 case 'l':
1655 {
1656 if (LocaleCompare(attribute,"label") == 0)
1657 {
1658 for ( ; image; image=image->next)
1659 (void) SetImageProperty(image,"label",InterpretImageProperties(
1660 info ? info->image_info : (ImageInfo *) NULL,image,
1661 SvPV(sval,na),exception),exception);
1662 break;
1663 }
1664 if (LocaleCompare(attribute,"loop") == 0)
1665 goto iterations;
1666 if (info)
1667 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1668 for ( ; image; image=image->next)
1669 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1670 break;
1671 }
1672 case 'M':
1673 case 'm':
1674 {
1675 if (LocaleCompare(attribute,"magick") == 0)
1676 {
1677 if (info)
cristy151b66d2015-04-15 10:50:31 +00001678 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00001679 "%s:",SvPV(sval,na));
1680 for ( ; image; image=image->next)
cristy151b66d2015-04-15 10:50:31 +00001681 (void) CopyMagickString(image->magick,SvPV(sval,na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001682 break;
1683 }
1684 if (LocaleCompare(attribute,"map-limit") == 0)
1685 {
1686 MagickSizeType
1687 limit;
1688
1689 limit=MagickResourceInfinity;
1690 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1691 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1692 100.0);
1693 (void) SetMagickResourceLimit(MapResource,limit);
1694 break;
1695 }
1696 if (LocaleCompare(attribute,"mask") == 0)
1697 {
1698 Image
1699 *mask;
1700
1701 mask=(Image *) NULL;
1702 if (SvPOK(sval))
1703 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1704 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001705 SetImageMask(image,ReadPixelMask,mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001706 break;
1707 }
1708 if (LocaleCompare(attribute,"mattecolor") == 0)
1709 {
1710 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1711 exception);
1712 if (info)
Cristy8645e042016-02-03 16:35:29 -05001713 info->image_info->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001714 for ( ; image; image=image->next)
Cristy8645e042016-02-03 16:35:29 -05001715 image->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001716 break;
1717 }
1718 if (LocaleCompare(attribute,"matte") == 0)
1719 {
1720 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1721 SvPV(sval,na)) : SvIV(sval);
1722 if (sp < 0)
1723 {
1724 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1725 SvPV(sval,na));
1726 break;
1727 }
1728 for ( ; image; image=image->next)
1729 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1730 break;
1731 }
1732 if (LocaleCompare(attribute,"memory-limit") == 0)
1733 {
1734 MagickSizeType
1735 limit;
1736
1737 limit=MagickResourceInfinity;
1738 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1739 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1740 100.0);
1741 (void) SetMagickResourceLimit(MemoryResource,limit);
1742 break;
1743 }
1744 if (LocaleCompare(attribute,"monochrome") == 0)
1745 {
1746 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1747 SvPV(sval,na)) : SvIV(sval);
1748 if (sp < 0)
1749 {
1750 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1751 SvPV(sval,na));
1752 break;
1753 }
1754 if (info)
1755 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1756 for ( ; image; image=image->next)
1757 (void) SetImageType(image,BilevelType,exception);
1758 break;
1759 }
1760 if (info)
1761 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1762 for ( ; image; image=image->next)
1763 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1764 break;
1765 }
1766 case 'O':
1767 case 'o':
1768 {
1769 if (LocaleCompare(attribute,"option") == 0)
1770 {
1771 if (info)
1772 DefineImageOption(info->image_info,SvPV(sval,na));
1773 break;
1774 }
1775 if (LocaleCompare(attribute,"orientation") == 0)
1776 {
1777 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1778 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1779 if (sp < 0)
1780 {
1781 ThrowPerlException(exception,OptionError,
1782 "UnrecognizedOrientationType",SvPV(sval,na));
1783 break;
1784 }
1785 if (info)
1786 info->image_info->orientation=(OrientationType) sp;
1787 for ( ; image; image=image->next)
1788 image->orientation=(OrientationType) sp;
1789 break;
1790 }
1791 if (info)
1792 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1793 for ( ; image; image=image->next)
1794 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1795 break;
1796 }
1797 case 'P':
1798 case 'p':
1799 {
1800 if (LocaleCompare(attribute,"page") == 0)
1801 {
1802 char
1803 *geometry;
1804
1805 geometry=GetPageGeometry(SvPV(sval,na));
1806 if (info)
1807 (void) CloneString(&info->image_info->page,geometry);
1808 for ( ; image; image=image->next)
1809 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1810 geometry=(char *) RelinquishMagickMemory(geometry);
1811 break;
1812 }
1813 if (LocaleNCompare(attribute,"pixel",5) == 0)
1814 {
1815 int
1816 items;
1817
1818 PixelInfo
1819 pixel;
1820
1821 register Quantum
1822 *q;
1823
1824 CacheView
1825 *image_view;
1826
1827 for ( ; image; image=image->next)
1828 {
1829 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1830 break;
1831 x=0;
1832 y=0;
1833 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1834 (void) items;
1835 image_view=AcquireVirtualCacheView(image,exception);
1836 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1837 if (q != (Quantum *) NULL)
1838 {
1839 if ((strchr(SvPV(sval,na),',') == 0) ||
1840 (strchr(SvPV(sval,na),')') != 0))
1841 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1842 &pixel,exception);
1843 else
1844 {
1845 GetPixelInfo(image,&pixel);
1846 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1847 pixel.red=geometry_info.rho;
1848 if ((flags & SigmaValue) != 0)
1849 pixel.green=geometry_info.sigma;
1850 if ((flags & XiValue) != 0)
1851 pixel.blue=geometry_info.xi;
1852 if ((flags & PsiValue) != 0)
1853 pixel.alpha=geometry_info.psi;
1854 if ((flags & ChiValue) != 0)
1855 pixel.black=geometry_info.chi;
1856 }
1857 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1858 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1859 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1860 if (image->colorspace == CMYKColorspace)
1861 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1862 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1863 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1864 }
1865 image_view=DestroyCacheView(image_view);
1866 }
1867 break;
1868 }
1869 if (LocaleCompare(attribute,"pointsize") == 0)
1870 {
1871 if (info)
1872 {
1873 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1874 info->image_info->pointsize=geometry_info.rho;
1875 }
1876 break;
1877 }
1878 if (LocaleCompare(attribute,"preview") == 0)
1879 {
1880 sp=SvPOK(sval) ? ParseCommandOption(MagickPreviewOptions,MagickFalse,
1881 SvPV(sval,na)) : SvIV(sval);
1882 if (sp < 0)
1883 {
1884 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1885 SvPV(sval,na));
1886 break;
1887 }
1888 if (info)
1889 info->image_info->preview_type=(PreviewType) sp;
1890 break;
1891 }
1892 if (info)
1893 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1894 for ( ; image; image=image->next)
1895 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1896 break;
1897 }
1898 case 'Q':
1899 case 'q':
1900 {
1901 if (LocaleCompare(attribute,"quality") == 0)
1902 {
1903 if (info)
1904 info->image_info->quality=SvIV(sval);
1905 for ( ; image; image=image->next)
1906 image->quality=SvIV(sval);
1907 break;
1908 }
1909 if (info)
1910 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1911 for ( ; image; image=image->next)
1912 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1913 break;
1914 }
1915 case 'R':
1916 case 'r':
1917 {
cristyc0fe4752015-07-27 18:02:39 +00001918 if (LocaleCompare(attribute,"read-mask") == 0)
1919 {
1920 Image
1921 *mask;
1922
1923 mask=(Image *) NULL;
1924 if (SvPOK(sval))
1925 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1926 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001927 SetImageMask(image,ReadPixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00001928 break;
1929 }
cristy4a3ce0a2013-08-03 20:06:59 +00001930 if (LocaleCompare(attribute,"red-primary") == 0)
1931 {
1932 for ( ; image; image=image->next)
1933 {
1934 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1935 image->chromaticity.red_primary.x=geometry_info.rho;
1936 image->chromaticity.red_primary.y=geometry_info.sigma;
1937 if ((flags & SigmaValue) == 0)
1938 image->chromaticity.red_primary.y=
1939 image->chromaticity.red_primary.x;
1940 }
1941 break;
1942 }
1943 if (LocaleCompare(attribute,"render") == 0)
1944 {
1945 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1946 SvPV(sval,na)) : SvIV(sval);
1947 if (sp < 0)
1948 {
1949 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1950 SvPV(sval,na));
1951 break;
1952 }
1953 for ( ; image; image=image->next)
1954 image->rendering_intent=(RenderingIntent) sp;
1955 break;
1956 }
1957 if (LocaleCompare(attribute,"repage") == 0)
1958 {
1959 RectangleInfo
1960 geometry;
1961
1962 for ( ; image; image=image->next)
1963 {
1964 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1965 if ((flags & WidthValue) != 0)
1966 {
1967 if ((flags & HeightValue) == 0)
1968 geometry.height=geometry.width;
1969 image->page.width=geometry.width;
1970 image->page.height=geometry.height;
1971 }
1972 if ((flags & AspectValue) != 0)
1973 {
1974 if ((flags & XValue) != 0)
1975 image->page.x+=geometry.x;
1976 if ((flags & YValue) != 0)
1977 image->page.y+=geometry.y;
1978 }
1979 else
1980 {
1981 if ((flags & XValue) != 0)
1982 {
1983 image->page.x=geometry.x;
1984 if (((flags & WidthValue) != 0) && (geometry.x > 0))
1985 image->page.width=image->columns+geometry.x;
1986 }
1987 if ((flags & YValue) != 0)
1988 {
1989 image->page.y=geometry.y;
1990 if (((flags & HeightValue) != 0) && (geometry.y > 0))
1991 image->page.height=image->rows+geometry.y;
1992 }
1993 }
1994 }
1995 break;
1996 }
1997 if (info)
1998 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1999 for ( ; image; image=image->next)
2000 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2001 break;
2002 }
2003 case 'S':
2004 case 's':
2005 {
2006 if (LocaleCompare(attribute,"sampling-factor") == 0)
2007 {
2008 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2009 {
2010 ThrowPerlException(exception,OptionError,"MissingGeometry",
2011 SvPV(sval,na));
2012 break;
2013 }
2014 if (info)
2015 (void) CloneString(&info->image_info->sampling_factor,
2016 SvPV(sval,na));
2017 break;
2018 }
2019 if (LocaleCompare(attribute,"scene") == 0)
2020 {
2021 for ( ; image; image=image->next)
2022 image->scene=SvIV(sval);
2023 break;
2024 }
2025 if (LocaleCompare(attribute,"server") == 0)
2026 goto display;
2027 if (LocaleCompare(attribute,"size") == 0)
2028 {
2029 if (info)
2030 {
2031 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2032 {
2033 ThrowPerlException(exception,OptionError,"MissingGeometry",
2034 SvPV(sval,na));
2035 break;
2036 }
2037 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2038 }
2039 break;
2040 }
2041 if (LocaleCompare(attribute,"stroke") == 0)
2042 {
2043 if (info)
2044 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2045 break;
2046 }
2047 if (info)
2048 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2049 for ( ; image; image=image->next)
2050 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2051 break;
2052 }
2053 case 'T':
2054 case 't':
2055 {
2056 if (LocaleCompare(attribute,"texture") == 0)
2057 {
2058 if (info)
2059 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2060 break;
2061 }
2062 if (LocaleCompare(attribute,"thread-limit") == 0)
2063 {
2064 MagickSizeType
2065 limit;
2066
2067 limit=MagickResourceInfinity;
2068 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2069 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2070 100.0);
2071 (void) SetMagickResourceLimit(ThreadResource,limit);
2072 break;
2073 }
2074 if (LocaleCompare(attribute,"tile-offset") == 0)
2075 {
2076 char
2077 *geometry;
2078
2079 geometry=GetPageGeometry(SvPV(sval,na));
2080 if (info)
2081 (void) CloneString(&info->image_info->page,geometry);
2082 for ( ; image; image=image->next)
2083 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2084 exception);
2085 geometry=(char *) RelinquishMagickMemory(geometry);
2086 break;
2087 }
2088 if (LocaleCompare(attribute,"time-limit") == 0)
2089 {
2090 MagickSizeType
2091 limit;
2092
2093 limit=MagickResourceInfinity;
2094 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2095 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2096 100.0);
2097 (void) SetMagickResourceLimit(TimeResource,limit);
2098 break;
2099 }
2100 if (LocaleCompare(attribute,"transparent-color") == 0)
2101 {
2102 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2103 exception);
2104 if (info)
2105 info->image_info->transparent_color=target_color;
2106 for ( ; image; image=image->next)
2107 image->transparent_color=target_color;
2108 break;
2109 }
2110 if (LocaleCompare(attribute,"type") == 0)
2111 {
2112 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2113 SvPV(sval,na)) : SvIV(sval);
2114 if (sp < 0)
2115 {
2116 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2117 SvPV(sval,na));
2118 break;
2119 }
2120 if (info)
2121 info->image_info->type=(ImageType) sp;
2122 for ( ; image; image=image->next)
2123 SetImageType(image,(ImageType) sp,exception);
2124 break;
2125 }
2126 if (info)
2127 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2128 for ( ; image; image=image->next)
2129 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2130 break;
2131 }
2132 case 'U':
2133 case 'u':
2134 {
2135 if (LocaleCompare(attribute,"units") == 0)
2136 {
2137 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2138 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2139 if (sp < 0)
2140 {
2141 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2142 SvPV(sval,na));
2143 break;
2144 }
2145 if (info)
2146 info->image_info->units=(ResolutionType) sp;
2147 for ( ; image; image=image->next)
2148 {
2149 ResolutionType
2150 units;
2151
2152 units=(ResolutionType) sp;
2153 if (image->units != units)
2154 switch (image->units)
2155 {
2156 case UndefinedResolution:
2157 case PixelsPerInchResolution:
2158 {
2159 if (units == PixelsPerCentimeterResolution)
2160 {
2161 image->resolution.x*=2.54;
2162 image->resolution.y*=2.54;
2163 }
2164 break;
2165 }
2166 case PixelsPerCentimeterResolution:
2167 {
2168 if (units == PixelsPerInchResolution)
2169 {
2170 image->resolution.x/=2.54;
2171 image->resolution.y/=2.54;
2172 }
2173 break;
2174 }
2175 }
2176 image->units=units;
2177 }
2178 break;
2179 }
2180 if (info)
2181 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2182 for ( ; image; image=image->next)
2183 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2184 break;
2185 }
2186 case 'V':
2187 case 'v':
2188 {
2189 if (LocaleCompare(attribute,"verbose") == 0)
2190 {
2191 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2192 SvPV(sval,na)) : SvIV(sval);
2193 if (sp < 0)
2194 {
2195 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2196 SvPV(sval,na));
2197 break;
2198 }
2199 if (info)
2200 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2201 break;
2202 }
cristy4a3ce0a2013-08-03 20:06:59 +00002203 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2204 {
2205 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2206 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2207 if (sp < 0)
2208 {
2209 ThrowPerlException(exception,OptionError,
2210 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2211 break;
2212 }
2213 for ( ; image; image=image->next)
2214 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2215 break;
2216 }
2217 if (info)
2218 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2219 for ( ; image; image=image->next)
2220 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2221 break;
2222 }
2223 case 'W':
2224 case 'w':
2225 {
2226 if (LocaleCompare(attribute,"white-point") == 0)
2227 {
2228 for ( ; image; image=image->next)
2229 {
2230 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2231 image->chromaticity.white_point.x=geometry_info.rho;
2232 image->chromaticity.white_point.y=geometry_info.sigma;
2233 if ((flags & SigmaValue) == 0)
2234 image->chromaticity.white_point.y=
2235 image->chromaticity.white_point.x;
2236 }
2237 break;
2238 }
cristyc0fe4752015-07-27 18:02:39 +00002239 if (LocaleCompare(attribute,"write-mask") == 0)
2240 {
2241 Image
2242 *mask;
2243
2244 mask=(Image *) NULL;
2245 if (SvPOK(sval))
2246 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2247 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002248 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002249 break;
2250 }
cristy4a3ce0a2013-08-03 20:06:59 +00002251 if (info)
2252 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2253 for ( ; image; image=image->next)
2254 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2255 break;
2256 }
2257 default:
2258 {
2259 if (info)
2260 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2261 for ( ; image; image=image->next)
2262 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2263 break;
2264 }
2265 }
2266}
2267
2268/*
2269%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2270% %
2271% %
2272% %
2273% S e t u p L i s t %
2274% %
2275% %
2276% %
2277%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2278%
2279% Method SetupList returns the list of all the images linked by their
2280% image->next and image->previous link lists for use with ImageMagick. If
2281% info is non-NULL, an info structure is returned in *info. If
2282% reference_vector is non-NULL,an array of SV* are returned in
2283% *reference_vector. Reference_vector is used when the images are going to be
2284% replaced with new Image*'s.
2285%
2286% The format of the SetupList routine is:
2287%
2288% Image *SetupList(SV *reference,struct PackageInfo **info,
2289% SV ***reference_vector,ExceptionInfo *exception)
2290%
2291% A description of each parameter follows:
2292%
2293% o list: a list of strings.
2294%
2295% o string: a character string.
2296%
2297% o exception: Return any errors or warnings in this structure.
2298%
2299*/
2300static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2301 SV ***reference_vector,ExceptionInfo *exception)
2302{
2303 Image
2304 *image;
2305
2306 ssize_t
2307 current,
2308 last;
2309
2310 if (reference_vector)
2311 *reference_vector=NULL;
2312 if (info)
2313 *info=NULL;
2314 current=0;
2315 last=0;
2316 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2317 if (info && (SvTYPE(reference) == SVt_PVAV))
2318 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2319 exception);
2320 return(image);
2321}
2322
2323/*
2324%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2325% %
2326% %
2327% %
2328% s t r E Q c a s e %
2329% %
2330% %
2331% %
2332%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2333%
2334% strEQcase() compares two strings and returns 0 if they are the
2335% same or if the second string runs out first. The comparison is case
2336% insensitive.
2337%
2338% The format of the strEQcase routine is:
2339%
2340% ssize_t strEQcase(const char *p,const char *q)
2341%
2342% A description of each parameter follows:
2343%
2344% o p: a character string.
2345%
2346% o q: a character string.
2347%
2348%
2349*/
2350static ssize_t strEQcase(const char *p,const char *q)
2351{
2352 char
2353 c;
2354
2355 register ssize_t
2356 i;
2357
2358 for (i=0 ; (c=(*q)) != 0; i++)
2359 {
2360 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2361 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2362 return(0);
2363 p++;
2364 q++;
2365 }
2366 return(((*q == 0) && (*p == 0)) ? i : 0);
2367}
2368
2369/*
2370%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2371% %
2372% %
2373% %
2374% I m a g e : : M a g i c k %
2375% %
2376% %
2377% %
2378%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2379%
2380%
2381*/
2382MODULE = Image::Magick PACKAGE = Image::Magick
2383
2384PROTOTYPES: ENABLE
2385
2386BOOT:
2387 MagickCoreGenesis("PerlMagick",MagickFalse);
2388 SetWarningHandler(NULL);
2389 SetErrorHandler(NULL);
2390 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2391 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2392
2393void
2394UNLOAD()
2395 PPCODE:
2396 {
2397 if (magick_registry != (SplayTreeInfo *) NULL)
2398 magick_registry=DestroySplayTree(magick_registry);
2399 MagickCoreTerminus();
2400 }
2401
2402double
2403constant(name,argument)
2404 char *name
2405 ssize_t argument
2406
2407#
2408###############################################################################
2409# #
2410# #
2411# #
2412# A n i m a t e #
2413# #
2414# #
2415# #
2416###############################################################################
2417#
2418#
2419void
2420Animate(ref,...)
2421 Image::Magick ref=NO_INIT
2422 ALIAS:
2423 AnimateImage = 1
2424 animate = 2
2425 animateimage = 3
2426 PPCODE:
2427 {
2428 ExceptionInfo
2429 *exception;
2430
2431 Image
2432 *image;
2433
2434 register ssize_t
2435 i;
2436
2437 struct PackageInfo
2438 *info,
2439 *package_info;
2440
2441 SV
2442 *perl_exception,
2443 *reference;
2444
2445 PERL_UNUSED_VAR(ref);
2446 PERL_UNUSED_VAR(ix);
2447 exception=AcquireExceptionInfo();
2448 perl_exception=newSVpv("",0);
2449 package_info=(struct PackageInfo *) NULL;
2450 if (sv_isobject(ST(0)) == 0)
2451 {
2452 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2453 PackageName);
2454 goto PerlException;
2455 }
2456 reference=SvRV(ST(0));
2457 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2458 if (image == (Image *) NULL)
2459 {
2460 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2461 PackageName);
2462 goto PerlException;
2463 }
2464 package_info=ClonePackageInfo(info,exception);
2465 if (items == 2)
2466 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2467 else
2468 if (items > 2)
2469 for (i=2; i < items; i+=2)
2470 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2471 exception);
2472 (void) AnimateImages(package_info->image_info,image,exception);
2473 (void) CatchImageException(image);
2474
2475 PerlException:
2476 if (package_info != (struct PackageInfo *) NULL)
2477 DestroyPackageInfo(package_info);
2478 InheritPerlException(exception,perl_exception);
2479 exception=DestroyExceptionInfo(exception);
2480 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2481 SvPOK_on(perl_exception);
2482 ST(0)=sv_2mortal(perl_exception);
2483 XSRETURN(1);
2484 }
2485
2486#
2487###############################################################################
2488# #
2489# #
2490# #
2491# A p p e n d #
2492# #
2493# #
2494# #
2495###############################################################################
2496#
2497#
2498void
2499Append(ref,...)
2500 Image::Magick ref=NO_INIT
2501 ALIAS:
2502 AppendImage = 1
2503 append = 2
2504 appendimage = 3
2505 PPCODE:
2506 {
2507 AV
2508 *av;
2509
2510 char
2511 *attribute;
2512
2513 ExceptionInfo
2514 *exception;
2515
2516 HV
2517 *hv;
2518
2519 Image
2520 *image;
2521
2522 register ssize_t
2523 i;
2524
2525 ssize_t
2526 stack;
2527
2528 struct PackageInfo
2529 *info;
2530
2531 SV
2532 *av_reference,
2533 *perl_exception,
2534 *reference,
2535 *rv,
2536 *sv;
2537
2538 PERL_UNUSED_VAR(ref);
2539 PERL_UNUSED_VAR(ix);
2540 exception=AcquireExceptionInfo();
2541 perl_exception=newSVpv("",0);
2542 sv=NULL;
2543 attribute=NULL;
2544 av=NULL;
2545 if (sv_isobject(ST(0)) == 0)
2546 {
2547 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2548 PackageName);
2549 goto PerlException;
2550 }
2551 reference=SvRV(ST(0));
2552 hv=SvSTASH(reference);
2553 av=newAV();
2554 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2555 SvREFCNT_dec(av);
2556 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2557 if (image == (Image *) NULL)
2558 {
2559 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2560 PackageName);
2561 goto PerlException;
2562 }
2563 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2564 /*
2565 Get options.
2566 */
2567 stack=MagickTrue;
2568 for (i=2; i < items; i+=2)
2569 {
2570 attribute=(char *) SvPV(ST(i-1),na);
2571 switch (*attribute)
2572 {
2573 case 'S':
2574 case 's':
2575 {
2576 if (LocaleCompare(attribute,"stack") == 0)
2577 {
2578 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2579 SvPV(ST(i),na));
2580 if (stack < 0)
2581 {
2582 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2583 SvPV(ST(i),na));
2584 return;
2585 }
2586 break;
2587 }
2588 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2589 attribute);
2590 break;
2591 }
2592 default:
2593 {
2594 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2595 attribute);
2596 break;
2597 }
2598 }
2599 }
2600 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2601 if (image == (Image *) NULL)
2602 goto PerlException;
2603 for ( ; image; image=image->next)
2604 {
2605 AddImageToRegistry(sv,image);
2606 rv=newRV(sv);
2607 av_push(av,sv_bless(rv,hv));
2608 SvREFCNT_dec(sv);
2609 }
2610 exception=DestroyExceptionInfo(exception);
2611 ST(0)=av_reference;
2612 SvREFCNT_dec(perl_exception);
2613 XSRETURN(1);
2614
2615 PerlException:
2616 InheritPerlException(exception,perl_exception);
2617 exception=DestroyExceptionInfo(exception);
2618 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2619 SvPOK_on(perl_exception);
2620 ST(0)=sv_2mortal(perl_exception);
2621 XSRETURN(1);
2622 }
2623
2624#
2625###############################################################################
2626# #
2627# #
2628# #
2629# A v e r a g e #
2630# #
2631# #
2632# #
2633###############################################################################
2634#
2635#
2636void
2637Average(ref)
2638 Image::Magick ref=NO_INIT
2639 ALIAS:
2640 AverageImage = 1
2641 average = 2
2642 averageimage = 3
2643 PPCODE:
2644 {
2645 AV
2646 *av;
2647
2648 char
2649 *p;
2650
2651 ExceptionInfo
2652 *exception;
2653
2654 HV
2655 *hv;
2656
2657 Image
2658 *image;
2659
2660 struct PackageInfo
2661 *info;
2662
2663 SV
2664 *perl_exception,
2665 *reference,
2666 *rv,
2667 *sv;
2668
2669 PERL_UNUSED_VAR(ref);
2670 PERL_UNUSED_VAR(ix);
2671 exception=AcquireExceptionInfo();
2672 perl_exception=newSVpv("",0);
2673 sv=NULL;
2674 if (sv_isobject(ST(0)) == 0)
2675 {
2676 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2677 PackageName);
2678 goto PerlException;
2679 }
2680 reference=SvRV(ST(0));
2681 hv=SvSTASH(reference);
2682 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2683 if (image == (Image *) NULL)
2684 {
2685 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2686 PackageName);
2687 goto PerlException;
2688 }
2689 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2690 if (image == (Image *) NULL)
2691 goto PerlException;
2692 /*
2693 Create blessed Perl array for the returned image.
2694 */
2695 av=newAV();
2696 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2697 SvREFCNT_dec(av);
2698 AddImageToRegistry(sv,image);
2699 rv=newRV(sv);
2700 av_push(av,sv_bless(rv,hv));
2701 SvREFCNT_dec(sv);
2702 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002703 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2704 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002705 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2706 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002707 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002708 SetImageInfo(info->image_info,0,exception);
2709 exception=DestroyExceptionInfo(exception);
2710 SvREFCNT_dec(perl_exception);
2711 XSRETURN(1);
2712
2713 PerlException:
2714 InheritPerlException(exception,perl_exception);
2715 exception=DestroyExceptionInfo(exception);
2716 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2717 SvPOK_on(perl_exception);
2718 ST(0)=sv_2mortal(perl_exception);
2719 XSRETURN(1);
2720 }
2721
2722#
2723###############################################################################
2724# #
2725# #
2726# #
2727# B l o b T o I m a g e #
2728# #
2729# #
2730# #
2731###############################################################################
2732#
2733#
2734void
2735BlobToImage(ref,...)
2736 Image::Magick ref=NO_INIT
2737 ALIAS:
2738 BlobToImage = 1
2739 blobtoimage = 2
2740 blobto = 3
2741 PPCODE:
2742 {
2743 AV
2744 *av;
2745
2746 char
2747 **keep,
2748 **list;
2749
2750 ExceptionInfo
2751 *exception;
2752
2753 HV
2754 *hv;
2755
2756 Image
2757 *image;
2758
2759 register char
2760 **p;
2761
2762 register ssize_t
2763 i;
2764
2765 ssize_t
2766 ac,
2767 n,
2768 number_images;
2769
2770 STRLEN
2771 *length;
2772
2773 struct PackageInfo
2774 *info;
2775
2776 SV
2777 *perl_exception,
2778 *reference,
2779 *rv,
2780 *sv;
2781
2782 PERL_UNUSED_VAR(ref);
2783 PERL_UNUSED_VAR(ix);
2784 exception=AcquireExceptionInfo();
2785 perl_exception=newSVpv("",0);
2786 sv=NULL;
2787 number_images=0;
2788 ac=(items < 2) ? 1 : items-1;
2789 length=(STRLEN *) NULL;
2790 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2791 if (list == (char **) NULL)
2792 {
2793 ThrowPerlException(exception,ResourceLimitError,
2794 "MemoryAllocationFailed",PackageName);
2795 goto PerlException;
2796 }
2797 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2798 if (length == (STRLEN *) NULL)
2799 {
2800 ThrowPerlException(exception,ResourceLimitError,
2801 "MemoryAllocationFailed",PackageName);
2802 goto PerlException;
2803 }
2804 if (sv_isobject(ST(0)) == 0)
2805 {
2806 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2807 PackageName);
2808 goto PerlException;
2809 }
2810 reference=SvRV(ST(0));
2811 hv=SvSTASH(reference);
2812 if (SvTYPE(reference) != SVt_PVAV)
2813 {
2814 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2815 PackageName);
2816 goto PerlException;
2817 }
2818 av=(AV *) reference;
2819 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2820 exception);
2821 n=1;
2822 if (items <= 1)
2823 {
2824 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2825 goto PerlException;
2826 }
2827 for (n=0, i=0; i < ac; i++)
2828 {
2829 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2830 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2831 {
2832 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2833 continue;
2834 }
2835 n++;
2836 }
2837 list[n]=(char *) NULL;
2838 keep=list;
2839 for (i=number_images=0; i < n; i++)
2840 {
2841 image=BlobToImage(info->image_info,list[i],length[i],exception);
2842 if (image == (Image *) NULL)
2843 break;
2844 for ( ; image; image=image->next)
2845 {
2846 AddImageToRegistry(sv,image);
2847 rv=newRV(sv);
2848 av_push(av,sv_bless(rv,hv));
2849 SvREFCNT_dec(sv);
2850 number_images++;
2851 }
2852 }
2853 /*
2854 Free resources.
2855 */
2856 for (i=0; i < n; i++)
2857 if (list[i] != (char *) NULL)
2858 for (p=keep; list[i] != *p++; )
2859 if (*p == (char *) NULL)
2860 {
2861 list[i]=(char *) RelinquishMagickMemory(list[i]);
2862 break;
2863 }
2864
2865 PerlException:
2866 if (list)
2867 list=(char **) RelinquishMagickMemory(list);
2868 if (length)
2869 length=(STRLEN *) RelinquishMagickMemory(length);
2870 InheritPerlException(exception,perl_exception);
2871 exception=DestroyExceptionInfo(exception);
2872 sv_setiv(perl_exception,(IV) number_images);
2873 SvPOK_on(perl_exception);
2874 ST(0)=sv_2mortal(perl_exception);
2875 XSRETURN(1);
2876 }
2877
2878#
2879###############################################################################
2880# #
2881# #
2882# #
2883# C h a n n e l F x #
2884# #
2885# #
2886# #
2887###############################################################################
2888#
2889#
2890void
2891ChannelFx(ref,...)
2892 Image::Magick ref=NO_INIT
2893 ALIAS:
2894 ChannelFxImage = 1
2895 channelfx = 2
2896 channelfximage = 3
2897 PPCODE:
2898 {
2899 AV
2900 *av;
2901
2902 char
2903 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002904 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002905
2906 ChannelType
2907 channel,
2908 channel_mask;
2909
2910 ExceptionInfo
2911 *exception;
2912
2913 HV
2914 *hv;
2915
2916 Image
2917 *image;
2918
2919 register ssize_t
2920 i;
2921
2922 struct PackageInfo
2923 *info;
2924
2925 SV
2926 *av_reference,
2927 *perl_exception,
2928 *reference,
2929 *rv,
2930 *sv;
2931
2932 PERL_UNUSED_VAR(ref);
2933 PERL_UNUSED_VAR(ix);
2934 exception=AcquireExceptionInfo();
2935 perl_exception=newSVpv("",0);
2936 sv=NULL;
2937 attribute=NULL;
2938 av=NULL;
2939 if (sv_isobject(ST(0)) == 0)
2940 {
2941 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2942 PackageName);
2943 goto PerlException;
2944 }
2945 reference=SvRV(ST(0));
2946 hv=SvSTASH(reference);
2947 av=newAV();
2948 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2949 SvREFCNT_dec(av);
2950 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2951 if (image == (Image *) NULL)
2952 {
2953 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2954 PackageName);
2955 goto PerlException;
2956 }
2957 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2958 /*
2959 Get options.
2960 */
2961 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00002962 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002963 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00002964 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002965 else
2966 for (i=2; i < items; i+=2)
2967 {
2968 attribute=(char *) SvPV(ST(i-1),na);
2969 switch (*attribute)
2970 {
2971 case 'C':
2972 case 'c':
2973 {
2974 if (LocaleCompare(attribute,"channel") == 0)
2975 {
2976 ssize_t
2977 option;
2978
2979 option=ParseChannelOption(SvPV(ST(i),na));
2980 if (option < 0)
2981 {
2982 ThrowPerlException(exception,OptionError,
2983 "UnrecognizedType",SvPV(ST(i),na));
2984 return;
2985 }
2986 channel=(ChannelType) option;
2987 break;
2988 }
2989 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2990 attribute);
2991 break;
2992 }
2993 case 'E':
2994 case 'e':
2995 {
2996 if (LocaleCompare(attribute,"expression") == 0)
2997 {
2998 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00002999 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003000 break;
3001 }
3002 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3003 attribute);
3004 break;
3005 }
3006 default:
3007 {
3008 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3009 attribute);
3010 break;
3011 }
3012 }
3013 }
3014 channel_mask=SetImageChannelMask(image,channel);
3015 image=ChannelFxImage(image,expression,exception);
3016 if (image != (Image *) NULL)
3017 (void) SetImageChannelMask(image,channel_mask);
3018 if (image == (Image *) NULL)
3019 goto PerlException;
3020 for ( ; image; image=image->next)
3021 {
3022 AddImageToRegistry(sv,image);
3023 rv=newRV(sv);
3024 av_push(av,sv_bless(rv,hv));
3025 SvREFCNT_dec(sv);
3026 }
3027 exception=DestroyExceptionInfo(exception);
3028 ST(0)=av_reference;
3029 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3030 XSRETURN(1);
3031
3032 PerlException:
3033 InheritPerlException(exception,perl_exception);
3034 exception=DestroyExceptionInfo(exception);
3035 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3036 SvPOK_on(perl_exception);
3037 ST(0)=sv_2mortal(perl_exception);
3038 XSRETURN(1);
3039 }
3040
3041#
3042###############################################################################
3043# #
3044# #
3045# #
3046# C l o n e #
3047# #
3048# #
3049# #
3050###############################################################################
3051#
3052#
3053void
3054Clone(ref)
3055 Image::Magick ref=NO_INIT
3056 ALIAS:
3057 CopyImage = 1
3058 copy = 2
3059 copyimage = 3
3060 CloneImage = 4
3061 clone = 5
3062 cloneimage = 6
3063 Clone = 7
3064 PPCODE:
3065 {
3066 AV
3067 *av;
3068
3069 ExceptionInfo
3070 *exception;
3071
3072 HV
3073 *hv;
3074
3075 Image
3076 *clone,
3077 *image;
3078
3079 struct PackageInfo
3080 *info;
3081
3082 SV
3083 *perl_exception,
3084 *reference,
3085 *rv,
3086 *sv;
3087
3088 PERL_UNUSED_VAR(ref);
3089 PERL_UNUSED_VAR(ix);
3090 exception=AcquireExceptionInfo();
3091 perl_exception=newSVpv("",0);
3092 sv=NULL;
3093 if (sv_isobject(ST(0)) == 0)
3094 {
3095 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3096 PackageName);
3097 goto PerlException;
3098 }
3099 reference=SvRV(ST(0));
3100 hv=SvSTASH(reference);
3101 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3102 if (image == (Image *) NULL)
3103 {
3104 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3105 PackageName);
3106 goto PerlException;
3107 }
3108 /*
3109 Create blessed Perl array for the returned image.
3110 */
3111 av=newAV();
3112 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3113 SvREFCNT_dec(av);
3114 for ( ; image; image=image->next)
3115 {
3116 clone=CloneImage(image,0,0,MagickTrue,exception);
3117 if (clone == (Image *) NULL)
3118 break;
3119 AddImageToRegistry(sv,clone);
3120 rv=newRV(sv);
3121 av_push(av,sv_bless(rv,hv));
3122 SvREFCNT_dec(sv);
3123 }
3124 exception=DestroyExceptionInfo(exception);
3125 SvREFCNT_dec(perl_exception);
3126 XSRETURN(1);
3127
3128 PerlException:
3129 InheritPerlException(exception,perl_exception);
3130 exception=DestroyExceptionInfo(exception);
3131 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3132 SvPOK_on(perl_exception);
3133 ST(0)=sv_2mortal(perl_exception);
3134 XSRETURN(1);
3135 }
3136
3137#
3138###############################################################################
3139# #
3140# #
3141# #
3142# C L O N E #
3143# #
3144# #
3145# #
3146###############################################################################
3147#
3148#
3149void
3150CLONE(ref,...)
3151 SV *ref;
3152 CODE:
3153 {
3154 PERL_UNUSED_VAR(ref);
3155 if (magick_registry != (SplayTreeInfo *) NULL)
3156 {
3157 register Image
3158 *p;
3159
3160 ResetSplayTreeIterator(magick_registry);
3161 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3162 while (p != (Image *) NULL)
3163 {
3164 ReferenceImage(p);
3165 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3166 }
3167 }
3168 }
3169
3170#
3171###############################################################################
3172# #
3173# #
3174# #
3175# C o a l e s c e #
3176# #
3177# #
3178# #
3179###############################################################################
3180#
3181#
3182void
3183Coalesce(ref)
3184 Image::Magick ref=NO_INIT
3185 ALIAS:
3186 CoalesceImage = 1
3187 coalesce = 2
3188 coalesceimage = 3
3189 PPCODE:
3190 {
3191 AV
3192 *av;
3193
3194 ExceptionInfo
3195 *exception;
3196
3197 HV
3198 *hv;
3199
3200 Image
3201 *image;
3202
3203 struct PackageInfo
3204 *info;
3205
3206 SV
3207 *av_reference,
3208 *perl_exception,
3209 *reference,
3210 *rv,
3211 *sv;
3212
3213 PERL_UNUSED_VAR(ref);
3214 PERL_UNUSED_VAR(ix);
3215 exception=AcquireExceptionInfo();
3216 perl_exception=newSVpv("",0);
3217 sv=NULL;
3218 if (sv_isobject(ST(0)) == 0)
3219 {
3220 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3221 PackageName);
3222 goto PerlException;
3223 }
3224 reference=SvRV(ST(0));
3225 hv=SvSTASH(reference);
3226 av=newAV();
3227 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3228 SvREFCNT_dec(av);
3229 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3230 if (image == (Image *) NULL)
3231 {
3232 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3233 PackageName);
3234 goto PerlException;
3235 }
3236 image=CoalesceImages(image,exception);
3237 if (image == (Image *) NULL)
3238 goto PerlException;
3239 for ( ; image; image=image->next)
3240 {
3241 AddImageToRegistry(sv,image);
3242 rv=newRV(sv);
3243 av_push(av,sv_bless(rv,hv));
3244 SvREFCNT_dec(sv);
3245 }
3246 exception=DestroyExceptionInfo(exception);
3247 ST(0)=av_reference;
3248 SvREFCNT_dec(perl_exception);
3249 XSRETURN(1);
3250
3251 PerlException:
3252 InheritPerlException(exception,perl_exception);
3253 exception=DestroyExceptionInfo(exception);
3254 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3255 SvPOK_on(perl_exception);
3256 ST(0)=sv_2mortal(perl_exception);
3257 XSRETURN(1);
3258 }
3259
3260#
3261###############################################################################
3262# #
3263# #
3264# #
3265# C o m p a r e #
3266# #
3267# #
3268# #
3269###############################################################################
3270#
3271#
3272void
3273Compare(ref,...)
3274 Image::Magick ref=NO_INIT
3275 ALIAS:
3276 CompareImages = 1
3277 compare = 2
3278 compareimage = 3
3279 PPCODE:
3280 {
3281 AV
3282 *av;
3283
3284 char
3285 *attribute;
3286
3287 double
3288 distortion;
3289
3290 ExceptionInfo
3291 *exception;
3292
3293 HV
3294 *hv;
3295
3296 Image
3297 *difference_image,
3298 *image,
3299 *reconstruct_image;
3300
3301 MetricType
3302 metric;
3303
3304 register ssize_t
3305 i;
3306
3307 ssize_t
3308 option;
3309
3310 struct PackageInfo
3311 *info;
3312
3313 SV
3314 *av_reference,
3315 *perl_exception,
3316 *reference,
3317 *rv,
3318 *sv;
3319
3320 PERL_UNUSED_VAR(ref);
3321 PERL_UNUSED_VAR(ix);
3322 exception=AcquireExceptionInfo();
3323 perl_exception=newSVpv("",0);
3324 sv=NULL;
3325 av=NULL;
3326 attribute=NULL;
3327 if (sv_isobject(ST(0)) == 0)
3328 {
3329 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3330 PackageName);
3331 goto PerlException;
3332 }
3333 reference=SvRV(ST(0));
3334 hv=SvSTASH(reference);
3335 av=newAV();
3336 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3337 SvREFCNT_dec(av);
3338 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3339 if (image == (Image *) NULL)
3340 {
3341 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3342 PackageName);
3343 goto PerlException;
3344 }
3345 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3346 /*
3347 Get attribute.
3348 */
3349 reconstruct_image=image;
3350 metric=RootMeanSquaredErrorMetric;
3351 for (i=2; i < items; i+=2)
3352 {
3353 attribute=(char *) SvPV(ST(i-1),na);
3354 switch (*attribute)
3355 {
3356 case 'C':
3357 case 'c':
3358 {
3359 if (LocaleCompare(attribute,"channel") == 0)
3360 {
3361 ssize_t
3362 option;
3363
3364 option=ParseChannelOption(SvPV(ST(i),na));
3365 if (option < 0)
3366 {
3367 ThrowPerlException(exception,OptionError,
3368 "UnrecognizedType",SvPV(ST(i),na));
3369 return;
3370 }
cristybcd59342015-06-07 14:07:19 +00003371 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003372 break;
3373 }
3374 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3375 attribute);
3376 break;
3377 }
3378 case 'F':
3379 case 'f':
3380 {
3381 if (LocaleCompare(attribute,"fuzz") == 0)
3382 {
3383 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3384 break;
3385 }
3386 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3387 attribute);
3388 break;
3389 }
3390 case 'I':
3391 case 'i':
3392 {
3393 if (LocaleCompare(attribute,"image") == 0)
3394 {
3395 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3396 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3397 break;
3398 }
3399 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3400 attribute);
3401 break;
3402 }
3403 case 'M':
3404 case 'm':
3405 {
3406 if (LocaleCompare(attribute,"metric") == 0)
3407 {
3408 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3409 SvPV(ST(i),na));
3410 if (option < 0)
3411 {
3412 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3413 SvPV(ST(i),na));
3414 break;
3415 }
3416 metric=(MetricType) option;
3417 break;
3418 }
3419 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3420 attribute);
3421 break;
3422 }
3423 default:
3424 {
3425 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3426 attribute);
3427 break;
3428 }
3429 }
3430 }
3431 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3432 exception);
3433 if (difference_image != (Image *) NULL)
3434 {
3435 difference_image->error.mean_error_per_pixel=distortion;
3436 AddImageToRegistry(sv,difference_image);
3437 rv=newRV(sv);
3438 av_push(av,sv_bless(rv,hv));
3439 SvREFCNT_dec(sv);
3440 }
3441 exception=DestroyExceptionInfo(exception);
3442 ST(0)=av_reference;
3443 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3444 XSRETURN(1);
3445
3446 PerlException:
3447 InheritPerlException(exception,perl_exception);
3448 exception=DestroyExceptionInfo(exception);
3449 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3450 SvPOK_on(perl_exception);
3451 ST(0)=sv_2mortal(perl_exception);
3452 XSRETURN(1);
3453 }
3454
3455#
3456###############################################################################
3457# #
3458# #
3459# #
cristy15655332013-10-06 00:27:33 +00003460# C o m p l e x I m a g e s #
3461# #
3462# #
3463# #
3464###############################################################################
3465#
3466#
3467void
3468ComplexImages(ref)
3469 Image::Magick ref=NO_INIT
3470 ALIAS:
3471 ComplexImages = 1
3472 compleximages = 2
3473 PPCODE:
3474 {
3475 AV
3476 *av;
3477
3478 char
3479 *attribute,
3480 *p;
3481
cristyfa21e9e2013-10-07 10:37:38 +00003482 ComplexOperator
3483 op;
3484
cristy15655332013-10-06 00:27:33 +00003485 ExceptionInfo
3486 *exception;
3487
3488 HV
3489 *hv;
3490
3491 Image
3492 *image;
3493
cristy15655332013-10-06 00:27:33 +00003494 register ssize_t
3495 i;
3496
3497 struct PackageInfo
3498 *info;
3499
3500 SV
3501 *perl_exception,
3502 *reference,
3503 *rv,
3504 *sv;
3505
3506 PERL_UNUSED_VAR(ref);
3507 PERL_UNUSED_VAR(ix);
3508 exception=AcquireExceptionInfo();
3509 perl_exception=newSVpv("",0);
3510 sv=NULL;
3511 if (sv_isobject(ST(0)) == 0)
3512 {
3513 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3514 PackageName);
3515 goto PerlException;
3516 }
3517 reference=SvRV(ST(0));
3518 hv=SvSTASH(reference);
3519 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3520 if (image == (Image *) NULL)
3521 {
3522 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3523 PackageName);
3524 goto PerlException;
3525 }
cristyfd168722013-10-07 15:59:31 +00003526 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003527 if (items == 2)
3528 {
3529 ssize_t
3530 in;
3531
3532 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3533 SvPV(ST(1),na));
3534 if (in < 0)
3535 {
3536 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3537 SvPV(ST(1),na));
3538 return;
3539 }
cristyfa21e9e2013-10-07 10:37:38 +00003540 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003541 }
3542 else
3543 for (i=2; i < items; i+=2)
3544 {
3545 attribute=(char *) SvPV(ST(i-1),na);
3546 switch (*attribute)
3547 {
3548 case 'O':
3549 case 'o':
3550 {
3551 if (LocaleCompare(attribute,"operator") == 0)
3552 {
3553 ssize_t
3554 in;
3555
3556 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3557 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3558 if (in < 0)
3559 {
3560 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3561 SvPV(ST(i),na));
3562 return;
3563 }
cristyfa21e9e2013-10-07 10:37:38 +00003564 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003565 break;
3566 }
3567 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3568 attribute);
3569 break;
3570 }
3571 default:
3572 {
3573 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3574 attribute);
3575 break;
3576 }
3577 }
3578 }
3579 image=ComplexImages(image,op,exception);
3580 if (image == (Image *) NULL)
3581 goto PerlException;
3582 /*
3583 Create blessed Perl array for the returned image.
3584 */
3585 av=newAV();
3586 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3587 SvREFCNT_dec(av);
3588 AddImageToRegistry(sv,image);
3589 rv=newRV(sv);
3590 av_push(av,sv_bless(rv,hv));
3591 SvREFCNT_dec(sv);
3592 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003593 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3594 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003595 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3596 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003597 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003598 SetImageInfo(info->image_info,0,exception);
3599 exception=DestroyExceptionInfo(exception);
3600 SvREFCNT_dec(perl_exception);
3601 XSRETURN(1);
3602
3603 PerlException:
3604 InheritPerlException(exception,perl_exception);
3605 exception=DestroyExceptionInfo(exception);
3606 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3607 SvPOK_on(perl_exception);
3608 ST(0)=sv_2mortal(perl_exception);
3609 XSRETURN(1);
3610 }
3611
3612#
3613###############################################################################
3614# #
3615# #
3616# #
cristy4a3ce0a2013-08-03 20:06:59 +00003617# C o m p a r e L a y e r s #
3618# #
3619# #
3620# #
3621###############################################################################
3622#
3623#
3624void
3625CompareLayers(ref)
3626 Image::Magick ref=NO_INIT
3627 ALIAS:
3628 CompareImagesLayers = 1
3629 comparelayers = 2
3630 compareimagelayers = 3
3631 PPCODE:
3632 {
3633 AV
3634 *av;
3635
3636 char
3637 *attribute;
3638
3639 ExceptionInfo
3640 *exception;
3641
3642 HV
3643 *hv;
3644
3645 Image
3646 *image;
3647
3648 LayerMethod
3649 method;
3650
3651 register ssize_t
3652 i;
3653
3654 ssize_t
3655 option;
3656
3657 struct PackageInfo
3658 *info;
3659
3660 SV
3661 *av_reference,
3662 *perl_exception,
3663 *reference,
3664 *rv,
3665 *sv;
3666
3667 PERL_UNUSED_VAR(ref);
3668 PERL_UNUSED_VAR(ix);
3669 exception=AcquireExceptionInfo();
3670 perl_exception=newSVpv("",0);
3671 sv=NULL;
3672 if (sv_isobject(ST(0)) == 0)
3673 {
3674 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3675 PackageName);
3676 goto PerlException;
3677 }
3678 reference=SvRV(ST(0));
3679 hv=SvSTASH(reference);
3680 av=newAV();
3681 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3682 SvREFCNT_dec(av);
3683 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3684 if (image == (Image *) NULL)
3685 {
3686 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3687 PackageName);
3688 goto PerlException;
3689 }
3690 method=CompareAnyLayer;
3691 for (i=2; i < items; i+=2)
3692 {
3693 attribute=(char *) SvPV(ST(i-1),na);
3694 switch (*attribute)
3695 {
3696 case 'M':
3697 case 'm':
3698 {
3699 if (LocaleCompare(attribute,"method") == 0)
3700 {
3701 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3702 SvPV(ST(i),na));
3703 if (option < 0)
3704 {
3705 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3706 SvPV(ST(i),na));
3707 break;
3708 }
3709 method=(LayerMethod) option;
3710 break;
3711 }
3712 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3713 attribute);
3714 break;
3715 }
3716 default:
3717 {
3718 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3719 attribute);
3720 break;
3721 }
3722 }
3723 }
3724 image=CompareImagesLayers(image,method,exception);
3725 if (image == (Image *) NULL)
3726 goto PerlException;
3727 for ( ; image; image=image->next)
3728 {
3729 AddImageToRegistry(sv,image);
3730 rv=newRV(sv);
3731 av_push(av,sv_bless(rv,hv));
3732 SvREFCNT_dec(sv);
3733 }
3734 exception=DestroyExceptionInfo(exception);
3735 ST(0)=av_reference;
3736 SvREFCNT_dec(perl_exception);
3737 XSRETURN(1);
3738
3739 PerlException:
3740 InheritPerlException(exception,perl_exception);
3741 exception=DestroyExceptionInfo(exception);
3742 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3743 SvPOK_on(perl_exception);
3744 ST(0)=sv_2mortal(perl_exception);
3745 XSRETURN(1);
3746 }
3747
3748#
3749###############################################################################
3750# #
3751# #
3752# #
3753# D e s t r o y #
3754# #
3755# #
3756# #
3757###############################################################################
3758#
3759#
3760void
3761DESTROY(ref)
3762 Image::Magick ref=NO_INIT
3763 PPCODE:
3764 {
3765 SV
3766 *reference;
3767
3768 PERL_UNUSED_VAR(ref);
3769 if (sv_isobject(ST(0)) == 0)
3770 croak("ReferenceIsNotMyType");
3771 reference=SvRV(ST(0));
3772 switch (SvTYPE(reference))
3773 {
3774 case SVt_PVAV:
3775 {
3776 char
cristy151b66d2015-04-15 10:50:31 +00003777 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003778
3779 const SV
3780 *key;
3781
3782 HV
3783 *hv;
3784
3785 GV
3786 **gvp;
3787
3788 struct PackageInfo
3789 *info;
3790
3791 SV
3792 *sv;
3793
3794 /*
3795 Array (AV *) reference
3796 */
cristy151b66d2015-04-15 10:50:31 +00003797 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003798 XS_VERSION,reference);
3799 hv=gv_stashpv(PackageName, FALSE);
3800 if (!hv)
3801 break;
3802 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3803 if (!gvp)
3804 break;
3805 sv=GvSV(*gvp);
3806 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3807 {
3808 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3809 DestroyPackageInfo(info);
3810 }
3811 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3812 (void) key;
3813 break;
3814 }
3815 case SVt_PVMG:
3816 {
3817 Image
3818 *image;
3819
3820 /*
3821 Blessed scalar = (Image *) SvIV(reference)
3822 */
3823 image=INT2PTR(Image *,SvIV(reference));
3824 if (image != (Image *) NULL)
3825 DeleteImageFromRegistry(reference,image);
3826 break;
3827 }
3828 default:
3829 break;
3830 }
3831 }
3832
3833#
3834###############################################################################
3835# #
3836# #
3837# #
3838# D i s p l a y #
3839# #
3840# #
3841# #
3842###############################################################################
3843#
3844#
3845void
3846Display(ref,...)
3847 Image::Magick ref=NO_INIT
3848 ALIAS:
3849 DisplayImage = 1
3850 display = 2
3851 displayimage = 3
3852 PPCODE:
3853 {
3854 ExceptionInfo
3855 *exception;
3856
3857 Image
3858 *image;
3859
3860 register ssize_t
3861 i;
3862
3863 struct PackageInfo
3864 *info,
3865 *package_info;
3866
3867 SV
3868 *perl_exception,
3869 *reference;
3870
3871 PERL_UNUSED_VAR(ref);
3872 PERL_UNUSED_VAR(ix);
3873 exception=AcquireExceptionInfo();
3874 perl_exception=newSVpv("",0);
3875 package_info=(struct PackageInfo *) NULL;
3876 if (sv_isobject(ST(0)) == 0)
3877 {
3878 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3879 PackageName);
3880 goto PerlException;
3881 }
3882 reference=SvRV(ST(0));
3883 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3884 if (image == (Image *) NULL)
3885 {
3886 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3887 PackageName);
3888 goto PerlException;
3889 }
3890 package_info=ClonePackageInfo(info,exception);
3891 if (items == 2)
3892 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3893 else
3894 if (items > 2)
3895 for (i=2; i < items; i+=2)
3896 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3897 exception);
3898 (void) DisplayImages(package_info->image_info,image,exception);
3899 (void) CatchImageException(image);
3900
3901 PerlException:
3902 if (package_info != (struct PackageInfo *) NULL)
3903 DestroyPackageInfo(package_info);
3904 InheritPerlException(exception,perl_exception);
3905 exception=DestroyExceptionInfo(exception);
3906 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3907 SvPOK_on(perl_exception);
3908 ST(0)=sv_2mortal(perl_exception);
3909 XSRETURN(1);
3910 }
3911
3912#
3913###############################################################################
3914# #
3915# #
3916# #
3917# E v a l u a t e I m a g e s #
3918# #
3919# #
3920# #
3921###############################################################################
3922#
3923#
3924void
3925EvaluateImages(ref)
3926 Image::Magick ref=NO_INIT
3927 ALIAS:
3928 EvaluateImages = 1
3929 evaluateimages = 2
3930 PPCODE:
3931 {
3932 AV
3933 *av;
3934
3935 char
3936 *attribute,
3937 *p;
3938
3939 ExceptionInfo
3940 *exception;
3941
3942 HV
3943 *hv;
3944
3945 Image
3946 *image;
3947
3948 MagickEvaluateOperator
3949 op;
3950
3951 register ssize_t
3952 i;
3953
3954 struct PackageInfo
3955 *info;
3956
3957 SV
3958 *perl_exception,
3959 *reference,
3960 *rv,
3961 *sv;
3962
3963 PERL_UNUSED_VAR(ref);
3964 PERL_UNUSED_VAR(ix);
3965 exception=AcquireExceptionInfo();
3966 perl_exception=newSVpv("",0);
3967 sv=NULL;
3968 if (sv_isobject(ST(0)) == 0)
3969 {
3970 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3971 PackageName);
3972 goto PerlException;
3973 }
3974 reference=SvRV(ST(0));
3975 hv=SvSTASH(reference);
3976 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3977 if (image == (Image *) NULL)
3978 {
3979 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3980 PackageName);
3981 goto PerlException;
3982 }
3983 op=MeanEvaluateOperator;
3984 if (items == 2)
3985 {
3986 ssize_t
3987 in;
3988
3989 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
3990 SvPV(ST(1),na));
3991 if (in < 0)
3992 {
3993 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3994 SvPV(ST(1),na));
3995 return;
3996 }
3997 op=(MagickEvaluateOperator) in;
3998 }
3999 else
4000 for (i=2; i < items; i+=2)
4001 {
4002 attribute=(char *) SvPV(ST(i-1),na);
4003 switch (*attribute)
4004 {
4005 case 'O':
4006 case 'o':
4007 {
4008 if (LocaleCompare(attribute,"operator") == 0)
4009 {
4010 ssize_t
4011 in;
4012
4013 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4014 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4015 if (in < 0)
4016 {
4017 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4018 SvPV(ST(i),na));
4019 return;
4020 }
4021 op=(MagickEvaluateOperator) in;
4022 break;
4023 }
4024 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4025 attribute);
4026 break;
4027 }
4028 default:
4029 {
4030 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4031 attribute);
4032 break;
4033 }
4034 }
4035 }
4036 image=EvaluateImages(image,op,exception);
4037 if (image == (Image *) NULL)
4038 goto PerlException;
4039 /*
4040 Create blessed Perl array for the returned image.
4041 */
4042 av=newAV();
4043 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4044 SvREFCNT_dec(av);
4045 AddImageToRegistry(sv,image);
4046 rv=newRV(sv);
4047 av_push(av,sv_bless(rv,hv));
4048 SvREFCNT_dec(sv);
4049 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004050 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4051 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004052 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4053 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004054 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004055 SetImageInfo(info->image_info,0,exception);
4056 exception=DestroyExceptionInfo(exception);
4057 SvREFCNT_dec(perl_exception);
4058 XSRETURN(1);
4059
4060 PerlException:
4061 InheritPerlException(exception,perl_exception);
4062 exception=DestroyExceptionInfo(exception);
4063 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4064 SvPOK_on(perl_exception);
4065 ST(0)=sv_2mortal(perl_exception);
4066 XSRETURN(1);
4067 }
4068
4069#
4070###############################################################################
4071# #
4072# #
4073# #
4074# F e a t u r e s #
4075# #
4076# #
4077# #
4078###############################################################################
4079#
4080#
4081void
4082Features(ref,...)
4083 Image::Magick ref=NO_INIT
4084 ALIAS:
4085 FeaturesImage = 1
4086 features = 2
4087 featuresimage = 3
4088 PPCODE:
4089 {
4090#define ChannelFeatures(channel,direction) \
4091{ \
cristy151b66d2015-04-15 10:50:31 +00004092 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004093 channel_features[channel].angular_second_moment[direction]); \
4094 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004095 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004096 channel_features[channel].contrast[direction]); \
4097 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004098 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004099 channel_features[channel].contrast[direction]); \
4100 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004101 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004102 channel_features[channel].variance_sum_of_squares[direction]); \
4103 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004104 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004105 channel_features[channel].inverse_difference_moment[direction]); \
4106 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004107 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004108 channel_features[channel].sum_average[direction]); \
4109 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004110 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004111 channel_features[channel].sum_variance[direction]); \
4112 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004113 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004114 channel_features[channel].sum_entropy[direction]); \
4115 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004116 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004117 channel_features[channel].entropy[direction]); \
4118 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004119 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004120 channel_features[channel].difference_variance[direction]); \
4121 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004122 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004123 channel_features[channel].difference_entropy[direction]); \
4124 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004125 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004126 channel_features[channel].measure_of_correlation_1[direction]); \
4127 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004128 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004129 channel_features[channel].measure_of_correlation_2[direction]); \
4130 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004131 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004132 channel_features[channel].maximum_correlation_coefficient[direction]); \
4133 PUSHs(sv_2mortal(newSVpv(message,0))); \
4134}
4135
4136 AV
4137 *av;
4138
4139 char
4140 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004141 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004142
4143 ChannelFeatures
4144 *channel_features;
4145
4146 double
4147 distance;
4148
4149 ExceptionInfo
4150 *exception;
4151
4152 Image
4153 *image;
4154
4155 register ssize_t
4156 i;
4157
4158 ssize_t
4159 count;
4160
4161 struct PackageInfo
4162 *info;
4163
4164 SV
4165 *perl_exception,
4166 *reference;
4167
4168 PERL_UNUSED_VAR(ref);
4169 PERL_UNUSED_VAR(ix);
4170 exception=AcquireExceptionInfo();
4171 perl_exception=newSVpv("",0);
4172 av=NULL;
4173 if (sv_isobject(ST(0)) == 0)
4174 {
4175 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4176 PackageName);
4177 goto PerlException;
4178 }
4179 reference=SvRV(ST(0));
4180 av=newAV();
4181 SvREFCNT_dec(av);
4182 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4183 if (image == (Image *) NULL)
4184 {
4185 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4186 PackageName);
4187 goto PerlException;
4188 }
cristy7dbd9262014-07-02 17:53:42 +00004189 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004190 for (i=2; i < items; i+=2)
4191 {
4192 attribute=(char *) SvPV(ST(i-1),na);
4193 switch (*attribute)
4194 {
4195 case 'D':
4196 case 'd':
4197 {
4198 if (LocaleCompare(attribute,"distance") == 0)
4199 {
4200 distance=StringToLong((char *) SvPV(ST(1),na));
4201 break;
4202 }
4203 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4204 attribute);
4205 break;
4206 }
4207 default:
4208 {
4209 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4210 attribute);
4211 break;
4212 }
4213 }
4214 }
4215 count=0;
4216 for ( ; image; image=image->next)
4217 {
4218 channel_features=GetImageFeatures(image,distance,exception);
4219 if (channel_features == (ChannelFeatures *) NULL)
4220 continue;
4221 count++;
cristyfcf3bdf2014-07-02 14:35:58 +00004222 EXTEND(sp,280*count);
cristy4a3ce0a2013-08-03 20:06:59 +00004223 for (i=0; i < 4; i++)
4224 {
4225 ChannelFeatures(RedChannel,i);
4226 ChannelFeatures(GreenChannel,i);
4227 ChannelFeatures(BlueChannel,i);
4228 if (image->colorspace == CMYKColorspace)
4229 ChannelFeatures(BlackChannel,i);
cristy17f11b02014-12-20 19:37:04 +00004230 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00004231 ChannelFeatures(AlphaChannel,i);
4232 }
4233 channel_features=(ChannelFeatures *)
4234 RelinquishMagickMemory(channel_features);
4235 }
4236
4237 PerlException:
4238 InheritPerlException(exception,perl_exception);
4239 exception=DestroyExceptionInfo(exception);
4240 SvREFCNT_dec(perl_exception);
4241 }
4242
4243#
4244###############################################################################
4245# #
4246# #
4247# #
4248# F l a t t e n #
4249# #
4250# #
4251# #
4252###############################################################################
4253#
4254#
4255void
4256Flatten(ref)
4257 Image::Magick ref=NO_INIT
4258 ALIAS:
4259 FlattenImage = 1
4260 flatten = 2
4261 flattenimage = 3
4262 PPCODE:
4263 {
4264 AV
4265 *av;
4266
4267 char
4268 *attribute,
4269 *p;
4270
4271 ExceptionInfo
4272 *exception;
4273
4274 HV
4275 *hv;
4276
4277 Image
4278 *image;
4279
4280 PixelInfo
4281 background_color;
4282
4283 register ssize_t
4284 i;
4285
4286 struct PackageInfo
4287 *info;
4288
4289 SV
4290 *perl_exception,
4291 *reference,
4292 *rv,
4293 *sv;
4294
4295 PERL_UNUSED_VAR(ref);
4296 PERL_UNUSED_VAR(ix);
4297 exception=AcquireExceptionInfo();
4298 perl_exception=newSVpv("",0);
4299 sv=NULL;
4300 if (sv_isobject(ST(0)) == 0)
4301 {
4302 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4303 PackageName);
4304 goto PerlException;
4305 }
4306 reference=SvRV(ST(0));
4307 hv=SvSTASH(reference);
4308 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4309 if (image == (Image *) NULL)
4310 {
4311 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4312 PackageName);
4313 goto PerlException;
4314 }
4315 background_color=image->background_color;
4316 if (items == 2)
4317 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4318 &background_color,exception);
4319 else
4320 for (i=2; i < items; i+=2)
4321 {
4322 attribute=(char *) SvPV(ST(i-1),na);
4323 switch (*attribute)
4324 {
4325 case 'B':
4326 case 'b':
4327 {
4328 if (LocaleCompare(attribute,"background") == 0)
4329 {
4330 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4331 AllCompliance,&background_color,exception);
4332 break;
4333 }
4334 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4335 attribute);
4336 break;
4337 }
4338 default:
4339 {
4340 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4341 attribute);
4342 break;
4343 }
4344 }
4345 }
4346 image->background_color=background_color;
4347 image=MergeImageLayers(image,FlattenLayer,exception);
4348 if (image == (Image *) NULL)
4349 goto PerlException;
4350 /*
4351 Create blessed Perl array for the returned image.
4352 */
4353 av=newAV();
4354 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4355 SvREFCNT_dec(av);
4356 AddImageToRegistry(sv,image);
4357 rv=newRV(sv);
4358 av_push(av,sv_bless(rv,hv));
4359 SvREFCNT_dec(sv);
4360 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004361 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4362 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004363 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4364 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004365 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004366 SetImageInfo(info->image_info,0,exception);
4367 exception=DestroyExceptionInfo(exception);
4368 SvREFCNT_dec(perl_exception);
4369 XSRETURN(1);
4370
4371 PerlException:
4372 InheritPerlException(exception,perl_exception);
4373 exception=DestroyExceptionInfo(exception);
4374 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4375 SvPOK_on(perl_exception); /* return messages in string context */
4376 ST(0)=sv_2mortal(perl_exception);
4377 XSRETURN(1);
4378 }
4379
4380#
4381###############################################################################
4382# #
4383# #
4384# #
4385# F x #
4386# #
4387# #
4388# #
4389###############################################################################
4390#
4391#
4392void
4393Fx(ref,...)
4394 Image::Magick ref=NO_INIT
4395 ALIAS:
4396 FxImage = 1
4397 fx = 2
4398 fximage = 3
4399 PPCODE:
4400 {
4401 AV
4402 *av;
4403
4404 char
4405 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004406 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004407
4408 ChannelType
4409 channel,
4410 channel_mask;
4411
4412 ExceptionInfo
4413 *exception;
4414
4415 HV
4416 *hv;
4417
4418 Image
4419 *image;
4420
4421 register ssize_t
4422 i;
4423
4424 struct PackageInfo
4425 *info;
4426
4427 SV
4428 *av_reference,
4429 *perl_exception,
4430 *reference,
4431 *rv,
4432 *sv;
4433
4434 PERL_UNUSED_VAR(ref);
4435 PERL_UNUSED_VAR(ix);
4436 exception=AcquireExceptionInfo();
4437 perl_exception=newSVpv("",0);
4438 sv=NULL;
4439 attribute=NULL;
4440 av=NULL;
4441 if (sv_isobject(ST(0)) == 0)
4442 {
4443 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4444 PackageName);
4445 goto PerlException;
4446 }
4447 reference=SvRV(ST(0));
4448 hv=SvSTASH(reference);
4449 av=newAV();
4450 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4451 SvREFCNT_dec(av);
4452 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4453 if (image == (Image *) NULL)
4454 {
4455 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4456 PackageName);
4457 goto PerlException;
4458 }
4459 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4460 /*
4461 Get options.
4462 */
4463 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004464 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004465 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004466 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004467 else
4468 for (i=2; i < items; i+=2)
4469 {
4470 attribute=(char *) SvPV(ST(i-1),na);
4471 switch (*attribute)
4472 {
4473 case 'C':
4474 case 'c':
4475 {
4476 if (LocaleCompare(attribute,"channel") == 0)
4477 {
4478 ssize_t
4479 option;
4480
4481 option=ParseChannelOption(SvPV(ST(i),na));
4482 if (option < 0)
4483 {
4484 ThrowPerlException(exception,OptionError,
4485 "UnrecognizedType",SvPV(ST(i),na));
4486 return;
4487 }
4488 channel=(ChannelType) option;
4489 break;
4490 }
4491 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4492 attribute);
4493 break;
4494 }
4495 case 'E':
4496 case 'e':
4497 {
4498 if (LocaleCompare(attribute,"expression") == 0)
4499 {
4500 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004501 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004502 break;
4503 }
4504 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4505 attribute);
4506 break;
4507 }
4508 default:
4509 {
4510 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4511 attribute);
4512 break;
4513 }
4514 }
4515 }
4516 channel_mask=SetImageChannelMask(image,channel);
4517 image=FxImage(image,expression,exception);
4518 if (image != (Image *) NULL)
4519 (void) SetImageChannelMask(image,channel_mask);
4520 if (image == (Image *) NULL)
4521 goto PerlException;
4522 for ( ; image; image=image->next)
4523 {
4524 AddImageToRegistry(sv,image);
4525 rv=newRV(sv);
4526 av_push(av,sv_bless(rv,hv));
4527 SvREFCNT_dec(sv);
4528 }
4529 exception=DestroyExceptionInfo(exception);
4530 ST(0)=av_reference;
4531 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4532 XSRETURN(1);
4533
4534 PerlException:
4535 InheritPerlException(exception,perl_exception);
4536 exception=DestroyExceptionInfo(exception);
4537 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4538 SvPOK_on(perl_exception);
4539 ST(0)=sv_2mortal(perl_exception);
4540 XSRETURN(1);
4541 }
4542
4543#
4544###############################################################################
4545# #
4546# #
4547# #
4548# G e t #
4549# #
4550# #
4551# #
4552###############################################################################
4553#
4554#
4555void
4556Get(ref,...)
4557 Image::Magick ref=NO_INIT
4558 ALIAS:
4559 GetAttributes = 1
4560 GetAttribute = 2
4561 get = 3
4562 getattributes = 4
4563 getattribute = 5
4564 PPCODE:
4565 {
4566 char
4567 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004568 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004569
4570 const char
4571 *value;
4572
4573 ExceptionInfo
4574 *exception;
4575
4576 Image
4577 *image;
4578
4579 long
4580 j;
4581
4582 register ssize_t
4583 i;
4584
4585 struct PackageInfo
4586 *info;
4587
4588 SV
4589 *perl_exception,
4590 *reference,
4591 *s;
4592
4593 PERL_UNUSED_VAR(ref);
4594 PERL_UNUSED_VAR(ix);
4595 exception=AcquireExceptionInfo();
4596 perl_exception=newSVpv("",0);
4597 if (sv_isobject(ST(0)) == 0)
4598 {
4599 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4600 PackageName);
4601 XSRETURN_EMPTY;
4602 }
4603 reference=SvRV(ST(0));
4604 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4605 if (image == (Image *) NULL && !info)
4606 XSRETURN_EMPTY;
4607 EXTEND(sp,items);
4608 for (i=1; i < items; i++)
4609 {
4610 attribute=(char *) SvPV(ST(i),na);
4611 s=NULL;
4612 switch (*attribute)
4613 {
4614 case 'A':
4615 case 'a':
4616 {
4617 if (LocaleCompare(attribute,"adjoin") == 0)
4618 {
4619 if (info)
4620 s=newSViv((ssize_t) info->image_info->adjoin);
4621 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4622 continue;
4623 }
4624 if (LocaleCompare(attribute,"antialias") == 0)
4625 {
4626 if (info)
4627 s=newSViv((ssize_t) info->image_info->antialias);
4628 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4629 continue;
4630 }
4631 if (LocaleCompare(attribute,"area") == 0)
4632 {
4633 s=newSViv(GetMagickResource(AreaResource));
4634 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4635 continue;
4636 }
4637 if (LocaleCompare(attribute,"attenuate") == 0)
4638 {
4639 const char
4640 *value;
4641
4642 value=GetImageProperty(image,attribute,exception);
4643 if (value != (const char *) NULL)
4644 s=newSVpv(value,0);
4645 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4646 continue;
4647 }
4648 if (LocaleCompare(attribute,"authenticate") == 0)
4649 {
4650 if (info)
4651 {
4652 const char
4653 *option;
4654
4655 option=GetImageOption(info->image_info,attribute);
4656 if (option != (const char *) NULL)
4657 s=newSVpv(option,0);
4658 }
4659 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4660 continue;
4661 }
4662 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4663 attribute);
4664 break;
4665 }
4666 case 'B':
4667 case 'b':
4668 {
4669 if (LocaleCompare(attribute,"background") == 0)
4670 {
4671 if (image == (Image *) NULL)
4672 break;
cristy151b66d2015-04-15 10:50:31 +00004673 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004674 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4675 (double) image->background_color.green,
4676 (double) image->background_color.blue,
4677 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004678 s=newSVpv(color,0);
4679 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4680 continue;
4681 }
4682 if (LocaleCompare(attribute,"base-columns") == 0)
4683 {
4684 if (image != (Image *) NULL)
4685 s=newSViv((ssize_t) image->magick_columns);
4686 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4687 continue;
4688 }
4689 if (LocaleCompare(attribute,"base-filename") == 0)
4690 {
4691 if (image != (Image *) NULL)
4692 s=newSVpv(image->magick_filename,0);
4693 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4694 continue;
4695 }
4696 if (LocaleCompare(attribute,"base-height") == 0)
4697 {
4698 if (image != (Image *) NULL)
4699 s=newSViv((ssize_t) image->magick_rows);
4700 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4701 continue;
4702 }
4703 if (LocaleCompare(attribute,"base-rows") == 0)
4704 {
4705 if (image != (Image *) NULL)
4706 s=newSViv((ssize_t) image->magick_rows);
4707 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4708 continue;
4709 }
4710 if (LocaleCompare(attribute,"base-width") == 0)
4711 {
4712 if (image != (Image *) NULL)
4713 s=newSViv((ssize_t) image->magick_columns);
4714 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4715 continue;
4716 }
4717 if (LocaleCompare(attribute,"blue-primary") == 0)
4718 {
4719 if (image == (Image *) NULL)
4720 break;
cristy151b66d2015-04-15 10:50:31 +00004721 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00004722 image->chromaticity.blue_primary.x,
4723 image->chromaticity.blue_primary.y);
4724 s=newSVpv(color,0);
4725 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4726 continue;
4727 }
4728 if (LocaleCompare(attribute,"bordercolor") == 0)
4729 {
4730 if (image == (Image *) NULL)
4731 break;
cristy151b66d2015-04-15 10:50:31 +00004732 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004733 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4734 (double) image->border_color.green,
4735 (double) image->border_color.blue,
4736 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004737 s=newSVpv(color,0);
4738 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4739 continue;
4740 }
4741 if (LocaleCompare(attribute,"bounding-box") == 0)
4742 {
4743 char
cristy151b66d2015-04-15 10:50:31 +00004744 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004745
4746 RectangleInfo
4747 page;
4748
4749 if (image == (Image *) NULL)
4750 break;
4751 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004752 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004753 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4754 page.height,(double) page.x,(double) page.y);
4755 s=newSVpv(geometry,0);
4756 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4757 continue;
4758 }
4759 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4760 attribute);
4761 break;
4762 }
4763 case 'C':
4764 case 'c':
4765 {
4766 if (LocaleCompare(attribute,"class") == 0)
4767 {
4768 if (image == (Image *) NULL)
4769 break;
4770 s=newSViv(image->storage_class);
4771 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4772 image->storage_class));
4773 SvIOK_on(s);
4774 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4775 continue;
4776 }
4777 if (LocaleCompare(attribute,"clip-mask") == 0)
4778 {
4779 if (image != (Image *) NULL)
4780 {
4781 Image
4782 *mask_image;
4783
4784 SV
4785 *sv;
4786
4787 sv=NULL;
4788 if (image->read_mask == MagickFalse)
4789 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004790 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004791 if (mask_image != (Image *) NULL)
4792 {
4793 AddImageToRegistry(sv,mask_image);
4794 s=sv_bless(newRV(sv),SvSTASH(reference));
4795 }
4796 }
4797 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4798 continue;
4799 }
4800 if (LocaleCompare(attribute,"clip-path") == 0)
4801 {
4802 if (image != (Image *) NULL)
4803 {
4804 Image
4805 *mask_image;
4806
4807 SV
4808 *sv;
4809
4810 sv=NULL;
4811 if (image->read_mask != MagickFalse)
4812 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004813 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004814 if (mask_image != (Image *) NULL)
4815 {
4816 AddImageToRegistry(sv,mask_image);
4817 s=sv_bless(newRV(sv),SvSTASH(reference));
4818 }
4819 }
4820 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4821 continue;
4822 }
4823 if (LocaleCompare(attribute,"compression") == 0)
4824 {
4825 j=info ? info->image_info->compression : image ?
4826 image->compression : UndefinedCompression;
4827 if (info)
4828 if (info->image_info->compression == UndefinedCompression)
4829 j=image->compression;
4830 s=newSViv(j);
4831 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4832 j));
4833 SvIOK_on(s);
4834 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4835 continue;
4836 }
4837 if (LocaleCompare(attribute,"colorspace") == 0)
4838 {
4839 j=image ? image->colorspace : RGBColorspace;
4840 s=newSViv(j);
4841 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4842 j));
4843 SvIOK_on(s);
4844 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4845 continue;
4846 }
4847 if (LocaleCompare(attribute,"colors") == 0)
4848 {
4849 if (image != (Image *) NULL)
4850 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4851 exception));
4852 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4853 continue;
4854 }
4855 if (LocaleNCompare(attribute,"colormap",8) == 0)
4856 {
4857 int
4858 items;
4859
4860 if (image == (Image *) NULL || !image->colormap)
4861 break;
4862 j=0;
4863 items=sscanf(attribute,"%*[^[][%ld",&j);
4864 (void) items;
4865 if (j > (ssize_t) image->colors)
4866 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004867 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004868 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4869 (double) image->colormap[j].green,
4870 (double) image->colormap[j].blue,
4871 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004872 s=newSVpv(color,0);
4873 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4874 continue;
4875 }
4876 if (LocaleCompare(attribute,"columns") == 0)
4877 {
4878 if (image != (Image *) NULL)
4879 s=newSViv((ssize_t) image->columns);
4880 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4881 continue;
4882 }
4883 if (LocaleCompare(attribute,"comment") == 0)
4884 {
4885 const char
4886 *value;
4887
4888 value=GetImageProperty(image,attribute,exception);
4889 if (value != (const char *) NULL)
4890 s=newSVpv(value,0);
4891 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4892 continue;
4893 }
4894 if (LocaleCompare(attribute,"copyright") == 0)
4895 {
4896 s=newSVpv(GetMagickCopyright(),0);
4897 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4898 continue;
4899 }
4900 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4901 attribute);
4902 break;
4903 }
4904 case 'D':
4905 case 'd':
4906 {
4907 if (LocaleCompare(attribute,"density") == 0)
4908 {
4909 char
cristy151b66d2015-04-15 10:50:31 +00004910 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004911
4912 if (image == (Image *) NULL)
4913 break;
cristy151b66d2015-04-15 10:50:31 +00004914 (void) FormatLocaleString(geometry,MagickPathExtent,"%.15gx%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00004915 image->resolution.x,image->resolution.y);
4916 s=newSVpv(geometry,0);
4917 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4918 continue;
4919 }
4920 if (LocaleCompare(attribute,"delay") == 0)
4921 {
4922 if (image != (Image *) NULL)
4923 s=newSViv((ssize_t) image->delay);
4924 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4925 continue;
4926 }
4927 if (LocaleCompare(attribute,"depth") == 0)
4928 {
4929 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4930 if (image != (Image *) NULL)
4931 s=newSViv((ssize_t) GetImageDepth(image,exception));
4932 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4933 continue;
4934 }
4935 if (LocaleCompare(attribute,"directory") == 0)
4936 {
4937 if (image && image->directory)
4938 s=newSVpv(image->directory,0);
4939 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4940 continue;
4941 }
4942 if (LocaleCompare(attribute,"dispose") == 0)
4943 {
4944 if (image == (Image *) NULL)
4945 break;
4946
4947 s=newSViv(image->dispose);
4948 (void) sv_setpv(s,
4949 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
4950 SvIOK_on(s);
4951 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4952 continue;
4953 }
4954 if (LocaleCompare(attribute,"disk") == 0)
4955 {
4956 s=newSViv(GetMagickResource(DiskResource));
4957 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4958 continue;
4959 }
4960 if (LocaleCompare(attribute,"dither") == 0)
4961 {
4962 if (info)
4963 s=newSViv((ssize_t) info->image_info->dither);
4964 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4965 continue;
4966 }
4967 if (LocaleCompare(attribute,"display") == 0) /* same as server */
4968 {
4969 if (info && info->image_info->server_name)
4970 s=newSVpv(info->image_info->server_name,0);
4971 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4972 continue;
4973 }
4974 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4975 attribute);
4976 break;
4977 }
4978 case 'E':
4979 case 'e':
4980 {
4981 if (LocaleCompare(attribute,"elapsed-time") == 0)
4982 {
4983 if (image != (Image *) NULL)
4984 s=newSVnv(GetElapsedTime(&image->timer));
4985 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4986 continue;
4987 }
4988 if (LocaleCompare(attribute,"endian") == 0)
4989 {
4990 j=info ? info->image_info->endian : image ? image->endian :
4991 UndefinedEndian;
4992 s=newSViv(j);
4993 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
4994 SvIOK_on(s);
4995 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4996 continue;
4997 }
4998 if (LocaleCompare(attribute,"error") == 0)
4999 {
5000 if (image != (Image *) NULL)
5001 s=newSVnv(image->error.mean_error_per_pixel);
5002 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5003 continue;
5004 }
5005 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5006 attribute);
5007 break;
5008 }
5009 case 'F':
5010 case 'f':
5011 {
5012 if (LocaleCompare(attribute,"filesize") == 0)
5013 {
5014 if (image != (Image *) NULL)
5015 s=newSViv((ssize_t) GetBlobSize(image));
5016 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5017 continue;
5018 }
5019 if (LocaleCompare(attribute,"filename") == 0)
5020 {
5021 if (info && info->image_info->filename &&
5022 *info->image_info->filename)
5023 s=newSVpv(info->image_info->filename,0);
5024 if (image != (Image *) NULL)
5025 s=newSVpv(image->filename,0);
5026 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5027 continue;
5028 }
5029 if (LocaleCompare(attribute,"filter") == 0)
5030 {
5031 s=image ? newSViv(image->filter) : newSViv(0);
5032 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5033 image->filter));
5034 SvIOK_on(s);
5035 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5036 continue;
5037 }
5038 if (LocaleCompare(attribute,"font") == 0)
5039 {
5040 if (info && info->image_info->font)
5041 s=newSVpv(info->image_info->font,0);
5042 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5043 continue;
5044 }
5045 if (LocaleCompare(attribute,"foreground") == 0)
5046 continue;
5047 if (LocaleCompare(attribute,"format") == 0)
5048 {
5049 const MagickInfo
5050 *magick_info;
5051
5052 magick_info=(const MagickInfo *) NULL;
5053 if (info && (*info->image_info->magick != '\0'))
5054 magick_info=GetMagickInfo(info->image_info->magick,exception);
5055 if (image != (Image *) NULL)
5056 magick_info=GetMagickInfo(image->magick,exception);
5057 if ((magick_info != (const MagickInfo *) NULL) &&
5058 (*magick_info->description != '\0'))
5059 s=newSVpv((char *) magick_info->description,0);
5060 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5061 continue;
5062 }
5063 if (LocaleCompare(attribute,"fuzz") == 0)
5064 {
5065 if (info)
5066 s=newSVnv(info->image_info->fuzz);
5067 if (image != (Image *) NULL)
5068 s=newSVnv(image->fuzz);
5069 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5070 continue;
5071 }
5072 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5073 attribute);
5074 break;
5075 }
5076 case 'G':
5077 case 'g':
5078 {
5079 if (LocaleCompare(attribute,"gamma") == 0)
5080 {
5081 if (image != (Image *) NULL)
5082 s=newSVnv(image->gamma);
5083 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5084 continue;
5085 }
5086 if (LocaleCompare(attribute,"geometry") == 0)
5087 {
5088 if (image && image->geometry)
5089 s=newSVpv(image->geometry,0);
5090 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5091 continue;
5092 }
5093 if (LocaleCompare(attribute,"gravity") == 0)
5094 {
5095 s=image ? newSViv(image->gravity) : newSViv(0);
5096 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5097 image->gravity));
5098 SvIOK_on(s);
5099 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5100 continue;
5101 }
5102 if (LocaleCompare(attribute,"green-primary") == 0)
5103 {
5104 if (image == (Image *) NULL)
5105 break;
cristy151b66d2015-04-15 10:50:31 +00005106 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005107 image->chromaticity.green_primary.x,
5108 image->chromaticity.green_primary.y);
5109 s=newSVpv(color,0);
5110 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5111 continue;
5112 }
5113 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5114 attribute);
5115 break;
5116 }
5117 case 'H':
5118 case 'h':
5119 {
5120 if (LocaleCompare(attribute,"height") == 0)
5121 {
5122 if (image != (Image *) NULL)
5123 s=newSViv((ssize_t) image->rows);
5124 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5125 continue;
5126 }
5127 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5128 attribute);
5129 break;
5130 }
5131 case 'I':
5132 case 'i':
5133 {
5134 if (LocaleCompare(attribute,"icc") == 0)
5135 {
5136 if (image != (Image *) NULL)
5137 {
5138 const StringInfo
5139 *profile;
5140
5141 profile=GetImageProfile(image,"icc");
5142 if (profile != (StringInfo *) NULL)
5143 s=newSVpv((const char *) GetStringInfoDatum(profile),
5144 GetStringInfoLength(profile));
5145 }
5146 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5147 continue;
5148 }
5149 if (LocaleCompare(attribute,"icm") == 0)
5150 {
5151 if (image != (Image *) NULL)
5152 {
5153 const StringInfo
5154 *profile;
5155
5156 profile=GetImageProfile(image,"icm");
5157 if (profile != (const StringInfo *) NULL)
5158 s=newSVpv((const char *) GetStringInfoDatum(profile),
5159 GetStringInfoLength(profile));
5160 }
5161 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5162 continue;
5163 }
5164 if (LocaleCompare(attribute,"id") == 0)
5165 {
5166 if (image != (Image *) NULL)
5167 {
5168 char
cristy151b66d2015-04-15 10:50:31 +00005169 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005170
5171 MagickBooleanType
5172 status;
5173
5174 static ssize_t
5175 id = 0;
5176
cristy151b66d2015-04-15 10:50:31 +00005177 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005178 id);
5179 status=SetImageRegistry(ImageRegistryType,key,image,
5180 exception);
5181 (void) status;
5182 s=newSViv(id++);
5183 }
5184 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5185 continue;
5186 }
5187 if (LocaleNCompare(attribute,"index",5) == 0)
5188 {
5189 char
cristy151b66d2015-04-15 10:50:31 +00005190 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005191
5192 int
5193 items;
5194
5195 long
5196 x,
5197 y;
5198
5199 register const Quantum
5200 *p;
5201
5202 CacheView
5203 *image_view;
5204
5205 if (image == (Image *) NULL)
5206 break;
5207 if (image->storage_class != PseudoClass)
5208 break;
5209 x=0;
5210 y=0;
5211 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5212 (void) items;
5213 image_view=AcquireVirtualCacheView(image,exception);
5214 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5215 if (p != (const Quantum *) NULL)
5216 {
cristy151b66d2015-04-15 10:50:31 +00005217 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005218 GetPixelIndex(image,p));
5219 s=newSVpv(name,0);
5220 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5221 }
5222 image_view=DestroyCacheView(image_view);
5223 continue;
5224 }
5225 if (LocaleCompare(attribute,"iptc") == 0)
5226 {
5227 if (image != (Image *) NULL)
5228 {
5229 const StringInfo
5230 *profile;
5231
5232 profile=GetImageProfile(image,"iptc");
5233 if (profile != (const StringInfo *) NULL)
5234 s=newSVpv((const char *) GetStringInfoDatum(profile),
5235 GetStringInfoLength(profile));
5236 }
5237 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5238 continue;
5239 }
5240 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5241 {
5242 if (image != (Image *) NULL)
5243 s=newSViv((ssize_t) image->iterations);
5244 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5245 continue;
5246 }
5247 if (LocaleCompare(attribute,"interlace") == 0)
5248 {
5249 j=info ? info->image_info->interlace : image ? image->interlace :
5250 UndefinedInterlace;
5251 s=newSViv(j);
5252 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5253 j));
5254 SvIOK_on(s);
5255 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5256 continue;
5257 }
5258 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5259 attribute);
5260 break;
5261 }
5262 case 'L':
5263 case 'l':
5264 {
5265 if (LocaleCompare(attribute,"label") == 0)
5266 {
5267 const char
5268 *value;
5269
5270 if (image == (Image *) NULL)
5271 break;
5272 value=GetImageProperty(image,"Label",exception);
5273 if (value != (const char *) NULL)
5274 s=newSVpv(value,0);
5275 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5276 continue;
5277 }
5278 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5279 {
5280 if (image != (Image *) NULL)
5281 s=newSViv((ssize_t) image->iterations);
5282 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5283 continue;
5284 }
5285 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5286 attribute);
5287 break;
5288 }
5289 case 'M':
5290 case 'm':
5291 {
5292 if (LocaleCompare(attribute,"magick") == 0)
5293 {
5294 if (info && *info->image_info->magick)
5295 s=newSVpv(info->image_info->magick,0);
5296 if (image != (Image *) NULL)
5297 s=newSVpv(image->magick,0);
5298 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5299 continue;
5300 }
5301 if (LocaleCompare(attribute,"map") == 0)
5302 {
5303 s=newSViv(GetMagickResource(MapResource));
5304 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5305 continue;
5306 }
5307 if (LocaleCompare(attribute,"maximum-error") == 0)
5308 {
5309 if (image != (Image *) NULL)
5310 s=newSVnv(image->error.normalized_maximum_error);
5311 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5312 continue;
5313 }
5314 if (LocaleCompare(attribute,"memory") == 0)
5315 {
5316 s=newSViv(GetMagickResource(MemoryResource));
5317 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5318 continue;
5319 }
5320 if (LocaleCompare(attribute,"mean-error") == 0)
5321 {
5322 if (image != (Image *) NULL)
5323 s=newSVnv(image->error.normalized_mean_error);
5324 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5325 continue;
5326 }
5327 if (LocaleCompare(attribute,"mime") == 0)
5328 {
5329 if (info && *info->image_info->magick)
5330 s=newSVpv(MagickToMime(info->image_info->magick),0);
5331 if (image != (Image *) NULL)
5332 s=newSVpv(MagickToMime(image->magick),0);
5333 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5334 continue;
5335 }
5336 if (LocaleCompare(attribute,"mattecolor") == 0)
5337 {
5338 if (image == (Image *) NULL)
5339 break;
cristy151b66d2015-04-15 10:50:31 +00005340 (void) FormatLocaleString(color,MagickPathExtent,
Cristy8645e042016-02-03 16:35:29 -05005341 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5342 (double) image->alpha_color.green,
5343 (double) image->alpha_color.blue,
5344 (double) image->alpha_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005345 s=newSVpv(color,0);
5346 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5347 continue;
5348 }
5349 if (LocaleCompare(attribute,"matte") == 0)
5350 {
5351 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005352 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005353 1 : 0);
5354 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5355 continue;
5356 }
5357 if (LocaleCompare(attribute,"mime") == 0)
5358 {
5359 const char
5360 *magick;
5361
5362 magick=NULL;
5363 if (info && *info->image_info->magick)
5364 magick=info->image_info->magick;
5365 if (image != (Image *) NULL)
5366 magick=image->magick;
5367 if (magick)
5368 {
5369 char
5370 *mime;
5371
5372 mime=MagickToMime(magick);
5373 s=newSVpv(mime,0);
5374 mime=(char *) RelinquishMagickMemory(mime);
5375 }
5376 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5377 continue;
5378 }
5379 if (LocaleCompare(attribute,"monochrome") == 0)
5380 {
5381 if (image == (Image *) NULL)
5382 continue;
5383 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005384 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005385 s=newSViv(j);
5386 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5387 continue;
5388 }
5389 if (LocaleCompare(attribute,"montage") == 0)
5390 {
5391 if (image && image->montage)
5392 s=newSVpv(image->montage,0);
5393 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5394 continue;
5395 }
5396 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5397 attribute);
5398 break;
5399 }
5400 case 'O':
5401 case 'o':
5402 {
5403 if (LocaleCompare(attribute,"orientation") == 0)
5404 {
5405 j=info ? info->image_info->orientation : image ?
5406 image->orientation : UndefinedOrientation;
5407 s=newSViv(j);
5408 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5409 j));
5410 SvIOK_on(s);
5411 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5412 continue;
5413 }
5414 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5415 attribute);
5416 break;
5417 }
5418 case 'P':
5419 case 'p':
5420 {
5421 if (LocaleCompare(attribute,"page") == 0)
5422 {
5423 if (info && info->image_info->page)
5424 s=newSVpv(info->image_info->page,0);
5425 if (image != (Image *) NULL)
5426 {
5427 char
cristy151b66d2015-04-15 10:50:31 +00005428 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005429
cristy151b66d2015-04-15 10:50:31 +00005430 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005431 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5432 (double) image->page.height,(double) image->page.x,(double)
5433 image->page.y);
5434 s=newSVpv(geometry,0);
5435 }
5436 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5437 continue;
5438 }
5439 if (LocaleCompare(attribute,"page.x") == 0)
5440 {
5441 if (image != (Image *) NULL)
5442 s=newSViv((ssize_t) image->page.x);
5443 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5444 continue;
5445 }
5446 if (LocaleCompare(attribute,"page.y") == 0)
5447 {
5448 if (image != (Image *) NULL)
5449 s=newSViv((ssize_t) image->page.y);
5450 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5451 continue;
5452 }
5453 if (LocaleNCompare(attribute,"pixel",5) == 0)
5454 {
5455 char
cristy151b66d2015-04-15 10:50:31 +00005456 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005457
5458 int
5459 items;
5460
5461 long
5462 x,
5463 y;
5464
5465 register const Quantum
5466 *p;
5467
5468 if (image == (Image *) NULL)
5469 break;
5470 x=0;
5471 y=0;
5472 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5473 (void) items;
5474 p=GetVirtualPixels(image,x,y,1,1,exception);
5475 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005476 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005477 QuantumFormat "," QuantumFormat "," QuantumFormat,
5478 GetPixelRed(image,p),GetPixelGreen(image,p),
5479 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5480 else
cristy151b66d2015-04-15 10:50:31 +00005481 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005482 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5483 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5484 GetPixelBlue(image,p),GetPixelBlack(image,p),
5485 GetPixelAlpha(image,p));
5486 s=newSVpv(tuple,0);
5487 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5488 continue;
5489 }
5490 if (LocaleCompare(attribute,"pointsize") == 0)
5491 {
5492 if (info)
5493 s=newSViv((ssize_t) info->image_info->pointsize);
5494 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5495 continue;
5496 }
5497 if (LocaleCompare(attribute,"preview") == 0)
5498 {
5499 s=newSViv(info->image_info->preview_type);
5500 (void) sv_setpv(s,CommandOptionToMnemonic(MagickPreviewOptions,
5501 info->image_info->preview_type));
5502 SvIOK_on(s);
5503 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5504 continue;
5505 }
5506 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5507 attribute);
5508 break;
5509 }
5510 case 'Q':
5511 case 'q':
5512 {
5513 if (LocaleCompare(attribute,"quality") == 0)
5514 {
5515 if (info)
5516 s=newSViv((ssize_t) info->image_info->quality);
5517 if (image != (Image *) NULL)
5518 s=newSViv((ssize_t) image->quality);
5519 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5520 continue;
5521 }
5522 if (LocaleCompare(attribute,"quantum") == 0)
5523 {
5524 if (info)
5525 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5526 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5527 continue;
5528 }
5529 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5530 attribute);
5531 break;
5532 }
5533 case 'R':
5534 case 'r':
5535 {
5536 if (LocaleCompare(attribute,"rendering-intent") == 0)
5537 {
5538 s=newSViv(image->rendering_intent);
5539 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5540 image->rendering_intent));
5541 SvIOK_on(s);
5542 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5543 continue;
5544 }
5545 if (LocaleCompare(attribute,"red-primary") == 0)
5546 {
5547 if (image == (Image *) NULL)
5548 break;
cristy151b66d2015-04-15 10:50:31 +00005549 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005550 image->chromaticity.red_primary.x,
5551 image->chromaticity.red_primary.y);
5552 s=newSVpv(color,0);
5553 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5554 continue;
5555 }
5556 if (LocaleCompare(attribute,"rows") == 0)
5557 {
5558 if (image != (Image *) NULL)
5559 s=newSViv((ssize_t) image->rows);
5560 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5561 continue;
5562 }
5563 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5564 attribute);
5565 break;
5566 }
5567 case 'S':
5568 case 's':
5569 {
5570 if (LocaleCompare(attribute,"sampling-factor") == 0)
5571 {
5572 if (info && info->image_info->sampling_factor)
5573 s=newSVpv(info->image_info->sampling_factor,0);
5574 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5575 continue;
5576 }
5577 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5578 {
5579 if (info && info->image_info->server_name)
5580 s=newSVpv(info->image_info->server_name,0);
5581 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5582 continue;
5583 }
5584 if (LocaleCompare(attribute,"size") == 0)
5585 {
5586 if (info && info->image_info->size)
5587 s=newSVpv(info->image_info->size,0);
5588 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5589 continue;
5590 }
5591 if (LocaleCompare(attribute,"scene") == 0)
5592 {
5593 if (image != (Image *) NULL)
5594 s=newSViv((ssize_t) image->scene);
5595 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5596 continue;
5597 }
5598 if (LocaleCompare(attribute,"scenes") == 0)
5599 {
5600 if (image != (Image *) NULL)
5601 s=newSViv((ssize_t) info->image_info->number_scenes);
5602 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5603 continue;
5604 }
5605 if (LocaleCompare(attribute,"signature") == 0)
5606 {
5607 const char
5608 *value;
5609
5610 if (image == (Image *) NULL)
5611 break;
5612 (void) SignatureImage(image,exception);
5613 value=GetImageProperty(image,"Signature",exception);
5614 if (value != (const char *) NULL)
5615 s=newSVpv(value,0);
5616 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5617 continue;
5618 }
5619 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5620 attribute);
5621 break;
5622 }
5623 case 'T':
5624 case 't':
5625 {
5626 if (LocaleCompare(attribute,"taint") == 0)
5627 {
5628 if (image != (Image *) NULL)
5629 s=newSViv((ssize_t) IsTaintImage(image));
5630 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5631 continue;
5632 }
5633 if (LocaleCompare(attribute,"texture") == 0)
5634 {
5635 if (info && info->image_info->texture)
5636 s=newSVpv(info->image_info->texture,0);
5637 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5638 continue;
5639 }
5640 if (LocaleCompare(attribute,"total-ink-density") == 0)
5641 {
5642 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5643 if (image != (Image *) NULL)
5644 s=newSVnv(GetImageTotalInkDensity(image,exception));
5645 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5646 continue;
5647 }
5648 if (LocaleCompare(attribute,"transparent-color") == 0)
5649 {
5650 if (image == (Image *) NULL)
5651 break;
cristy151b66d2015-04-15 10:50:31 +00005652 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005653 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5654 (double) image->transparent_color.green,
5655 (double) image->transparent_color.blue,
5656 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005657 s=newSVpv(color,0);
5658 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5659 continue;
5660 }
5661 if (LocaleCompare(attribute,"type") == 0)
5662 {
5663 if (image == (Image *) NULL)
5664 break;
cristya26f54c2015-07-29 12:26:12 +00005665 j=(ssize_t) GetImageType(image);
cristy4a3ce0a2013-08-03 20:06:59 +00005666 s=newSViv(j);
5667 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5668 SvIOK_on(s);
5669 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5670 continue;
5671 }
5672 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5673 attribute);
5674 break;
5675 }
5676 case 'U':
5677 case 'u':
5678 {
5679 if (LocaleCompare(attribute,"units") == 0)
5680 {
5681 j=info ? info->image_info->units : image ? image->units :
5682 UndefinedResolution;
5683 if (info && (info->image_info->units == UndefinedResolution))
5684 if (image)
5685 j=image->units;
5686 if (j == UndefinedResolution)
5687 s=newSVpv("undefined units",0);
5688 else
5689 if (j == PixelsPerInchResolution)
5690 s=newSVpv("pixels / inch",0);
5691 else
5692 s=newSVpv("pixels / centimeter",0);
5693 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5694 continue;
5695 }
5696 if (LocaleCompare(attribute,"user-time") == 0)
5697 {
5698 if (image != (Image *) NULL)
5699 s=newSVnv(GetUserTime(&image->timer));
5700 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5701 continue;
5702 }
5703 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5704 attribute);
5705 break;
5706 }
5707 case 'V':
5708 case 'v':
5709 {
5710 if (LocaleCompare(attribute,"verbose") == 0)
5711 {
5712 if (info)
5713 s=newSViv((ssize_t) info->image_info->verbose);
5714 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5715 continue;
5716 }
5717 if (LocaleCompare(attribute,"version") == 0)
5718 {
5719 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5720 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5721 continue;
5722 }
cristy4a3ce0a2013-08-03 20:06:59 +00005723 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5724 {
5725 if (image == (Image *) NULL)
5726 break;
5727 j=(ssize_t) GetImageVirtualPixelMethod(image);
5728 s=newSViv(j);
5729 (void) sv_setpv(s,CommandOptionToMnemonic(
5730 MagickVirtualPixelOptions,j));
5731 SvIOK_on(s);
5732 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5733 continue;
5734 }
5735 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5736 attribute);
5737 break;
5738 }
5739 case 'W':
5740 case 'w':
5741 {
5742 if (LocaleCompare(attribute,"white-point") == 0)
5743 {
5744 if (image == (Image *) NULL)
5745 break;
cristy151b66d2015-04-15 10:50:31 +00005746 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005747 image->chromaticity.white_point.x,
5748 image->chromaticity.white_point.y);
5749 s=newSVpv(color,0);
5750 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5751 continue;
5752 }
5753 if (LocaleCompare(attribute,"width") == 0)
5754 {
5755 if (image != (Image *) NULL)
5756 s=newSViv((ssize_t) image->columns);
5757 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5758 continue;
5759 }
5760 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5761 attribute);
5762 break;
5763 }
5764 case 'X':
5765 case 'x':
5766 {
Cristyc1f9f9f2016-01-05 08:19:28 -05005767 if (LocaleCompare(attribute,"xmp") == 0)
5768 {
5769 if (image != (Image *) NULL)
5770 {
5771 const StringInfo
5772 *profile;
5773
5774 profile=GetImageProfile(image,"xmp");
5775 if (profile != (StringInfo *) NULL)
5776 s=newSVpv((const char *) GetStringInfoDatum(profile),
5777 GetStringInfoLength(profile));
5778 }
5779 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5780 continue;
5781 }
cristy4a3ce0a2013-08-03 20:06:59 +00005782 if (LocaleCompare(attribute,"x-resolution") == 0)
5783 {
5784 if (image != (Image *) NULL)
5785 s=newSVnv(image->resolution.x);
5786 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5787 continue;
5788 }
5789 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5790 attribute);
5791 break;
5792 }
5793 case 'Y':
5794 case 'y':
5795 {
5796 if (LocaleCompare(attribute,"y-resolution") == 0)
5797 {
5798 if (image != (Image *) NULL)
5799 s=newSVnv(image->resolution.y);
5800 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5801 continue;
5802 }
5803 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5804 attribute);
5805 break;
5806 }
5807 default:
5808 break;
5809 }
5810 if (image == (Image *) NULL)
5811 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5812 attribute)
5813 else
5814 {
5815 value=GetImageProperty(image,attribute,exception);
5816 if (value != (const char *) NULL)
5817 {
5818 s=newSVpv(value,0);
5819 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5820 }
5821 else
5822 if (*attribute != '%')
5823 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5824 attribute)
5825 else
5826 {
5827 char
5828 *meta;
5829
5830 meta=InterpretImageProperties(info ? info->image_info :
5831 (ImageInfo *) NULL,image,attribute,exception);
5832 s=newSVpv(meta,0);
5833 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5834 meta=(char *) RelinquishMagickMemory(meta);
5835 }
5836 }
5837 }
5838 exception=DestroyExceptionInfo(exception);
5839 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5840 }
5841
5842#
5843###############################################################################
5844# #
5845# #
5846# #
5847# G e t A u t h e n t i c P i x e l s #
5848# #
5849# #
5850# #
5851###############################################################################
5852#
5853#
5854void *
5855GetAuthenticPixels(ref,...)
5856 Image::Magick ref = NO_INIT
5857 ALIAS:
5858 getauthenticpixels = 1
5859 GetImagePixels = 2
5860 getimagepixels = 3
5861 CODE:
5862 {
5863 char
5864 *attribute;
5865
5866 ExceptionInfo
5867 *exception;
5868
5869 Image
5870 *image;
5871
5872 RectangleInfo
5873 region;
5874
5875 ssize_t
5876 i;
5877
5878 struct PackageInfo
5879 *info;
5880
5881 SV
5882 *perl_exception,
5883 *reference;
5884
5885 void
5886 *blob = NULL;
5887
5888 PERL_UNUSED_VAR(ref);
5889 PERL_UNUSED_VAR(ix);
5890 exception=AcquireExceptionInfo();
5891 perl_exception=newSVpv("",0);
5892 if (sv_isobject(ST(0)) == 0)
5893 {
5894 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5895 PackageName);
5896 goto PerlException;
5897 }
5898 reference=SvRV(ST(0));
5899
5900 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5901 if (image == (Image *) NULL)
5902 {
5903 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5904 PackageName);
5905 goto PerlException;
5906 }
5907
5908 region.x=0;
5909 region.y=0;
5910 region.width=image->columns;
5911 region.height=1;
5912 if (items == 1)
5913 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5914 for (i=2; i < items; i+=2)
5915 {
5916 attribute=(char *) SvPV(ST(i-1),na);
5917 switch (*attribute)
5918 {
5919 case 'g':
5920 case 'G':
5921 {
5922 if (LocaleCompare(attribute,"geometry") == 0)
5923 {
5924 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5925 break;
5926 }
5927 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5928 attribute);
5929 break;
5930 }
5931 case 'H':
5932 case 'h':
5933 {
5934 if (LocaleCompare(attribute,"height") == 0)
5935 {
5936 region.height=SvIV(ST(i));
5937 continue;
5938 }
5939 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5940 attribute);
5941 break;
5942 }
5943 case 'X':
5944 case 'x':
5945 {
5946 if (LocaleCompare(attribute,"x") == 0)
5947 {
5948 region.x=SvIV(ST(i));
5949 continue;
5950 }
5951 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5952 attribute);
5953 break;
5954 }
5955 case 'Y':
5956 case 'y':
5957 {
5958 if (LocaleCompare(attribute,"y") == 0)
5959 {
5960 region.y=SvIV(ST(i));
5961 continue;
5962 }
5963 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5964 attribute);
5965 break;
5966 }
5967 case 'W':
5968 case 'w':
5969 {
5970 if (LocaleCompare(attribute,"width") == 0)
5971 {
5972 region.width=SvIV(ST(i));
5973 continue;
5974 }
5975 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5976 attribute);
5977 break;
5978 }
5979 }
5980 }
5981 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5982 region.height,exception);
5983 if (blob != (void *) NULL)
5984 goto PerlEnd;
5985
5986 PerlException:
5987 InheritPerlException(exception,perl_exception);
5988 exception=DestroyExceptionInfo(exception);
5989 SvREFCNT_dec(perl_exception); /* throw away all errors */
5990
5991 PerlEnd:
5992 RETVAL = blob;
5993 }
5994 OUTPUT:
5995 RETVAL
5996
5997#
5998###############################################################################
5999# #
6000# #
6001# #
6002# G e t V i r t u a l P i x e l s #
6003# #
6004# #
6005# #
6006###############################################################################
6007#
6008#
6009void *
6010GetVirtualPixels(ref,...)
6011 Image::Magick ref = NO_INIT
6012 ALIAS:
6013 getvirtualpixels = 1
6014 AcquireImagePixels = 2
6015 acquireimagepixels = 3
6016 CODE:
6017 {
6018 char
6019 *attribute;
6020
6021 const void
6022 *blob = NULL;
6023
6024 ExceptionInfo
6025 *exception;
6026
6027 Image
6028 *image;
6029
6030 RectangleInfo
6031 region;
6032
6033 ssize_t
6034 i;
6035
6036 struct PackageInfo
6037 *info;
6038
6039 SV
6040 *perl_exception,
6041 *reference;
6042
6043 PERL_UNUSED_VAR(ref);
6044 PERL_UNUSED_VAR(ix);
6045 exception=AcquireExceptionInfo();
6046 perl_exception=newSVpv("",0);
6047 if (sv_isobject(ST(0)) == 0)
6048 {
6049 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6050 PackageName);
6051 goto PerlException;
6052 }
6053 reference=SvRV(ST(0));
6054
6055 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6056 if (image == (Image *) NULL)
6057 {
6058 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6059 PackageName);
6060 goto PerlException;
6061 }
6062
6063 region.x=0;
6064 region.y=0;
6065 region.width=image->columns;
6066 region.height=1;
6067 if (items == 1)
6068 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6069 for (i=2; i < items; i+=2)
6070 {
6071 attribute=(char *) SvPV(ST(i-1),na);
6072 switch (*attribute)
6073 {
6074 case 'g':
6075 case 'G':
6076 {
6077 if (LocaleCompare(attribute,"geometry") == 0)
6078 {
6079 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6080 break;
6081 }
6082 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6083 attribute);
6084 break;
6085 }
6086 case 'H':
6087 case 'h':
6088 {
6089 if (LocaleCompare(attribute,"height") == 0)
6090 {
6091 region.height=SvIV(ST(i));
6092 continue;
6093 }
6094 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6095 attribute);
6096 break;
6097 }
6098 case 'X':
6099 case 'x':
6100 {
6101 if (LocaleCompare(attribute,"x") == 0)
6102 {
6103 region.x=SvIV(ST(i));
6104 continue;
6105 }
6106 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6107 attribute);
6108 break;
6109 }
6110 case 'Y':
6111 case 'y':
6112 {
6113 if (LocaleCompare(attribute,"y") == 0)
6114 {
6115 region.y=SvIV(ST(i));
6116 continue;
6117 }
6118 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6119 attribute);
6120 break;
6121 }
6122 case 'W':
6123 case 'w':
6124 {
6125 if (LocaleCompare(attribute,"width") == 0)
6126 {
6127 region.width=SvIV(ST(i));
6128 continue;
6129 }
6130 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6131 attribute);
6132 break;
6133 }
6134 }
6135 }
6136 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6137 region.height,exception);
6138 if (blob != (void *) NULL)
6139 goto PerlEnd;
6140
6141 PerlException:
6142 InheritPerlException(exception,perl_exception);
6143 exception=DestroyExceptionInfo(exception);
6144 SvREFCNT_dec(perl_exception); /* throw away all errors */
6145
6146 PerlEnd:
6147 RETVAL = (void *) blob;
6148 }
6149 OUTPUT:
6150 RETVAL
6151
6152#
6153###############################################################################
6154# #
6155# #
6156# #
6157# G e t A u t h e n t i c M e t a c o n t e n t #
6158# #
6159# #
6160# #
6161###############################################################################
6162#
6163#
6164void *
6165GetAuthenticMetacontent(ref,...)
6166 Image::Magick ref = NO_INIT
6167 ALIAS:
6168 getauthenticmetacontent = 1
6169 GetMetacontent = 2
6170 getmetacontent = 3
6171 CODE:
6172 {
6173 ExceptionInfo
6174 *exception;
6175
6176 Image
6177 *image;
6178
6179 struct PackageInfo
6180 *info;
6181
6182 SV
6183 *perl_exception,
6184 *reference;
6185
6186 void
6187 *blob = NULL;
6188
6189 PERL_UNUSED_VAR(ref);
6190 PERL_UNUSED_VAR(ix);
6191 exception=AcquireExceptionInfo();
6192 perl_exception=newSVpv("",0);
6193 if (sv_isobject(ST(0)) == 0)
6194 {
6195 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6196 PackageName);
6197 goto PerlException;
6198 }
6199 reference=SvRV(ST(0));
6200
6201 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6202 if (image == (Image *) NULL)
6203 {
6204 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6205 PackageName);
6206 goto PerlException;
6207 }
6208
6209 blob=(void *) GetAuthenticMetacontent(image);
6210 if (blob != (void *) NULL)
6211 goto PerlEnd;
6212
6213 PerlException:
6214 InheritPerlException(exception,perl_exception);
6215 exception=DestroyExceptionInfo(exception);
6216 SvREFCNT_dec(perl_exception); /* throw away all errors */
6217
6218 PerlEnd:
6219 RETVAL = blob;
6220 }
6221 OUTPUT:
6222 RETVAL
6223
6224#
6225###############################################################################
6226# #
6227# #
6228# #
6229# G e t V i r t u a l M e t a c o n t e n t #
6230# #
6231# #
6232# #
6233###############################################################################
6234#
6235#
6236void *
6237GetVirtualMetacontent(ref,...)
6238 Image::Magick ref = NO_INIT
6239 ALIAS:
6240 getvirtualmetacontent = 1
6241 CODE:
6242 {
6243 ExceptionInfo
6244 *exception;
6245
6246 Image
6247 *image;
6248
6249 struct PackageInfo
6250 *info;
6251
6252 SV
6253 *perl_exception,
6254 *reference;
6255
6256 void
6257 *blob = NULL;
6258
6259 PERL_UNUSED_VAR(ref);
6260 PERL_UNUSED_VAR(ix);
6261 exception=AcquireExceptionInfo();
6262 perl_exception=newSVpv("",0);
6263 if (sv_isobject(ST(0)) == 0)
6264 {
6265 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6266 PackageName);
6267 goto PerlException;
6268 }
6269 reference=SvRV(ST(0));
6270
6271 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6272 if (image == (Image *) NULL)
6273 {
6274 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6275 PackageName);
6276 goto PerlException;
6277 }
6278
6279 blob=(void *) GetVirtualMetacontent(image);
6280 if (blob != (void *) NULL)
6281 goto PerlEnd;
6282
6283 PerlException:
6284 InheritPerlException(exception,perl_exception);
6285 exception=DestroyExceptionInfo(exception);
6286 SvREFCNT_dec(perl_exception); /* throw away all errors */
6287
6288 PerlEnd:
6289 RETVAL = blob;
6290 }
6291 OUTPUT:
6292 RETVAL
6293
6294#
6295###############################################################################
6296# #
6297# #
6298# #
6299# H i s t o g r a m #
6300# #
6301# #
6302# #
6303###############################################################################
6304#
6305#
6306void
6307Histogram(ref,...)
6308 Image::Magick ref=NO_INIT
6309 ALIAS:
6310 HistogramImage = 1
6311 histogram = 2
6312 histogramimage = 3
6313 PPCODE:
6314 {
6315 AV
6316 *av;
6317
6318 char
cristy151b66d2015-04-15 10:50:31 +00006319 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006320
6321 PixelInfo
6322 *histogram;
6323
6324 ExceptionInfo
6325 *exception;
6326
6327 Image
6328 *image;
6329
6330 register ssize_t
6331 i;
6332
6333 ssize_t
6334 count;
6335
6336 struct PackageInfo
6337 *info;
6338
6339 SV
6340 *perl_exception,
6341 *reference;
6342
6343 size_t
6344 number_colors;
6345
6346 PERL_UNUSED_VAR(ref);
6347 PERL_UNUSED_VAR(ix);
6348 exception=AcquireExceptionInfo();
6349 perl_exception=newSVpv("",0);
6350 av=NULL;
6351 if (sv_isobject(ST(0)) == 0)
6352 {
6353 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6354 PackageName);
6355 goto PerlException;
6356 }
6357 reference=SvRV(ST(0));
6358 av=newAV();
6359 SvREFCNT_dec(av);
6360 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6361 if (image == (Image *) NULL)
6362 {
6363 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6364 PackageName);
6365 goto PerlException;
6366 }
cristy4a3ce0a2013-08-03 20:06:59 +00006367 count=0;
6368 for ( ; image; image=image->next)
6369 {
6370 histogram=GetImageHistogram(image,&number_colors,exception);
6371 if (histogram == (PixelInfo *) NULL)
6372 continue;
6373 count+=(ssize_t) number_colors;
6374 EXTEND(sp,6*count);
6375 for (i=0; i < (ssize_t) number_colors; i++)
6376 {
cristy151b66d2015-04-15 10:50:31 +00006377 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006378 histogram[i].red);
6379 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006380 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006381 histogram[i].green);
6382 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006383 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006384 histogram[i].blue);
6385 PUSHs(sv_2mortal(newSVpv(message,0)));
6386 if (image->colorspace == CMYKColorspace)
6387 {
cristy151b66d2015-04-15 10:50:31 +00006388 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006389 histogram[i].black);
6390 PUSHs(sv_2mortal(newSVpv(message,0)));
6391 }
cristy151b66d2015-04-15 10:50:31 +00006392 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006393 histogram[i].alpha);
6394 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006395 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006396 histogram[i].count);
6397 PUSHs(sv_2mortal(newSVpv(message,0)));
6398 }
6399 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6400 }
6401
6402 PerlException:
6403 InheritPerlException(exception,perl_exception);
6404 exception=DestroyExceptionInfo(exception);
6405 SvREFCNT_dec(perl_exception);
6406 }
6407
6408#
6409###############################################################################
6410# #
6411# #
6412# #
6413# G e t P i x e l #
6414# #
6415# #
6416# #
6417###############################################################################
6418#
6419#
6420void
6421GetPixel(ref,...)
6422 Image::Magick ref=NO_INIT
6423 ALIAS:
6424 getpixel = 1
6425 getPixel = 2
6426 PPCODE:
6427 {
6428 AV
6429 *av;
6430
6431 char
6432 *attribute;
6433
6434 ExceptionInfo
6435 *exception;
6436
6437 Image
6438 *image;
6439
6440 MagickBooleanType
6441 normalize;
6442
6443 RectangleInfo
6444 region;
6445
6446 register const Quantum
6447 *p;
6448
6449 register ssize_t
6450 i;
6451
6452 ssize_t
6453 option;
6454
6455 struct PackageInfo
6456 *info;
6457
6458 SV
6459 *perl_exception,
6460 *reference; /* reference is the SV* of ref=SvIV(reference) */
6461
6462 PERL_UNUSED_VAR(ref);
6463 PERL_UNUSED_VAR(ix);
6464 exception=AcquireExceptionInfo();
6465 perl_exception=newSVpv("",0);
6466 reference=SvRV(ST(0));
6467 av=(AV *) reference;
6468 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6469 exception);
6470 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6471 if (image == (Image *) NULL)
6472 {
6473 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6474 PackageName);
6475 goto PerlException;
6476 }
6477 normalize=MagickTrue;
6478 region.x=0;
6479 region.y=0;
6480 region.width=image->columns;
6481 region.height=1;
6482 if (items == 1)
6483 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6484 for (i=2; i < items; i+=2)
6485 {
6486 attribute=(char *) SvPV(ST(i-1),na);
6487 switch (*attribute)
6488 {
6489 case 'C':
6490 case 'c':
6491 {
6492 if (LocaleCompare(attribute,"channel") == 0)
6493 {
6494 ssize_t
6495 option;
6496
6497 option=ParseChannelOption(SvPV(ST(i),na));
6498 if (option < 0)
6499 {
6500 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6501 SvPV(ST(i),na));
6502 return;
6503 }
cristybcd59342015-06-07 14:07:19 +00006504 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00006505 break;
6506 }
6507 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6508 attribute);
6509 break;
6510 }
6511 case 'g':
6512 case 'G':
6513 {
6514 if (LocaleCompare(attribute,"geometry") == 0)
6515 {
6516 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6517 break;
6518 }
6519 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6520 attribute);
6521 break;
6522 }
6523 case 'N':
6524 case 'n':
6525 {
6526 if (LocaleCompare(attribute,"normalize") == 0)
6527 {
6528 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6529 SvPV(ST(i),na));
6530 if (option < 0)
6531 {
6532 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6533 SvPV(ST(i),na));
6534 break;
6535 }
6536 normalize=option != 0 ? MagickTrue : MagickFalse;
6537 break;
6538 }
6539 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6540 attribute);
6541 break;
6542 }
6543 case 'x':
6544 case 'X':
6545 {
6546 if (LocaleCompare(attribute,"x") == 0)
6547 {
6548 region.x=SvIV(ST(i));
6549 break;
6550 }
6551 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6552 attribute);
6553 break;
6554 }
6555 case 'y':
6556 case 'Y':
6557 {
6558 if (LocaleCompare(attribute,"y") == 0)
6559 {
6560 region.y=SvIV(ST(i));
6561 break;
6562 }
6563 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6564 attribute);
6565 break;
6566 }
6567 default:
6568 {
6569 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6570 attribute);
6571 break;
6572 }
6573 }
6574 }
6575 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6576 if (p == (const Quantum *) NULL)
6577 PUSHs(&sv_undef);
6578 else
6579 {
6580 double
6581 scale;
6582
6583 scale=1.0;
6584 if (normalize != MagickFalse)
6585 scale=1.0/QuantumRange;
6586 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6587 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6588 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6589 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6590 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6591 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6592 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6593 (image->colorspace == CMYKColorspace))
6594 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6595 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6596 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6597 }
6598
6599 PerlException:
6600 InheritPerlException(exception,perl_exception);
6601 exception=DestroyExceptionInfo(exception);
6602 SvREFCNT_dec(perl_exception);
6603 }
6604
6605#
6606###############################################################################
6607# #
6608# #
6609# #
6610# G e t P i x e l s #
6611# #
6612# #
6613# #
6614###############################################################################
6615#
6616#
6617void
6618GetPixels(ref,...)
6619 Image::Magick ref=NO_INIT
6620 ALIAS:
6621 getpixels = 1
6622 getPixels = 2
6623 PPCODE:
6624 {
6625 AV
6626 *av;
6627
6628 char
6629 *attribute;
6630
6631 const char
6632 *map;
6633
6634 ExceptionInfo
6635 *exception;
6636
6637 Image
6638 *image;
6639
6640 MagickBooleanType
6641 normalize,
6642 status;
6643
6644 RectangleInfo
6645 region;
6646
6647 register ssize_t
6648 i;
6649
6650 ssize_t
6651 option;
6652
6653 struct PackageInfo
6654 *info;
6655
6656 SV
6657 *perl_exception,
6658 *reference; /* reference is the SV* of ref=SvIV(reference) */
6659
6660 PERL_UNUSED_VAR(ref);
6661 PERL_UNUSED_VAR(ix);
6662 exception=AcquireExceptionInfo();
6663 perl_exception=newSVpv("",0);
6664 reference=SvRV(ST(0));
6665 av=(AV *) reference;
6666 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6667 exception);
6668 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6669 if (image == (Image *) NULL)
6670 {
6671 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6672 PackageName);
6673 goto PerlException;
6674 }
6675 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006676 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006677 map="RGBA";
6678 if (image->colorspace == CMYKColorspace)
6679 {
6680 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006681 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006682 map="CMYKA";
6683 }
6684 normalize=MagickFalse;
6685 region.x=0;
6686 region.y=0;
6687 region.width=image->columns;
6688 region.height=1;
6689 if (items == 1)
6690 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6691 for (i=2; i < items; i+=2)
6692 {
6693 attribute=(char *) SvPV(ST(i-1),na);
6694 switch (*attribute)
6695 {
6696 case 'g':
6697 case 'G':
6698 {
6699 if (LocaleCompare(attribute,"geometry") == 0)
6700 {
6701 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6702 break;
6703 }
6704 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6705 attribute);
6706 break;
6707 }
6708 case 'H':
6709 case 'h':
6710 {
6711 if (LocaleCompare(attribute,"height") == 0)
6712 {
6713 region.height=SvIV(ST(i));
6714 break;
6715 }
6716 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6717 attribute);
6718 break;
6719 }
6720 case 'M':
6721 case 'm':
6722 {
6723 if (LocaleCompare(attribute,"map") == 0)
6724 {
6725 map=SvPV(ST(i),na);
6726 break;
6727 }
6728 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6729 attribute);
6730 break;
6731 }
6732 case 'N':
6733 case 'n':
6734 {
6735 if (LocaleCompare(attribute,"normalize") == 0)
6736 {
6737 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6738 SvPV(ST(i),na));
6739 if (option < 0)
6740 {
6741 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6742 SvPV(ST(i),na));
6743 break;
6744 }
6745 normalize=option != 0 ? MagickTrue : MagickFalse;
6746 break;
6747 }
6748 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6749 attribute);
6750 break;
6751 }
6752 case 'W':
6753 case 'w':
6754 {
6755 if (LocaleCompare(attribute,"width") == 0)
6756 {
6757 region.width=SvIV(ST(i));
6758 break;
6759 }
6760 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6761 attribute);
6762 break;
6763 }
6764 case 'x':
6765 case 'X':
6766 {
6767 if (LocaleCompare(attribute,"x") == 0)
6768 {
6769 region.x=SvIV(ST(i));
6770 break;
6771 }
6772 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6773 attribute);
6774 break;
6775 }
6776 case 'y':
6777 case 'Y':
6778 {
6779 if (LocaleCompare(attribute,"y") == 0)
6780 {
6781 region.y=SvIV(ST(i));
6782 break;
6783 }
6784 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6785 attribute);
6786 break;
6787 }
6788 default:
6789 {
6790 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6791 attribute);
6792 break;
6793 }
6794 }
6795 }
6796 if (normalize != MagickFalse)
6797 {
6798 float
6799 *pixels;
6800
6801 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6802 region.height*sizeof(*pixels));
6803 if (pixels == (float *) NULL)
6804 {
6805 ThrowPerlException(exception,ResourceLimitError,
6806 "MemoryAllocationFailed",PackageName);
6807 goto PerlException;
6808 }
6809 status=ExportImagePixels(image,region.x,region.y,region.width,
6810 region.height,map,FloatPixel,pixels,exception);
6811 if (status == MagickFalse)
6812 PUSHs(&sv_undef);
6813 else
6814 {
6815 EXTEND(sp,strlen(map)*region.width*region.height);
6816 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6817 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6818 }
6819 pixels=(float *) RelinquishMagickMemory(pixels);
6820 }
6821 else
6822 {
6823 Quantum
6824 *pixels;
6825
6826 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6827 region.height*sizeof(*pixels));
6828 if (pixels == (Quantum *) NULL)
6829 {
6830 ThrowPerlException(exception,ResourceLimitError,
6831 "MemoryAllocationFailed",PackageName);
6832 goto PerlException;
6833 }
6834 status=ExportImagePixels(image,region.x,region.y,region.width,
6835 region.height,map,QuantumPixel,pixels,exception);
6836 if (status == MagickFalse)
6837 PUSHs(&sv_undef);
6838 else
6839 {
6840 EXTEND(sp,strlen(map)*region.width*region.height);
6841 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6842 PUSHs(sv_2mortal(newSViv(pixels[i])));
6843 }
6844 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6845 }
6846
6847 PerlException:
6848 InheritPerlException(exception,perl_exception);
6849 exception=DestroyExceptionInfo(exception);
6850 SvREFCNT_dec(perl_exception);
6851 }
6852
6853#
6854###############################################################################
6855# #
6856# #
6857# #
6858# I m a g e T o B l o b #
6859# #
6860# #
6861# #
6862###############################################################################
6863#
6864#
6865void
6866ImageToBlob(ref,...)
6867 Image::Magick ref=NO_INIT
6868 ALIAS:
6869 ImageToBlob = 1
6870 imagetoblob = 2
6871 toblob = 3
6872 blob = 4
6873 PPCODE:
6874 {
6875 char
cristy151b66d2015-04-15 10:50:31 +00006876 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006877
6878 ExceptionInfo
6879 *exception;
6880
6881 Image
6882 *image,
6883 *next;
6884
6885 register ssize_t
6886 i;
6887
6888 struct PackageInfo
6889 *info,
6890 *package_info;
6891
6892 size_t
6893 length;
6894
6895 ssize_t
6896 scene;
6897
6898 SV
6899 *perl_exception,
6900 *reference;
6901
6902 void
6903 *blob;
6904
6905 PERL_UNUSED_VAR(ref);
6906 PERL_UNUSED_VAR(ix);
6907 exception=AcquireExceptionInfo();
6908 perl_exception=newSVpv("",0);
6909 package_info=(struct PackageInfo *) NULL;
6910 if (sv_isobject(ST(0)) == 0)
6911 {
6912 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6913 PackageName);
6914 goto PerlException;
6915 }
6916 reference=SvRV(ST(0));
6917 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6918 if (image == (Image *) NULL)
6919 {
6920 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6921 PackageName);
6922 goto PerlException;
6923 }
6924 package_info=ClonePackageInfo(info,exception);
6925 for (i=2; i < items; i+=2)
6926 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6927 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006928 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006929 scene=0;
6930 for (next=image; next; next=next->next)
6931 {
cristy151b66d2015-04-15 10:50:31 +00006932 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006933 next->scene=scene++;
6934 }
6935 SetImageInfo(package_info->image_info,(unsigned int)
6936 GetImageListLength(image),exception);
6937 EXTEND(sp,(ssize_t) GetImageListLength(image));
6938 for ( ; image; image=image->next)
6939 {
6940 length=0;
6941 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6942 if (blob != (char *) NULL)
6943 {
6944 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6945 blob=(unsigned char *) RelinquishMagickMemory(blob);
6946 }
6947 if (package_info->image_info->adjoin)
6948 break;
6949 }
6950
6951 PerlException:
6952 if (package_info != (struct PackageInfo *) NULL)
6953 DestroyPackageInfo(package_info);
6954 InheritPerlException(exception,perl_exception);
6955 exception=DestroyExceptionInfo(exception);
6956 SvREFCNT_dec(perl_exception); /* throw away all errors */
6957 }
6958
6959#
6960###############################################################################
6961# #
6962# #
6963# #
6964# L a y e r s #
6965# #
6966# #
6967# #
6968###############################################################################
6969#
6970#
6971void
6972Layers(ref,...)
6973 Image::Magick ref=NO_INIT
6974 ALIAS:
6975 Layers = 1
6976 layers = 2
6977 OptimizeImageLayers = 3
6978 optimizelayers = 4
6979 optimizeimagelayers = 5
6980 PPCODE:
6981 {
6982 AV
6983 *av;
6984
6985 char
6986 *attribute;
6987
6988 CompositeOperator
6989 compose;
6990
6991 ExceptionInfo
6992 *exception;
6993
6994 HV
6995 *hv;
6996
6997 Image
6998 *image,
6999 *layers;
7000
7001 LayerMethod
7002 method;
7003
7004 register ssize_t
7005 i;
7006
7007 ssize_t
7008 option,
7009 sp;
7010
7011 struct PackageInfo
7012 *info;
7013
7014 SV
7015 *av_reference,
7016 *perl_exception,
7017 *reference,
7018 *rv,
7019 *sv;
7020
7021 PERL_UNUSED_VAR(ref);
7022 PERL_UNUSED_VAR(ix);
7023 exception=AcquireExceptionInfo();
7024 perl_exception=newSVpv("",0);
7025 sv=NULL;
7026 if (sv_isobject(ST(0)) == 0)
7027 {
7028 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7029 PackageName);
7030 goto PerlException;
7031 }
7032 reference=SvRV(ST(0));
7033 hv=SvSTASH(reference);
7034 av=newAV();
7035 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7036 SvREFCNT_dec(av);
7037 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7038 if (image == (Image *) NULL)
7039 {
7040 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7041 PackageName);
7042 goto PerlException;
7043 }
7044 compose=image->compose;
7045 method=OptimizeLayer;
7046 for (i=2; i < items; i+=2)
7047 {
7048 attribute=(char *) SvPV(ST(i-1),na);
7049 switch (*attribute)
7050 {
7051 case 'C':
7052 case 'c':
7053 {
7054 if (LocaleCompare(attribute,"compose") == 0)
7055 {
7056 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7057 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7058 if (sp < 0)
7059 {
7060 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7061 SvPV(ST(i),na));
7062 break;
7063 }
7064 compose=(CompositeOperator) sp;
7065 break;
7066 }
7067 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7068 attribute);
7069 break;
7070 }
7071 case 'M':
7072 case 'm':
7073 {
7074 if (LocaleCompare(attribute,"method") == 0)
7075 {
7076 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7077 SvPV(ST(i),na));
7078 if (option < 0)
7079 {
7080 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7081 SvPV(ST(i),na));
7082 break;
7083 }
7084 method=(LayerMethod) option;
7085 break;
7086 }
7087 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7088 attribute);
7089 break;
7090 }
7091 default:
7092 {
7093 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7094 attribute);
7095 break;
7096 }
7097 }
7098 }
7099 layers=(Image *) NULL;
7100 switch (method)
7101 {
7102 case CompareAnyLayer:
7103 case CompareClearLayer:
7104 case CompareOverlayLayer:
7105 default:
7106 {
7107 layers=CompareImagesLayers(image,method,exception);
7108 break;
7109 }
7110 case MergeLayer:
7111 case FlattenLayer:
7112 case MosaicLayer:
7113 {
7114 layers=MergeImageLayers(image,method,exception);
7115 break;
7116 }
7117 case DisposeLayer:
7118 {
7119 layers=DisposeImages(image,exception);
7120 break;
7121 }
7122 case OptimizeImageLayer:
7123 {
7124 layers=OptimizeImageLayers(image,exception);
7125 break;
7126 }
7127 case OptimizePlusLayer:
7128 {
7129 layers=OptimizePlusImageLayers(image,exception);
7130 break;
7131 }
7132 case OptimizeTransLayer:
7133 {
7134 OptimizeImageTransparency(image,exception);
7135 break;
7136 }
7137 case RemoveDupsLayer:
7138 {
7139 RemoveDuplicateLayers(&image,exception);
7140 break;
7141 }
7142 case RemoveZeroLayer:
7143 {
7144 RemoveZeroDelayLayers(&image,exception);
7145 break;
7146 }
7147 case OptimizeLayer:
7148 {
7149 QuantizeInfo
7150 *quantize_info;
7151
7152 /*
7153 General Purpose, GIF Animation Optimizer.
7154 */
7155 layers=CoalesceImages(image,exception);
7156 if (layers == (Image *) NULL)
7157 break;
7158 image=layers;
7159 layers=OptimizeImageLayers(image,exception);
7160 if (layers == (Image *) NULL)
7161 break;
7162 image=DestroyImageList(image);
7163 image=layers;
7164 layers=(Image *) NULL;
7165 OptimizeImageTransparency(image,exception);
7166 quantize_info=AcquireQuantizeInfo(info->image_info);
7167 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7168 quantize_info=DestroyQuantizeInfo(quantize_info);
7169 break;
7170 }
7171 case CompositeLayer:
7172 {
7173 Image
7174 *source;
7175
7176 RectangleInfo
7177 geometry;
7178
7179 /*
7180 Split image sequence at the first 'NULL:' image.
7181 */
7182 source=image;
7183 while (source != (Image *) NULL)
7184 {
7185 source=GetNextImageInList(source);
7186 if ((source != (Image *) NULL) &&
7187 (LocaleCompare(source->magick,"NULL") == 0))
7188 break;
7189 }
7190 if (source != (Image *) NULL)
7191 {
7192 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7193 (GetNextImageInList(source) == (Image *) NULL))
7194 source=(Image *) NULL;
7195 else
7196 {
7197 /*
7198 Separate the two lists, junk the null: image.
7199 */
7200 source=SplitImageList(source->previous);
7201 DeleteImageFromList(&source);
7202 }
7203 }
7204 if (source == (Image *) NULL)
7205 {
7206 (void) ThrowMagickException(exception,GetMagickModule(),
7207 OptionError,"MissingNullSeparator","layers Composite");
7208 break;
7209 }
7210 /*
7211 Adjust offset with gravity and virtual canvas.
7212 */
7213 SetGeometry(image,&geometry);
7214 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7215 geometry.width=source->page.width != 0 ? source->page.width :
7216 source->columns;
7217 geometry.height=source->page.height != 0 ? source->page.height :
7218 source->rows;
7219 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7220 image->columns,image->page.height != 0 ? image->page.height :
7221 image->rows,image->gravity,&geometry);
7222 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7223 source=DestroyImageList(source);
7224 break;
7225 }
7226 }
7227 if (layers != (Image *) NULL)
7228 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007229 else
7230 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007231 if (image == (Image *) NULL)
7232 goto PerlException;
7233 for ( ; image; image=image->next)
7234 {
7235 AddImageToRegistry(sv,image);
7236 rv=newRV(sv);
7237 av_push(av,sv_bless(rv,hv));
7238 SvREFCNT_dec(sv);
7239 }
7240 exception=DestroyExceptionInfo(exception);
7241 ST(0)=av_reference;
7242 SvREFCNT_dec(perl_exception);
7243 XSRETURN(1);
7244
7245 PerlException:
7246 InheritPerlException(exception,perl_exception);
7247 exception=DestroyExceptionInfo(exception);
7248 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7249 SvPOK_on(perl_exception);
7250 ST(0)=sv_2mortal(perl_exception);
7251 XSRETURN(1);
7252 }
7253
7254#
7255###############################################################################
7256# #
7257# #
7258# #
7259# M a g i c k T o M i m e #
7260# #
7261# #
7262# #
7263###############################################################################
7264#
7265#
7266SV *
7267MagickToMime(ref,name)
7268 Image::Magick ref=NO_INIT
7269 char *name
7270 ALIAS:
7271 magicktomime = 1
7272 CODE:
7273 {
7274 char
7275 *mime;
7276
7277 PERL_UNUSED_VAR(ref);
7278 PERL_UNUSED_VAR(ix);
7279 mime=MagickToMime(name);
7280 RETVAL=newSVpv(mime,0);
7281 mime=(char *) RelinquishMagickMemory(mime);
7282 }
7283 OUTPUT:
7284 RETVAL
7285
7286#
7287###############################################################################
7288# #
7289# #
7290# #
7291# M o g r i f y #
7292# #
7293# #
7294# #
7295###############################################################################
7296#
7297#
7298void
7299Mogrify(ref,...)
7300 Image::Magick ref=NO_INIT
7301 ALIAS:
7302 Comment = 1
7303 CommentImage = 2
7304 Label = 3
7305 LabelImage = 4
7306 AddNoise = 5
7307 AddNoiseImage = 6
7308 Colorize = 7
7309 ColorizeImage = 8
7310 Border = 9
7311 BorderImage = 10
7312 Blur = 11
7313 BlurImage = 12
7314 Chop = 13
7315 ChopImage = 14
7316 Crop = 15
7317 CropImage = 16
7318 Despeckle = 17
7319 DespeckleImage = 18
7320 Edge = 19
7321 EdgeImage = 20
7322 Emboss = 21
7323 EmbossImage = 22
7324 Enhance = 23
7325 EnhanceImage = 24
7326 Flip = 25
7327 FlipImage = 26
7328 Flop = 27
7329 FlopImage = 28
7330 Frame = 29
7331 FrameImage = 30
7332 Implode = 31
7333 ImplodeImage = 32
7334 Magnify = 33
7335 MagnifyImage = 34
7336 MedianFilter = 35
7337 MedianConvolveImage = 36
7338 Minify = 37
7339 MinifyImage = 38
7340 OilPaint = 39
7341 OilPaintImage = 40
7342 ReduceNoise = 41
7343 ReduceNoiseImage = 42
7344 Roll = 43
7345 RollImage = 44
7346 Rotate = 45
7347 RotateImage = 46
7348 Sample = 47
7349 SampleImage = 48
7350 Scale = 49
7351 ScaleImage = 50
7352 Shade = 51
7353 ShadeImage = 52
7354 Sharpen = 53
7355 SharpenImage = 54
7356 Shear = 55
7357 ShearImage = 56
7358 Spread = 57
7359 SpreadImage = 58
7360 Swirl = 59
7361 SwirlImage = 60
7362 Resize = 61
7363 ResizeImage = 62
7364 Zoom = 63
7365 ZoomImage = 64
7366 Annotate = 65
7367 AnnotateImage = 66
7368 ColorFloodfill = 67
7369 ColorFloodfillImage= 68
7370 Composite = 69
7371 CompositeImage = 70
7372 Contrast = 71
7373 ContrastImage = 72
7374 CycleColormap = 73
7375 CycleColormapImage = 74
7376 Draw = 75
7377 DrawImage = 76
7378 Equalize = 77
7379 EqualizeImage = 78
7380 Gamma = 79
7381 GammaImage = 80
7382 Map = 81
7383 MapImage = 82
7384 MatteFloodfill = 83
7385 MatteFloodfillImage= 84
7386 Modulate = 85
7387 ModulateImage = 86
7388 Negate = 87
7389 NegateImage = 88
7390 Normalize = 89
7391 NormalizeImage = 90
7392 NumberColors = 91
7393 NumberColorsImage = 92
7394 Opaque = 93
7395 OpaqueImage = 94
7396 Quantize = 95
7397 QuantizeImage = 96
7398 Raise = 97
7399 RaiseImage = 98
7400 Segment = 99
7401 SegmentImage = 100
7402 Signature = 101
7403 SignatureImage = 102
7404 Solarize = 103
7405 SolarizeImage = 104
7406 Sync = 105
7407 SyncImage = 106
7408 Texture = 107
7409 TextureImage = 108
7410 Evaluate = 109
7411 EvaluateImage = 110
7412 Transparent = 111
7413 TransparentImage = 112
7414 Threshold = 113
7415 ThresholdImage = 114
7416 Charcoal = 115
7417 CharcoalImage = 116
7418 Trim = 117
7419 TrimImage = 118
7420 Wave = 119
7421 WaveImage = 120
7422 Separate = 121
7423 SeparateImage = 122
7424 Stereo = 125
7425 StereoImage = 126
7426 Stegano = 127
7427 SteganoImage = 128
7428 Deconstruct = 129
7429 DeconstructImage = 130
7430 GaussianBlur = 131
7431 GaussianBlurImage = 132
7432 Convolve = 133
7433 ConvolveImage = 134
7434 Profile = 135
7435 ProfileImage = 136
7436 UnsharpMask = 137
7437 UnsharpMaskImage = 138
7438 MotionBlur = 139
7439 MotionBlurImage = 140
7440 OrderedDither = 141
7441 OrderedDitherImage = 142
7442 Shave = 143
7443 ShaveImage = 144
7444 Level = 145
7445 LevelImage = 146
7446 Clip = 147
7447 ClipImage = 148
7448 AffineTransform = 149
7449 AffineTransformImage = 150
7450 Difference = 151
7451 DifferenceImage = 152
7452 AdaptiveThreshold = 153
7453 AdaptiveThresholdImage = 154
7454 Resample = 155
7455 ResampleImage = 156
7456 Describe = 157
7457 DescribeImage = 158
7458 BlackThreshold = 159
7459 BlackThresholdImage= 160
7460 WhiteThreshold = 161
7461 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007462 RotationalBlur = 163
7463 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007464 Thumbnail = 165
7465 ThumbnailImage = 166
7466 Strip = 167
7467 StripImage = 168
7468 Tint = 169
7469 TintImage = 170
7470 Channel = 171
7471 ChannelImage = 172
7472 Splice = 173
7473 SpliceImage = 174
7474 Posterize = 175
7475 PosterizeImage = 176
7476 Shadow = 177
7477 ShadowImage = 178
7478 Identify = 179
7479 IdentifyImage = 180
7480 SepiaTone = 181
7481 SepiaToneImage = 182
7482 SigmoidalContrast = 183
7483 SigmoidalContrastImage = 184
7484 Extent = 185
7485 ExtentImage = 186
7486 Vignette = 187
7487 VignetteImage = 188
7488 ContrastStretch = 189
7489 ContrastStretchImage = 190
7490 Sans0 = 191
7491 Sans0Image = 192
7492 Sans1 = 193
7493 Sans1Image = 194
7494 AdaptiveSharpen = 195
7495 AdaptiveSharpenImage = 196
7496 Transpose = 197
7497 TransposeImage = 198
7498 Transverse = 199
7499 TransverseImage = 200
7500 AutoOrient = 201
7501 AutoOrientImage = 202
7502 AdaptiveBlur = 203
7503 AdaptiveBlurImage = 204
7504 Sketch = 205
7505 SketchImage = 206
7506 UniqueColors = 207
7507 UniqueColorsImage = 208
7508 AdaptiveResize = 209
7509 AdaptiveResizeImage= 210
7510 ClipMask = 211
7511 ClipMaskImage = 212
7512 LinearStretch = 213
7513 LinearStretchImage = 214
7514 ColorMatrix = 215
7515 ColorMatrixImage = 216
7516 Mask = 217
7517 MaskImage = 218
7518 Polaroid = 219
7519 PolaroidImage = 220
7520 FloodfillPaint = 221
7521 FloodfillPaintImage= 222
7522 Distort = 223
7523 DistortImage = 224
7524 Clut = 225
7525 ClutImage = 226
7526 LiquidRescale = 227
7527 LiquidRescaleImage = 228
7528 Encipher = 229
7529 EncipherImage = 230
7530 Decipher = 231
7531 DecipherImage = 232
7532 Deskew = 233
7533 DeskewImage = 234
7534 Remap = 235
7535 RemapImage = 236
7536 SparseColor = 237
7537 SparseColorImage = 238
7538 Function = 239
7539 FunctionImage = 240
7540 SelectiveBlur = 241
7541 SelectiveBlurImage = 242
7542 HaldClut = 243
7543 HaldClutImage = 244
7544 BlueShift = 245
7545 BlueShiftImage = 246
7546 ForwardFourierTransform = 247
7547 ForwardFourierTransformImage = 248
7548 InverseFourierTransform = 249
7549 InverseFourierTransformImage = 250
7550 ColorDecisionList = 251
7551 ColorDecisionListImage = 252
7552 AutoGamma = 253
7553 AutoGammaImage = 254
7554 AutoLevel = 255
7555 AutoLevelImage = 256
7556 LevelColors = 257
7557 LevelImageColors = 258
7558 Clamp = 259
7559 ClampImage = 260
7560 BrightnessContrast = 261
7561 BrightnessContrastImage = 262
7562 Morphology = 263
7563 MorphologyImage = 264
Cristy3ca633e2016-02-13 12:49:01 -05007564 Mode = 265
7565 ModeImage = 266
7566 Statistic = 267
7567 StatisticImage = 268
7568 Perceptible = 269
7569 PerceptibleImage = 270
7570 Poly = 271
7571 PolyImage = 272
7572 Grayscale = 273
7573 GrayscaleImage = 274
7574 CannyEdge = 275
7575 CannyEdgeImage = 276
7576 HoughLine = 277
7577 HoughLineImage = 278
7578 MeanShift = 279
7579 MeanShiftImage = 280
7580 Kuwahara = 281
7581 KuwaharaImage = 282
7582 ConnectedComponent = 283
7583 ConnectedComponentImage = 284
7584 CopyPixels = 285
7585 CopyImagePixels = 286
Cristy5488c982016-02-13 14:07:50 -05007586 Color = 287
7587 ColorImage = 288
Cristy2d830ed2016-02-21 10:54:16 -05007588 WaveletDenoise = 289
7589 WaveletDenoiseImage= 290
cristy4a3ce0a2013-08-03 20:06:59 +00007590 MogrifyRegion = 666
7591 PPCODE:
7592 {
7593 AffineMatrix
7594 affine,
7595 current;
7596
7597 char
7598 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007599 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007600
7601 ChannelType
7602 channel,
7603 channel_mask;
7604
7605 CompositeOperator
7606 compose;
7607
7608 const char
7609 *attribute,
7610 *value;
7611
7612 double
7613 angle;
7614
7615 ExceptionInfo
7616 *exception;
7617
7618 GeometryInfo
7619 geometry_info;
7620
7621 Image
7622 *image,
7623 *next,
7624 *region_image;
7625
7626 MagickBooleanType
7627 status;
7628
7629 MagickStatusType
7630 flags;
7631
7632 PixelInfo
7633 fill_color;
7634
7635 RectangleInfo
7636 geometry,
7637 region_info;
7638
7639 register ssize_t
7640 i;
7641
7642 ssize_t
7643 base,
7644 j,
7645 number_images;
7646
7647 struct Methods
7648 *rp;
7649
7650 struct PackageInfo
7651 *info;
7652
7653 SV
7654 *perl_exception,
7655 **pv,
7656 *reference,
7657 **reference_vector;
7658
7659 struct ArgumentList
7660 argument_list[MaxArguments];
7661
7662 PERL_UNUSED_VAR(ref);
7663 PERL_UNUSED_VAR(ix);
7664 exception=AcquireExceptionInfo();
7665 perl_exception=newSVpv("",0);
7666 reference_vector=NULL;
7667 region_image=NULL;
7668 number_images=0;
7669 base=2;
7670 if (sv_isobject(ST(0)) == 0)
7671 {
7672 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7673 PackageName);
7674 goto PerlException;
7675 }
7676 reference=SvRV(ST(0));
7677 region_info.width=0;
7678 region_info.height=0;
7679 region_info.x=0;
7680 region_info.y=0;
7681 region_image=(Image *) NULL;
7682 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7683 if (ix && (ix != 666))
7684 {
7685 /*
7686 Called as Method(...)
7687 */
7688 ix=(ix+1)/2;
7689 rp=(&Methods[ix-1]);
7690 attribute=rp->name;
7691 }
7692 else
7693 {
7694 /*
7695 Called as Mogrify("Method",...)
7696 */
7697 attribute=(char *) SvPV(ST(1),na);
7698 if (ix)
7699 {
7700 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7701 attribute=(char *) SvPV(ST(2),na);
7702 base++;
7703 }
7704 for (rp=Methods; ; rp++)
7705 {
7706 if (rp >= EndOf(Methods))
7707 {
7708 ThrowPerlException(exception,OptionError,
7709 "UnrecognizedPerlMagickMethod",attribute);
7710 goto PerlException;
7711 }
7712 if (strEQcase(attribute,rp->name))
7713 break;
7714 }
7715 ix=rp-Methods+1;
7716 base++;
7717 }
7718 if (image == (Image *) NULL)
7719 {
7720 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7721 goto PerlException;
7722 }
7723 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7724 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7725 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7726 {
7727 Arguments
7728 *pp,
7729 *qq;
7730
7731 ssize_t
7732 ssize_test;
7733
7734 struct ArgumentList
7735 *al;
7736
7737 SV
7738 *sv;
7739
7740 sv=NULL;
7741 ssize_test=0;
7742 pp=(Arguments *) NULL;
7743 qq=rp->arguments;
7744 if (i == items)
7745 {
7746 pp=rp->arguments,
7747 sv=ST(i-1);
7748 }
7749 else
7750 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7751 {
7752 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7753 break;
7754 if (strEQcase(attribute,qq->method) > ssize_test)
7755 {
7756 pp=qq;
7757 ssize_test=strEQcase(attribute,qq->method);
7758 }
7759 }
7760 if (pp == (Arguments *) NULL)
7761 {
7762 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7763 attribute);
7764 goto continue_outer_loop;
7765 }
7766 al=(&argument_list[pp-rp->arguments]);
7767 switch (pp->type)
7768 {
7769 case ArrayReference:
7770 {
7771 if (SvTYPE(sv) != SVt_RV)
7772 {
cristy151b66d2015-04-15 10:50:31 +00007773 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007774 "invalid %.60s value",pp->method);
7775 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7776 goto continue_outer_loop;
7777 }
7778 al->array_reference=SvRV(sv);
7779 break;
7780 }
7781 case RealReference:
7782 {
7783 al->real_reference=SvNV(sv);
7784 break;
7785 }
7786 case FileReference:
7787 {
7788 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7789 break;
7790 }
7791 case ImageReference:
7792 {
7793 if (!sv_isobject(sv) ||
7794 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7795 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7796 {
7797 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7798 PackageName);
7799 goto PerlException;
7800 }
7801 break;
7802 }
7803 case IntegerReference:
7804 {
7805 al->integer_reference=SvIV(sv);
7806 break;
7807 }
7808 case StringReference:
7809 {
7810 al->string_reference=(char *) SvPV(sv,al->length);
7811 if (sv_isobject(sv))
7812 al->image_reference=SetupList(aTHX_ SvRV(sv),
7813 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7814 break;
7815 }
7816 default:
7817 {
7818 /*
7819 Is a string; look up name.
7820 */
7821 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7822 {
7823 al->string_reference=(char *) SvPV(sv,al->length);
7824 al->integer_reference=(-1);
7825 break;
7826 }
7827 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7828 MagickFalse,SvPV(sv,na));
7829 if (pp->type == MagickChannelOptions)
7830 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7831 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7832 {
cristy151b66d2015-04-15 10:50:31 +00007833 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007834 "invalid %.60s value",pp->method);
7835 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7836 goto continue_outer_loop;
7837 }
7838 break;
7839 }
7840 }
7841 attribute_flag[pp-rp->arguments]++;
7842 continue_outer_loop: ;
7843 }
7844 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7845 pv=reference_vector;
7846 SetGeometryInfo(&geometry_info);
7847 channel=DefaultChannels;
7848 for (next=image; next; next=next->next)
7849 {
7850 image=next;
7851 SetGeometry(image,&geometry);
7852 if ((region_info.width*region_info.height) != 0)
7853 {
7854 region_image=image;
7855 image=CropImage(image,&region_info,exception);
7856 }
7857 switch (ix)
7858 {
7859 default:
7860 {
cristy151b66d2015-04-15 10:50:31 +00007861 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007862 ThrowPerlException(exception,OptionError,
7863 "UnrecognizedPerlMagickMethod",message);
7864 goto PerlException;
7865 }
7866 case 1: /* Comment */
7867 {
7868 if (attribute_flag[0] == 0)
7869 argument_list[0].string_reference=(char *) NULL;
7870 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7871 info ? info->image_info : (ImageInfo *) NULL,image,
7872 argument_list[0].string_reference,exception),exception);
7873 break;
7874 }
7875 case 2: /* Label */
7876 {
7877 if (attribute_flag[0] == 0)
7878 argument_list[0].string_reference=(char *) NULL;
7879 (void) SetImageProperty(image,"label",InterpretImageProperties(
7880 info ? info->image_info : (ImageInfo *) NULL,image,
7881 argument_list[0].string_reference,exception),exception);
7882 break;
7883 }
7884 case 3: /* AddNoise */
7885 {
7886 double
7887 attenuate;
7888
7889 if (attribute_flag[0] == 0)
7890 argument_list[0].integer_reference=UniformNoise;
7891 attenuate=1.0;
7892 if (attribute_flag[1] != 0)
7893 attenuate=argument_list[1].real_reference;
7894 if (attribute_flag[2] != 0)
7895 channel=(ChannelType) argument_list[2].integer_reference;
7896 channel_mask=SetImageChannelMask(image,channel);
7897 image=AddNoiseImage(image,(NoiseType)
7898 argument_list[0].integer_reference,attenuate,exception);
7899 if (image != (Image *) NULL)
7900 (void) SetImageChannelMask(image,channel_mask);
7901 break;
7902 }
7903 case 4: /* Colorize */
7904 {
7905 PixelInfo
7906 target;
7907
7908 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7909 0,0,&target,exception);
7910 if (attribute_flag[0] != 0)
7911 (void) QueryColorCompliance(argument_list[0].string_reference,
7912 AllCompliance,&target,exception);
7913 if (attribute_flag[1] == 0)
7914 argument_list[1].string_reference="100%";
7915 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7916 exception);
7917 break;
7918 }
7919 case 5: /* Border */
7920 {
7921 CompositeOperator
7922 compose;
7923
7924 geometry.width=0;
7925 geometry.height=0;
7926 if (attribute_flag[0] != 0)
7927 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7928 &geometry,exception);
7929 if (attribute_flag[1] != 0)
7930 geometry.width=argument_list[1].integer_reference;
7931 if (attribute_flag[2] != 0)
7932 geometry.height=argument_list[2].integer_reference;
7933 if (attribute_flag[3] != 0)
7934 QueryColorCompliance(argument_list[3].string_reference,
7935 AllCompliance,&image->border_color,exception);
7936 if (attribute_flag[4] != 0)
7937 QueryColorCompliance(argument_list[4].string_reference,
7938 AllCompliance,&image->border_color,exception);
7939 if (attribute_flag[5] != 0)
7940 QueryColorCompliance(argument_list[5].string_reference,
7941 AllCompliance,&image->border_color,exception);
7942 compose=image->compose;
7943 if (attribute_flag[6] != 0)
7944 compose=(CompositeOperator) argument_list[6].integer_reference;
7945 image=BorderImage(image,&geometry,compose,exception);
7946 break;
7947 }
7948 case 6: /* Blur */
7949 {
7950 if (attribute_flag[0] != 0)
7951 {
7952 flags=ParseGeometry(argument_list[0].string_reference,
7953 &geometry_info);
7954 if ((flags & SigmaValue) == 0)
7955 geometry_info.sigma=1.0;
7956 }
7957 if (attribute_flag[1] != 0)
7958 geometry_info.rho=argument_list[1].real_reference;
7959 if (attribute_flag[2] != 0)
7960 geometry_info.sigma=argument_list[2].real_reference;
7961 if (attribute_flag[3] != 0)
7962 channel=(ChannelType) argument_list[3].integer_reference;
7963 channel_mask=SetImageChannelMask(image,channel);
7964 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
7965 exception);
7966 if (image != (Image *) NULL)
7967 (void) SetImageChannelMask(image,channel_mask);
7968 break;
7969 }
7970 case 7: /* Chop */
7971 {
cristy260bd762014-08-15 12:46:34 +00007972 if (attribute_flag[5] != 0)
7973 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00007974 if (attribute_flag[0] != 0)
7975 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7976 &geometry,exception);
7977 if (attribute_flag[1] != 0)
7978 geometry.width=argument_list[1].integer_reference;
7979 if (attribute_flag[2] != 0)
7980 geometry.height=argument_list[2].integer_reference;
7981 if (attribute_flag[3] != 0)
7982 geometry.x=argument_list[3].integer_reference;
7983 if (attribute_flag[4] != 0)
7984 geometry.y=argument_list[4].integer_reference;
7985 image=ChopImage(image,&geometry,exception);
7986 break;
7987 }
7988 case 8: /* Crop */
7989 {
7990 if (attribute_flag[6] != 0)
7991 image->gravity=(GravityType) argument_list[6].integer_reference;
7992 if (attribute_flag[0] != 0)
7993 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7994 &geometry,exception);
7995 if (attribute_flag[1] != 0)
7996 geometry.width=argument_list[1].integer_reference;
7997 if (attribute_flag[2] != 0)
7998 geometry.height=argument_list[2].integer_reference;
7999 if (attribute_flag[3] != 0)
8000 geometry.x=argument_list[3].integer_reference;
8001 if (attribute_flag[4] != 0)
8002 geometry.y=argument_list[4].integer_reference;
8003 if (attribute_flag[5] != 0)
8004 image->fuzz=StringToDoubleInterval(
8005 argument_list[5].string_reference,(double) QuantumRange+1.0);
8006 image=CropImage(image,&geometry,exception);
8007 break;
8008 }
8009 case 9: /* Despeckle */
8010 {
8011 image=DespeckleImage(image,exception);
8012 break;
8013 }
8014 case 10: /* Edge */
8015 {
8016 if (attribute_flag[0] != 0)
8017 geometry_info.rho=argument_list[0].real_reference;
8018 image=EdgeImage(image,geometry_info.rho,exception);
8019 break;
8020 }
8021 case 11: /* Emboss */
8022 {
8023 if (attribute_flag[0] != 0)
8024 {
8025 flags=ParseGeometry(argument_list[0].string_reference,
8026 &geometry_info);
8027 if ((flags & SigmaValue) == 0)
8028 geometry_info.sigma=1.0;
8029 }
8030 if (attribute_flag[1] != 0)
8031 geometry_info.rho=argument_list[1].real_reference;
8032 if (attribute_flag[2] != 0)
8033 geometry_info.sigma=argument_list[2].real_reference;
8034 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8035 exception);
8036 break;
8037 }
8038 case 12: /* Enhance */
8039 {
8040 image=EnhanceImage(image,exception);
8041 break;
8042 }
8043 case 13: /* Flip */
8044 {
8045 image=FlipImage(image,exception);
8046 break;
8047 }
8048 case 14: /* Flop */
8049 {
8050 image=FlopImage(image,exception);
8051 break;
8052 }
8053 case 15: /* Frame */
8054 {
8055 CompositeOperator
8056 compose;
8057
8058 FrameInfo
8059 frame_info;
8060
8061 if (attribute_flag[0] != 0)
8062 {
8063 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8064 &geometry,exception);
8065 frame_info.width=geometry.width;
8066 frame_info.height=geometry.height;
8067 frame_info.outer_bevel=geometry.x;
8068 frame_info.inner_bevel=geometry.y;
8069 }
8070 if (attribute_flag[1] != 0)
8071 frame_info.width=argument_list[1].integer_reference;
8072 if (attribute_flag[2] != 0)
8073 frame_info.height=argument_list[2].integer_reference;
8074 if (attribute_flag[3] != 0)
8075 frame_info.inner_bevel=argument_list[3].integer_reference;
8076 if (attribute_flag[4] != 0)
8077 frame_info.outer_bevel=argument_list[4].integer_reference;
8078 if (attribute_flag[5] != 0)
8079 QueryColorCompliance(argument_list[5].string_reference,
8080 AllCompliance,&fill_color,exception);
8081 if (attribute_flag[6] != 0)
8082 QueryColorCompliance(argument_list[6].string_reference,
8083 AllCompliance,&fill_color,exception);
8084 frame_info.x=(ssize_t) frame_info.width;
8085 frame_info.y=(ssize_t) frame_info.height;
8086 frame_info.width=image->columns+2*frame_info.x;
8087 frame_info.height=image->rows+2*frame_info.y;
8088 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
Cristy8645e042016-02-03 16:35:29 -05008089 image->alpha_color=fill_color;
cristy4a3ce0a2013-08-03 20:06:59 +00008090 compose=image->compose;
8091 if (attribute_flag[7] != 0)
8092 compose=(CompositeOperator) argument_list[7].integer_reference;
8093 image=FrameImage(image,&frame_info,compose,exception);
8094 break;
8095 }
8096 case 16: /* Implode */
8097 {
8098 PixelInterpolateMethod
8099 method;
8100
8101 if (attribute_flag[0] == 0)
8102 argument_list[0].real_reference=0.5;
8103 method=UndefinedInterpolatePixel;
8104 if (attribute_flag[1] != 0)
8105 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8106 image=ImplodeImage(image,argument_list[0].real_reference,
8107 method,exception);
8108 break;
8109 }
8110 case 17: /* Magnify */
8111 {
8112 image=MagnifyImage(image,exception);
8113 break;
8114 }
8115 case 18: /* MedianFilter */
8116 {
8117 if (attribute_flag[0] != 0)
8118 {
8119 flags=ParseGeometry(argument_list[0].string_reference,
8120 &geometry_info);
8121 if ((flags & SigmaValue) == 0)
8122 geometry_info.sigma=geometry_info.rho;
8123 }
8124 if (attribute_flag[1] != 0)
8125 geometry_info.rho=argument_list[1].real_reference;
8126 if (attribute_flag[2] != 0)
8127 geometry_info.sigma=argument_list[2].real_reference;
8128 if (attribute_flag[3] != 0)
8129 channel=(ChannelType) argument_list[3].integer_reference;
8130 channel_mask=SetImageChannelMask(image,channel);
8131 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8132 (size_t) geometry_info.sigma,exception);
8133 if (image != (Image *) NULL)
8134 (void) SetImageChannelMask(image,channel_mask);
8135 break;
8136 }
8137 case 19: /* Minify */
8138 {
8139 image=MinifyImage(image,exception);
8140 break;
8141 }
8142 case 20: /* OilPaint */
8143 {
8144 if (attribute_flag[0] == 0)
8145 argument_list[0].real_reference=0.0;
8146 if (attribute_flag[1] == 0)
8147 argument_list[1].real_reference=1.0;
8148 image=OilPaintImage(image,argument_list[0].real_reference,
8149 argument_list[1].real_reference,exception);
8150 break;
8151 }
8152 case 21: /* ReduceNoise */
8153 {
8154 if (attribute_flag[0] != 0)
8155 {
8156 flags=ParseGeometry(argument_list[0].string_reference,
8157 &geometry_info);
8158 if ((flags & SigmaValue) == 0)
8159 geometry_info.sigma=1.0;
8160 }
8161 if (attribute_flag[1] != 0)
8162 geometry_info.rho=argument_list[1].real_reference;
8163 if (attribute_flag[2] != 0)
8164 geometry_info.sigma=argument_list[2].real_reference;
8165 if (attribute_flag[3] != 0)
8166 channel=(ChannelType) argument_list[3].integer_reference;
8167 channel_mask=SetImageChannelMask(image,channel);
8168 image=StatisticImage(image,NonpeakStatistic,(size_t)
8169 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8170 if (image != (Image *) NULL)
8171 (void) SetImageChannelMask(image,channel_mask);
8172 break;
8173 }
8174 case 22: /* Roll */
8175 {
8176 if (attribute_flag[0] != 0)
8177 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8178 &geometry,exception);
8179 if (attribute_flag[1] != 0)
8180 geometry.x=argument_list[1].integer_reference;
8181 if (attribute_flag[2] != 0)
8182 geometry.y=argument_list[2].integer_reference;
8183 image=RollImage(image,geometry.x,geometry.y,exception);
8184 break;
8185 }
8186 case 23: /* Rotate */
8187 {
8188 if (attribute_flag[0] == 0)
8189 argument_list[0].real_reference=90.0;
8190 if (attribute_flag[1] != 0)
8191 {
8192 QueryColorCompliance(argument_list[1].string_reference,
8193 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008194 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8195 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008196 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8197 }
8198 image=RotateImage(image,argument_list[0].real_reference,exception);
8199 break;
8200 }
8201 case 24: /* Sample */
8202 {
8203 if (attribute_flag[0] != 0)
8204 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8205 &geometry,exception);
8206 if (attribute_flag[1] != 0)
8207 geometry.width=argument_list[1].integer_reference;
8208 if (attribute_flag[2] != 0)
8209 geometry.height=argument_list[2].integer_reference;
8210 image=SampleImage(image,geometry.width,geometry.height,exception);
8211 break;
8212 }
8213 case 25: /* Scale */
8214 {
8215 if (attribute_flag[0] != 0)
8216 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8217 &geometry,exception);
8218 if (attribute_flag[1] != 0)
8219 geometry.width=argument_list[1].integer_reference;
8220 if (attribute_flag[2] != 0)
8221 geometry.height=argument_list[2].integer_reference;
8222 image=ScaleImage(image,geometry.width,geometry.height,exception);
8223 break;
8224 }
8225 case 26: /* Shade */
8226 {
8227 if (attribute_flag[0] != 0)
8228 {
8229 flags=ParseGeometry(argument_list[0].string_reference,
8230 &geometry_info);
8231 if ((flags & SigmaValue) == 0)
8232 geometry_info.sigma=0.0;
8233 }
8234 if (attribute_flag[1] != 0)
8235 geometry_info.rho=argument_list[1].real_reference;
8236 if (attribute_flag[2] != 0)
8237 geometry_info.sigma=argument_list[2].real_reference;
8238 image=ShadeImage(image,
8239 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8240 geometry_info.rho,geometry_info.sigma,exception);
8241 break;
8242 }
8243 case 27: /* Sharpen */
8244 {
8245 if (attribute_flag[0] != 0)
8246 {
8247 flags=ParseGeometry(argument_list[0].string_reference,
8248 &geometry_info);
8249 if ((flags & SigmaValue) == 0)
8250 geometry_info.sigma=1.0;
8251 }
8252 if (attribute_flag[1] != 0)
8253 geometry_info.rho=argument_list[1].real_reference;
8254 if (attribute_flag[2] != 0)
8255 geometry_info.sigma=argument_list[2].real_reference;
8256 if (attribute_flag[3] != 0)
8257 channel=(ChannelType) argument_list[3].integer_reference;
8258 channel_mask=SetImageChannelMask(image,channel);
8259 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8260 exception);
8261 if (image != (Image *) NULL)
8262 (void) SetImageChannelMask(image,channel_mask);
8263 break;
8264 }
8265 case 28: /* Shear */
8266 {
8267 if (attribute_flag[0] != 0)
8268 {
8269 flags=ParseGeometry(argument_list[0].string_reference,
8270 &geometry_info);
8271 if ((flags & SigmaValue) == 0)
8272 geometry_info.sigma=geometry_info.rho;
8273 }
8274 if (attribute_flag[1] != 0)
8275 geometry_info.rho=argument_list[1].real_reference;
8276 if (attribute_flag[2] != 0)
8277 geometry_info.sigma=argument_list[2].real_reference;
8278 if (attribute_flag[3] != 0)
8279 QueryColorCompliance(argument_list[3].string_reference,
8280 AllCompliance,&image->background_color,exception);
8281 if (attribute_flag[4] != 0)
8282 QueryColorCompliance(argument_list[4].string_reference,
8283 AllCompliance,&image->background_color,exception);
8284 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8285 exception);
8286 break;
8287 }
8288 case 29: /* Spread */
8289 {
Cristye3319c12015-08-24 07:11:48 -04008290 PixelInterpolateMethod
8291 method;
8292
cristy4a3ce0a2013-08-03 20:06:59 +00008293 if (attribute_flag[0] == 0)
8294 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008295 method=UndefinedInterpolatePixel;
8296 if (attribute_flag[1] != 0)
8297 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8298 image=SpreadImage(image,method,argument_list[0].real_reference,
8299 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008300 break;
8301 }
8302 case 30: /* Swirl */
8303 {
8304 PixelInterpolateMethod
8305 method;
8306
8307 if (attribute_flag[0] == 0)
8308 argument_list[0].real_reference=50.0;
8309 method=UndefinedInterpolatePixel;
8310 if (attribute_flag[1] != 0)
8311 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8312 image=SwirlImage(image,argument_list[0].real_reference,
8313 method,exception);
8314 break;
8315 }
8316 case 31: /* Resize */
8317 case 32: /* Zoom */
8318 {
8319 if (attribute_flag[0] != 0)
8320 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8321 &geometry,exception);
8322 if (attribute_flag[1] != 0)
8323 geometry.width=argument_list[1].integer_reference;
8324 if (attribute_flag[2] != 0)
8325 geometry.height=argument_list[2].integer_reference;
8326 if (attribute_flag[3] == 0)
8327 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8328 if (attribute_flag[4] != 0)
8329 SetImageArtifact(image,"filter:support",
8330 argument_list[4].string_reference);
8331 image=ResizeImage(image,geometry.width,geometry.height,
Cristy8645e042016-02-03 16:35:29 -05008332 (FilterType) argument_list[3].integer_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00008333 exception);
8334 break;
8335 }
8336 case 33: /* Annotate */
8337 {
8338 DrawInfo
8339 *draw_info;
8340
8341 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8342 (DrawInfo *) NULL);
8343 if (attribute_flag[0] != 0)
8344 {
8345 char
8346 *text;
8347
8348 text=InterpretImageProperties(info ? info->image_info :
8349 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8350 exception);
8351 (void) CloneString(&draw_info->text,text);
8352 text=DestroyString(text);
8353 }
8354 if (attribute_flag[1] != 0)
8355 (void) CloneString(&draw_info->font,
8356 argument_list[1].string_reference);
8357 if (attribute_flag[2] != 0)
8358 draw_info->pointsize=argument_list[2].real_reference;
8359 if (attribute_flag[3] != 0)
8360 (void) CloneString(&draw_info->density,
8361 argument_list[3].string_reference);
8362 if (attribute_flag[4] != 0)
8363 (void) QueryColorCompliance(argument_list[4].string_reference,
8364 AllCompliance,&draw_info->undercolor,exception);
8365 if (attribute_flag[5] != 0)
8366 {
8367 (void) QueryColorCompliance(argument_list[5].string_reference,
8368 AllCompliance,&draw_info->stroke,exception);
8369 if (argument_list[5].image_reference != (Image *) NULL)
8370 draw_info->stroke_pattern=CloneImage(
8371 argument_list[5].image_reference,0,0,MagickTrue,exception);
8372 }
8373 if (attribute_flag[6] != 0)
8374 {
8375 (void) QueryColorCompliance(argument_list[6].string_reference,
8376 AllCompliance,&draw_info->fill,exception);
8377 if (argument_list[6].image_reference != (Image *) NULL)
8378 draw_info->fill_pattern=CloneImage(
8379 argument_list[6].image_reference,0,0,MagickTrue,exception);
8380 }
8381 if (attribute_flag[7] != 0)
8382 {
8383 (void) CloneString(&draw_info->geometry,
8384 argument_list[7].string_reference);
8385 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8386 &geometry,exception);
8387 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8388 geometry_info.sigma=geometry_info.xi;
8389 }
8390 if (attribute_flag[8] != 0)
8391 (void) QueryColorCompliance(argument_list[8].string_reference,
8392 AllCompliance,&draw_info->fill,exception);
8393 if (attribute_flag[11] != 0)
8394 draw_info->gravity=(GravityType)
8395 argument_list[11].integer_reference;
8396 if (attribute_flag[25] != 0)
8397 {
8398 AV
8399 *av;
8400
8401 av=(AV *) argument_list[25].array_reference;
8402 if ((av_len(av) != 3) && (av_len(av) != 5))
8403 {
8404 ThrowPerlException(exception,OptionError,
8405 "affine matrix must have 4 or 6 elements",PackageName);
8406 goto PerlException;
8407 }
8408 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8409 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8410 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8411 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8412 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8413 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8414 {
8415 ThrowPerlException(exception,OptionError,
8416 "affine matrix is singular",PackageName);
8417 goto PerlException;
8418 }
8419 if (av_len(av) == 5)
8420 {
8421 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8422 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8423 }
8424 }
8425 for (j=12; j < 17; j++)
8426 {
8427 if (attribute_flag[j] == 0)
8428 continue;
8429 value=argument_list[j].string_reference;
8430 angle=argument_list[j].real_reference;
8431 current=draw_info->affine;
8432 GetAffineMatrix(&affine);
8433 switch (j)
8434 {
8435 case 12:
8436 {
8437 /*
8438 Translate.
8439 */
8440 flags=ParseGeometry(value,&geometry_info);
8441 affine.tx=geometry_info.xi;
8442 affine.ty=geometry_info.psi;
8443 if ((flags & PsiValue) == 0)
8444 affine.ty=affine.tx;
8445 break;
8446 }
8447 case 13:
8448 {
8449 /*
8450 Scale.
8451 */
8452 flags=ParseGeometry(value,&geometry_info);
8453 affine.sx=geometry_info.rho;
8454 affine.sy=geometry_info.sigma;
8455 if ((flags & SigmaValue) == 0)
8456 affine.sy=affine.sx;
8457 break;
8458 }
8459 case 14:
8460 {
8461 /*
8462 Rotate.
8463 */
8464 if (angle == 0.0)
8465 break;
8466 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8467 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8468 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8469 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8470 break;
8471 }
8472 case 15:
8473 {
8474 /*
8475 SkewX.
8476 */
8477 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8478 break;
8479 }
8480 case 16:
8481 {
8482 /*
8483 SkewY.
8484 */
8485 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8486 break;
8487 }
8488 }
8489 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8490 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8491 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8492 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8493 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8494 current.tx;
8495 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8496 current.ty;
8497 }
8498 if (attribute_flag[9] == 0)
8499 argument_list[9].real_reference=0.0;
8500 if (attribute_flag[10] == 0)
8501 argument_list[10].real_reference=0.0;
8502 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8503 {
8504 char
cristy151b66d2015-04-15 10:50:31 +00008505 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008506
cristy151b66d2015-04-15 10:50:31 +00008507 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008508 (double) argument_list[9].real_reference+draw_info->affine.tx,
8509 (double) argument_list[10].real_reference+draw_info->affine.ty);
8510 (void) CloneString(&draw_info->geometry,geometry);
8511 }
8512 if (attribute_flag[17] != 0)
8513 draw_info->stroke_width=argument_list[17].real_reference;
8514 if (attribute_flag[18] != 0)
8515 {
8516 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8517 MagickTrue : MagickFalse;
8518 draw_info->stroke_antialias=draw_info->text_antialias;
8519 }
8520 if (attribute_flag[19] != 0)
8521 (void) CloneString(&draw_info->family,
8522 argument_list[19].string_reference);
8523 if (attribute_flag[20] != 0)
8524 draw_info->style=(StyleType) argument_list[20].integer_reference;
8525 if (attribute_flag[21] != 0)
8526 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8527 if (attribute_flag[22] != 0)
8528 draw_info->weight=argument_list[22].integer_reference;
8529 if (attribute_flag[23] != 0)
8530 draw_info->align=(AlignType) argument_list[23].integer_reference;
8531 if (attribute_flag[24] != 0)
8532 (void) CloneString(&draw_info->encoding,
8533 argument_list[24].string_reference);
8534 if (attribute_flag[25] != 0)
8535 draw_info->fill_pattern=CloneImage(
8536 argument_list[25].image_reference,0,0,MagickTrue,exception);
8537 if (attribute_flag[26] != 0)
8538 draw_info->fill_pattern=CloneImage(
8539 argument_list[26].image_reference,0,0,MagickTrue,exception);
8540 if (attribute_flag[27] != 0)
8541 draw_info->stroke_pattern=CloneImage(
8542 argument_list[27].image_reference,0,0,MagickTrue,exception);
8543 if (attribute_flag[29] != 0)
8544 draw_info->kerning=argument_list[29].real_reference;
8545 if (attribute_flag[30] != 0)
8546 draw_info->interline_spacing=argument_list[30].real_reference;
8547 if (attribute_flag[31] != 0)
8548 draw_info->interword_spacing=argument_list[31].real_reference;
8549 if (attribute_flag[32] != 0)
8550 draw_info->direction=(DirectionType)
8551 argument_list[32].integer_reference;
8552 (void) AnnotateImage(image,draw_info,exception);
8553 draw_info=DestroyDrawInfo(draw_info);
8554 break;
8555 }
8556 case 34: /* ColorFloodfill */
8557 {
8558 DrawInfo
8559 *draw_info;
8560
8561 MagickBooleanType
8562 invert;
8563
8564 PixelInfo
8565 target;
8566
8567 draw_info=CloneDrawInfo(info ? info->image_info :
8568 (ImageInfo *) NULL,(DrawInfo *) NULL);
8569 if (attribute_flag[0] != 0)
8570 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8571 &geometry,exception);
8572 if (attribute_flag[1] != 0)
8573 geometry.x=argument_list[1].integer_reference;
8574 if (attribute_flag[2] != 0)
8575 geometry.y=argument_list[2].integer_reference;
8576 if (attribute_flag[3] != 0)
8577 (void) QueryColorCompliance(argument_list[3].string_reference,
8578 AllCompliance,&draw_info->fill,exception);
8579 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8580 geometry.x,geometry.y,&target,exception);
8581 invert=MagickFalse;
8582 if (attribute_flag[4] != 0)
8583 {
8584 QueryColorCompliance(argument_list[4].string_reference,
8585 AllCompliance,&target,exception);
8586 invert=MagickTrue;
8587 }
8588 if (attribute_flag[5] != 0)
8589 image->fuzz=StringToDoubleInterval(
8590 argument_list[5].string_reference,(double) QuantumRange+1.0);
8591 if (attribute_flag[6] != 0)
8592 invert=(MagickBooleanType) argument_list[6].integer_reference;
8593 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8594 geometry.y,invert,exception);
8595 draw_info=DestroyDrawInfo(draw_info);
8596 break;
8597 }
8598 case 35: /* Composite */
8599 {
8600 char
cristy151b66d2015-04-15 10:50:31 +00008601 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008602
8603 Image
8604 *composite_image,
8605 *rotate_image;
8606
8607 MagickBooleanType
8608 clip_to_self;
8609
8610 compose=OverCompositeOp;
8611 if (attribute_flag[0] != 0)
8612 composite_image=argument_list[0].image_reference;
8613 else
8614 {
8615 ThrowPerlException(exception,OptionError,
8616 "CompositeImageRequired",PackageName);
8617 goto PerlException;
8618 }
8619 /*
8620 Parameter Handling used for BOTH normal and tiled composition.
8621 */
8622 if (attribute_flag[1] != 0) /* compose */
8623 compose=(CompositeOperator) argument_list[1].integer_reference;
8624 if (attribute_flag[6] != 0) /* opacity */
8625 {
8626 if (compose != DissolveCompositeOp)
8627 (void) SetImageAlpha(composite_image,(Quantum)
8628 StringToDoubleInterval(argument_list[6].string_reference,
8629 (double) QuantumRange+1.0),exception);
8630 else
8631 {
8632 CacheView
8633 *composite_view;
8634
8635 double
8636 opacity;
8637
8638 MagickBooleanType
8639 sync;
8640
8641 register ssize_t
8642 x;
8643
8644 register Quantum
8645 *q;
8646
8647 ssize_t
8648 y;
8649
8650 /*
8651 Handle dissolve composite operator (patch by
8652 Kevin A. McGrail).
8653 */
8654 (void) CloneString(&image->geometry,
8655 argument_list[6].string_reference);
8656 opacity=(Quantum) StringToDoubleInterval(
8657 argument_list[6].string_reference,(double) QuantumRange+
8658 1.0);
cristy17f11b02014-12-20 19:37:04 +00008659 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008660 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8661 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8662 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8663 {
8664 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8665 composite_image->columns,1,exception);
8666 for (x=0; x < (ssize_t) composite_image->columns; x++)
8667 {
8668 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8669 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8670 q);
8671 q+=GetPixelChannels(composite_image);
8672 }
8673 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8674 if (sync == MagickFalse)
8675 break;
8676 }
8677 composite_view=DestroyCacheView(composite_view);
8678 }
8679 }
8680 if (attribute_flag[9] != 0) /* "color=>" */
8681 QueryColorCompliance(argument_list[9].string_reference,
8682 AllCompliance,&composite_image->background_color,exception);
8683 if (attribute_flag[12] != 0) /* "interpolate=>" */
8684 image->interpolate=(PixelInterpolateMethod)
8685 argument_list[12].integer_reference;
8686 if (attribute_flag[13] != 0) /* "args=>" */
8687 (void) SetImageArtifact(composite_image,"compose:args",
8688 argument_list[13].string_reference);
8689 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8690 (void) SetImageArtifact(composite_image,"compose:args",
8691 argument_list[14].string_reference);
8692 clip_to_self=MagickTrue;
8693 if (attribute_flag[15] != 0)
8694 clip_to_self=(MagickBooleanType)
8695 argument_list[15].integer_reference;
8696 /*
8697 Tiling Composition (with orthogonal rotate).
8698 */
8699 rotate_image=(Image *) NULL;
8700 if (attribute_flag[8] != 0) /* "rotate=>" */
8701 {
8702 /*
8703 Rotate image.
8704 */
8705 rotate_image=RotateImage(composite_image,
8706 argument_list[8].real_reference,exception);
8707 if (rotate_image == (Image *) NULL)
8708 break;
8709 }
8710 if ((attribute_flag[7] != 0) &&
8711 (argument_list[7].integer_reference != 0)) /* tile */
8712 {
8713 ssize_t
8714 x,
8715 y;
8716
8717 /*
8718 Tile the composite image.
8719 */
8720 if (attribute_flag[8] != 0) /* "tile=>" */
8721 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8722 "false");
8723 else
8724 (void) SetImageArtifact(composite_image,
8725 "compose:outside-overlay","false");
8726 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8727 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8728 {
8729 if (attribute_flag[8] != 0) /* rotate */
8730 (void) CompositeImage(image,rotate_image,compose,
8731 MagickTrue,x,y,exception);
8732 else
8733 (void) CompositeImage(image,composite_image,compose,
8734 MagickTrue,x,y,exception);
8735 }
8736 if (attribute_flag[8] != 0) /* rotate */
8737 rotate_image=DestroyImage(rotate_image);
8738 break;
8739 }
8740 /*
8741 Parameter Handling used used ONLY for normal composition.
8742 */
8743 if (attribute_flag[5] != 0) /* gravity */
8744 image->gravity=(GravityType) argument_list[5].integer_reference;
8745 if (attribute_flag[2] != 0) /* geometry offset */
8746 {
8747 SetGeometry(image,&geometry);
8748 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8749 &geometry);
8750 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8751 &geometry);
8752 }
8753 if (attribute_flag[3] != 0) /* x offset */
8754 geometry.x=argument_list[3].integer_reference;
8755 if (attribute_flag[4] != 0) /* y offset */
8756 geometry.y=argument_list[4].integer_reference;
8757 if (attribute_flag[10] != 0) /* mask */
8758 {
8759 if ((image->compose == DisplaceCompositeOp) ||
8760 (image->compose == DistortCompositeOp))
8761 {
8762 /*
8763 Merge Y displacement into X displacement image.
8764 */
8765 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8766 exception);
8767 (void) CompositeImage(composite_image,
8768 argument_list[10].image_reference,CopyGreenCompositeOp,
8769 MagickTrue,0,0,exception);
8770 }
8771 else
8772 {
8773 Image
8774 *mask_image;
8775
8776 /*
8777 Set a blending mask for the composition.
8778 */
8779 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8780 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008781 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008782 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008783 mask_image=DestroyImage(mask_image);
8784 }
8785 }
8786 if (attribute_flag[11] != 0) /* channel */
8787 channel=(ChannelType) argument_list[11].integer_reference;
8788 /*
8789 Composite two images (normal composition).
8790 */
cristy151b66d2015-04-15 10:50:31 +00008791 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008792 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8793 (double) composite_image->rows,(double) geometry.x,(double)
8794 geometry.y);
8795 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8796 exception);
8797 channel_mask=SetImageChannelMask(image,channel);
8798 if (attribute_flag[8] == 0) /* no rotate */
8799 CompositeImage(image,composite_image,compose,clip_to_self,
8800 geometry.x,geometry.y,exception);
8801 else
8802 {
8803 /*
8804 Position adjust rotated image then composite.
8805 */
8806 geometry.x-=(ssize_t) (rotate_image->columns-
8807 composite_image->columns)/2;
8808 geometry.y-=(ssize_t) (rotate_image->rows-
8809 composite_image->rows)/2;
8810 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8811 geometry.y,exception);
8812 rotate_image=DestroyImage(rotate_image);
8813 }
8814 if (attribute_flag[10] != 0) /* mask */
8815 {
8816 if ((image->compose == DisplaceCompositeOp) ||
8817 (image->compose == DistortCompositeOp))
8818 composite_image=DestroyImage(composite_image);
8819 else
cristy1f7ffb72015-07-29 11:07:03 +00008820 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008821 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008822 }
8823 (void) SetImageChannelMask(image,channel_mask);
8824 break;
8825 }
8826 case 36: /* Contrast */
8827 {
8828 if (attribute_flag[0] == 0)
8829 argument_list[0].integer_reference=0;
8830 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8831 MagickTrue : MagickFalse,exception);
8832 break;
8833 }
8834 case 37: /* CycleColormap */
8835 {
8836 if (attribute_flag[0] == 0)
8837 argument_list[0].integer_reference=6;
8838 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8839 exception);
8840 break;
8841 }
8842 case 38: /* Draw */
8843 {
8844 DrawInfo
8845 *draw_info;
8846
8847 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8848 (DrawInfo *) NULL);
8849 (void) CloneString(&draw_info->primitive,"point");
8850 if (attribute_flag[0] != 0)
8851 {
8852 if (argument_list[0].integer_reference < 0)
8853 (void) CloneString(&draw_info->primitive,
8854 argument_list[0].string_reference);
8855 else
8856 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8857 MagickPrimitiveOptions,argument_list[0].integer_reference));
8858 }
8859 if (attribute_flag[1] != 0)
8860 {
8861 if (LocaleCompare(draw_info->primitive,"path") == 0)
8862 {
8863 (void) ConcatenateString(&draw_info->primitive," '");
8864 ConcatenateString(&draw_info->primitive,
8865 argument_list[1].string_reference);
8866 (void) ConcatenateString(&draw_info->primitive,"'");
8867 }
8868 else
8869 {
8870 (void) ConcatenateString(&draw_info->primitive," ");
8871 ConcatenateString(&draw_info->primitive,
8872 argument_list[1].string_reference);
8873 }
8874 }
8875 if (attribute_flag[2] != 0)
8876 {
8877 (void) ConcatenateString(&draw_info->primitive," ");
8878 (void) ConcatenateString(&draw_info->primitive,
8879 CommandOptionToMnemonic(MagickMethodOptions,
8880 argument_list[2].integer_reference));
8881 }
8882 if (attribute_flag[3] != 0)
8883 {
8884 (void) QueryColorCompliance(argument_list[3].string_reference,
8885 AllCompliance,&draw_info->stroke,exception);
8886 if (argument_list[3].image_reference != (Image *) NULL)
8887 draw_info->stroke_pattern=CloneImage(
8888 argument_list[3].image_reference,0,0,MagickTrue,exception);
8889 }
8890 if (attribute_flag[4] != 0)
8891 {
8892 (void) QueryColorCompliance(argument_list[4].string_reference,
8893 AllCompliance,&draw_info->fill,exception);
8894 if (argument_list[4].image_reference != (Image *) NULL)
8895 draw_info->fill_pattern=CloneImage(
8896 argument_list[4].image_reference,0,0,MagickTrue,exception);
8897 }
8898 if (attribute_flag[5] != 0)
8899 draw_info->stroke_width=argument_list[5].real_reference;
8900 if (attribute_flag[6] != 0)
8901 (void) CloneString(&draw_info->font,
8902 argument_list[6].string_reference);
8903 if (attribute_flag[7] != 0)
8904 (void) QueryColorCompliance(argument_list[7].string_reference,
8905 AllCompliance,&draw_info->border_color,exception);
8906 if (attribute_flag[8] != 0)
8907 draw_info->affine.tx=argument_list[8].real_reference;
8908 if (attribute_flag[9] != 0)
8909 draw_info->affine.ty=argument_list[9].real_reference;
8910 if (attribute_flag[20] != 0)
8911 {
8912 AV
8913 *av;
8914
8915 av=(AV *) argument_list[20].array_reference;
8916 if ((av_len(av) != 3) && (av_len(av) != 5))
8917 {
8918 ThrowPerlException(exception,OptionError,
8919 "affine matrix must have 4 or 6 elements",PackageName);
8920 goto PerlException;
8921 }
8922 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8923 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8924 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8925 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8926 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8927 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8928 {
8929 ThrowPerlException(exception,OptionError,
8930 "affine matrix is singular",PackageName);
8931 goto PerlException;
8932 }
8933 if (av_len(av) == 5)
8934 {
8935 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8936 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8937 }
8938 }
8939 for (j=10; j < 15; j++)
8940 {
8941 if (attribute_flag[j] == 0)
8942 continue;
8943 value=argument_list[j].string_reference;
8944 angle=argument_list[j].real_reference;
8945 current=draw_info->affine;
8946 GetAffineMatrix(&affine);
8947 switch (j)
8948 {
8949 case 10:
8950 {
8951 /*
8952 Translate.
8953 */
8954 flags=ParseGeometry(value,&geometry_info);
8955 affine.tx=geometry_info.xi;
8956 affine.ty=geometry_info.psi;
8957 if ((flags & PsiValue) == 0)
8958 affine.ty=affine.tx;
8959 break;
8960 }
8961 case 11:
8962 {
8963 /*
8964 Scale.
8965 */
8966 flags=ParseGeometry(value,&geometry_info);
8967 affine.sx=geometry_info.rho;
8968 affine.sy=geometry_info.sigma;
8969 if ((flags & SigmaValue) == 0)
8970 affine.sy=affine.sx;
8971 break;
8972 }
8973 case 12:
8974 {
8975 /*
8976 Rotate.
8977 */
8978 if (angle == 0.0)
8979 break;
8980 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8981 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8982 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8983 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8984 break;
8985 }
8986 case 13:
8987 {
8988 /*
8989 SkewX.
8990 */
8991 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8992 break;
8993 }
8994 case 14:
8995 {
8996 /*
8997 SkewY.
8998 */
8999 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9000 break;
9001 }
9002 }
9003 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9004 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9005 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9006 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9007 draw_info->affine.tx=
9008 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9009 draw_info->affine.ty=
9010 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9011 }
9012 if (attribute_flag[15] != 0)
9013 draw_info->fill_pattern=CloneImage(
9014 argument_list[15].image_reference,0,0,MagickTrue,exception);
9015 if (attribute_flag[16] != 0)
9016 draw_info->pointsize=argument_list[16].real_reference;
9017 if (attribute_flag[17] != 0)
9018 {
9019 draw_info->stroke_antialias=argument_list[17].integer_reference != 0
9020 ? MagickTrue : MagickFalse;
9021 draw_info->text_antialias=draw_info->stroke_antialias;
9022 }
9023 if (attribute_flag[18] != 0)
9024 (void) CloneString(&draw_info->density,
9025 argument_list[18].string_reference);
9026 if (attribute_flag[19] != 0)
9027 draw_info->stroke_width=argument_list[19].real_reference;
9028 if (attribute_flag[21] != 0)
9029 draw_info->dash_offset=argument_list[21].real_reference;
9030 if (attribute_flag[22] != 0)
9031 {
9032 AV
9033 *av;
9034
9035 av=(AV *) argument_list[22].array_reference;
9036 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9037 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9038 if (draw_info->dash_pattern != (double *) NULL)
9039 {
9040 for (i=0; i <= av_len(av); i++)
9041 draw_info->dash_pattern[i]=(double)
9042 SvNV(*(av_fetch(av,i,0)));
9043 draw_info->dash_pattern[i]=0.0;
9044 }
9045 }
9046 if (attribute_flag[23] != 0)
9047 image->interpolate=(PixelInterpolateMethod)
9048 argument_list[23].integer_reference;
9049 if ((attribute_flag[24] != 0) &&
9050 (draw_info->fill_pattern != (Image *) NULL))
9051 flags=ParsePageGeometry(draw_info->fill_pattern,
9052 argument_list[24].string_reference,
9053 &draw_info->fill_pattern->tile_offset,exception);
9054 if (attribute_flag[25] != 0)
9055 {
9056 (void) ConcatenateString(&draw_info->primitive," '");
9057 (void) ConcatenateString(&draw_info->primitive,
9058 argument_list[25].string_reference);
9059 (void) ConcatenateString(&draw_info->primitive,"'");
9060 }
9061 if (attribute_flag[26] != 0)
9062 draw_info->fill_pattern=CloneImage(
9063 argument_list[26].image_reference,0,0,MagickTrue,exception);
9064 if (attribute_flag[27] != 0)
9065 draw_info->stroke_pattern=CloneImage(
9066 argument_list[27].image_reference,0,0,MagickTrue,exception);
9067 if (attribute_flag[28] != 0)
9068 (void) CloneString(&draw_info->primitive,
9069 argument_list[28].string_reference);
9070 if (attribute_flag[29] != 0)
9071 draw_info->kerning=argument_list[29].real_reference;
9072 if (attribute_flag[30] != 0)
9073 draw_info->interline_spacing=argument_list[30].real_reference;
9074 if (attribute_flag[31] != 0)
9075 draw_info->interword_spacing=argument_list[31].real_reference;
9076 if (attribute_flag[32] != 0)
9077 draw_info->direction=(DirectionType)
9078 argument_list[32].integer_reference;
9079 DrawImage(image,draw_info,exception);
9080 draw_info=DestroyDrawInfo(draw_info);
9081 break;
9082 }
9083 case 39: /* Equalize */
9084 {
9085 if (attribute_flag[0] != 0)
9086 channel=(ChannelType) argument_list[0].integer_reference;
9087 channel_mask=SetImageChannelMask(image,channel);
9088 EqualizeImage(image,exception);
9089 (void) SetImageChannelMask(image,channel_mask);
9090 break;
9091 }
9092 case 40: /* Gamma */
9093 {
9094 if (attribute_flag[1] != 0)
9095 channel=(ChannelType) argument_list[1].integer_reference;
9096 if (attribute_flag[2] == 0)
9097 argument_list[2].real_reference=1.0;
9098 if (attribute_flag[3] == 0)
9099 argument_list[3].real_reference=1.0;
9100 if (attribute_flag[4] == 0)
9101 argument_list[4].real_reference=1.0;
9102 if (attribute_flag[0] == 0)
9103 {
cristy151b66d2015-04-15 10:50:31 +00009104 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00009105 "%.15g,%.15g,%.15g",(double) argument_list[2].real_reference,
9106 (double) argument_list[3].real_reference,
9107 (double) argument_list[4].real_reference);
9108 argument_list[0].string_reference=message;
9109 }
9110 (void) GammaImage(image,StringToDouble(
9111 argument_list[0].string_reference,(char **) NULL),exception);
9112 break;
9113 }
9114 case 41: /* Map */
9115 {
9116 QuantizeInfo
9117 *quantize_info;
9118
9119 if (attribute_flag[0] == 0)
9120 {
9121 ThrowPerlException(exception,OptionError,"MapImageRequired",
9122 PackageName);
9123 goto PerlException;
9124 }
9125 quantize_info=AcquireQuantizeInfo(info->image_info);
9126 if (attribute_flag[1] != 0)
9127 quantize_info->dither_method=(DitherMethod)
9128 argument_list[1].integer_reference;
9129 (void) RemapImages(quantize_info,image,
9130 argument_list[0].image_reference,exception);
9131 quantize_info=DestroyQuantizeInfo(quantize_info);
9132 break;
9133 }
9134 case 42: /* MatteFloodfill */
9135 {
9136 DrawInfo
9137 *draw_info;
9138
9139 MagickBooleanType
9140 invert;
9141
9142 PixelInfo
9143 target;
9144
9145 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9146 (DrawInfo *) NULL);
9147 if (attribute_flag[0] != 0)
9148 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9149 &geometry,exception);
9150 if (attribute_flag[1] != 0)
9151 geometry.x=argument_list[1].integer_reference;
9152 if (attribute_flag[2] != 0)
9153 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009154 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009155 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9156 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9157 geometry.x,geometry.y,&target,exception);
9158 if (attribute_flag[4] != 0)
9159 QueryColorCompliance(argument_list[4].string_reference,
9160 AllCompliance,&target,exception);
9161 if (attribute_flag[3] != 0)
9162 target.alpha=StringToDoubleInterval(
9163 argument_list[3].string_reference,(double) (double) QuantumRange+
9164 1.0);
9165 if (attribute_flag[5] != 0)
9166 image->fuzz=StringToDoubleInterval(
9167 argument_list[5].string_reference,(double) QuantumRange+1.0);
9168 invert=MagickFalse;
9169 if (attribute_flag[6] != 0)
9170 invert=(MagickBooleanType) argument_list[6].integer_reference;
9171 channel_mask=SetImageChannelMask(image,AlphaChannel);
9172 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9173 geometry.y,invert,exception);
9174 (void) SetImageChannelMask(image,channel_mask);
9175 draw_info=DestroyDrawInfo(draw_info);
9176 break;
9177 }
9178 case 43: /* Modulate */
9179 {
9180 char
cristy151b66d2015-04-15 10:50:31 +00009181 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009182
9183 geometry_info.rho=100.0;
9184 geometry_info.sigma=100.0;
9185 geometry_info.xi=100.0;
9186 if (attribute_flag[0] != 0)
9187 (void)ParseGeometry(argument_list[0].string_reference,
9188 &geometry_info);
9189 if (attribute_flag[1] != 0)
9190 geometry_info.xi=argument_list[1].real_reference;
9191 if (attribute_flag[2] != 0)
9192 geometry_info.sigma=argument_list[2].real_reference;
9193 if (attribute_flag[3] != 0)
9194 {
9195 geometry_info.sigma=argument_list[3].real_reference;
9196 SetImageArtifact(image,"modulate:colorspace","HWB");
9197 }
9198 if (attribute_flag[4] != 0)
9199 {
9200 geometry_info.rho=argument_list[4].real_reference;
9201 SetImageArtifact(image,"modulate:colorspace","HSB");
9202 }
9203 if (attribute_flag[5] != 0)
9204 {
9205 geometry_info.sigma=argument_list[5].real_reference;
9206 SetImageArtifact(image,"modulate:colorspace","HSL");
9207 }
9208 if (attribute_flag[6] != 0)
9209 {
9210 geometry_info.rho=argument_list[6].real_reference;
9211 SetImageArtifact(image,"modulate:colorspace","HWB");
9212 }
cristy151b66d2015-04-15 10:50:31 +00009213 (void) FormatLocaleString(modulate,MagickPathExtent,"%.15g,%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00009214 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
9215 (void) ModulateImage(image,modulate,exception);
9216 break;
9217 }
9218 case 44: /* Negate */
9219 {
9220 if (attribute_flag[0] == 0)
9221 argument_list[0].integer_reference=0;
9222 if (attribute_flag[1] != 0)
9223 channel=(ChannelType) argument_list[1].integer_reference;
9224 channel_mask=SetImageChannelMask(image,channel);
9225 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9226 MagickTrue : MagickFalse,exception);
9227 (void) SetImageChannelMask(image,channel_mask);
9228 break;
9229 }
9230 case 45: /* Normalize */
9231 {
9232 if (attribute_flag[0] != 0)
9233 channel=(ChannelType) argument_list[0].integer_reference;
9234 channel_mask=SetImageChannelMask(image,channel);
9235 NormalizeImage(image,exception);
9236 (void) SetImageChannelMask(image,channel_mask);
9237 break;
9238 }
9239 case 46: /* NumberColors */
9240 break;
9241 case 47: /* Opaque */
9242 {
9243 MagickBooleanType
9244 invert;
9245
9246 PixelInfo
9247 fill_color,
9248 target;
9249
9250 (void) QueryColorCompliance("none",AllCompliance,&target,
9251 exception);
9252 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9253 exception);
9254 if (attribute_flag[0] != 0)
9255 (void) QueryColorCompliance(argument_list[0].string_reference,
9256 AllCompliance,&target,exception);
9257 if (attribute_flag[1] != 0)
9258 (void) QueryColorCompliance(argument_list[1].string_reference,
9259 AllCompliance,&fill_color,exception);
9260 if (attribute_flag[2] != 0)
9261 image->fuzz=StringToDoubleInterval(
9262 argument_list[2].string_reference,(double) QuantumRange+1.0);
9263 if (attribute_flag[3] != 0)
9264 channel=(ChannelType) argument_list[3].integer_reference;
9265 invert=MagickFalse;
9266 if (attribute_flag[4] != 0)
9267 invert=(MagickBooleanType) argument_list[4].integer_reference;
9268 channel_mask=SetImageChannelMask(image,channel);
9269 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9270 (void) SetImageChannelMask(image,channel_mask);
9271 break;
9272 }
9273 case 48: /* Quantize */
9274 {
9275 QuantizeInfo
9276 *quantize_info;
9277
9278 quantize_info=AcquireQuantizeInfo(info->image_info);
9279 if (attribute_flag[0] != 0)
9280 quantize_info->number_colors=(size_t)
9281 argument_list[0].integer_reference;
9282 if (attribute_flag[1] != 0)
9283 quantize_info->tree_depth=(size_t)
9284 argument_list[1].integer_reference;
9285 if (attribute_flag[2] != 0)
9286 quantize_info->colorspace=(ColorspaceType)
9287 argument_list[2].integer_reference;
9288 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009289 quantize_info->dither_method=(DitherMethod)
9290 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009291 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009292 quantize_info->measure_error=
9293 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009294 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009295 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009296 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009297 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009298 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009299 argument_list[7].integer_reference;
9300 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009301 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009302 else
cristyf7563392014-03-25 13:54:04 +00009303 if ((image->storage_class == DirectClass) ||
9304 (image->colors > quantize_info->number_colors) ||
9305 (quantize_info->colorspace == GRAYColorspace))
9306 (void) QuantizeImage(quantize_info,image,exception);
9307 else
9308 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009309 quantize_info=DestroyQuantizeInfo(quantize_info);
9310 break;
9311 }
9312 case 49: /* Raise */
9313 {
9314 if (attribute_flag[0] != 0)
9315 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9316 &geometry,exception);
9317 if (attribute_flag[1] != 0)
9318 geometry.width=argument_list[1].integer_reference;
9319 if (attribute_flag[2] != 0)
9320 geometry.height=argument_list[2].integer_reference;
9321 if (attribute_flag[3] == 0)
9322 argument_list[3].integer_reference=1;
9323 (void) RaiseImage(image,&geometry,
9324 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9325 exception);
9326 break;
9327 }
9328 case 50: /* Segment */
9329 {
9330 ColorspaceType
9331 colorspace;
9332
9333 double
9334 cluster_threshold,
9335 smoothing_threshold;
9336
9337 MagickBooleanType
9338 verbose;
9339
9340 cluster_threshold=1.0;
9341 smoothing_threshold=1.5;
9342 colorspace=sRGBColorspace;
9343 verbose=MagickFalse;
9344 if (attribute_flag[0] != 0)
9345 {
9346 flags=ParseGeometry(argument_list[0].string_reference,
9347 &geometry_info);
9348 cluster_threshold=geometry_info.rho;
9349 if (flags & SigmaValue)
9350 smoothing_threshold=geometry_info.sigma;
9351 }
9352 if (attribute_flag[1] != 0)
9353 cluster_threshold=argument_list[1].real_reference;
9354 if (attribute_flag[2] != 0)
9355 smoothing_threshold=argument_list[2].real_reference;
9356 if (attribute_flag[3] != 0)
9357 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9358 if (attribute_flag[4] != 0)
9359 verbose=argument_list[4].integer_reference != 0 ?
9360 MagickTrue : MagickFalse;
9361 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9362 smoothing_threshold,exception);
9363 break;
9364 }
9365 case 51: /* Signature */
9366 {
9367 (void) SignatureImage(image,exception);
9368 break;
9369 }
9370 case 52: /* Solarize */
9371 {
9372 geometry_info.rho=QuantumRange/2.0;
9373 if (attribute_flag[0] != 0)
9374 flags=ParseGeometry(argument_list[0].string_reference,
9375 &geometry_info);
9376 if (attribute_flag[1] != 0)
9377 geometry_info.rho=StringToDoubleInterval(
9378 argument_list[1].string_reference,(double) QuantumRange+1.0);
9379 (void) SolarizeImage(image,geometry_info.rho,exception);
9380 break;
9381 }
9382 case 53: /* Sync */
9383 {
9384 (void) SyncImage(image,exception);
9385 break;
9386 }
9387 case 54: /* Texture */
9388 {
9389 if (attribute_flag[0] == 0)
9390 break;
9391 TextureImage(image,argument_list[0].image_reference,exception);
9392 break;
9393 }
9394 case 55: /* Evalute */
9395 {
9396 MagickEvaluateOperator
9397 op;
9398
9399 op=SetEvaluateOperator;
9400 if (attribute_flag[0] == MagickFalse)
9401 argument_list[0].real_reference=0.0;
9402 if (attribute_flag[1] != MagickFalse)
9403 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9404 if (attribute_flag[2] != MagickFalse)
9405 channel=(ChannelType) argument_list[2].integer_reference;
9406 channel_mask=SetImageChannelMask(image,channel);
9407 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9408 exception);
9409 (void) SetImageChannelMask(image,channel_mask);
9410 break;
9411 }
9412 case 56: /* Transparent */
9413 {
9414 double
9415 opacity;
9416
9417 MagickBooleanType
9418 invert;
9419
9420 PixelInfo
9421 target;
9422
9423 (void) QueryColorCompliance("none",AllCompliance,&target,
9424 exception);
9425 if (attribute_flag[0] != 0)
9426 (void) QueryColorCompliance(argument_list[0].string_reference,
9427 AllCompliance,&target,exception);
9428 opacity=TransparentAlpha;
9429 if (attribute_flag[1] != 0)
9430 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9431 (double) QuantumRange+1.0);
9432 if (attribute_flag[2] != 0)
9433 image->fuzz=StringToDoubleInterval(
9434 argument_list[2].string_reference,(double) QuantumRange+1.0);
9435 if (attribute_flag[3] == 0)
9436 argument_list[3].integer_reference=0;
9437 invert=MagickFalse;
9438 if (attribute_flag[3] != 0)
9439 invert=(MagickBooleanType) argument_list[3].integer_reference;
9440 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9441 invert,exception);
9442 break;
9443 }
9444 case 57: /* Threshold */
9445 {
9446 double
9447 threshold;
9448
9449 if (attribute_flag[0] == 0)
9450 argument_list[0].string_reference="50%";
9451 if (attribute_flag[1] != 0)
9452 channel=(ChannelType) argument_list[1].integer_reference;
9453 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9454 (double) QuantumRange+1.0);
9455 channel_mask=SetImageChannelMask(image,channel);
9456 (void) BilevelImage(image,threshold,exception);
9457 (void) SetImageChannelMask(image,channel_mask);
9458 break;
9459 }
9460 case 58: /* Charcoal */
9461 {
9462 if (attribute_flag[0] != 0)
9463 {
9464 flags=ParseGeometry(argument_list[0].string_reference,
9465 &geometry_info);
9466 if ((flags & SigmaValue) == 0)
9467 geometry_info.sigma=1.0;
9468 }
9469 if (attribute_flag[1] != 0)
9470 geometry_info.rho=argument_list[1].real_reference;
9471 if (attribute_flag[2] != 0)
9472 geometry_info.sigma=argument_list[2].real_reference;
9473 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9474 exception);
9475 break;
9476 }
9477 case 59: /* Trim */
9478 {
9479 if (attribute_flag[0] != 0)
9480 image->fuzz=StringToDoubleInterval(
9481 argument_list[0].string_reference,(double) QuantumRange+1.0);
9482 image=TrimImage(image,exception);
9483 break;
9484 }
9485 case 60: /* Wave */
9486 {
9487 PixelInterpolateMethod
9488 method;
9489
9490 if (attribute_flag[0] != 0)
9491 {
9492 flags=ParseGeometry(argument_list[0].string_reference,
9493 &geometry_info);
9494 if ((flags & SigmaValue) == 0)
9495 geometry_info.sigma=1.0;
9496 }
9497 if (attribute_flag[1] != 0)
9498 geometry_info.rho=argument_list[1].real_reference;
9499 if (attribute_flag[2] != 0)
9500 geometry_info.sigma=argument_list[2].real_reference;
9501 method=UndefinedInterpolatePixel;
9502 if (attribute_flag[3] != 0)
9503 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9504 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9505 method,exception);
9506 break;
9507 }
9508 case 61: /* Separate */
9509 {
9510 if (attribute_flag[0] != 0)
9511 channel=(ChannelType) argument_list[0].integer_reference;
9512 image=SeparateImage(image,channel,exception);
9513 break;
9514 }
9515 case 63: /* Stereo */
9516 {
9517 if (attribute_flag[0] == 0)
9518 {
9519 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9520 PackageName);
9521 goto PerlException;
9522 }
9523 if (attribute_flag[1] != 0)
9524 geometry.x=argument_list[1].integer_reference;
9525 if (attribute_flag[2] != 0)
9526 geometry.y=argument_list[2].integer_reference;
9527 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9528 geometry.x,geometry.y,exception);
9529 break;
9530 }
9531 case 64: /* Stegano */
9532 {
9533 if (attribute_flag[0] == 0)
9534 {
9535 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9536 PackageName);
9537 goto PerlException;
9538 }
9539 if (attribute_flag[1] == 0)
9540 argument_list[1].integer_reference=0;
9541 image->offset=argument_list[1].integer_reference;
9542 image=SteganoImage(image,argument_list[0].image_reference,exception);
9543 break;
9544 }
9545 case 65: /* Deconstruct */
9546 {
9547 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9548 break;
9549 }
9550 case 66: /* GaussianBlur */
9551 {
9552 if (attribute_flag[0] != 0)
9553 {
9554 flags=ParseGeometry(argument_list[0].string_reference,
9555 &geometry_info);
9556 if ((flags & SigmaValue) == 0)
9557 geometry_info.sigma=1.0;
9558 }
9559 if (attribute_flag[1] != 0)
9560 geometry_info.rho=argument_list[1].real_reference;
9561 if (attribute_flag[2] != 0)
9562 geometry_info.sigma=argument_list[2].real_reference;
9563 if (attribute_flag[3] != 0)
9564 channel=(ChannelType) argument_list[3].integer_reference;
9565 channel_mask=SetImageChannelMask(image,channel);
9566 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9567 exception);
9568 if (image != (Image *) NULL)
9569 (void) SetImageChannelMask(image,channel_mask);
9570 break;
9571 }
9572 case 67: /* Convolve */
9573 {
9574 KernelInfo
9575 *kernel;
9576
9577 kernel=(KernelInfo *) NULL;
9578 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9579 break;
9580 if (attribute_flag[0] != 0)
9581 {
9582 AV
9583 *av;
9584
9585 size_t
9586 order;
9587
cristy2c57b742014-10-31 00:40:34 +00009588 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009589 if (kernel == (KernelInfo *) NULL)
9590 break;
9591 av=(AV *) argument_list[0].array_reference;
9592 order=(size_t) sqrt(av_len(av)+1);
9593 kernel->width=order;
9594 kernel->height=order;
9595 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9596 order*sizeof(*kernel->values));
9597 if (kernel->values == (MagickRealType *) NULL)
9598 {
9599 kernel=DestroyKernelInfo(kernel);
9600 ThrowPerlException(exception,ResourceLimitFatalError,
9601 "MemoryAllocationFailed",PackageName);
9602 goto PerlException;
9603 }
9604 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9605 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9606 for ( ; j < (ssize_t) (order*order); j++)
9607 kernel->values[j]=0.0;
9608 }
9609 if (attribute_flag[1] != 0)
9610 channel=(ChannelType) argument_list[1].integer_reference;
9611 if (attribute_flag[2] != 0)
9612 SetImageArtifact(image,"filter:blur",
9613 argument_list[2].string_reference);
9614 if (attribute_flag[3] != 0)
9615 {
cristy2c57b742014-10-31 00:40:34 +00009616 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9617 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009618 if (kernel == (KernelInfo *) NULL)
9619 break;
9620 }
9621 channel_mask=SetImageChannelMask(image,channel);
9622 image=ConvolveImage(image,kernel,exception);
9623 if (image != (Image *) NULL)
9624 (void) SetImageChannelMask(image,channel_mask);
9625 kernel=DestroyKernelInfo(kernel);
9626 break;
9627 }
9628 case 68: /* Profile */
9629 {
9630 const char
9631 *name;
9632
9633 Image
9634 *profile_image;
9635
9636 ImageInfo
9637 *profile_info;
9638
9639 StringInfo
9640 *profile;
9641
9642 name="*";
9643 if (attribute_flag[0] != 0)
9644 name=argument_list[0].string_reference;
9645 if (attribute_flag[2] != 0)
9646 image->rendering_intent=(RenderingIntent)
9647 argument_list[2].integer_reference;
9648 if (attribute_flag[3] != 0)
9649 image->black_point_compensation=
9650 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9651 if (attribute_flag[1] != 0)
9652 {
9653 if (argument_list[1].length == 0)
9654 {
9655 /*
9656 Remove a profile from the image.
9657 */
9658 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9659 exception);
9660 break;
9661 }
9662 /*
9663 Associate user supplied profile with the image.
9664 */
9665 profile=AcquireStringInfo(argument_list[1].length);
9666 SetStringInfoDatum(profile,(const unsigned char *)
9667 argument_list[1].string_reference);
9668 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9669 (size_t) GetStringInfoLength(profile),exception);
9670 profile=DestroyStringInfo(profile);
9671 break;
9672 }
9673 /*
9674 Associate a profile with the image.
9675 */
9676 profile_info=CloneImageInfo(info ? info->image_info :
9677 (ImageInfo *) NULL);
9678 profile_image=ReadImages(profile_info,name,exception);
9679 if (profile_image == (Image *) NULL)
9680 break;
9681 ResetImageProfileIterator(profile_image);
9682 name=GetNextImageProfile(profile_image);
9683 while (name != (const char *) NULL)
9684 {
9685 const StringInfo
9686 *profile;
9687
9688 profile=GetImageProfile(profile_image,name);
9689 if (profile != (const StringInfo *) NULL)
9690 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9691 (size_t) GetStringInfoLength(profile),exception);
9692 name=GetNextImageProfile(profile_image);
9693 }
9694 profile_image=DestroyImage(profile_image);
9695 profile_info=DestroyImageInfo(profile_info);
9696 break;
9697 }
9698 case 69: /* UnsharpMask */
9699 {
9700 if (attribute_flag[0] != 0)
9701 {
9702 flags=ParseGeometry(argument_list[0].string_reference,
9703 &geometry_info);
9704 if ((flags & SigmaValue) == 0)
9705 geometry_info.sigma=1.0;
9706 if ((flags & XiValue) == 0)
9707 geometry_info.xi=1.0;
9708 if ((flags & PsiValue) == 0)
9709 geometry_info.psi=0.5;
9710 }
9711 if (attribute_flag[1] != 0)
9712 geometry_info.rho=argument_list[1].real_reference;
9713 if (attribute_flag[2] != 0)
9714 geometry_info.sigma=argument_list[2].real_reference;
9715 if (attribute_flag[3] != 0)
9716 geometry_info.xi=argument_list[3].real_reference;
9717 if (attribute_flag[4] != 0)
9718 geometry_info.psi=argument_list[4].real_reference;
9719 if (attribute_flag[5] != 0)
9720 channel=(ChannelType) argument_list[5].integer_reference;
9721 channel_mask=SetImageChannelMask(image,channel);
9722 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9723 geometry_info.xi,geometry_info.psi,exception);
9724 if (image != (Image *) NULL)
9725 (void) SetImageChannelMask(image,channel_mask);
9726 break;
9727 }
9728 case 70: /* MotionBlur */
9729 {
9730 if (attribute_flag[0] != 0)
9731 {
9732 flags=ParseGeometry(argument_list[0].string_reference,
9733 &geometry_info);
9734 if ((flags & SigmaValue) == 0)
9735 geometry_info.sigma=1.0;
9736 if ((flags & XiValue) == 0)
9737 geometry_info.xi=1.0;
9738 }
9739 if (attribute_flag[1] != 0)
9740 geometry_info.rho=argument_list[1].real_reference;
9741 if (attribute_flag[2] != 0)
9742 geometry_info.sigma=argument_list[2].real_reference;
9743 if (attribute_flag[3] != 0)
9744 geometry_info.xi=argument_list[3].real_reference;
9745 if (attribute_flag[4] != 0)
9746 channel=(ChannelType) argument_list[4].integer_reference;
9747 channel_mask=SetImageChannelMask(image,channel);
9748 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9749 geometry_info.xi,exception);
9750 if (image != (Image *) NULL)
9751 (void) SetImageChannelMask(image,channel_mask);
9752 break;
9753 }
9754 case 71: /* OrderedDither */
9755 {
9756 if (attribute_flag[0] == 0)
9757 argument_list[0].string_reference="o8x8";
9758 if (attribute_flag[1] != 0)
9759 channel=(ChannelType) argument_list[1].integer_reference;
9760 channel_mask=SetImageChannelMask(image,channel);
Cristy6b93c072016-02-04 07:45:48 -05009761 (void) OrderedDitherImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009762 exception);
9763 (void) SetImageChannelMask(image,channel_mask);
9764 break;
9765 }
9766 case 72: /* Shave */
9767 {
9768 if (attribute_flag[0] != 0)
9769 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9770 &geometry,exception);
9771 if (attribute_flag[1] != 0)
9772 geometry.width=argument_list[1].integer_reference;
9773 if (attribute_flag[2] != 0)
9774 geometry.height=argument_list[2].integer_reference;
9775 image=ShaveImage(image,&geometry,exception);
9776 break;
9777 }
9778 case 73: /* Level */
9779 {
9780 double
9781 black_point,
9782 gamma,
9783 white_point;
9784
9785 black_point=0.0;
9786 white_point=(double) image->columns*image->rows;
9787 gamma=1.0;
9788 if (attribute_flag[0] != 0)
9789 {
9790 flags=ParseGeometry(argument_list[0].string_reference,
9791 &geometry_info);
9792 black_point=geometry_info.rho;
9793 if ((flags & SigmaValue) != 0)
9794 white_point=geometry_info.sigma;
9795 if ((flags & XiValue) != 0)
9796 gamma=geometry_info.xi;
9797 if ((flags & PercentValue) != 0)
9798 {
9799 black_point*=(double) (QuantumRange/100.0);
9800 white_point*=(double) (QuantumRange/100.0);
9801 }
9802 if ((flags & SigmaValue) == 0)
9803 white_point=(double) QuantumRange-black_point;
9804 }
9805 if (attribute_flag[1] != 0)
9806 black_point=argument_list[1].real_reference;
9807 if (attribute_flag[2] != 0)
9808 white_point=argument_list[2].real_reference;
9809 if (attribute_flag[3] != 0)
9810 gamma=argument_list[3].real_reference;
9811 if (attribute_flag[4] != 0)
9812 channel=(ChannelType) argument_list[4].integer_reference;
9813 if (attribute_flag[5] != 0)
9814 {
9815 argument_list[0].real_reference=argument_list[5].real_reference;
9816 attribute_flag[0]=attribute_flag[5];
9817 }
9818 channel_mask=SetImageChannelMask(image,channel);
9819 (void) LevelImage(image,black_point,white_point,gamma,exception);
9820 (void) SetImageChannelMask(image,channel_mask);
9821 break;
9822 }
9823 case 74: /* Clip */
9824 {
9825 if (attribute_flag[0] == 0)
9826 argument_list[0].string_reference="#1";
9827 if (attribute_flag[1] == 0)
9828 argument_list[1].integer_reference=MagickTrue;
9829 (void) ClipImagePath(image,argument_list[0].string_reference,
9830 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9831 exception);
9832 break;
9833 }
9834 case 75: /* AffineTransform */
9835 {
9836 DrawInfo
9837 *draw_info;
9838
9839 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9840 (DrawInfo *) NULL);
9841 if (attribute_flag[0] != 0)
9842 {
9843 AV
9844 *av;
9845
9846 av=(AV *) argument_list[0].array_reference;
9847 if ((av_len(av) != 3) && (av_len(av) != 5))
9848 {
9849 ThrowPerlException(exception,OptionError,
9850 "affine matrix must have 4 or 6 elements",PackageName);
9851 goto PerlException;
9852 }
9853 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9854 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9855 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9856 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9857 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9858 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9859 {
9860 ThrowPerlException(exception,OptionError,
9861 "affine matrix is singular",PackageName);
9862 goto PerlException;
9863 }
9864 if (av_len(av) == 5)
9865 {
9866 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9867 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9868 }
9869 }
9870 for (j=1; j < 6; j++)
9871 {
9872 if (attribute_flag[j] == 0)
9873 continue;
9874 value=argument_list[j].string_reference;
9875 angle=argument_list[j].real_reference;
9876 current=draw_info->affine;
9877 GetAffineMatrix(&affine);
9878 switch (j)
9879 {
9880 case 1:
9881 {
9882 /*
9883 Translate.
9884 */
9885 flags=ParseGeometry(value,&geometry_info);
9886 affine.tx=geometry_info.xi;
9887 affine.ty=geometry_info.psi;
9888 if ((flags & PsiValue) == 0)
9889 affine.ty=affine.tx;
9890 break;
9891 }
9892 case 2:
9893 {
9894 /*
9895 Scale.
9896 */
9897 flags=ParseGeometry(value,&geometry_info);
9898 affine.sx=geometry_info.rho;
9899 affine.sy=geometry_info.sigma;
9900 if ((flags & SigmaValue) == 0)
9901 affine.sy=affine.sx;
9902 break;
9903 }
9904 case 3:
9905 {
9906 /*
9907 Rotate.
9908 */
9909 if (angle == 0.0)
9910 break;
9911 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9912 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9913 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9914 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9915 break;
9916 }
9917 case 4:
9918 {
9919 /*
9920 SkewX.
9921 */
9922 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9923 break;
9924 }
9925 case 5:
9926 {
9927 /*
9928 SkewY.
9929 */
9930 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9931 break;
9932 }
9933 }
9934 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9935 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9936 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9937 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9938 draw_info->affine.tx=
9939 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9940 draw_info->affine.ty=
9941 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9942 }
9943 if (attribute_flag[6] != 0)
9944 image->interpolate=(PixelInterpolateMethod)
9945 argument_list[6].integer_reference;
9946 if (attribute_flag[7] != 0)
9947 QueryColorCompliance(argument_list[7].string_reference,
9948 AllCompliance,&image->background_color,exception);
9949 image=AffineTransformImage(image,&draw_info->affine,exception);
9950 draw_info=DestroyDrawInfo(draw_info);
9951 break;
9952 }
9953 case 76: /* Difference */
9954 {
9955 if (attribute_flag[0] == 0)
9956 {
9957 ThrowPerlException(exception,OptionError,
9958 "ReferenceImageRequired",PackageName);
9959 goto PerlException;
9960 }
9961 if (attribute_flag[1] != 0)
9962 image->fuzz=StringToDoubleInterval(
9963 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -05009964 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009965 exception);
9966 break;
9967 }
9968 case 77: /* AdaptiveThreshold */
9969 {
9970 if (attribute_flag[0] != 0)
9971 {
9972 flags=ParseGeometry(argument_list[0].string_reference,
9973 &geometry_info);
9974 if ((flags & PercentValue) != 0)
9975 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9976 }
9977 if (attribute_flag[1] != 0)
9978 geometry_info.rho=argument_list[1].integer_reference;
9979 if (attribute_flag[2] != 0)
9980 geometry_info.sigma=argument_list[2].integer_reference;
9981 if (attribute_flag[3] != 0)
9982 geometry_info.xi=argument_list[3].integer_reference;;
9983 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9984 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9985 break;
9986 }
9987 case 78: /* Resample */
9988 {
9989 size_t
9990 height,
9991 width;
9992
9993 if (attribute_flag[0] != 0)
9994 {
9995 flags=ParseGeometry(argument_list[0].string_reference,
9996 &geometry_info);
9997 if ((flags & SigmaValue) == 0)
9998 geometry_info.sigma=geometry_info.rho;
9999 }
10000 if (attribute_flag[1] != 0)
10001 geometry_info.rho=argument_list[1].real_reference;
10002 if (attribute_flag[2] != 0)
10003 geometry_info.sigma=argument_list[2].real_reference;
10004 if (attribute_flag[3] == 0)
10005 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10006 if (attribute_flag[4] == 0)
10007 SetImageArtifact(image,"filter:support",
10008 argument_list[4].string_reference);
10009 width=(size_t) (geometry_info.rho*image->columns/
10010 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10011 height=(size_t) (geometry_info.sigma*image->rows/
10012 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
Cristy8645e042016-02-03 16:35:29 -050010013 image=ResizeImage(image,width,height,(FilterType)
cristy4a3ce0a2013-08-03 20:06:59 +000010014 argument_list[3].integer_reference,exception);
10015 if (image != (Image *) NULL)
10016 {
10017 image->resolution.x=geometry_info.rho;
10018 image->resolution.y=geometry_info.sigma;
10019 }
10020 break;
10021 }
10022 case 79: /* Describe */
10023 {
10024 if (attribute_flag[0] == 0)
10025 argument_list[0].file_reference=(FILE *) NULL;
10026 if (attribute_flag[1] != 0)
10027 (void) SetImageArtifact(image,"identify:features",
10028 argument_list[1].string_reference);
10029 (void) IdentifyImage(image,argument_list[0].file_reference,
10030 MagickTrue,exception);
10031 break;
10032 }
10033 case 80: /* BlackThreshold */
10034 {
10035 if (attribute_flag[0] == 0)
10036 argument_list[0].string_reference="50%";
10037 if (attribute_flag[2] != 0)
10038 channel=(ChannelType) argument_list[2].integer_reference;
10039 channel_mask=SetImageChannelMask(image,channel);
10040 BlackThresholdImage(image,argument_list[0].string_reference,
10041 exception);
10042 (void) SetImageChannelMask(image,channel_mask);
10043 break;
10044 }
10045 case 81: /* WhiteThreshold */
10046 {
10047 if (attribute_flag[0] == 0)
10048 argument_list[0].string_reference="50%";
10049 if (attribute_flag[2] != 0)
10050 channel=(ChannelType) argument_list[2].integer_reference;
10051 channel_mask=SetImageChannelMask(image,channel);
10052 WhiteThresholdImage(image,argument_list[0].string_reference,
10053 exception);
10054 (void) SetImageChannelMask(image,channel_mask);
10055 break;
10056 }
cristy60c73c02014-03-25 12:09:58 +000010057 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010058 {
10059 if (attribute_flag[0] != 0)
10060 {
10061 flags=ParseGeometry(argument_list[0].string_reference,
10062 &geometry_info);
10063 }
10064 if (attribute_flag[1] != 0)
10065 geometry_info.rho=argument_list[1].real_reference;
10066 if (attribute_flag[2] != 0)
10067 channel=(ChannelType) argument_list[2].integer_reference;
10068 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010069 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010070 if (image != (Image *) NULL)
10071 (void) SetImageChannelMask(image,channel_mask);
10072 break;
10073 }
10074 case 83: /* Thumbnail */
10075 {
10076 if (attribute_flag[0] != 0)
10077 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10078 &geometry,exception);
10079 if (attribute_flag[1] != 0)
10080 geometry.width=argument_list[1].integer_reference;
10081 if (attribute_flag[2] != 0)
10082 geometry.height=argument_list[2].integer_reference;
10083 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10084 break;
10085 }
10086 case 84: /* Strip */
10087 {
10088 (void) StripImage(image,exception);
10089 break;
10090 }
10091 case 85: /* Tint */
10092 {
10093 PixelInfo
10094 tint;
10095
10096 GetPixelInfo(image,&tint);
10097 if (attribute_flag[0] != 0)
10098 (void) QueryColorCompliance(argument_list[0].string_reference,
10099 AllCompliance,&tint,exception);
10100 if (attribute_flag[1] == 0)
10101 argument_list[1].string_reference="100";
10102 image=TintImage(image,argument_list[1].string_reference,&tint,
10103 exception);
10104 break;
10105 }
10106 case 86: /* Channel */
10107 {
10108 if (attribute_flag[0] != 0)
10109 channel=(ChannelType) argument_list[0].integer_reference;
10110 image=SeparateImage(image,channel,exception);
10111 break;
10112 }
10113 case 87: /* Splice */
10114 {
cristy260bd762014-08-15 12:46:34 +000010115 if (attribute_flag[7] != 0)
10116 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010117 if (attribute_flag[0] != 0)
10118 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10119 &geometry,exception);
10120 if (attribute_flag[1] != 0)
10121 geometry.width=argument_list[1].integer_reference;
10122 if (attribute_flag[2] != 0)
10123 geometry.height=argument_list[2].integer_reference;
10124 if (attribute_flag[3] != 0)
10125 geometry.x=argument_list[3].integer_reference;
10126 if (attribute_flag[4] != 0)
10127 geometry.y=argument_list[4].integer_reference;
10128 if (attribute_flag[5] != 0)
10129 image->fuzz=StringToDoubleInterval(
10130 argument_list[5].string_reference,(double) QuantumRange+1.0);
10131 if (attribute_flag[6] != 0)
10132 (void) QueryColorCompliance(argument_list[6].string_reference,
10133 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010134 image=SpliceImage(image,&geometry,exception);
10135 break;
10136 }
10137 case 88: /* Posterize */
10138 {
10139 if (attribute_flag[0] == 0)
10140 argument_list[0].integer_reference=3;
10141 if (attribute_flag[1] == 0)
10142 argument_list[1].integer_reference=0;
10143 (void) PosterizeImage(image,argument_list[0].integer_reference,
10144 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10145 NoDitherMethod,exception);
10146 break;
10147 }
10148 case 89: /* Shadow */
10149 {
10150 if (attribute_flag[0] != 0)
10151 {
10152 flags=ParseGeometry(argument_list[0].string_reference,
10153 &geometry_info);
10154 if ((flags & SigmaValue) == 0)
10155 geometry_info.sigma=1.0;
10156 if ((flags & XiValue) == 0)
10157 geometry_info.xi=4.0;
10158 if ((flags & PsiValue) == 0)
10159 geometry_info.psi=4.0;
10160 }
10161 if (attribute_flag[1] != 0)
10162 geometry_info.rho=argument_list[1].real_reference;
10163 if (attribute_flag[2] != 0)
10164 geometry_info.sigma=argument_list[2].real_reference;
10165 if (attribute_flag[3] != 0)
10166 geometry_info.xi=argument_list[3].integer_reference;
10167 if (attribute_flag[4] != 0)
10168 geometry_info.psi=argument_list[4].integer_reference;
10169 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10170 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10171 ceil(geometry_info.psi-0.5),exception);
10172 break;
10173 }
10174 case 90: /* Identify */
10175 {
10176 if (attribute_flag[0] == 0)
10177 argument_list[0].file_reference=(FILE *) NULL;
10178 if (attribute_flag[1] != 0)
10179 (void) SetImageArtifact(image,"identify:features",
10180 argument_list[1].string_reference);
10181 if ((attribute_flag[2] != 0) &&
10182 (argument_list[2].integer_reference != 0))
10183 (void) SetImageArtifact(image,"identify:unique","true");
10184 (void) IdentifyImage(image,argument_list[0].file_reference,
10185 MagickTrue,exception);
10186 break;
10187 }
10188 case 91: /* SepiaTone */
10189 {
10190 if (attribute_flag[0] == 0)
10191 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10192 image=SepiaToneImage(image,argument_list[0].real_reference,
10193 exception);
10194 break;
10195 }
10196 case 92: /* SigmoidalContrast */
10197 {
10198 MagickBooleanType
10199 sharpen;
10200
10201 if (attribute_flag[0] != 0)
10202 {
10203 flags=ParseGeometry(argument_list[0].string_reference,
10204 &geometry_info);
10205 if ((flags & SigmaValue) == 0)
10206 geometry_info.sigma=QuantumRange/2.0;
10207 if ((flags & PercentValue) != 0)
10208 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10209 }
10210 if (attribute_flag[1] != 0)
10211 geometry_info.rho=argument_list[1].real_reference;
10212 if (attribute_flag[2] != 0)
10213 geometry_info.sigma=argument_list[2].real_reference;
10214 if (attribute_flag[3] != 0)
10215 channel=(ChannelType) argument_list[3].integer_reference;
10216 sharpen=MagickTrue;
10217 if (attribute_flag[4] != 0)
10218 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10219 MagickFalse;
10220 channel_mask=SetImageChannelMask(image,channel);
10221 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10222 geometry_info.sigma,exception);
10223 (void) SetImageChannelMask(image,channel_mask);
10224 break;
10225 }
10226 case 93: /* Extent */
10227 {
10228 if (attribute_flag[7] != 0)
10229 image->gravity=(GravityType) argument_list[7].integer_reference;
10230 if (attribute_flag[0] != 0)
10231 {
10232 int
10233 flags;
10234
10235 flags=ParseGravityGeometry(image,
10236 argument_list[0].string_reference,&geometry,exception);
10237 (void) flags;
10238 if (geometry.width == 0)
10239 geometry.width=image->columns;
10240 if (geometry.height == 0)
10241 geometry.height=image->rows;
10242 }
10243 if (attribute_flag[1] != 0)
10244 geometry.width=argument_list[1].integer_reference;
10245 if (attribute_flag[2] != 0)
10246 geometry.height=argument_list[2].integer_reference;
10247 if (attribute_flag[3] != 0)
10248 geometry.x=argument_list[3].integer_reference;
10249 if (attribute_flag[4] != 0)
10250 geometry.y=argument_list[4].integer_reference;
10251 if (attribute_flag[5] != 0)
10252 image->fuzz=StringToDoubleInterval(
10253 argument_list[5].string_reference,(double) QuantumRange+1.0);
10254 if (attribute_flag[6] != 0)
10255 (void) QueryColorCompliance(argument_list[6].string_reference,
10256 AllCompliance,&image->background_color,exception);
10257 image=ExtentImage(image,&geometry,exception);
10258 break;
10259 }
10260 case 94: /* Vignette */
10261 {
10262 if (attribute_flag[0] != 0)
10263 {
10264 flags=ParseGeometry(argument_list[0].string_reference,
10265 &geometry_info);
10266 if ((flags & SigmaValue) == 0)
10267 geometry_info.sigma=1.0;
10268 if ((flags & XiValue) == 0)
10269 geometry_info.xi=0.1*image->columns;
10270 if ((flags & PsiValue) == 0)
10271 geometry_info.psi=0.1*image->rows;
10272 }
10273 if (attribute_flag[1] != 0)
10274 geometry_info.rho=argument_list[1].real_reference;
10275 if (attribute_flag[2] != 0)
10276 geometry_info.sigma=argument_list[2].real_reference;
10277 if (attribute_flag[3] != 0)
10278 geometry_info.xi=argument_list[3].integer_reference;
10279 if (attribute_flag[4] != 0)
10280 geometry_info.psi=argument_list[4].integer_reference;
10281 if (attribute_flag[5] != 0)
10282 (void) QueryColorCompliance(argument_list[5].string_reference,
10283 AllCompliance,&image->background_color,exception);
10284 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10285 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10286 ceil(geometry_info.psi-0.5),exception);
10287 break;
10288 }
10289 case 95: /* ContrastStretch */
10290 {
10291 double
10292 black_point,
10293 white_point;
10294
10295 black_point=0.0;
10296 white_point=(double) image->columns*image->rows;
10297 if (attribute_flag[0] != 0)
10298 {
10299 flags=ParseGeometry(argument_list[0].string_reference,
10300 &geometry_info);
10301 black_point=geometry_info.rho;
10302 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10303 black_point;
10304 if ((flags & PercentValue) != 0)
10305 {
10306 black_point*=(double) image->columns*image->rows/100.0;
10307 white_point*=(double) image->columns*image->rows/100.0;
10308 }
10309 white_point=(double) image->columns*image->rows-
10310 white_point;
10311 }
10312 if (attribute_flag[1] != 0)
10313 black_point=argument_list[1].real_reference;
10314 if (attribute_flag[2] != 0)
10315 white_point=argument_list[2].real_reference;
10316 if (attribute_flag[4] != 0)
10317 channel=(ChannelType) argument_list[4].integer_reference;
10318 channel_mask=SetImageChannelMask(image,channel);
10319 (void) ContrastStretchImage(image,black_point,white_point,exception);
10320 (void) SetImageChannelMask(image,channel_mask);
10321 break;
10322 }
10323 case 96: /* Sans0 */
10324 {
10325 break;
10326 }
10327 case 97: /* Sans1 */
10328 {
10329 break;
10330 }
10331 case 98: /* AdaptiveSharpen */
10332 {
10333 if (attribute_flag[0] != 0)
10334 {
10335 flags=ParseGeometry(argument_list[0].string_reference,
10336 &geometry_info);
10337 if ((flags & SigmaValue) == 0)
10338 geometry_info.sigma=1.0;
10339 if ((flags & XiValue) == 0)
10340 geometry_info.xi=0.0;
10341 }
10342 if (attribute_flag[1] != 0)
10343 geometry_info.rho=argument_list[1].real_reference;
10344 if (attribute_flag[2] != 0)
10345 geometry_info.sigma=argument_list[2].real_reference;
10346 if (attribute_flag[3] != 0)
10347 geometry_info.xi=argument_list[3].real_reference;
10348 if (attribute_flag[4] != 0)
10349 channel=(ChannelType) argument_list[4].integer_reference;
10350 channel_mask=SetImageChannelMask(image,channel);
10351 image=AdaptiveSharpenImage(image,geometry_info.rho,
10352 geometry_info.sigma,exception);
10353 if (image != (Image *) NULL)
10354 (void) SetImageChannelMask(image,channel_mask);
10355 break;
10356 }
10357 case 99: /* Transpose */
10358 {
10359 image=TransposeImage(image,exception);
10360 break;
10361 }
10362 case 100: /* Tranverse */
10363 {
10364 image=TransverseImage(image,exception);
10365 break;
10366 }
10367 case 101: /* AutoOrient */
10368 {
10369 image=AutoOrientImage(image,image->orientation,exception);
10370 break;
10371 }
10372 case 102: /* AdaptiveBlur */
10373 {
10374 if (attribute_flag[0] != 0)
10375 {
10376 flags=ParseGeometry(argument_list[0].string_reference,
10377 &geometry_info);
10378 if ((flags & SigmaValue) == 0)
10379 geometry_info.sigma=1.0;
10380 if ((flags & XiValue) == 0)
10381 geometry_info.xi=0.0;
10382 }
10383 if (attribute_flag[1] != 0)
10384 geometry_info.rho=argument_list[1].real_reference;
10385 if (attribute_flag[2] != 0)
10386 geometry_info.sigma=argument_list[2].real_reference;
10387 if (attribute_flag[3] != 0)
10388 channel=(ChannelType) argument_list[3].integer_reference;
10389 channel_mask=SetImageChannelMask(image,channel);
10390 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10391 exception);
10392 if (image != (Image *) NULL)
10393 (void) SetImageChannelMask(image,channel_mask);
10394 break;
10395 }
10396 case 103: /* Sketch */
10397 {
10398 if (attribute_flag[0] != 0)
10399 {
10400 flags=ParseGeometry(argument_list[0].string_reference,
10401 &geometry_info);
10402 if ((flags & SigmaValue) == 0)
10403 geometry_info.sigma=1.0;
10404 if ((flags & XiValue) == 0)
10405 geometry_info.xi=1.0;
10406 }
10407 if (attribute_flag[1] != 0)
10408 geometry_info.rho=argument_list[1].real_reference;
10409 if (attribute_flag[2] != 0)
10410 geometry_info.sigma=argument_list[2].real_reference;
10411 if (attribute_flag[3] != 0)
10412 geometry_info.xi=argument_list[3].real_reference;
10413 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10414 geometry_info.xi,exception);
10415 break;
10416 }
10417 case 104: /* UniqueColors */
10418 {
10419 image=UniqueImageColors(image,exception);
10420 break;
10421 }
10422 case 105: /* AdaptiveResize */
10423 {
10424 if (attribute_flag[0] != 0)
10425 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10426 &geometry,exception);
10427 if (attribute_flag[1] != 0)
10428 geometry.width=argument_list[1].integer_reference;
10429 if (attribute_flag[2] != 0)
10430 geometry.height=argument_list[2].integer_reference;
10431 if (attribute_flag[3] != 0)
Cristy8645e042016-02-03 16:35:29 -050010432 image->filter=(FilterType) argument_list[4].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010433 if (attribute_flag[4] != 0)
10434 SetImageArtifact(image,"filter:support",
10435 argument_list[4].string_reference);
10436 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10437 exception);
10438 break;
10439 }
10440 case 106: /* ClipMask */
10441 {
10442 Image
10443 *mask_image;
10444
10445 if (attribute_flag[0] == 0)
10446 {
10447 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10448 PackageName);
10449 goto PerlException;
10450 }
10451 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10452 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010453 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010454 mask_image=DestroyImage(mask_image);
10455 break;
10456 }
10457 case 107: /* LinearStretch */
10458 {
10459 double
10460 black_point,
10461 white_point;
10462
10463 black_point=0.0;
10464 white_point=(double) image->columns*image->rows;
10465 if (attribute_flag[0] != 0)
10466 {
10467 flags=ParseGeometry(argument_list[0].string_reference,
10468 &geometry_info);
10469 if ((flags & SigmaValue) != 0)
10470 white_point=geometry_info.sigma;
10471 if ((flags & PercentValue) != 0)
10472 {
10473 black_point*=(double) image->columns*image->rows/100.0;
10474 white_point*=(double) image->columns*image->rows/100.0;
10475 }
10476 if ((flags & SigmaValue) == 0)
10477 white_point=(double) image->columns*image->rows-black_point;
10478 }
10479 if (attribute_flag[1] != 0)
10480 black_point=argument_list[1].real_reference;
10481 if (attribute_flag[2] != 0)
10482 white_point=argument_list[2].real_reference;
10483 (void) LinearStretchImage(image,black_point,white_point,exception);
10484 break;
10485 }
10486 case 108: /* ColorMatrix */
10487 {
10488 AV
10489 *av;
10490
10491 double
10492 *color_matrix;
10493
10494 KernelInfo
10495 *kernel_info;
10496
10497 size_t
10498 order;
10499
10500 if (attribute_flag[0] == 0)
10501 break;
10502 av=(AV *) argument_list[0].array_reference;
10503 order=(size_t) sqrt(av_len(av)+1);
10504 color_matrix=(double *) AcquireQuantumMemory(order,order*
10505 sizeof(*color_matrix));
10506 if (color_matrix == (double *) NULL)
10507 {
10508 ThrowPerlException(exception,ResourceLimitFatalError,
10509 "MemoryAllocationFailed",PackageName);
10510 goto PerlException;
10511 }
10512 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10513 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10514 for ( ; j < (ssize_t) (order*order); j++)
10515 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010516 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010517 if (kernel_info == (KernelInfo *) NULL)
10518 break;
10519 kernel_info->width=order;
10520 kernel_info->height=order;
10521 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10522 order*sizeof(*kernel_info->values));
10523 if (kernel_info->values != (MagickRealType *) NULL)
10524 {
10525 for (i=0; i < (ssize_t) (order*order); i++)
10526 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10527 image=ColorMatrixImage(image,kernel_info,exception);
10528 }
10529 kernel_info=DestroyKernelInfo(kernel_info);
10530 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10531 break;
10532 }
10533 case 109: /* Mask */
10534 {
10535 Image
10536 *mask_image;
10537
10538 if (attribute_flag[0] == 0)
10539 {
10540 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10541 PackageName);
10542 goto PerlException;
10543 }
10544 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10545 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010546 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010547 mask_image=DestroyImage(mask_image);
10548 break;
10549 }
10550 case 110: /* Polaroid */
10551 {
10552 char
10553 *caption;
10554
10555 DrawInfo
10556 *draw_info;
10557
10558 double
10559 angle;
10560
10561 PixelInterpolateMethod
10562 method;
10563
10564 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10565 (DrawInfo *) NULL);
10566 caption=(char *) NULL;
10567 if (attribute_flag[0] != 0)
10568 caption=InterpretImageProperties(info ? info->image_info :
10569 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10570 exception);
10571 angle=0.0;
10572 if (attribute_flag[1] != 0)
10573 angle=argument_list[1].real_reference;
10574 if (attribute_flag[2] != 0)
10575 (void) CloneString(&draw_info->font,
10576 argument_list[2].string_reference);
10577 if (attribute_flag[3] != 0)
10578 (void) QueryColorCompliance(argument_list[3].string_reference,
10579 AllCompliance,&draw_info->stroke,exception);
10580 if (attribute_flag[4] != 0)
10581 (void) QueryColorCompliance(argument_list[4].string_reference,
10582 AllCompliance,&draw_info->fill,exception);
10583 if (attribute_flag[5] != 0)
10584 draw_info->stroke_width=argument_list[5].real_reference;
10585 if (attribute_flag[6] != 0)
10586 draw_info->pointsize=argument_list[6].real_reference;
10587 if (attribute_flag[7] != 0)
10588 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10589 if (attribute_flag[8] != 0)
10590 (void) QueryColorCompliance(argument_list[8].string_reference,
10591 AllCompliance,&image->background_color,exception);
10592 method=UndefinedInterpolatePixel;
10593 if (attribute_flag[9] != 0)
10594 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10595 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10596 draw_info=DestroyDrawInfo(draw_info);
10597 if (caption != (char *) NULL)
10598 caption=DestroyString(caption);
10599 break;
10600 }
10601 case 111: /* FloodfillPaint */
10602 {
10603 DrawInfo
10604 *draw_info;
10605
10606 MagickBooleanType
10607 invert;
10608
10609 PixelInfo
10610 target;
10611
10612 draw_info=CloneDrawInfo(info ? info->image_info :
10613 (ImageInfo *) NULL,(DrawInfo *) NULL);
10614 if (attribute_flag[0] != 0)
10615 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10616 &geometry,exception);
10617 if (attribute_flag[1] != 0)
10618 geometry.x=argument_list[1].integer_reference;
10619 if (attribute_flag[2] != 0)
10620 geometry.y=argument_list[2].integer_reference;
10621 if (attribute_flag[3] != 0)
10622 (void) QueryColorCompliance(argument_list[3].string_reference,
10623 AllCompliance,&draw_info->fill,exception);
10624 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10625 geometry.x,geometry.y,&target,exception);
10626 if (attribute_flag[4] != 0)
10627 QueryColorCompliance(argument_list[4].string_reference,
10628 AllCompliance,&target,exception);
10629 if (attribute_flag[5] != 0)
10630 image->fuzz=StringToDoubleInterval(
10631 argument_list[5].string_reference,(double) QuantumRange+1.0);
10632 if (attribute_flag[6] != 0)
10633 channel=(ChannelType) argument_list[6].integer_reference;
10634 invert=MagickFalse;
10635 if (attribute_flag[7] != 0)
10636 invert=(MagickBooleanType) argument_list[7].integer_reference;
10637 channel_mask=SetImageChannelMask(image,channel);
10638 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10639 geometry.y,invert,exception);
10640 (void) SetImageChannelMask(image,channel_mask);
10641 draw_info=DestroyDrawInfo(draw_info);
10642 break;
10643 }
10644 case 112: /* Distort */
10645 {
10646 AV
10647 *av;
10648
10649 double
10650 *coordinates;
10651
Cristy8645e042016-02-03 16:35:29 -050010652 DistortMethod
cristy4a3ce0a2013-08-03 20:06:59 +000010653 method;
10654
10655 size_t
10656 number_coordinates;
10657
10658 VirtualPixelMethod
10659 virtual_pixel;
10660
10661 if (attribute_flag[0] == 0)
10662 break;
10663 method=UndefinedDistortion;
10664 if (attribute_flag[1] != 0)
Cristy8645e042016-02-03 16:35:29 -050010665 method=(DistortMethod) argument_list[1].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010666 av=(AV *) argument_list[0].array_reference;
10667 number_coordinates=(size_t) av_len(av)+1;
10668 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10669 sizeof(*coordinates));
10670 if (coordinates == (double *) NULL)
10671 {
10672 ThrowPerlException(exception,ResourceLimitFatalError,
10673 "MemoryAllocationFailed",PackageName);
10674 goto PerlException;
10675 }
10676 for (j=0; j < (ssize_t) number_coordinates; j++)
10677 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10678 virtual_pixel=UndefinedVirtualPixelMethod;
10679 if (attribute_flag[2] != 0)
10680 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10681 argument_list[2].integer_reference,exception);
10682 image=DistortImage(image,method,number_coordinates,coordinates,
10683 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10684 exception);
10685 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10686 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10687 exception);
10688 coordinates=(double *) RelinquishMagickMemory(coordinates);
10689 break;
10690 }
10691 case 113: /* Clut */
10692 {
10693 PixelInterpolateMethod
10694 method;
10695
10696 if (attribute_flag[0] == 0)
10697 {
10698 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10699 PackageName);
10700 goto PerlException;
10701 }
10702 method=UndefinedInterpolatePixel;
10703 if (attribute_flag[1] != 0)
10704 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10705 if (attribute_flag[2] != 0)
10706 channel=(ChannelType) argument_list[2].integer_reference;
10707 channel_mask=SetImageChannelMask(image,channel);
10708 (void) ClutImage(image,argument_list[0].image_reference,method,
10709 exception);
10710 (void) SetImageChannelMask(image,channel_mask);
10711 break;
10712 }
10713 case 114: /* LiquidRescale */
10714 {
10715 if (attribute_flag[0] != 0)
10716 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10717 &geometry,exception);
10718 if (attribute_flag[1] != 0)
10719 geometry.width=argument_list[1].integer_reference;
10720 if (attribute_flag[2] != 0)
10721 geometry.height=argument_list[2].integer_reference;
10722 if (attribute_flag[3] == 0)
10723 argument_list[3].real_reference=1.0;
10724 if (attribute_flag[4] == 0)
10725 argument_list[4].real_reference=0.0;
10726 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10727 argument_list[3].real_reference,argument_list[4].real_reference,
10728 exception);
10729 break;
10730 }
10731 case 115: /* EncipherImage */
10732 {
10733 (void) EncipherImage(image,argument_list[0].string_reference,
10734 exception);
10735 break;
10736 }
10737 case 116: /* DecipherImage */
10738 {
10739 (void) DecipherImage(image,argument_list[0].string_reference,
10740 exception);
10741 break;
10742 }
10743 case 117: /* Deskew */
10744 {
10745 geometry_info.rho=QuantumRange/2.0;
10746 if (attribute_flag[0] != 0)
10747 flags=ParseGeometry(argument_list[0].string_reference,
10748 &geometry_info);
10749 if (attribute_flag[1] != 0)
10750 geometry_info.rho=StringToDoubleInterval(
10751 argument_list[1].string_reference,(double) QuantumRange+1.0);
10752 image=DeskewImage(image,geometry_info.rho,exception);
10753 break;
10754 }
10755 case 118: /* Remap */
10756 {
10757 QuantizeInfo
10758 *quantize_info;
10759
10760 if (attribute_flag[0] == 0)
10761 {
10762 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10763 PackageName);
10764 goto PerlException;
10765 }
10766 quantize_info=AcquireQuantizeInfo(info->image_info);
10767 if (attribute_flag[1] != 0)
10768 quantize_info->dither_method=(DitherMethod)
10769 argument_list[1].integer_reference;
10770 (void) RemapImages(quantize_info,image,
10771 argument_list[0].image_reference,exception);
10772 quantize_info=DestroyQuantizeInfo(quantize_info);
10773 break;
10774 }
10775 case 119: /* SparseColor */
10776 {
10777 AV
10778 *av;
10779
10780 double
10781 *coordinates;
10782
10783 SparseColorMethod
10784 method;
10785
10786 size_t
10787 number_coordinates;
10788
10789 VirtualPixelMethod
10790 virtual_pixel;
10791
10792 if (attribute_flag[0] == 0)
10793 break;
10794 method=UndefinedColorInterpolate;
10795 if (attribute_flag[1] != 0)
10796 method=(SparseColorMethod) argument_list[1].integer_reference;
10797 av=(AV *) argument_list[0].array_reference;
10798 number_coordinates=(size_t) av_len(av)+1;
10799 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10800 sizeof(*coordinates));
10801 if (coordinates == (double *) NULL)
10802 {
10803 ThrowPerlException(exception,ResourceLimitFatalError,
10804 "MemoryAllocationFailed",PackageName);
10805 goto PerlException;
10806 }
10807 for (j=0; j < (ssize_t) number_coordinates; j++)
10808 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10809 virtual_pixel=UndefinedVirtualPixelMethod;
10810 if (attribute_flag[2] != 0)
10811 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10812 argument_list[2].integer_reference,exception);
10813 if (attribute_flag[3] != 0)
10814 channel=(ChannelType) argument_list[3].integer_reference;
10815 channel_mask=SetImageChannelMask(image,channel);
10816 image=SparseColorImage(image,method,number_coordinates,coordinates,
10817 exception);
10818 if (image != (Image *) NULL)
10819 (void) SetImageChannelMask(image,channel_mask);
10820 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10821 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10822 exception);
10823 coordinates=(double *) RelinquishMagickMemory(coordinates);
10824 break;
10825 }
10826 case 120: /* Function */
10827 {
10828 AV
10829 *av;
10830
10831 double
10832 *parameters;
10833
10834 MagickFunction
10835 function;
10836
10837 size_t
10838 number_parameters;
10839
10840 VirtualPixelMethod
10841 virtual_pixel;
10842
10843 if (attribute_flag[0] == 0)
10844 break;
10845 function=UndefinedFunction;
10846 if (attribute_flag[1] != 0)
10847 function=(MagickFunction) argument_list[1].integer_reference;
10848 av=(AV *) argument_list[0].array_reference;
10849 number_parameters=(size_t) av_len(av)+1;
10850 parameters=(double *) AcquireQuantumMemory(number_parameters,
10851 sizeof(*parameters));
10852 if (parameters == (double *) NULL)
10853 {
10854 ThrowPerlException(exception,ResourceLimitFatalError,
10855 "MemoryAllocationFailed",PackageName);
10856 goto PerlException;
10857 }
10858 for (j=0; j < (ssize_t) number_parameters; j++)
10859 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10860 virtual_pixel=UndefinedVirtualPixelMethod;
10861 if (attribute_flag[2] != 0)
10862 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10863 argument_list[2].integer_reference,exception);
10864 (void) FunctionImage(image,function,number_parameters,parameters,
10865 exception);
10866 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10867 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10868 exception);
10869 parameters=(double *) RelinquishMagickMemory(parameters);
10870 break;
10871 }
10872 case 121: /* SelectiveBlur */
10873 {
10874 if (attribute_flag[0] != 0)
10875 {
10876 flags=ParseGeometry(argument_list[0].string_reference,
10877 &geometry_info);
10878 if ((flags & SigmaValue) == 0)
10879 geometry_info.sigma=1.0;
10880 if ((flags & PercentValue) != 0)
10881 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10882 }
10883 if (attribute_flag[1] != 0)
10884 geometry_info.rho=argument_list[1].real_reference;
10885 if (attribute_flag[2] != 0)
10886 geometry_info.sigma=argument_list[2].real_reference;
10887 if (attribute_flag[3] != 0)
10888 geometry_info.xi=argument_list[3].integer_reference;;
10889 if (attribute_flag[5] != 0)
10890 channel=(ChannelType) argument_list[5].integer_reference;
10891 channel_mask=SetImageChannelMask(image,channel);
10892 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10893 geometry_info.xi,exception);
10894 if (image != (Image *) NULL)
10895 (void) SetImageChannelMask(image,channel_mask);
10896 break;
10897 }
10898 case 122: /* HaldClut */
10899 {
10900 if (attribute_flag[0] == 0)
10901 {
10902 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10903 PackageName);
10904 goto PerlException;
10905 }
10906 if (attribute_flag[1] != 0)
10907 channel=(ChannelType) argument_list[1].integer_reference;
10908 channel_mask=SetImageChannelMask(image,channel);
10909 (void) HaldClutImage(image,argument_list[0].image_reference,
10910 exception);
10911 (void) SetImageChannelMask(image,channel_mask);
10912 break;
10913 }
10914 case 123: /* BlueShift */
10915 {
10916 if (attribute_flag[0] != 0)
10917 (void) ParseGeometry(argument_list[0].string_reference,
10918 &geometry_info);
10919 image=BlueShiftImage(image,geometry_info.rho,exception);
10920 break;
10921 }
10922 case 124: /* ForwardFourierTransformImage */
10923 {
10924 image=ForwardFourierTransformImage(image,
10925 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10926 exception);
10927 break;
10928 }
10929 case 125: /* InverseFourierTransformImage */
10930 {
10931 image=InverseFourierTransformImage(image,image->next,
10932 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10933 exception);
10934 break;
10935 }
10936 case 126: /* ColorDecisionList */
10937 {
10938 if (attribute_flag[0] == 0)
10939 argument_list[0].string_reference=(char *) NULL;
10940 (void) ColorDecisionListImage(image,
10941 argument_list[0].string_reference,exception);
10942 break;
10943 }
10944 case 127: /* AutoGamma */
10945 {
10946 if (attribute_flag[0] != 0)
10947 channel=(ChannelType) argument_list[0].integer_reference;
10948 channel_mask=SetImageChannelMask(image,channel);
10949 (void) AutoGammaImage(image,exception);
10950 (void) SetImageChannelMask(image,channel_mask);
10951 break;
10952 }
10953 case 128: /* AutoLevel */
10954 {
10955 if (attribute_flag[0] != 0)
10956 channel=(ChannelType) argument_list[0].integer_reference;
10957 channel_mask=SetImageChannelMask(image,channel);
10958 (void) AutoLevelImage(image,exception);
10959 (void) SetImageChannelMask(image,channel_mask);
10960 break;
10961 }
10962 case 129: /* LevelColors */
10963 {
10964 PixelInfo
10965 black_point,
10966 white_point;
10967
10968 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10969 exception);
10970 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10971 exception);
10972 if (attribute_flag[1] != 0)
10973 (void) QueryColorCompliance(
10974 argument_list[1].string_reference,AllCompliance,&black_point,
10975 exception);
10976 if (attribute_flag[2] != 0)
10977 (void) QueryColorCompliance(
10978 argument_list[2].string_reference,AllCompliance,&white_point,
10979 exception);
10980 if (attribute_flag[3] != 0)
10981 channel=(ChannelType) argument_list[3].integer_reference;
10982 channel_mask=SetImageChannelMask(image,channel);
10983 (void) LevelImageColors(image,&black_point,&white_point,
10984 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10985 exception);
10986 (void) SetImageChannelMask(image,channel_mask);
10987 break;
10988 }
10989 case 130: /* Clamp */
10990 {
10991 if (attribute_flag[0] != 0)
10992 channel=(ChannelType) argument_list[0].integer_reference;
10993 channel_mask=SetImageChannelMask(image,channel);
10994 (void) ClampImage(image,exception);
10995 (void) SetImageChannelMask(image,channel_mask);
10996 break;
10997 }
10998 case 131: /* BrightnessContrast */
10999 {
11000 double
11001 brightness,
11002 contrast;
11003
11004 brightness=0.0;
11005 contrast=0.0;
11006 if (attribute_flag[0] != 0)
11007 {
11008 flags=ParseGeometry(argument_list[0].string_reference,
11009 &geometry_info);
11010 brightness=geometry_info.rho;
11011 if ((flags & SigmaValue) == 0)
11012 contrast=geometry_info.sigma;
11013 }
11014 if (attribute_flag[1] != 0)
11015 brightness=argument_list[1].real_reference;
11016 if (attribute_flag[2] != 0)
11017 contrast=argument_list[2].real_reference;
11018 if (attribute_flag[4] != 0)
11019 channel=(ChannelType) argument_list[4].integer_reference;
11020 channel_mask=SetImageChannelMask(image,channel);
11021 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11022 (void) SetImageChannelMask(image,channel_mask);
11023 break;
11024 }
11025 case 132: /* Morphology */
11026 {
11027 KernelInfo
11028 *kernel;
11029
11030 MorphologyMethod
11031 method;
11032
11033 ssize_t
11034 iterations;
11035
11036 if (attribute_flag[0] == 0)
11037 break;
cristy2c57b742014-10-31 00:40:34 +000011038 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011039 if (kernel == (KernelInfo *) NULL)
11040 break;
11041 if (attribute_flag[1] != 0)
11042 channel=(ChannelType) argument_list[1].integer_reference;
11043 method=UndefinedMorphology;
11044 if (attribute_flag[2] != 0)
11045 method=argument_list[2].integer_reference;
11046 iterations=1;
11047 if (attribute_flag[3] != 0)
11048 iterations=argument_list[3].integer_reference;
11049 channel_mask=SetImageChannelMask(image,channel);
11050 image=MorphologyImage(image,method,iterations,kernel,exception);
11051 if (image != (Image *) NULL)
11052 (void) SetImageChannelMask(image,channel_mask);
11053 kernel=DestroyKernelInfo(kernel);
11054 break;
11055 }
11056 case 133: /* Mode */
11057 {
11058 if (attribute_flag[0] != 0)
11059 {
11060 flags=ParseGeometry(argument_list[0].string_reference,
11061 &geometry_info);
11062 if ((flags & SigmaValue) == 0)
11063 geometry_info.sigma=1.0;
11064 }
11065 if (attribute_flag[1] != 0)
11066 geometry_info.rho=argument_list[1].real_reference;
11067 if (attribute_flag[2] != 0)
11068 geometry_info.sigma=argument_list[2].real_reference;
11069 if (attribute_flag[3] != 0)
11070 channel=(ChannelType) argument_list[3].integer_reference;
11071 channel_mask=SetImageChannelMask(image,channel);
11072 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11073 (size_t) geometry_info.sigma,exception);
11074 if (image != (Image *) NULL)
11075 (void) SetImageChannelMask(image,channel_mask);
11076 break;
11077 }
11078 case 134: /* Statistic */
11079 {
11080 StatisticType
11081 statistic;
11082
11083 statistic=UndefinedStatistic;
11084 if (attribute_flag[0] != 0)
11085 {
11086 flags=ParseGeometry(argument_list[0].string_reference,
11087 &geometry_info);
11088 if ((flags & SigmaValue) == 0)
11089 geometry_info.sigma=1.0;
11090 }
11091 if (attribute_flag[1] != 0)
11092 geometry_info.rho=argument_list[1].real_reference;
11093 if (attribute_flag[2] != 0)
11094 geometry_info.sigma=argument_list[2].real_reference;
11095 if (attribute_flag[3] != 0)
11096 channel=(ChannelType) argument_list[3].integer_reference;
11097 if (attribute_flag[4] != 0)
11098 statistic=(StatisticType) argument_list[4].integer_reference;
11099 channel_mask=SetImageChannelMask(image,channel);
11100 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11101 (size_t) geometry_info.sigma,exception);
11102 if (image != (Image *) NULL)
11103 (void) SetImageChannelMask(image,channel_mask);
11104 break;
11105 }
11106 case 135: /* Perceptible */
11107 {
11108 double
11109 epsilon;
11110
11111 epsilon=MagickEpsilon;
11112 if (attribute_flag[0] != 0)
11113 epsilon=argument_list[0].real_reference;
11114 if (attribute_flag[1] != 0)
11115 channel=(ChannelType) argument_list[1].integer_reference;
11116 channel_mask=SetImageChannelMask(image,channel);
11117 (void) PerceptibleImage(image,epsilon,exception);
11118 (void) SetImageChannelMask(image,channel_mask);
11119 break;
11120 }
11121 case 136: /* Poly */
11122 {
11123 AV
11124 *av;
11125
11126 double
11127 *terms;
11128
11129 size_t
11130 number_terms;
11131
11132 if (attribute_flag[0] == 0)
11133 break;
11134 if (attribute_flag[1] != 0)
11135 channel=(ChannelType) argument_list[1].integer_reference;
11136 av=(AV *) argument_list[0].array_reference;
11137 number_terms=(size_t) av_len(av);
11138 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11139 if (terms == (double *) NULL)
11140 {
11141 ThrowPerlException(exception,ResourceLimitFatalError,
11142 "MemoryAllocationFailed",PackageName);
11143 goto PerlException;
11144 }
11145 for (j=0; j < av_len(av); j++)
11146 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11147 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11148 terms=(double *) RelinquishMagickMemory(terms);
11149 break;
11150 }
11151 case 137: /* Grayscale */
11152 {
11153 PixelIntensityMethod
11154 method;
11155
11156 method=UndefinedPixelIntensityMethod;
11157 if (attribute_flag[0] != 0)
11158 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11159 (void) GrayscaleImage(image,method,exception);
11160 break;
11161 }
cristy4ceadb82014-03-29 15:30:43 +000011162 case 138: /* Canny */
11163 {
11164 if (attribute_flag[0] != 0)
11165 {
11166 flags=ParseGeometry(argument_list[0].string_reference,
11167 &geometry_info);
11168 if ((flags & SigmaValue) == 0)
11169 geometry_info.sigma=1.0;
11170 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011171 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011172 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011173 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011174 if ((flags & PercentValue) != 0)
11175 {
11176 geometry_info.xi/=100.0;
11177 geometry_info.psi/=100.0;
11178 }
cristy4ceadb82014-03-29 15:30:43 +000011179 }
11180 if (attribute_flag[1] != 0)
11181 geometry_info.rho=argument_list[1].real_reference;
11182 if (attribute_flag[2] != 0)
11183 geometry_info.sigma=argument_list[2].real_reference;
11184 if (attribute_flag[3] != 0)
11185 geometry_info.xi=argument_list[3].real_reference;
11186 if (attribute_flag[4] != 0)
11187 geometry_info.psi=argument_list[4].real_reference;
11188 if (attribute_flag[5] != 0)
11189 channel=(ChannelType) argument_list[5].integer_reference;
11190 channel_mask=SetImageChannelMask(image,channel);
11191 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11192 geometry_info.xi,geometry_info.psi,exception);
11193 if (image != (Image *) NULL)
11194 (void) SetImageChannelMask(image,channel_mask);
11195 break;
11196 }
cristy2fc10e52014-04-26 14:13:53 +000011197 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011198 {
11199 if (attribute_flag[0] != 0)
11200 {
11201 flags=ParseGeometry(argument_list[0].string_reference,
11202 &geometry_info);
11203 if ((flags & SigmaValue) == 0)
11204 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011205 if ((flags & XiValue) == 0)
11206 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011207 }
11208 if (attribute_flag[1] != 0)
11209 geometry_info.rho=(double) argument_list[1].integer_reference;
11210 if (attribute_flag[2] != 0)
11211 geometry_info.sigma=(double) argument_list[2].integer_reference;
11212 if (attribute_flag[3] != 0)
11213 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011214 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11215 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11216 break;
11217 }
11218 case 140: /* MeanShift */
11219 {
11220 if (attribute_flag[0] != 0)
11221 {
11222 flags=ParseGeometry(argument_list[0].string_reference,
11223 &geometry_info);
11224 if ((flags & SigmaValue) == 0)
11225 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011226 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011227 geometry_info.xi=0.10*QuantumRange;
11228 if ((flags & PercentValue) != 0)
11229 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011230 }
11231 if (attribute_flag[1] != 0)
11232 geometry_info.rho=(double) argument_list[1].integer_reference;
11233 if (attribute_flag[2] != 0)
11234 geometry_info.sigma=(double) argument_list[2].integer_reference;
11235 if (attribute_flag[3] != 0)
11236 geometry_info.xi=(double) argument_list[3].integer_reference;
11237 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011238 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011239 break;
11240 }
cristy3b207f82014-09-27 14:21:20 +000011241 case 141: /* Kuwahara */
11242 {
11243 if (attribute_flag[0] != 0)
11244 {
11245 flags=ParseGeometry(argument_list[0].string_reference,
11246 &geometry_info);
11247 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011248 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011249 }
11250 if (attribute_flag[1] != 0)
11251 geometry_info.rho=argument_list[1].real_reference;
11252 if (attribute_flag[2] != 0)
11253 geometry_info.sigma=argument_list[2].real_reference;
11254 if (attribute_flag[3] != 0)
11255 channel=(ChannelType) argument_list[3].integer_reference;
11256 channel_mask=SetImageChannelMask(image,channel);
11257 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11258 exception);
11259 if (image != (Image *) NULL)
11260 (void) SetImageChannelMask(image,channel_mask);
11261 break;
11262 }
cristy6e0b3bc2014-10-19 17:51:42 +000011263 case 142: /* ConnectedComponent */
11264 {
11265 size_t
11266 connectivity;
11267
11268 connectivity=4;
11269 if (attribute_flag[0] != 0)
11270 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011271 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011272 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011273 break;
11274 }
cristy0b94b392015-06-22 18:56:37 +000011275 case 143: /* Copy */
11276 {
11277 Image
11278 *source_image;
11279
11280 OffsetInfo
11281 offset;
11282
cristy2ffdb092015-06-25 14:31:20 +000011283 RectangleInfo
11284 offset_geometry;
11285
cristyf3a724a2015-06-25 13:02:53 +000011286 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011287 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011288 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011289 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011290 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011291 flags=ParseGravityGeometry(source_image,
11292 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011293 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011294 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011295 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011296 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011297 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011298 geometry.x=argument_list[4].integer_reference;
11299 if (attribute_flag[5] != 0)
11300 geometry.y=argument_list[5].integer_reference;
11301 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011302 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011303 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011304 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011305 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11306 &offset_geometry,exception);
11307 offset.x=offset_geometry.x;
11308 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011309 if (attribute_flag[8] != 0)
11310 offset.x=argument_list[8].integer_reference;
11311 if (attribute_flag[9] != 0)
11312 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011313 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11314 exception);
cristy0b94b392015-06-22 18:56:37 +000011315 break;
11316 }
Cristy5488c982016-02-13 14:07:50 -050011317 case 144: /* Color */
11318 {
11319 PixelInfo
11320 color;
11321
Cristyf20e3562016-02-14 09:08:15 -050011322 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011323 if (attribute_flag[0] != 0)
Cristyf20e3562016-02-14 09:08:15 -050011324 (void) QueryColorCompliance(argument_list[0].string_reference,
11325 AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011326 (void) SetImageColor(image,&color,exception);
11327 break;
11328 }
Cristy2d830ed2016-02-21 10:54:16 -050011329 case 145: /* WaveletDenoise */
11330 {
Cristyc1759412016-02-27 12:17:58 -050011331 if (attribute_flag[0] != 0)
Cristyee21f7f2016-02-27 15:56:49 -050011332 {
11333 flags=ParseGeometry(argument_list[0].string_reference,
11334 &geometry_info);
11335 if ((flags & PercentValue) != 0)
11336 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11337 if ((flags & SigmaValue) == 0)
11338 geometry_info.sigma=0.0;
11339 }
Cristyc1759412016-02-27 12:17:58 -050011340 if (attribute_flag[1] != 0)
11341 geometry_info.rho=argument_list[1].real_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011342 if (attribute_flag[2] != 0)
Cristyc1759412016-02-27 12:17:58 -050011343 geometry_info.sigma=argument_list[2].real_reference;
11344 if (attribute_flag[3] != 0)
11345 channel=(ChannelType) argument_list[3].integer_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011346 channel_mask=SetImageChannelMask(image,channel);
Cristyc1759412016-02-27 12:17:58 -050011347 image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11348 exception);
Cristy2d830ed2016-02-21 10:54:16 -050011349 if (image != (Image *) NULL)
11350 (void) SetImageChannelMask(image,channel_mask);
11351 break;
11352 }
cristy4a3ce0a2013-08-03 20:06:59 +000011353 }
11354 if (next != (Image *) NULL)
11355 (void) CatchImageException(next);
11356 if (region_image != (Image *) NULL)
11357 {
11358 /*
11359 Composite region.
cristy83a28a02013-08-03 20:25:48 +000011360 */
cristy4a3ce0a2013-08-03 20:06:59 +000011361 status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11362 region_info.x,region_info.y,exception);
11363 (void) status;
11364 (void) CatchImageException(region_image);
11365 image=DestroyImage(image);
11366 image=region_image;
11367 }
11368 if (image != (Image *) NULL)
11369 {
11370 number_images++;
11371 if (next && (next != image))
11372 {
11373 image->next=next->next;
11374 if (image->next != (Image *) NULL)
11375 image->next->previous=image;
11376 DeleteImageFromRegistry(*pv,next);
11377 }
11378 sv_setiv(*pv,PTR2IV(image));
11379 next=image;
11380 }
11381 if (*pv)
11382 pv++;
11383 }
11384
11385 PerlException:
11386 if (reference_vector)
11387 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11388 InheritPerlException(exception,perl_exception);
11389 exception=DestroyExceptionInfo(exception);
11390 sv_setiv(perl_exception,(IV) number_images);
11391 SvPOK_on(perl_exception);
11392 ST(0)=sv_2mortal(perl_exception);
11393 XSRETURN(1);
11394 }
11395
11396#
11397###############################################################################
11398# #
11399# #
11400# #
11401# M o n t a g e #
11402# #
11403# #
11404# #
11405###############################################################################
11406#
11407#
11408void
11409Montage(ref,...)
11410 Image::Magick ref=NO_INIT
11411 ALIAS:
11412 MontageImage = 1
11413 montage = 2
11414 montageimage = 3
11415 PPCODE:
11416 {
11417 AV
11418 *av;
11419
11420 char
11421 *attribute;
11422
11423 ExceptionInfo
11424 *exception;
11425
11426 HV
11427 *hv;
11428
11429 Image
11430 *image,
11431 *next;
11432
11433 PixelInfo
11434 transparent_color;
11435
11436 MontageInfo
11437 *montage_info;
11438
11439 register ssize_t
11440 i;
11441
11442 ssize_t
11443 sp;
11444
11445 struct PackageInfo
11446 *info;
11447
11448 SV
11449 *av_reference,
11450 *perl_exception,
11451 *reference,
11452 *rv,
11453 *sv;
11454
11455 PERL_UNUSED_VAR(ref);
11456 PERL_UNUSED_VAR(ix);
11457 exception=AcquireExceptionInfo();
11458 perl_exception=newSVpv("",0);
11459 sv=NULL;
11460 attribute=NULL;
11461 if (sv_isobject(ST(0)) == 0)
11462 {
11463 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11464 PackageName);
11465 goto PerlException;
11466 }
11467 reference=SvRV(ST(0));
11468 hv=SvSTASH(reference);
11469 av=newAV();
11470 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11471 SvREFCNT_dec(av);
11472 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11473 if (image == (Image *) NULL)
11474 {
11475 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11476 PackageName);
11477 goto PerlException;
11478 }
11479 /*
11480 Get options.
11481 */
11482 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11483 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11484 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11485 exception);
11486 for (i=2; i < items; i+=2)
11487 {
11488 attribute=(char *) SvPV(ST(i-1),na);
11489 switch (*attribute)
11490 {
11491 case 'B':
11492 case 'b':
11493 {
11494 if (LocaleCompare(attribute,"background") == 0)
11495 {
11496 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11497 &montage_info->background_color,exception);
11498 for (next=image; next; next=next->next)
11499 next->background_color=montage_info->background_color;
11500 break;
11501 }
11502 if (LocaleCompare(attribute,"border") == 0)
11503 {
11504 montage_info->border_width=SvIV(ST(i));
11505 break;
11506 }
11507 if (LocaleCompare(attribute,"bordercolor") == 0)
11508 {
11509 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11510 &montage_info->border_color,exception);
11511 for (next=image; next; next=next->next)
11512 next->border_color=montage_info->border_color;
11513 break;
11514 }
11515 if (LocaleCompare(attribute,"borderwidth") == 0)
11516 {
11517 montage_info->border_width=SvIV(ST(i));
11518 break;
11519 }
11520 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11521 attribute);
11522 break;
11523 }
11524 case 'C':
11525 case 'c':
11526 {
11527 if (LocaleCompare(attribute,"compose") == 0)
11528 {
11529 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11530 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11531 if (sp < 0)
11532 {
11533 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11534 SvPV(ST(i),na));
11535 break;
11536 }
11537 for (next=image; next; next=next->next)
11538 next->compose=(CompositeOperator) sp;
11539 break;
11540 }
11541 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11542 attribute);
11543 break;
11544 }
11545 case 'F':
11546 case 'f':
11547 {
11548 if (LocaleCompare(attribute,"fill") == 0)
11549 {
11550 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11551 &montage_info->fill,exception);
11552 break;
11553 }
11554 if (LocaleCompare(attribute,"font") == 0)
11555 {
11556 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11557 break;
11558 }
11559 if (LocaleCompare(attribute,"frame") == 0)
11560 {
11561 char
11562 *p;
11563
11564 p=SvPV(ST(i),na);
11565 if (IsGeometry(p) == MagickFalse)
11566 {
11567 ThrowPerlException(exception,OptionError,"MissingGeometry",
11568 p);
11569 break;
11570 }
11571 (void) CloneString(&montage_info->frame,p);
11572 if (*p == '\0')
11573 montage_info->frame=(char *) NULL;
11574 break;
11575 }
11576 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11577 attribute);
11578 break;
11579 }
11580 case 'G':
11581 case 'g':
11582 {
11583 if (LocaleCompare(attribute,"geometry") == 0)
11584 {
11585 char
11586 *p;
11587
11588 p=SvPV(ST(i),na);
11589 if (IsGeometry(p) == MagickFalse)
11590 {
11591 ThrowPerlException(exception,OptionError,"MissingGeometry",
11592 p);
11593 break;
11594 }
11595 (void) CloneString(&montage_info->geometry,p);
11596 if (*p == '\0')
11597 montage_info->geometry=(char *) NULL;
11598 break;
11599 }
11600 if (LocaleCompare(attribute,"gravity") == 0)
11601 {
11602 ssize_t
11603 in;
11604
11605 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11606 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11607 if (in < 0)
11608 {
11609 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11610 SvPV(ST(i),na));
11611 return;
11612 }
11613 montage_info->gravity=(GravityType) in;
11614 for (next=image; next; next=next->next)
11615 next->gravity=(GravityType) in;
11616 break;
11617 }
11618 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11619 attribute);
11620 break;
11621 }
11622 case 'L':
11623 case 'l':
11624 {
11625 if (LocaleCompare(attribute,"label") == 0)
11626 {
11627 for (next=image; next; next=next->next)
11628 (void) SetImageProperty(next,"label",InterpretImageProperties(
11629 info ? info->image_info : (ImageInfo *) NULL,next,
11630 SvPV(ST(i),na),exception),exception);
11631 break;
11632 }
11633 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11634 attribute);
11635 break;
11636 }
11637 case 'M':
11638 case 'm':
11639 {
11640 if (LocaleCompare(attribute,"mattecolor") == 0)
11641 {
11642 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
Cristy8645e042016-02-03 16:35:29 -050011643 &montage_info->alpha_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011644 for (next=image; next; next=next->next)
Cristy8645e042016-02-03 16:35:29 -050011645 next->alpha_color=montage_info->alpha_color;
cristy4a3ce0a2013-08-03 20:06:59 +000011646 break;
11647 }
11648 if (LocaleCompare(attribute,"mode") == 0)
11649 {
11650 ssize_t
11651 in;
11652
11653 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11654 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11655 switch (in)
11656 {
11657 default:
11658 {
11659 ThrowPerlException(exception,OptionError,
11660 "UnrecognizedModeType",SvPV(ST(i),na));
11661 break;
11662 }
11663 case FrameMode:
11664 {
11665 (void) CloneString(&montage_info->frame,"15x15+3+3");
11666 montage_info->shadow=MagickTrue;
11667 break;
11668 }
11669 case UnframeMode:
11670 {
11671 montage_info->frame=(char *) NULL;
11672 montage_info->shadow=MagickFalse;
11673 montage_info->border_width=0;
11674 break;
11675 }
11676 case ConcatenateMode:
11677 {
11678 montage_info->frame=(char *) NULL;
11679 montage_info->shadow=MagickFalse;
11680 (void) CloneString(&montage_info->geometry,"+0+0");
11681 montage_info->border_width=0;
11682 }
11683 }
11684 break;
11685 }
11686 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11687 attribute);
11688 break;
11689 }
11690 case 'P':
11691 case 'p':
11692 {
11693 if (LocaleCompare(attribute,"pointsize") == 0)
11694 {
11695 montage_info->pointsize=SvIV(ST(i));
11696 break;
11697 }
11698 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11699 attribute);
11700 break;
11701 }
11702 case 'S':
11703 case 's':
11704 {
11705 if (LocaleCompare(attribute,"shadow") == 0)
11706 {
11707 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11708 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11709 if (sp < 0)
11710 {
11711 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11712 SvPV(ST(i),na));
11713 break;
11714 }
11715 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11716 break;
11717 }
11718 if (LocaleCompare(attribute,"stroke") == 0)
11719 {
11720 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11721 &montage_info->stroke,exception);
11722 break;
11723 }
11724 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11725 attribute);
11726 break;
11727 }
11728 case 'T':
11729 case 't':
11730 {
11731 if (LocaleCompare(attribute,"texture") == 0)
11732 {
11733 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11734 break;
11735 }
11736 if (LocaleCompare(attribute,"tile") == 0)
11737 {
11738 char *p=SvPV(ST(i),na);
11739 if (IsGeometry(p) == MagickFalse)
11740 {
11741 ThrowPerlException(exception,OptionError,"MissingGeometry",
11742 p);
11743 break;
11744 }
11745 (void) CloneString(&montage_info->tile,p);
11746 if (*p == '\0')
11747 montage_info->tile=(char *) NULL;
11748 break;
11749 }
11750 if (LocaleCompare(attribute,"title") == 0)
11751 {
11752 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11753 break;
11754 }
11755 if (LocaleCompare(attribute,"transparent") == 0)
11756 {
11757 PixelInfo
11758 transparent_color;
11759
11760 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11761 &transparent_color,exception);
11762 for (next=image; next; next=next->next)
11763 (void) TransparentPaintImage(next,&transparent_color,
11764 TransparentAlpha,MagickFalse,exception);
11765 break;
11766 }
11767 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11768 attribute);
11769 break;
11770 }
11771 default:
11772 {
11773 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11774 attribute);
11775 break;
11776 }
11777 }
11778 }
11779 image=MontageImageList(info->image_info,montage_info,image,exception);
11780 montage_info=DestroyMontageInfo(montage_info);
11781 if (image == (Image *) NULL)
11782 goto PerlException;
11783 if (transparent_color.alpha != TransparentAlpha)
11784 for (next=image; next; next=next->next)
11785 (void) TransparentPaintImage(next,&transparent_color,
11786 TransparentAlpha,MagickFalse,exception);
11787 for ( ; image; image=image->next)
11788 {
11789 AddImageToRegistry(sv,image);
11790 rv=newRV(sv);
11791 av_push(av,sv_bless(rv,hv));
11792 SvREFCNT_dec(sv);
11793 }
11794 exception=DestroyExceptionInfo(exception);
11795 ST(0)=av_reference;
11796 SvREFCNT_dec(perl_exception);
11797 XSRETURN(1);
11798
11799 PerlException:
11800 InheritPerlException(exception,perl_exception);
11801 exception=DestroyExceptionInfo(exception);
11802 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11803 SvPOK_on(perl_exception);
11804 ST(0)=sv_2mortal(perl_exception);
11805 XSRETURN(1);
11806 }
11807
11808#
11809###############################################################################
11810# #
11811# #
11812# #
11813# M o r p h #
11814# #
11815# #
11816# #
11817###############################################################################
11818#
11819#
11820void
11821Morph(ref,...)
11822 Image::Magick ref=NO_INIT
11823 ALIAS:
11824 MorphImage = 1
11825 morph = 2
11826 morphimage = 3
11827 PPCODE:
11828 {
11829 AV
11830 *av;
11831
11832 char
11833 *attribute;
11834
11835 ExceptionInfo
11836 *exception;
11837
11838 HV
11839 *hv;
11840
11841 Image
11842 *image;
11843
11844 register ssize_t
11845 i;
11846
11847 ssize_t
11848 number_frames;
11849
11850 struct PackageInfo
11851 *info;
11852
11853 SV
11854 *av_reference,
11855 *perl_exception,
11856 *reference,
11857 *rv,
11858 *sv;
11859
11860 PERL_UNUSED_VAR(ref);
11861 PERL_UNUSED_VAR(ix);
11862 exception=AcquireExceptionInfo();
11863 perl_exception=newSVpv("",0);
11864 sv=NULL;
11865 av=NULL;
11866 attribute=NULL;
11867 if (sv_isobject(ST(0)) == 0)
11868 {
11869 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11870 PackageName);
11871 goto PerlException;
11872 }
11873 reference=SvRV(ST(0));
11874 hv=SvSTASH(reference);
11875 av=newAV();
11876 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11877 SvREFCNT_dec(av);
11878 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11879 if (image == (Image *) NULL)
11880 {
11881 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11882 PackageName);
11883 goto PerlException;
11884 }
11885 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11886 /*
11887 Get attribute.
11888 */
11889 number_frames=30;
11890 for (i=2; i < items; i+=2)
11891 {
11892 attribute=(char *) SvPV(ST(i-1),na);
11893 switch (*attribute)
11894 {
11895 case 'F':
11896 case 'f':
11897 {
11898 if (LocaleCompare(attribute,"frames") == 0)
11899 {
11900 number_frames=SvIV(ST(i));
11901 break;
11902 }
11903 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11904 attribute);
11905 break;
11906 }
11907 default:
11908 {
11909 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11910 attribute);
11911 break;
11912 }
11913 }
11914 }
11915 image=MorphImages(image,number_frames,exception);
11916 if (image == (Image *) NULL)
11917 goto PerlException;
11918 for ( ; image; image=image->next)
11919 {
11920 AddImageToRegistry(sv,image);
11921 rv=newRV(sv);
11922 av_push(av,sv_bless(rv,hv));
11923 SvREFCNT_dec(sv);
11924 }
11925 exception=DestroyExceptionInfo(exception);
11926 ST(0)=av_reference;
11927 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11928 XSRETURN(1);
11929
11930 PerlException:
11931 InheritPerlException(exception,perl_exception);
11932 exception=DestroyExceptionInfo(exception);
11933 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11934 SvPOK_on(perl_exception);
11935 ST(0)=sv_2mortal(perl_exception);
11936 XSRETURN(1);
11937 }
11938
11939#
11940###############################################################################
11941# #
11942# #
11943# #
11944# M o s a i c #
11945# #
11946# #
11947# #
11948###############################################################################
11949#
11950#
11951void
11952Mosaic(ref)
11953 Image::Magick ref=NO_INIT
11954 ALIAS:
11955 MosaicImage = 1
11956 mosaic = 2
11957 mosaicimage = 3
11958 PPCODE:
11959 {
11960 AV
11961 *av;
11962
11963 ExceptionInfo
11964 *exception;
11965
11966 HV
11967 *hv;
11968
11969 Image
11970 *image;
11971
11972 struct PackageInfo
11973 *info;
11974
11975 SV
11976 *perl_exception,
11977 *reference,
11978 *rv,
11979 *sv;
11980
11981 PERL_UNUSED_VAR(ref);
11982 PERL_UNUSED_VAR(ix);
11983 exception=AcquireExceptionInfo();
11984 perl_exception=newSVpv("",0);
11985 sv=NULL;
11986 if (sv_isobject(ST(0)) == 0)
11987 {
11988 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11989 PackageName);
11990 goto PerlException;
11991 }
11992 reference=SvRV(ST(0));
11993 hv=SvSTASH(reference);
11994 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11995 if (image == (Image *) NULL)
11996 {
11997 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11998 PackageName);
11999 goto PerlException;
12000 }
12001 image=MergeImageLayers(image,MosaicLayer,exception);
12002 /*
12003 Create blessed Perl array for the returned image.
12004 */
12005 av=newAV();
12006 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12007 SvREFCNT_dec(av);
12008 AddImageToRegistry(sv,image);
12009 rv=newRV(sv);
12010 av_push(av,sv_bless(rv,hv));
12011 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000012012 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000012013 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012014 SetImageInfo(info->image_info,0,exception);
12015 exception=DestroyExceptionInfo(exception);
12016 SvREFCNT_dec(perl_exception);
12017 XSRETURN(1);
12018
12019 PerlException:
12020 InheritPerlException(exception,perl_exception);
12021 exception=DestroyExceptionInfo(exception);
12022 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12023 SvPOK_on(perl_exception); /* return messages in string context */
12024 ST(0)=sv_2mortal(perl_exception);
12025 XSRETURN(1);
12026 }
12027
12028#
12029###############################################################################
12030# #
12031# #
12032# #
12033# P i n g #
12034# #
12035# #
12036# #
12037###############################################################################
12038#
12039#
12040void
12041Ping(ref,...)
12042 Image::Magick ref=NO_INIT
12043 ALIAS:
12044 PingImage = 1
12045 ping = 2
12046 pingimage = 3
12047 PPCODE:
12048 {
12049 AV
12050 *av;
12051
12052 char
12053 **keep,
12054 **list;
12055
12056 ExceptionInfo
12057 *exception;
12058
12059 Image
12060 *image,
12061 *next;
12062
12063 int
12064 n;
12065
12066 MagickBooleanType
12067 status;
12068
12069 register char
12070 **p;
12071
12072 register ssize_t
12073 i;
12074
12075 ssize_t
12076 ac;
12077
12078 STRLEN
12079 *length;
12080
12081 struct PackageInfo
12082 *info,
12083 *package_info;
12084
12085 SV
12086 *perl_exception,
12087 *reference;
12088
12089 size_t
12090 count;
12091
12092 PERL_UNUSED_VAR(ref);
12093 PERL_UNUSED_VAR(ix);
12094 exception=AcquireExceptionInfo();
12095 perl_exception=newSVpv("",0);
12096 package_info=(struct PackageInfo *) NULL;
12097 ac=(items < 2) ? 1 : items-1;
12098 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12099 keep=list;
12100 length=(STRLEN *) NULL;
12101 if (list == (char **) NULL)
12102 {
12103 ThrowPerlException(exception,ResourceLimitError,
12104 "MemoryAllocationFailed",PackageName);
12105 goto PerlException;
12106 }
12107 keep=list;
12108 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12109 if (length == (STRLEN *) NULL)
12110 {
12111 ThrowPerlException(exception,ResourceLimitError,
12112 "MemoryAllocationFailed",PackageName);
12113 goto PerlException;
12114 }
12115 if (sv_isobject(ST(0)) == 0)
12116 {
12117 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12118 PackageName);
12119 goto PerlException;
12120 }
12121 reference=SvRV(ST(0));
12122 if (SvTYPE(reference) != SVt_PVAV)
12123 {
12124 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12125 PackageName);
12126 goto PerlException;
12127 }
12128 av=(AV *) reference;
12129 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12130 exception);
12131 package_info=ClonePackageInfo(info,exception);
12132 n=1;
12133 if (items <= 1)
12134 *list=(char *) (*package_info->image_info->filename ?
12135 package_info->image_info->filename : "XC:black");
12136 else
12137 for (n=0, i=0; i < ac; i++)
12138 {
12139 list[n]=(char *) SvPV(ST(i+1),length[n]);
12140 if ((items >= 3) && strEQcase(list[n],"blob"))
12141 {
12142 void
12143 *blob;
12144
12145 i++;
12146 blob=(void *) (SvPV(ST(i+1),length[n]));
12147 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12148 }
12149 if ((items >= 3) && strEQcase(list[n],"filename"))
12150 continue;
12151 if ((items >= 3) && strEQcase(list[n],"file"))
12152 {
12153 FILE
12154 *file;
12155
12156 PerlIO
12157 *io_info;
12158
12159 i++;
12160 io_info=IoIFP(sv_2io(ST(i+1)));
12161 if (io_info == (PerlIO *) NULL)
12162 {
12163 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12164 PackageName);
12165 continue;
12166 }
12167 file=PerlIO_findFILE(io_info);
12168 if (file == (FILE *) NULL)
12169 {
12170 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12171 PackageName);
12172 continue;
12173 }
12174 SetImageInfoFile(package_info->image_info,file);
12175 }
12176 if ((items >= 3) && strEQcase(list[n],"magick"))
12177 continue;
12178 n++;
12179 }
12180 list[n]=(char *) NULL;
12181 keep=list;
12182 status=ExpandFilenames(&n,&list);
12183 if (status == MagickFalse)
12184 {
12185 ThrowPerlException(exception,ResourceLimitError,
12186 "MemoryAllocationFailed",PackageName);
12187 goto PerlException;
12188 }
12189 count=0;
12190 for (i=0; i < n; i++)
12191 {
12192 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012193 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012194 image=PingImage(package_info->image_info,exception);
12195 if (image == (Image *) NULL)
12196 break;
12197 if ((package_info->image_info->file != (FILE *) NULL) ||
12198 (package_info->image_info->blob != (void *) NULL))
12199 DisassociateImageStream(image);
12200 count+=GetImageListLength(image);
12201 EXTEND(sp,4*count);
12202 for (next=image; next; next=next->next)
12203 {
12204 PUSHs(sv_2mortal(newSViv(next->columns)));
12205 PUSHs(sv_2mortal(newSViv(next->rows)));
12206 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12207 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12208 }
12209 image=DestroyImageList(image);
12210 }
12211 /*
12212 Free resources.
12213 */
12214 for (i=0; i < n; i++)
12215 if (list[i] != (char *) NULL)
12216 for (p=keep; list[i] != *p++; )
12217 if (*p == NULL)
12218 {
12219 list[i]=(char *) RelinquishMagickMemory(list[i]);
12220 break;
12221 }
12222
12223 PerlException:
12224 if (package_info != (struct PackageInfo *) NULL)
12225 DestroyPackageInfo(package_info);
12226 if (list && (list != keep))
12227 list=(char **) RelinquishMagickMemory(list);
12228 if (keep)
12229 keep=(char **) RelinquishMagickMemory(keep);
12230 if (length)
12231 length=(STRLEN *) RelinquishMagickMemory(length);
12232 InheritPerlException(exception,perl_exception);
12233 exception=DestroyExceptionInfo(exception);
12234 SvREFCNT_dec(perl_exception); /* throw away all errors */
12235 }
12236
12237#
12238###############################################################################
12239# #
12240# #
12241# #
12242# P r e v i e w #
12243# #
12244# #
12245# #
12246###############################################################################
12247#
12248#
12249void
12250Preview(ref,...)
12251 Image::Magick ref=NO_INIT
12252 ALIAS:
12253 PreviewImage = 1
12254 preview = 2
12255 previewimage = 3
12256 PPCODE:
12257 {
12258 AV
12259 *av;
12260
12261 ExceptionInfo
12262 *exception;
12263
12264 HV
12265 *hv;
12266
12267 Image
12268 *image,
12269 *preview_image;
12270
12271 PreviewType
12272 preview_type;
12273
12274 struct PackageInfo
12275 *info;
12276
12277 SV
12278 *av_reference,
12279 *perl_exception,
12280 *reference,
12281 *rv,
12282 *sv;
12283
12284 PERL_UNUSED_VAR(ref);
12285 PERL_UNUSED_VAR(ix);
12286 exception=AcquireExceptionInfo();
12287 perl_exception=newSVpv("",0);
12288 sv=NULL;
12289 av=NULL;
12290 if (sv_isobject(ST(0)) == 0)
12291 {
12292 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12293 PackageName);
12294 goto PerlException;
12295 }
12296 reference=SvRV(ST(0));
12297 hv=SvSTASH(reference);
12298 av=newAV();
12299 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12300 SvREFCNT_dec(av);
12301 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12302 if (image == (Image *) NULL)
12303 {
12304 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12305 PackageName);
12306 goto PerlException;
12307 }
12308 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12309 preview_type=GammaPreview;
12310 if (items > 1)
12311 preview_type=(PreviewType)
12312 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12313 for ( ; image; image=image->next)
12314 {
12315 preview_image=PreviewImage(image,preview_type,exception);
12316 if (preview_image == (Image *) NULL)
12317 goto PerlException;
12318 AddImageToRegistry(sv,preview_image);
12319 rv=newRV(sv);
12320 av_push(av,sv_bless(rv,hv));
12321 SvREFCNT_dec(sv);
12322 }
12323 exception=DestroyExceptionInfo(exception);
12324 ST(0)=av_reference;
12325 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12326 XSRETURN(1);
12327
12328 PerlException:
12329 InheritPerlException(exception,perl_exception);
12330 exception=DestroyExceptionInfo(exception);
12331 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12332 SvPOK_on(perl_exception);
12333 ST(0)=sv_2mortal(perl_exception);
12334 XSRETURN(1);
12335 }
12336
12337#
12338###############################################################################
12339# #
12340# #
12341# #
12342# Q u e r y C o l o r #
12343# #
12344# #
12345# #
12346###############################################################################
12347#
12348#
12349void
12350QueryColor(ref,...)
12351 Image::Magick ref=NO_INIT
12352 ALIAS:
12353 querycolor = 1
12354 PPCODE:
12355 {
12356 char
12357 *name;
12358
12359 ExceptionInfo
12360 *exception;
12361
12362 PixelInfo
12363 color;
12364
12365 register ssize_t
12366 i;
12367
12368 SV
12369 *perl_exception;
12370
12371 PERL_UNUSED_VAR(ref);
12372 PERL_UNUSED_VAR(ix);
12373 exception=AcquireExceptionInfo();
12374 perl_exception=newSVpv("",0);
12375 if (items == 1)
12376 {
12377 const ColorInfo
12378 **colorlist;
12379
12380 size_t
12381 colors;
12382
12383 colorlist=GetColorInfoList("*",&colors,exception);
12384 EXTEND(sp,colors);
12385 for (i=0; i < (ssize_t) colors; i++)
12386 {
12387 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12388 }
12389 colorlist=(const ColorInfo **)
12390 RelinquishMagickMemory((ColorInfo **) colorlist);
12391 goto PerlException;
12392 }
12393 EXTEND(sp,5*items);
12394 for (i=1; i < items; i++)
12395 {
12396 name=(char *) SvPV(ST(i),na);
12397 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12398 {
12399 PUSHs(&sv_undef);
12400 continue;
12401 }
12402 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12403 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12404 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12405 if (color.colorspace == CMYKColorspace)
12406 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012407 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012408 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12409 }
12410
12411 PerlException:
12412 InheritPerlException(exception,perl_exception);
12413 exception=DestroyExceptionInfo(exception);
12414 SvREFCNT_dec(perl_exception);
12415 }
12416
12417#
12418###############################################################################
12419# #
12420# #
12421# #
12422# Q u e r y C o l o r N a m e #
12423# #
12424# #
12425# #
12426###############################################################################
12427#
12428#
12429void
12430QueryColorname(ref,...)
12431 Image::Magick ref=NO_INIT
12432 ALIAS:
12433 querycolorname = 1
12434 PPCODE:
12435 {
12436 AV
12437 *av;
12438
12439 char
cristy151b66d2015-04-15 10:50:31 +000012440 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012441
12442 ExceptionInfo
12443 *exception;
12444
12445 Image
12446 *image;
12447
12448 PixelInfo
12449 target_color;
12450
12451 register ssize_t
12452 i;
12453
12454 struct PackageInfo
12455 *info;
12456
12457 SV
12458 *perl_exception,
12459 *reference; /* reference is the SV* of ref=SvIV(reference) */
12460
12461 PERL_UNUSED_VAR(ref);
12462 PERL_UNUSED_VAR(ix);
12463 exception=AcquireExceptionInfo();
12464 perl_exception=newSVpv("",0);
12465 reference=SvRV(ST(0));
12466 av=(AV *) reference;
12467 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12468 exception);
12469 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12470 if (image == (Image *) NULL)
12471 {
12472 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12473 PackageName);
12474 goto PerlException;
12475 }
12476 EXTEND(sp,items);
12477 for (i=1; i < items; i++)
12478 {
12479 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12480 exception);
12481 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12482 exception);
12483 PUSHs(sv_2mortal(newSVpv(message,0)));
12484 }
12485
12486 PerlException:
12487 InheritPerlException(exception,perl_exception);
12488 exception=DestroyExceptionInfo(exception);
12489 SvREFCNT_dec(perl_exception);
12490 }
12491
12492#
12493###############################################################################
12494# #
12495# #
12496# #
12497# Q u e r y F o n t #
12498# #
12499# #
12500# #
12501###############################################################################
12502#
12503#
12504void
12505QueryFont(ref,...)
12506 Image::Magick ref=NO_INIT
12507 ALIAS:
12508 queryfont = 1
12509 PPCODE:
12510 {
12511 char
12512 *name,
cristy151b66d2015-04-15 10:50:31 +000012513 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012514
12515 ExceptionInfo
12516 *exception;
12517
12518 register ssize_t
12519 i;
12520
12521 SV
12522 *perl_exception;
12523
12524 volatile const TypeInfo
12525 *type_info;
12526
12527 PERL_UNUSED_VAR(ref);
12528 PERL_UNUSED_VAR(ix);
12529 exception=AcquireExceptionInfo();
12530 perl_exception=newSVpv("",0);
12531 if (items == 1)
12532 {
12533 const TypeInfo
12534 **typelist;
12535
12536 size_t
12537 types;
12538
12539 typelist=GetTypeInfoList("*",&types,exception);
12540 EXTEND(sp,types);
12541 for (i=0; i < (ssize_t) types; i++)
12542 {
12543 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12544 }
12545 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12546 typelist);
12547 goto PerlException;
12548 }
12549 EXTEND(sp,10*items);
12550 for (i=1; i < items; i++)
12551 {
12552 name=(char *) SvPV(ST(i),na);
12553 type_info=GetTypeInfo(name,exception);
12554 if (type_info == (TypeInfo *) NULL)
12555 {
12556 PUSHs(&sv_undef);
12557 continue;
12558 }
12559 if (type_info->name == (char *) NULL)
12560 PUSHs(&sv_undef);
12561 else
12562 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12563 if (type_info->description == (char *) NULL)
12564 PUSHs(&sv_undef);
12565 else
12566 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12567 if (type_info->family == (char *) NULL)
12568 PUSHs(&sv_undef);
12569 else
12570 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12571 if (type_info->style == UndefinedStyle)
12572 PUSHs(&sv_undef);
12573 else
12574 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12575 type_info->style),0)));
12576 if (type_info->stretch == UndefinedStretch)
12577 PUSHs(&sv_undef);
12578 else
12579 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12580 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012581 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012582 type_info->weight);
12583 PUSHs(sv_2mortal(newSVpv(message,0)));
12584 if (type_info->encoding == (char *) NULL)
12585 PUSHs(&sv_undef);
12586 else
12587 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12588 if (type_info->foundry == (char *) NULL)
12589 PUSHs(&sv_undef);
12590 else
12591 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12592 if (type_info->format == (char *) NULL)
12593 PUSHs(&sv_undef);
12594 else
12595 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12596 if (type_info->metrics == (char *) NULL)
12597 PUSHs(&sv_undef);
12598 else
12599 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12600 if (type_info->glyphs == (char *) NULL)
12601 PUSHs(&sv_undef);
12602 else
12603 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12604 }
12605
12606 PerlException:
12607 InheritPerlException(exception,perl_exception);
12608 exception=DestroyExceptionInfo(exception);
12609 SvREFCNT_dec(perl_exception);
12610 }
12611
12612#
12613###############################################################################
12614# #
12615# #
12616# #
12617# Q u e r y F o n t M e t r i c s #
12618# #
12619# #
12620# #
12621###############################################################################
12622#
12623#
12624void
12625QueryFontMetrics(ref,...)
12626 Image::Magick ref=NO_INIT
12627 ALIAS:
12628 queryfontmetrics = 1
12629 PPCODE:
12630 {
12631 AffineMatrix
12632 affine,
12633 current;
12634
12635 AV
12636 *av;
12637
12638 char
12639 *attribute;
12640
12641 double
12642 x,
12643 y;
12644
12645 DrawInfo
12646 *draw_info;
12647
12648 ExceptionInfo
12649 *exception;
12650
12651 GeometryInfo
12652 geometry_info;
12653
12654 Image
12655 *image;
12656
12657 MagickBooleanType
12658 status;
12659
12660 MagickStatusType
12661 flags;
12662
12663 register ssize_t
12664 i;
12665
12666 ssize_t
12667 type;
12668
12669 struct PackageInfo
12670 *info,
12671 *package_info;
12672
12673 SV
12674 *perl_exception,
12675 *reference; /* reference is the SV* of ref=SvIV(reference) */
12676
12677 TypeMetric
12678 metrics;
12679
12680 PERL_UNUSED_VAR(ref);
12681 PERL_UNUSED_VAR(ix);
12682 exception=AcquireExceptionInfo();
12683 package_info=(struct PackageInfo *) NULL;
12684 perl_exception=newSVpv("",0);
12685 reference=SvRV(ST(0));
12686 av=(AV *) reference;
12687 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12688 exception);
12689 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12690 if (image == (Image *) NULL)
12691 {
12692 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12693 PackageName);
12694 goto PerlException;
12695 }
12696 package_info=ClonePackageInfo(info,exception);
12697 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12698 CloneString(&draw_info->text,"");
12699 current=draw_info->affine;
12700 GetAffineMatrix(&affine);
12701 x=0.0;
12702 y=0.0;
12703 EXTEND(sp,7*items);
12704 for (i=2; i < items; i+=2)
12705 {
12706 attribute=(char *) SvPV(ST(i-1),na);
12707 switch (*attribute)
12708 {
12709 case 'A':
12710 case 'a':
12711 {
12712 if (LocaleCompare(attribute,"antialias") == 0)
12713 {
12714 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12715 SvPV(ST(i),na));
12716 if (type < 0)
12717 {
12718 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12719 SvPV(ST(i),na));
12720 break;
12721 }
12722 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12723 break;
12724 }
12725 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12726 attribute);
12727 break;
12728 }
12729 case 'd':
12730 case 'D':
12731 {
12732 if (LocaleCompare(attribute,"density") == 0)
12733 {
12734 CloneString(&draw_info->density,SvPV(ST(i),na));
12735 break;
12736 }
12737 if (LocaleCompare(attribute,"direction") == 0)
12738 {
12739 draw_info->direction=(DirectionType) ParseCommandOption(
12740 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12741 break;
12742 }
12743 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12744 attribute);
12745 break;
12746 }
12747 case 'e':
12748 case 'E':
12749 {
12750 if (LocaleCompare(attribute,"encoding") == 0)
12751 {
12752 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12753 break;
12754 }
12755 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12756 attribute);
12757 break;
12758 }
12759 case 'f':
12760 case 'F':
12761 {
12762 if (LocaleCompare(attribute,"family") == 0)
12763 {
12764 CloneString(&draw_info->family,SvPV(ST(i),na));
12765 break;
12766 }
12767 if (LocaleCompare(attribute,"fill") == 0)
12768 {
12769 if (info)
12770 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12771 &draw_info->fill,exception);
12772 break;
12773 }
12774 if (LocaleCompare(attribute,"font") == 0)
12775 {
12776 CloneString(&draw_info->font,SvPV(ST(i),na));
12777 break;
12778 }
12779 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12780 attribute);
12781 break;
12782 }
12783 case 'g':
12784 case 'G':
12785 {
12786 if (LocaleCompare(attribute,"geometry") == 0)
12787 {
12788 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12789 break;
12790 }
12791 if (LocaleCompare(attribute,"gravity") == 0)
12792 {
12793 draw_info->gravity=(GravityType) ParseCommandOption(
12794 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12795 break;
12796 }
12797 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12798 attribute);
12799 break;
12800 }
12801 case 'i':
12802 case 'I':
12803 {
12804 if (LocaleCompare(attribute,"interline-spacing") == 0)
12805 {
12806 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12807 draw_info->interline_spacing=geometry_info.rho;
12808 break;
12809 }
12810 if (LocaleCompare(attribute,"interword-spacing") == 0)
12811 {
12812 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12813 draw_info->interword_spacing=geometry_info.rho;
12814 break;
12815 }
12816 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12817 attribute);
12818 break;
12819 }
12820 case 'k':
12821 case 'K':
12822 {
12823 if (LocaleCompare(attribute,"kerning") == 0)
12824 {
12825 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12826 draw_info->kerning=geometry_info.rho;
12827 break;
12828 }
12829 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12830 attribute);
12831 break;
12832 }
12833 case 'p':
12834 case 'P':
12835 {
12836 if (LocaleCompare(attribute,"pointsize") == 0)
12837 {
12838 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12839 draw_info->pointsize=geometry_info.rho;
12840 break;
12841 }
12842 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12843 attribute);
12844 break;
12845 }
12846 case 'r':
12847 case 'R':
12848 {
12849 if (LocaleCompare(attribute,"rotate") == 0)
12850 {
12851 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12852 affine.rx=geometry_info.rho;
12853 affine.ry=geometry_info.sigma;
12854 if ((flags & SigmaValue) == 0)
12855 affine.ry=affine.rx;
12856 break;
12857 }
12858 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12859 attribute);
12860 break;
12861 }
12862 case 's':
12863 case 'S':
12864 {
12865 if (LocaleCompare(attribute,"scale") == 0)
12866 {
12867 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12868 affine.sx=geometry_info.rho;
12869 affine.sy=geometry_info.sigma;
12870 if ((flags & SigmaValue) == 0)
12871 affine.sy=affine.sx;
12872 break;
12873 }
12874 if (LocaleCompare(attribute,"skew") == 0)
12875 {
12876 double
12877 x_angle,
12878 y_angle;
12879
12880 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12881 x_angle=geometry_info.rho;
12882 y_angle=geometry_info.sigma;
12883 if ((flags & SigmaValue) == 0)
12884 y_angle=x_angle;
12885 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12886 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12887 break;
12888 }
12889 if (LocaleCompare(attribute,"stroke") == 0)
12890 {
12891 if (info)
12892 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12893 &draw_info->stroke,exception);
12894 break;
12895 }
12896 if (LocaleCompare(attribute,"style") == 0)
12897 {
12898 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12899 SvPV(ST(i),na));
12900 if (type < 0)
12901 {
12902 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12903 SvPV(ST(i),na));
12904 break;
12905 }
12906 draw_info->style=(StyleType) type;
12907 break;
12908 }
12909 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12910 attribute);
12911 break;
12912 }
12913 case 't':
12914 case 'T':
12915 {
12916 if (LocaleCompare(attribute,"text") == 0)
12917 {
12918 CloneString(&draw_info->text,SvPV(ST(i),na));
12919 break;
12920 }
12921 if (LocaleCompare(attribute,"translate") == 0)
12922 {
12923 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12924 affine.tx=geometry_info.rho;
12925 affine.ty=geometry_info.sigma;
12926 if ((flags & SigmaValue) == 0)
12927 affine.ty=affine.tx;
12928 break;
12929 }
12930 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12931 attribute);
12932 break;
12933 }
12934 case 'w':
12935 case 'W':
12936 {
12937 if (LocaleCompare(attribute,"weight") == 0)
12938 {
12939 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12940 draw_info->weight=(size_t) geometry_info.rho;
12941 break;
12942 }
12943 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12944 attribute);
12945 break;
12946 }
12947 case 'x':
12948 case 'X':
12949 {
12950 if (LocaleCompare(attribute,"x") == 0)
12951 {
12952 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12953 x=geometry_info.rho;
12954 break;
12955 }
12956 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12957 attribute);
12958 break;
12959 }
12960 case 'y':
12961 case 'Y':
12962 {
12963 if (LocaleCompare(attribute,"y") == 0)
12964 {
12965 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12966 y=geometry_info.rho;
12967 break;
12968 }
12969 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12970 attribute);
12971 break;
12972 }
12973 default:
12974 {
12975 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12976 attribute);
12977 break;
12978 }
12979 }
12980 }
12981 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12982 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12983 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12984 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12985 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12986 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12987 if (draw_info->geometry == (char *) NULL)
12988 {
12989 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000012990 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000012991 "%.15g,%.15g",x,y);
12992 }
12993 status=GetTypeMetrics(image,draw_info,&metrics,exception);
12994 (void) CatchImageException(image);
12995 if (status == MagickFalse)
12996 PUSHs(&sv_undef);
12997 else
12998 {
12999 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13000 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13001 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13002 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13003 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13004 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13005 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13006 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13007 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13008 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13009 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13010 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13011 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13012 }
13013 draw_info=DestroyDrawInfo(draw_info);
13014
13015 PerlException:
13016 if (package_info != (struct PackageInfo *) NULL)
13017 DestroyPackageInfo(package_info);
13018 InheritPerlException(exception,perl_exception);
13019 exception=DestroyExceptionInfo(exception);
13020 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13021 }
13022
13023#
13024###############################################################################
13025# #
13026# #
13027# #
13028# 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 #
13029# #
13030# #
13031# #
13032###############################################################################
13033#
13034#
13035void
13036QueryMultilineFontMetrics(ref,...)
13037 Image::Magick ref=NO_INIT
13038 ALIAS:
13039 querymultilinefontmetrics = 1
13040 PPCODE:
13041 {
13042 AffineMatrix
13043 affine,
13044 current;
13045
13046 AV
13047 *av;
13048
13049 char
13050 *attribute;
13051
13052 double
13053 x,
13054 y;
13055
13056 DrawInfo
13057 *draw_info;
13058
13059 ExceptionInfo
13060 *exception;
13061
13062 GeometryInfo
13063 geometry_info;
13064
13065 Image
13066 *image;
13067
13068 MagickBooleanType
13069 status;
13070
13071 MagickStatusType
13072 flags;
13073
13074 register ssize_t
13075 i;
13076
13077 ssize_t
13078 type;
13079
13080 struct PackageInfo
13081 *info,
13082 *package_info;
13083
13084 SV
13085 *perl_exception,
13086 *reference; /* reference is the SV* of ref=SvIV(reference) */
13087
13088 TypeMetric
13089 metrics;
13090
13091 PERL_UNUSED_VAR(ref);
13092 PERL_UNUSED_VAR(ix);
13093 exception=AcquireExceptionInfo();
13094 package_info=(struct PackageInfo *) NULL;
13095 perl_exception=newSVpv("",0);
13096 reference=SvRV(ST(0));
13097 av=(AV *) reference;
13098 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13099 exception);
13100 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13101 if (image == (Image *) NULL)
13102 {
13103 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13104 PackageName);
13105 goto PerlException;
13106 }
13107 package_info=ClonePackageInfo(info,exception);
13108 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13109 CloneString(&draw_info->text,"");
13110 current=draw_info->affine;
13111 GetAffineMatrix(&affine);
13112 x=0.0;
13113 y=0.0;
13114 EXTEND(sp,7*items);
13115 for (i=2; i < items; i+=2)
13116 {
13117 attribute=(char *) SvPV(ST(i-1),na);
13118 switch (*attribute)
13119 {
13120 case 'A':
13121 case 'a':
13122 {
13123 if (LocaleCompare(attribute,"antialias") == 0)
13124 {
13125 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13126 SvPV(ST(i),na));
13127 if (type < 0)
13128 {
13129 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13130 SvPV(ST(i),na));
13131 break;
13132 }
13133 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13134 break;
13135 }
13136 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13137 attribute);
13138 break;
13139 }
13140 case 'd':
13141 case 'D':
13142 {
13143 if (LocaleCompare(attribute,"density") == 0)
13144 {
13145 CloneString(&draw_info->density,SvPV(ST(i),na));
13146 break;
13147 }
13148 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13149 attribute);
13150 break;
13151 }
13152 case 'e':
13153 case 'E':
13154 {
13155 if (LocaleCompare(attribute,"encoding") == 0)
13156 {
13157 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13158 break;
13159 }
13160 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13161 attribute);
13162 break;
13163 }
13164 case 'f':
13165 case 'F':
13166 {
13167 if (LocaleCompare(attribute,"family") == 0)
13168 {
13169 CloneString(&draw_info->family,SvPV(ST(i),na));
13170 break;
13171 }
13172 if (LocaleCompare(attribute,"fill") == 0)
13173 {
13174 if (info)
13175 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13176 &draw_info->fill,exception);
13177 break;
13178 }
13179 if (LocaleCompare(attribute,"font") == 0)
13180 {
13181 CloneString(&draw_info->font,SvPV(ST(i),na));
13182 break;
13183 }
13184 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13185 attribute);
13186 break;
13187 }
13188 case 'g':
13189 case 'G':
13190 {
13191 if (LocaleCompare(attribute,"geometry") == 0)
13192 {
13193 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13194 break;
13195 }
13196 if (LocaleCompare(attribute,"gravity") == 0)
13197 {
13198 draw_info->gravity=(GravityType) ParseCommandOption(
13199 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13200 break;
13201 }
13202 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13203 attribute);
13204 break;
13205 }
13206 case 'p':
13207 case 'P':
13208 {
13209 if (LocaleCompare(attribute,"pointsize") == 0)
13210 {
13211 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13212 draw_info->pointsize=geometry_info.rho;
13213 break;
13214 }
13215 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13216 attribute);
13217 break;
13218 }
13219 case 'r':
13220 case 'R':
13221 {
13222 if (LocaleCompare(attribute,"rotate") == 0)
13223 {
13224 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13225 affine.rx=geometry_info.rho;
13226 affine.ry=geometry_info.sigma;
13227 if ((flags & SigmaValue) == 0)
13228 affine.ry=affine.rx;
13229 break;
13230 }
13231 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13232 attribute);
13233 break;
13234 }
13235 case 's':
13236 case 'S':
13237 {
13238 if (LocaleCompare(attribute,"scale") == 0)
13239 {
13240 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13241 affine.sx=geometry_info.rho;
13242 affine.sy=geometry_info.sigma;
13243 if ((flags & SigmaValue) == 0)
13244 affine.sy=affine.sx;
13245 break;
13246 }
13247 if (LocaleCompare(attribute,"skew") == 0)
13248 {
13249 double
13250 x_angle,
13251 y_angle;
13252
13253 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13254 x_angle=geometry_info.rho;
13255 y_angle=geometry_info.sigma;
13256 if ((flags & SigmaValue) == 0)
13257 y_angle=x_angle;
13258 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13259 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13260 break;
13261 }
13262 if (LocaleCompare(attribute,"stroke") == 0)
13263 {
13264 if (info)
13265 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13266 &draw_info->stroke,exception);
13267 break;
13268 }
13269 if (LocaleCompare(attribute,"style") == 0)
13270 {
13271 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13272 SvPV(ST(i),na));
13273 if (type < 0)
13274 {
13275 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13276 SvPV(ST(i),na));
13277 break;
13278 }
13279 draw_info->style=(StyleType) type;
13280 break;
13281 }
13282 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13283 attribute);
13284 break;
13285 }
13286 case 't':
13287 case 'T':
13288 {
13289 if (LocaleCompare(attribute,"text") == 0)
13290 {
13291 CloneString(&draw_info->text,SvPV(ST(i),na));
13292 break;
13293 }
13294 if (LocaleCompare(attribute,"translate") == 0)
13295 {
13296 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13297 affine.tx=geometry_info.rho;
13298 affine.ty=geometry_info.sigma;
13299 if ((flags & SigmaValue) == 0)
13300 affine.ty=affine.tx;
13301 break;
13302 }
13303 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13304 attribute);
13305 break;
13306 }
13307 case 'w':
13308 case 'W':
13309 {
13310 if (LocaleCompare(attribute,"weight") == 0)
13311 {
13312 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13313 draw_info->weight=(size_t) geometry_info.rho;
13314 break;
13315 }
13316 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13317 attribute);
13318 break;
13319 }
13320 case 'x':
13321 case 'X':
13322 {
13323 if (LocaleCompare(attribute,"x") == 0)
13324 {
13325 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13326 x=geometry_info.rho;
13327 break;
13328 }
13329 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13330 attribute);
13331 break;
13332 }
13333 case 'y':
13334 case 'Y':
13335 {
13336 if (LocaleCompare(attribute,"y") == 0)
13337 {
13338 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13339 y=geometry_info.rho;
13340 break;
13341 }
13342 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13343 attribute);
13344 break;
13345 }
13346 default:
13347 {
13348 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13349 attribute);
13350 break;
13351 }
13352 }
13353 }
13354 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13355 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13356 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13357 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13358 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13359 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13360 if (draw_info->geometry == (char *) NULL)
13361 {
13362 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013363 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013364 "%.15g,%.15g",x,y);
13365 }
13366 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13367 (void) CatchException(exception);
13368 if (status == MagickFalse)
13369 PUSHs(&sv_undef);
13370 else
13371 {
13372 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13373 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13374 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13375 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13376 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13377 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13378 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13379 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13380 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13381 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13382 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13383 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13384 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13385 }
13386 draw_info=DestroyDrawInfo(draw_info);
13387
13388 PerlException:
13389 if (package_info != (struct PackageInfo *) NULL)
13390 DestroyPackageInfo(package_info);
13391 InheritPerlException(exception,perl_exception);
13392 exception=DestroyExceptionInfo(exception);
13393 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13394 }
13395
13396#
13397###############################################################################
13398# #
13399# #
13400# #
13401# Q u e r y F o r m a t #
13402# #
13403# #
13404# #
13405###############################################################################
13406#
13407#
13408void
13409QueryFormat(ref,...)
13410 Image::Magick ref=NO_INIT
13411 ALIAS:
13412 queryformat = 1
13413 PPCODE:
13414 {
13415 char
13416 *name;
13417
13418 ExceptionInfo
13419 *exception;
13420
13421 register ssize_t
13422 i;
13423
13424 SV
13425 *perl_exception;
13426
13427 volatile const MagickInfo
13428 *magick_info;
13429
13430 PERL_UNUSED_VAR(ref);
13431 PERL_UNUSED_VAR(ix);
13432 exception=AcquireExceptionInfo();
13433 perl_exception=newSVpv("",0);
13434 if (items == 1)
13435 {
13436 char
cristy151b66d2015-04-15 10:50:31 +000013437 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013438
13439 const MagickInfo
13440 **format_list;
13441
13442 size_t
13443 types;
13444
13445 format_list=GetMagickInfoList("*",&types,exception);
13446 EXTEND(sp,types);
13447 for (i=0; i < (ssize_t) types; i++)
13448 {
cristy151b66d2015-04-15 10:50:31 +000013449 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013450 LocaleLower(format);
13451 PUSHs(sv_2mortal(newSVpv(format,0)));
13452 }
13453 format_list=(const MagickInfo **)
13454 RelinquishMagickMemory((MagickInfo *) format_list);
13455 goto PerlException;
13456 }
13457 EXTEND(sp,8*items);
13458 for (i=1; i < items; i++)
13459 {
13460 name=(char *) SvPV(ST(i),na);
13461 magick_info=GetMagickInfo(name,exception);
13462 if (magick_info == (const MagickInfo *) NULL)
13463 {
13464 PUSHs(&sv_undef);
13465 continue;
13466 }
cristy4a3ce0a2013-08-03 20:06:59 +000013467 if (magick_info->description == (char *) NULL)
13468 PUSHs(&sv_undef);
13469 else
13470 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13471 if (magick_info->module == (char *) NULL)
13472 PUSHs(&sv_undef);
13473 else
13474 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13475 }
13476
13477 PerlException:
13478 InheritPerlException(exception,perl_exception);
13479 exception=DestroyExceptionInfo(exception);
13480 SvREFCNT_dec(perl_exception);
13481 }
13482
13483#
13484###############################################################################
13485# #
13486# #
13487# #
13488# Q u e r y O p t i o n #
13489# #
13490# #
13491# #
13492###############################################################################
13493#
13494#
13495void
13496QueryOption(ref,...)
13497 Image::Magick ref=NO_INIT
13498 ALIAS:
13499 queryoption = 1
13500 PPCODE:
13501 {
13502 char
13503 **options;
13504
13505 ExceptionInfo
13506 *exception;
13507
13508 register ssize_t
13509 i;
13510
13511 ssize_t
13512 j,
13513 option;
13514
13515 SV
13516 *perl_exception;
13517
13518 PERL_UNUSED_VAR(ref);
13519 PERL_UNUSED_VAR(ix);
13520 exception=AcquireExceptionInfo();
13521 perl_exception=newSVpv("",0);
13522 EXTEND(sp,8*items);
13523 for (i=1; i < items; i++)
13524 {
13525 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13526 SvPV(ST(i),na));
13527 options=GetCommandOptions((CommandOption) option);
13528 if (options == (char **) NULL)
13529 PUSHs(&sv_undef);
13530 else
13531 {
13532 for (j=0; options[j] != (char *) NULL; j++)
13533 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13534 options=DestroyStringList(options);
13535 }
13536 }
13537
13538 InheritPerlException(exception,perl_exception);
13539 exception=DestroyExceptionInfo(exception);
13540 SvREFCNT_dec(perl_exception);
13541 }
13542
13543#
13544###############################################################################
13545# #
13546# #
13547# #
13548# R e a d #
13549# #
13550# #
13551# #
13552###############################################################################
13553#
13554#
13555void
13556Read(ref,...)
13557 Image::Magick ref=NO_INIT
13558 ALIAS:
13559 ReadImage = 1
13560 read = 2
13561 readimage = 3
13562 PPCODE:
13563 {
13564 AV
13565 *av;
13566
13567 char
13568 **keep,
13569 **list;
13570
13571 ExceptionInfo
13572 *exception;
13573
13574 HV
13575 *hv;
13576
13577 Image
13578 *image;
13579
13580 int
13581 n;
13582
13583 MagickBooleanType
13584 status;
13585
13586 register char
13587 **p;
13588
13589 register ssize_t
13590 i;
13591
13592 ssize_t
13593 ac,
13594 number_images;
13595
13596 STRLEN
13597 *length;
13598
13599 struct PackageInfo
13600 *info,
13601 *package_info;
13602
13603 SV
13604 *perl_exception, /* Perl variable for storing messages */
13605 *reference,
13606 *rv,
13607 *sv;
13608
13609 PERL_UNUSED_VAR(ref);
13610 PERL_UNUSED_VAR(ix);
13611 exception=AcquireExceptionInfo();
13612 perl_exception=newSVpv("",0);
13613 sv=NULL;
13614 package_info=(struct PackageInfo *) NULL;
13615 number_images=0;
13616 ac=(items < 2) ? 1 : items-1;
13617 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13618 keep=list;
13619 length=(STRLEN *) NULL;
13620 if (list == (char **) NULL)
13621 {
13622 ThrowPerlException(exception,ResourceLimitError,
13623 "MemoryAllocationFailed",PackageName);
13624 goto PerlException;
13625 }
13626 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13627 if (length == (STRLEN *) NULL)
13628 {
13629 ThrowPerlException(exception,ResourceLimitError,
13630 "MemoryAllocationFailed",PackageName);
13631 goto PerlException;
13632 }
13633 if (sv_isobject(ST(0)) == 0)
13634 {
13635 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13636 PackageName);
13637 goto PerlException;
13638 }
13639 reference=SvRV(ST(0));
13640 hv=SvSTASH(reference);
13641 if (SvTYPE(reference) != SVt_PVAV)
13642 {
13643 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13644 PackageName);
13645 goto PerlException;
13646 }
13647 av=(AV *) reference;
13648 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13649 exception);
13650 package_info=ClonePackageInfo(info,exception);
13651 n=1;
13652 if (items <= 1)
13653 *list=(char *) (*package_info->image_info->filename ?
13654 package_info->image_info->filename : "XC:black");
13655 else
13656 for (n=0, i=0; i < ac; i++)
13657 {
13658 list[n]=(char *) SvPV(ST(i+1),length[n]);
13659 if ((items >= 3) && strEQcase(list[n],"blob"))
13660 {
13661 void
13662 *blob;
13663
13664 i++;
13665 blob=(void *) (SvPV(ST(i+1),length[n]));
13666 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13667 }
13668 if ((items >= 3) && strEQcase(list[n],"filename"))
13669 continue;
13670 if ((items >= 3) && strEQcase(list[n],"file"))
13671 {
13672 FILE
13673 *file;
13674
13675 PerlIO
13676 *io_info;
13677
13678 i++;
13679 io_info=IoIFP(sv_2io(ST(i+1)));
13680 if (io_info == (PerlIO *) NULL)
13681 {
13682 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13683 PackageName);
13684 continue;
13685 }
13686 file=PerlIO_findFILE(io_info);
13687 if (file == (FILE *) NULL)
13688 {
13689 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13690 PackageName);
13691 continue;
13692 }
13693 SetImageInfoFile(package_info->image_info,file);
13694 }
13695 if ((items >= 3) && strEQcase(list[n],"magick"))
13696 continue;
13697 n++;
13698 }
13699 list[n]=(char *) NULL;
13700 keep=list;
13701 status=ExpandFilenames(&n,&list);
13702 if (status == MagickFalse)
13703 {
13704 ThrowPerlException(exception,ResourceLimitError,
13705 "MemoryAllocationFailed",PackageName);
13706 goto PerlException;
13707 }
13708 number_images=0;
13709 for (i=0; i < n; i++)
13710 {
13711 if ((package_info->image_info->file == (FILE *) NULL) &&
13712 (package_info->image_info->blob == (void *) NULL))
13713 image=ReadImages(package_info->image_info,list[i],exception);
13714 else
13715 {
13716 image=ReadImages(package_info->image_info,
13717 package_info->image_info->filename,exception);
13718 if (image != (Image *) NULL)
13719 DisassociateImageStream(image);
13720 }
13721 if (image == (Image *) NULL)
13722 break;
13723 for ( ; image; image=image->next)
13724 {
13725 AddImageToRegistry(sv,image);
13726 rv=newRV(sv);
13727 av_push(av,sv_bless(rv,hv));
13728 SvREFCNT_dec(sv);
13729 number_images++;
13730 }
13731 }
13732 /*
13733 Free resources.
13734 */
13735 for (i=0; i < n; i++)
13736 if (list[i] != (char *) NULL)
13737 for (p=keep; list[i] != *p++; )
13738 if (*p == (char *) NULL)
13739 {
13740 list[i]=(char *) RelinquishMagickMemory(list[i]);
13741 break;
13742 }
13743
13744 PerlException:
13745 if (package_info != (struct PackageInfo *) NULL)
13746 DestroyPackageInfo(package_info);
13747 if (list && (list != keep))
13748 list=(char **) RelinquishMagickMemory(list);
13749 if (keep)
13750 keep=(char **) RelinquishMagickMemory(keep);
13751 if (length)
13752 length=(STRLEN *) RelinquishMagickMemory(length);
13753 InheritPerlException(exception,perl_exception);
13754 exception=DestroyExceptionInfo(exception);
13755 sv_setiv(perl_exception,(IV) number_images);
13756 SvPOK_on(perl_exception);
13757 ST(0)=sv_2mortal(perl_exception);
13758 XSRETURN(1);
13759 }
13760
13761#
13762###############################################################################
13763# #
13764# #
13765# #
13766# R e m o t e #
13767# #
13768# #
13769# #
13770###############################################################################
13771#
13772#
13773void
13774Remote(ref,...)
13775 Image::Magick ref=NO_INIT
13776 ALIAS:
13777 RemoteCommand = 1
13778 remote = 2
13779 remoteCommand = 3
13780 PPCODE:
13781 {
13782 AV
13783 *av;
13784
13785 ExceptionInfo
13786 *exception;
13787
13788 register ssize_t
13789 i;
13790
13791 SV
13792 *perl_exception,
13793 *reference;
13794
13795 struct PackageInfo
13796 *info;
13797
13798 PERL_UNUSED_VAR(ref);
13799 PERL_UNUSED_VAR(ix);
13800 exception=AcquireExceptionInfo();
13801 perl_exception=newSVpv("",0);
13802 reference=SvRV(ST(0));
13803 av=(AV *) reference;
13804 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13805 exception);
13806 for (i=1; i < items; i++)
13807 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13808 SvPV(ST(i),na),exception);
13809 InheritPerlException(exception,perl_exception);
13810 exception=DestroyExceptionInfo(exception);
13811 SvREFCNT_dec(perl_exception); /* throw away all errors */
13812 }
13813
13814#
13815###############################################################################
13816# #
13817# #
13818# #
13819# S e t #
13820# #
13821# #
13822# #
13823###############################################################################
13824#
13825#
13826void
13827Set(ref,...)
13828 Image::Magick ref=NO_INIT
13829 ALIAS:
13830 SetAttributes = 1
13831 SetAttribute = 2
13832 set = 3
13833 setattributes = 4
13834 setattribute = 5
13835 PPCODE:
13836 {
13837 ExceptionInfo
13838 *exception;
13839
13840 Image
13841 *image;
13842
13843 register ssize_t
13844 i;
13845
13846 struct PackageInfo
13847 *info;
13848
13849 SV
13850 *perl_exception,
13851 *reference; /* reference is the SV* of ref=SvIV(reference) */
13852
13853 PERL_UNUSED_VAR(ref);
13854 PERL_UNUSED_VAR(ix);
13855 exception=AcquireExceptionInfo();
13856 perl_exception=newSVpv("",0);
13857 if (sv_isobject(ST(0)) == 0)
13858 {
13859 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13860 PackageName);
13861 goto PerlException;
13862 }
13863 reference=SvRV(ST(0));
13864 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13865 if (items == 2)
13866 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13867 else
13868 for (i=2; i < items; i+=2)
13869 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13870
13871 PerlException:
13872 InheritPerlException(exception,perl_exception);
13873 exception=DestroyExceptionInfo(exception);
13874 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13875 SvPOK_on(perl_exception);
13876 ST(0)=sv_2mortal(perl_exception);
13877 XSRETURN(1);
13878 }
13879
13880#
13881###############################################################################
13882# #
13883# #
13884# #
13885# S e t P i x e l #
13886# #
13887# #
13888# #
13889###############################################################################
13890#
13891#
13892void
13893SetPixel(ref,...)
13894 Image::Magick ref=NO_INIT
13895 ALIAS:
13896 setpixel = 1
13897 setPixel = 2
13898 PPCODE:
13899 {
13900 AV
13901 *av;
13902
13903 char
13904 *attribute;
13905
13906 ChannelType
13907 channel,
13908 channel_mask;
13909
13910 ExceptionInfo
13911 *exception;
13912
13913 Image
13914 *image;
13915
13916 MagickBooleanType
13917 normalize;
13918
13919 RectangleInfo
13920 region;
13921
13922 register ssize_t
13923 i;
13924
13925 register Quantum
13926 *q;
13927
13928 ssize_t
13929 option;
13930
13931 struct PackageInfo
13932 *info;
13933
13934 SV
13935 *perl_exception,
13936 *reference; /* reference is the SV* of ref=SvIV(reference) */
13937
13938 PERL_UNUSED_VAR(ref);
13939 PERL_UNUSED_VAR(ix);
13940 exception=AcquireExceptionInfo();
13941 perl_exception=newSVpv("",0);
13942 reference=SvRV(ST(0));
13943 av=(AV *) reference;
13944 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13945 exception);
13946 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13947 if (image == (Image *) NULL)
13948 {
13949 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13950 PackageName);
13951 goto PerlException;
13952 }
13953 av=(AV *) NULL;
13954 normalize=MagickTrue;
13955 region.x=0;
13956 region.y=0;
13957 region.width=image->columns;
13958 region.height=1;
13959 if (items == 1)
13960 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
13961 channel=DefaultChannels;
13962 for (i=2; i < items; i+=2)
13963 {
13964 attribute=(char *) SvPV(ST(i-1),na);
13965 switch (*attribute)
13966 {
13967 case 'C':
13968 case 'c':
13969 {
13970 if (LocaleCompare(attribute,"channel") == 0)
13971 {
13972 ssize_t
13973 option;
13974
13975 option=ParseChannelOption(SvPV(ST(i),na));
13976 if (option < 0)
13977 {
13978 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13979 SvPV(ST(i),na));
13980 return;
13981 }
13982 channel=(ChannelType) option;
13983 break;
13984 }
13985 if (LocaleCompare(attribute,"color") == 0)
13986 {
13987 if (SvTYPE(ST(i)) != SVt_RV)
13988 {
13989 char
cristy151b66d2015-04-15 10:50:31 +000013990 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013991
cristy151b66d2015-04-15 10:50:31 +000013992 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013993 "invalid %.60s value",attribute);
13994 ThrowPerlException(exception,OptionError,message,
13995 SvPV(ST(i),na));
13996 }
13997 av=(AV *) SvRV(ST(i));
13998 break;
13999 }
14000 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14001 attribute);
14002 break;
14003 }
14004 case 'g':
14005 case 'G':
14006 {
14007 if (LocaleCompare(attribute,"geometry") == 0)
14008 {
14009 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14010 break;
14011 }
14012 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14013 attribute);
14014 break;
14015 }
14016 case 'N':
14017 case 'n':
14018 {
14019 if (LocaleCompare(attribute,"normalize") == 0)
14020 {
14021 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14022 SvPV(ST(i),na));
14023 if (option < 0)
14024 {
14025 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14026 SvPV(ST(i),na));
14027 break;
14028 }
14029 normalize=option != 0 ? MagickTrue : MagickFalse;
14030 break;
14031 }
14032 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14033 attribute);
14034 break;
14035 }
14036 case 'x':
14037 case 'X':
14038 {
14039 if (LocaleCompare(attribute,"x") == 0)
14040 {
14041 region.x=SvIV(ST(i));
14042 break;
14043 }
14044 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14045 attribute);
14046 break;
14047 }
14048 case 'y':
14049 case 'Y':
14050 {
14051 if (LocaleCompare(attribute,"y") == 0)
14052 {
14053 region.y=SvIV(ST(i));
14054 break;
14055 }
14056 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14057 attribute);
14058 break;
14059 }
14060 default:
14061 {
14062 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14063 attribute);
14064 break;
14065 }
14066 }
14067 }
14068 (void) SetImageStorageClass(image,DirectClass,exception);
14069 channel_mask=SetImageChannelMask(image,channel);
14070 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14071 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14072 (SvTYPE(av) != SVt_PVAV))
14073 PUSHs(&sv_undef);
14074 else
14075 {
14076 double
14077 scale;
14078
14079 register ssize_t
14080 i;
14081
14082 i=0;
14083 scale=1.0;
14084 if (normalize != MagickFalse)
14085 scale=QuantumRange;
14086 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14087 (i <= av_len(av)))
14088 {
14089 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14090 av_fetch(av,i,0)))),q);
14091 i++;
14092 }
14093 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14094 (i <= av_len(av)))
14095 {
14096 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14097 av_fetch(av,i,0)))),q);
14098 i++;
14099 }
14100 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14101 (i <= av_len(av)))
14102 {
14103 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14104 av_fetch(av,i,0)))),q);
14105 i++;
14106 }
14107 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14108 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14109 {
14110 SetPixelBlack(image,ClampToQuantum(scale*
14111 SvNV(*(av_fetch(av,i,0)))),q);
14112 i++;
14113 }
14114 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14115 (i <= av_len(av)))
14116 {
14117 SetPixelAlpha(image,ClampToQuantum(scale*
14118 SvNV(*(av_fetch(av,i,0)))),q);
14119 i++;
14120 }
14121 (void) SyncAuthenticPixels(image,exception);
14122 }
14123 (void) SetImageChannelMask(image,channel_mask);
14124
14125 PerlException:
14126 InheritPerlException(exception,perl_exception);
14127 exception=DestroyExceptionInfo(exception);
14128 SvREFCNT_dec(perl_exception);
14129 }
14130
14131#
14132###############################################################################
14133# #
14134# #
14135# #
14136# S m u s h #
14137# #
14138# #
14139# #
14140###############################################################################
14141#
14142#
14143void
14144Smush(ref,...)
14145 Image::Magick ref=NO_INIT
14146 ALIAS:
14147 SmushImage = 1
14148 smush = 2
14149 smushimage = 3
14150 PPCODE:
14151 {
14152 AV
14153 *av;
14154
14155 char
14156 *attribute;
14157
14158 ExceptionInfo
14159 *exception;
14160
14161 HV
14162 *hv;
14163
14164 Image
14165 *image;
14166
14167 register ssize_t
14168 i;
14169
14170 ssize_t
14171 offset,
14172 stack;
14173
14174 struct PackageInfo
14175 *info;
14176
14177 SV
14178 *av_reference,
14179 *perl_exception,
14180 *reference,
14181 *rv,
14182 *sv;
14183
14184 PERL_UNUSED_VAR(ref);
14185 PERL_UNUSED_VAR(ix);
14186 exception=AcquireExceptionInfo();
14187 perl_exception=newSVpv("",0);
14188 sv=NULL;
14189 attribute=NULL;
14190 av=NULL;
14191 if (sv_isobject(ST(0)) == 0)
14192 {
14193 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14194 PackageName);
14195 goto PerlException;
14196 }
14197 reference=SvRV(ST(0));
14198 hv=SvSTASH(reference);
14199 av=newAV();
14200 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14201 SvREFCNT_dec(av);
14202 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14203 if (image == (Image *) NULL)
14204 {
14205 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14206 PackageName);
14207 goto PerlException;
14208 }
14209 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14210 /*
14211 Get options.
14212 */
14213 offset=0;
14214 stack=MagickTrue;
14215 for (i=2; i < items; i+=2)
14216 {
14217 attribute=(char *) SvPV(ST(i-1),na);
14218 switch (*attribute)
14219 {
14220 case 'O':
14221 case 'o':
14222 {
14223 if (LocaleCompare(attribute,"offset") == 0)
14224 {
14225 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14226 break;
14227 }
14228 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14229 attribute);
14230 break;
14231 }
14232 case 'S':
14233 case 's':
14234 {
14235 if (LocaleCompare(attribute,"stack") == 0)
14236 {
14237 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14238 SvPV(ST(i),na));
14239 if (stack < 0)
14240 {
14241 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14242 SvPV(ST(i),na));
14243 return;
14244 }
14245 break;
14246 }
14247 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14248 attribute);
14249 break;
14250 }
14251 default:
14252 {
14253 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14254 attribute);
14255 break;
14256 }
14257 }
14258 }
14259 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14260 exception);
14261 if (image == (Image *) NULL)
14262 goto PerlException;
14263 for ( ; image; image=image->next)
14264 {
14265 AddImageToRegistry(sv,image);
14266 rv=newRV(sv);
14267 av_push(av,sv_bless(rv,hv));
14268 SvREFCNT_dec(sv);
14269 }
14270 exception=DestroyExceptionInfo(exception);
14271 ST(0)=av_reference;
14272 SvREFCNT_dec(perl_exception);
14273 XSRETURN(1);
14274
14275 PerlException:
14276 InheritPerlException(exception,perl_exception);
14277 exception=DestroyExceptionInfo(exception);
14278 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14279 SvPOK_on(perl_exception);
14280 ST(0)=sv_2mortal(perl_exception);
14281 XSRETURN(1);
14282 }
14283
14284#
14285###############################################################################
14286# #
14287# #
14288# #
14289# S t a t i s t i c s #
14290# #
14291# #
14292# #
14293###############################################################################
14294#
14295#
14296void
14297Statistics(ref,...)
14298 Image::Magick ref=NO_INIT
14299 ALIAS:
14300 StatisticsImage = 1
14301 statistics = 2
14302 statisticsimage = 3
14303 PPCODE:
14304 {
14305#define ChannelStatistics(channel) \
14306{ \
cristy151b66d2015-04-15 10:50:31 +000014307 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014308 (double) channel_statistics[channel].depth); \
14309 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014310 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014311 channel_statistics[channel].minima/scale); \
14312 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014313 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014314 channel_statistics[channel].maxima/scale); \
14315 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014316 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014317 channel_statistics[channel].mean/scale); \
14318 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014319 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014320 channel_statistics[channel].standard_deviation/scale); \
14321 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014322 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014323 channel_statistics[channel].kurtosis); \
14324 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014325 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014326 channel_statistics[channel].skewness); \
14327 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014328 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy275bdd92014-11-08 23:45:03 +000014329 channel_statistics[channel].entropy); \
14330 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014331}
14332
14333 AV
14334 *av;
14335
14336 char
cristy151b66d2015-04-15 10:50:31 +000014337 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014338
14339 ChannelStatistics
14340 *channel_statistics;
14341
14342 double
14343 scale;
14344
14345 ExceptionInfo
14346 *exception;
14347
14348 Image
14349 *image;
14350
14351 ssize_t
14352 count;
14353
14354 struct PackageInfo
14355 *info;
14356
14357 SV
14358 *perl_exception,
14359 *reference;
14360
14361 PERL_UNUSED_VAR(ref);
14362 PERL_UNUSED_VAR(ix);
14363 exception=AcquireExceptionInfo();
14364 perl_exception=newSVpv("",0);
14365 av=NULL;
14366 if (sv_isobject(ST(0)) == 0)
14367 {
14368 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14369 PackageName);
14370 goto PerlException;
14371 }
14372 reference=SvRV(ST(0));
14373 av=newAV();
14374 SvREFCNT_dec(av);
14375 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14376 if (image == (Image *) NULL)
14377 {
14378 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14379 PackageName);
14380 goto PerlException;
14381 }
cristy4a3ce0a2013-08-03 20:06:59 +000014382 count=0;
14383 for ( ; image; image=image->next)
14384 {
14385 channel_statistics=GetImageStatistics(image,exception);
14386 if (channel_statistics == (ChannelStatistics *) NULL)
14387 continue;
14388 count++;
14389 EXTEND(sp,35*count);
14390 scale=(double) QuantumRange;
14391 ChannelStatistics(RedChannel);
14392 ChannelStatistics(GreenChannel);
14393 ChannelStatistics(BlueChannel);
14394 if (image->colorspace == CMYKColorspace)
14395 ChannelStatistics(BlackChannel);
cristy17f11b02014-12-20 19:37:04 +000014396 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000014397 ChannelStatistics(AlphaChannel);
14398 channel_statistics=(ChannelStatistics *)
14399 RelinquishMagickMemory(channel_statistics);
14400 }
14401
14402 PerlException:
14403 InheritPerlException(exception,perl_exception);
14404 exception=DestroyExceptionInfo(exception);
14405 SvREFCNT_dec(perl_exception);
14406 }
14407
14408#
14409###############################################################################
14410# #
14411# #
14412# #
14413# S y n c A u t h e n t i c P i x e l s #
14414# #
14415# #
14416# #
14417###############################################################################
14418#
14419#
14420void
14421SyncAuthenticPixels(ref,...)
14422 Image::Magick ref = NO_INIT
14423 ALIAS:
14424 Syncauthenticpixels = 1
14425 SyncImagePixels = 2
14426 syncimagepixels = 3
14427 CODE:
14428 {
14429 ExceptionInfo
14430 *exception;
14431
14432 Image
14433 *image;
14434
14435 MagickBooleanType
14436 status;
14437
14438 struct PackageInfo
14439 *info;
14440
14441 SV
14442 *perl_exception,
14443 *reference;
14444
14445 PERL_UNUSED_VAR(ref);
14446 PERL_UNUSED_VAR(ix);
14447 exception=AcquireExceptionInfo();
14448 perl_exception=newSVpv("",0);
14449 if (sv_isobject(ST(0)) == 0)
14450 {
14451 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14452 PackageName);
14453 goto PerlException;
14454 }
14455
14456 reference=SvRV(ST(0));
14457 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14458 if (image == (Image *) NULL)
14459 {
14460 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14461 PackageName);
14462 goto PerlException;
14463 }
14464
14465 status=SyncAuthenticPixels(image,exception);
14466 if (status != MagickFalse)
14467 return;
14468
14469 PerlException:
14470 InheritPerlException(exception,perl_exception);
14471 exception=DestroyExceptionInfo(exception);
14472 SvREFCNT_dec(perl_exception); /* throw away all errors */
14473 }
14474
14475#
14476###############################################################################
14477# #
14478# #
14479# #
14480# T r a n s f o r m #
14481# #
14482# #
14483# #
14484###############################################################################
14485#
14486#
14487void
14488Transform(ref,...)
14489 Image::Magick ref=NO_INIT
14490 ALIAS:
14491 TransformImage = 1
14492 transform = 2
14493 transformimage = 3
14494 PPCODE:
14495 {
14496 AV
14497 *av;
14498
14499 char
14500 *attribute,
14501 *crop_geometry,
14502 *geometry;
14503
14504 ExceptionInfo
14505 *exception;
14506
14507 HV
14508 *hv;
14509
14510 Image
14511 *clone,
14512 *image;
14513
14514 register ssize_t
14515 i;
14516
14517 struct PackageInfo
14518 *info;
14519
14520 SV
14521 *av_reference,
14522 *perl_exception,
14523 *reference,
14524 *rv,
14525 *sv;
14526
14527 PERL_UNUSED_VAR(ref);
14528 PERL_UNUSED_VAR(ix);
14529 exception=AcquireExceptionInfo();
14530 perl_exception=newSVpv("",0);
14531 sv=NULL;
14532 av=NULL;
14533 attribute=NULL;
14534 if (sv_isobject(ST(0)) == 0)
14535 {
14536 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14537 PackageName);
14538 goto PerlException;
14539 }
14540 reference=SvRV(ST(0));
14541 hv=SvSTASH(reference);
14542 av=newAV();
14543 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14544 SvREFCNT_dec(av);
14545 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14546 if (image == (Image *) NULL)
14547 {
14548 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14549 PackageName);
14550 goto PerlException;
14551 }
14552 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14553 /*
14554 Get attribute.
14555 */
14556 crop_geometry=(char *) NULL;
14557 geometry=(char *) NULL;
14558 for (i=2; i < items; i+=2)
14559 {
14560 attribute=(char *) SvPV(ST(i-1),na);
14561 switch (*attribute)
14562 {
14563 case 'c':
14564 case 'C':
14565 {
14566 if (LocaleCompare(attribute,"crop") == 0)
14567 {
14568 crop_geometry=SvPV(ST(i),na);
14569 break;
14570 }
14571 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14572 attribute);
14573 break;
14574 }
14575 case 'g':
14576 case 'G':
14577 {
14578 if (LocaleCompare(attribute,"geometry") == 0)
14579 {
14580 geometry=SvPV(ST(i),na);
14581 break;
14582 }
14583 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14584 attribute);
14585 break;
14586 }
14587 default:
14588 {
14589 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14590 attribute);
14591 break;
14592 }
14593 }
14594 }
14595 for ( ; image; image=image->next)
14596 {
14597 clone=CloneImage(image,0,0,MagickTrue,exception);
14598 if (clone == (Image *) NULL)
14599 goto PerlException;
14600 TransformImage(&clone,crop_geometry,geometry,exception);
14601 for ( ; clone; clone=clone->next)
14602 {
14603 AddImageToRegistry(sv,clone);
14604 rv=newRV(sv);
14605 av_push(av,sv_bless(rv,hv));
14606 SvREFCNT_dec(sv);
14607 }
14608 }
14609 exception=DestroyExceptionInfo(exception);
14610 ST(0)=av_reference;
14611 SvREFCNT_dec(perl_exception); /* can't return warning messages */
14612 XSRETURN(1);
14613
14614 PerlException:
14615 InheritPerlException(exception,perl_exception);
14616 exception=DestroyExceptionInfo(exception);
14617 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14618 SvPOK_on(perl_exception);
14619 ST(0)=sv_2mortal(perl_exception);
14620 XSRETURN(1);
14621 }
14622
14623#
14624###############################################################################
14625# #
14626# #
14627# #
14628# W r i t e #
14629# #
14630# #
14631# #
14632###############################################################################
14633#
14634#
14635void
14636Write(ref,...)
14637 Image::Magick ref=NO_INIT
14638 ALIAS:
14639 WriteImage = 1
14640 write = 2
14641 writeimage = 3
14642 PPCODE:
14643 {
14644 char
cristy151b66d2015-04-15 10:50:31 +000014645 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014646
14647 ExceptionInfo
14648 *exception;
14649
14650 Image
14651 *image,
14652 *next;
14653
14654 register ssize_t
14655 i;
14656
14657 ssize_t
14658 number_images,
14659 scene;
14660
14661 struct PackageInfo
14662 *info,
14663 *package_info;
14664
14665 SV
14666 *perl_exception,
14667 *reference;
14668
14669 PERL_UNUSED_VAR(ref);
14670 PERL_UNUSED_VAR(ix);
14671 exception=AcquireExceptionInfo();
14672 perl_exception=newSVpv("",0);
14673 number_images=0;
14674 package_info=(struct PackageInfo *) NULL;
14675 if (sv_isobject(ST(0)) == 0)
14676 {
14677 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14678 PackageName);
14679 goto PerlException;
14680 }
14681 reference=SvRV(ST(0));
14682 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14683 if (image == (Image *) NULL)
14684 {
14685 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14686 PackageName);
14687 goto PerlException;
14688 }
14689 package_info=ClonePackageInfo(info,exception);
14690 if (items == 2)
14691 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14692 else
14693 if (items > 2)
14694 for (i=2; i < items; i+=2)
14695 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14696 exception);
14697 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014698 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014699 scene=0;
14700 for (next=image; next; next=next->next)
14701 {
cristy151b66d2015-04-15 10:50:31 +000014702 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014703 next->scene=scene++;
14704 }
cristy68bd79a2015-02-25 12:23:36 +000014705 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014706 SetImageInfo(package_info->image_info,(unsigned int)
14707 GetImageListLength(image),exception);
14708 for (next=image; next; next=next->next)
14709 {
14710 (void) WriteImage(package_info->image_info,next,exception);
14711 number_images++;
14712 if (package_info->image_info->adjoin)
14713 break;
14714 }
14715
14716 PerlException:
14717 if (package_info != (struct PackageInfo *) NULL)
14718 DestroyPackageInfo(package_info);
14719 InheritPerlException(exception,perl_exception);
14720 exception=DestroyExceptionInfo(exception);
14721 sv_setiv(perl_exception,(IV) number_images);
14722 SvPOK_on(perl_exception);
14723 ST(0)=sv_2mortal(perl_exception);
14724 XSRETURN(1);
14725 }