blob: a27be55b1127a1e5cd2f92358848fb59c58ca4c0 [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},
dirk2045cf92015-08-29 00:02:54 +0200264 {"interpolate", MagickInterpolateOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000265 { "Swirl", { {"degrees", RealReference},
266 {"interpolate", MagickInterpolateOptions} } },
267 { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
268 {"height", IntegerReference}, {"filter", MagickFilterOptions},
269 {"support", StringReference } } },
270 { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
271 {"height", IntegerReference}, {"filter", MagickFilterOptions},
272 {"support", RealReference } } },
273 { "Annotate", { {"text", StringReference}, {"font", StringReference},
274 {"pointsize", RealReference}, {"density", StringReference},
275 {"undercolor", StringReference}, {"stroke", StringReference},
276 {"fill", StringReference}, {"geometry", StringReference},
277 {"sans", StringReference}, {"x", RealReference},
278 {"y", RealReference}, {"gravity", MagickGravityOptions},
279 {"translate", StringReference}, {"scale", StringReference},
280 {"rotate", RealReference}, {"skewX", RealReference},
281 {"skewY", RealReference}, {"strokewidth", RealReference},
282 {"antialias", MagickBooleanOptions}, {"family", StringReference},
283 {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
284 {"weight", IntegerReference}, {"align", MagickAlignOptions},
285 {"encoding", StringReference}, {"affine", ArrayReference},
286 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
287 {"tile", ImageReference}, {"kerning", RealReference},
288 {"interline-spacing", RealReference},
289 {"interword-spacing", RealReference},
290 {"direction", MagickDirectionOptions} } },
291 { "ColorFloodfill", { {"geometry", StringReference},
292 {"x", IntegerReference}, {"y", IntegerReference},
293 {"fill", StringReference}, {"bordercolor", StringReference},
294 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
295 { "Composite", { {"image", ImageReference},
296 {"compose", MagickComposeOptions}, {"geometry", StringReference},
297 {"x", IntegerReference}, {"y", IntegerReference},
298 {"gravity", MagickGravityOptions}, {"opacity", StringReference},
299 {"tile", MagickBooleanOptions}, {"rotate", RealReference},
300 {"color", StringReference}, {"mask", ImageReference},
301 {"channel", MagickChannelOptions},
302 {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
303 {"blend", StringReference}, {"crop-to-self", MagickBooleanOptions} } },
304 { "Contrast", { {"sharpen", MagickBooleanOptions} } },
305 { "CycleColormap", { {"display", IntegerReference} } },
306 { "Draw", { {"primitive", MagickPrimitiveOptions},
307 {"points", StringReference}, {"method", MagickMethodOptions},
308 {"stroke", StringReference}, {"fill", StringReference},
309 {"strokewidth", RealReference}, {"font", StringReference},
310 {"bordercolor", StringReference}, {"x", RealReference},
311 {"y", RealReference}, {"translate", StringReference},
312 {"scale", StringReference}, {"rotate", RealReference},
313 {"skewX", RealReference}, {"skewY", RealReference},
314 {"tile", ImageReference}, {"pointsize", RealReference},
315 {"antialias", MagickBooleanOptions}, {"density", StringReference},
316 {"linewidth", RealReference}, {"affine", ArrayReference},
317 {"stroke-dashoffset", RealReference},
318 {"stroke-dasharray", ArrayReference},
319 {"interpolate", MagickInterpolateOptions},
320 {"origin", StringReference}, {"text", StringReference},
321 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
322 {"vector-graphics", StringReference}, {"kerning", RealReference},
323 {"interline-spacing", RealReference},
324 {"interword-spacing", RealReference},
325 {"direction", MagickDirectionOptions} } },
326 { "Equalize", { {"channel", MagickChannelOptions} } },
327 { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
328 {"red", RealReference}, {"green", RealReference},
329 {"blue", RealReference} } },
330 { "Map", { {"image", ImageReference},
331 {"dither-method", MagickDitherOptions} } },
332 { "MatteFloodfill", { {"geometry", StringReference},
333 {"x", IntegerReference}, {"y", IntegerReference},
334 {"opacity", StringReference}, {"bordercolor", StringReference},
335 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
336 { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
337 {"saturation", RealReference}, {"whiteness", RealReference},
338 {"brightness", RealReference}, {"lightness", RealReference},
339 {"blackness", RealReference} } },
340 { "Negate", { {"gray", MagickBooleanOptions},
341 {"channel", MagickChannelOptions} } },
342 { "Normalize", { {"channel", MagickChannelOptions} } },
343 { "NumberColors", },
344 { "Opaque", { {"color", StringReference}, {"fill", StringReference},
345 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
346 {"invert", MagickBooleanOptions} } },
347 { "Quantize", { {"colors", IntegerReference},
348 {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
349 {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
350 {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
351 {"dither-method", MagickDitherOptions} } },
352 { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
353 {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
354 { "Segment", { {"geometry", StringReference},
355 {"cluster-threshold", RealReference},
356 {"smoothing-threshold", RealReference},
357 {"colorspace", MagickColorspaceOptions},
358 {"verbose", MagickBooleanOptions} } },
359 { "Signature", },
360 { "Solarize", { {"geometry", StringReference},
361 {"threshold", StringReference} } },
362 { "Sync", },
363 { "Texture", { {"texture", ImageReference} } },
364 { "Evaluate", { {"value", RealReference},
365 {"operator", MagickEvaluateOptions},
366 {"channel", MagickChannelOptions} } },
367 { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
368 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
369 { "Threshold", { {"threshold", StringReference},
370 {"channel", MagickChannelOptions} } },
371 { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
372 {"sigma", RealReference} } },
373 { "Trim", { {"fuzz", StringReference} } },
374 { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
375 {"wavelength", RealReference},
376 {"interpolate", MagickInterpolateOptions} } },
377 { "Separate", { {"channel", MagickChannelOptions} } },
378 { "Condense", },
379 { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
380 {"y", IntegerReference} } },
381 { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
382 { "Deconstruct", },
383 { "GaussianBlur", { {"geometry", StringReference},
384 {"radius", RealReference}, {"sigma", RealReference},
385 {"channel", MagickChannelOptions} } },
386 { "Convolve", { {"coefficients", ArrayReference},
387 {"channel", MagickChannelOptions}, {"bias", StringReference},
388 {"kernel", StringReference} } },
389 { "Profile", { {"name", StringReference}, {"profile", StringReference},
390 { "rendering-intent", MagickIntentOptions},
391 { "black-point-compensation", MagickBooleanOptions} } },
392 { "UnsharpMask", { {"geometry", StringReference},
393 {"radius", RealReference}, {"sigma", RealReference},
394 {"gain", RealReference}, {"threshold", RealReference},
395 {"channel", MagickChannelOptions} } },
396 { "MotionBlur", { {"geometry", StringReference},
397 {"radius", RealReference}, {"sigma", RealReference},
398 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
399 { "OrderedDither", { {"threshold", StringReference},
400 {"channel", MagickChannelOptions} } },
401 { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
402 {"height", IntegerReference} } },
403 { "Level", { {"levels", StringReference}, {"black-point", RealReference},
404 {"white-point", RealReference}, {"gamma", RealReference},
405 {"channel", MagickChannelOptions}, {"level", StringReference} } },
406 { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
407 { "AffineTransform", { {"affine", ArrayReference},
408 {"translate", StringReference}, {"scale", StringReference},
409 {"rotate", RealReference}, {"skewX", RealReference},
410 {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
411 {"background", StringReference} } },
412 { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
413 { "AdaptiveThreshold", { {"geometry", StringReference},
414 {"width", IntegerReference}, {"height", IntegerReference} } },
415 { "Resample", { {"density", StringReference}, {"x", RealReference},
416 {"y", RealReference}, {"filter", MagickFilterOptions},
417 {"support", RealReference } } },
418 { "Describe", { {"file", FileReference} } },
419 { "BlackThreshold", { {"threshold", StringReference},
420 {"channel", MagickChannelOptions} } },
421 { "WhiteThreshold", { {"threshold", StringReference},
422 {"channel", MagickChannelOptions} } },
cristy60c73c02014-03-25 12:09:58 +0000423 { "RotationalBlur", { {"geometry", StringReference},
424 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000425 { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
426 {"height", IntegerReference} } },
427 { "Strip", },
428 { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
429 { "Channel", { {"channel", MagickChannelOptions} } },
430 { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
431 {"height", IntegerReference}, {"x", IntegerReference},
432 {"y", IntegerReference}, {"fuzz", StringReference},
433 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
434 { "Posterize", { {"levels", IntegerReference},
435 {"dither", MagickBooleanOptions} } },
436 { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
437 {"sigma", RealReference}, {"x", IntegerReference},
438 {"y", IntegerReference} } },
439 { "Identify", { {"file", FileReference}, {"features", StringReference},
440 {"unique", MagickBooleanOptions} } },
441 { "SepiaTone", { {"threshold", RealReference} } },
442 { "SigmoidalContrast", { {"geometry", StringReference},
443 {"contrast", RealReference}, {"mid-point", RealReference},
444 {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
445 { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
446 {"height", IntegerReference}, {"x", IntegerReference},
447 {"y", IntegerReference}, {"fuzz", StringReference},
448 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
449 { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
450 {"sigma", RealReference}, {"x", IntegerReference},
451 {"y", IntegerReference}, {"background", StringReference} } },
452 { "ContrastStretch", { {"levels", StringReference},
453 {"black-point", RealReference},{"white-point", RealReference},
454 {"channel", MagickChannelOptions} } },
455 { "Sans0", },
456 { "Sans1", },
457 { "AdaptiveSharpen", { {"geometry", StringReference},
458 {"radius", RealReference}, {"sigma", RealReference},
459 {"bias", RealReference}, {"channel", MagickChannelOptions} } },
460 { "Transpose", },
461 { "Transverse", },
462 { "AutoOrient", },
463 { "AdaptiveBlur", { {"geometry", StringReference},
464 {"radius", RealReference}, {"sigma", RealReference},
465 {"channel", MagickChannelOptions} } },
466 { "Sketch", { {"geometry", StringReference},
467 {"radius", RealReference}, {"sigma", RealReference},
468 {"angle", RealReference} } },
469 { "UniqueColors", },
470 { "AdaptiveResize", { {"geometry", StringReference},
471 {"width", IntegerReference}, {"height", IntegerReference},
472 {"filter", MagickFilterOptions}, {"support", StringReference },
473 {"blur", RealReference } } },
474 { "ClipMask", { {"mask", ImageReference} } },
475 { "LinearStretch", { {"levels", StringReference},
476 {"black-point", RealReference},{"white-point", RealReference} } },
477 { "ColorMatrix", { {"matrix", ArrayReference} } },
478 { "Mask", { {"mask", ImageReference} } },
479 { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
480 {"font", StringReference}, {"stroke", StringReference},
481 {"fill", StringReference}, {"strokewidth", RealReference},
482 {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
483 {"background", StringReference},
484 {"interpolate", MagickInterpolateOptions} } },
485 { "FloodfillPaint", { {"geometry", StringReference},
486 {"x", IntegerReference}, {"y", IntegerReference},
487 {"fill", StringReference}, {"bordercolor", StringReference},
488 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
489 {"invert", MagickBooleanOptions} } },
490 { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
491 {"virtual-pixel", MagickVirtualPixelOptions},
492 {"best-fit", MagickBooleanOptions} } },
493 { "Clut", { {"image", ImageReference},
494 {"interpolate", MagickInterpolateOptions},
495 {"channel", MagickChannelOptions} } },
496 { "LiquidRescale", { {"geometry", StringReference},
497 {"width", IntegerReference}, {"height", IntegerReference},
498 {"delta-x", RealReference}, {"rigidity", RealReference } } },
499 { "Encipher", { {"passphrase", StringReference} } },
500 { "Decipher", { {"passphrase", StringReference} } },
501 { "Deskew", { {"geometry", StringReference},
502 {"threshold", StringReference} } },
503 { "Remap", { {"image", ImageReference},
504 {"dither-method", MagickDitherOptions} } },
505 { "SparseColor", { {"points", ArrayReference},
506 {"method", MagickSparseColorOptions},
507 {"virtual-pixel", MagickVirtualPixelOptions},
508 {"channel", MagickChannelOptions} } },
509 { "Function", { {"parameters", ArrayReference},
510 {"function", MagickFunctionOptions},
511 {"virtual-pixel", MagickVirtualPixelOptions} } },
512 { "SelectiveBlur", { {"geometry", StringReference},
513 {"radius", RealReference}, {"sigma", RealReference},
514 {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
515 { "HaldClut", { {"image", ImageReference},
516 {"channel", MagickChannelOptions} } },
517 { "BlueShift", { {"factor", StringReference} } },
518 { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
519 { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
520 { "ColorDecisionList", {
521 {"color-correction-collection", StringReference} } },
522 { "AutoGamma", { {"channel", MagickChannelOptions} } },
523 { "AutoLevel", { {"channel", MagickChannelOptions} } },
524 { "LevelColors", { {"invert", MagickBooleanOptions},
525 {"black-point", StringReference}, {"white-point", StringReference},
526 {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
527 { "Clamp", { {"channel", MagickChannelOptions} } },
528 { "BrightnessContrast", { {"levels", StringReference},
529 {"brightness", RealReference},{"contrast", RealReference},
530 {"channel", MagickChannelOptions} } },
531 { "Morphology", { {"kernel", StringReference},
532 {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
533 {"iterations", IntegerReference} } },
534 { "Sans", { {"matrix", ArrayReference} } },
535 { "Color", { {"color", StringReference} } },
536 { "Mode", { {"geometry", StringReference},
537 {"width", IntegerReference},{"height", IntegerReference},
538 {"channel", MagickChannelOptions} } },
539 { "Statistic", { {"geometry", StringReference},
540 {"width", IntegerReference},{"height", IntegerReference},
541 {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
542 { "Perceptible", { {"epsilon", RealReference},
543 {"channel", MagickChannelOptions} } },
544 { "Poly", { {"terms", ArrayReference},
545 {"channel", MagickChannelOptions} } },
546 { "Grayscale", { {"method", MagickNoiseOptions} } },
cristy4ceadb82014-03-29 15:30:43 +0000547 { "CannyEdge", { {"geometry", StringReference},
548 {"radius", RealReference}, {"sigma", RealReference},
cristycfe7bf02014-04-04 15:31:52 +0000549 {"lower-percent", RealReference}, {"upper-percent", RealReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000550 { "HoughLine", { {"geometry", StringReference},
cristy4e215022014-04-19 18:02:35 +0000551 {"width", IntegerReference}, {"height", IntegerReference},
552 {"threshold", IntegerReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000553 { "MeanShift", { {"geometry", StringReference},
554 {"width", IntegerReference}, {"height", IntegerReference},
cristy1309fc32014-04-26 18:48:37 +0000555 {"distance", RealReference} } },
cristy3b207f82014-09-27 14:21:20 +0000556 { "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
557 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
Cristy2ca0e9a2016-01-01 08:36:14 -0500558 { "ConnectedComponents", { {"connectivity", IntegerReference} } },
cristyf3a724a2015-06-25 13:02:53 +0000559 { "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
560 {"width", IntegerReference}, {"height", IntegerReference},
561 {"x", IntegerReference}, {"y", IntegerReference},
562 {"gravity", MagickGravityOptions}, {"offset", StringReference},
563 {"dx", IntegerReference}, {"dy", IntegerReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000564 };
565
566static SplayTreeInfo
567 *magick_registry = (SplayTreeInfo *) NULL;
568
569/*
570 Forward declarations.
571*/
572static Image
573 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
574
575static ssize_t
576 strEQcase(const char *,const char *);
577
578/*
579%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
580% %
581% %
582% %
583% C l o n e P a c k a g e I n f o %
584% %
585% %
586% %
587%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
588%
589% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
590% a new one.
591%
592% The format of the ClonePackageInfo routine is:
593%
594% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
595% exception)
596%
597% A description of each parameter follows:
598%
599% o info: a structure of type info.
600%
601% o exception: Return any errors or warnings in this structure.
602%
603*/
604static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
605 ExceptionInfo *exception)
606{
607 struct PackageInfo
608 *clone_info;
609
610 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
611 if (clone_info == (struct PackageInfo *) NULL)
612 {
613 ThrowPerlException(exception,ResourceLimitError,
614 "UnableToClonePackageInfo",PackageName);
615 return((struct PackageInfo *) NULL);
616 }
617 if (info == (struct PackageInfo *) NULL)
618 {
619 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
620 return(clone_info);
621 }
622 *clone_info=(*info);
623 clone_info->image_info=CloneImageInfo(info->image_info);
624 return(clone_info);
625}
626
627/*
628%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
629% %
630% %
631% %
632% c o n s t a n t %
633% %
634% %
635% %
636%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
637%
638% constant() returns a double value for the specified name.
639%
640% The format of the constant routine is:
641%
642% double constant(char *name,ssize_t sans)
643%
644% A description of each parameter follows:
645%
646% o value: Method constant returns a double value for the specified name.
647%
648% o name: The name of the constant.
649%
650% o sans: This integer value is not used.
651%
652*/
653static double constant(char *name,ssize_t sans)
654{
655 (void) sans;
656 errno=0;
657 switch (*name)
658 {
659 case 'B':
660 {
661 if (strEQ(name,"BlobError"))
662 return(BlobError);
663 if (strEQ(name,"BlobWarning"))
664 return(BlobWarning);
665 break;
666 }
667 case 'C':
668 {
669 if (strEQ(name,"CacheError"))
670 return(CacheError);
671 if (strEQ(name,"CacheWarning"))
672 return(CacheWarning);
673 if (strEQ(name,"CoderError"))
674 return(CoderError);
675 if (strEQ(name,"CoderWarning"))
676 return(CoderWarning);
677 if (strEQ(name,"ConfigureError"))
678 return(ConfigureError);
679 if (strEQ(name,"ConfigureWarning"))
680 return(ConfigureWarning);
681 if (strEQ(name,"CorruptImageError"))
682 return(CorruptImageError);
683 if (strEQ(name,"CorruptImageWarning"))
684 return(CorruptImageWarning);
685 break;
686 }
687 case 'D':
688 {
689 if (strEQ(name,"DelegateError"))
690 return(DelegateError);
691 if (strEQ(name,"DelegateWarning"))
692 return(DelegateWarning);
693 if (strEQ(name,"DrawError"))
694 return(DrawError);
695 if (strEQ(name,"DrawWarning"))
696 return(DrawWarning);
697 break;
698 }
699 case 'E':
700 {
701 if (strEQ(name,"ErrorException"))
702 return(ErrorException);
703 if (strEQ(name,"ExceptionError"))
704 return(CoderError);
705 if (strEQ(name,"ExceptionWarning"))
706 return(CoderWarning);
707 break;
708 }
709 case 'F':
710 {
711 if (strEQ(name,"FatalErrorException"))
712 return(FatalErrorException);
713 if (strEQ(name,"FileOpenError"))
714 return(FileOpenError);
715 if (strEQ(name,"FileOpenWarning"))
716 return(FileOpenWarning);
717 break;
718 }
719 case 'I':
720 {
721 if (strEQ(name,"ImageError"))
722 return(ImageError);
723 if (strEQ(name,"ImageWarning"))
724 return(ImageWarning);
725 break;
726 }
727 case 'M':
728 {
729 if (strEQ(name,"MaxRGB"))
730 return(QuantumRange);
731 if (strEQ(name,"MissingDelegateError"))
732 return(MissingDelegateError);
733 if (strEQ(name,"MissingDelegateWarning"))
734 return(MissingDelegateWarning);
735 if (strEQ(name,"ModuleError"))
736 return(ModuleError);
737 if (strEQ(name,"ModuleWarning"))
738 return(ModuleWarning);
739 break;
740 }
741 case 'O':
742 {
743 if (strEQ(name,"Opaque"))
744 return(OpaqueAlpha);
745 if (strEQ(name,"OptionError"))
746 return(OptionError);
747 if (strEQ(name,"OptionWarning"))
748 return(OptionWarning);
749 break;
750 }
751 case 'Q':
752 {
753 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
754 return(MAGICKCORE_QUANTUM_DEPTH);
755 if (strEQ(name,"QuantumDepth"))
756 return(MAGICKCORE_QUANTUM_DEPTH);
757 if (strEQ(name,"QuantumRange"))
758 return(QuantumRange);
759 break;
760 }
761 case 'R':
762 {
763 if (strEQ(name,"ResourceLimitError"))
764 return(ResourceLimitError);
765 if (strEQ(name,"ResourceLimitWarning"))
766 return(ResourceLimitWarning);
767 if (strEQ(name,"RegistryError"))
768 return(RegistryError);
769 if (strEQ(name,"RegistryWarning"))
770 return(RegistryWarning);
771 break;
772 }
773 case 'S':
774 {
775 if (strEQ(name,"StreamError"))
776 return(StreamError);
777 if (strEQ(name,"StreamWarning"))
778 return(StreamWarning);
779 if (strEQ(name,"Success"))
780 return(0);
781 break;
782 }
783 case 'T':
784 {
785 if (strEQ(name,"Transparent"))
786 return(TransparentAlpha);
787 if (strEQ(name,"TypeError"))
788 return(TypeError);
789 if (strEQ(name,"TypeWarning"))
790 return(TypeWarning);
791 break;
792 }
793 case 'W':
794 {
795 if (strEQ(name,"WarningException"))
796 return(WarningException);
797 break;
798 }
799 case 'X':
800 {
801 if (strEQ(name,"XServerError"))
802 return(XServerError);
803 if (strEQ(name,"XServerWarning"))
804 return(XServerWarning);
805 break;
806 }
807 }
808 errno=EINVAL;
809 return(0);
810}
811
812/*
813%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
814% %
815% %
816% %
817% D e s t r o y P a c k a g e I n f o %
818% %
819% %
820% %
821%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
822%
823% Method DestroyPackageInfo frees a previously created info structure.
824%
825% The format of the DestroyPackageInfo routine is:
826%
827% DestroyPackageInfo(struct PackageInfo *info)
828%
829% A description of each parameter follows:
830%
831% o info: a structure of type info.
832%
833*/
834static void DestroyPackageInfo(struct PackageInfo *info)
835{
836 info->image_info=DestroyImageInfo(info->image_info);
837 info=(struct PackageInfo *) RelinquishMagickMemory(info);
838}
839
840/*
841%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
842% %
843% %
844% %
845% G e t L i s t %
846% %
847% %
848% %
849%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
850%
851% Method GetList is recursively called by SetupList to traverse the
852% Image__Magick reference. If building an reference_vector (see SetupList),
853% *current is the current position in *reference_vector and *last is the final
854% entry in *reference_vector.
855%
856% The format of the GetList routine is:
857%
858% GetList(info)
859%
860% A description of each parameter follows:
861%
862% o info: a structure of type info.
863%
864*/
865static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
866 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
867{
868 Image
869 *image;
870
871 if (reference == (SV *) NULL)
872 return(NULL);
873 switch (SvTYPE(reference))
874 {
875 case SVt_PVAV:
876 {
877 AV
878 *av;
879
880 Image
881 *head,
882 *previous;
883
884 register ssize_t
885 i;
886
887 ssize_t
888 n;
889
890 /*
891 Array of images.
892 */
893 previous=(Image *) NULL;
894 head=(Image *) NULL;
895 av=(AV *) reference;
896 n=av_len(av);
897 for (i=0; i <= n; i++)
898 {
899 SV
900 **rv;
901
902 rv=av_fetch(av,i,0);
903 if (rv && *rv && sv_isobject(*rv))
904 {
905 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
906 exception);
907 if (image == (Image *) NULL)
908 continue;
909 if (image == previous)
910 {
911 image=CloneImage(image,0,0,MagickTrue,exception);
912 if (image == (Image *) NULL)
913 return(NULL);
914 }
915 image->previous=previous;
916 *(previous ? &previous->next : &head)=image;
917 for (previous=image; previous->next; previous=previous->next) ;
918 }
919 }
920 return(head);
921 }
922 case SVt_PVMG:
923 {
924 /*
925 Blessed scalar, one image.
926 */
927 image=INT2PTR(Image *,SvIV(reference));
928 if (image == (Image *) NULL)
929 return(NULL);
930 image->previous=(Image *) NULL;
931 image->next=(Image *) NULL;
932 if (reference_vector)
933 {
934 if (*current == *last)
935 {
936 *last+=256;
937 if (*reference_vector == (SV **) NULL)
938 *reference_vector=(SV **) AcquireQuantumMemory(*last,
939 sizeof(*reference_vector));
940 else
941 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
942 *last,sizeof(*reference_vector));
943 }
944 if (*reference_vector == (SV **) NULL)
945 {
946 ThrowPerlException(exception,ResourceLimitError,
947 "MemoryAllocationFailed",PackageName);
948 return((Image *) NULL);
949 }
950 (*reference_vector)[*current]=reference;
951 (*reference_vector)[++(*current)]=NULL;
952 }
953 return(image);
954 }
955 default:
956 break;
957 }
958 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
959 (double) SvTYPE(reference));
960 return((Image *) NULL);
961}
962
963/*
964%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
965% %
966% %
967% %
968% G e t P a c k a g e I n f o %
969% %
970% %
971% %
972%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
973%
974% Method GetPackageInfo looks up or creates an info structure for the given
975% Image__Magick reference. If it does create a new one, the information in
976% package_info is used to initialize it.
977%
978% The format of the GetPackageInfo routine is:
979%
980% struct PackageInfo *GetPackageInfo(void *reference,
981% struct PackageInfo *package_info,ExceptionInfo *exception)
982%
983% A description of each parameter follows:
984%
985% o info: a structure of type info.
986%
987% o exception: Return any errors or warnings in this structure.
988%
989*/
990static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
991 struct PackageInfo *package_info,ExceptionInfo *exception)
992{
993 char
cristy151b66d2015-04-15 10:50:31 +0000994 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +0000995
996 struct PackageInfo
997 *clone_info;
998
999 SV
1000 *sv;
1001
cristy151b66d2015-04-15 10:50:31 +00001002 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00001003 PackageName,XS_VERSION,reference);
1004 sv=perl_get_sv(message,(TRUE | 0x02));
1005 if (sv == (SV *) NULL)
1006 {
1007 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1008 message);
1009 return(package_info);
1010 }
1011 if (SvREFCNT(sv) == 0)
1012 (void) SvREFCNT_inc(sv);
1013 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1014 return(clone_info);
1015 clone_info=ClonePackageInfo(package_info,exception);
1016 sv_setiv(sv,PTR2IV(clone_info));
1017 return(clone_info);
1018}
1019
1020/*
1021%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1022% %
1023% %
1024% %
1025% S e t A t t r i b u t e %
1026% %
1027% %
1028% %
1029%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1030%
1031% SetAttribute() sets the attribute to the value in sval. This can change
1032% either or both of image or info.
1033%
1034% The format of the SetAttribute routine is:
1035%
1036% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1037% SV *sval,ExceptionInfo *exception)
1038%
1039% A description of each parameter follows:
1040%
1041% o list: a list of strings.
1042%
1043% o string: a character string.
1044%
1045*/
1046
1047static double SiPrefixToDoubleInterval(const char *string,const double interval)
1048{
1049 char
1050 *q;
1051
1052 double
1053 value;
1054
1055 value=InterpretSiPrefixValue(string,&q);
1056 if (*q == '%')
1057 value*=interval/100.0;
1058 return(value);
1059}
1060
1061static inline double StringToDouble(const char *string,char **sentinal)
1062{
1063 return(InterpretLocaleValue(string,sentinal));
1064}
1065
1066static double StringToDoubleInterval(const char *string,const double interval)
1067{
1068 char
1069 *q;
1070
1071 double
1072 value;
1073
1074 value=InterpretLocaleValue(string,&q);
1075 if (*q == '%')
1076 value*=interval/100.0;
1077 return(value);
1078}
1079
1080static inline ssize_t StringToLong(const char *value)
1081{
1082 return(strtol(value,(char **) NULL,10));
1083}
1084
1085static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1086 const char *attribute,SV *sval,ExceptionInfo *exception)
1087{
1088 GeometryInfo
1089 geometry_info;
1090
1091 long
1092 x,
1093 y;
1094
1095 PixelInfo
1096 pixel;
1097
1098 MagickStatusType
1099 flags;
1100
1101 PixelInfo
1102 *color,
1103 target_color;
1104
1105 ssize_t
1106 sp;
1107
1108 switch (*attribute)
1109 {
1110 case 'A':
1111 case 'a':
1112 {
1113 if (LocaleCompare(attribute,"adjoin") == 0)
1114 {
1115 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1116 SvPV(sval,na)) : SvIV(sval);
1117 if (sp < 0)
1118 {
1119 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1120 SvPV(sval,na));
1121 break;
1122 }
1123 if (info)
1124 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1125 break;
1126 }
1127 if (LocaleCompare(attribute,"alpha") == 0)
1128 {
1129 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1130 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1131 if (sp < 0)
1132 {
1133 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1134 SvPV(sval,na));
1135 break;
1136 }
1137 for ( ; image; image=image->next)
1138 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1139 exception);
1140 break;
1141 }
1142 if (LocaleCompare(attribute,"antialias") == 0)
1143 {
1144 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1145 SvPV(sval,na)) : SvIV(sval);
1146 if (sp < 0)
1147 {
1148 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1149 SvPV(sval,na));
1150 break;
1151 }
1152 if (info)
1153 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1154 break;
1155 }
1156 if (LocaleCompare(attribute,"area-limit") == 0)
1157 {
1158 MagickSizeType
1159 limit;
1160
1161 limit=MagickResourceInfinity;
1162 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1163 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1164 100.0);
1165 (void) SetMagickResourceLimit(AreaResource,limit);
1166 break;
1167 }
1168 if (LocaleCompare(attribute,"attenuate") == 0)
1169 {
1170 if (info)
1171 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1172 break;
1173 }
1174 if (LocaleCompare(attribute,"authenticate") == 0)
1175 {
1176 if (info)
1177 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1178 break;
1179 }
1180 if (info)
1181 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1182 for ( ; image; image=image->next)
1183 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1184 break;
1185 }
1186 case 'B':
1187 case 'b':
1188 {
1189 if (LocaleCompare(attribute,"background") == 0)
1190 {
1191 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1192 exception);
1193 if (info)
1194 info->image_info->background_color=target_color;
1195 for ( ; image; image=image->next)
1196 image->background_color=target_color;
1197 break;
1198 }
1199 if (LocaleCompare(attribute,"blue-primary") == 0)
1200 {
1201 for ( ; image; image=image->next)
1202 {
1203 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1204 image->chromaticity.blue_primary.x=geometry_info.rho;
1205 image->chromaticity.blue_primary.y=geometry_info.sigma;
1206 if ((flags & SigmaValue) == 0)
1207 image->chromaticity.blue_primary.y=
1208 image->chromaticity.blue_primary.x;
1209 }
1210 break;
1211 }
1212 if (LocaleCompare(attribute,"bordercolor") == 0)
1213 {
1214 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1215 exception);
1216 if (info)
1217 info->image_info->border_color=target_color;
1218 for ( ; image; image=image->next)
1219 image->border_color=target_color;
1220 break;
1221 }
1222 if (info)
1223 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1224 for ( ; image; image=image->next)
1225 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1226 break;
1227 }
1228 case 'C':
1229 case 'c':
1230 {
1231 if (LocaleCompare(attribute,"cache-threshold") == 0)
1232 {
1233 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1234 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1235 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1236 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1237 break;
1238 }
1239 if (LocaleCompare(attribute,"clip-mask") == 0)
1240 {
1241 Image
1242 *clip_mask;
1243
1244 clip_mask=(Image *) NULL;
1245 if (SvPOK(sval))
1246 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1247 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001248 SetImageMask(image,ReadPixelMask,clip_mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001249 break;
1250 }
1251 if (LocaleNCompare(attribute,"colormap",8) == 0)
1252 {
1253 for ( ; image; image=image->next)
1254 {
1255 int
1256 items;
1257
1258 long
1259 i;
1260
1261 if (image->storage_class == DirectClass)
1262 continue;
1263 i=0;
1264 items=sscanf(attribute,"%*[^[][%ld",&i);
1265 (void) items;
1266 if (i > (ssize_t) image->colors)
1267 i%=image->colors;
1268 if ((strchr(SvPV(sval,na),',') == 0) ||
1269 (strchr(SvPV(sval,na),')') != 0))
1270 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1271 image->colormap+i,exception);
1272 else
1273 {
1274 color=image->colormap+i;
1275 pixel.red=color->red;
1276 pixel.green=color->green;
1277 pixel.blue=color->blue;
1278 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1279 pixel.red=geometry_info.rho;
1280 pixel.green=geometry_info.sigma;
1281 pixel.blue=geometry_info.xi;
1282 color->red=ClampToQuantum(pixel.red);
1283 color->green=ClampToQuantum(pixel.green);
1284 color->blue=ClampToQuantum(pixel.blue);
1285 }
1286 }
1287 break;
1288 }
1289 if (LocaleCompare(attribute,"colorspace") == 0)
1290 {
1291 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1292 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1293 if (sp < 0)
1294 {
1295 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1296 SvPV(sval,na));
1297 break;
1298 }
1299 for ( ; image; image=image->next)
1300 (void) TransformImageColorspace(image,(ColorspaceType) sp,
1301 exception);
1302 break;
1303 }
1304 if (LocaleCompare(attribute,"comment") == 0)
1305 {
1306 for ( ; image; image=image->next)
1307 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1308 info ? info->image_info : (ImageInfo *) NULL,image,
1309 SvPV(sval,na),exception),exception);
1310 break;
1311 }
1312 if (LocaleCompare(attribute,"compression") == 0)
1313 {
1314 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1315 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1316 if (sp < 0)
1317 {
1318 ThrowPerlException(exception,OptionError,
1319 "UnrecognizedImageCompression",SvPV(sval,na));
1320 break;
1321 }
1322 if (info)
1323 info->image_info->compression=(CompressionType) sp;
1324 for ( ; image; image=image->next)
1325 image->compression=(CompressionType) sp;
1326 break;
1327 }
1328 if (info)
1329 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1330 for ( ; image; image=image->next)
1331 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1332 break;
1333 }
1334 case 'D':
1335 case 'd':
1336 {
1337 if (LocaleCompare(attribute,"debug") == 0)
1338 {
1339 SetLogEventMask(SvPV(sval,na));
1340 break;
1341 }
1342 if (LocaleCompare(attribute,"delay") == 0)
1343 {
1344 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1345 for ( ; image; image=image->next)
1346 {
1347 image->delay=(size_t) floor(geometry_info.rho+0.5);
1348 if ((flags & SigmaValue) != 0)
1349 image->ticks_per_second=(ssize_t)
1350 floor(geometry_info.sigma+0.5);
1351 }
1352 break;
1353 }
1354 if (LocaleCompare(attribute,"disk-limit") == 0)
1355 {
1356 MagickSizeType
1357 limit;
1358
1359 limit=MagickResourceInfinity;
1360 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1361 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1362 100.0);
1363 (void) SetMagickResourceLimit(DiskResource,limit);
1364 break;
1365 }
1366 if (LocaleCompare(attribute,"density") == 0)
1367 {
1368 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1369 {
1370 ThrowPerlException(exception,OptionError,"MissingGeometry",
1371 SvPV(sval,na));
1372 break;
1373 }
1374 if (info)
1375 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1376 for ( ; image; image=image->next)
1377 {
1378 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1379 image->resolution.x=geometry_info.rho;
1380 image->resolution.y=geometry_info.sigma;
1381 if ((flags & SigmaValue) == 0)
1382 image->resolution.y=image->resolution.x;
1383 }
1384 break;
1385 }
1386 if (LocaleCompare(attribute,"depth") == 0)
1387 {
1388 if (info)
1389 info->image_info->depth=SvIV(sval);
1390 for ( ; image; image=image->next)
1391 (void) SetImageDepth(image,SvIV(sval),exception);
1392 break;
1393 }
1394 if (LocaleCompare(attribute,"dispose") == 0)
1395 {
1396 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1397 SvPV(sval,na)) : SvIV(sval);
1398 if (sp < 0)
1399 {
1400 ThrowPerlException(exception,OptionError,
1401 "UnrecognizedDisposeMethod",SvPV(sval,na));
1402 break;
1403 }
1404 for ( ; image; image=image->next)
1405 image->dispose=(DisposeType) sp;
1406 break;
1407 }
1408 if (LocaleCompare(attribute,"dither") == 0)
1409 {
1410 if (info)
1411 {
1412 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1413 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1414 if (sp < 0)
1415 {
1416 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1417 SvPV(sval,na));
1418 break;
1419 }
1420 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1421 }
1422 break;
1423 }
1424 if (LocaleCompare(attribute,"display") == 0)
1425 {
1426 display:
1427 if (info)
1428 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1429 break;
1430 }
1431 if (info)
1432 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1433 for ( ; image; image=image->next)
1434 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1435 break;
1436 }
1437 case 'E':
1438 case 'e':
1439 {
1440 if (LocaleCompare(attribute,"endian") == 0)
1441 {
1442 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1443 SvPV(sval,na)) : SvIV(sval);
1444 if (sp < 0)
1445 {
1446 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1447 SvPV(sval,na));
1448 break;
1449 }
1450 if (info)
1451 info->image_info->endian=(EndianType) sp;
1452 for ( ; image; image=image->next)
1453 image->endian=(EndianType) sp;
1454 break;
1455 }
1456 if (LocaleCompare(attribute,"extract") == 0)
1457 {
1458 /*
1459 Set image extract geometry.
1460 */
1461 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1462 break;
1463 }
1464 if (info)
1465 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1466 for ( ; image; image=image->next)
1467 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1468 break;
1469 }
1470 case 'F':
1471 case 'f':
1472 {
1473 if (LocaleCompare(attribute,"filename") == 0)
1474 {
1475 if (info)
1476 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001477 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001478 for ( ; image; image=image->next)
1479 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001480 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001481 break;
1482 }
1483 if (LocaleCompare(attribute,"file") == 0)
1484 {
1485 FILE
1486 *file;
1487
1488 PerlIO
1489 *io_info;
1490
1491 if (info == (struct PackageInfo *) NULL)
1492 break;
1493 io_info=IoIFP(sv_2io(sval));
1494 if (io_info == (PerlIO *) NULL)
1495 {
1496 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1497 PackageName);
1498 break;
1499 }
1500 file=PerlIO_findFILE(io_info);
1501 if (file == (FILE *) NULL)
1502 {
1503 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1504 PackageName);
1505 break;
1506 }
1507 SetImageInfoFile(info->image_info,file);
1508 break;
1509 }
1510 if (LocaleCompare(attribute,"fill") == 0)
1511 {
1512 if (info)
1513 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1514 break;
1515 }
1516 if (LocaleCompare(attribute,"font") == 0)
1517 {
1518 if (info)
1519 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1520 break;
1521 }
1522 if (LocaleCompare(attribute,"foreground") == 0)
1523 break;
1524 if (LocaleCompare(attribute,"fuzz") == 0)
1525 {
1526 if (info)
1527 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1528 QuantumRange+1.0);
1529 for ( ; image; image=image->next)
1530 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1531 QuantumRange+1.0);
1532 break;
1533 }
1534 if (info)
1535 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1536 for ( ; image; image=image->next)
1537 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1538 break;
1539 }
1540 case 'G':
1541 case 'g':
1542 {
1543 if (LocaleCompare(attribute,"gamma") == 0)
1544 {
1545 for ( ; image; image=image->next)
1546 image->gamma=SvNV(sval);
1547 break;
1548 }
1549 if (LocaleCompare(attribute,"gravity") == 0)
1550 {
1551 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1552 SvPV(sval,na)) : SvIV(sval);
1553 if (sp < 0)
1554 {
1555 ThrowPerlException(exception,OptionError,
1556 "UnrecognizedGravityType",SvPV(sval,na));
1557 break;
1558 }
1559 if (info)
1560 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1561 for ( ; image; image=image->next)
1562 image->gravity=(GravityType) sp;
1563 break;
1564 }
1565 if (LocaleCompare(attribute,"green-primary") == 0)
1566 {
1567 for ( ; image; image=image->next)
1568 {
1569 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1570 image->chromaticity.green_primary.x=geometry_info.rho;
1571 image->chromaticity.green_primary.y=geometry_info.sigma;
1572 if ((flags & SigmaValue) == 0)
1573 image->chromaticity.green_primary.y=
1574 image->chromaticity.green_primary.x;
1575 }
1576 break;
1577 }
1578 if (info)
1579 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1580 for ( ; image; image=image->next)
1581 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1582 break;
1583 }
1584 case 'I':
1585 case 'i':
1586 {
1587 if (LocaleNCompare(attribute,"index",5) == 0)
1588 {
1589 int
1590 items;
1591
1592 long
1593 index;
1594
1595 register Quantum
1596 *q;
1597
1598 CacheView
1599 *image_view;
1600
1601 for ( ; image; image=image->next)
1602 {
1603 if (image->storage_class != PseudoClass)
1604 continue;
1605 x=0;
1606 y=0;
1607 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1608 (void) items;
1609 image_view=AcquireAuthenticCacheView(image,exception);
1610 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1611 if (q != (Quantum *) NULL)
1612 {
1613 items=sscanf(SvPV(sval,na),"%ld",&index);
1614 if ((index >= 0) && (index < (ssize_t) image->colors))
1615 SetPixelIndex(image,index,q);
1616 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1617 }
1618 image_view=DestroyCacheView(image_view);
1619 }
1620 break;
1621 }
1622 if (LocaleCompare(attribute,"iterations") == 0)
1623 {
1624 iterations:
1625 for ( ; image; image=image->next)
1626 image->iterations=SvIV(sval);
1627 break;
1628 }
1629 if (LocaleCompare(attribute,"interlace") == 0)
1630 {
1631 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1632 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1633 if (sp < 0)
1634 {
1635 ThrowPerlException(exception,OptionError,
1636 "UnrecognizedInterlaceType",SvPV(sval,na));
1637 break;
1638 }
1639 if (info)
1640 info->image_info->interlace=(InterlaceType) sp;
1641 for ( ; image; image=image->next)
1642 image->interlace=(InterlaceType) sp;
1643 break;
1644 }
1645 if (info)
1646 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1647 for ( ; image; image=image->next)
1648 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1649 break;
1650 }
1651 case 'L':
1652 case 'l':
1653 {
1654 if (LocaleCompare(attribute,"label") == 0)
1655 {
1656 for ( ; image; image=image->next)
1657 (void) SetImageProperty(image,"label",InterpretImageProperties(
1658 info ? info->image_info : (ImageInfo *) NULL,image,
1659 SvPV(sval,na),exception),exception);
1660 break;
1661 }
1662 if (LocaleCompare(attribute,"loop") == 0)
1663 goto iterations;
1664 if (info)
1665 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1666 for ( ; image; image=image->next)
1667 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1668 break;
1669 }
1670 case 'M':
1671 case 'm':
1672 {
1673 if (LocaleCompare(attribute,"magick") == 0)
1674 {
1675 if (info)
cristy151b66d2015-04-15 10:50:31 +00001676 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00001677 "%s:",SvPV(sval,na));
1678 for ( ; image; image=image->next)
cristy151b66d2015-04-15 10:50:31 +00001679 (void) CopyMagickString(image->magick,SvPV(sval,na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001680 break;
1681 }
1682 if (LocaleCompare(attribute,"map-limit") == 0)
1683 {
1684 MagickSizeType
1685 limit;
1686
1687 limit=MagickResourceInfinity;
1688 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1689 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1690 100.0);
1691 (void) SetMagickResourceLimit(MapResource,limit);
1692 break;
1693 }
1694 if (LocaleCompare(attribute,"mask") == 0)
1695 {
1696 Image
1697 *mask;
1698
1699 mask=(Image *) NULL;
1700 if (SvPOK(sval))
1701 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1702 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001703 SetImageMask(image,ReadPixelMask,mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001704 break;
1705 }
1706 if (LocaleCompare(attribute,"mattecolor") == 0)
1707 {
1708 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1709 exception);
1710 if (info)
1711 info->image_info->matte_color=target_color;
1712 for ( ; image; image=image->next)
1713 image->matte_color=target_color;
1714 break;
1715 }
1716 if (LocaleCompare(attribute,"matte") == 0)
1717 {
1718 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1719 SvPV(sval,na)) : SvIV(sval);
1720 if (sp < 0)
1721 {
1722 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1723 SvPV(sval,na));
1724 break;
1725 }
1726 for ( ; image; image=image->next)
1727 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1728 break;
1729 }
1730 if (LocaleCompare(attribute,"memory-limit") == 0)
1731 {
1732 MagickSizeType
1733 limit;
1734
1735 limit=MagickResourceInfinity;
1736 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1737 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1738 100.0);
1739 (void) SetMagickResourceLimit(MemoryResource,limit);
1740 break;
1741 }
1742 if (LocaleCompare(attribute,"monochrome") == 0)
1743 {
1744 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1745 SvPV(sval,na)) : SvIV(sval);
1746 if (sp < 0)
1747 {
1748 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1749 SvPV(sval,na));
1750 break;
1751 }
1752 if (info)
1753 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1754 for ( ; image; image=image->next)
1755 (void) SetImageType(image,BilevelType,exception);
1756 break;
1757 }
1758 if (info)
1759 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1760 for ( ; image; image=image->next)
1761 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1762 break;
1763 }
1764 case 'O':
1765 case 'o':
1766 {
1767 if (LocaleCompare(attribute,"option") == 0)
1768 {
1769 if (info)
1770 DefineImageOption(info->image_info,SvPV(sval,na));
1771 break;
1772 }
1773 if (LocaleCompare(attribute,"orientation") == 0)
1774 {
1775 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1776 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1777 if (sp < 0)
1778 {
1779 ThrowPerlException(exception,OptionError,
1780 "UnrecognizedOrientationType",SvPV(sval,na));
1781 break;
1782 }
1783 if (info)
1784 info->image_info->orientation=(OrientationType) sp;
1785 for ( ; image; image=image->next)
1786 image->orientation=(OrientationType) sp;
1787 break;
1788 }
1789 if (info)
1790 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1791 for ( ; image; image=image->next)
1792 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1793 break;
1794 }
1795 case 'P':
1796 case 'p':
1797 {
1798 if (LocaleCompare(attribute,"page") == 0)
1799 {
1800 char
1801 *geometry;
1802
1803 geometry=GetPageGeometry(SvPV(sval,na));
1804 if (info)
1805 (void) CloneString(&info->image_info->page,geometry);
1806 for ( ; image; image=image->next)
1807 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1808 geometry=(char *) RelinquishMagickMemory(geometry);
1809 break;
1810 }
1811 if (LocaleNCompare(attribute,"pixel",5) == 0)
1812 {
1813 int
1814 items;
1815
1816 PixelInfo
1817 pixel;
1818
1819 register Quantum
1820 *q;
1821
1822 CacheView
1823 *image_view;
1824
1825 for ( ; image; image=image->next)
1826 {
1827 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1828 break;
1829 x=0;
1830 y=0;
1831 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1832 (void) items;
1833 image_view=AcquireVirtualCacheView(image,exception);
1834 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1835 if (q != (Quantum *) NULL)
1836 {
1837 if ((strchr(SvPV(sval,na),',') == 0) ||
1838 (strchr(SvPV(sval,na),')') != 0))
1839 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1840 &pixel,exception);
1841 else
1842 {
1843 GetPixelInfo(image,&pixel);
1844 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1845 pixel.red=geometry_info.rho;
1846 if ((flags & SigmaValue) != 0)
1847 pixel.green=geometry_info.sigma;
1848 if ((flags & XiValue) != 0)
1849 pixel.blue=geometry_info.xi;
1850 if ((flags & PsiValue) != 0)
1851 pixel.alpha=geometry_info.psi;
1852 if ((flags & ChiValue) != 0)
1853 pixel.black=geometry_info.chi;
1854 }
1855 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1856 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1857 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1858 if (image->colorspace == CMYKColorspace)
1859 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1860 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1861 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1862 }
1863 image_view=DestroyCacheView(image_view);
1864 }
1865 break;
1866 }
1867 if (LocaleCompare(attribute,"pointsize") == 0)
1868 {
1869 if (info)
1870 {
1871 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1872 info->image_info->pointsize=geometry_info.rho;
1873 }
1874 break;
1875 }
1876 if (LocaleCompare(attribute,"preview") == 0)
1877 {
1878 sp=SvPOK(sval) ? ParseCommandOption(MagickPreviewOptions,MagickFalse,
1879 SvPV(sval,na)) : SvIV(sval);
1880 if (sp < 0)
1881 {
1882 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1883 SvPV(sval,na));
1884 break;
1885 }
1886 if (info)
1887 info->image_info->preview_type=(PreviewType) sp;
1888 break;
1889 }
1890 if (info)
1891 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1892 for ( ; image; image=image->next)
1893 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1894 break;
1895 }
1896 case 'Q':
1897 case 'q':
1898 {
1899 if (LocaleCompare(attribute,"quality") == 0)
1900 {
1901 if (info)
1902 info->image_info->quality=SvIV(sval);
1903 for ( ; image; image=image->next)
1904 image->quality=SvIV(sval);
1905 break;
1906 }
1907 if (info)
1908 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1909 for ( ; image; image=image->next)
1910 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1911 break;
1912 }
1913 case 'R':
1914 case 'r':
1915 {
cristyc0fe4752015-07-27 18:02:39 +00001916 if (LocaleCompare(attribute,"read-mask") == 0)
1917 {
1918 Image
1919 *mask;
1920
1921 mask=(Image *) NULL;
1922 if (SvPOK(sval))
1923 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1924 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001925 SetImageMask(image,ReadPixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00001926 break;
1927 }
cristy4a3ce0a2013-08-03 20:06:59 +00001928 if (LocaleCompare(attribute,"red-primary") == 0)
1929 {
1930 for ( ; image; image=image->next)
1931 {
1932 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1933 image->chromaticity.red_primary.x=geometry_info.rho;
1934 image->chromaticity.red_primary.y=geometry_info.sigma;
1935 if ((flags & SigmaValue) == 0)
1936 image->chromaticity.red_primary.y=
1937 image->chromaticity.red_primary.x;
1938 }
1939 break;
1940 }
1941 if (LocaleCompare(attribute,"render") == 0)
1942 {
1943 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1944 SvPV(sval,na)) : SvIV(sval);
1945 if (sp < 0)
1946 {
1947 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1948 SvPV(sval,na));
1949 break;
1950 }
1951 for ( ; image; image=image->next)
1952 image->rendering_intent=(RenderingIntent) sp;
1953 break;
1954 }
1955 if (LocaleCompare(attribute,"repage") == 0)
1956 {
1957 RectangleInfo
1958 geometry;
1959
1960 for ( ; image; image=image->next)
1961 {
1962 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1963 if ((flags & WidthValue) != 0)
1964 {
1965 if ((flags & HeightValue) == 0)
1966 geometry.height=geometry.width;
1967 image->page.width=geometry.width;
1968 image->page.height=geometry.height;
1969 }
1970 if ((flags & AspectValue) != 0)
1971 {
1972 if ((flags & XValue) != 0)
1973 image->page.x+=geometry.x;
1974 if ((flags & YValue) != 0)
1975 image->page.y+=geometry.y;
1976 }
1977 else
1978 {
1979 if ((flags & XValue) != 0)
1980 {
1981 image->page.x=geometry.x;
1982 if (((flags & WidthValue) != 0) && (geometry.x > 0))
1983 image->page.width=image->columns+geometry.x;
1984 }
1985 if ((flags & YValue) != 0)
1986 {
1987 image->page.y=geometry.y;
1988 if (((flags & HeightValue) != 0) && (geometry.y > 0))
1989 image->page.height=image->rows+geometry.y;
1990 }
1991 }
1992 }
1993 break;
1994 }
1995 if (info)
1996 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1997 for ( ; image; image=image->next)
1998 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1999 break;
2000 }
2001 case 'S':
2002 case 's':
2003 {
2004 if (LocaleCompare(attribute,"sampling-factor") == 0)
2005 {
2006 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2007 {
2008 ThrowPerlException(exception,OptionError,"MissingGeometry",
2009 SvPV(sval,na));
2010 break;
2011 }
2012 if (info)
2013 (void) CloneString(&info->image_info->sampling_factor,
2014 SvPV(sval,na));
2015 break;
2016 }
2017 if (LocaleCompare(attribute,"scene") == 0)
2018 {
2019 for ( ; image; image=image->next)
2020 image->scene=SvIV(sval);
2021 break;
2022 }
2023 if (LocaleCompare(attribute,"server") == 0)
2024 goto display;
2025 if (LocaleCompare(attribute,"size") == 0)
2026 {
2027 if (info)
2028 {
2029 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2030 {
2031 ThrowPerlException(exception,OptionError,"MissingGeometry",
2032 SvPV(sval,na));
2033 break;
2034 }
2035 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2036 }
2037 break;
2038 }
2039 if (LocaleCompare(attribute,"stroke") == 0)
2040 {
2041 if (info)
2042 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2043 break;
2044 }
2045 if (info)
2046 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2047 for ( ; image; image=image->next)
2048 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2049 break;
2050 }
2051 case 'T':
2052 case 't':
2053 {
2054 if (LocaleCompare(attribute,"texture") == 0)
2055 {
2056 if (info)
2057 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2058 break;
2059 }
2060 if (LocaleCompare(attribute,"thread-limit") == 0)
2061 {
2062 MagickSizeType
2063 limit;
2064
2065 limit=MagickResourceInfinity;
2066 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2067 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2068 100.0);
2069 (void) SetMagickResourceLimit(ThreadResource,limit);
2070 break;
2071 }
2072 if (LocaleCompare(attribute,"tile-offset") == 0)
2073 {
2074 char
2075 *geometry;
2076
2077 geometry=GetPageGeometry(SvPV(sval,na));
2078 if (info)
2079 (void) CloneString(&info->image_info->page,geometry);
2080 for ( ; image; image=image->next)
2081 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2082 exception);
2083 geometry=(char *) RelinquishMagickMemory(geometry);
2084 break;
2085 }
2086 if (LocaleCompare(attribute,"time-limit") == 0)
2087 {
2088 MagickSizeType
2089 limit;
2090
2091 limit=MagickResourceInfinity;
2092 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2093 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2094 100.0);
2095 (void) SetMagickResourceLimit(TimeResource,limit);
2096 break;
2097 }
2098 if (LocaleCompare(attribute,"transparent-color") == 0)
2099 {
2100 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2101 exception);
2102 if (info)
2103 info->image_info->transparent_color=target_color;
2104 for ( ; image; image=image->next)
2105 image->transparent_color=target_color;
2106 break;
2107 }
2108 if (LocaleCompare(attribute,"type") == 0)
2109 {
2110 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2111 SvPV(sval,na)) : SvIV(sval);
2112 if (sp < 0)
2113 {
2114 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2115 SvPV(sval,na));
2116 break;
2117 }
2118 if (info)
2119 info->image_info->type=(ImageType) sp;
2120 for ( ; image; image=image->next)
2121 SetImageType(image,(ImageType) sp,exception);
2122 break;
2123 }
2124 if (info)
2125 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2126 for ( ; image; image=image->next)
2127 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2128 break;
2129 }
2130 case 'U':
2131 case 'u':
2132 {
2133 if (LocaleCompare(attribute,"units") == 0)
2134 {
2135 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2136 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2137 if (sp < 0)
2138 {
2139 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2140 SvPV(sval,na));
2141 break;
2142 }
2143 if (info)
2144 info->image_info->units=(ResolutionType) sp;
2145 for ( ; image; image=image->next)
2146 {
2147 ResolutionType
2148 units;
2149
2150 units=(ResolutionType) sp;
2151 if (image->units != units)
2152 switch (image->units)
2153 {
2154 case UndefinedResolution:
2155 case PixelsPerInchResolution:
2156 {
2157 if (units == PixelsPerCentimeterResolution)
2158 {
2159 image->resolution.x*=2.54;
2160 image->resolution.y*=2.54;
2161 }
2162 break;
2163 }
2164 case PixelsPerCentimeterResolution:
2165 {
2166 if (units == PixelsPerInchResolution)
2167 {
2168 image->resolution.x/=2.54;
2169 image->resolution.y/=2.54;
2170 }
2171 break;
2172 }
2173 }
2174 image->units=units;
2175 }
2176 break;
2177 }
2178 if (info)
2179 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2180 for ( ; image; image=image->next)
2181 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2182 break;
2183 }
2184 case 'V':
2185 case 'v':
2186 {
2187 if (LocaleCompare(attribute,"verbose") == 0)
2188 {
2189 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2190 SvPV(sval,na)) : SvIV(sval);
2191 if (sp < 0)
2192 {
2193 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2194 SvPV(sval,na));
2195 break;
2196 }
2197 if (info)
2198 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2199 break;
2200 }
cristy4a3ce0a2013-08-03 20:06:59 +00002201 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2202 {
2203 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2204 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2205 if (sp < 0)
2206 {
2207 ThrowPerlException(exception,OptionError,
2208 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2209 break;
2210 }
2211 for ( ; image; image=image->next)
2212 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2213 break;
2214 }
2215 if (info)
2216 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2217 for ( ; image; image=image->next)
2218 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2219 break;
2220 }
2221 case 'W':
2222 case 'w':
2223 {
2224 if (LocaleCompare(attribute,"white-point") == 0)
2225 {
2226 for ( ; image; image=image->next)
2227 {
2228 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2229 image->chromaticity.white_point.x=geometry_info.rho;
2230 image->chromaticity.white_point.y=geometry_info.sigma;
2231 if ((flags & SigmaValue) == 0)
2232 image->chromaticity.white_point.y=
2233 image->chromaticity.white_point.x;
2234 }
2235 break;
2236 }
cristyc0fe4752015-07-27 18:02:39 +00002237 if (LocaleCompare(attribute,"write-mask") == 0)
2238 {
2239 Image
2240 *mask;
2241
2242 mask=(Image *) NULL;
2243 if (SvPOK(sval))
2244 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2245 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002246 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002247 break;
2248 }
cristy4a3ce0a2013-08-03 20:06:59 +00002249 if (info)
2250 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2251 for ( ; image; image=image->next)
2252 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2253 break;
2254 }
2255 default:
2256 {
2257 if (info)
2258 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2259 for ( ; image; image=image->next)
2260 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2261 break;
2262 }
2263 }
2264}
2265
2266/*
2267%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2268% %
2269% %
2270% %
2271% S e t u p L i s t %
2272% %
2273% %
2274% %
2275%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2276%
2277% Method SetupList returns the list of all the images linked by their
2278% image->next and image->previous link lists for use with ImageMagick. If
2279% info is non-NULL, an info structure is returned in *info. If
2280% reference_vector is non-NULL,an array of SV* are returned in
2281% *reference_vector. Reference_vector is used when the images are going to be
2282% replaced with new Image*'s.
2283%
2284% The format of the SetupList routine is:
2285%
2286% Image *SetupList(SV *reference,struct PackageInfo **info,
2287% SV ***reference_vector,ExceptionInfo *exception)
2288%
2289% A description of each parameter follows:
2290%
2291% o list: a list of strings.
2292%
2293% o string: a character string.
2294%
2295% o exception: Return any errors or warnings in this structure.
2296%
2297*/
2298static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2299 SV ***reference_vector,ExceptionInfo *exception)
2300{
2301 Image
2302 *image;
2303
2304 ssize_t
2305 current,
2306 last;
2307
2308 if (reference_vector)
2309 *reference_vector=NULL;
2310 if (info)
2311 *info=NULL;
2312 current=0;
2313 last=0;
2314 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2315 if (info && (SvTYPE(reference) == SVt_PVAV))
2316 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2317 exception);
2318 return(image);
2319}
2320
2321/*
2322%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2323% %
2324% %
2325% %
2326% s t r E Q c a s e %
2327% %
2328% %
2329% %
2330%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2331%
2332% strEQcase() compares two strings and returns 0 if they are the
2333% same or if the second string runs out first. The comparison is case
2334% insensitive.
2335%
2336% The format of the strEQcase routine is:
2337%
2338% ssize_t strEQcase(const char *p,const char *q)
2339%
2340% A description of each parameter follows:
2341%
2342% o p: a character string.
2343%
2344% o q: a character string.
2345%
2346%
2347*/
2348static ssize_t strEQcase(const char *p,const char *q)
2349{
2350 char
2351 c;
2352
2353 register ssize_t
2354 i;
2355
2356 for (i=0 ; (c=(*q)) != 0; i++)
2357 {
2358 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2359 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2360 return(0);
2361 p++;
2362 q++;
2363 }
2364 return(((*q == 0) && (*p == 0)) ? i : 0);
2365}
2366
2367/*
2368%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2369% %
2370% %
2371% %
2372% I m a g e : : M a g i c k %
2373% %
2374% %
2375% %
2376%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2377%
2378%
2379*/
2380MODULE = Image::Magick PACKAGE = Image::Magick
2381
2382PROTOTYPES: ENABLE
2383
2384BOOT:
2385 MagickCoreGenesis("PerlMagick",MagickFalse);
2386 SetWarningHandler(NULL);
2387 SetErrorHandler(NULL);
2388 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2389 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2390
2391void
2392UNLOAD()
2393 PPCODE:
2394 {
2395 if (magick_registry != (SplayTreeInfo *) NULL)
2396 magick_registry=DestroySplayTree(magick_registry);
2397 MagickCoreTerminus();
2398 }
2399
2400double
2401constant(name,argument)
2402 char *name
2403 ssize_t argument
2404
2405#
2406###############################################################################
2407# #
2408# #
2409# #
2410# A n i m a t e #
2411# #
2412# #
2413# #
2414###############################################################################
2415#
2416#
2417void
2418Animate(ref,...)
2419 Image::Magick ref=NO_INIT
2420 ALIAS:
2421 AnimateImage = 1
2422 animate = 2
2423 animateimage = 3
2424 PPCODE:
2425 {
2426 ExceptionInfo
2427 *exception;
2428
2429 Image
2430 *image;
2431
2432 register ssize_t
2433 i;
2434
2435 struct PackageInfo
2436 *info,
2437 *package_info;
2438
2439 SV
2440 *perl_exception,
2441 *reference;
2442
2443 PERL_UNUSED_VAR(ref);
2444 PERL_UNUSED_VAR(ix);
2445 exception=AcquireExceptionInfo();
2446 perl_exception=newSVpv("",0);
2447 package_info=(struct PackageInfo *) NULL;
2448 if (sv_isobject(ST(0)) == 0)
2449 {
2450 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2451 PackageName);
2452 goto PerlException;
2453 }
2454 reference=SvRV(ST(0));
2455 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2456 if (image == (Image *) NULL)
2457 {
2458 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2459 PackageName);
2460 goto PerlException;
2461 }
2462 package_info=ClonePackageInfo(info,exception);
2463 if (items == 2)
2464 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2465 else
2466 if (items > 2)
2467 for (i=2; i < items; i+=2)
2468 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2469 exception);
2470 (void) AnimateImages(package_info->image_info,image,exception);
2471 (void) CatchImageException(image);
2472
2473 PerlException:
2474 if (package_info != (struct PackageInfo *) NULL)
2475 DestroyPackageInfo(package_info);
2476 InheritPerlException(exception,perl_exception);
2477 exception=DestroyExceptionInfo(exception);
2478 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2479 SvPOK_on(perl_exception);
2480 ST(0)=sv_2mortal(perl_exception);
2481 XSRETURN(1);
2482 }
2483
2484#
2485###############################################################################
2486# #
2487# #
2488# #
2489# A p p e n d #
2490# #
2491# #
2492# #
2493###############################################################################
2494#
2495#
2496void
2497Append(ref,...)
2498 Image::Magick ref=NO_INIT
2499 ALIAS:
2500 AppendImage = 1
2501 append = 2
2502 appendimage = 3
2503 PPCODE:
2504 {
2505 AV
2506 *av;
2507
2508 char
2509 *attribute;
2510
2511 ExceptionInfo
2512 *exception;
2513
2514 HV
2515 *hv;
2516
2517 Image
2518 *image;
2519
2520 register ssize_t
2521 i;
2522
2523 ssize_t
2524 stack;
2525
2526 struct PackageInfo
2527 *info;
2528
2529 SV
2530 *av_reference,
2531 *perl_exception,
2532 *reference,
2533 *rv,
2534 *sv;
2535
2536 PERL_UNUSED_VAR(ref);
2537 PERL_UNUSED_VAR(ix);
2538 exception=AcquireExceptionInfo();
2539 perl_exception=newSVpv("",0);
2540 sv=NULL;
2541 attribute=NULL;
2542 av=NULL;
2543 if (sv_isobject(ST(0)) == 0)
2544 {
2545 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2546 PackageName);
2547 goto PerlException;
2548 }
2549 reference=SvRV(ST(0));
2550 hv=SvSTASH(reference);
2551 av=newAV();
2552 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2553 SvREFCNT_dec(av);
2554 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2555 if (image == (Image *) NULL)
2556 {
2557 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2558 PackageName);
2559 goto PerlException;
2560 }
2561 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2562 /*
2563 Get options.
2564 */
2565 stack=MagickTrue;
2566 for (i=2; i < items; i+=2)
2567 {
2568 attribute=(char *) SvPV(ST(i-1),na);
2569 switch (*attribute)
2570 {
2571 case 'S':
2572 case 's':
2573 {
2574 if (LocaleCompare(attribute,"stack") == 0)
2575 {
2576 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2577 SvPV(ST(i),na));
2578 if (stack < 0)
2579 {
2580 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2581 SvPV(ST(i),na));
2582 return;
2583 }
2584 break;
2585 }
2586 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2587 attribute);
2588 break;
2589 }
2590 default:
2591 {
2592 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2593 attribute);
2594 break;
2595 }
2596 }
2597 }
2598 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2599 if (image == (Image *) NULL)
2600 goto PerlException;
2601 for ( ; image; image=image->next)
2602 {
2603 AddImageToRegistry(sv,image);
2604 rv=newRV(sv);
2605 av_push(av,sv_bless(rv,hv));
2606 SvREFCNT_dec(sv);
2607 }
2608 exception=DestroyExceptionInfo(exception);
2609 ST(0)=av_reference;
2610 SvREFCNT_dec(perl_exception);
2611 XSRETURN(1);
2612
2613 PerlException:
2614 InheritPerlException(exception,perl_exception);
2615 exception=DestroyExceptionInfo(exception);
2616 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2617 SvPOK_on(perl_exception);
2618 ST(0)=sv_2mortal(perl_exception);
2619 XSRETURN(1);
2620 }
2621
2622#
2623###############################################################################
2624# #
2625# #
2626# #
2627# A v e r a g e #
2628# #
2629# #
2630# #
2631###############################################################################
2632#
2633#
2634void
2635Average(ref)
2636 Image::Magick ref=NO_INIT
2637 ALIAS:
2638 AverageImage = 1
2639 average = 2
2640 averageimage = 3
2641 PPCODE:
2642 {
2643 AV
2644 *av;
2645
2646 char
2647 *p;
2648
2649 ExceptionInfo
2650 *exception;
2651
2652 HV
2653 *hv;
2654
2655 Image
2656 *image;
2657
2658 struct PackageInfo
2659 *info;
2660
2661 SV
2662 *perl_exception,
2663 *reference,
2664 *rv,
2665 *sv;
2666
2667 PERL_UNUSED_VAR(ref);
2668 PERL_UNUSED_VAR(ix);
2669 exception=AcquireExceptionInfo();
2670 perl_exception=newSVpv("",0);
2671 sv=NULL;
2672 if (sv_isobject(ST(0)) == 0)
2673 {
2674 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2675 PackageName);
2676 goto PerlException;
2677 }
2678 reference=SvRV(ST(0));
2679 hv=SvSTASH(reference);
2680 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2681 if (image == (Image *) NULL)
2682 {
2683 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2684 PackageName);
2685 goto PerlException;
2686 }
2687 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2688 if (image == (Image *) NULL)
2689 goto PerlException;
2690 /*
2691 Create blessed Perl array for the returned image.
2692 */
2693 av=newAV();
2694 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2695 SvREFCNT_dec(av);
2696 AddImageToRegistry(sv,image);
2697 rv=newRV(sv);
2698 av_push(av,sv_bless(rv,hv));
2699 SvREFCNT_dec(sv);
2700 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002701 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2702 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002703 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2704 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002705 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002706 SetImageInfo(info->image_info,0,exception);
2707 exception=DestroyExceptionInfo(exception);
2708 SvREFCNT_dec(perl_exception);
2709 XSRETURN(1);
2710
2711 PerlException:
2712 InheritPerlException(exception,perl_exception);
2713 exception=DestroyExceptionInfo(exception);
2714 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2715 SvPOK_on(perl_exception);
2716 ST(0)=sv_2mortal(perl_exception);
2717 XSRETURN(1);
2718 }
2719
2720#
2721###############################################################################
2722# #
2723# #
2724# #
2725# B l o b T o I m a g e #
2726# #
2727# #
2728# #
2729###############################################################################
2730#
2731#
2732void
2733BlobToImage(ref,...)
2734 Image::Magick ref=NO_INIT
2735 ALIAS:
2736 BlobToImage = 1
2737 blobtoimage = 2
2738 blobto = 3
2739 PPCODE:
2740 {
2741 AV
2742 *av;
2743
2744 char
2745 **keep,
2746 **list;
2747
2748 ExceptionInfo
2749 *exception;
2750
2751 HV
2752 *hv;
2753
2754 Image
2755 *image;
2756
2757 register char
2758 **p;
2759
2760 register ssize_t
2761 i;
2762
2763 ssize_t
2764 ac,
2765 n,
2766 number_images;
2767
2768 STRLEN
2769 *length;
2770
2771 struct PackageInfo
2772 *info;
2773
2774 SV
2775 *perl_exception,
2776 *reference,
2777 *rv,
2778 *sv;
2779
2780 PERL_UNUSED_VAR(ref);
2781 PERL_UNUSED_VAR(ix);
2782 exception=AcquireExceptionInfo();
2783 perl_exception=newSVpv("",0);
2784 sv=NULL;
2785 number_images=0;
2786 ac=(items < 2) ? 1 : items-1;
2787 length=(STRLEN *) NULL;
2788 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2789 if (list == (char **) NULL)
2790 {
2791 ThrowPerlException(exception,ResourceLimitError,
2792 "MemoryAllocationFailed",PackageName);
2793 goto PerlException;
2794 }
2795 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2796 if (length == (STRLEN *) NULL)
2797 {
2798 ThrowPerlException(exception,ResourceLimitError,
2799 "MemoryAllocationFailed",PackageName);
2800 goto PerlException;
2801 }
2802 if (sv_isobject(ST(0)) == 0)
2803 {
2804 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2805 PackageName);
2806 goto PerlException;
2807 }
2808 reference=SvRV(ST(0));
2809 hv=SvSTASH(reference);
2810 if (SvTYPE(reference) != SVt_PVAV)
2811 {
2812 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2813 PackageName);
2814 goto PerlException;
2815 }
2816 av=(AV *) reference;
2817 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2818 exception);
2819 n=1;
2820 if (items <= 1)
2821 {
2822 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2823 goto PerlException;
2824 }
2825 for (n=0, i=0; i < ac; i++)
2826 {
2827 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2828 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2829 {
2830 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2831 continue;
2832 }
2833 n++;
2834 }
2835 list[n]=(char *) NULL;
2836 keep=list;
2837 for (i=number_images=0; i < n; i++)
2838 {
2839 image=BlobToImage(info->image_info,list[i],length[i],exception);
2840 if (image == (Image *) NULL)
2841 break;
2842 for ( ; image; image=image->next)
2843 {
2844 AddImageToRegistry(sv,image);
2845 rv=newRV(sv);
2846 av_push(av,sv_bless(rv,hv));
2847 SvREFCNT_dec(sv);
2848 number_images++;
2849 }
2850 }
2851 /*
2852 Free resources.
2853 */
2854 for (i=0; i < n; i++)
2855 if (list[i] != (char *) NULL)
2856 for (p=keep; list[i] != *p++; )
2857 if (*p == (char *) NULL)
2858 {
2859 list[i]=(char *) RelinquishMagickMemory(list[i]);
2860 break;
2861 }
2862
2863 PerlException:
2864 if (list)
2865 list=(char **) RelinquishMagickMemory(list);
2866 if (length)
2867 length=(STRLEN *) RelinquishMagickMemory(length);
2868 InheritPerlException(exception,perl_exception);
2869 exception=DestroyExceptionInfo(exception);
2870 sv_setiv(perl_exception,(IV) number_images);
2871 SvPOK_on(perl_exception);
2872 ST(0)=sv_2mortal(perl_exception);
2873 XSRETURN(1);
2874 }
2875
2876#
2877###############################################################################
2878# #
2879# #
2880# #
2881# C h a n n e l F x #
2882# #
2883# #
2884# #
2885###############################################################################
2886#
2887#
2888void
2889ChannelFx(ref,...)
2890 Image::Magick ref=NO_INIT
2891 ALIAS:
2892 ChannelFxImage = 1
2893 channelfx = 2
2894 channelfximage = 3
2895 PPCODE:
2896 {
2897 AV
2898 *av;
2899
2900 char
2901 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002902 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002903
2904 ChannelType
2905 channel,
2906 channel_mask;
2907
2908 ExceptionInfo
2909 *exception;
2910
2911 HV
2912 *hv;
2913
2914 Image
2915 *image;
2916
2917 register ssize_t
2918 i;
2919
2920 struct PackageInfo
2921 *info;
2922
2923 SV
2924 *av_reference,
2925 *perl_exception,
2926 *reference,
2927 *rv,
2928 *sv;
2929
2930 PERL_UNUSED_VAR(ref);
2931 PERL_UNUSED_VAR(ix);
2932 exception=AcquireExceptionInfo();
2933 perl_exception=newSVpv("",0);
2934 sv=NULL;
2935 attribute=NULL;
2936 av=NULL;
2937 if (sv_isobject(ST(0)) == 0)
2938 {
2939 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2940 PackageName);
2941 goto PerlException;
2942 }
2943 reference=SvRV(ST(0));
2944 hv=SvSTASH(reference);
2945 av=newAV();
2946 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2947 SvREFCNT_dec(av);
2948 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2949 if (image == (Image *) NULL)
2950 {
2951 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2952 PackageName);
2953 goto PerlException;
2954 }
2955 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2956 /*
2957 Get options.
2958 */
2959 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00002960 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002961 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00002962 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002963 else
2964 for (i=2; i < items; i+=2)
2965 {
2966 attribute=(char *) SvPV(ST(i-1),na);
2967 switch (*attribute)
2968 {
2969 case 'C':
2970 case 'c':
2971 {
2972 if (LocaleCompare(attribute,"channel") == 0)
2973 {
2974 ssize_t
2975 option;
2976
2977 option=ParseChannelOption(SvPV(ST(i),na));
2978 if (option < 0)
2979 {
2980 ThrowPerlException(exception,OptionError,
2981 "UnrecognizedType",SvPV(ST(i),na));
2982 return;
2983 }
2984 channel=(ChannelType) option;
2985 break;
2986 }
2987 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2988 attribute);
2989 break;
2990 }
2991 case 'E':
2992 case 'e':
2993 {
2994 if (LocaleCompare(attribute,"expression") == 0)
2995 {
2996 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00002997 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002998 break;
2999 }
3000 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3001 attribute);
3002 break;
3003 }
3004 default:
3005 {
3006 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3007 attribute);
3008 break;
3009 }
3010 }
3011 }
3012 channel_mask=SetImageChannelMask(image,channel);
3013 image=ChannelFxImage(image,expression,exception);
3014 if (image != (Image *) NULL)
3015 (void) SetImageChannelMask(image,channel_mask);
3016 if (image == (Image *) NULL)
3017 goto PerlException;
3018 for ( ; image; image=image->next)
3019 {
3020 AddImageToRegistry(sv,image);
3021 rv=newRV(sv);
3022 av_push(av,sv_bless(rv,hv));
3023 SvREFCNT_dec(sv);
3024 }
3025 exception=DestroyExceptionInfo(exception);
3026 ST(0)=av_reference;
3027 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3028 XSRETURN(1);
3029
3030 PerlException:
3031 InheritPerlException(exception,perl_exception);
3032 exception=DestroyExceptionInfo(exception);
3033 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3034 SvPOK_on(perl_exception);
3035 ST(0)=sv_2mortal(perl_exception);
3036 XSRETURN(1);
3037 }
3038
3039#
3040###############################################################################
3041# #
3042# #
3043# #
3044# C l o n e #
3045# #
3046# #
3047# #
3048###############################################################################
3049#
3050#
3051void
3052Clone(ref)
3053 Image::Magick ref=NO_INIT
3054 ALIAS:
3055 CopyImage = 1
3056 copy = 2
3057 copyimage = 3
3058 CloneImage = 4
3059 clone = 5
3060 cloneimage = 6
3061 Clone = 7
3062 PPCODE:
3063 {
3064 AV
3065 *av;
3066
3067 ExceptionInfo
3068 *exception;
3069
3070 HV
3071 *hv;
3072
3073 Image
3074 *clone,
3075 *image;
3076
3077 struct PackageInfo
3078 *info;
3079
3080 SV
3081 *perl_exception,
3082 *reference,
3083 *rv,
3084 *sv;
3085
3086 PERL_UNUSED_VAR(ref);
3087 PERL_UNUSED_VAR(ix);
3088 exception=AcquireExceptionInfo();
3089 perl_exception=newSVpv("",0);
3090 sv=NULL;
3091 if (sv_isobject(ST(0)) == 0)
3092 {
3093 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3094 PackageName);
3095 goto PerlException;
3096 }
3097 reference=SvRV(ST(0));
3098 hv=SvSTASH(reference);
3099 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3100 if (image == (Image *) NULL)
3101 {
3102 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3103 PackageName);
3104 goto PerlException;
3105 }
3106 /*
3107 Create blessed Perl array for the returned image.
3108 */
3109 av=newAV();
3110 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3111 SvREFCNT_dec(av);
3112 for ( ; image; image=image->next)
3113 {
3114 clone=CloneImage(image,0,0,MagickTrue,exception);
3115 if (clone == (Image *) NULL)
3116 break;
3117 AddImageToRegistry(sv,clone);
3118 rv=newRV(sv);
3119 av_push(av,sv_bless(rv,hv));
3120 SvREFCNT_dec(sv);
3121 }
3122 exception=DestroyExceptionInfo(exception);
3123 SvREFCNT_dec(perl_exception);
3124 XSRETURN(1);
3125
3126 PerlException:
3127 InheritPerlException(exception,perl_exception);
3128 exception=DestroyExceptionInfo(exception);
3129 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3130 SvPOK_on(perl_exception);
3131 ST(0)=sv_2mortal(perl_exception);
3132 XSRETURN(1);
3133 }
3134
3135#
3136###############################################################################
3137# #
3138# #
3139# #
3140# C L O N E #
3141# #
3142# #
3143# #
3144###############################################################################
3145#
3146#
3147void
3148CLONE(ref,...)
3149 SV *ref;
3150 CODE:
3151 {
3152 PERL_UNUSED_VAR(ref);
3153 if (magick_registry != (SplayTreeInfo *) NULL)
3154 {
3155 register Image
3156 *p;
3157
3158 ResetSplayTreeIterator(magick_registry);
3159 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3160 while (p != (Image *) NULL)
3161 {
3162 ReferenceImage(p);
3163 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3164 }
3165 }
3166 }
3167
3168#
3169###############################################################################
3170# #
3171# #
3172# #
3173# C o a l e s c e #
3174# #
3175# #
3176# #
3177###############################################################################
3178#
3179#
3180void
3181Coalesce(ref)
3182 Image::Magick ref=NO_INIT
3183 ALIAS:
3184 CoalesceImage = 1
3185 coalesce = 2
3186 coalesceimage = 3
3187 PPCODE:
3188 {
3189 AV
3190 *av;
3191
3192 ExceptionInfo
3193 *exception;
3194
3195 HV
3196 *hv;
3197
3198 Image
3199 *image;
3200
3201 struct PackageInfo
3202 *info;
3203
3204 SV
3205 *av_reference,
3206 *perl_exception,
3207 *reference,
3208 *rv,
3209 *sv;
3210
3211 PERL_UNUSED_VAR(ref);
3212 PERL_UNUSED_VAR(ix);
3213 exception=AcquireExceptionInfo();
3214 perl_exception=newSVpv("",0);
3215 sv=NULL;
3216 if (sv_isobject(ST(0)) == 0)
3217 {
3218 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3219 PackageName);
3220 goto PerlException;
3221 }
3222 reference=SvRV(ST(0));
3223 hv=SvSTASH(reference);
3224 av=newAV();
3225 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3226 SvREFCNT_dec(av);
3227 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3228 if (image == (Image *) NULL)
3229 {
3230 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3231 PackageName);
3232 goto PerlException;
3233 }
3234 image=CoalesceImages(image,exception);
3235 if (image == (Image *) NULL)
3236 goto PerlException;
3237 for ( ; image; image=image->next)
3238 {
3239 AddImageToRegistry(sv,image);
3240 rv=newRV(sv);
3241 av_push(av,sv_bless(rv,hv));
3242 SvREFCNT_dec(sv);
3243 }
3244 exception=DestroyExceptionInfo(exception);
3245 ST(0)=av_reference;
3246 SvREFCNT_dec(perl_exception);
3247 XSRETURN(1);
3248
3249 PerlException:
3250 InheritPerlException(exception,perl_exception);
3251 exception=DestroyExceptionInfo(exception);
3252 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3253 SvPOK_on(perl_exception);
3254 ST(0)=sv_2mortal(perl_exception);
3255 XSRETURN(1);
3256 }
3257
3258#
3259###############################################################################
3260# #
3261# #
3262# #
3263# C o m p a r e #
3264# #
3265# #
3266# #
3267###############################################################################
3268#
3269#
3270void
3271Compare(ref,...)
3272 Image::Magick ref=NO_INIT
3273 ALIAS:
3274 CompareImages = 1
3275 compare = 2
3276 compareimage = 3
3277 PPCODE:
3278 {
3279 AV
3280 *av;
3281
3282 char
3283 *attribute;
3284
3285 double
3286 distortion;
3287
3288 ExceptionInfo
3289 *exception;
3290
3291 HV
3292 *hv;
3293
3294 Image
3295 *difference_image,
3296 *image,
3297 *reconstruct_image;
3298
3299 MetricType
3300 metric;
3301
3302 register ssize_t
3303 i;
3304
3305 ssize_t
3306 option;
3307
3308 struct PackageInfo
3309 *info;
3310
3311 SV
3312 *av_reference,
3313 *perl_exception,
3314 *reference,
3315 *rv,
3316 *sv;
3317
3318 PERL_UNUSED_VAR(ref);
3319 PERL_UNUSED_VAR(ix);
3320 exception=AcquireExceptionInfo();
3321 perl_exception=newSVpv("",0);
3322 sv=NULL;
3323 av=NULL;
3324 attribute=NULL;
3325 if (sv_isobject(ST(0)) == 0)
3326 {
3327 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3328 PackageName);
3329 goto PerlException;
3330 }
3331 reference=SvRV(ST(0));
3332 hv=SvSTASH(reference);
3333 av=newAV();
3334 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3335 SvREFCNT_dec(av);
3336 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3337 if (image == (Image *) NULL)
3338 {
3339 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3340 PackageName);
3341 goto PerlException;
3342 }
3343 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3344 /*
3345 Get attribute.
3346 */
3347 reconstruct_image=image;
3348 metric=RootMeanSquaredErrorMetric;
3349 for (i=2; i < items; i+=2)
3350 {
3351 attribute=(char *) SvPV(ST(i-1),na);
3352 switch (*attribute)
3353 {
3354 case 'C':
3355 case 'c':
3356 {
3357 if (LocaleCompare(attribute,"channel") == 0)
3358 {
3359 ssize_t
3360 option;
3361
3362 option=ParseChannelOption(SvPV(ST(i),na));
3363 if (option < 0)
3364 {
3365 ThrowPerlException(exception,OptionError,
3366 "UnrecognizedType",SvPV(ST(i),na));
3367 return;
3368 }
cristybcd59342015-06-07 14:07:19 +00003369 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003370 break;
3371 }
3372 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3373 attribute);
3374 break;
3375 }
3376 case 'F':
3377 case 'f':
3378 {
3379 if (LocaleCompare(attribute,"fuzz") == 0)
3380 {
3381 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3382 break;
3383 }
3384 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3385 attribute);
3386 break;
3387 }
3388 case 'I':
3389 case 'i':
3390 {
3391 if (LocaleCompare(attribute,"image") == 0)
3392 {
3393 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3394 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3395 break;
3396 }
3397 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3398 attribute);
3399 break;
3400 }
3401 case 'M':
3402 case 'm':
3403 {
3404 if (LocaleCompare(attribute,"metric") == 0)
3405 {
3406 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3407 SvPV(ST(i),na));
3408 if (option < 0)
3409 {
3410 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3411 SvPV(ST(i),na));
3412 break;
3413 }
3414 metric=(MetricType) option;
3415 break;
3416 }
3417 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3418 attribute);
3419 break;
3420 }
3421 default:
3422 {
3423 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3424 attribute);
3425 break;
3426 }
3427 }
3428 }
3429 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3430 exception);
3431 if (difference_image != (Image *) NULL)
3432 {
3433 difference_image->error.mean_error_per_pixel=distortion;
3434 AddImageToRegistry(sv,difference_image);
3435 rv=newRV(sv);
3436 av_push(av,sv_bless(rv,hv));
3437 SvREFCNT_dec(sv);
3438 }
3439 exception=DestroyExceptionInfo(exception);
3440 ST(0)=av_reference;
3441 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3442 XSRETURN(1);
3443
3444 PerlException:
3445 InheritPerlException(exception,perl_exception);
3446 exception=DestroyExceptionInfo(exception);
3447 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3448 SvPOK_on(perl_exception);
3449 ST(0)=sv_2mortal(perl_exception);
3450 XSRETURN(1);
3451 }
3452
3453#
3454###############################################################################
3455# #
3456# #
3457# #
cristy15655332013-10-06 00:27:33 +00003458# C o m p l e x I m a g e s #
3459# #
3460# #
3461# #
3462###############################################################################
3463#
3464#
3465void
3466ComplexImages(ref)
3467 Image::Magick ref=NO_INIT
3468 ALIAS:
3469 ComplexImages = 1
3470 compleximages = 2
3471 PPCODE:
3472 {
3473 AV
3474 *av;
3475
3476 char
3477 *attribute,
3478 *p;
3479
cristyfa21e9e2013-10-07 10:37:38 +00003480 ComplexOperator
3481 op;
3482
cristy15655332013-10-06 00:27:33 +00003483 ExceptionInfo
3484 *exception;
3485
3486 HV
3487 *hv;
3488
3489 Image
3490 *image;
3491
cristy15655332013-10-06 00:27:33 +00003492 register ssize_t
3493 i;
3494
3495 struct PackageInfo
3496 *info;
3497
3498 SV
3499 *perl_exception,
3500 *reference,
3501 *rv,
3502 *sv;
3503
3504 PERL_UNUSED_VAR(ref);
3505 PERL_UNUSED_VAR(ix);
3506 exception=AcquireExceptionInfo();
3507 perl_exception=newSVpv("",0);
3508 sv=NULL;
3509 if (sv_isobject(ST(0)) == 0)
3510 {
3511 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3512 PackageName);
3513 goto PerlException;
3514 }
3515 reference=SvRV(ST(0));
3516 hv=SvSTASH(reference);
3517 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3518 if (image == (Image *) NULL)
3519 {
3520 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3521 PackageName);
3522 goto PerlException;
3523 }
cristyfd168722013-10-07 15:59:31 +00003524 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003525 if (items == 2)
3526 {
3527 ssize_t
3528 in;
3529
3530 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3531 SvPV(ST(1),na));
3532 if (in < 0)
3533 {
3534 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3535 SvPV(ST(1),na));
3536 return;
3537 }
cristyfa21e9e2013-10-07 10:37:38 +00003538 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003539 }
3540 else
3541 for (i=2; i < items; i+=2)
3542 {
3543 attribute=(char *) SvPV(ST(i-1),na);
3544 switch (*attribute)
3545 {
3546 case 'O':
3547 case 'o':
3548 {
3549 if (LocaleCompare(attribute,"operator") == 0)
3550 {
3551 ssize_t
3552 in;
3553
3554 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3555 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3556 if (in < 0)
3557 {
3558 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3559 SvPV(ST(i),na));
3560 return;
3561 }
cristyfa21e9e2013-10-07 10:37:38 +00003562 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003563 break;
3564 }
3565 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3566 attribute);
3567 break;
3568 }
3569 default:
3570 {
3571 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3572 attribute);
3573 break;
3574 }
3575 }
3576 }
3577 image=ComplexImages(image,op,exception);
3578 if (image == (Image *) NULL)
3579 goto PerlException;
3580 /*
3581 Create blessed Perl array for the returned image.
3582 */
3583 av=newAV();
3584 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3585 SvREFCNT_dec(av);
3586 AddImageToRegistry(sv,image);
3587 rv=newRV(sv);
3588 av_push(av,sv_bless(rv,hv));
3589 SvREFCNT_dec(sv);
3590 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003591 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3592 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003593 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3594 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003595 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003596 SetImageInfo(info->image_info,0,exception);
3597 exception=DestroyExceptionInfo(exception);
3598 SvREFCNT_dec(perl_exception);
3599 XSRETURN(1);
3600
3601 PerlException:
3602 InheritPerlException(exception,perl_exception);
3603 exception=DestroyExceptionInfo(exception);
3604 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3605 SvPOK_on(perl_exception);
3606 ST(0)=sv_2mortal(perl_exception);
3607 XSRETURN(1);
3608 }
3609
3610#
3611###############################################################################
3612# #
3613# #
3614# #
cristy4a3ce0a2013-08-03 20:06:59 +00003615# C o m p a r e L a y e r s #
3616# #
3617# #
3618# #
3619###############################################################################
3620#
3621#
3622void
3623CompareLayers(ref)
3624 Image::Magick ref=NO_INIT
3625 ALIAS:
3626 CompareImagesLayers = 1
3627 comparelayers = 2
3628 compareimagelayers = 3
3629 PPCODE:
3630 {
3631 AV
3632 *av;
3633
3634 char
3635 *attribute;
3636
3637 ExceptionInfo
3638 *exception;
3639
3640 HV
3641 *hv;
3642
3643 Image
3644 *image;
3645
3646 LayerMethod
3647 method;
3648
3649 register ssize_t
3650 i;
3651
3652 ssize_t
3653 option;
3654
3655 struct PackageInfo
3656 *info;
3657
3658 SV
3659 *av_reference,
3660 *perl_exception,
3661 *reference,
3662 *rv,
3663 *sv;
3664
3665 PERL_UNUSED_VAR(ref);
3666 PERL_UNUSED_VAR(ix);
3667 exception=AcquireExceptionInfo();
3668 perl_exception=newSVpv("",0);
3669 sv=NULL;
3670 if (sv_isobject(ST(0)) == 0)
3671 {
3672 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3673 PackageName);
3674 goto PerlException;
3675 }
3676 reference=SvRV(ST(0));
3677 hv=SvSTASH(reference);
3678 av=newAV();
3679 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3680 SvREFCNT_dec(av);
3681 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3682 if (image == (Image *) NULL)
3683 {
3684 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3685 PackageName);
3686 goto PerlException;
3687 }
3688 method=CompareAnyLayer;
3689 for (i=2; i < items; i+=2)
3690 {
3691 attribute=(char *) SvPV(ST(i-1),na);
3692 switch (*attribute)
3693 {
3694 case 'M':
3695 case 'm':
3696 {
3697 if (LocaleCompare(attribute,"method") == 0)
3698 {
3699 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3700 SvPV(ST(i),na));
3701 if (option < 0)
3702 {
3703 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3704 SvPV(ST(i),na));
3705 break;
3706 }
3707 method=(LayerMethod) option;
3708 break;
3709 }
3710 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3711 attribute);
3712 break;
3713 }
3714 default:
3715 {
3716 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3717 attribute);
3718 break;
3719 }
3720 }
3721 }
3722 image=CompareImagesLayers(image,method,exception);
3723 if (image == (Image *) NULL)
3724 goto PerlException;
3725 for ( ; image; image=image->next)
3726 {
3727 AddImageToRegistry(sv,image);
3728 rv=newRV(sv);
3729 av_push(av,sv_bless(rv,hv));
3730 SvREFCNT_dec(sv);
3731 }
3732 exception=DestroyExceptionInfo(exception);
3733 ST(0)=av_reference;
3734 SvREFCNT_dec(perl_exception);
3735 XSRETURN(1);
3736
3737 PerlException:
3738 InheritPerlException(exception,perl_exception);
3739 exception=DestroyExceptionInfo(exception);
3740 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3741 SvPOK_on(perl_exception);
3742 ST(0)=sv_2mortal(perl_exception);
3743 XSRETURN(1);
3744 }
3745
3746#
3747###############################################################################
3748# #
3749# #
3750# #
3751# D e s t r o y #
3752# #
3753# #
3754# #
3755###############################################################################
3756#
3757#
3758void
3759DESTROY(ref)
3760 Image::Magick ref=NO_INIT
3761 PPCODE:
3762 {
3763 SV
3764 *reference;
3765
3766 PERL_UNUSED_VAR(ref);
3767 if (sv_isobject(ST(0)) == 0)
3768 croak("ReferenceIsNotMyType");
3769 reference=SvRV(ST(0));
3770 switch (SvTYPE(reference))
3771 {
3772 case SVt_PVAV:
3773 {
3774 char
cristy151b66d2015-04-15 10:50:31 +00003775 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003776
3777 const SV
3778 *key;
3779
3780 HV
3781 *hv;
3782
3783 GV
3784 **gvp;
3785
3786 struct PackageInfo
3787 *info;
3788
3789 SV
3790 *sv;
3791
3792 /*
3793 Array (AV *) reference
3794 */
cristy151b66d2015-04-15 10:50:31 +00003795 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003796 XS_VERSION,reference);
3797 hv=gv_stashpv(PackageName, FALSE);
3798 if (!hv)
3799 break;
3800 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3801 if (!gvp)
3802 break;
3803 sv=GvSV(*gvp);
3804 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3805 {
3806 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3807 DestroyPackageInfo(info);
3808 }
3809 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3810 (void) key;
3811 break;
3812 }
3813 case SVt_PVMG:
3814 {
3815 Image
3816 *image;
3817
3818 /*
3819 Blessed scalar = (Image *) SvIV(reference)
3820 */
3821 image=INT2PTR(Image *,SvIV(reference));
3822 if (image != (Image *) NULL)
3823 DeleteImageFromRegistry(reference,image);
3824 break;
3825 }
3826 default:
3827 break;
3828 }
3829 }
3830
3831#
3832###############################################################################
3833# #
3834# #
3835# #
3836# D i s p l a y #
3837# #
3838# #
3839# #
3840###############################################################################
3841#
3842#
3843void
3844Display(ref,...)
3845 Image::Magick ref=NO_INIT
3846 ALIAS:
3847 DisplayImage = 1
3848 display = 2
3849 displayimage = 3
3850 PPCODE:
3851 {
3852 ExceptionInfo
3853 *exception;
3854
3855 Image
3856 *image;
3857
3858 register ssize_t
3859 i;
3860
3861 struct PackageInfo
3862 *info,
3863 *package_info;
3864
3865 SV
3866 *perl_exception,
3867 *reference;
3868
3869 PERL_UNUSED_VAR(ref);
3870 PERL_UNUSED_VAR(ix);
3871 exception=AcquireExceptionInfo();
3872 perl_exception=newSVpv("",0);
3873 package_info=(struct PackageInfo *) NULL;
3874 if (sv_isobject(ST(0)) == 0)
3875 {
3876 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3877 PackageName);
3878 goto PerlException;
3879 }
3880 reference=SvRV(ST(0));
3881 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3882 if (image == (Image *) NULL)
3883 {
3884 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3885 PackageName);
3886 goto PerlException;
3887 }
3888 package_info=ClonePackageInfo(info,exception);
3889 if (items == 2)
3890 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3891 else
3892 if (items > 2)
3893 for (i=2; i < items; i+=2)
3894 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3895 exception);
3896 (void) DisplayImages(package_info->image_info,image,exception);
3897 (void) CatchImageException(image);
3898
3899 PerlException:
3900 if (package_info != (struct PackageInfo *) NULL)
3901 DestroyPackageInfo(package_info);
3902 InheritPerlException(exception,perl_exception);
3903 exception=DestroyExceptionInfo(exception);
3904 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3905 SvPOK_on(perl_exception);
3906 ST(0)=sv_2mortal(perl_exception);
3907 XSRETURN(1);
3908 }
3909
3910#
3911###############################################################################
3912# #
3913# #
3914# #
3915# E v a l u a t e I m a g e s #
3916# #
3917# #
3918# #
3919###############################################################################
3920#
3921#
3922void
3923EvaluateImages(ref)
3924 Image::Magick ref=NO_INIT
3925 ALIAS:
3926 EvaluateImages = 1
3927 evaluateimages = 2
3928 PPCODE:
3929 {
3930 AV
3931 *av;
3932
3933 char
3934 *attribute,
3935 *p;
3936
3937 ExceptionInfo
3938 *exception;
3939
3940 HV
3941 *hv;
3942
3943 Image
3944 *image;
3945
3946 MagickEvaluateOperator
3947 op;
3948
3949 register ssize_t
3950 i;
3951
3952 struct PackageInfo
3953 *info;
3954
3955 SV
3956 *perl_exception,
3957 *reference,
3958 *rv,
3959 *sv;
3960
3961 PERL_UNUSED_VAR(ref);
3962 PERL_UNUSED_VAR(ix);
3963 exception=AcquireExceptionInfo();
3964 perl_exception=newSVpv("",0);
3965 sv=NULL;
3966 if (sv_isobject(ST(0)) == 0)
3967 {
3968 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3969 PackageName);
3970 goto PerlException;
3971 }
3972 reference=SvRV(ST(0));
3973 hv=SvSTASH(reference);
3974 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3975 if (image == (Image *) NULL)
3976 {
3977 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3978 PackageName);
3979 goto PerlException;
3980 }
3981 op=MeanEvaluateOperator;
3982 if (items == 2)
3983 {
3984 ssize_t
3985 in;
3986
3987 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
3988 SvPV(ST(1),na));
3989 if (in < 0)
3990 {
3991 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3992 SvPV(ST(1),na));
3993 return;
3994 }
3995 op=(MagickEvaluateOperator) in;
3996 }
3997 else
3998 for (i=2; i < items; i+=2)
3999 {
4000 attribute=(char *) SvPV(ST(i-1),na);
4001 switch (*attribute)
4002 {
4003 case 'O':
4004 case 'o':
4005 {
4006 if (LocaleCompare(attribute,"operator") == 0)
4007 {
4008 ssize_t
4009 in;
4010
4011 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4012 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4013 if (in < 0)
4014 {
4015 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4016 SvPV(ST(i),na));
4017 return;
4018 }
4019 op=(MagickEvaluateOperator) in;
4020 break;
4021 }
4022 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4023 attribute);
4024 break;
4025 }
4026 default:
4027 {
4028 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4029 attribute);
4030 break;
4031 }
4032 }
4033 }
4034 image=EvaluateImages(image,op,exception);
4035 if (image == (Image *) NULL)
4036 goto PerlException;
4037 /*
4038 Create blessed Perl array for the returned image.
4039 */
4040 av=newAV();
4041 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4042 SvREFCNT_dec(av);
4043 AddImageToRegistry(sv,image);
4044 rv=newRV(sv);
4045 av_push(av,sv_bless(rv,hv));
4046 SvREFCNT_dec(sv);
4047 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004048 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4049 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004050 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4051 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004052 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004053 SetImageInfo(info->image_info,0,exception);
4054 exception=DestroyExceptionInfo(exception);
4055 SvREFCNT_dec(perl_exception);
4056 XSRETURN(1);
4057
4058 PerlException:
4059 InheritPerlException(exception,perl_exception);
4060 exception=DestroyExceptionInfo(exception);
4061 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4062 SvPOK_on(perl_exception);
4063 ST(0)=sv_2mortal(perl_exception);
4064 XSRETURN(1);
4065 }
4066
4067#
4068###############################################################################
4069# #
4070# #
4071# #
4072# F e a t u r e s #
4073# #
4074# #
4075# #
4076###############################################################################
4077#
4078#
4079void
4080Features(ref,...)
4081 Image::Magick ref=NO_INIT
4082 ALIAS:
4083 FeaturesImage = 1
4084 features = 2
4085 featuresimage = 3
4086 PPCODE:
4087 {
4088#define ChannelFeatures(channel,direction) \
4089{ \
cristy151b66d2015-04-15 10:50:31 +00004090 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004091 channel_features[channel].angular_second_moment[direction]); \
4092 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004093 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004094 channel_features[channel].contrast[direction]); \
4095 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004096 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004097 channel_features[channel].contrast[direction]); \
4098 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004099 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004100 channel_features[channel].variance_sum_of_squares[direction]); \
4101 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004102 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004103 channel_features[channel].inverse_difference_moment[direction]); \
4104 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004105 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004106 channel_features[channel].sum_average[direction]); \
4107 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004108 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004109 channel_features[channel].sum_variance[direction]); \
4110 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004111 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004112 channel_features[channel].sum_entropy[direction]); \
4113 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004114 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004115 channel_features[channel].entropy[direction]); \
4116 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004117 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004118 channel_features[channel].difference_variance[direction]); \
4119 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004120 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004121 channel_features[channel].difference_entropy[direction]); \
4122 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004123 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004124 channel_features[channel].measure_of_correlation_1[direction]); \
4125 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004126 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004127 channel_features[channel].measure_of_correlation_2[direction]); \
4128 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004129 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004130 channel_features[channel].maximum_correlation_coefficient[direction]); \
4131 PUSHs(sv_2mortal(newSVpv(message,0))); \
4132}
4133
4134 AV
4135 *av;
4136
4137 char
4138 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004139 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004140
4141 ChannelFeatures
4142 *channel_features;
4143
4144 double
4145 distance;
4146
4147 ExceptionInfo
4148 *exception;
4149
4150 Image
4151 *image;
4152
4153 register ssize_t
4154 i;
4155
4156 ssize_t
4157 count;
4158
4159 struct PackageInfo
4160 *info;
4161
4162 SV
4163 *perl_exception,
4164 *reference;
4165
4166 PERL_UNUSED_VAR(ref);
4167 PERL_UNUSED_VAR(ix);
4168 exception=AcquireExceptionInfo();
4169 perl_exception=newSVpv("",0);
4170 av=NULL;
4171 if (sv_isobject(ST(0)) == 0)
4172 {
4173 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4174 PackageName);
4175 goto PerlException;
4176 }
4177 reference=SvRV(ST(0));
4178 av=newAV();
4179 SvREFCNT_dec(av);
4180 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4181 if (image == (Image *) NULL)
4182 {
4183 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4184 PackageName);
4185 goto PerlException;
4186 }
cristy7dbd9262014-07-02 17:53:42 +00004187 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004188 for (i=2; i < items; i+=2)
4189 {
4190 attribute=(char *) SvPV(ST(i-1),na);
4191 switch (*attribute)
4192 {
4193 case 'D':
4194 case 'd':
4195 {
4196 if (LocaleCompare(attribute,"distance") == 0)
4197 {
4198 distance=StringToLong((char *) SvPV(ST(1),na));
4199 break;
4200 }
4201 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4202 attribute);
4203 break;
4204 }
4205 default:
4206 {
4207 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4208 attribute);
4209 break;
4210 }
4211 }
4212 }
4213 count=0;
4214 for ( ; image; image=image->next)
4215 {
4216 channel_features=GetImageFeatures(image,distance,exception);
4217 if (channel_features == (ChannelFeatures *) NULL)
4218 continue;
4219 count++;
cristyfcf3bdf2014-07-02 14:35:58 +00004220 EXTEND(sp,280*count);
cristy4a3ce0a2013-08-03 20:06:59 +00004221 for (i=0; i < 4; i++)
4222 {
4223 ChannelFeatures(RedChannel,i);
4224 ChannelFeatures(GreenChannel,i);
4225 ChannelFeatures(BlueChannel,i);
4226 if (image->colorspace == CMYKColorspace)
4227 ChannelFeatures(BlackChannel,i);
cristy17f11b02014-12-20 19:37:04 +00004228 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00004229 ChannelFeatures(AlphaChannel,i);
4230 }
4231 channel_features=(ChannelFeatures *)
4232 RelinquishMagickMemory(channel_features);
4233 }
4234
4235 PerlException:
4236 InheritPerlException(exception,perl_exception);
4237 exception=DestroyExceptionInfo(exception);
4238 SvREFCNT_dec(perl_exception);
4239 }
4240
4241#
4242###############################################################################
4243# #
4244# #
4245# #
4246# F l a t t e n #
4247# #
4248# #
4249# #
4250###############################################################################
4251#
4252#
4253void
4254Flatten(ref)
4255 Image::Magick ref=NO_INIT
4256 ALIAS:
4257 FlattenImage = 1
4258 flatten = 2
4259 flattenimage = 3
4260 PPCODE:
4261 {
4262 AV
4263 *av;
4264
4265 char
4266 *attribute,
4267 *p;
4268
4269 ExceptionInfo
4270 *exception;
4271
4272 HV
4273 *hv;
4274
4275 Image
4276 *image;
4277
4278 PixelInfo
4279 background_color;
4280
4281 register ssize_t
4282 i;
4283
4284 struct PackageInfo
4285 *info;
4286
4287 SV
4288 *perl_exception,
4289 *reference,
4290 *rv,
4291 *sv;
4292
4293 PERL_UNUSED_VAR(ref);
4294 PERL_UNUSED_VAR(ix);
4295 exception=AcquireExceptionInfo();
4296 perl_exception=newSVpv("",0);
4297 sv=NULL;
4298 if (sv_isobject(ST(0)) == 0)
4299 {
4300 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4301 PackageName);
4302 goto PerlException;
4303 }
4304 reference=SvRV(ST(0));
4305 hv=SvSTASH(reference);
4306 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4307 if (image == (Image *) NULL)
4308 {
4309 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4310 PackageName);
4311 goto PerlException;
4312 }
4313 background_color=image->background_color;
4314 if (items == 2)
4315 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4316 &background_color,exception);
4317 else
4318 for (i=2; i < items; i+=2)
4319 {
4320 attribute=(char *) SvPV(ST(i-1),na);
4321 switch (*attribute)
4322 {
4323 case 'B':
4324 case 'b':
4325 {
4326 if (LocaleCompare(attribute,"background") == 0)
4327 {
4328 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4329 AllCompliance,&background_color,exception);
4330 break;
4331 }
4332 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4333 attribute);
4334 break;
4335 }
4336 default:
4337 {
4338 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4339 attribute);
4340 break;
4341 }
4342 }
4343 }
4344 image->background_color=background_color;
4345 image=MergeImageLayers(image,FlattenLayer,exception);
4346 if (image == (Image *) NULL)
4347 goto PerlException;
4348 /*
4349 Create blessed Perl array for the returned image.
4350 */
4351 av=newAV();
4352 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4353 SvREFCNT_dec(av);
4354 AddImageToRegistry(sv,image);
4355 rv=newRV(sv);
4356 av_push(av,sv_bless(rv,hv));
4357 SvREFCNT_dec(sv);
4358 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004359 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4360 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004361 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4362 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004363 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004364 SetImageInfo(info->image_info,0,exception);
4365 exception=DestroyExceptionInfo(exception);
4366 SvREFCNT_dec(perl_exception);
4367 XSRETURN(1);
4368
4369 PerlException:
4370 InheritPerlException(exception,perl_exception);
4371 exception=DestroyExceptionInfo(exception);
4372 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4373 SvPOK_on(perl_exception); /* return messages in string context */
4374 ST(0)=sv_2mortal(perl_exception);
4375 XSRETURN(1);
4376 }
4377
4378#
4379###############################################################################
4380# #
4381# #
4382# #
4383# F x #
4384# #
4385# #
4386# #
4387###############################################################################
4388#
4389#
4390void
4391Fx(ref,...)
4392 Image::Magick ref=NO_INIT
4393 ALIAS:
4394 FxImage = 1
4395 fx = 2
4396 fximage = 3
4397 PPCODE:
4398 {
4399 AV
4400 *av;
4401
4402 char
4403 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004404 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004405
4406 ChannelType
4407 channel,
4408 channel_mask;
4409
4410 ExceptionInfo
4411 *exception;
4412
4413 HV
4414 *hv;
4415
4416 Image
4417 *image;
4418
4419 register ssize_t
4420 i;
4421
4422 struct PackageInfo
4423 *info;
4424
4425 SV
4426 *av_reference,
4427 *perl_exception,
4428 *reference,
4429 *rv,
4430 *sv;
4431
4432 PERL_UNUSED_VAR(ref);
4433 PERL_UNUSED_VAR(ix);
4434 exception=AcquireExceptionInfo();
4435 perl_exception=newSVpv("",0);
4436 sv=NULL;
4437 attribute=NULL;
4438 av=NULL;
4439 if (sv_isobject(ST(0)) == 0)
4440 {
4441 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4442 PackageName);
4443 goto PerlException;
4444 }
4445 reference=SvRV(ST(0));
4446 hv=SvSTASH(reference);
4447 av=newAV();
4448 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4449 SvREFCNT_dec(av);
4450 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4451 if (image == (Image *) NULL)
4452 {
4453 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4454 PackageName);
4455 goto PerlException;
4456 }
4457 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4458 /*
4459 Get options.
4460 */
4461 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004462 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004463 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004464 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004465 else
4466 for (i=2; i < items; i+=2)
4467 {
4468 attribute=(char *) SvPV(ST(i-1),na);
4469 switch (*attribute)
4470 {
4471 case 'C':
4472 case 'c':
4473 {
4474 if (LocaleCompare(attribute,"channel") == 0)
4475 {
4476 ssize_t
4477 option;
4478
4479 option=ParseChannelOption(SvPV(ST(i),na));
4480 if (option < 0)
4481 {
4482 ThrowPerlException(exception,OptionError,
4483 "UnrecognizedType",SvPV(ST(i),na));
4484 return;
4485 }
4486 channel=(ChannelType) option;
4487 break;
4488 }
4489 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4490 attribute);
4491 break;
4492 }
4493 case 'E':
4494 case 'e':
4495 {
4496 if (LocaleCompare(attribute,"expression") == 0)
4497 {
4498 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004499 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004500 break;
4501 }
4502 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4503 attribute);
4504 break;
4505 }
4506 default:
4507 {
4508 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4509 attribute);
4510 break;
4511 }
4512 }
4513 }
4514 channel_mask=SetImageChannelMask(image,channel);
4515 image=FxImage(image,expression,exception);
4516 if (image != (Image *) NULL)
4517 (void) SetImageChannelMask(image,channel_mask);
4518 if (image == (Image *) NULL)
4519 goto PerlException;
4520 for ( ; image; image=image->next)
4521 {
4522 AddImageToRegistry(sv,image);
4523 rv=newRV(sv);
4524 av_push(av,sv_bless(rv,hv));
4525 SvREFCNT_dec(sv);
4526 }
4527 exception=DestroyExceptionInfo(exception);
4528 ST(0)=av_reference;
4529 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4530 XSRETURN(1);
4531
4532 PerlException:
4533 InheritPerlException(exception,perl_exception);
4534 exception=DestroyExceptionInfo(exception);
4535 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4536 SvPOK_on(perl_exception);
4537 ST(0)=sv_2mortal(perl_exception);
4538 XSRETURN(1);
4539 }
4540
4541#
4542###############################################################################
4543# #
4544# #
4545# #
4546# G e t #
4547# #
4548# #
4549# #
4550###############################################################################
4551#
4552#
4553void
4554Get(ref,...)
4555 Image::Magick ref=NO_INIT
4556 ALIAS:
4557 GetAttributes = 1
4558 GetAttribute = 2
4559 get = 3
4560 getattributes = 4
4561 getattribute = 5
4562 PPCODE:
4563 {
4564 char
4565 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004566 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004567
4568 const char
4569 *value;
4570
4571 ExceptionInfo
4572 *exception;
4573
4574 Image
4575 *image;
4576
4577 long
4578 j;
4579
4580 register ssize_t
4581 i;
4582
4583 struct PackageInfo
4584 *info;
4585
4586 SV
4587 *perl_exception,
4588 *reference,
4589 *s;
4590
4591 PERL_UNUSED_VAR(ref);
4592 PERL_UNUSED_VAR(ix);
4593 exception=AcquireExceptionInfo();
4594 perl_exception=newSVpv("",0);
4595 if (sv_isobject(ST(0)) == 0)
4596 {
4597 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4598 PackageName);
4599 XSRETURN_EMPTY;
4600 }
4601 reference=SvRV(ST(0));
4602 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4603 if (image == (Image *) NULL && !info)
4604 XSRETURN_EMPTY;
4605 EXTEND(sp,items);
4606 for (i=1; i < items; i++)
4607 {
4608 attribute=(char *) SvPV(ST(i),na);
4609 s=NULL;
4610 switch (*attribute)
4611 {
4612 case 'A':
4613 case 'a':
4614 {
4615 if (LocaleCompare(attribute,"adjoin") == 0)
4616 {
4617 if (info)
4618 s=newSViv((ssize_t) info->image_info->adjoin);
4619 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4620 continue;
4621 }
4622 if (LocaleCompare(attribute,"antialias") == 0)
4623 {
4624 if (info)
4625 s=newSViv((ssize_t) info->image_info->antialias);
4626 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4627 continue;
4628 }
4629 if (LocaleCompare(attribute,"area") == 0)
4630 {
4631 s=newSViv(GetMagickResource(AreaResource));
4632 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4633 continue;
4634 }
4635 if (LocaleCompare(attribute,"attenuate") == 0)
4636 {
4637 const char
4638 *value;
4639
4640 value=GetImageProperty(image,attribute,exception);
4641 if (value != (const char *) NULL)
4642 s=newSVpv(value,0);
4643 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4644 continue;
4645 }
4646 if (LocaleCompare(attribute,"authenticate") == 0)
4647 {
4648 if (info)
4649 {
4650 const char
4651 *option;
4652
4653 option=GetImageOption(info->image_info,attribute);
4654 if (option != (const char *) NULL)
4655 s=newSVpv(option,0);
4656 }
4657 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4658 continue;
4659 }
4660 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4661 attribute);
4662 break;
4663 }
4664 case 'B':
4665 case 'b':
4666 {
4667 if (LocaleCompare(attribute,"background") == 0)
4668 {
4669 if (image == (Image *) NULL)
4670 break;
cristy151b66d2015-04-15 10:50:31 +00004671 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004672 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4673 (double) image->background_color.green,
4674 (double) image->background_color.blue,
4675 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004676 s=newSVpv(color,0);
4677 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4678 continue;
4679 }
4680 if (LocaleCompare(attribute,"base-columns") == 0)
4681 {
4682 if (image != (Image *) NULL)
4683 s=newSViv((ssize_t) image->magick_columns);
4684 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4685 continue;
4686 }
4687 if (LocaleCompare(attribute,"base-filename") == 0)
4688 {
4689 if (image != (Image *) NULL)
4690 s=newSVpv(image->magick_filename,0);
4691 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4692 continue;
4693 }
4694 if (LocaleCompare(attribute,"base-height") == 0)
4695 {
4696 if (image != (Image *) NULL)
4697 s=newSViv((ssize_t) image->magick_rows);
4698 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4699 continue;
4700 }
4701 if (LocaleCompare(attribute,"base-rows") == 0)
4702 {
4703 if (image != (Image *) NULL)
4704 s=newSViv((ssize_t) image->magick_rows);
4705 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4706 continue;
4707 }
4708 if (LocaleCompare(attribute,"base-width") == 0)
4709 {
4710 if (image != (Image *) NULL)
4711 s=newSViv((ssize_t) image->magick_columns);
4712 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4713 continue;
4714 }
4715 if (LocaleCompare(attribute,"blue-primary") == 0)
4716 {
4717 if (image == (Image *) NULL)
4718 break;
cristy151b66d2015-04-15 10:50:31 +00004719 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00004720 image->chromaticity.blue_primary.x,
4721 image->chromaticity.blue_primary.y);
4722 s=newSVpv(color,0);
4723 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4724 continue;
4725 }
4726 if (LocaleCompare(attribute,"bordercolor") == 0)
4727 {
4728 if (image == (Image *) NULL)
4729 break;
cristy151b66d2015-04-15 10:50:31 +00004730 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004731 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4732 (double) image->border_color.green,
4733 (double) image->border_color.blue,
4734 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004735 s=newSVpv(color,0);
4736 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4737 continue;
4738 }
4739 if (LocaleCompare(attribute,"bounding-box") == 0)
4740 {
4741 char
cristy151b66d2015-04-15 10:50:31 +00004742 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004743
4744 RectangleInfo
4745 page;
4746
4747 if (image == (Image *) NULL)
4748 break;
4749 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004750 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004751 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4752 page.height,(double) page.x,(double) page.y);
4753 s=newSVpv(geometry,0);
4754 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4755 continue;
4756 }
4757 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4758 attribute);
4759 break;
4760 }
4761 case 'C':
4762 case 'c':
4763 {
4764 if (LocaleCompare(attribute,"class") == 0)
4765 {
4766 if (image == (Image *) NULL)
4767 break;
4768 s=newSViv(image->storage_class);
4769 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4770 image->storage_class));
4771 SvIOK_on(s);
4772 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4773 continue;
4774 }
4775 if (LocaleCompare(attribute,"clip-mask") == 0)
4776 {
4777 if (image != (Image *) NULL)
4778 {
4779 Image
4780 *mask_image;
4781
4782 SV
4783 *sv;
4784
4785 sv=NULL;
4786 if (image->read_mask == MagickFalse)
4787 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004788 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004789 if (mask_image != (Image *) NULL)
4790 {
4791 AddImageToRegistry(sv,mask_image);
4792 s=sv_bless(newRV(sv),SvSTASH(reference));
4793 }
4794 }
4795 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4796 continue;
4797 }
4798 if (LocaleCompare(attribute,"clip-path") == 0)
4799 {
4800 if (image != (Image *) NULL)
4801 {
4802 Image
4803 *mask_image;
4804
4805 SV
4806 *sv;
4807
4808 sv=NULL;
4809 if (image->read_mask != MagickFalse)
4810 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004811 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004812 if (mask_image != (Image *) NULL)
4813 {
4814 AddImageToRegistry(sv,mask_image);
4815 s=sv_bless(newRV(sv),SvSTASH(reference));
4816 }
4817 }
4818 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4819 continue;
4820 }
4821 if (LocaleCompare(attribute,"compression") == 0)
4822 {
4823 j=info ? info->image_info->compression : image ?
4824 image->compression : UndefinedCompression;
4825 if (info)
4826 if (info->image_info->compression == UndefinedCompression)
4827 j=image->compression;
4828 s=newSViv(j);
4829 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4830 j));
4831 SvIOK_on(s);
4832 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4833 continue;
4834 }
4835 if (LocaleCompare(attribute,"colorspace") == 0)
4836 {
4837 j=image ? image->colorspace : RGBColorspace;
4838 s=newSViv(j);
4839 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4840 j));
4841 SvIOK_on(s);
4842 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4843 continue;
4844 }
4845 if (LocaleCompare(attribute,"colors") == 0)
4846 {
4847 if (image != (Image *) NULL)
4848 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4849 exception));
4850 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4851 continue;
4852 }
4853 if (LocaleNCompare(attribute,"colormap",8) == 0)
4854 {
4855 int
4856 items;
4857
4858 if (image == (Image *) NULL || !image->colormap)
4859 break;
4860 j=0;
4861 items=sscanf(attribute,"%*[^[][%ld",&j);
4862 (void) items;
4863 if (j > (ssize_t) image->colors)
4864 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004865 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004866 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4867 (double) image->colormap[j].green,
4868 (double) image->colormap[j].blue,
4869 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004870 s=newSVpv(color,0);
4871 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4872 continue;
4873 }
4874 if (LocaleCompare(attribute,"columns") == 0)
4875 {
4876 if (image != (Image *) NULL)
4877 s=newSViv((ssize_t) image->columns);
4878 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4879 continue;
4880 }
4881 if (LocaleCompare(attribute,"comment") == 0)
4882 {
4883 const char
4884 *value;
4885
4886 value=GetImageProperty(image,attribute,exception);
4887 if (value != (const char *) NULL)
4888 s=newSVpv(value,0);
4889 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4890 continue;
4891 }
4892 if (LocaleCompare(attribute,"copyright") == 0)
4893 {
4894 s=newSVpv(GetMagickCopyright(),0);
4895 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4896 continue;
4897 }
4898 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4899 attribute);
4900 break;
4901 }
4902 case 'D':
4903 case 'd':
4904 {
4905 if (LocaleCompare(attribute,"density") == 0)
4906 {
4907 char
cristy151b66d2015-04-15 10:50:31 +00004908 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004909
4910 if (image == (Image *) NULL)
4911 break;
cristy151b66d2015-04-15 10:50:31 +00004912 (void) FormatLocaleString(geometry,MagickPathExtent,"%.15gx%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00004913 image->resolution.x,image->resolution.y);
4914 s=newSVpv(geometry,0);
4915 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4916 continue;
4917 }
4918 if (LocaleCompare(attribute,"delay") == 0)
4919 {
4920 if (image != (Image *) NULL)
4921 s=newSViv((ssize_t) image->delay);
4922 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4923 continue;
4924 }
4925 if (LocaleCompare(attribute,"depth") == 0)
4926 {
4927 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4928 if (image != (Image *) NULL)
4929 s=newSViv((ssize_t) GetImageDepth(image,exception));
4930 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4931 continue;
4932 }
4933 if (LocaleCompare(attribute,"directory") == 0)
4934 {
4935 if (image && image->directory)
4936 s=newSVpv(image->directory,0);
4937 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4938 continue;
4939 }
4940 if (LocaleCompare(attribute,"dispose") == 0)
4941 {
4942 if (image == (Image *) NULL)
4943 break;
4944
4945 s=newSViv(image->dispose);
4946 (void) sv_setpv(s,
4947 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
4948 SvIOK_on(s);
4949 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4950 continue;
4951 }
4952 if (LocaleCompare(attribute,"disk") == 0)
4953 {
4954 s=newSViv(GetMagickResource(DiskResource));
4955 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4956 continue;
4957 }
4958 if (LocaleCompare(attribute,"dither") == 0)
4959 {
4960 if (info)
4961 s=newSViv((ssize_t) info->image_info->dither);
4962 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4963 continue;
4964 }
4965 if (LocaleCompare(attribute,"display") == 0) /* same as server */
4966 {
4967 if (info && info->image_info->server_name)
4968 s=newSVpv(info->image_info->server_name,0);
4969 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4970 continue;
4971 }
4972 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4973 attribute);
4974 break;
4975 }
4976 case 'E':
4977 case 'e':
4978 {
4979 if (LocaleCompare(attribute,"elapsed-time") == 0)
4980 {
4981 if (image != (Image *) NULL)
4982 s=newSVnv(GetElapsedTime(&image->timer));
4983 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4984 continue;
4985 }
4986 if (LocaleCompare(attribute,"endian") == 0)
4987 {
4988 j=info ? info->image_info->endian : image ? image->endian :
4989 UndefinedEndian;
4990 s=newSViv(j);
4991 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
4992 SvIOK_on(s);
4993 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4994 continue;
4995 }
4996 if (LocaleCompare(attribute,"error") == 0)
4997 {
4998 if (image != (Image *) NULL)
4999 s=newSVnv(image->error.mean_error_per_pixel);
5000 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5001 continue;
5002 }
5003 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5004 attribute);
5005 break;
5006 }
5007 case 'F':
5008 case 'f':
5009 {
5010 if (LocaleCompare(attribute,"filesize") == 0)
5011 {
5012 if (image != (Image *) NULL)
5013 s=newSViv((ssize_t) GetBlobSize(image));
5014 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5015 continue;
5016 }
5017 if (LocaleCompare(attribute,"filename") == 0)
5018 {
5019 if (info && info->image_info->filename &&
5020 *info->image_info->filename)
5021 s=newSVpv(info->image_info->filename,0);
5022 if (image != (Image *) NULL)
5023 s=newSVpv(image->filename,0);
5024 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5025 continue;
5026 }
5027 if (LocaleCompare(attribute,"filter") == 0)
5028 {
5029 s=image ? newSViv(image->filter) : newSViv(0);
5030 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5031 image->filter));
5032 SvIOK_on(s);
5033 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5034 continue;
5035 }
5036 if (LocaleCompare(attribute,"font") == 0)
5037 {
5038 if (info && info->image_info->font)
5039 s=newSVpv(info->image_info->font,0);
5040 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5041 continue;
5042 }
5043 if (LocaleCompare(attribute,"foreground") == 0)
5044 continue;
5045 if (LocaleCompare(attribute,"format") == 0)
5046 {
5047 const MagickInfo
5048 *magick_info;
5049
5050 magick_info=(const MagickInfo *) NULL;
5051 if (info && (*info->image_info->magick != '\0'))
5052 magick_info=GetMagickInfo(info->image_info->magick,exception);
5053 if (image != (Image *) NULL)
5054 magick_info=GetMagickInfo(image->magick,exception);
5055 if ((magick_info != (const MagickInfo *) NULL) &&
5056 (*magick_info->description != '\0'))
5057 s=newSVpv((char *) magick_info->description,0);
5058 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5059 continue;
5060 }
5061 if (LocaleCompare(attribute,"fuzz") == 0)
5062 {
5063 if (info)
5064 s=newSVnv(info->image_info->fuzz);
5065 if (image != (Image *) NULL)
5066 s=newSVnv(image->fuzz);
5067 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5068 continue;
5069 }
5070 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5071 attribute);
5072 break;
5073 }
5074 case 'G':
5075 case 'g':
5076 {
5077 if (LocaleCompare(attribute,"gamma") == 0)
5078 {
5079 if (image != (Image *) NULL)
5080 s=newSVnv(image->gamma);
5081 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5082 continue;
5083 }
5084 if (LocaleCompare(attribute,"geometry") == 0)
5085 {
5086 if (image && image->geometry)
5087 s=newSVpv(image->geometry,0);
5088 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5089 continue;
5090 }
5091 if (LocaleCompare(attribute,"gravity") == 0)
5092 {
5093 s=image ? newSViv(image->gravity) : newSViv(0);
5094 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5095 image->gravity));
5096 SvIOK_on(s);
5097 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5098 continue;
5099 }
5100 if (LocaleCompare(attribute,"green-primary") == 0)
5101 {
5102 if (image == (Image *) NULL)
5103 break;
cristy151b66d2015-04-15 10:50:31 +00005104 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005105 image->chromaticity.green_primary.x,
5106 image->chromaticity.green_primary.y);
5107 s=newSVpv(color,0);
5108 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5109 continue;
5110 }
5111 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5112 attribute);
5113 break;
5114 }
5115 case 'H':
5116 case 'h':
5117 {
5118 if (LocaleCompare(attribute,"height") == 0)
5119 {
5120 if (image != (Image *) NULL)
5121 s=newSViv((ssize_t) image->rows);
5122 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5123 continue;
5124 }
5125 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5126 attribute);
5127 break;
5128 }
5129 case 'I':
5130 case 'i':
5131 {
5132 if (LocaleCompare(attribute,"icc") == 0)
5133 {
5134 if (image != (Image *) NULL)
5135 {
5136 const StringInfo
5137 *profile;
5138
5139 profile=GetImageProfile(image,"icc");
5140 if (profile != (StringInfo *) NULL)
5141 s=newSVpv((const char *) GetStringInfoDatum(profile),
5142 GetStringInfoLength(profile));
5143 }
5144 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5145 continue;
5146 }
5147 if (LocaleCompare(attribute,"icm") == 0)
5148 {
5149 if (image != (Image *) NULL)
5150 {
5151 const StringInfo
5152 *profile;
5153
5154 profile=GetImageProfile(image,"icm");
5155 if (profile != (const StringInfo *) NULL)
5156 s=newSVpv((const char *) GetStringInfoDatum(profile),
5157 GetStringInfoLength(profile));
5158 }
5159 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5160 continue;
5161 }
5162 if (LocaleCompare(attribute,"id") == 0)
5163 {
5164 if (image != (Image *) NULL)
5165 {
5166 char
cristy151b66d2015-04-15 10:50:31 +00005167 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005168
5169 MagickBooleanType
5170 status;
5171
5172 static ssize_t
5173 id = 0;
5174
cristy151b66d2015-04-15 10:50:31 +00005175 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005176 id);
5177 status=SetImageRegistry(ImageRegistryType,key,image,
5178 exception);
5179 (void) status;
5180 s=newSViv(id++);
5181 }
5182 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5183 continue;
5184 }
5185 if (LocaleNCompare(attribute,"index",5) == 0)
5186 {
5187 char
cristy151b66d2015-04-15 10:50:31 +00005188 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005189
5190 int
5191 items;
5192
5193 long
5194 x,
5195 y;
5196
5197 register const Quantum
5198 *p;
5199
5200 CacheView
5201 *image_view;
5202
5203 if (image == (Image *) NULL)
5204 break;
5205 if (image->storage_class != PseudoClass)
5206 break;
5207 x=0;
5208 y=0;
5209 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5210 (void) items;
5211 image_view=AcquireVirtualCacheView(image,exception);
5212 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5213 if (p != (const Quantum *) NULL)
5214 {
cristy151b66d2015-04-15 10:50:31 +00005215 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005216 GetPixelIndex(image,p));
5217 s=newSVpv(name,0);
5218 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5219 }
5220 image_view=DestroyCacheView(image_view);
5221 continue;
5222 }
5223 if (LocaleCompare(attribute,"iptc") == 0)
5224 {
5225 if (image != (Image *) NULL)
5226 {
5227 const StringInfo
5228 *profile;
5229
5230 profile=GetImageProfile(image,"iptc");
5231 if (profile != (const StringInfo *) NULL)
5232 s=newSVpv((const char *) GetStringInfoDatum(profile),
5233 GetStringInfoLength(profile));
5234 }
5235 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5236 continue;
5237 }
5238 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5239 {
5240 if (image != (Image *) NULL)
5241 s=newSViv((ssize_t) image->iterations);
5242 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5243 continue;
5244 }
5245 if (LocaleCompare(attribute,"interlace") == 0)
5246 {
5247 j=info ? info->image_info->interlace : image ? image->interlace :
5248 UndefinedInterlace;
5249 s=newSViv(j);
5250 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5251 j));
5252 SvIOK_on(s);
5253 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5254 continue;
5255 }
5256 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5257 attribute);
5258 break;
5259 }
5260 case 'L':
5261 case 'l':
5262 {
5263 if (LocaleCompare(attribute,"label") == 0)
5264 {
5265 const char
5266 *value;
5267
5268 if (image == (Image *) NULL)
5269 break;
5270 value=GetImageProperty(image,"Label",exception);
5271 if (value != (const char *) NULL)
5272 s=newSVpv(value,0);
5273 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5274 continue;
5275 }
5276 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5277 {
5278 if (image != (Image *) NULL)
5279 s=newSViv((ssize_t) image->iterations);
5280 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5281 continue;
5282 }
5283 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5284 attribute);
5285 break;
5286 }
5287 case 'M':
5288 case 'm':
5289 {
5290 if (LocaleCompare(attribute,"magick") == 0)
5291 {
5292 if (info && *info->image_info->magick)
5293 s=newSVpv(info->image_info->magick,0);
5294 if (image != (Image *) NULL)
5295 s=newSVpv(image->magick,0);
5296 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5297 continue;
5298 }
5299 if (LocaleCompare(attribute,"map") == 0)
5300 {
5301 s=newSViv(GetMagickResource(MapResource));
5302 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5303 continue;
5304 }
5305 if (LocaleCompare(attribute,"maximum-error") == 0)
5306 {
5307 if (image != (Image *) NULL)
5308 s=newSVnv(image->error.normalized_maximum_error);
5309 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5310 continue;
5311 }
5312 if (LocaleCompare(attribute,"memory") == 0)
5313 {
5314 s=newSViv(GetMagickResource(MemoryResource));
5315 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5316 continue;
5317 }
5318 if (LocaleCompare(attribute,"mean-error") == 0)
5319 {
5320 if (image != (Image *) NULL)
5321 s=newSVnv(image->error.normalized_mean_error);
5322 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5323 continue;
5324 }
5325 if (LocaleCompare(attribute,"mime") == 0)
5326 {
5327 if (info && *info->image_info->magick)
5328 s=newSVpv(MagickToMime(info->image_info->magick),0);
5329 if (image != (Image *) NULL)
5330 s=newSVpv(MagickToMime(image->magick),0);
5331 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5332 continue;
5333 }
5334 if (LocaleCompare(attribute,"mattecolor") == 0)
5335 {
5336 if (image == (Image *) NULL)
5337 break;
cristy151b66d2015-04-15 10:50:31 +00005338 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005339 "%.20g,%.20g,%.20g,%.20g",(double) image->matte_color.red,
5340 (double) image->matte_color.green,
5341 (double) image->matte_color.blue,
5342 (double) image->matte_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005343 s=newSVpv(color,0);
5344 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5345 continue;
5346 }
5347 if (LocaleCompare(attribute,"matte") == 0)
5348 {
5349 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005350 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005351 1 : 0);
5352 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5353 continue;
5354 }
5355 if (LocaleCompare(attribute,"mime") == 0)
5356 {
5357 const char
5358 *magick;
5359
5360 magick=NULL;
5361 if (info && *info->image_info->magick)
5362 magick=info->image_info->magick;
5363 if (image != (Image *) NULL)
5364 magick=image->magick;
5365 if (magick)
5366 {
5367 char
5368 *mime;
5369
5370 mime=MagickToMime(magick);
5371 s=newSVpv(mime,0);
5372 mime=(char *) RelinquishMagickMemory(mime);
5373 }
5374 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5375 continue;
5376 }
5377 if (LocaleCompare(attribute,"monochrome") == 0)
5378 {
5379 if (image == (Image *) NULL)
5380 continue;
5381 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005382 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005383 s=newSViv(j);
5384 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5385 continue;
5386 }
5387 if (LocaleCompare(attribute,"montage") == 0)
5388 {
5389 if (image && image->montage)
5390 s=newSVpv(image->montage,0);
5391 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5392 continue;
5393 }
5394 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5395 attribute);
5396 break;
5397 }
5398 case 'O':
5399 case 'o':
5400 {
5401 if (LocaleCompare(attribute,"orientation") == 0)
5402 {
5403 j=info ? info->image_info->orientation : image ?
5404 image->orientation : UndefinedOrientation;
5405 s=newSViv(j);
5406 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5407 j));
5408 SvIOK_on(s);
5409 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5410 continue;
5411 }
5412 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5413 attribute);
5414 break;
5415 }
5416 case 'P':
5417 case 'p':
5418 {
5419 if (LocaleCompare(attribute,"page") == 0)
5420 {
5421 if (info && info->image_info->page)
5422 s=newSVpv(info->image_info->page,0);
5423 if (image != (Image *) NULL)
5424 {
5425 char
cristy151b66d2015-04-15 10:50:31 +00005426 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005427
cristy151b66d2015-04-15 10:50:31 +00005428 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005429 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5430 (double) image->page.height,(double) image->page.x,(double)
5431 image->page.y);
5432 s=newSVpv(geometry,0);
5433 }
5434 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5435 continue;
5436 }
5437 if (LocaleCompare(attribute,"page.x") == 0)
5438 {
5439 if (image != (Image *) NULL)
5440 s=newSViv((ssize_t) image->page.x);
5441 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5442 continue;
5443 }
5444 if (LocaleCompare(attribute,"page.y") == 0)
5445 {
5446 if (image != (Image *) NULL)
5447 s=newSViv((ssize_t) image->page.y);
5448 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5449 continue;
5450 }
5451 if (LocaleNCompare(attribute,"pixel",5) == 0)
5452 {
5453 char
cristy151b66d2015-04-15 10:50:31 +00005454 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005455
5456 int
5457 items;
5458
5459 long
5460 x,
5461 y;
5462
5463 register const Quantum
5464 *p;
5465
5466 if (image == (Image *) NULL)
5467 break;
5468 x=0;
5469 y=0;
5470 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5471 (void) items;
5472 p=GetVirtualPixels(image,x,y,1,1,exception);
5473 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005474 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005475 QuantumFormat "," QuantumFormat "," QuantumFormat,
5476 GetPixelRed(image,p),GetPixelGreen(image,p),
5477 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5478 else
cristy151b66d2015-04-15 10:50:31 +00005479 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005480 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5481 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5482 GetPixelBlue(image,p),GetPixelBlack(image,p),
5483 GetPixelAlpha(image,p));
5484 s=newSVpv(tuple,0);
5485 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5486 continue;
5487 }
5488 if (LocaleCompare(attribute,"pointsize") == 0)
5489 {
5490 if (info)
5491 s=newSViv((ssize_t) info->image_info->pointsize);
5492 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5493 continue;
5494 }
5495 if (LocaleCompare(attribute,"preview") == 0)
5496 {
5497 s=newSViv(info->image_info->preview_type);
5498 (void) sv_setpv(s,CommandOptionToMnemonic(MagickPreviewOptions,
5499 info->image_info->preview_type));
5500 SvIOK_on(s);
5501 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5502 continue;
5503 }
5504 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5505 attribute);
5506 break;
5507 }
5508 case 'Q':
5509 case 'q':
5510 {
5511 if (LocaleCompare(attribute,"quality") == 0)
5512 {
5513 if (info)
5514 s=newSViv((ssize_t) info->image_info->quality);
5515 if (image != (Image *) NULL)
5516 s=newSViv((ssize_t) image->quality);
5517 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5518 continue;
5519 }
5520 if (LocaleCompare(attribute,"quantum") == 0)
5521 {
5522 if (info)
5523 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5524 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5525 continue;
5526 }
5527 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5528 attribute);
5529 break;
5530 }
5531 case 'R':
5532 case 'r':
5533 {
5534 if (LocaleCompare(attribute,"rendering-intent") == 0)
5535 {
5536 s=newSViv(image->rendering_intent);
5537 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5538 image->rendering_intent));
5539 SvIOK_on(s);
5540 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5541 continue;
5542 }
5543 if (LocaleCompare(attribute,"red-primary") == 0)
5544 {
5545 if (image == (Image *) NULL)
5546 break;
cristy151b66d2015-04-15 10:50:31 +00005547 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005548 image->chromaticity.red_primary.x,
5549 image->chromaticity.red_primary.y);
5550 s=newSVpv(color,0);
5551 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5552 continue;
5553 }
5554 if (LocaleCompare(attribute,"rows") == 0)
5555 {
5556 if (image != (Image *) NULL)
5557 s=newSViv((ssize_t) image->rows);
5558 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5559 continue;
5560 }
5561 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5562 attribute);
5563 break;
5564 }
5565 case 'S':
5566 case 's':
5567 {
5568 if (LocaleCompare(attribute,"sampling-factor") == 0)
5569 {
5570 if (info && info->image_info->sampling_factor)
5571 s=newSVpv(info->image_info->sampling_factor,0);
5572 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5573 continue;
5574 }
5575 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5576 {
5577 if (info && info->image_info->server_name)
5578 s=newSVpv(info->image_info->server_name,0);
5579 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5580 continue;
5581 }
5582 if (LocaleCompare(attribute,"size") == 0)
5583 {
5584 if (info && info->image_info->size)
5585 s=newSVpv(info->image_info->size,0);
5586 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5587 continue;
5588 }
5589 if (LocaleCompare(attribute,"scene") == 0)
5590 {
5591 if (image != (Image *) NULL)
5592 s=newSViv((ssize_t) image->scene);
5593 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5594 continue;
5595 }
5596 if (LocaleCompare(attribute,"scenes") == 0)
5597 {
5598 if (image != (Image *) NULL)
5599 s=newSViv((ssize_t) info->image_info->number_scenes);
5600 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5601 continue;
5602 }
5603 if (LocaleCompare(attribute,"signature") == 0)
5604 {
5605 const char
5606 *value;
5607
5608 if (image == (Image *) NULL)
5609 break;
5610 (void) SignatureImage(image,exception);
5611 value=GetImageProperty(image,"Signature",exception);
5612 if (value != (const char *) NULL)
5613 s=newSVpv(value,0);
5614 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5615 continue;
5616 }
5617 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5618 attribute);
5619 break;
5620 }
5621 case 'T':
5622 case 't':
5623 {
5624 if (LocaleCompare(attribute,"taint") == 0)
5625 {
5626 if (image != (Image *) NULL)
5627 s=newSViv((ssize_t) IsTaintImage(image));
5628 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5629 continue;
5630 }
5631 if (LocaleCompare(attribute,"texture") == 0)
5632 {
5633 if (info && info->image_info->texture)
5634 s=newSVpv(info->image_info->texture,0);
5635 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5636 continue;
5637 }
5638 if (LocaleCompare(attribute,"total-ink-density") == 0)
5639 {
5640 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5641 if (image != (Image *) NULL)
5642 s=newSVnv(GetImageTotalInkDensity(image,exception));
5643 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5644 continue;
5645 }
5646 if (LocaleCompare(attribute,"transparent-color") == 0)
5647 {
5648 if (image == (Image *) NULL)
5649 break;
cristy151b66d2015-04-15 10:50:31 +00005650 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005651 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5652 (double) image->transparent_color.green,
5653 (double) image->transparent_color.blue,
5654 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005655 s=newSVpv(color,0);
5656 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5657 continue;
5658 }
5659 if (LocaleCompare(attribute,"type") == 0)
5660 {
5661 if (image == (Image *) NULL)
5662 break;
cristya26f54c2015-07-29 12:26:12 +00005663 j=(ssize_t) GetImageType(image);
cristy4a3ce0a2013-08-03 20:06:59 +00005664 s=newSViv(j);
5665 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5666 SvIOK_on(s);
5667 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5668 continue;
5669 }
5670 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5671 attribute);
5672 break;
5673 }
5674 case 'U':
5675 case 'u':
5676 {
5677 if (LocaleCompare(attribute,"units") == 0)
5678 {
5679 j=info ? info->image_info->units : image ? image->units :
5680 UndefinedResolution;
5681 if (info && (info->image_info->units == UndefinedResolution))
5682 if (image)
5683 j=image->units;
5684 if (j == UndefinedResolution)
5685 s=newSVpv("undefined units",0);
5686 else
5687 if (j == PixelsPerInchResolution)
5688 s=newSVpv("pixels / inch",0);
5689 else
5690 s=newSVpv("pixels / centimeter",0);
5691 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5692 continue;
5693 }
5694 if (LocaleCompare(attribute,"user-time") == 0)
5695 {
5696 if (image != (Image *) NULL)
5697 s=newSVnv(GetUserTime(&image->timer));
5698 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5699 continue;
5700 }
5701 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5702 attribute);
5703 break;
5704 }
5705 case 'V':
5706 case 'v':
5707 {
5708 if (LocaleCompare(attribute,"verbose") == 0)
5709 {
5710 if (info)
5711 s=newSViv((ssize_t) info->image_info->verbose);
5712 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5713 continue;
5714 }
5715 if (LocaleCompare(attribute,"version") == 0)
5716 {
5717 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5718 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5719 continue;
5720 }
5721 if (LocaleCompare(attribute,"view") == 0)
5722 {
5723 if (info && info->image_info->view)
5724 s=newSVpv(info->image_info->view,0);
5725 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5726 continue;
5727 }
5728 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5729 {
5730 if (image == (Image *) NULL)
5731 break;
5732 j=(ssize_t) GetImageVirtualPixelMethod(image);
5733 s=newSViv(j);
5734 (void) sv_setpv(s,CommandOptionToMnemonic(
5735 MagickVirtualPixelOptions,j));
5736 SvIOK_on(s);
5737 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5738 continue;
5739 }
5740 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5741 attribute);
5742 break;
5743 }
5744 case 'W':
5745 case 'w':
5746 {
5747 if (LocaleCompare(attribute,"white-point") == 0)
5748 {
5749 if (image == (Image *) NULL)
5750 break;
cristy151b66d2015-04-15 10:50:31 +00005751 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005752 image->chromaticity.white_point.x,
5753 image->chromaticity.white_point.y);
5754 s=newSVpv(color,0);
5755 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5756 continue;
5757 }
5758 if (LocaleCompare(attribute,"width") == 0)
5759 {
5760 if (image != (Image *) NULL)
5761 s=newSViv((ssize_t) image->columns);
5762 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5763 continue;
5764 }
5765 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5766 attribute);
5767 break;
5768 }
5769 case 'X':
5770 case 'x':
5771 {
Cristyc1f9f9f2016-01-05 08:19:28 -05005772 if (LocaleCompare(attribute,"xmp") == 0)
5773 {
5774 if (image != (Image *) NULL)
5775 {
5776 const StringInfo
5777 *profile;
5778
5779 profile=GetImageProfile(image,"xmp");
5780 if (profile != (StringInfo *) NULL)
5781 s=newSVpv((const char *) GetStringInfoDatum(profile),
5782 GetStringInfoLength(profile));
5783 }
5784 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5785 continue;
5786 }
cristy4a3ce0a2013-08-03 20:06:59 +00005787 if (LocaleCompare(attribute,"x-resolution") == 0)
5788 {
5789 if (image != (Image *) NULL)
5790 s=newSVnv(image->resolution.x);
5791 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5792 continue;
5793 }
5794 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5795 attribute);
5796 break;
5797 }
5798 case 'Y':
5799 case 'y':
5800 {
5801 if (LocaleCompare(attribute,"y-resolution") == 0)
5802 {
5803 if (image != (Image *) NULL)
5804 s=newSVnv(image->resolution.y);
5805 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5806 continue;
5807 }
5808 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5809 attribute);
5810 break;
5811 }
5812 default:
5813 break;
5814 }
5815 if (image == (Image *) NULL)
5816 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5817 attribute)
5818 else
5819 {
5820 value=GetImageProperty(image,attribute,exception);
5821 if (value != (const char *) NULL)
5822 {
5823 s=newSVpv(value,0);
5824 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5825 }
5826 else
5827 if (*attribute != '%')
5828 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5829 attribute)
5830 else
5831 {
5832 char
5833 *meta;
5834
5835 meta=InterpretImageProperties(info ? info->image_info :
5836 (ImageInfo *) NULL,image,attribute,exception);
5837 s=newSVpv(meta,0);
5838 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5839 meta=(char *) RelinquishMagickMemory(meta);
5840 }
5841 }
5842 }
5843 exception=DestroyExceptionInfo(exception);
5844 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5845 }
5846
5847#
5848###############################################################################
5849# #
5850# #
5851# #
5852# G e t A u t h e n t i c P i x e l s #
5853# #
5854# #
5855# #
5856###############################################################################
5857#
5858#
5859void *
5860GetAuthenticPixels(ref,...)
5861 Image::Magick ref = NO_INIT
5862 ALIAS:
5863 getauthenticpixels = 1
5864 GetImagePixels = 2
5865 getimagepixels = 3
5866 CODE:
5867 {
5868 char
5869 *attribute;
5870
5871 ExceptionInfo
5872 *exception;
5873
5874 Image
5875 *image;
5876
5877 RectangleInfo
5878 region;
5879
5880 ssize_t
5881 i;
5882
5883 struct PackageInfo
5884 *info;
5885
5886 SV
5887 *perl_exception,
5888 *reference;
5889
5890 void
5891 *blob = NULL;
5892
5893 PERL_UNUSED_VAR(ref);
5894 PERL_UNUSED_VAR(ix);
5895 exception=AcquireExceptionInfo();
5896 perl_exception=newSVpv("",0);
5897 if (sv_isobject(ST(0)) == 0)
5898 {
5899 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5900 PackageName);
5901 goto PerlException;
5902 }
5903 reference=SvRV(ST(0));
5904
5905 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5906 if (image == (Image *) NULL)
5907 {
5908 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5909 PackageName);
5910 goto PerlException;
5911 }
5912
5913 region.x=0;
5914 region.y=0;
5915 region.width=image->columns;
5916 region.height=1;
5917 if (items == 1)
5918 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5919 for (i=2; i < items; i+=2)
5920 {
5921 attribute=(char *) SvPV(ST(i-1),na);
5922 switch (*attribute)
5923 {
5924 case 'g':
5925 case 'G':
5926 {
5927 if (LocaleCompare(attribute,"geometry") == 0)
5928 {
5929 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5930 break;
5931 }
5932 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5933 attribute);
5934 break;
5935 }
5936 case 'H':
5937 case 'h':
5938 {
5939 if (LocaleCompare(attribute,"height") == 0)
5940 {
5941 region.height=SvIV(ST(i));
5942 continue;
5943 }
5944 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5945 attribute);
5946 break;
5947 }
5948 case 'X':
5949 case 'x':
5950 {
5951 if (LocaleCompare(attribute,"x") == 0)
5952 {
5953 region.x=SvIV(ST(i));
5954 continue;
5955 }
5956 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5957 attribute);
5958 break;
5959 }
5960 case 'Y':
5961 case 'y':
5962 {
5963 if (LocaleCompare(attribute,"y") == 0)
5964 {
5965 region.y=SvIV(ST(i));
5966 continue;
5967 }
5968 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5969 attribute);
5970 break;
5971 }
5972 case 'W':
5973 case 'w':
5974 {
5975 if (LocaleCompare(attribute,"width") == 0)
5976 {
5977 region.width=SvIV(ST(i));
5978 continue;
5979 }
5980 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5981 attribute);
5982 break;
5983 }
5984 }
5985 }
5986 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5987 region.height,exception);
5988 if (blob != (void *) NULL)
5989 goto PerlEnd;
5990
5991 PerlException:
5992 InheritPerlException(exception,perl_exception);
5993 exception=DestroyExceptionInfo(exception);
5994 SvREFCNT_dec(perl_exception); /* throw away all errors */
5995
5996 PerlEnd:
5997 RETVAL = blob;
5998 }
5999 OUTPUT:
6000 RETVAL
6001
6002#
6003###############################################################################
6004# #
6005# #
6006# #
6007# G e t V i r t u a l P i x e l s #
6008# #
6009# #
6010# #
6011###############################################################################
6012#
6013#
6014void *
6015GetVirtualPixels(ref,...)
6016 Image::Magick ref = NO_INIT
6017 ALIAS:
6018 getvirtualpixels = 1
6019 AcquireImagePixels = 2
6020 acquireimagepixels = 3
6021 CODE:
6022 {
6023 char
6024 *attribute;
6025
6026 const void
6027 *blob = NULL;
6028
6029 ExceptionInfo
6030 *exception;
6031
6032 Image
6033 *image;
6034
6035 RectangleInfo
6036 region;
6037
6038 ssize_t
6039 i;
6040
6041 struct PackageInfo
6042 *info;
6043
6044 SV
6045 *perl_exception,
6046 *reference;
6047
6048 PERL_UNUSED_VAR(ref);
6049 PERL_UNUSED_VAR(ix);
6050 exception=AcquireExceptionInfo();
6051 perl_exception=newSVpv("",0);
6052 if (sv_isobject(ST(0)) == 0)
6053 {
6054 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6055 PackageName);
6056 goto PerlException;
6057 }
6058 reference=SvRV(ST(0));
6059
6060 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6061 if (image == (Image *) NULL)
6062 {
6063 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6064 PackageName);
6065 goto PerlException;
6066 }
6067
6068 region.x=0;
6069 region.y=0;
6070 region.width=image->columns;
6071 region.height=1;
6072 if (items == 1)
6073 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6074 for (i=2; i < items; i+=2)
6075 {
6076 attribute=(char *) SvPV(ST(i-1),na);
6077 switch (*attribute)
6078 {
6079 case 'g':
6080 case 'G':
6081 {
6082 if (LocaleCompare(attribute,"geometry") == 0)
6083 {
6084 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6085 break;
6086 }
6087 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6088 attribute);
6089 break;
6090 }
6091 case 'H':
6092 case 'h':
6093 {
6094 if (LocaleCompare(attribute,"height") == 0)
6095 {
6096 region.height=SvIV(ST(i));
6097 continue;
6098 }
6099 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6100 attribute);
6101 break;
6102 }
6103 case 'X':
6104 case 'x':
6105 {
6106 if (LocaleCompare(attribute,"x") == 0)
6107 {
6108 region.x=SvIV(ST(i));
6109 continue;
6110 }
6111 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6112 attribute);
6113 break;
6114 }
6115 case 'Y':
6116 case 'y':
6117 {
6118 if (LocaleCompare(attribute,"y") == 0)
6119 {
6120 region.y=SvIV(ST(i));
6121 continue;
6122 }
6123 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6124 attribute);
6125 break;
6126 }
6127 case 'W':
6128 case 'w':
6129 {
6130 if (LocaleCompare(attribute,"width") == 0)
6131 {
6132 region.width=SvIV(ST(i));
6133 continue;
6134 }
6135 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6136 attribute);
6137 break;
6138 }
6139 }
6140 }
6141 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6142 region.height,exception);
6143 if (blob != (void *) NULL)
6144 goto PerlEnd;
6145
6146 PerlException:
6147 InheritPerlException(exception,perl_exception);
6148 exception=DestroyExceptionInfo(exception);
6149 SvREFCNT_dec(perl_exception); /* throw away all errors */
6150
6151 PerlEnd:
6152 RETVAL = (void *) blob;
6153 }
6154 OUTPUT:
6155 RETVAL
6156
6157#
6158###############################################################################
6159# #
6160# #
6161# #
6162# G e t A u t h e n t i c M e t a c o n t e n t #
6163# #
6164# #
6165# #
6166###############################################################################
6167#
6168#
6169void *
6170GetAuthenticMetacontent(ref,...)
6171 Image::Magick ref = NO_INIT
6172 ALIAS:
6173 getauthenticmetacontent = 1
6174 GetMetacontent = 2
6175 getmetacontent = 3
6176 CODE:
6177 {
6178 ExceptionInfo
6179 *exception;
6180
6181 Image
6182 *image;
6183
6184 struct PackageInfo
6185 *info;
6186
6187 SV
6188 *perl_exception,
6189 *reference;
6190
6191 void
6192 *blob = NULL;
6193
6194 PERL_UNUSED_VAR(ref);
6195 PERL_UNUSED_VAR(ix);
6196 exception=AcquireExceptionInfo();
6197 perl_exception=newSVpv("",0);
6198 if (sv_isobject(ST(0)) == 0)
6199 {
6200 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6201 PackageName);
6202 goto PerlException;
6203 }
6204 reference=SvRV(ST(0));
6205
6206 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6207 if (image == (Image *) NULL)
6208 {
6209 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6210 PackageName);
6211 goto PerlException;
6212 }
6213
6214 blob=(void *) GetAuthenticMetacontent(image);
6215 if (blob != (void *) NULL)
6216 goto PerlEnd;
6217
6218 PerlException:
6219 InheritPerlException(exception,perl_exception);
6220 exception=DestroyExceptionInfo(exception);
6221 SvREFCNT_dec(perl_exception); /* throw away all errors */
6222
6223 PerlEnd:
6224 RETVAL = blob;
6225 }
6226 OUTPUT:
6227 RETVAL
6228
6229#
6230###############################################################################
6231# #
6232# #
6233# #
6234# G e t V i r t u a l M e t a c o n t e n t #
6235# #
6236# #
6237# #
6238###############################################################################
6239#
6240#
6241void *
6242GetVirtualMetacontent(ref,...)
6243 Image::Magick ref = NO_INIT
6244 ALIAS:
6245 getvirtualmetacontent = 1
6246 CODE:
6247 {
6248 ExceptionInfo
6249 *exception;
6250
6251 Image
6252 *image;
6253
6254 struct PackageInfo
6255 *info;
6256
6257 SV
6258 *perl_exception,
6259 *reference;
6260
6261 void
6262 *blob = NULL;
6263
6264 PERL_UNUSED_VAR(ref);
6265 PERL_UNUSED_VAR(ix);
6266 exception=AcquireExceptionInfo();
6267 perl_exception=newSVpv("",0);
6268 if (sv_isobject(ST(0)) == 0)
6269 {
6270 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6271 PackageName);
6272 goto PerlException;
6273 }
6274 reference=SvRV(ST(0));
6275
6276 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6277 if (image == (Image *) NULL)
6278 {
6279 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6280 PackageName);
6281 goto PerlException;
6282 }
6283
6284 blob=(void *) GetVirtualMetacontent(image);
6285 if (blob != (void *) NULL)
6286 goto PerlEnd;
6287
6288 PerlException:
6289 InheritPerlException(exception,perl_exception);
6290 exception=DestroyExceptionInfo(exception);
6291 SvREFCNT_dec(perl_exception); /* throw away all errors */
6292
6293 PerlEnd:
6294 RETVAL = blob;
6295 }
6296 OUTPUT:
6297 RETVAL
6298
6299#
6300###############################################################################
6301# #
6302# #
6303# #
6304# H i s t o g r a m #
6305# #
6306# #
6307# #
6308###############################################################################
6309#
6310#
6311void
6312Histogram(ref,...)
6313 Image::Magick ref=NO_INIT
6314 ALIAS:
6315 HistogramImage = 1
6316 histogram = 2
6317 histogramimage = 3
6318 PPCODE:
6319 {
6320 AV
6321 *av;
6322
6323 char
cristy151b66d2015-04-15 10:50:31 +00006324 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006325
6326 PixelInfo
6327 *histogram;
6328
6329 ExceptionInfo
6330 *exception;
6331
6332 Image
6333 *image;
6334
6335 register ssize_t
6336 i;
6337
6338 ssize_t
6339 count;
6340
6341 struct PackageInfo
6342 *info;
6343
6344 SV
6345 *perl_exception,
6346 *reference;
6347
6348 size_t
6349 number_colors;
6350
6351 PERL_UNUSED_VAR(ref);
6352 PERL_UNUSED_VAR(ix);
6353 exception=AcquireExceptionInfo();
6354 perl_exception=newSVpv("",0);
6355 av=NULL;
6356 if (sv_isobject(ST(0)) == 0)
6357 {
6358 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6359 PackageName);
6360 goto PerlException;
6361 }
6362 reference=SvRV(ST(0));
6363 av=newAV();
6364 SvREFCNT_dec(av);
6365 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6366 if (image == (Image *) NULL)
6367 {
6368 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6369 PackageName);
6370 goto PerlException;
6371 }
cristy4a3ce0a2013-08-03 20:06:59 +00006372 count=0;
6373 for ( ; image; image=image->next)
6374 {
6375 histogram=GetImageHistogram(image,&number_colors,exception);
6376 if (histogram == (PixelInfo *) NULL)
6377 continue;
6378 count+=(ssize_t) number_colors;
6379 EXTEND(sp,6*count);
6380 for (i=0; i < (ssize_t) number_colors; i++)
6381 {
cristy151b66d2015-04-15 10:50:31 +00006382 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006383 histogram[i].red);
6384 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006385 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006386 histogram[i].green);
6387 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006388 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006389 histogram[i].blue);
6390 PUSHs(sv_2mortal(newSVpv(message,0)));
6391 if (image->colorspace == CMYKColorspace)
6392 {
cristy151b66d2015-04-15 10:50:31 +00006393 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006394 histogram[i].black);
6395 PUSHs(sv_2mortal(newSVpv(message,0)));
6396 }
cristy151b66d2015-04-15 10:50:31 +00006397 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006398 histogram[i].alpha);
6399 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006400 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006401 histogram[i].count);
6402 PUSHs(sv_2mortal(newSVpv(message,0)));
6403 }
6404 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6405 }
6406
6407 PerlException:
6408 InheritPerlException(exception,perl_exception);
6409 exception=DestroyExceptionInfo(exception);
6410 SvREFCNT_dec(perl_exception);
6411 }
6412
6413#
6414###############################################################################
6415# #
6416# #
6417# #
6418# G e t P i x e l #
6419# #
6420# #
6421# #
6422###############################################################################
6423#
6424#
6425void
6426GetPixel(ref,...)
6427 Image::Magick ref=NO_INIT
6428 ALIAS:
6429 getpixel = 1
6430 getPixel = 2
6431 PPCODE:
6432 {
6433 AV
6434 *av;
6435
6436 char
6437 *attribute;
6438
6439 ExceptionInfo
6440 *exception;
6441
6442 Image
6443 *image;
6444
6445 MagickBooleanType
6446 normalize;
6447
6448 RectangleInfo
6449 region;
6450
6451 register const Quantum
6452 *p;
6453
6454 register ssize_t
6455 i;
6456
6457 ssize_t
6458 option;
6459
6460 struct PackageInfo
6461 *info;
6462
6463 SV
6464 *perl_exception,
6465 *reference; /* reference is the SV* of ref=SvIV(reference) */
6466
6467 PERL_UNUSED_VAR(ref);
6468 PERL_UNUSED_VAR(ix);
6469 exception=AcquireExceptionInfo();
6470 perl_exception=newSVpv("",0);
6471 reference=SvRV(ST(0));
6472 av=(AV *) reference;
6473 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6474 exception);
6475 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6476 if (image == (Image *) NULL)
6477 {
6478 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6479 PackageName);
6480 goto PerlException;
6481 }
6482 normalize=MagickTrue;
6483 region.x=0;
6484 region.y=0;
6485 region.width=image->columns;
6486 region.height=1;
6487 if (items == 1)
6488 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6489 for (i=2; i < items; i+=2)
6490 {
6491 attribute=(char *) SvPV(ST(i-1),na);
6492 switch (*attribute)
6493 {
6494 case 'C':
6495 case 'c':
6496 {
6497 if (LocaleCompare(attribute,"channel") == 0)
6498 {
6499 ssize_t
6500 option;
6501
6502 option=ParseChannelOption(SvPV(ST(i),na));
6503 if (option < 0)
6504 {
6505 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6506 SvPV(ST(i),na));
6507 return;
6508 }
cristybcd59342015-06-07 14:07:19 +00006509 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00006510 break;
6511 }
6512 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6513 attribute);
6514 break;
6515 }
6516 case 'g':
6517 case 'G':
6518 {
6519 if (LocaleCompare(attribute,"geometry") == 0)
6520 {
6521 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6522 break;
6523 }
6524 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6525 attribute);
6526 break;
6527 }
6528 case 'N':
6529 case 'n':
6530 {
6531 if (LocaleCompare(attribute,"normalize") == 0)
6532 {
6533 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6534 SvPV(ST(i),na));
6535 if (option < 0)
6536 {
6537 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6538 SvPV(ST(i),na));
6539 break;
6540 }
6541 normalize=option != 0 ? MagickTrue : MagickFalse;
6542 break;
6543 }
6544 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6545 attribute);
6546 break;
6547 }
6548 case 'x':
6549 case 'X':
6550 {
6551 if (LocaleCompare(attribute,"x") == 0)
6552 {
6553 region.x=SvIV(ST(i));
6554 break;
6555 }
6556 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6557 attribute);
6558 break;
6559 }
6560 case 'y':
6561 case 'Y':
6562 {
6563 if (LocaleCompare(attribute,"y") == 0)
6564 {
6565 region.y=SvIV(ST(i));
6566 break;
6567 }
6568 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6569 attribute);
6570 break;
6571 }
6572 default:
6573 {
6574 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6575 attribute);
6576 break;
6577 }
6578 }
6579 }
6580 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6581 if (p == (const Quantum *) NULL)
6582 PUSHs(&sv_undef);
6583 else
6584 {
6585 double
6586 scale;
6587
6588 scale=1.0;
6589 if (normalize != MagickFalse)
6590 scale=1.0/QuantumRange;
6591 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6592 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6593 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6594 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6595 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6596 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6597 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6598 (image->colorspace == CMYKColorspace))
6599 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6600 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6601 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6602 }
6603
6604 PerlException:
6605 InheritPerlException(exception,perl_exception);
6606 exception=DestroyExceptionInfo(exception);
6607 SvREFCNT_dec(perl_exception);
6608 }
6609
6610#
6611###############################################################################
6612# #
6613# #
6614# #
6615# G e t P i x e l s #
6616# #
6617# #
6618# #
6619###############################################################################
6620#
6621#
6622void
6623GetPixels(ref,...)
6624 Image::Magick ref=NO_INIT
6625 ALIAS:
6626 getpixels = 1
6627 getPixels = 2
6628 PPCODE:
6629 {
6630 AV
6631 *av;
6632
6633 char
6634 *attribute;
6635
6636 const char
6637 *map;
6638
6639 ExceptionInfo
6640 *exception;
6641
6642 Image
6643 *image;
6644
6645 MagickBooleanType
6646 normalize,
6647 status;
6648
6649 RectangleInfo
6650 region;
6651
6652 register ssize_t
6653 i;
6654
6655 ssize_t
6656 option;
6657
6658 struct PackageInfo
6659 *info;
6660
6661 SV
6662 *perl_exception,
6663 *reference; /* reference is the SV* of ref=SvIV(reference) */
6664
6665 PERL_UNUSED_VAR(ref);
6666 PERL_UNUSED_VAR(ix);
6667 exception=AcquireExceptionInfo();
6668 perl_exception=newSVpv("",0);
6669 reference=SvRV(ST(0));
6670 av=(AV *) reference;
6671 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6672 exception);
6673 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6674 if (image == (Image *) NULL)
6675 {
6676 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6677 PackageName);
6678 goto PerlException;
6679 }
6680 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006681 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006682 map="RGBA";
6683 if (image->colorspace == CMYKColorspace)
6684 {
6685 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006686 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006687 map="CMYKA";
6688 }
6689 normalize=MagickFalse;
6690 region.x=0;
6691 region.y=0;
6692 region.width=image->columns;
6693 region.height=1;
6694 if (items == 1)
6695 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6696 for (i=2; i < items; i+=2)
6697 {
6698 attribute=(char *) SvPV(ST(i-1),na);
6699 switch (*attribute)
6700 {
6701 case 'g':
6702 case 'G':
6703 {
6704 if (LocaleCompare(attribute,"geometry") == 0)
6705 {
6706 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6707 break;
6708 }
6709 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6710 attribute);
6711 break;
6712 }
6713 case 'H':
6714 case 'h':
6715 {
6716 if (LocaleCompare(attribute,"height") == 0)
6717 {
6718 region.height=SvIV(ST(i));
6719 break;
6720 }
6721 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6722 attribute);
6723 break;
6724 }
6725 case 'M':
6726 case 'm':
6727 {
6728 if (LocaleCompare(attribute,"map") == 0)
6729 {
6730 map=SvPV(ST(i),na);
6731 break;
6732 }
6733 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6734 attribute);
6735 break;
6736 }
6737 case 'N':
6738 case 'n':
6739 {
6740 if (LocaleCompare(attribute,"normalize") == 0)
6741 {
6742 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6743 SvPV(ST(i),na));
6744 if (option < 0)
6745 {
6746 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6747 SvPV(ST(i),na));
6748 break;
6749 }
6750 normalize=option != 0 ? MagickTrue : MagickFalse;
6751 break;
6752 }
6753 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6754 attribute);
6755 break;
6756 }
6757 case 'W':
6758 case 'w':
6759 {
6760 if (LocaleCompare(attribute,"width") == 0)
6761 {
6762 region.width=SvIV(ST(i));
6763 break;
6764 }
6765 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6766 attribute);
6767 break;
6768 }
6769 case 'x':
6770 case 'X':
6771 {
6772 if (LocaleCompare(attribute,"x") == 0)
6773 {
6774 region.x=SvIV(ST(i));
6775 break;
6776 }
6777 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6778 attribute);
6779 break;
6780 }
6781 case 'y':
6782 case 'Y':
6783 {
6784 if (LocaleCompare(attribute,"y") == 0)
6785 {
6786 region.y=SvIV(ST(i));
6787 break;
6788 }
6789 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6790 attribute);
6791 break;
6792 }
6793 default:
6794 {
6795 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6796 attribute);
6797 break;
6798 }
6799 }
6800 }
6801 if (normalize != MagickFalse)
6802 {
6803 float
6804 *pixels;
6805
6806 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6807 region.height*sizeof(*pixels));
6808 if (pixels == (float *) NULL)
6809 {
6810 ThrowPerlException(exception,ResourceLimitError,
6811 "MemoryAllocationFailed",PackageName);
6812 goto PerlException;
6813 }
6814 status=ExportImagePixels(image,region.x,region.y,region.width,
6815 region.height,map,FloatPixel,pixels,exception);
6816 if (status == MagickFalse)
6817 PUSHs(&sv_undef);
6818 else
6819 {
6820 EXTEND(sp,strlen(map)*region.width*region.height);
6821 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6822 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6823 }
6824 pixels=(float *) RelinquishMagickMemory(pixels);
6825 }
6826 else
6827 {
6828 Quantum
6829 *pixels;
6830
6831 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6832 region.height*sizeof(*pixels));
6833 if (pixels == (Quantum *) NULL)
6834 {
6835 ThrowPerlException(exception,ResourceLimitError,
6836 "MemoryAllocationFailed",PackageName);
6837 goto PerlException;
6838 }
6839 status=ExportImagePixels(image,region.x,region.y,region.width,
6840 region.height,map,QuantumPixel,pixels,exception);
6841 if (status == MagickFalse)
6842 PUSHs(&sv_undef);
6843 else
6844 {
6845 EXTEND(sp,strlen(map)*region.width*region.height);
6846 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6847 PUSHs(sv_2mortal(newSViv(pixels[i])));
6848 }
6849 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6850 }
6851
6852 PerlException:
6853 InheritPerlException(exception,perl_exception);
6854 exception=DestroyExceptionInfo(exception);
6855 SvREFCNT_dec(perl_exception);
6856 }
6857
6858#
6859###############################################################################
6860# #
6861# #
6862# #
6863# I m a g e T o B l o b #
6864# #
6865# #
6866# #
6867###############################################################################
6868#
6869#
6870void
6871ImageToBlob(ref,...)
6872 Image::Magick ref=NO_INIT
6873 ALIAS:
6874 ImageToBlob = 1
6875 imagetoblob = 2
6876 toblob = 3
6877 blob = 4
6878 PPCODE:
6879 {
6880 char
cristy151b66d2015-04-15 10:50:31 +00006881 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006882
6883 ExceptionInfo
6884 *exception;
6885
6886 Image
6887 *image,
6888 *next;
6889
6890 register ssize_t
6891 i;
6892
6893 struct PackageInfo
6894 *info,
6895 *package_info;
6896
6897 size_t
6898 length;
6899
6900 ssize_t
6901 scene;
6902
6903 SV
6904 *perl_exception,
6905 *reference;
6906
6907 void
6908 *blob;
6909
6910 PERL_UNUSED_VAR(ref);
6911 PERL_UNUSED_VAR(ix);
6912 exception=AcquireExceptionInfo();
6913 perl_exception=newSVpv("",0);
6914 package_info=(struct PackageInfo *) NULL;
6915 if (sv_isobject(ST(0)) == 0)
6916 {
6917 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6918 PackageName);
6919 goto PerlException;
6920 }
6921 reference=SvRV(ST(0));
6922 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6923 if (image == (Image *) NULL)
6924 {
6925 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6926 PackageName);
6927 goto PerlException;
6928 }
6929 package_info=ClonePackageInfo(info,exception);
6930 for (i=2; i < items; i+=2)
6931 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6932 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006933 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006934 scene=0;
6935 for (next=image; next; next=next->next)
6936 {
cristy151b66d2015-04-15 10:50:31 +00006937 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006938 next->scene=scene++;
6939 }
6940 SetImageInfo(package_info->image_info,(unsigned int)
6941 GetImageListLength(image),exception);
6942 EXTEND(sp,(ssize_t) GetImageListLength(image));
6943 for ( ; image; image=image->next)
6944 {
6945 length=0;
6946 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6947 if (blob != (char *) NULL)
6948 {
6949 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6950 blob=(unsigned char *) RelinquishMagickMemory(blob);
6951 }
6952 if (package_info->image_info->adjoin)
6953 break;
6954 }
6955
6956 PerlException:
6957 if (package_info != (struct PackageInfo *) NULL)
6958 DestroyPackageInfo(package_info);
6959 InheritPerlException(exception,perl_exception);
6960 exception=DestroyExceptionInfo(exception);
6961 SvREFCNT_dec(perl_exception); /* throw away all errors */
6962 }
6963
6964#
6965###############################################################################
6966# #
6967# #
6968# #
6969# L a y e r s #
6970# #
6971# #
6972# #
6973###############################################################################
6974#
6975#
6976void
6977Layers(ref,...)
6978 Image::Magick ref=NO_INIT
6979 ALIAS:
6980 Layers = 1
6981 layers = 2
6982 OptimizeImageLayers = 3
6983 optimizelayers = 4
6984 optimizeimagelayers = 5
6985 PPCODE:
6986 {
6987 AV
6988 *av;
6989
6990 char
6991 *attribute;
6992
6993 CompositeOperator
6994 compose;
6995
6996 ExceptionInfo
6997 *exception;
6998
6999 HV
7000 *hv;
7001
7002 Image
7003 *image,
7004 *layers;
7005
7006 LayerMethod
7007 method;
7008
7009 register ssize_t
7010 i;
7011
7012 ssize_t
7013 option,
7014 sp;
7015
7016 struct PackageInfo
7017 *info;
7018
7019 SV
7020 *av_reference,
7021 *perl_exception,
7022 *reference,
7023 *rv,
7024 *sv;
7025
7026 PERL_UNUSED_VAR(ref);
7027 PERL_UNUSED_VAR(ix);
7028 exception=AcquireExceptionInfo();
7029 perl_exception=newSVpv("",0);
7030 sv=NULL;
7031 if (sv_isobject(ST(0)) == 0)
7032 {
7033 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7034 PackageName);
7035 goto PerlException;
7036 }
7037 reference=SvRV(ST(0));
7038 hv=SvSTASH(reference);
7039 av=newAV();
7040 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7041 SvREFCNT_dec(av);
7042 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7043 if (image == (Image *) NULL)
7044 {
7045 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7046 PackageName);
7047 goto PerlException;
7048 }
7049 compose=image->compose;
7050 method=OptimizeLayer;
7051 for (i=2; i < items; i+=2)
7052 {
7053 attribute=(char *) SvPV(ST(i-1),na);
7054 switch (*attribute)
7055 {
7056 case 'C':
7057 case 'c':
7058 {
7059 if (LocaleCompare(attribute,"compose") == 0)
7060 {
7061 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7062 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7063 if (sp < 0)
7064 {
7065 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7066 SvPV(ST(i),na));
7067 break;
7068 }
7069 compose=(CompositeOperator) sp;
7070 break;
7071 }
7072 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7073 attribute);
7074 break;
7075 }
7076 case 'M':
7077 case 'm':
7078 {
7079 if (LocaleCompare(attribute,"method") == 0)
7080 {
7081 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7082 SvPV(ST(i),na));
7083 if (option < 0)
7084 {
7085 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7086 SvPV(ST(i),na));
7087 break;
7088 }
7089 method=(LayerMethod) option;
7090 break;
7091 }
7092 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7093 attribute);
7094 break;
7095 }
7096 default:
7097 {
7098 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7099 attribute);
7100 break;
7101 }
7102 }
7103 }
7104 layers=(Image *) NULL;
7105 switch (method)
7106 {
7107 case CompareAnyLayer:
7108 case CompareClearLayer:
7109 case CompareOverlayLayer:
7110 default:
7111 {
7112 layers=CompareImagesLayers(image,method,exception);
7113 break;
7114 }
7115 case MergeLayer:
7116 case FlattenLayer:
7117 case MosaicLayer:
7118 {
7119 layers=MergeImageLayers(image,method,exception);
7120 break;
7121 }
7122 case DisposeLayer:
7123 {
7124 layers=DisposeImages(image,exception);
7125 break;
7126 }
7127 case OptimizeImageLayer:
7128 {
7129 layers=OptimizeImageLayers(image,exception);
7130 break;
7131 }
7132 case OptimizePlusLayer:
7133 {
7134 layers=OptimizePlusImageLayers(image,exception);
7135 break;
7136 }
7137 case OptimizeTransLayer:
7138 {
7139 OptimizeImageTransparency(image,exception);
7140 break;
7141 }
7142 case RemoveDupsLayer:
7143 {
7144 RemoveDuplicateLayers(&image,exception);
7145 break;
7146 }
7147 case RemoveZeroLayer:
7148 {
7149 RemoveZeroDelayLayers(&image,exception);
7150 break;
7151 }
7152 case OptimizeLayer:
7153 {
7154 QuantizeInfo
7155 *quantize_info;
7156
7157 /*
7158 General Purpose, GIF Animation Optimizer.
7159 */
7160 layers=CoalesceImages(image,exception);
7161 if (layers == (Image *) NULL)
7162 break;
7163 image=layers;
7164 layers=OptimizeImageLayers(image,exception);
7165 if (layers == (Image *) NULL)
7166 break;
7167 image=DestroyImageList(image);
7168 image=layers;
7169 layers=(Image *) NULL;
7170 OptimizeImageTransparency(image,exception);
7171 quantize_info=AcquireQuantizeInfo(info->image_info);
7172 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7173 quantize_info=DestroyQuantizeInfo(quantize_info);
7174 break;
7175 }
7176 case CompositeLayer:
7177 {
7178 Image
7179 *source;
7180
7181 RectangleInfo
7182 geometry;
7183
7184 /*
7185 Split image sequence at the first 'NULL:' image.
7186 */
7187 source=image;
7188 while (source != (Image *) NULL)
7189 {
7190 source=GetNextImageInList(source);
7191 if ((source != (Image *) NULL) &&
7192 (LocaleCompare(source->magick,"NULL") == 0))
7193 break;
7194 }
7195 if (source != (Image *) NULL)
7196 {
7197 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7198 (GetNextImageInList(source) == (Image *) NULL))
7199 source=(Image *) NULL;
7200 else
7201 {
7202 /*
7203 Separate the two lists, junk the null: image.
7204 */
7205 source=SplitImageList(source->previous);
7206 DeleteImageFromList(&source);
7207 }
7208 }
7209 if (source == (Image *) NULL)
7210 {
7211 (void) ThrowMagickException(exception,GetMagickModule(),
7212 OptionError,"MissingNullSeparator","layers Composite");
7213 break;
7214 }
7215 /*
7216 Adjust offset with gravity and virtual canvas.
7217 */
7218 SetGeometry(image,&geometry);
7219 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7220 geometry.width=source->page.width != 0 ? source->page.width :
7221 source->columns;
7222 geometry.height=source->page.height != 0 ? source->page.height :
7223 source->rows;
7224 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7225 image->columns,image->page.height != 0 ? image->page.height :
7226 image->rows,image->gravity,&geometry);
7227 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7228 source=DestroyImageList(source);
7229 break;
7230 }
7231 }
7232 if (layers != (Image *) NULL)
7233 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007234 else
7235 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007236 if (image == (Image *) NULL)
7237 goto PerlException;
7238 for ( ; image; image=image->next)
7239 {
7240 AddImageToRegistry(sv,image);
7241 rv=newRV(sv);
7242 av_push(av,sv_bless(rv,hv));
7243 SvREFCNT_dec(sv);
7244 }
7245 exception=DestroyExceptionInfo(exception);
7246 ST(0)=av_reference;
7247 SvREFCNT_dec(perl_exception);
7248 XSRETURN(1);
7249
7250 PerlException:
7251 InheritPerlException(exception,perl_exception);
7252 exception=DestroyExceptionInfo(exception);
7253 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7254 SvPOK_on(perl_exception);
7255 ST(0)=sv_2mortal(perl_exception);
7256 XSRETURN(1);
7257 }
7258
7259#
7260###############################################################################
7261# #
7262# #
7263# #
7264# M a g i c k T o M i m e #
7265# #
7266# #
7267# #
7268###############################################################################
7269#
7270#
7271SV *
7272MagickToMime(ref,name)
7273 Image::Magick ref=NO_INIT
7274 char *name
7275 ALIAS:
7276 magicktomime = 1
7277 CODE:
7278 {
7279 char
7280 *mime;
7281
7282 PERL_UNUSED_VAR(ref);
7283 PERL_UNUSED_VAR(ix);
7284 mime=MagickToMime(name);
7285 RETVAL=newSVpv(mime,0);
7286 mime=(char *) RelinquishMagickMemory(mime);
7287 }
7288 OUTPUT:
7289 RETVAL
7290
7291#
7292###############################################################################
7293# #
7294# #
7295# #
7296# M o g r i f y #
7297# #
7298# #
7299# #
7300###############################################################################
7301#
7302#
7303void
7304Mogrify(ref,...)
7305 Image::Magick ref=NO_INIT
7306 ALIAS:
7307 Comment = 1
7308 CommentImage = 2
7309 Label = 3
7310 LabelImage = 4
7311 AddNoise = 5
7312 AddNoiseImage = 6
7313 Colorize = 7
7314 ColorizeImage = 8
7315 Border = 9
7316 BorderImage = 10
7317 Blur = 11
7318 BlurImage = 12
7319 Chop = 13
7320 ChopImage = 14
7321 Crop = 15
7322 CropImage = 16
7323 Despeckle = 17
7324 DespeckleImage = 18
7325 Edge = 19
7326 EdgeImage = 20
7327 Emboss = 21
7328 EmbossImage = 22
7329 Enhance = 23
7330 EnhanceImage = 24
7331 Flip = 25
7332 FlipImage = 26
7333 Flop = 27
7334 FlopImage = 28
7335 Frame = 29
7336 FrameImage = 30
7337 Implode = 31
7338 ImplodeImage = 32
7339 Magnify = 33
7340 MagnifyImage = 34
7341 MedianFilter = 35
7342 MedianConvolveImage = 36
7343 Minify = 37
7344 MinifyImage = 38
7345 OilPaint = 39
7346 OilPaintImage = 40
7347 ReduceNoise = 41
7348 ReduceNoiseImage = 42
7349 Roll = 43
7350 RollImage = 44
7351 Rotate = 45
7352 RotateImage = 46
7353 Sample = 47
7354 SampleImage = 48
7355 Scale = 49
7356 ScaleImage = 50
7357 Shade = 51
7358 ShadeImage = 52
7359 Sharpen = 53
7360 SharpenImage = 54
7361 Shear = 55
7362 ShearImage = 56
7363 Spread = 57
7364 SpreadImage = 58
7365 Swirl = 59
7366 SwirlImage = 60
7367 Resize = 61
7368 ResizeImage = 62
7369 Zoom = 63
7370 ZoomImage = 64
7371 Annotate = 65
7372 AnnotateImage = 66
7373 ColorFloodfill = 67
7374 ColorFloodfillImage= 68
7375 Composite = 69
7376 CompositeImage = 70
7377 Contrast = 71
7378 ContrastImage = 72
7379 CycleColormap = 73
7380 CycleColormapImage = 74
7381 Draw = 75
7382 DrawImage = 76
7383 Equalize = 77
7384 EqualizeImage = 78
7385 Gamma = 79
7386 GammaImage = 80
7387 Map = 81
7388 MapImage = 82
7389 MatteFloodfill = 83
7390 MatteFloodfillImage= 84
7391 Modulate = 85
7392 ModulateImage = 86
7393 Negate = 87
7394 NegateImage = 88
7395 Normalize = 89
7396 NormalizeImage = 90
7397 NumberColors = 91
7398 NumberColorsImage = 92
7399 Opaque = 93
7400 OpaqueImage = 94
7401 Quantize = 95
7402 QuantizeImage = 96
7403 Raise = 97
7404 RaiseImage = 98
7405 Segment = 99
7406 SegmentImage = 100
7407 Signature = 101
7408 SignatureImage = 102
7409 Solarize = 103
7410 SolarizeImage = 104
7411 Sync = 105
7412 SyncImage = 106
7413 Texture = 107
7414 TextureImage = 108
7415 Evaluate = 109
7416 EvaluateImage = 110
7417 Transparent = 111
7418 TransparentImage = 112
7419 Threshold = 113
7420 ThresholdImage = 114
7421 Charcoal = 115
7422 CharcoalImage = 116
7423 Trim = 117
7424 TrimImage = 118
7425 Wave = 119
7426 WaveImage = 120
7427 Separate = 121
7428 SeparateImage = 122
7429 Stereo = 125
7430 StereoImage = 126
7431 Stegano = 127
7432 SteganoImage = 128
7433 Deconstruct = 129
7434 DeconstructImage = 130
7435 GaussianBlur = 131
7436 GaussianBlurImage = 132
7437 Convolve = 133
7438 ConvolveImage = 134
7439 Profile = 135
7440 ProfileImage = 136
7441 UnsharpMask = 137
7442 UnsharpMaskImage = 138
7443 MotionBlur = 139
7444 MotionBlurImage = 140
7445 OrderedDither = 141
7446 OrderedDitherImage = 142
7447 Shave = 143
7448 ShaveImage = 144
7449 Level = 145
7450 LevelImage = 146
7451 Clip = 147
7452 ClipImage = 148
7453 AffineTransform = 149
7454 AffineTransformImage = 150
7455 Difference = 151
7456 DifferenceImage = 152
7457 AdaptiveThreshold = 153
7458 AdaptiveThresholdImage = 154
7459 Resample = 155
7460 ResampleImage = 156
7461 Describe = 157
7462 DescribeImage = 158
7463 BlackThreshold = 159
7464 BlackThresholdImage= 160
7465 WhiteThreshold = 161
7466 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007467 RotationalBlur = 163
7468 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007469 Thumbnail = 165
7470 ThumbnailImage = 166
7471 Strip = 167
7472 StripImage = 168
7473 Tint = 169
7474 TintImage = 170
7475 Channel = 171
7476 ChannelImage = 172
7477 Splice = 173
7478 SpliceImage = 174
7479 Posterize = 175
7480 PosterizeImage = 176
7481 Shadow = 177
7482 ShadowImage = 178
7483 Identify = 179
7484 IdentifyImage = 180
7485 SepiaTone = 181
7486 SepiaToneImage = 182
7487 SigmoidalContrast = 183
7488 SigmoidalContrastImage = 184
7489 Extent = 185
7490 ExtentImage = 186
7491 Vignette = 187
7492 VignetteImage = 188
7493 ContrastStretch = 189
7494 ContrastStretchImage = 190
7495 Sans0 = 191
7496 Sans0Image = 192
7497 Sans1 = 193
7498 Sans1Image = 194
7499 AdaptiveSharpen = 195
7500 AdaptiveSharpenImage = 196
7501 Transpose = 197
7502 TransposeImage = 198
7503 Transverse = 199
7504 TransverseImage = 200
7505 AutoOrient = 201
7506 AutoOrientImage = 202
7507 AdaptiveBlur = 203
7508 AdaptiveBlurImage = 204
7509 Sketch = 205
7510 SketchImage = 206
7511 UniqueColors = 207
7512 UniqueColorsImage = 208
7513 AdaptiveResize = 209
7514 AdaptiveResizeImage= 210
7515 ClipMask = 211
7516 ClipMaskImage = 212
7517 LinearStretch = 213
7518 LinearStretchImage = 214
7519 ColorMatrix = 215
7520 ColorMatrixImage = 216
7521 Mask = 217
7522 MaskImage = 218
7523 Polaroid = 219
7524 PolaroidImage = 220
7525 FloodfillPaint = 221
7526 FloodfillPaintImage= 222
7527 Distort = 223
7528 DistortImage = 224
7529 Clut = 225
7530 ClutImage = 226
7531 LiquidRescale = 227
7532 LiquidRescaleImage = 228
7533 Encipher = 229
7534 EncipherImage = 230
7535 Decipher = 231
7536 DecipherImage = 232
7537 Deskew = 233
7538 DeskewImage = 234
7539 Remap = 235
7540 RemapImage = 236
7541 SparseColor = 237
7542 SparseColorImage = 238
7543 Function = 239
7544 FunctionImage = 240
7545 SelectiveBlur = 241
7546 SelectiveBlurImage = 242
7547 HaldClut = 243
7548 HaldClutImage = 244
7549 BlueShift = 245
7550 BlueShiftImage = 246
7551 ForwardFourierTransform = 247
7552 ForwardFourierTransformImage = 248
7553 InverseFourierTransform = 249
7554 InverseFourierTransformImage = 250
7555 ColorDecisionList = 251
7556 ColorDecisionListImage = 252
7557 AutoGamma = 253
7558 AutoGammaImage = 254
7559 AutoLevel = 255
7560 AutoLevelImage = 256
7561 LevelColors = 257
7562 LevelImageColors = 258
7563 Clamp = 259
7564 ClampImage = 260
7565 BrightnessContrast = 261
7566 BrightnessContrastImage = 262
7567 Morphology = 263
7568 MorphologyImage = 264
7569 Color = 265
7570 ColorImage = 266
7571 Mode = 267
7572 ModeImage = 268
7573 Statistic = 269
7574 StatisticImage = 270
7575 Perceptible = 271
7576 PerceptibleImage = 272
7577 Poly = 273
7578 PolyImage = 274
7579 Grayscale = 275
7580 GrayscaleImage = 276
cristy4ceadb82014-03-29 15:30:43 +00007581 CannyEdge = 278
7582 CannyEdgeImage = 279
cristy2fc10e52014-04-26 14:13:53 +00007583 HoughLine = 280
7584 HoughLineImage = 281
7585 MeanShift = 282
7586 MeanShiftImage = 283
cristy3b207f82014-09-27 14:21:20 +00007587 Kuwahara = 284
7588 KuwaharaImage = 285
cristy6e0b3bc2014-10-19 17:51:42 +00007589 ConnectedComponent = 286
7590 ConnectedComponentImage = 287
cristy0b94b392015-06-22 18:56:37 +00007591 CopyPixels = 288
7592 CopyImagePixels = 289
cristy4a3ce0a2013-08-03 20:06:59 +00007593 MogrifyRegion = 666
7594 PPCODE:
7595 {
7596 AffineMatrix
7597 affine,
7598 current;
7599
7600 char
7601 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007602 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007603
7604 ChannelType
7605 channel,
7606 channel_mask;
7607
7608 CompositeOperator
7609 compose;
7610
7611 const char
7612 *attribute,
7613 *value;
7614
7615 double
7616 angle;
7617
7618 ExceptionInfo
7619 *exception;
7620
7621 GeometryInfo
7622 geometry_info;
7623
7624 Image
7625 *image,
7626 *next,
7627 *region_image;
7628
7629 MagickBooleanType
7630 status;
7631
7632 MagickStatusType
7633 flags;
7634
7635 PixelInfo
7636 fill_color;
7637
7638 RectangleInfo
7639 geometry,
7640 region_info;
7641
7642 register ssize_t
7643 i;
7644
7645 ssize_t
7646 base,
7647 j,
7648 number_images;
7649
7650 struct Methods
7651 *rp;
7652
7653 struct PackageInfo
7654 *info;
7655
7656 SV
7657 *perl_exception,
7658 **pv,
7659 *reference,
7660 **reference_vector;
7661
7662 struct ArgumentList
7663 argument_list[MaxArguments];
7664
7665 PERL_UNUSED_VAR(ref);
7666 PERL_UNUSED_VAR(ix);
7667 exception=AcquireExceptionInfo();
7668 perl_exception=newSVpv("",0);
7669 reference_vector=NULL;
7670 region_image=NULL;
7671 number_images=0;
7672 base=2;
7673 if (sv_isobject(ST(0)) == 0)
7674 {
7675 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7676 PackageName);
7677 goto PerlException;
7678 }
7679 reference=SvRV(ST(0));
7680 region_info.width=0;
7681 region_info.height=0;
7682 region_info.x=0;
7683 region_info.y=0;
7684 region_image=(Image *) NULL;
7685 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7686 if (ix && (ix != 666))
7687 {
7688 /*
7689 Called as Method(...)
7690 */
7691 ix=(ix+1)/2;
7692 rp=(&Methods[ix-1]);
7693 attribute=rp->name;
7694 }
7695 else
7696 {
7697 /*
7698 Called as Mogrify("Method",...)
7699 */
7700 attribute=(char *) SvPV(ST(1),na);
7701 if (ix)
7702 {
7703 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7704 attribute=(char *) SvPV(ST(2),na);
7705 base++;
7706 }
7707 for (rp=Methods; ; rp++)
7708 {
7709 if (rp >= EndOf(Methods))
7710 {
7711 ThrowPerlException(exception,OptionError,
7712 "UnrecognizedPerlMagickMethod",attribute);
7713 goto PerlException;
7714 }
7715 if (strEQcase(attribute,rp->name))
7716 break;
7717 }
7718 ix=rp-Methods+1;
7719 base++;
7720 }
7721 if (image == (Image *) NULL)
7722 {
7723 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7724 goto PerlException;
7725 }
7726 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7727 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7728 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7729 {
7730 Arguments
7731 *pp,
7732 *qq;
7733
7734 ssize_t
7735 ssize_test;
7736
7737 struct ArgumentList
7738 *al;
7739
7740 SV
7741 *sv;
7742
7743 sv=NULL;
7744 ssize_test=0;
7745 pp=(Arguments *) NULL;
7746 qq=rp->arguments;
7747 if (i == items)
7748 {
7749 pp=rp->arguments,
7750 sv=ST(i-1);
7751 }
7752 else
7753 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7754 {
7755 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7756 break;
7757 if (strEQcase(attribute,qq->method) > ssize_test)
7758 {
7759 pp=qq;
7760 ssize_test=strEQcase(attribute,qq->method);
7761 }
7762 }
7763 if (pp == (Arguments *) NULL)
7764 {
7765 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7766 attribute);
7767 goto continue_outer_loop;
7768 }
7769 al=(&argument_list[pp-rp->arguments]);
7770 switch (pp->type)
7771 {
7772 case ArrayReference:
7773 {
7774 if (SvTYPE(sv) != SVt_RV)
7775 {
cristy151b66d2015-04-15 10:50:31 +00007776 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007777 "invalid %.60s value",pp->method);
7778 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7779 goto continue_outer_loop;
7780 }
7781 al->array_reference=SvRV(sv);
7782 break;
7783 }
7784 case RealReference:
7785 {
7786 al->real_reference=SvNV(sv);
7787 break;
7788 }
7789 case FileReference:
7790 {
7791 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7792 break;
7793 }
7794 case ImageReference:
7795 {
7796 if (!sv_isobject(sv) ||
7797 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7798 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7799 {
7800 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7801 PackageName);
7802 goto PerlException;
7803 }
7804 break;
7805 }
7806 case IntegerReference:
7807 {
7808 al->integer_reference=SvIV(sv);
7809 break;
7810 }
7811 case StringReference:
7812 {
7813 al->string_reference=(char *) SvPV(sv,al->length);
7814 if (sv_isobject(sv))
7815 al->image_reference=SetupList(aTHX_ SvRV(sv),
7816 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7817 break;
7818 }
7819 default:
7820 {
7821 /*
7822 Is a string; look up name.
7823 */
7824 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7825 {
7826 al->string_reference=(char *) SvPV(sv,al->length);
7827 al->integer_reference=(-1);
7828 break;
7829 }
7830 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7831 MagickFalse,SvPV(sv,na));
7832 if (pp->type == MagickChannelOptions)
7833 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7834 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7835 {
cristy151b66d2015-04-15 10:50:31 +00007836 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007837 "invalid %.60s value",pp->method);
7838 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7839 goto continue_outer_loop;
7840 }
7841 break;
7842 }
7843 }
7844 attribute_flag[pp-rp->arguments]++;
7845 continue_outer_loop: ;
7846 }
7847 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7848 pv=reference_vector;
7849 SetGeometryInfo(&geometry_info);
7850 channel=DefaultChannels;
7851 for (next=image; next; next=next->next)
7852 {
7853 image=next;
7854 SetGeometry(image,&geometry);
7855 if ((region_info.width*region_info.height) != 0)
7856 {
7857 region_image=image;
7858 image=CropImage(image,&region_info,exception);
7859 }
7860 switch (ix)
7861 {
7862 default:
7863 {
cristy151b66d2015-04-15 10:50:31 +00007864 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007865 ThrowPerlException(exception,OptionError,
7866 "UnrecognizedPerlMagickMethod",message);
7867 goto PerlException;
7868 }
7869 case 1: /* Comment */
7870 {
7871 if (attribute_flag[0] == 0)
7872 argument_list[0].string_reference=(char *) NULL;
7873 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7874 info ? info->image_info : (ImageInfo *) NULL,image,
7875 argument_list[0].string_reference,exception),exception);
7876 break;
7877 }
7878 case 2: /* Label */
7879 {
7880 if (attribute_flag[0] == 0)
7881 argument_list[0].string_reference=(char *) NULL;
7882 (void) SetImageProperty(image,"label",InterpretImageProperties(
7883 info ? info->image_info : (ImageInfo *) NULL,image,
7884 argument_list[0].string_reference,exception),exception);
7885 break;
7886 }
7887 case 3: /* AddNoise */
7888 {
7889 double
7890 attenuate;
7891
7892 if (attribute_flag[0] == 0)
7893 argument_list[0].integer_reference=UniformNoise;
7894 attenuate=1.0;
7895 if (attribute_flag[1] != 0)
7896 attenuate=argument_list[1].real_reference;
7897 if (attribute_flag[2] != 0)
7898 channel=(ChannelType) argument_list[2].integer_reference;
7899 channel_mask=SetImageChannelMask(image,channel);
7900 image=AddNoiseImage(image,(NoiseType)
7901 argument_list[0].integer_reference,attenuate,exception);
7902 if (image != (Image *) NULL)
7903 (void) SetImageChannelMask(image,channel_mask);
7904 break;
7905 }
7906 case 4: /* Colorize */
7907 {
7908 PixelInfo
7909 target;
7910
7911 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7912 0,0,&target,exception);
7913 if (attribute_flag[0] != 0)
7914 (void) QueryColorCompliance(argument_list[0].string_reference,
7915 AllCompliance,&target,exception);
7916 if (attribute_flag[1] == 0)
7917 argument_list[1].string_reference="100%";
7918 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7919 exception);
7920 break;
7921 }
7922 case 5: /* Border */
7923 {
7924 CompositeOperator
7925 compose;
7926
7927 geometry.width=0;
7928 geometry.height=0;
7929 if (attribute_flag[0] != 0)
7930 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7931 &geometry,exception);
7932 if (attribute_flag[1] != 0)
7933 geometry.width=argument_list[1].integer_reference;
7934 if (attribute_flag[2] != 0)
7935 geometry.height=argument_list[2].integer_reference;
7936 if (attribute_flag[3] != 0)
7937 QueryColorCompliance(argument_list[3].string_reference,
7938 AllCompliance,&image->border_color,exception);
7939 if (attribute_flag[4] != 0)
7940 QueryColorCompliance(argument_list[4].string_reference,
7941 AllCompliance,&image->border_color,exception);
7942 if (attribute_flag[5] != 0)
7943 QueryColorCompliance(argument_list[5].string_reference,
7944 AllCompliance,&image->border_color,exception);
7945 compose=image->compose;
7946 if (attribute_flag[6] != 0)
7947 compose=(CompositeOperator) argument_list[6].integer_reference;
7948 image=BorderImage(image,&geometry,compose,exception);
7949 break;
7950 }
7951 case 6: /* Blur */
7952 {
7953 if (attribute_flag[0] != 0)
7954 {
7955 flags=ParseGeometry(argument_list[0].string_reference,
7956 &geometry_info);
7957 if ((flags & SigmaValue) == 0)
7958 geometry_info.sigma=1.0;
7959 }
7960 if (attribute_flag[1] != 0)
7961 geometry_info.rho=argument_list[1].real_reference;
7962 if (attribute_flag[2] != 0)
7963 geometry_info.sigma=argument_list[2].real_reference;
7964 if (attribute_flag[3] != 0)
7965 channel=(ChannelType) argument_list[3].integer_reference;
7966 channel_mask=SetImageChannelMask(image,channel);
7967 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
7968 exception);
7969 if (image != (Image *) NULL)
7970 (void) SetImageChannelMask(image,channel_mask);
7971 break;
7972 }
7973 case 7: /* Chop */
7974 {
cristy260bd762014-08-15 12:46:34 +00007975 if (attribute_flag[5] != 0)
7976 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00007977 if (attribute_flag[0] != 0)
7978 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7979 &geometry,exception);
7980 if (attribute_flag[1] != 0)
7981 geometry.width=argument_list[1].integer_reference;
7982 if (attribute_flag[2] != 0)
7983 geometry.height=argument_list[2].integer_reference;
7984 if (attribute_flag[3] != 0)
7985 geometry.x=argument_list[3].integer_reference;
7986 if (attribute_flag[4] != 0)
7987 geometry.y=argument_list[4].integer_reference;
7988 image=ChopImage(image,&geometry,exception);
7989 break;
7990 }
7991 case 8: /* Crop */
7992 {
7993 if (attribute_flag[6] != 0)
7994 image->gravity=(GravityType) argument_list[6].integer_reference;
7995 if (attribute_flag[0] != 0)
7996 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7997 &geometry,exception);
7998 if (attribute_flag[1] != 0)
7999 geometry.width=argument_list[1].integer_reference;
8000 if (attribute_flag[2] != 0)
8001 geometry.height=argument_list[2].integer_reference;
8002 if (attribute_flag[3] != 0)
8003 geometry.x=argument_list[3].integer_reference;
8004 if (attribute_flag[4] != 0)
8005 geometry.y=argument_list[4].integer_reference;
8006 if (attribute_flag[5] != 0)
8007 image->fuzz=StringToDoubleInterval(
8008 argument_list[5].string_reference,(double) QuantumRange+1.0);
8009 image=CropImage(image,&geometry,exception);
8010 break;
8011 }
8012 case 9: /* Despeckle */
8013 {
8014 image=DespeckleImage(image,exception);
8015 break;
8016 }
8017 case 10: /* Edge */
8018 {
8019 if (attribute_flag[0] != 0)
8020 geometry_info.rho=argument_list[0].real_reference;
8021 image=EdgeImage(image,geometry_info.rho,exception);
8022 break;
8023 }
8024 case 11: /* Emboss */
8025 {
8026 if (attribute_flag[0] != 0)
8027 {
8028 flags=ParseGeometry(argument_list[0].string_reference,
8029 &geometry_info);
8030 if ((flags & SigmaValue) == 0)
8031 geometry_info.sigma=1.0;
8032 }
8033 if (attribute_flag[1] != 0)
8034 geometry_info.rho=argument_list[1].real_reference;
8035 if (attribute_flag[2] != 0)
8036 geometry_info.sigma=argument_list[2].real_reference;
8037 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8038 exception);
8039 break;
8040 }
8041 case 12: /* Enhance */
8042 {
8043 image=EnhanceImage(image,exception);
8044 break;
8045 }
8046 case 13: /* Flip */
8047 {
8048 image=FlipImage(image,exception);
8049 break;
8050 }
8051 case 14: /* Flop */
8052 {
8053 image=FlopImage(image,exception);
8054 break;
8055 }
8056 case 15: /* Frame */
8057 {
8058 CompositeOperator
8059 compose;
8060
8061 FrameInfo
8062 frame_info;
8063
8064 if (attribute_flag[0] != 0)
8065 {
8066 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8067 &geometry,exception);
8068 frame_info.width=geometry.width;
8069 frame_info.height=geometry.height;
8070 frame_info.outer_bevel=geometry.x;
8071 frame_info.inner_bevel=geometry.y;
8072 }
8073 if (attribute_flag[1] != 0)
8074 frame_info.width=argument_list[1].integer_reference;
8075 if (attribute_flag[2] != 0)
8076 frame_info.height=argument_list[2].integer_reference;
8077 if (attribute_flag[3] != 0)
8078 frame_info.inner_bevel=argument_list[3].integer_reference;
8079 if (attribute_flag[4] != 0)
8080 frame_info.outer_bevel=argument_list[4].integer_reference;
8081 if (attribute_flag[5] != 0)
8082 QueryColorCompliance(argument_list[5].string_reference,
8083 AllCompliance,&fill_color,exception);
8084 if (attribute_flag[6] != 0)
8085 QueryColorCompliance(argument_list[6].string_reference,
8086 AllCompliance,&fill_color,exception);
8087 frame_info.x=(ssize_t) frame_info.width;
8088 frame_info.y=(ssize_t) frame_info.height;
8089 frame_info.width=image->columns+2*frame_info.x;
8090 frame_info.height=image->rows+2*frame_info.y;
8091 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
8092 image->matte_color=fill_color;
8093 compose=image->compose;
8094 if (attribute_flag[7] != 0)
8095 compose=(CompositeOperator) argument_list[7].integer_reference;
8096 image=FrameImage(image,&frame_info,compose,exception);
8097 break;
8098 }
8099 case 16: /* Implode */
8100 {
8101 PixelInterpolateMethod
8102 method;
8103
8104 if (attribute_flag[0] == 0)
8105 argument_list[0].real_reference=0.5;
8106 method=UndefinedInterpolatePixel;
8107 if (attribute_flag[1] != 0)
8108 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8109 image=ImplodeImage(image,argument_list[0].real_reference,
8110 method,exception);
8111 break;
8112 }
8113 case 17: /* Magnify */
8114 {
8115 image=MagnifyImage(image,exception);
8116 break;
8117 }
8118 case 18: /* MedianFilter */
8119 {
8120 if (attribute_flag[0] != 0)
8121 {
8122 flags=ParseGeometry(argument_list[0].string_reference,
8123 &geometry_info);
8124 if ((flags & SigmaValue) == 0)
8125 geometry_info.sigma=geometry_info.rho;
8126 }
8127 if (attribute_flag[1] != 0)
8128 geometry_info.rho=argument_list[1].real_reference;
8129 if (attribute_flag[2] != 0)
8130 geometry_info.sigma=argument_list[2].real_reference;
8131 if (attribute_flag[3] != 0)
8132 channel=(ChannelType) argument_list[3].integer_reference;
8133 channel_mask=SetImageChannelMask(image,channel);
8134 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8135 (size_t) geometry_info.sigma,exception);
8136 if (image != (Image *) NULL)
8137 (void) SetImageChannelMask(image,channel_mask);
8138 break;
8139 }
8140 case 19: /* Minify */
8141 {
8142 image=MinifyImage(image,exception);
8143 break;
8144 }
8145 case 20: /* OilPaint */
8146 {
8147 if (attribute_flag[0] == 0)
8148 argument_list[0].real_reference=0.0;
8149 if (attribute_flag[1] == 0)
8150 argument_list[1].real_reference=1.0;
8151 image=OilPaintImage(image,argument_list[0].real_reference,
8152 argument_list[1].real_reference,exception);
8153 break;
8154 }
8155 case 21: /* ReduceNoise */
8156 {
8157 if (attribute_flag[0] != 0)
8158 {
8159 flags=ParseGeometry(argument_list[0].string_reference,
8160 &geometry_info);
8161 if ((flags & SigmaValue) == 0)
8162 geometry_info.sigma=1.0;
8163 }
8164 if (attribute_flag[1] != 0)
8165 geometry_info.rho=argument_list[1].real_reference;
8166 if (attribute_flag[2] != 0)
8167 geometry_info.sigma=argument_list[2].real_reference;
8168 if (attribute_flag[3] != 0)
8169 channel=(ChannelType) argument_list[3].integer_reference;
8170 channel_mask=SetImageChannelMask(image,channel);
8171 image=StatisticImage(image,NonpeakStatistic,(size_t)
8172 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8173 if (image != (Image *) NULL)
8174 (void) SetImageChannelMask(image,channel_mask);
8175 break;
8176 }
8177 case 22: /* Roll */
8178 {
8179 if (attribute_flag[0] != 0)
8180 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8181 &geometry,exception);
8182 if (attribute_flag[1] != 0)
8183 geometry.x=argument_list[1].integer_reference;
8184 if (attribute_flag[2] != 0)
8185 geometry.y=argument_list[2].integer_reference;
8186 image=RollImage(image,geometry.x,geometry.y,exception);
8187 break;
8188 }
8189 case 23: /* Rotate */
8190 {
8191 if (attribute_flag[0] == 0)
8192 argument_list[0].real_reference=90.0;
8193 if (attribute_flag[1] != 0)
8194 {
8195 QueryColorCompliance(argument_list[1].string_reference,
8196 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008197 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8198 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008199 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8200 }
8201 image=RotateImage(image,argument_list[0].real_reference,exception);
8202 break;
8203 }
8204 case 24: /* Sample */
8205 {
8206 if (attribute_flag[0] != 0)
8207 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8208 &geometry,exception);
8209 if (attribute_flag[1] != 0)
8210 geometry.width=argument_list[1].integer_reference;
8211 if (attribute_flag[2] != 0)
8212 geometry.height=argument_list[2].integer_reference;
8213 image=SampleImage(image,geometry.width,geometry.height,exception);
8214 break;
8215 }
8216 case 25: /* Scale */
8217 {
8218 if (attribute_flag[0] != 0)
8219 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8220 &geometry,exception);
8221 if (attribute_flag[1] != 0)
8222 geometry.width=argument_list[1].integer_reference;
8223 if (attribute_flag[2] != 0)
8224 geometry.height=argument_list[2].integer_reference;
8225 image=ScaleImage(image,geometry.width,geometry.height,exception);
8226 break;
8227 }
8228 case 26: /* Shade */
8229 {
8230 if (attribute_flag[0] != 0)
8231 {
8232 flags=ParseGeometry(argument_list[0].string_reference,
8233 &geometry_info);
8234 if ((flags & SigmaValue) == 0)
8235 geometry_info.sigma=0.0;
8236 }
8237 if (attribute_flag[1] != 0)
8238 geometry_info.rho=argument_list[1].real_reference;
8239 if (attribute_flag[2] != 0)
8240 geometry_info.sigma=argument_list[2].real_reference;
8241 image=ShadeImage(image,
8242 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8243 geometry_info.rho,geometry_info.sigma,exception);
8244 break;
8245 }
8246 case 27: /* Sharpen */
8247 {
8248 if (attribute_flag[0] != 0)
8249 {
8250 flags=ParseGeometry(argument_list[0].string_reference,
8251 &geometry_info);
8252 if ((flags & SigmaValue) == 0)
8253 geometry_info.sigma=1.0;
8254 }
8255 if (attribute_flag[1] != 0)
8256 geometry_info.rho=argument_list[1].real_reference;
8257 if (attribute_flag[2] != 0)
8258 geometry_info.sigma=argument_list[2].real_reference;
8259 if (attribute_flag[3] != 0)
8260 channel=(ChannelType) argument_list[3].integer_reference;
8261 channel_mask=SetImageChannelMask(image,channel);
8262 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8263 exception);
8264 if (image != (Image *) NULL)
8265 (void) SetImageChannelMask(image,channel_mask);
8266 break;
8267 }
8268 case 28: /* Shear */
8269 {
8270 if (attribute_flag[0] != 0)
8271 {
8272 flags=ParseGeometry(argument_list[0].string_reference,
8273 &geometry_info);
8274 if ((flags & SigmaValue) == 0)
8275 geometry_info.sigma=geometry_info.rho;
8276 }
8277 if (attribute_flag[1] != 0)
8278 geometry_info.rho=argument_list[1].real_reference;
8279 if (attribute_flag[2] != 0)
8280 geometry_info.sigma=argument_list[2].real_reference;
8281 if (attribute_flag[3] != 0)
8282 QueryColorCompliance(argument_list[3].string_reference,
8283 AllCompliance,&image->background_color,exception);
8284 if (attribute_flag[4] != 0)
8285 QueryColorCompliance(argument_list[4].string_reference,
8286 AllCompliance,&image->background_color,exception);
8287 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8288 exception);
8289 break;
8290 }
8291 case 29: /* Spread */
8292 {
Cristye3319c12015-08-24 07:11:48 -04008293 PixelInterpolateMethod
8294 method;
8295
cristy4a3ce0a2013-08-03 20:06:59 +00008296 if (attribute_flag[0] == 0)
8297 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008298 method=UndefinedInterpolatePixel;
8299 if (attribute_flag[1] != 0)
8300 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8301 image=SpreadImage(image,method,argument_list[0].real_reference,
8302 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008303 break;
8304 }
8305 case 30: /* Swirl */
8306 {
8307 PixelInterpolateMethod
8308 method;
8309
8310 if (attribute_flag[0] == 0)
8311 argument_list[0].real_reference=50.0;
8312 method=UndefinedInterpolatePixel;
8313 if (attribute_flag[1] != 0)
8314 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8315 image=SwirlImage(image,argument_list[0].real_reference,
8316 method,exception);
8317 break;
8318 }
8319 case 31: /* Resize */
8320 case 32: /* Zoom */
8321 {
8322 if (attribute_flag[0] != 0)
8323 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8324 &geometry,exception);
8325 if (attribute_flag[1] != 0)
8326 geometry.width=argument_list[1].integer_reference;
8327 if (attribute_flag[2] != 0)
8328 geometry.height=argument_list[2].integer_reference;
8329 if (attribute_flag[3] == 0)
8330 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8331 if (attribute_flag[4] != 0)
8332 SetImageArtifact(image,"filter:support",
8333 argument_list[4].string_reference);
8334 image=ResizeImage(image,geometry.width,geometry.height,
8335 (FilterTypes) argument_list[3].integer_reference,
8336 exception);
8337 break;
8338 }
8339 case 33: /* Annotate */
8340 {
8341 DrawInfo
8342 *draw_info;
8343
8344 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8345 (DrawInfo *) NULL);
8346 if (attribute_flag[0] != 0)
8347 {
8348 char
8349 *text;
8350
8351 text=InterpretImageProperties(info ? info->image_info :
8352 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8353 exception);
8354 (void) CloneString(&draw_info->text,text);
8355 text=DestroyString(text);
8356 }
8357 if (attribute_flag[1] != 0)
8358 (void) CloneString(&draw_info->font,
8359 argument_list[1].string_reference);
8360 if (attribute_flag[2] != 0)
8361 draw_info->pointsize=argument_list[2].real_reference;
8362 if (attribute_flag[3] != 0)
8363 (void) CloneString(&draw_info->density,
8364 argument_list[3].string_reference);
8365 if (attribute_flag[4] != 0)
8366 (void) QueryColorCompliance(argument_list[4].string_reference,
8367 AllCompliance,&draw_info->undercolor,exception);
8368 if (attribute_flag[5] != 0)
8369 {
8370 (void) QueryColorCompliance(argument_list[5].string_reference,
8371 AllCompliance,&draw_info->stroke,exception);
8372 if (argument_list[5].image_reference != (Image *) NULL)
8373 draw_info->stroke_pattern=CloneImage(
8374 argument_list[5].image_reference,0,0,MagickTrue,exception);
8375 }
8376 if (attribute_flag[6] != 0)
8377 {
8378 (void) QueryColorCompliance(argument_list[6].string_reference,
8379 AllCompliance,&draw_info->fill,exception);
8380 if (argument_list[6].image_reference != (Image *) NULL)
8381 draw_info->fill_pattern=CloneImage(
8382 argument_list[6].image_reference,0,0,MagickTrue,exception);
8383 }
8384 if (attribute_flag[7] != 0)
8385 {
8386 (void) CloneString(&draw_info->geometry,
8387 argument_list[7].string_reference);
8388 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8389 &geometry,exception);
8390 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8391 geometry_info.sigma=geometry_info.xi;
8392 }
8393 if (attribute_flag[8] != 0)
8394 (void) QueryColorCompliance(argument_list[8].string_reference,
8395 AllCompliance,&draw_info->fill,exception);
8396 if (attribute_flag[11] != 0)
8397 draw_info->gravity=(GravityType)
8398 argument_list[11].integer_reference;
8399 if (attribute_flag[25] != 0)
8400 {
8401 AV
8402 *av;
8403
8404 av=(AV *) argument_list[25].array_reference;
8405 if ((av_len(av) != 3) && (av_len(av) != 5))
8406 {
8407 ThrowPerlException(exception,OptionError,
8408 "affine matrix must have 4 or 6 elements",PackageName);
8409 goto PerlException;
8410 }
8411 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8412 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8413 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8414 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8415 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8416 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8417 {
8418 ThrowPerlException(exception,OptionError,
8419 "affine matrix is singular",PackageName);
8420 goto PerlException;
8421 }
8422 if (av_len(av) == 5)
8423 {
8424 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8425 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8426 }
8427 }
8428 for (j=12; j < 17; j++)
8429 {
8430 if (attribute_flag[j] == 0)
8431 continue;
8432 value=argument_list[j].string_reference;
8433 angle=argument_list[j].real_reference;
8434 current=draw_info->affine;
8435 GetAffineMatrix(&affine);
8436 switch (j)
8437 {
8438 case 12:
8439 {
8440 /*
8441 Translate.
8442 */
8443 flags=ParseGeometry(value,&geometry_info);
8444 affine.tx=geometry_info.xi;
8445 affine.ty=geometry_info.psi;
8446 if ((flags & PsiValue) == 0)
8447 affine.ty=affine.tx;
8448 break;
8449 }
8450 case 13:
8451 {
8452 /*
8453 Scale.
8454 */
8455 flags=ParseGeometry(value,&geometry_info);
8456 affine.sx=geometry_info.rho;
8457 affine.sy=geometry_info.sigma;
8458 if ((flags & SigmaValue) == 0)
8459 affine.sy=affine.sx;
8460 break;
8461 }
8462 case 14:
8463 {
8464 /*
8465 Rotate.
8466 */
8467 if (angle == 0.0)
8468 break;
8469 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8470 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8471 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8472 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8473 break;
8474 }
8475 case 15:
8476 {
8477 /*
8478 SkewX.
8479 */
8480 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8481 break;
8482 }
8483 case 16:
8484 {
8485 /*
8486 SkewY.
8487 */
8488 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8489 break;
8490 }
8491 }
8492 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8493 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8494 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8495 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8496 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8497 current.tx;
8498 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8499 current.ty;
8500 }
8501 if (attribute_flag[9] == 0)
8502 argument_list[9].real_reference=0.0;
8503 if (attribute_flag[10] == 0)
8504 argument_list[10].real_reference=0.0;
8505 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8506 {
8507 char
cristy151b66d2015-04-15 10:50:31 +00008508 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008509
cristy151b66d2015-04-15 10:50:31 +00008510 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008511 (double) argument_list[9].real_reference+draw_info->affine.tx,
8512 (double) argument_list[10].real_reference+draw_info->affine.ty);
8513 (void) CloneString(&draw_info->geometry,geometry);
8514 }
8515 if (attribute_flag[17] != 0)
8516 draw_info->stroke_width=argument_list[17].real_reference;
8517 if (attribute_flag[18] != 0)
8518 {
8519 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8520 MagickTrue : MagickFalse;
8521 draw_info->stroke_antialias=draw_info->text_antialias;
8522 }
8523 if (attribute_flag[19] != 0)
8524 (void) CloneString(&draw_info->family,
8525 argument_list[19].string_reference);
8526 if (attribute_flag[20] != 0)
8527 draw_info->style=(StyleType) argument_list[20].integer_reference;
8528 if (attribute_flag[21] != 0)
8529 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8530 if (attribute_flag[22] != 0)
8531 draw_info->weight=argument_list[22].integer_reference;
8532 if (attribute_flag[23] != 0)
8533 draw_info->align=(AlignType) argument_list[23].integer_reference;
8534 if (attribute_flag[24] != 0)
8535 (void) CloneString(&draw_info->encoding,
8536 argument_list[24].string_reference);
8537 if (attribute_flag[25] != 0)
8538 draw_info->fill_pattern=CloneImage(
8539 argument_list[25].image_reference,0,0,MagickTrue,exception);
8540 if (attribute_flag[26] != 0)
8541 draw_info->fill_pattern=CloneImage(
8542 argument_list[26].image_reference,0,0,MagickTrue,exception);
8543 if (attribute_flag[27] != 0)
8544 draw_info->stroke_pattern=CloneImage(
8545 argument_list[27].image_reference,0,0,MagickTrue,exception);
8546 if (attribute_flag[29] != 0)
8547 draw_info->kerning=argument_list[29].real_reference;
8548 if (attribute_flag[30] != 0)
8549 draw_info->interline_spacing=argument_list[30].real_reference;
8550 if (attribute_flag[31] != 0)
8551 draw_info->interword_spacing=argument_list[31].real_reference;
8552 if (attribute_flag[32] != 0)
8553 draw_info->direction=(DirectionType)
8554 argument_list[32].integer_reference;
8555 (void) AnnotateImage(image,draw_info,exception);
8556 draw_info=DestroyDrawInfo(draw_info);
8557 break;
8558 }
8559 case 34: /* ColorFloodfill */
8560 {
8561 DrawInfo
8562 *draw_info;
8563
8564 MagickBooleanType
8565 invert;
8566
8567 PixelInfo
8568 target;
8569
8570 draw_info=CloneDrawInfo(info ? info->image_info :
8571 (ImageInfo *) NULL,(DrawInfo *) NULL);
8572 if (attribute_flag[0] != 0)
8573 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8574 &geometry,exception);
8575 if (attribute_flag[1] != 0)
8576 geometry.x=argument_list[1].integer_reference;
8577 if (attribute_flag[2] != 0)
8578 geometry.y=argument_list[2].integer_reference;
8579 if (attribute_flag[3] != 0)
8580 (void) QueryColorCompliance(argument_list[3].string_reference,
8581 AllCompliance,&draw_info->fill,exception);
8582 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8583 geometry.x,geometry.y,&target,exception);
8584 invert=MagickFalse;
8585 if (attribute_flag[4] != 0)
8586 {
8587 QueryColorCompliance(argument_list[4].string_reference,
8588 AllCompliance,&target,exception);
8589 invert=MagickTrue;
8590 }
8591 if (attribute_flag[5] != 0)
8592 image->fuzz=StringToDoubleInterval(
8593 argument_list[5].string_reference,(double) QuantumRange+1.0);
8594 if (attribute_flag[6] != 0)
8595 invert=(MagickBooleanType) argument_list[6].integer_reference;
8596 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8597 geometry.y,invert,exception);
8598 draw_info=DestroyDrawInfo(draw_info);
8599 break;
8600 }
8601 case 35: /* Composite */
8602 {
8603 char
cristy151b66d2015-04-15 10:50:31 +00008604 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008605
8606 Image
8607 *composite_image,
8608 *rotate_image;
8609
8610 MagickBooleanType
8611 clip_to_self;
8612
8613 compose=OverCompositeOp;
8614 if (attribute_flag[0] != 0)
8615 composite_image=argument_list[0].image_reference;
8616 else
8617 {
8618 ThrowPerlException(exception,OptionError,
8619 "CompositeImageRequired",PackageName);
8620 goto PerlException;
8621 }
8622 /*
8623 Parameter Handling used for BOTH normal and tiled composition.
8624 */
8625 if (attribute_flag[1] != 0) /* compose */
8626 compose=(CompositeOperator) argument_list[1].integer_reference;
8627 if (attribute_flag[6] != 0) /* opacity */
8628 {
8629 if (compose != DissolveCompositeOp)
8630 (void) SetImageAlpha(composite_image,(Quantum)
8631 StringToDoubleInterval(argument_list[6].string_reference,
8632 (double) QuantumRange+1.0),exception);
8633 else
8634 {
8635 CacheView
8636 *composite_view;
8637
8638 double
8639 opacity;
8640
8641 MagickBooleanType
8642 sync;
8643
8644 register ssize_t
8645 x;
8646
8647 register Quantum
8648 *q;
8649
8650 ssize_t
8651 y;
8652
8653 /*
8654 Handle dissolve composite operator (patch by
8655 Kevin A. McGrail).
8656 */
8657 (void) CloneString(&image->geometry,
8658 argument_list[6].string_reference);
8659 opacity=(Quantum) StringToDoubleInterval(
8660 argument_list[6].string_reference,(double) QuantumRange+
8661 1.0);
cristy17f11b02014-12-20 19:37:04 +00008662 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008663 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8664 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8665 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8666 {
8667 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8668 composite_image->columns,1,exception);
8669 for (x=0; x < (ssize_t) composite_image->columns; x++)
8670 {
8671 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8672 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8673 q);
8674 q+=GetPixelChannels(composite_image);
8675 }
8676 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8677 if (sync == MagickFalse)
8678 break;
8679 }
8680 composite_view=DestroyCacheView(composite_view);
8681 }
8682 }
8683 if (attribute_flag[9] != 0) /* "color=>" */
8684 QueryColorCompliance(argument_list[9].string_reference,
8685 AllCompliance,&composite_image->background_color,exception);
8686 if (attribute_flag[12] != 0) /* "interpolate=>" */
8687 image->interpolate=(PixelInterpolateMethod)
8688 argument_list[12].integer_reference;
8689 if (attribute_flag[13] != 0) /* "args=>" */
8690 (void) SetImageArtifact(composite_image,"compose:args",
8691 argument_list[13].string_reference);
8692 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8693 (void) SetImageArtifact(composite_image,"compose:args",
8694 argument_list[14].string_reference);
8695 clip_to_self=MagickTrue;
8696 if (attribute_flag[15] != 0)
8697 clip_to_self=(MagickBooleanType)
8698 argument_list[15].integer_reference;
8699 /*
8700 Tiling Composition (with orthogonal rotate).
8701 */
8702 rotate_image=(Image *) NULL;
8703 if (attribute_flag[8] != 0) /* "rotate=>" */
8704 {
8705 /*
8706 Rotate image.
8707 */
8708 rotate_image=RotateImage(composite_image,
8709 argument_list[8].real_reference,exception);
8710 if (rotate_image == (Image *) NULL)
8711 break;
8712 }
8713 if ((attribute_flag[7] != 0) &&
8714 (argument_list[7].integer_reference != 0)) /* tile */
8715 {
8716 ssize_t
8717 x,
8718 y;
8719
8720 /*
8721 Tile the composite image.
8722 */
8723 if (attribute_flag[8] != 0) /* "tile=>" */
8724 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8725 "false");
8726 else
8727 (void) SetImageArtifact(composite_image,
8728 "compose:outside-overlay","false");
8729 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8730 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8731 {
8732 if (attribute_flag[8] != 0) /* rotate */
8733 (void) CompositeImage(image,rotate_image,compose,
8734 MagickTrue,x,y,exception);
8735 else
8736 (void) CompositeImage(image,composite_image,compose,
8737 MagickTrue,x,y,exception);
8738 }
8739 if (attribute_flag[8] != 0) /* rotate */
8740 rotate_image=DestroyImage(rotate_image);
8741 break;
8742 }
8743 /*
8744 Parameter Handling used used ONLY for normal composition.
8745 */
8746 if (attribute_flag[5] != 0) /* gravity */
8747 image->gravity=(GravityType) argument_list[5].integer_reference;
8748 if (attribute_flag[2] != 0) /* geometry offset */
8749 {
8750 SetGeometry(image,&geometry);
8751 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8752 &geometry);
8753 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8754 &geometry);
8755 }
8756 if (attribute_flag[3] != 0) /* x offset */
8757 geometry.x=argument_list[3].integer_reference;
8758 if (attribute_flag[4] != 0) /* y offset */
8759 geometry.y=argument_list[4].integer_reference;
8760 if (attribute_flag[10] != 0) /* mask */
8761 {
8762 if ((image->compose == DisplaceCompositeOp) ||
8763 (image->compose == DistortCompositeOp))
8764 {
8765 /*
8766 Merge Y displacement into X displacement image.
8767 */
8768 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8769 exception);
8770 (void) CompositeImage(composite_image,
8771 argument_list[10].image_reference,CopyGreenCompositeOp,
8772 MagickTrue,0,0,exception);
8773 }
8774 else
8775 {
8776 Image
8777 *mask_image;
8778
8779 /*
8780 Set a blending mask for the composition.
8781 */
8782 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8783 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008784 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008785 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008786 mask_image=DestroyImage(mask_image);
8787 }
8788 }
8789 if (attribute_flag[11] != 0) /* channel */
8790 channel=(ChannelType) argument_list[11].integer_reference;
8791 /*
8792 Composite two images (normal composition).
8793 */
cristy151b66d2015-04-15 10:50:31 +00008794 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008795 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8796 (double) composite_image->rows,(double) geometry.x,(double)
8797 geometry.y);
8798 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8799 exception);
8800 channel_mask=SetImageChannelMask(image,channel);
8801 if (attribute_flag[8] == 0) /* no rotate */
8802 CompositeImage(image,composite_image,compose,clip_to_self,
8803 geometry.x,geometry.y,exception);
8804 else
8805 {
8806 /*
8807 Position adjust rotated image then composite.
8808 */
8809 geometry.x-=(ssize_t) (rotate_image->columns-
8810 composite_image->columns)/2;
8811 geometry.y-=(ssize_t) (rotate_image->rows-
8812 composite_image->rows)/2;
8813 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8814 geometry.y,exception);
8815 rotate_image=DestroyImage(rotate_image);
8816 }
8817 if (attribute_flag[10] != 0) /* mask */
8818 {
8819 if ((image->compose == DisplaceCompositeOp) ||
8820 (image->compose == DistortCompositeOp))
8821 composite_image=DestroyImage(composite_image);
8822 else
cristy1f7ffb72015-07-29 11:07:03 +00008823 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008824 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008825 }
8826 (void) SetImageChannelMask(image,channel_mask);
8827 break;
8828 }
8829 case 36: /* Contrast */
8830 {
8831 if (attribute_flag[0] == 0)
8832 argument_list[0].integer_reference=0;
8833 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8834 MagickTrue : MagickFalse,exception);
8835 break;
8836 }
8837 case 37: /* CycleColormap */
8838 {
8839 if (attribute_flag[0] == 0)
8840 argument_list[0].integer_reference=6;
8841 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8842 exception);
8843 break;
8844 }
8845 case 38: /* Draw */
8846 {
8847 DrawInfo
8848 *draw_info;
8849
8850 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8851 (DrawInfo *) NULL);
8852 (void) CloneString(&draw_info->primitive,"point");
8853 if (attribute_flag[0] != 0)
8854 {
8855 if (argument_list[0].integer_reference < 0)
8856 (void) CloneString(&draw_info->primitive,
8857 argument_list[0].string_reference);
8858 else
8859 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8860 MagickPrimitiveOptions,argument_list[0].integer_reference));
8861 }
8862 if (attribute_flag[1] != 0)
8863 {
8864 if (LocaleCompare(draw_info->primitive,"path") == 0)
8865 {
8866 (void) ConcatenateString(&draw_info->primitive," '");
8867 ConcatenateString(&draw_info->primitive,
8868 argument_list[1].string_reference);
8869 (void) ConcatenateString(&draw_info->primitive,"'");
8870 }
8871 else
8872 {
8873 (void) ConcatenateString(&draw_info->primitive," ");
8874 ConcatenateString(&draw_info->primitive,
8875 argument_list[1].string_reference);
8876 }
8877 }
8878 if (attribute_flag[2] != 0)
8879 {
8880 (void) ConcatenateString(&draw_info->primitive," ");
8881 (void) ConcatenateString(&draw_info->primitive,
8882 CommandOptionToMnemonic(MagickMethodOptions,
8883 argument_list[2].integer_reference));
8884 }
8885 if (attribute_flag[3] != 0)
8886 {
8887 (void) QueryColorCompliance(argument_list[3].string_reference,
8888 AllCompliance,&draw_info->stroke,exception);
8889 if (argument_list[3].image_reference != (Image *) NULL)
8890 draw_info->stroke_pattern=CloneImage(
8891 argument_list[3].image_reference,0,0,MagickTrue,exception);
8892 }
8893 if (attribute_flag[4] != 0)
8894 {
8895 (void) QueryColorCompliance(argument_list[4].string_reference,
8896 AllCompliance,&draw_info->fill,exception);
8897 if (argument_list[4].image_reference != (Image *) NULL)
8898 draw_info->fill_pattern=CloneImage(
8899 argument_list[4].image_reference,0,0,MagickTrue,exception);
8900 }
8901 if (attribute_flag[5] != 0)
8902 draw_info->stroke_width=argument_list[5].real_reference;
8903 if (attribute_flag[6] != 0)
8904 (void) CloneString(&draw_info->font,
8905 argument_list[6].string_reference);
8906 if (attribute_flag[7] != 0)
8907 (void) QueryColorCompliance(argument_list[7].string_reference,
8908 AllCompliance,&draw_info->border_color,exception);
8909 if (attribute_flag[8] != 0)
8910 draw_info->affine.tx=argument_list[8].real_reference;
8911 if (attribute_flag[9] != 0)
8912 draw_info->affine.ty=argument_list[9].real_reference;
8913 if (attribute_flag[20] != 0)
8914 {
8915 AV
8916 *av;
8917
8918 av=(AV *) argument_list[20].array_reference;
8919 if ((av_len(av) != 3) && (av_len(av) != 5))
8920 {
8921 ThrowPerlException(exception,OptionError,
8922 "affine matrix must have 4 or 6 elements",PackageName);
8923 goto PerlException;
8924 }
8925 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8926 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8927 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8928 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8929 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8930 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8931 {
8932 ThrowPerlException(exception,OptionError,
8933 "affine matrix is singular",PackageName);
8934 goto PerlException;
8935 }
8936 if (av_len(av) == 5)
8937 {
8938 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8939 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8940 }
8941 }
8942 for (j=10; j < 15; j++)
8943 {
8944 if (attribute_flag[j] == 0)
8945 continue;
8946 value=argument_list[j].string_reference;
8947 angle=argument_list[j].real_reference;
8948 current=draw_info->affine;
8949 GetAffineMatrix(&affine);
8950 switch (j)
8951 {
8952 case 10:
8953 {
8954 /*
8955 Translate.
8956 */
8957 flags=ParseGeometry(value,&geometry_info);
8958 affine.tx=geometry_info.xi;
8959 affine.ty=geometry_info.psi;
8960 if ((flags & PsiValue) == 0)
8961 affine.ty=affine.tx;
8962 break;
8963 }
8964 case 11:
8965 {
8966 /*
8967 Scale.
8968 */
8969 flags=ParseGeometry(value,&geometry_info);
8970 affine.sx=geometry_info.rho;
8971 affine.sy=geometry_info.sigma;
8972 if ((flags & SigmaValue) == 0)
8973 affine.sy=affine.sx;
8974 break;
8975 }
8976 case 12:
8977 {
8978 /*
8979 Rotate.
8980 */
8981 if (angle == 0.0)
8982 break;
8983 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8984 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8985 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8986 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8987 break;
8988 }
8989 case 13:
8990 {
8991 /*
8992 SkewX.
8993 */
8994 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8995 break;
8996 }
8997 case 14:
8998 {
8999 /*
9000 SkewY.
9001 */
9002 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9003 break;
9004 }
9005 }
9006 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9007 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9008 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9009 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9010 draw_info->affine.tx=
9011 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9012 draw_info->affine.ty=
9013 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9014 }
9015 if (attribute_flag[15] != 0)
9016 draw_info->fill_pattern=CloneImage(
9017 argument_list[15].image_reference,0,0,MagickTrue,exception);
9018 if (attribute_flag[16] != 0)
9019 draw_info->pointsize=argument_list[16].real_reference;
9020 if (attribute_flag[17] != 0)
9021 {
9022 draw_info->stroke_antialias=argument_list[17].integer_reference != 0
9023 ? MagickTrue : MagickFalse;
9024 draw_info->text_antialias=draw_info->stroke_antialias;
9025 }
9026 if (attribute_flag[18] != 0)
9027 (void) CloneString(&draw_info->density,
9028 argument_list[18].string_reference);
9029 if (attribute_flag[19] != 0)
9030 draw_info->stroke_width=argument_list[19].real_reference;
9031 if (attribute_flag[21] != 0)
9032 draw_info->dash_offset=argument_list[21].real_reference;
9033 if (attribute_flag[22] != 0)
9034 {
9035 AV
9036 *av;
9037
9038 av=(AV *) argument_list[22].array_reference;
9039 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9040 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9041 if (draw_info->dash_pattern != (double *) NULL)
9042 {
9043 for (i=0; i <= av_len(av); i++)
9044 draw_info->dash_pattern[i]=(double)
9045 SvNV(*(av_fetch(av,i,0)));
9046 draw_info->dash_pattern[i]=0.0;
9047 }
9048 }
9049 if (attribute_flag[23] != 0)
9050 image->interpolate=(PixelInterpolateMethod)
9051 argument_list[23].integer_reference;
9052 if ((attribute_flag[24] != 0) &&
9053 (draw_info->fill_pattern != (Image *) NULL))
9054 flags=ParsePageGeometry(draw_info->fill_pattern,
9055 argument_list[24].string_reference,
9056 &draw_info->fill_pattern->tile_offset,exception);
9057 if (attribute_flag[25] != 0)
9058 {
9059 (void) ConcatenateString(&draw_info->primitive," '");
9060 (void) ConcatenateString(&draw_info->primitive,
9061 argument_list[25].string_reference);
9062 (void) ConcatenateString(&draw_info->primitive,"'");
9063 }
9064 if (attribute_flag[26] != 0)
9065 draw_info->fill_pattern=CloneImage(
9066 argument_list[26].image_reference,0,0,MagickTrue,exception);
9067 if (attribute_flag[27] != 0)
9068 draw_info->stroke_pattern=CloneImage(
9069 argument_list[27].image_reference,0,0,MagickTrue,exception);
9070 if (attribute_flag[28] != 0)
9071 (void) CloneString(&draw_info->primitive,
9072 argument_list[28].string_reference);
9073 if (attribute_flag[29] != 0)
9074 draw_info->kerning=argument_list[29].real_reference;
9075 if (attribute_flag[30] != 0)
9076 draw_info->interline_spacing=argument_list[30].real_reference;
9077 if (attribute_flag[31] != 0)
9078 draw_info->interword_spacing=argument_list[31].real_reference;
9079 if (attribute_flag[32] != 0)
9080 draw_info->direction=(DirectionType)
9081 argument_list[32].integer_reference;
9082 DrawImage(image,draw_info,exception);
9083 draw_info=DestroyDrawInfo(draw_info);
9084 break;
9085 }
9086 case 39: /* Equalize */
9087 {
9088 if (attribute_flag[0] != 0)
9089 channel=(ChannelType) argument_list[0].integer_reference;
9090 channel_mask=SetImageChannelMask(image,channel);
9091 EqualizeImage(image,exception);
9092 (void) SetImageChannelMask(image,channel_mask);
9093 break;
9094 }
9095 case 40: /* Gamma */
9096 {
9097 if (attribute_flag[1] != 0)
9098 channel=(ChannelType) argument_list[1].integer_reference;
9099 if (attribute_flag[2] == 0)
9100 argument_list[2].real_reference=1.0;
9101 if (attribute_flag[3] == 0)
9102 argument_list[3].real_reference=1.0;
9103 if (attribute_flag[4] == 0)
9104 argument_list[4].real_reference=1.0;
9105 if (attribute_flag[0] == 0)
9106 {
cristy151b66d2015-04-15 10:50:31 +00009107 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00009108 "%.15g,%.15g,%.15g",(double) argument_list[2].real_reference,
9109 (double) argument_list[3].real_reference,
9110 (double) argument_list[4].real_reference);
9111 argument_list[0].string_reference=message;
9112 }
9113 (void) GammaImage(image,StringToDouble(
9114 argument_list[0].string_reference,(char **) NULL),exception);
9115 break;
9116 }
9117 case 41: /* Map */
9118 {
9119 QuantizeInfo
9120 *quantize_info;
9121
9122 if (attribute_flag[0] == 0)
9123 {
9124 ThrowPerlException(exception,OptionError,"MapImageRequired",
9125 PackageName);
9126 goto PerlException;
9127 }
9128 quantize_info=AcquireQuantizeInfo(info->image_info);
9129 if (attribute_flag[1] != 0)
9130 quantize_info->dither_method=(DitherMethod)
9131 argument_list[1].integer_reference;
9132 (void) RemapImages(quantize_info,image,
9133 argument_list[0].image_reference,exception);
9134 quantize_info=DestroyQuantizeInfo(quantize_info);
9135 break;
9136 }
9137 case 42: /* MatteFloodfill */
9138 {
9139 DrawInfo
9140 *draw_info;
9141
9142 MagickBooleanType
9143 invert;
9144
9145 PixelInfo
9146 target;
9147
9148 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9149 (DrawInfo *) NULL);
9150 if (attribute_flag[0] != 0)
9151 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9152 &geometry,exception);
9153 if (attribute_flag[1] != 0)
9154 geometry.x=argument_list[1].integer_reference;
9155 if (attribute_flag[2] != 0)
9156 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009157 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009158 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9159 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9160 geometry.x,geometry.y,&target,exception);
9161 if (attribute_flag[4] != 0)
9162 QueryColorCompliance(argument_list[4].string_reference,
9163 AllCompliance,&target,exception);
9164 if (attribute_flag[3] != 0)
9165 target.alpha=StringToDoubleInterval(
9166 argument_list[3].string_reference,(double) (double) QuantumRange+
9167 1.0);
9168 if (attribute_flag[5] != 0)
9169 image->fuzz=StringToDoubleInterval(
9170 argument_list[5].string_reference,(double) QuantumRange+1.0);
9171 invert=MagickFalse;
9172 if (attribute_flag[6] != 0)
9173 invert=(MagickBooleanType) argument_list[6].integer_reference;
9174 channel_mask=SetImageChannelMask(image,AlphaChannel);
9175 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9176 geometry.y,invert,exception);
9177 (void) SetImageChannelMask(image,channel_mask);
9178 draw_info=DestroyDrawInfo(draw_info);
9179 break;
9180 }
9181 case 43: /* Modulate */
9182 {
9183 char
cristy151b66d2015-04-15 10:50:31 +00009184 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009185
9186 geometry_info.rho=100.0;
9187 geometry_info.sigma=100.0;
9188 geometry_info.xi=100.0;
9189 if (attribute_flag[0] != 0)
9190 (void)ParseGeometry(argument_list[0].string_reference,
9191 &geometry_info);
9192 if (attribute_flag[1] != 0)
9193 geometry_info.xi=argument_list[1].real_reference;
9194 if (attribute_flag[2] != 0)
9195 geometry_info.sigma=argument_list[2].real_reference;
9196 if (attribute_flag[3] != 0)
9197 {
9198 geometry_info.sigma=argument_list[3].real_reference;
9199 SetImageArtifact(image,"modulate:colorspace","HWB");
9200 }
9201 if (attribute_flag[4] != 0)
9202 {
9203 geometry_info.rho=argument_list[4].real_reference;
9204 SetImageArtifact(image,"modulate:colorspace","HSB");
9205 }
9206 if (attribute_flag[5] != 0)
9207 {
9208 geometry_info.sigma=argument_list[5].real_reference;
9209 SetImageArtifact(image,"modulate:colorspace","HSL");
9210 }
9211 if (attribute_flag[6] != 0)
9212 {
9213 geometry_info.rho=argument_list[6].real_reference;
9214 SetImageArtifact(image,"modulate:colorspace","HWB");
9215 }
cristy151b66d2015-04-15 10:50:31 +00009216 (void) FormatLocaleString(modulate,MagickPathExtent,"%.15g,%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00009217 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
9218 (void) ModulateImage(image,modulate,exception);
9219 break;
9220 }
9221 case 44: /* Negate */
9222 {
9223 if (attribute_flag[0] == 0)
9224 argument_list[0].integer_reference=0;
9225 if (attribute_flag[1] != 0)
9226 channel=(ChannelType) argument_list[1].integer_reference;
9227 channel_mask=SetImageChannelMask(image,channel);
9228 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9229 MagickTrue : MagickFalse,exception);
9230 (void) SetImageChannelMask(image,channel_mask);
9231 break;
9232 }
9233 case 45: /* Normalize */
9234 {
9235 if (attribute_flag[0] != 0)
9236 channel=(ChannelType) argument_list[0].integer_reference;
9237 channel_mask=SetImageChannelMask(image,channel);
9238 NormalizeImage(image,exception);
9239 (void) SetImageChannelMask(image,channel_mask);
9240 break;
9241 }
9242 case 46: /* NumberColors */
9243 break;
9244 case 47: /* Opaque */
9245 {
9246 MagickBooleanType
9247 invert;
9248
9249 PixelInfo
9250 fill_color,
9251 target;
9252
9253 (void) QueryColorCompliance("none",AllCompliance,&target,
9254 exception);
9255 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9256 exception);
9257 if (attribute_flag[0] != 0)
9258 (void) QueryColorCompliance(argument_list[0].string_reference,
9259 AllCompliance,&target,exception);
9260 if (attribute_flag[1] != 0)
9261 (void) QueryColorCompliance(argument_list[1].string_reference,
9262 AllCompliance,&fill_color,exception);
9263 if (attribute_flag[2] != 0)
9264 image->fuzz=StringToDoubleInterval(
9265 argument_list[2].string_reference,(double) QuantumRange+1.0);
9266 if (attribute_flag[3] != 0)
9267 channel=(ChannelType) argument_list[3].integer_reference;
9268 invert=MagickFalse;
9269 if (attribute_flag[4] != 0)
9270 invert=(MagickBooleanType) argument_list[4].integer_reference;
9271 channel_mask=SetImageChannelMask(image,channel);
9272 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9273 (void) SetImageChannelMask(image,channel_mask);
9274 break;
9275 }
9276 case 48: /* Quantize */
9277 {
9278 QuantizeInfo
9279 *quantize_info;
9280
9281 quantize_info=AcquireQuantizeInfo(info->image_info);
9282 if (attribute_flag[0] != 0)
9283 quantize_info->number_colors=(size_t)
9284 argument_list[0].integer_reference;
9285 if (attribute_flag[1] != 0)
9286 quantize_info->tree_depth=(size_t)
9287 argument_list[1].integer_reference;
9288 if (attribute_flag[2] != 0)
9289 quantize_info->colorspace=(ColorspaceType)
9290 argument_list[2].integer_reference;
9291 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009292 quantize_info->dither_method=(DitherMethod)
9293 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009294 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009295 quantize_info->measure_error=
9296 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009297 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009298 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009299 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009300 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009301 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009302 argument_list[7].integer_reference;
9303 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009304 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009305 else
cristyf7563392014-03-25 13:54:04 +00009306 if ((image->storage_class == DirectClass) ||
9307 (image->colors > quantize_info->number_colors) ||
9308 (quantize_info->colorspace == GRAYColorspace))
9309 (void) QuantizeImage(quantize_info,image,exception);
9310 else
9311 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009312 quantize_info=DestroyQuantizeInfo(quantize_info);
9313 break;
9314 }
9315 case 49: /* Raise */
9316 {
9317 if (attribute_flag[0] != 0)
9318 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9319 &geometry,exception);
9320 if (attribute_flag[1] != 0)
9321 geometry.width=argument_list[1].integer_reference;
9322 if (attribute_flag[2] != 0)
9323 geometry.height=argument_list[2].integer_reference;
9324 if (attribute_flag[3] == 0)
9325 argument_list[3].integer_reference=1;
9326 (void) RaiseImage(image,&geometry,
9327 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9328 exception);
9329 break;
9330 }
9331 case 50: /* Segment */
9332 {
9333 ColorspaceType
9334 colorspace;
9335
9336 double
9337 cluster_threshold,
9338 smoothing_threshold;
9339
9340 MagickBooleanType
9341 verbose;
9342
9343 cluster_threshold=1.0;
9344 smoothing_threshold=1.5;
9345 colorspace=sRGBColorspace;
9346 verbose=MagickFalse;
9347 if (attribute_flag[0] != 0)
9348 {
9349 flags=ParseGeometry(argument_list[0].string_reference,
9350 &geometry_info);
9351 cluster_threshold=geometry_info.rho;
9352 if (flags & SigmaValue)
9353 smoothing_threshold=geometry_info.sigma;
9354 }
9355 if (attribute_flag[1] != 0)
9356 cluster_threshold=argument_list[1].real_reference;
9357 if (attribute_flag[2] != 0)
9358 smoothing_threshold=argument_list[2].real_reference;
9359 if (attribute_flag[3] != 0)
9360 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9361 if (attribute_flag[4] != 0)
9362 verbose=argument_list[4].integer_reference != 0 ?
9363 MagickTrue : MagickFalse;
9364 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9365 smoothing_threshold,exception);
9366 break;
9367 }
9368 case 51: /* Signature */
9369 {
9370 (void) SignatureImage(image,exception);
9371 break;
9372 }
9373 case 52: /* Solarize */
9374 {
9375 geometry_info.rho=QuantumRange/2.0;
9376 if (attribute_flag[0] != 0)
9377 flags=ParseGeometry(argument_list[0].string_reference,
9378 &geometry_info);
9379 if (attribute_flag[1] != 0)
9380 geometry_info.rho=StringToDoubleInterval(
9381 argument_list[1].string_reference,(double) QuantumRange+1.0);
9382 (void) SolarizeImage(image,geometry_info.rho,exception);
9383 break;
9384 }
9385 case 53: /* Sync */
9386 {
9387 (void) SyncImage(image,exception);
9388 break;
9389 }
9390 case 54: /* Texture */
9391 {
9392 if (attribute_flag[0] == 0)
9393 break;
9394 TextureImage(image,argument_list[0].image_reference,exception);
9395 break;
9396 }
9397 case 55: /* Evalute */
9398 {
9399 MagickEvaluateOperator
9400 op;
9401
9402 op=SetEvaluateOperator;
9403 if (attribute_flag[0] == MagickFalse)
9404 argument_list[0].real_reference=0.0;
9405 if (attribute_flag[1] != MagickFalse)
9406 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9407 if (attribute_flag[2] != MagickFalse)
9408 channel=(ChannelType) argument_list[2].integer_reference;
9409 channel_mask=SetImageChannelMask(image,channel);
9410 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9411 exception);
9412 (void) SetImageChannelMask(image,channel_mask);
9413 break;
9414 }
9415 case 56: /* Transparent */
9416 {
9417 double
9418 opacity;
9419
9420 MagickBooleanType
9421 invert;
9422
9423 PixelInfo
9424 target;
9425
9426 (void) QueryColorCompliance("none",AllCompliance,&target,
9427 exception);
9428 if (attribute_flag[0] != 0)
9429 (void) QueryColorCompliance(argument_list[0].string_reference,
9430 AllCompliance,&target,exception);
9431 opacity=TransparentAlpha;
9432 if (attribute_flag[1] != 0)
9433 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9434 (double) QuantumRange+1.0);
9435 if (attribute_flag[2] != 0)
9436 image->fuzz=StringToDoubleInterval(
9437 argument_list[2].string_reference,(double) QuantumRange+1.0);
9438 if (attribute_flag[3] == 0)
9439 argument_list[3].integer_reference=0;
9440 invert=MagickFalse;
9441 if (attribute_flag[3] != 0)
9442 invert=(MagickBooleanType) argument_list[3].integer_reference;
9443 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9444 invert,exception);
9445 break;
9446 }
9447 case 57: /* Threshold */
9448 {
9449 double
9450 threshold;
9451
9452 if (attribute_flag[0] == 0)
9453 argument_list[0].string_reference="50%";
9454 if (attribute_flag[1] != 0)
9455 channel=(ChannelType) argument_list[1].integer_reference;
9456 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9457 (double) QuantumRange+1.0);
9458 channel_mask=SetImageChannelMask(image,channel);
9459 (void) BilevelImage(image,threshold,exception);
9460 (void) SetImageChannelMask(image,channel_mask);
9461 break;
9462 }
9463 case 58: /* Charcoal */
9464 {
9465 if (attribute_flag[0] != 0)
9466 {
9467 flags=ParseGeometry(argument_list[0].string_reference,
9468 &geometry_info);
9469 if ((flags & SigmaValue) == 0)
9470 geometry_info.sigma=1.0;
9471 }
9472 if (attribute_flag[1] != 0)
9473 geometry_info.rho=argument_list[1].real_reference;
9474 if (attribute_flag[2] != 0)
9475 geometry_info.sigma=argument_list[2].real_reference;
9476 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9477 exception);
9478 break;
9479 }
9480 case 59: /* Trim */
9481 {
9482 if (attribute_flag[0] != 0)
9483 image->fuzz=StringToDoubleInterval(
9484 argument_list[0].string_reference,(double) QuantumRange+1.0);
9485 image=TrimImage(image,exception);
9486 break;
9487 }
9488 case 60: /* Wave */
9489 {
9490 PixelInterpolateMethod
9491 method;
9492
9493 if (attribute_flag[0] != 0)
9494 {
9495 flags=ParseGeometry(argument_list[0].string_reference,
9496 &geometry_info);
9497 if ((flags & SigmaValue) == 0)
9498 geometry_info.sigma=1.0;
9499 }
9500 if (attribute_flag[1] != 0)
9501 geometry_info.rho=argument_list[1].real_reference;
9502 if (attribute_flag[2] != 0)
9503 geometry_info.sigma=argument_list[2].real_reference;
9504 method=UndefinedInterpolatePixel;
9505 if (attribute_flag[3] != 0)
9506 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9507 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9508 method,exception);
9509 break;
9510 }
9511 case 61: /* Separate */
9512 {
9513 if (attribute_flag[0] != 0)
9514 channel=(ChannelType) argument_list[0].integer_reference;
9515 image=SeparateImage(image,channel,exception);
9516 break;
9517 }
9518 case 63: /* Stereo */
9519 {
9520 if (attribute_flag[0] == 0)
9521 {
9522 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9523 PackageName);
9524 goto PerlException;
9525 }
9526 if (attribute_flag[1] != 0)
9527 geometry.x=argument_list[1].integer_reference;
9528 if (attribute_flag[2] != 0)
9529 geometry.y=argument_list[2].integer_reference;
9530 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9531 geometry.x,geometry.y,exception);
9532 break;
9533 }
9534 case 64: /* Stegano */
9535 {
9536 if (attribute_flag[0] == 0)
9537 {
9538 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9539 PackageName);
9540 goto PerlException;
9541 }
9542 if (attribute_flag[1] == 0)
9543 argument_list[1].integer_reference=0;
9544 image->offset=argument_list[1].integer_reference;
9545 image=SteganoImage(image,argument_list[0].image_reference,exception);
9546 break;
9547 }
9548 case 65: /* Deconstruct */
9549 {
9550 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9551 break;
9552 }
9553 case 66: /* GaussianBlur */
9554 {
9555 if (attribute_flag[0] != 0)
9556 {
9557 flags=ParseGeometry(argument_list[0].string_reference,
9558 &geometry_info);
9559 if ((flags & SigmaValue) == 0)
9560 geometry_info.sigma=1.0;
9561 }
9562 if (attribute_flag[1] != 0)
9563 geometry_info.rho=argument_list[1].real_reference;
9564 if (attribute_flag[2] != 0)
9565 geometry_info.sigma=argument_list[2].real_reference;
9566 if (attribute_flag[3] != 0)
9567 channel=(ChannelType) argument_list[3].integer_reference;
9568 channel_mask=SetImageChannelMask(image,channel);
9569 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9570 exception);
9571 if (image != (Image *) NULL)
9572 (void) SetImageChannelMask(image,channel_mask);
9573 break;
9574 }
9575 case 67: /* Convolve */
9576 {
9577 KernelInfo
9578 *kernel;
9579
9580 kernel=(KernelInfo *) NULL;
9581 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9582 break;
9583 if (attribute_flag[0] != 0)
9584 {
9585 AV
9586 *av;
9587
9588 size_t
9589 order;
9590
cristy2c57b742014-10-31 00:40:34 +00009591 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009592 if (kernel == (KernelInfo *) NULL)
9593 break;
9594 av=(AV *) argument_list[0].array_reference;
9595 order=(size_t) sqrt(av_len(av)+1);
9596 kernel->width=order;
9597 kernel->height=order;
9598 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9599 order*sizeof(*kernel->values));
9600 if (kernel->values == (MagickRealType *) NULL)
9601 {
9602 kernel=DestroyKernelInfo(kernel);
9603 ThrowPerlException(exception,ResourceLimitFatalError,
9604 "MemoryAllocationFailed",PackageName);
9605 goto PerlException;
9606 }
9607 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9608 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9609 for ( ; j < (ssize_t) (order*order); j++)
9610 kernel->values[j]=0.0;
9611 }
9612 if (attribute_flag[1] != 0)
9613 channel=(ChannelType) argument_list[1].integer_reference;
9614 if (attribute_flag[2] != 0)
9615 SetImageArtifact(image,"filter:blur",
9616 argument_list[2].string_reference);
9617 if (attribute_flag[3] != 0)
9618 {
cristy2c57b742014-10-31 00:40:34 +00009619 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9620 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009621 if (kernel == (KernelInfo *) NULL)
9622 break;
9623 }
9624 channel_mask=SetImageChannelMask(image,channel);
9625 image=ConvolveImage(image,kernel,exception);
9626 if (image != (Image *) NULL)
9627 (void) SetImageChannelMask(image,channel_mask);
9628 kernel=DestroyKernelInfo(kernel);
9629 break;
9630 }
9631 case 68: /* Profile */
9632 {
9633 const char
9634 *name;
9635
9636 Image
9637 *profile_image;
9638
9639 ImageInfo
9640 *profile_info;
9641
9642 StringInfo
9643 *profile;
9644
9645 name="*";
9646 if (attribute_flag[0] != 0)
9647 name=argument_list[0].string_reference;
9648 if (attribute_flag[2] != 0)
9649 image->rendering_intent=(RenderingIntent)
9650 argument_list[2].integer_reference;
9651 if (attribute_flag[3] != 0)
9652 image->black_point_compensation=
9653 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9654 if (attribute_flag[1] != 0)
9655 {
9656 if (argument_list[1].length == 0)
9657 {
9658 /*
9659 Remove a profile from the image.
9660 */
9661 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9662 exception);
9663 break;
9664 }
9665 /*
9666 Associate user supplied profile with the image.
9667 */
9668 profile=AcquireStringInfo(argument_list[1].length);
9669 SetStringInfoDatum(profile,(const unsigned char *)
9670 argument_list[1].string_reference);
9671 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9672 (size_t) GetStringInfoLength(profile),exception);
9673 profile=DestroyStringInfo(profile);
9674 break;
9675 }
9676 /*
9677 Associate a profile with the image.
9678 */
9679 profile_info=CloneImageInfo(info ? info->image_info :
9680 (ImageInfo *) NULL);
9681 profile_image=ReadImages(profile_info,name,exception);
9682 if (profile_image == (Image *) NULL)
9683 break;
9684 ResetImageProfileIterator(profile_image);
9685 name=GetNextImageProfile(profile_image);
9686 while (name != (const char *) NULL)
9687 {
9688 const StringInfo
9689 *profile;
9690
9691 profile=GetImageProfile(profile_image,name);
9692 if (profile != (const StringInfo *) NULL)
9693 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9694 (size_t) GetStringInfoLength(profile),exception);
9695 name=GetNextImageProfile(profile_image);
9696 }
9697 profile_image=DestroyImage(profile_image);
9698 profile_info=DestroyImageInfo(profile_info);
9699 break;
9700 }
9701 case 69: /* UnsharpMask */
9702 {
9703 if (attribute_flag[0] != 0)
9704 {
9705 flags=ParseGeometry(argument_list[0].string_reference,
9706 &geometry_info);
9707 if ((flags & SigmaValue) == 0)
9708 geometry_info.sigma=1.0;
9709 if ((flags & XiValue) == 0)
9710 geometry_info.xi=1.0;
9711 if ((flags & PsiValue) == 0)
9712 geometry_info.psi=0.5;
9713 }
9714 if (attribute_flag[1] != 0)
9715 geometry_info.rho=argument_list[1].real_reference;
9716 if (attribute_flag[2] != 0)
9717 geometry_info.sigma=argument_list[2].real_reference;
9718 if (attribute_flag[3] != 0)
9719 geometry_info.xi=argument_list[3].real_reference;
9720 if (attribute_flag[4] != 0)
9721 geometry_info.psi=argument_list[4].real_reference;
9722 if (attribute_flag[5] != 0)
9723 channel=(ChannelType) argument_list[5].integer_reference;
9724 channel_mask=SetImageChannelMask(image,channel);
9725 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9726 geometry_info.xi,geometry_info.psi,exception);
9727 if (image != (Image *) NULL)
9728 (void) SetImageChannelMask(image,channel_mask);
9729 break;
9730 }
9731 case 70: /* MotionBlur */
9732 {
9733 if (attribute_flag[0] != 0)
9734 {
9735 flags=ParseGeometry(argument_list[0].string_reference,
9736 &geometry_info);
9737 if ((flags & SigmaValue) == 0)
9738 geometry_info.sigma=1.0;
9739 if ((flags & XiValue) == 0)
9740 geometry_info.xi=1.0;
9741 }
9742 if (attribute_flag[1] != 0)
9743 geometry_info.rho=argument_list[1].real_reference;
9744 if (attribute_flag[2] != 0)
9745 geometry_info.sigma=argument_list[2].real_reference;
9746 if (attribute_flag[3] != 0)
9747 geometry_info.xi=argument_list[3].real_reference;
9748 if (attribute_flag[4] != 0)
9749 channel=(ChannelType) argument_list[4].integer_reference;
9750 channel_mask=SetImageChannelMask(image,channel);
9751 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9752 geometry_info.xi,exception);
9753 if (image != (Image *) NULL)
9754 (void) SetImageChannelMask(image,channel_mask);
9755 break;
9756 }
9757 case 71: /* OrderedDither */
9758 {
9759 if (attribute_flag[0] == 0)
9760 argument_list[0].string_reference="o8x8";
9761 if (attribute_flag[1] != 0)
9762 channel=(ChannelType) argument_list[1].integer_reference;
9763 channel_mask=SetImageChannelMask(image,channel);
9764 (void) OrderedPosterizeImage(image,argument_list[0].string_reference,
9765 exception);
9766 (void) SetImageChannelMask(image,channel_mask);
9767 break;
9768 }
9769 case 72: /* Shave */
9770 {
9771 if (attribute_flag[0] != 0)
9772 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9773 &geometry,exception);
9774 if (attribute_flag[1] != 0)
9775 geometry.width=argument_list[1].integer_reference;
9776 if (attribute_flag[2] != 0)
9777 geometry.height=argument_list[2].integer_reference;
9778 image=ShaveImage(image,&geometry,exception);
9779 break;
9780 }
9781 case 73: /* Level */
9782 {
9783 double
9784 black_point,
9785 gamma,
9786 white_point;
9787
9788 black_point=0.0;
9789 white_point=(double) image->columns*image->rows;
9790 gamma=1.0;
9791 if (attribute_flag[0] != 0)
9792 {
9793 flags=ParseGeometry(argument_list[0].string_reference,
9794 &geometry_info);
9795 black_point=geometry_info.rho;
9796 if ((flags & SigmaValue) != 0)
9797 white_point=geometry_info.sigma;
9798 if ((flags & XiValue) != 0)
9799 gamma=geometry_info.xi;
9800 if ((flags & PercentValue) != 0)
9801 {
9802 black_point*=(double) (QuantumRange/100.0);
9803 white_point*=(double) (QuantumRange/100.0);
9804 }
9805 if ((flags & SigmaValue) == 0)
9806 white_point=(double) QuantumRange-black_point;
9807 }
9808 if (attribute_flag[1] != 0)
9809 black_point=argument_list[1].real_reference;
9810 if (attribute_flag[2] != 0)
9811 white_point=argument_list[2].real_reference;
9812 if (attribute_flag[3] != 0)
9813 gamma=argument_list[3].real_reference;
9814 if (attribute_flag[4] != 0)
9815 channel=(ChannelType) argument_list[4].integer_reference;
9816 if (attribute_flag[5] != 0)
9817 {
9818 argument_list[0].real_reference=argument_list[5].real_reference;
9819 attribute_flag[0]=attribute_flag[5];
9820 }
9821 channel_mask=SetImageChannelMask(image,channel);
9822 (void) LevelImage(image,black_point,white_point,gamma,exception);
9823 (void) SetImageChannelMask(image,channel_mask);
9824 break;
9825 }
9826 case 74: /* Clip */
9827 {
9828 if (attribute_flag[0] == 0)
9829 argument_list[0].string_reference="#1";
9830 if (attribute_flag[1] == 0)
9831 argument_list[1].integer_reference=MagickTrue;
9832 (void) ClipImagePath(image,argument_list[0].string_reference,
9833 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9834 exception);
9835 break;
9836 }
9837 case 75: /* AffineTransform */
9838 {
9839 DrawInfo
9840 *draw_info;
9841
9842 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9843 (DrawInfo *) NULL);
9844 if (attribute_flag[0] != 0)
9845 {
9846 AV
9847 *av;
9848
9849 av=(AV *) argument_list[0].array_reference;
9850 if ((av_len(av) != 3) && (av_len(av) != 5))
9851 {
9852 ThrowPerlException(exception,OptionError,
9853 "affine matrix must have 4 or 6 elements",PackageName);
9854 goto PerlException;
9855 }
9856 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9857 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9858 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9859 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9860 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9861 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9862 {
9863 ThrowPerlException(exception,OptionError,
9864 "affine matrix is singular",PackageName);
9865 goto PerlException;
9866 }
9867 if (av_len(av) == 5)
9868 {
9869 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9870 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9871 }
9872 }
9873 for (j=1; j < 6; j++)
9874 {
9875 if (attribute_flag[j] == 0)
9876 continue;
9877 value=argument_list[j].string_reference;
9878 angle=argument_list[j].real_reference;
9879 current=draw_info->affine;
9880 GetAffineMatrix(&affine);
9881 switch (j)
9882 {
9883 case 1:
9884 {
9885 /*
9886 Translate.
9887 */
9888 flags=ParseGeometry(value,&geometry_info);
9889 affine.tx=geometry_info.xi;
9890 affine.ty=geometry_info.psi;
9891 if ((flags & PsiValue) == 0)
9892 affine.ty=affine.tx;
9893 break;
9894 }
9895 case 2:
9896 {
9897 /*
9898 Scale.
9899 */
9900 flags=ParseGeometry(value,&geometry_info);
9901 affine.sx=geometry_info.rho;
9902 affine.sy=geometry_info.sigma;
9903 if ((flags & SigmaValue) == 0)
9904 affine.sy=affine.sx;
9905 break;
9906 }
9907 case 3:
9908 {
9909 /*
9910 Rotate.
9911 */
9912 if (angle == 0.0)
9913 break;
9914 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9915 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9916 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9917 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9918 break;
9919 }
9920 case 4:
9921 {
9922 /*
9923 SkewX.
9924 */
9925 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9926 break;
9927 }
9928 case 5:
9929 {
9930 /*
9931 SkewY.
9932 */
9933 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9934 break;
9935 }
9936 }
9937 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9938 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9939 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9940 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9941 draw_info->affine.tx=
9942 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9943 draw_info->affine.ty=
9944 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9945 }
9946 if (attribute_flag[6] != 0)
9947 image->interpolate=(PixelInterpolateMethod)
9948 argument_list[6].integer_reference;
9949 if (attribute_flag[7] != 0)
9950 QueryColorCompliance(argument_list[7].string_reference,
9951 AllCompliance,&image->background_color,exception);
9952 image=AffineTransformImage(image,&draw_info->affine,exception);
9953 draw_info=DestroyDrawInfo(draw_info);
9954 break;
9955 }
9956 case 76: /* Difference */
9957 {
9958 if (attribute_flag[0] == 0)
9959 {
9960 ThrowPerlException(exception,OptionError,
9961 "ReferenceImageRequired",PackageName);
9962 goto PerlException;
9963 }
9964 if (attribute_flag[1] != 0)
9965 image->fuzz=StringToDoubleInterval(
9966 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -05009967 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009968 exception);
9969 break;
9970 }
9971 case 77: /* AdaptiveThreshold */
9972 {
9973 if (attribute_flag[0] != 0)
9974 {
9975 flags=ParseGeometry(argument_list[0].string_reference,
9976 &geometry_info);
9977 if ((flags & PercentValue) != 0)
9978 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9979 }
9980 if (attribute_flag[1] != 0)
9981 geometry_info.rho=argument_list[1].integer_reference;
9982 if (attribute_flag[2] != 0)
9983 geometry_info.sigma=argument_list[2].integer_reference;
9984 if (attribute_flag[3] != 0)
9985 geometry_info.xi=argument_list[3].integer_reference;;
9986 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9987 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9988 break;
9989 }
9990 case 78: /* Resample */
9991 {
9992 size_t
9993 height,
9994 width;
9995
9996 if (attribute_flag[0] != 0)
9997 {
9998 flags=ParseGeometry(argument_list[0].string_reference,
9999 &geometry_info);
10000 if ((flags & SigmaValue) == 0)
10001 geometry_info.sigma=geometry_info.rho;
10002 }
10003 if (attribute_flag[1] != 0)
10004 geometry_info.rho=argument_list[1].real_reference;
10005 if (attribute_flag[2] != 0)
10006 geometry_info.sigma=argument_list[2].real_reference;
10007 if (attribute_flag[3] == 0)
10008 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10009 if (attribute_flag[4] == 0)
10010 SetImageArtifact(image,"filter:support",
10011 argument_list[4].string_reference);
10012 width=(size_t) (geometry_info.rho*image->columns/
10013 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10014 height=(size_t) (geometry_info.sigma*image->rows/
10015 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
10016 image=ResizeImage(image,width,height,(FilterTypes)
10017 argument_list[3].integer_reference,exception);
10018 if (image != (Image *) NULL)
10019 {
10020 image->resolution.x=geometry_info.rho;
10021 image->resolution.y=geometry_info.sigma;
10022 }
10023 break;
10024 }
10025 case 79: /* Describe */
10026 {
10027 if (attribute_flag[0] == 0)
10028 argument_list[0].file_reference=(FILE *) NULL;
10029 if (attribute_flag[1] != 0)
10030 (void) SetImageArtifact(image,"identify:features",
10031 argument_list[1].string_reference);
10032 (void) IdentifyImage(image,argument_list[0].file_reference,
10033 MagickTrue,exception);
10034 break;
10035 }
10036 case 80: /* BlackThreshold */
10037 {
10038 if (attribute_flag[0] == 0)
10039 argument_list[0].string_reference="50%";
10040 if (attribute_flag[2] != 0)
10041 channel=(ChannelType) argument_list[2].integer_reference;
10042 channel_mask=SetImageChannelMask(image,channel);
10043 BlackThresholdImage(image,argument_list[0].string_reference,
10044 exception);
10045 (void) SetImageChannelMask(image,channel_mask);
10046 break;
10047 }
10048 case 81: /* WhiteThreshold */
10049 {
10050 if (attribute_flag[0] == 0)
10051 argument_list[0].string_reference="50%";
10052 if (attribute_flag[2] != 0)
10053 channel=(ChannelType) argument_list[2].integer_reference;
10054 channel_mask=SetImageChannelMask(image,channel);
10055 WhiteThresholdImage(image,argument_list[0].string_reference,
10056 exception);
10057 (void) SetImageChannelMask(image,channel_mask);
10058 break;
10059 }
cristy60c73c02014-03-25 12:09:58 +000010060 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010061 {
10062 if (attribute_flag[0] != 0)
10063 {
10064 flags=ParseGeometry(argument_list[0].string_reference,
10065 &geometry_info);
10066 }
10067 if (attribute_flag[1] != 0)
10068 geometry_info.rho=argument_list[1].real_reference;
10069 if (attribute_flag[2] != 0)
10070 channel=(ChannelType) argument_list[2].integer_reference;
10071 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010072 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010073 if (image != (Image *) NULL)
10074 (void) SetImageChannelMask(image,channel_mask);
10075 break;
10076 }
10077 case 83: /* Thumbnail */
10078 {
10079 if (attribute_flag[0] != 0)
10080 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10081 &geometry,exception);
10082 if (attribute_flag[1] != 0)
10083 geometry.width=argument_list[1].integer_reference;
10084 if (attribute_flag[2] != 0)
10085 geometry.height=argument_list[2].integer_reference;
10086 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10087 break;
10088 }
10089 case 84: /* Strip */
10090 {
10091 (void) StripImage(image,exception);
10092 break;
10093 }
10094 case 85: /* Tint */
10095 {
10096 PixelInfo
10097 tint;
10098
10099 GetPixelInfo(image,&tint);
10100 if (attribute_flag[0] != 0)
10101 (void) QueryColorCompliance(argument_list[0].string_reference,
10102 AllCompliance,&tint,exception);
10103 if (attribute_flag[1] == 0)
10104 argument_list[1].string_reference="100";
10105 image=TintImage(image,argument_list[1].string_reference,&tint,
10106 exception);
10107 break;
10108 }
10109 case 86: /* Channel */
10110 {
10111 if (attribute_flag[0] != 0)
10112 channel=(ChannelType) argument_list[0].integer_reference;
10113 image=SeparateImage(image,channel,exception);
10114 break;
10115 }
10116 case 87: /* Splice */
10117 {
cristy260bd762014-08-15 12:46:34 +000010118 if (attribute_flag[7] != 0)
10119 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010120 if (attribute_flag[0] != 0)
10121 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10122 &geometry,exception);
10123 if (attribute_flag[1] != 0)
10124 geometry.width=argument_list[1].integer_reference;
10125 if (attribute_flag[2] != 0)
10126 geometry.height=argument_list[2].integer_reference;
10127 if (attribute_flag[3] != 0)
10128 geometry.x=argument_list[3].integer_reference;
10129 if (attribute_flag[4] != 0)
10130 geometry.y=argument_list[4].integer_reference;
10131 if (attribute_flag[5] != 0)
10132 image->fuzz=StringToDoubleInterval(
10133 argument_list[5].string_reference,(double) QuantumRange+1.0);
10134 if (attribute_flag[6] != 0)
10135 (void) QueryColorCompliance(argument_list[6].string_reference,
10136 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010137 image=SpliceImage(image,&geometry,exception);
10138 break;
10139 }
10140 case 88: /* Posterize */
10141 {
10142 if (attribute_flag[0] == 0)
10143 argument_list[0].integer_reference=3;
10144 if (attribute_flag[1] == 0)
10145 argument_list[1].integer_reference=0;
10146 (void) PosterizeImage(image,argument_list[0].integer_reference,
10147 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10148 NoDitherMethod,exception);
10149 break;
10150 }
10151 case 89: /* Shadow */
10152 {
10153 if (attribute_flag[0] != 0)
10154 {
10155 flags=ParseGeometry(argument_list[0].string_reference,
10156 &geometry_info);
10157 if ((flags & SigmaValue) == 0)
10158 geometry_info.sigma=1.0;
10159 if ((flags & XiValue) == 0)
10160 geometry_info.xi=4.0;
10161 if ((flags & PsiValue) == 0)
10162 geometry_info.psi=4.0;
10163 }
10164 if (attribute_flag[1] != 0)
10165 geometry_info.rho=argument_list[1].real_reference;
10166 if (attribute_flag[2] != 0)
10167 geometry_info.sigma=argument_list[2].real_reference;
10168 if (attribute_flag[3] != 0)
10169 geometry_info.xi=argument_list[3].integer_reference;
10170 if (attribute_flag[4] != 0)
10171 geometry_info.psi=argument_list[4].integer_reference;
10172 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10173 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10174 ceil(geometry_info.psi-0.5),exception);
10175 break;
10176 }
10177 case 90: /* Identify */
10178 {
10179 if (attribute_flag[0] == 0)
10180 argument_list[0].file_reference=(FILE *) NULL;
10181 if (attribute_flag[1] != 0)
10182 (void) SetImageArtifact(image,"identify:features",
10183 argument_list[1].string_reference);
10184 if ((attribute_flag[2] != 0) &&
10185 (argument_list[2].integer_reference != 0))
10186 (void) SetImageArtifact(image,"identify:unique","true");
10187 (void) IdentifyImage(image,argument_list[0].file_reference,
10188 MagickTrue,exception);
10189 break;
10190 }
10191 case 91: /* SepiaTone */
10192 {
10193 if (attribute_flag[0] == 0)
10194 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10195 image=SepiaToneImage(image,argument_list[0].real_reference,
10196 exception);
10197 break;
10198 }
10199 case 92: /* SigmoidalContrast */
10200 {
10201 MagickBooleanType
10202 sharpen;
10203
10204 if (attribute_flag[0] != 0)
10205 {
10206 flags=ParseGeometry(argument_list[0].string_reference,
10207 &geometry_info);
10208 if ((flags & SigmaValue) == 0)
10209 geometry_info.sigma=QuantumRange/2.0;
10210 if ((flags & PercentValue) != 0)
10211 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10212 }
10213 if (attribute_flag[1] != 0)
10214 geometry_info.rho=argument_list[1].real_reference;
10215 if (attribute_flag[2] != 0)
10216 geometry_info.sigma=argument_list[2].real_reference;
10217 if (attribute_flag[3] != 0)
10218 channel=(ChannelType) argument_list[3].integer_reference;
10219 sharpen=MagickTrue;
10220 if (attribute_flag[4] != 0)
10221 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10222 MagickFalse;
10223 channel_mask=SetImageChannelMask(image,channel);
10224 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10225 geometry_info.sigma,exception);
10226 (void) SetImageChannelMask(image,channel_mask);
10227 break;
10228 }
10229 case 93: /* Extent */
10230 {
10231 if (attribute_flag[7] != 0)
10232 image->gravity=(GravityType) argument_list[7].integer_reference;
10233 if (attribute_flag[0] != 0)
10234 {
10235 int
10236 flags;
10237
10238 flags=ParseGravityGeometry(image,
10239 argument_list[0].string_reference,&geometry,exception);
10240 (void) flags;
10241 if (geometry.width == 0)
10242 geometry.width=image->columns;
10243 if (geometry.height == 0)
10244 geometry.height=image->rows;
10245 }
10246 if (attribute_flag[1] != 0)
10247 geometry.width=argument_list[1].integer_reference;
10248 if (attribute_flag[2] != 0)
10249 geometry.height=argument_list[2].integer_reference;
10250 if (attribute_flag[3] != 0)
10251 geometry.x=argument_list[3].integer_reference;
10252 if (attribute_flag[4] != 0)
10253 geometry.y=argument_list[4].integer_reference;
10254 if (attribute_flag[5] != 0)
10255 image->fuzz=StringToDoubleInterval(
10256 argument_list[5].string_reference,(double) QuantumRange+1.0);
10257 if (attribute_flag[6] != 0)
10258 (void) QueryColorCompliance(argument_list[6].string_reference,
10259 AllCompliance,&image->background_color,exception);
10260 image=ExtentImage(image,&geometry,exception);
10261 break;
10262 }
10263 case 94: /* Vignette */
10264 {
10265 if (attribute_flag[0] != 0)
10266 {
10267 flags=ParseGeometry(argument_list[0].string_reference,
10268 &geometry_info);
10269 if ((flags & SigmaValue) == 0)
10270 geometry_info.sigma=1.0;
10271 if ((flags & XiValue) == 0)
10272 geometry_info.xi=0.1*image->columns;
10273 if ((flags & PsiValue) == 0)
10274 geometry_info.psi=0.1*image->rows;
10275 }
10276 if (attribute_flag[1] != 0)
10277 geometry_info.rho=argument_list[1].real_reference;
10278 if (attribute_flag[2] != 0)
10279 geometry_info.sigma=argument_list[2].real_reference;
10280 if (attribute_flag[3] != 0)
10281 geometry_info.xi=argument_list[3].integer_reference;
10282 if (attribute_flag[4] != 0)
10283 geometry_info.psi=argument_list[4].integer_reference;
10284 if (attribute_flag[5] != 0)
10285 (void) QueryColorCompliance(argument_list[5].string_reference,
10286 AllCompliance,&image->background_color,exception);
10287 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10288 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10289 ceil(geometry_info.psi-0.5),exception);
10290 break;
10291 }
10292 case 95: /* ContrastStretch */
10293 {
10294 double
10295 black_point,
10296 white_point;
10297
10298 black_point=0.0;
10299 white_point=(double) image->columns*image->rows;
10300 if (attribute_flag[0] != 0)
10301 {
10302 flags=ParseGeometry(argument_list[0].string_reference,
10303 &geometry_info);
10304 black_point=geometry_info.rho;
10305 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10306 black_point;
10307 if ((flags & PercentValue) != 0)
10308 {
10309 black_point*=(double) image->columns*image->rows/100.0;
10310 white_point*=(double) image->columns*image->rows/100.0;
10311 }
10312 white_point=(double) image->columns*image->rows-
10313 white_point;
10314 }
10315 if (attribute_flag[1] != 0)
10316 black_point=argument_list[1].real_reference;
10317 if (attribute_flag[2] != 0)
10318 white_point=argument_list[2].real_reference;
10319 if (attribute_flag[4] != 0)
10320 channel=(ChannelType) argument_list[4].integer_reference;
10321 channel_mask=SetImageChannelMask(image,channel);
10322 (void) ContrastStretchImage(image,black_point,white_point,exception);
10323 (void) SetImageChannelMask(image,channel_mask);
10324 break;
10325 }
10326 case 96: /* Sans0 */
10327 {
10328 break;
10329 }
10330 case 97: /* Sans1 */
10331 {
10332 break;
10333 }
10334 case 98: /* AdaptiveSharpen */
10335 {
10336 if (attribute_flag[0] != 0)
10337 {
10338 flags=ParseGeometry(argument_list[0].string_reference,
10339 &geometry_info);
10340 if ((flags & SigmaValue) == 0)
10341 geometry_info.sigma=1.0;
10342 if ((flags & XiValue) == 0)
10343 geometry_info.xi=0.0;
10344 }
10345 if (attribute_flag[1] != 0)
10346 geometry_info.rho=argument_list[1].real_reference;
10347 if (attribute_flag[2] != 0)
10348 geometry_info.sigma=argument_list[2].real_reference;
10349 if (attribute_flag[3] != 0)
10350 geometry_info.xi=argument_list[3].real_reference;
10351 if (attribute_flag[4] != 0)
10352 channel=(ChannelType) argument_list[4].integer_reference;
10353 channel_mask=SetImageChannelMask(image,channel);
10354 image=AdaptiveSharpenImage(image,geometry_info.rho,
10355 geometry_info.sigma,exception);
10356 if (image != (Image *) NULL)
10357 (void) SetImageChannelMask(image,channel_mask);
10358 break;
10359 }
10360 case 99: /* Transpose */
10361 {
10362 image=TransposeImage(image,exception);
10363 break;
10364 }
10365 case 100: /* Tranverse */
10366 {
10367 image=TransverseImage(image,exception);
10368 break;
10369 }
10370 case 101: /* AutoOrient */
10371 {
10372 image=AutoOrientImage(image,image->orientation,exception);
10373 break;
10374 }
10375 case 102: /* AdaptiveBlur */
10376 {
10377 if (attribute_flag[0] != 0)
10378 {
10379 flags=ParseGeometry(argument_list[0].string_reference,
10380 &geometry_info);
10381 if ((flags & SigmaValue) == 0)
10382 geometry_info.sigma=1.0;
10383 if ((flags & XiValue) == 0)
10384 geometry_info.xi=0.0;
10385 }
10386 if (attribute_flag[1] != 0)
10387 geometry_info.rho=argument_list[1].real_reference;
10388 if (attribute_flag[2] != 0)
10389 geometry_info.sigma=argument_list[2].real_reference;
10390 if (attribute_flag[3] != 0)
10391 channel=(ChannelType) argument_list[3].integer_reference;
10392 channel_mask=SetImageChannelMask(image,channel);
10393 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10394 exception);
10395 if (image != (Image *) NULL)
10396 (void) SetImageChannelMask(image,channel_mask);
10397 break;
10398 }
10399 case 103: /* Sketch */
10400 {
10401 if (attribute_flag[0] != 0)
10402 {
10403 flags=ParseGeometry(argument_list[0].string_reference,
10404 &geometry_info);
10405 if ((flags & SigmaValue) == 0)
10406 geometry_info.sigma=1.0;
10407 if ((flags & XiValue) == 0)
10408 geometry_info.xi=1.0;
10409 }
10410 if (attribute_flag[1] != 0)
10411 geometry_info.rho=argument_list[1].real_reference;
10412 if (attribute_flag[2] != 0)
10413 geometry_info.sigma=argument_list[2].real_reference;
10414 if (attribute_flag[3] != 0)
10415 geometry_info.xi=argument_list[3].real_reference;
10416 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10417 geometry_info.xi,exception);
10418 break;
10419 }
10420 case 104: /* UniqueColors */
10421 {
10422 image=UniqueImageColors(image,exception);
10423 break;
10424 }
10425 case 105: /* AdaptiveResize */
10426 {
10427 if (attribute_flag[0] != 0)
10428 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10429 &geometry,exception);
10430 if (attribute_flag[1] != 0)
10431 geometry.width=argument_list[1].integer_reference;
10432 if (attribute_flag[2] != 0)
10433 geometry.height=argument_list[2].integer_reference;
10434 if (attribute_flag[3] != 0)
10435 image->filter=(FilterTypes) argument_list[4].integer_reference;
10436 if (attribute_flag[4] != 0)
10437 SetImageArtifact(image,"filter:support",
10438 argument_list[4].string_reference);
10439 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10440 exception);
10441 break;
10442 }
10443 case 106: /* ClipMask */
10444 {
10445 Image
10446 *mask_image;
10447
10448 if (attribute_flag[0] == 0)
10449 {
10450 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10451 PackageName);
10452 goto PerlException;
10453 }
10454 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10455 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010456 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010457 mask_image=DestroyImage(mask_image);
10458 break;
10459 }
10460 case 107: /* LinearStretch */
10461 {
10462 double
10463 black_point,
10464 white_point;
10465
10466 black_point=0.0;
10467 white_point=(double) image->columns*image->rows;
10468 if (attribute_flag[0] != 0)
10469 {
10470 flags=ParseGeometry(argument_list[0].string_reference,
10471 &geometry_info);
10472 if ((flags & SigmaValue) != 0)
10473 white_point=geometry_info.sigma;
10474 if ((flags & PercentValue) != 0)
10475 {
10476 black_point*=(double) image->columns*image->rows/100.0;
10477 white_point*=(double) image->columns*image->rows/100.0;
10478 }
10479 if ((flags & SigmaValue) == 0)
10480 white_point=(double) image->columns*image->rows-black_point;
10481 }
10482 if (attribute_flag[1] != 0)
10483 black_point=argument_list[1].real_reference;
10484 if (attribute_flag[2] != 0)
10485 white_point=argument_list[2].real_reference;
10486 (void) LinearStretchImage(image,black_point,white_point,exception);
10487 break;
10488 }
10489 case 108: /* ColorMatrix */
10490 {
10491 AV
10492 *av;
10493
10494 double
10495 *color_matrix;
10496
10497 KernelInfo
10498 *kernel_info;
10499
10500 size_t
10501 order;
10502
10503 if (attribute_flag[0] == 0)
10504 break;
10505 av=(AV *) argument_list[0].array_reference;
10506 order=(size_t) sqrt(av_len(av)+1);
10507 color_matrix=(double *) AcquireQuantumMemory(order,order*
10508 sizeof(*color_matrix));
10509 if (color_matrix == (double *) NULL)
10510 {
10511 ThrowPerlException(exception,ResourceLimitFatalError,
10512 "MemoryAllocationFailed",PackageName);
10513 goto PerlException;
10514 }
10515 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10516 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10517 for ( ; j < (ssize_t) (order*order); j++)
10518 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010519 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010520 if (kernel_info == (KernelInfo *) NULL)
10521 break;
10522 kernel_info->width=order;
10523 kernel_info->height=order;
10524 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10525 order*sizeof(*kernel_info->values));
10526 if (kernel_info->values != (MagickRealType *) NULL)
10527 {
10528 for (i=0; i < (ssize_t) (order*order); i++)
10529 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10530 image=ColorMatrixImage(image,kernel_info,exception);
10531 }
10532 kernel_info=DestroyKernelInfo(kernel_info);
10533 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10534 break;
10535 }
10536 case 109: /* Mask */
10537 {
10538 Image
10539 *mask_image;
10540
10541 if (attribute_flag[0] == 0)
10542 {
10543 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10544 PackageName);
10545 goto PerlException;
10546 }
10547 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10548 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010549 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010550 mask_image=DestroyImage(mask_image);
10551 break;
10552 }
10553 case 110: /* Polaroid */
10554 {
10555 char
10556 *caption;
10557
10558 DrawInfo
10559 *draw_info;
10560
10561 double
10562 angle;
10563
10564 PixelInterpolateMethod
10565 method;
10566
10567 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10568 (DrawInfo *) NULL);
10569 caption=(char *) NULL;
10570 if (attribute_flag[0] != 0)
10571 caption=InterpretImageProperties(info ? info->image_info :
10572 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10573 exception);
10574 angle=0.0;
10575 if (attribute_flag[1] != 0)
10576 angle=argument_list[1].real_reference;
10577 if (attribute_flag[2] != 0)
10578 (void) CloneString(&draw_info->font,
10579 argument_list[2].string_reference);
10580 if (attribute_flag[3] != 0)
10581 (void) QueryColorCompliance(argument_list[3].string_reference,
10582 AllCompliance,&draw_info->stroke,exception);
10583 if (attribute_flag[4] != 0)
10584 (void) QueryColorCompliance(argument_list[4].string_reference,
10585 AllCompliance,&draw_info->fill,exception);
10586 if (attribute_flag[5] != 0)
10587 draw_info->stroke_width=argument_list[5].real_reference;
10588 if (attribute_flag[6] != 0)
10589 draw_info->pointsize=argument_list[6].real_reference;
10590 if (attribute_flag[7] != 0)
10591 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10592 if (attribute_flag[8] != 0)
10593 (void) QueryColorCompliance(argument_list[8].string_reference,
10594 AllCompliance,&image->background_color,exception);
10595 method=UndefinedInterpolatePixel;
10596 if (attribute_flag[9] != 0)
10597 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10598 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10599 draw_info=DestroyDrawInfo(draw_info);
10600 if (caption != (char *) NULL)
10601 caption=DestroyString(caption);
10602 break;
10603 }
10604 case 111: /* FloodfillPaint */
10605 {
10606 DrawInfo
10607 *draw_info;
10608
10609 MagickBooleanType
10610 invert;
10611
10612 PixelInfo
10613 target;
10614
10615 draw_info=CloneDrawInfo(info ? info->image_info :
10616 (ImageInfo *) NULL,(DrawInfo *) NULL);
10617 if (attribute_flag[0] != 0)
10618 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10619 &geometry,exception);
10620 if (attribute_flag[1] != 0)
10621 geometry.x=argument_list[1].integer_reference;
10622 if (attribute_flag[2] != 0)
10623 geometry.y=argument_list[2].integer_reference;
10624 if (attribute_flag[3] != 0)
10625 (void) QueryColorCompliance(argument_list[3].string_reference,
10626 AllCompliance,&draw_info->fill,exception);
10627 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10628 geometry.x,geometry.y,&target,exception);
10629 if (attribute_flag[4] != 0)
10630 QueryColorCompliance(argument_list[4].string_reference,
10631 AllCompliance,&target,exception);
10632 if (attribute_flag[5] != 0)
10633 image->fuzz=StringToDoubleInterval(
10634 argument_list[5].string_reference,(double) QuantumRange+1.0);
10635 if (attribute_flag[6] != 0)
10636 channel=(ChannelType) argument_list[6].integer_reference;
10637 invert=MagickFalse;
10638 if (attribute_flag[7] != 0)
10639 invert=(MagickBooleanType) argument_list[7].integer_reference;
10640 channel_mask=SetImageChannelMask(image,channel);
10641 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10642 geometry.y,invert,exception);
10643 (void) SetImageChannelMask(image,channel_mask);
10644 draw_info=DestroyDrawInfo(draw_info);
10645 break;
10646 }
10647 case 112: /* Distort */
10648 {
10649 AV
10650 *av;
10651
10652 double
10653 *coordinates;
10654
10655 DistortImageMethod
10656 method;
10657
10658 size_t
10659 number_coordinates;
10660
10661 VirtualPixelMethod
10662 virtual_pixel;
10663
10664 if (attribute_flag[0] == 0)
10665 break;
10666 method=UndefinedDistortion;
10667 if (attribute_flag[1] != 0)
10668 method=(DistortImageMethod) argument_list[1].integer_reference;
10669 av=(AV *) argument_list[0].array_reference;
10670 number_coordinates=(size_t) av_len(av)+1;
10671 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10672 sizeof(*coordinates));
10673 if (coordinates == (double *) NULL)
10674 {
10675 ThrowPerlException(exception,ResourceLimitFatalError,
10676 "MemoryAllocationFailed",PackageName);
10677 goto PerlException;
10678 }
10679 for (j=0; j < (ssize_t) number_coordinates; j++)
10680 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10681 virtual_pixel=UndefinedVirtualPixelMethod;
10682 if (attribute_flag[2] != 0)
10683 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10684 argument_list[2].integer_reference,exception);
10685 image=DistortImage(image,method,number_coordinates,coordinates,
10686 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10687 exception);
10688 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10689 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10690 exception);
10691 coordinates=(double *) RelinquishMagickMemory(coordinates);
10692 break;
10693 }
10694 case 113: /* Clut */
10695 {
10696 PixelInterpolateMethod
10697 method;
10698
10699 if (attribute_flag[0] == 0)
10700 {
10701 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10702 PackageName);
10703 goto PerlException;
10704 }
10705 method=UndefinedInterpolatePixel;
10706 if (attribute_flag[1] != 0)
10707 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10708 if (attribute_flag[2] != 0)
10709 channel=(ChannelType) argument_list[2].integer_reference;
10710 channel_mask=SetImageChannelMask(image,channel);
10711 (void) ClutImage(image,argument_list[0].image_reference,method,
10712 exception);
10713 (void) SetImageChannelMask(image,channel_mask);
10714 break;
10715 }
10716 case 114: /* LiquidRescale */
10717 {
10718 if (attribute_flag[0] != 0)
10719 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10720 &geometry,exception);
10721 if (attribute_flag[1] != 0)
10722 geometry.width=argument_list[1].integer_reference;
10723 if (attribute_flag[2] != 0)
10724 geometry.height=argument_list[2].integer_reference;
10725 if (attribute_flag[3] == 0)
10726 argument_list[3].real_reference=1.0;
10727 if (attribute_flag[4] == 0)
10728 argument_list[4].real_reference=0.0;
10729 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10730 argument_list[3].real_reference,argument_list[4].real_reference,
10731 exception);
10732 break;
10733 }
10734 case 115: /* EncipherImage */
10735 {
10736 (void) EncipherImage(image,argument_list[0].string_reference,
10737 exception);
10738 break;
10739 }
10740 case 116: /* DecipherImage */
10741 {
10742 (void) DecipherImage(image,argument_list[0].string_reference,
10743 exception);
10744 break;
10745 }
10746 case 117: /* Deskew */
10747 {
10748 geometry_info.rho=QuantumRange/2.0;
10749 if (attribute_flag[0] != 0)
10750 flags=ParseGeometry(argument_list[0].string_reference,
10751 &geometry_info);
10752 if (attribute_flag[1] != 0)
10753 geometry_info.rho=StringToDoubleInterval(
10754 argument_list[1].string_reference,(double) QuantumRange+1.0);
10755 image=DeskewImage(image,geometry_info.rho,exception);
10756 break;
10757 }
10758 case 118: /* Remap */
10759 {
10760 QuantizeInfo
10761 *quantize_info;
10762
10763 if (attribute_flag[0] == 0)
10764 {
10765 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10766 PackageName);
10767 goto PerlException;
10768 }
10769 quantize_info=AcquireQuantizeInfo(info->image_info);
10770 if (attribute_flag[1] != 0)
10771 quantize_info->dither_method=(DitherMethod)
10772 argument_list[1].integer_reference;
10773 (void) RemapImages(quantize_info,image,
10774 argument_list[0].image_reference,exception);
10775 quantize_info=DestroyQuantizeInfo(quantize_info);
10776 break;
10777 }
10778 case 119: /* SparseColor */
10779 {
10780 AV
10781 *av;
10782
10783 double
10784 *coordinates;
10785
10786 SparseColorMethod
10787 method;
10788
10789 size_t
10790 number_coordinates;
10791
10792 VirtualPixelMethod
10793 virtual_pixel;
10794
10795 if (attribute_flag[0] == 0)
10796 break;
10797 method=UndefinedColorInterpolate;
10798 if (attribute_flag[1] != 0)
10799 method=(SparseColorMethod) argument_list[1].integer_reference;
10800 av=(AV *) argument_list[0].array_reference;
10801 number_coordinates=(size_t) av_len(av)+1;
10802 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10803 sizeof(*coordinates));
10804 if (coordinates == (double *) NULL)
10805 {
10806 ThrowPerlException(exception,ResourceLimitFatalError,
10807 "MemoryAllocationFailed",PackageName);
10808 goto PerlException;
10809 }
10810 for (j=0; j < (ssize_t) number_coordinates; j++)
10811 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10812 virtual_pixel=UndefinedVirtualPixelMethod;
10813 if (attribute_flag[2] != 0)
10814 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10815 argument_list[2].integer_reference,exception);
10816 if (attribute_flag[3] != 0)
10817 channel=(ChannelType) argument_list[3].integer_reference;
10818 channel_mask=SetImageChannelMask(image,channel);
10819 image=SparseColorImage(image,method,number_coordinates,coordinates,
10820 exception);
10821 if (image != (Image *) NULL)
10822 (void) SetImageChannelMask(image,channel_mask);
10823 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10824 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10825 exception);
10826 coordinates=(double *) RelinquishMagickMemory(coordinates);
10827 break;
10828 }
10829 case 120: /* Function */
10830 {
10831 AV
10832 *av;
10833
10834 double
10835 *parameters;
10836
10837 MagickFunction
10838 function;
10839
10840 size_t
10841 number_parameters;
10842
10843 VirtualPixelMethod
10844 virtual_pixel;
10845
10846 if (attribute_flag[0] == 0)
10847 break;
10848 function=UndefinedFunction;
10849 if (attribute_flag[1] != 0)
10850 function=(MagickFunction) argument_list[1].integer_reference;
10851 av=(AV *) argument_list[0].array_reference;
10852 number_parameters=(size_t) av_len(av)+1;
10853 parameters=(double *) AcquireQuantumMemory(number_parameters,
10854 sizeof(*parameters));
10855 if (parameters == (double *) NULL)
10856 {
10857 ThrowPerlException(exception,ResourceLimitFatalError,
10858 "MemoryAllocationFailed",PackageName);
10859 goto PerlException;
10860 }
10861 for (j=0; j < (ssize_t) number_parameters; j++)
10862 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10863 virtual_pixel=UndefinedVirtualPixelMethod;
10864 if (attribute_flag[2] != 0)
10865 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10866 argument_list[2].integer_reference,exception);
10867 (void) FunctionImage(image,function,number_parameters,parameters,
10868 exception);
10869 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10870 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10871 exception);
10872 parameters=(double *) RelinquishMagickMemory(parameters);
10873 break;
10874 }
10875 case 121: /* SelectiveBlur */
10876 {
10877 if (attribute_flag[0] != 0)
10878 {
10879 flags=ParseGeometry(argument_list[0].string_reference,
10880 &geometry_info);
10881 if ((flags & SigmaValue) == 0)
10882 geometry_info.sigma=1.0;
10883 if ((flags & PercentValue) != 0)
10884 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10885 }
10886 if (attribute_flag[1] != 0)
10887 geometry_info.rho=argument_list[1].real_reference;
10888 if (attribute_flag[2] != 0)
10889 geometry_info.sigma=argument_list[2].real_reference;
10890 if (attribute_flag[3] != 0)
10891 geometry_info.xi=argument_list[3].integer_reference;;
10892 if (attribute_flag[5] != 0)
10893 channel=(ChannelType) argument_list[5].integer_reference;
10894 channel_mask=SetImageChannelMask(image,channel);
10895 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10896 geometry_info.xi,exception);
10897 if (image != (Image *) NULL)
10898 (void) SetImageChannelMask(image,channel_mask);
10899 break;
10900 }
10901 case 122: /* HaldClut */
10902 {
10903 if (attribute_flag[0] == 0)
10904 {
10905 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10906 PackageName);
10907 goto PerlException;
10908 }
10909 if (attribute_flag[1] != 0)
10910 channel=(ChannelType) argument_list[1].integer_reference;
10911 channel_mask=SetImageChannelMask(image,channel);
10912 (void) HaldClutImage(image,argument_list[0].image_reference,
10913 exception);
10914 (void) SetImageChannelMask(image,channel_mask);
10915 break;
10916 }
10917 case 123: /* BlueShift */
10918 {
10919 if (attribute_flag[0] != 0)
10920 (void) ParseGeometry(argument_list[0].string_reference,
10921 &geometry_info);
10922 image=BlueShiftImage(image,geometry_info.rho,exception);
10923 break;
10924 }
10925 case 124: /* ForwardFourierTransformImage */
10926 {
10927 image=ForwardFourierTransformImage(image,
10928 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10929 exception);
10930 break;
10931 }
10932 case 125: /* InverseFourierTransformImage */
10933 {
10934 image=InverseFourierTransformImage(image,image->next,
10935 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10936 exception);
10937 break;
10938 }
10939 case 126: /* ColorDecisionList */
10940 {
10941 if (attribute_flag[0] == 0)
10942 argument_list[0].string_reference=(char *) NULL;
10943 (void) ColorDecisionListImage(image,
10944 argument_list[0].string_reference,exception);
10945 break;
10946 }
10947 case 127: /* AutoGamma */
10948 {
10949 if (attribute_flag[0] != 0)
10950 channel=(ChannelType) argument_list[0].integer_reference;
10951 channel_mask=SetImageChannelMask(image,channel);
10952 (void) AutoGammaImage(image,exception);
10953 (void) SetImageChannelMask(image,channel_mask);
10954 break;
10955 }
10956 case 128: /* AutoLevel */
10957 {
10958 if (attribute_flag[0] != 0)
10959 channel=(ChannelType) argument_list[0].integer_reference;
10960 channel_mask=SetImageChannelMask(image,channel);
10961 (void) AutoLevelImage(image,exception);
10962 (void) SetImageChannelMask(image,channel_mask);
10963 break;
10964 }
10965 case 129: /* LevelColors */
10966 {
10967 PixelInfo
10968 black_point,
10969 white_point;
10970
10971 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10972 exception);
10973 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10974 exception);
10975 if (attribute_flag[1] != 0)
10976 (void) QueryColorCompliance(
10977 argument_list[1].string_reference,AllCompliance,&black_point,
10978 exception);
10979 if (attribute_flag[2] != 0)
10980 (void) QueryColorCompliance(
10981 argument_list[2].string_reference,AllCompliance,&white_point,
10982 exception);
10983 if (attribute_flag[3] != 0)
10984 channel=(ChannelType) argument_list[3].integer_reference;
10985 channel_mask=SetImageChannelMask(image,channel);
10986 (void) LevelImageColors(image,&black_point,&white_point,
10987 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10988 exception);
10989 (void) SetImageChannelMask(image,channel_mask);
10990 break;
10991 }
10992 case 130: /* Clamp */
10993 {
10994 if (attribute_flag[0] != 0)
10995 channel=(ChannelType) argument_list[0].integer_reference;
10996 channel_mask=SetImageChannelMask(image,channel);
10997 (void) ClampImage(image,exception);
10998 (void) SetImageChannelMask(image,channel_mask);
10999 break;
11000 }
11001 case 131: /* BrightnessContrast */
11002 {
11003 double
11004 brightness,
11005 contrast;
11006
11007 brightness=0.0;
11008 contrast=0.0;
11009 if (attribute_flag[0] != 0)
11010 {
11011 flags=ParseGeometry(argument_list[0].string_reference,
11012 &geometry_info);
11013 brightness=geometry_info.rho;
11014 if ((flags & SigmaValue) == 0)
11015 contrast=geometry_info.sigma;
11016 }
11017 if (attribute_flag[1] != 0)
11018 brightness=argument_list[1].real_reference;
11019 if (attribute_flag[2] != 0)
11020 contrast=argument_list[2].real_reference;
11021 if (attribute_flag[4] != 0)
11022 channel=(ChannelType) argument_list[4].integer_reference;
11023 channel_mask=SetImageChannelMask(image,channel);
11024 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11025 (void) SetImageChannelMask(image,channel_mask);
11026 break;
11027 }
11028 case 132: /* Morphology */
11029 {
11030 KernelInfo
11031 *kernel;
11032
11033 MorphologyMethod
11034 method;
11035
11036 ssize_t
11037 iterations;
11038
11039 if (attribute_flag[0] == 0)
11040 break;
cristy2c57b742014-10-31 00:40:34 +000011041 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011042 if (kernel == (KernelInfo *) NULL)
11043 break;
11044 if (attribute_flag[1] != 0)
11045 channel=(ChannelType) argument_list[1].integer_reference;
11046 method=UndefinedMorphology;
11047 if (attribute_flag[2] != 0)
11048 method=argument_list[2].integer_reference;
11049 iterations=1;
11050 if (attribute_flag[3] != 0)
11051 iterations=argument_list[3].integer_reference;
11052 channel_mask=SetImageChannelMask(image,channel);
11053 image=MorphologyImage(image,method,iterations,kernel,exception);
11054 if (image != (Image *) NULL)
11055 (void) SetImageChannelMask(image,channel_mask);
11056 kernel=DestroyKernelInfo(kernel);
11057 break;
11058 }
11059 case 133: /* Mode */
11060 {
11061 if (attribute_flag[0] != 0)
11062 {
11063 flags=ParseGeometry(argument_list[0].string_reference,
11064 &geometry_info);
11065 if ((flags & SigmaValue) == 0)
11066 geometry_info.sigma=1.0;
11067 }
11068 if (attribute_flag[1] != 0)
11069 geometry_info.rho=argument_list[1].real_reference;
11070 if (attribute_flag[2] != 0)
11071 geometry_info.sigma=argument_list[2].real_reference;
11072 if (attribute_flag[3] != 0)
11073 channel=(ChannelType) argument_list[3].integer_reference;
11074 channel_mask=SetImageChannelMask(image,channel);
11075 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11076 (size_t) geometry_info.sigma,exception);
11077 if (image != (Image *) NULL)
11078 (void) SetImageChannelMask(image,channel_mask);
11079 break;
11080 }
11081 case 134: /* Statistic */
11082 {
11083 StatisticType
11084 statistic;
11085
11086 statistic=UndefinedStatistic;
11087 if (attribute_flag[0] != 0)
11088 {
11089 flags=ParseGeometry(argument_list[0].string_reference,
11090 &geometry_info);
11091 if ((flags & SigmaValue) == 0)
11092 geometry_info.sigma=1.0;
11093 }
11094 if (attribute_flag[1] != 0)
11095 geometry_info.rho=argument_list[1].real_reference;
11096 if (attribute_flag[2] != 0)
11097 geometry_info.sigma=argument_list[2].real_reference;
11098 if (attribute_flag[3] != 0)
11099 channel=(ChannelType) argument_list[3].integer_reference;
11100 if (attribute_flag[4] != 0)
11101 statistic=(StatisticType) argument_list[4].integer_reference;
11102 channel_mask=SetImageChannelMask(image,channel);
11103 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11104 (size_t) geometry_info.sigma,exception);
11105 if (image != (Image *) NULL)
11106 (void) SetImageChannelMask(image,channel_mask);
11107 break;
11108 }
11109 case 135: /* Perceptible */
11110 {
11111 double
11112 epsilon;
11113
11114 epsilon=MagickEpsilon;
11115 if (attribute_flag[0] != 0)
11116 epsilon=argument_list[0].real_reference;
11117 if (attribute_flag[1] != 0)
11118 channel=(ChannelType) argument_list[1].integer_reference;
11119 channel_mask=SetImageChannelMask(image,channel);
11120 (void) PerceptibleImage(image,epsilon,exception);
11121 (void) SetImageChannelMask(image,channel_mask);
11122 break;
11123 }
11124 case 136: /* Poly */
11125 {
11126 AV
11127 *av;
11128
11129 double
11130 *terms;
11131
11132 size_t
11133 number_terms;
11134
11135 if (attribute_flag[0] == 0)
11136 break;
11137 if (attribute_flag[1] != 0)
11138 channel=(ChannelType) argument_list[1].integer_reference;
11139 av=(AV *) argument_list[0].array_reference;
11140 number_terms=(size_t) av_len(av);
11141 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11142 if (terms == (double *) NULL)
11143 {
11144 ThrowPerlException(exception,ResourceLimitFatalError,
11145 "MemoryAllocationFailed",PackageName);
11146 goto PerlException;
11147 }
11148 for (j=0; j < av_len(av); j++)
11149 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11150 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11151 terms=(double *) RelinquishMagickMemory(terms);
11152 break;
11153 }
11154 case 137: /* Grayscale */
11155 {
11156 PixelIntensityMethod
11157 method;
11158
11159 method=UndefinedPixelIntensityMethod;
11160 if (attribute_flag[0] != 0)
11161 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11162 (void) GrayscaleImage(image,method,exception);
11163 break;
11164 }
cristy4ceadb82014-03-29 15:30:43 +000011165 case 138: /* Canny */
11166 {
11167 if (attribute_flag[0] != 0)
11168 {
11169 flags=ParseGeometry(argument_list[0].string_reference,
11170 &geometry_info);
11171 if ((flags & SigmaValue) == 0)
11172 geometry_info.sigma=1.0;
11173 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011174 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011175 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011176 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011177 if ((flags & PercentValue) != 0)
11178 {
11179 geometry_info.xi/=100.0;
11180 geometry_info.psi/=100.0;
11181 }
cristy4ceadb82014-03-29 15:30:43 +000011182 }
11183 if (attribute_flag[1] != 0)
11184 geometry_info.rho=argument_list[1].real_reference;
11185 if (attribute_flag[2] != 0)
11186 geometry_info.sigma=argument_list[2].real_reference;
11187 if (attribute_flag[3] != 0)
11188 geometry_info.xi=argument_list[3].real_reference;
11189 if (attribute_flag[4] != 0)
11190 geometry_info.psi=argument_list[4].real_reference;
11191 if (attribute_flag[5] != 0)
11192 channel=(ChannelType) argument_list[5].integer_reference;
11193 channel_mask=SetImageChannelMask(image,channel);
11194 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11195 geometry_info.xi,geometry_info.psi,exception);
11196 if (image != (Image *) NULL)
11197 (void) SetImageChannelMask(image,channel_mask);
11198 break;
11199 }
cristy2fc10e52014-04-26 14:13:53 +000011200 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011201 {
11202 if (attribute_flag[0] != 0)
11203 {
11204 flags=ParseGeometry(argument_list[0].string_reference,
11205 &geometry_info);
11206 if ((flags & SigmaValue) == 0)
11207 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011208 if ((flags & XiValue) == 0)
11209 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011210 }
11211 if (attribute_flag[1] != 0)
11212 geometry_info.rho=(double) argument_list[1].integer_reference;
11213 if (attribute_flag[2] != 0)
11214 geometry_info.sigma=(double) argument_list[2].integer_reference;
11215 if (attribute_flag[3] != 0)
11216 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011217 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11218 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11219 break;
11220 }
11221 case 140: /* MeanShift */
11222 {
11223 if (attribute_flag[0] != 0)
11224 {
11225 flags=ParseGeometry(argument_list[0].string_reference,
11226 &geometry_info);
11227 if ((flags & SigmaValue) == 0)
11228 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011229 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011230 geometry_info.xi=0.10*QuantumRange;
11231 if ((flags & PercentValue) != 0)
11232 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011233 }
11234 if (attribute_flag[1] != 0)
11235 geometry_info.rho=(double) argument_list[1].integer_reference;
11236 if (attribute_flag[2] != 0)
11237 geometry_info.sigma=(double) argument_list[2].integer_reference;
11238 if (attribute_flag[3] != 0)
11239 geometry_info.xi=(double) argument_list[3].integer_reference;
11240 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011241 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011242 break;
11243 }
cristy3b207f82014-09-27 14:21:20 +000011244 case 141: /* Kuwahara */
11245 {
11246 if (attribute_flag[0] != 0)
11247 {
11248 flags=ParseGeometry(argument_list[0].string_reference,
11249 &geometry_info);
11250 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011251 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011252 }
11253 if (attribute_flag[1] != 0)
11254 geometry_info.rho=argument_list[1].real_reference;
11255 if (attribute_flag[2] != 0)
11256 geometry_info.sigma=argument_list[2].real_reference;
11257 if (attribute_flag[3] != 0)
11258 channel=(ChannelType) argument_list[3].integer_reference;
11259 channel_mask=SetImageChannelMask(image,channel);
11260 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11261 exception);
11262 if (image != (Image *) NULL)
11263 (void) SetImageChannelMask(image,channel_mask);
11264 break;
11265 }
cristy6e0b3bc2014-10-19 17:51:42 +000011266 case 142: /* ConnectedComponent */
11267 {
11268 size_t
11269 connectivity;
11270
11271 connectivity=4;
11272 if (attribute_flag[0] != 0)
11273 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011274 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011275 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011276 break;
11277 }
cristy0b94b392015-06-22 18:56:37 +000011278 case 143: /* Copy */
11279 {
11280 Image
11281 *source_image;
11282
11283 OffsetInfo
11284 offset;
11285
cristy2ffdb092015-06-25 14:31:20 +000011286 RectangleInfo
11287 offset_geometry;
11288
cristyf3a724a2015-06-25 13:02:53 +000011289 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011290 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011291 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011292 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011293 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011294 flags=ParseGravityGeometry(source_image,
11295 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011296 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011297 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011298 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011299 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011300 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011301 geometry.x=argument_list[4].integer_reference;
11302 if (attribute_flag[5] != 0)
11303 geometry.y=argument_list[5].integer_reference;
11304 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011305 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011306 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011307 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011308 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11309 &offset_geometry,exception);
11310 offset.x=offset_geometry.x;
11311 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011312 if (attribute_flag[8] != 0)
11313 offset.x=argument_list[8].integer_reference;
11314 if (attribute_flag[9] != 0)
11315 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011316 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11317 exception);
cristy0b94b392015-06-22 18:56:37 +000011318 break;
11319 }
cristy4a3ce0a2013-08-03 20:06:59 +000011320 }
11321 if (next != (Image *) NULL)
11322 (void) CatchImageException(next);
11323 if (region_image != (Image *) NULL)
11324 {
11325 /*
11326 Composite region.
cristy83a28a02013-08-03 20:25:48 +000011327 */
cristy4a3ce0a2013-08-03 20:06:59 +000011328 status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11329 region_info.x,region_info.y,exception);
11330 (void) status;
11331 (void) CatchImageException(region_image);
11332 image=DestroyImage(image);
11333 image=region_image;
11334 }
11335 if (image != (Image *) NULL)
11336 {
11337 number_images++;
11338 if (next && (next != image))
11339 {
11340 image->next=next->next;
11341 if (image->next != (Image *) NULL)
11342 image->next->previous=image;
11343 DeleteImageFromRegistry(*pv,next);
11344 }
11345 sv_setiv(*pv,PTR2IV(image));
11346 next=image;
11347 }
11348 if (*pv)
11349 pv++;
11350 }
11351
11352 PerlException:
11353 if (reference_vector)
11354 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11355 InheritPerlException(exception,perl_exception);
11356 exception=DestroyExceptionInfo(exception);
11357 sv_setiv(perl_exception,(IV) number_images);
11358 SvPOK_on(perl_exception);
11359 ST(0)=sv_2mortal(perl_exception);
11360 XSRETURN(1);
11361 }
11362
11363#
11364###############################################################################
11365# #
11366# #
11367# #
11368# M o n t a g e #
11369# #
11370# #
11371# #
11372###############################################################################
11373#
11374#
11375void
11376Montage(ref,...)
11377 Image::Magick ref=NO_INIT
11378 ALIAS:
11379 MontageImage = 1
11380 montage = 2
11381 montageimage = 3
11382 PPCODE:
11383 {
11384 AV
11385 *av;
11386
11387 char
11388 *attribute;
11389
11390 ExceptionInfo
11391 *exception;
11392
11393 HV
11394 *hv;
11395
11396 Image
11397 *image,
11398 *next;
11399
11400 PixelInfo
11401 transparent_color;
11402
11403 MontageInfo
11404 *montage_info;
11405
11406 register ssize_t
11407 i;
11408
11409 ssize_t
11410 sp;
11411
11412 struct PackageInfo
11413 *info;
11414
11415 SV
11416 *av_reference,
11417 *perl_exception,
11418 *reference,
11419 *rv,
11420 *sv;
11421
11422 PERL_UNUSED_VAR(ref);
11423 PERL_UNUSED_VAR(ix);
11424 exception=AcquireExceptionInfo();
11425 perl_exception=newSVpv("",0);
11426 sv=NULL;
11427 attribute=NULL;
11428 if (sv_isobject(ST(0)) == 0)
11429 {
11430 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11431 PackageName);
11432 goto PerlException;
11433 }
11434 reference=SvRV(ST(0));
11435 hv=SvSTASH(reference);
11436 av=newAV();
11437 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11438 SvREFCNT_dec(av);
11439 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11440 if (image == (Image *) NULL)
11441 {
11442 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11443 PackageName);
11444 goto PerlException;
11445 }
11446 /*
11447 Get options.
11448 */
11449 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11450 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11451 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11452 exception);
11453 for (i=2; i < items; i+=2)
11454 {
11455 attribute=(char *) SvPV(ST(i-1),na);
11456 switch (*attribute)
11457 {
11458 case 'B':
11459 case 'b':
11460 {
11461 if (LocaleCompare(attribute,"background") == 0)
11462 {
11463 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11464 &montage_info->background_color,exception);
11465 for (next=image; next; next=next->next)
11466 next->background_color=montage_info->background_color;
11467 break;
11468 }
11469 if (LocaleCompare(attribute,"border") == 0)
11470 {
11471 montage_info->border_width=SvIV(ST(i));
11472 break;
11473 }
11474 if (LocaleCompare(attribute,"bordercolor") == 0)
11475 {
11476 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11477 &montage_info->border_color,exception);
11478 for (next=image; next; next=next->next)
11479 next->border_color=montage_info->border_color;
11480 break;
11481 }
11482 if (LocaleCompare(attribute,"borderwidth") == 0)
11483 {
11484 montage_info->border_width=SvIV(ST(i));
11485 break;
11486 }
11487 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11488 attribute);
11489 break;
11490 }
11491 case 'C':
11492 case 'c':
11493 {
11494 if (LocaleCompare(attribute,"compose") == 0)
11495 {
11496 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11497 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11498 if (sp < 0)
11499 {
11500 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11501 SvPV(ST(i),na));
11502 break;
11503 }
11504 for (next=image; next; next=next->next)
11505 next->compose=(CompositeOperator) sp;
11506 break;
11507 }
11508 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11509 attribute);
11510 break;
11511 }
11512 case 'F':
11513 case 'f':
11514 {
11515 if (LocaleCompare(attribute,"fill") == 0)
11516 {
11517 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11518 &montage_info->fill,exception);
11519 break;
11520 }
11521 if (LocaleCompare(attribute,"font") == 0)
11522 {
11523 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11524 break;
11525 }
11526 if (LocaleCompare(attribute,"frame") == 0)
11527 {
11528 char
11529 *p;
11530
11531 p=SvPV(ST(i),na);
11532 if (IsGeometry(p) == MagickFalse)
11533 {
11534 ThrowPerlException(exception,OptionError,"MissingGeometry",
11535 p);
11536 break;
11537 }
11538 (void) CloneString(&montage_info->frame,p);
11539 if (*p == '\0')
11540 montage_info->frame=(char *) NULL;
11541 break;
11542 }
11543 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11544 attribute);
11545 break;
11546 }
11547 case 'G':
11548 case 'g':
11549 {
11550 if (LocaleCompare(attribute,"geometry") == 0)
11551 {
11552 char
11553 *p;
11554
11555 p=SvPV(ST(i),na);
11556 if (IsGeometry(p) == MagickFalse)
11557 {
11558 ThrowPerlException(exception,OptionError,"MissingGeometry",
11559 p);
11560 break;
11561 }
11562 (void) CloneString(&montage_info->geometry,p);
11563 if (*p == '\0')
11564 montage_info->geometry=(char *) NULL;
11565 break;
11566 }
11567 if (LocaleCompare(attribute,"gravity") == 0)
11568 {
11569 ssize_t
11570 in;
11571
11572 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11573 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11574 if (in < 0)
11575 {
11576 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11577 SvPV(ST(i),na));
11578 return;
11579 }
11580 montage_info->gravity=(GravityType) in;
11581 for (next=image; next; next=next->next)
11582 next->gravity=(GravityType) in;
11583 break;
11584 }
11585 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11586 attribute);
11587 break;
11588 }
11589 case 'L':
11590 case 'l':
11591 {
11592 if (LocaleCompare(attribute,"label") == 0)
11593 {
11594 for (next=image; next; next=next->next)
11595 (void) SetImageProperty(next,"label",InterpretImageProperties(
11596 info ? info->image_info : (ImageInfo *) NULL,next,
11597 SvPV(ST(i),na),exception),exception);
11598 break;
11599 }
11600 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11601 attribute);
11602 break;
11603 }
11604 case 'M':
11605 case 'm':
11606 {
11607 if (LocaleCompare(attribute,"mattecolor") == 0)
11608 {
11609 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11610 &montage_info->matte_color,exception);
11611 for (next=image; next; next=next->next)
11612 next->matte_color=montage_info->matte_color;
11613 break;
11614 }
11615 if (LocaleCompare(attribute,"mode") == 0)
11616 {
11617 ssize_t
11618 in;
11619
11620 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11621 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11622 switch (in)
11623 {
11624 default:
11625 {
11626 ThrowPerlException(exception,OptionError,
11627 "UnrecognizedModeType",SvPV(ST(i),na));
11628 break;
11629 }
11630 case FrameMode:
11631 {
11632 (void) CloneString(&montage_info->frame,"15x15+3+3");
11633 montage_info->shadow=MagickTrue;
11634 break;
11635 }
11636 case UnframeMode:
11637 {
11638 montage_info->frame=(char *) NULL;
11639 montage_info->shadow=MagickFalse;
11640 montage_info->border_width=0;
11641 break;
11642 }
11643 case ConcatenateMode:
11644 {
11645 montage_info->frame=(char *) NULL;
11646 montage_info->shadow=MagickFalse;
11647 (void) CloneString(&montage_info->geometry,"+0+0");
11648 montage_info->border_width=0;
11649 }
11650 }
11651 break;
11652 }
11653 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11654 attribute);
11655 break;
11656 }
11657 case 'P':
11658 case 'p':
11659 {
11660 if (LocaleCompare(attribute,"pointsize") == 0)
11661 {
11662 montage_info->pointsize=SvIV(ST(i));
11663 break;
11664 }
11665 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11666 attribute);
11667 break;
11668 }
11669 case 'S':
11670 case 's':
11671 {
11672 if (LocaleCompare(attribute,"shadow") == 0)
11673 {
11674 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11675 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11676 if (sp < 0)
11677 {
11678 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11679 SvPV(ST(i),na));
11680 break;
11681 }
11682 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11683 break;
11684 }
11685 if (LocaleCompare(attribute,"stroke") == 0)
11686 {
11687 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11688 &montage_info->stroke,exception);
11689 break;
11690 }
11691 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11692 attribute);
11693 break;
11694 }
11695 case 'T':
11696 case 't':
11697 {
11698 if (LocaleCompare(attribute,"texture") == 0)
11699 {
11700 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11701 break;
11702 }
11703 if (LocaleCompare(attribute,"tile") == 0)
11704 {
11705 char *p=SvPV(ST(i),na);
11706 if (IsGeometry(p) == MagickFalse)
11707 {
11708 ThrowPerlException(exception,OptionError,"MissingGeometry",
11709 p);
11710 break;
11711 }
11712 (void) CloneString(&montage_info->tile,p);
11713 if (*p == '\0')
11714 montage_info->tile=(char *) NULL;
11715 break;
11716 }
11717 if (LocaleCompare(attribute,"title") == 0)
11718 {
11719 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11720 break;
11721 }
11722 if (LocaleCompare(attribute,"transparent") == 0)
11723 {
11724 PixelInfo
11725 transparent_color;
11726
11727 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11728 &transparent_color,exception);
11729 for (next=image; next; next=next->next)
11730 (void) TransparentPaintImage(next,&transparent_color,
11731 TransparentAlpha,MagickFalse,exception);
11732 break;
11733 }
11734 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11735 attribute);
11736 break;
11737 }
11738 default:
11739 {
11740 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11741 attribute);
11742 break;
11743 }
11744 }
11745 }
11746 image=MontageImageList(info->image_info,montage_info,image,exception);
11747 montage_info=DestroyMontageInfo(montage_info);
11748 if (image == (Image *) NULL)
11749 goto PerlException;
11750 if (transparent_color.alpha != TransparentAlpha)
11751 for (next=image; next; next=next->next)
11752 (void) TransparentPaintImage(next,&transparent_color,
11753 TransparentAlpha,MagickFalse,exception);
11754 for ( ; image; image=image->next)
11755 {
11756 AddImageToRegistry(sv,image);
11757 rv=newRV(sv);
11758 av_push(av,sv_bless(rv,hv));
11759 SvREFCNT_dec(sv);
11760 }
11761 exception=DestroyExceptionInfo(exception);
11762 ST(0)=av_reference;
11763 SvREFCNT_dec(perl_exception);
11764 XSRETURN(1);
11765
11766 PerlException:
11767 InheritPerlException(exception,perl_exception);
11768 exception=DestroyExceptionInfo(exception);
11769 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11770 SvPOK_on(perl_exception);
11771 ST(0)=sv_2mortal(perl_exception);
11772 XSRETURN(1);
11773 }
11774
11775#
11776###############################################################################
11777# #
11778# #
11779# #
11780# M o r p h #
11781# #
11782# #
11783# #
11784###############################################################################
11785#
11786#
11787void
11788Morph(ref,...)
11789 Image::Magick ref=NO_INIT
11790 ALIAS:
11791 MorphImage = 1
11792 morph = 2
11793 morphimage = 3
11794 PPCODE:
11795 {
11796 AV
11797 *av;
11798
11799 char
11800 *attribute;
11801
11802 ExceptionInfo
11803 *exception;
11804
11805 HV
11806 *hv;
11807
11808 Image
11809 *image;
11810
11811 register ssize_t
11812 i;
11813
11814 ssize_t
11815 number_frames;
11816
11817 struct PackageInfo
11818 *info;
11819
11820 SV
11821 *av_reference,
11822 *perl_exception,
11823 *reference,
11824 *rv,
11825 *sv;
11826
11827 PERL_UNUSED_VAR(ref);
11828 PERL_UNUSED_VAR(ix);
11829 exception=AcquireExceptionInfo();
11830 perl_exception=newSVpv("",0);
11831 sv=NULL;
11832 av=NULL;
11833 attribute=NULL;
11834 if (sv_isobject(ST(0)) == 0)
11835 {
11836 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11837 PackageName);
11838 goto PerlException;
11839 }
11840 reference=SvRV(ST(0));
11841 hv=SvSTASH(reference);
11842 av=newAV();
11843 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11844 SvREFCNT_dec(av);
11845 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11846 if (image == (Image *) NULL)
11847 {
11848 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11849 PackageName);
11850 goto PerlException;
11851 }
11852 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11853 /*
11854 Get attribute.
11855 */
11856 number_frames=30;
11857 for (i=2; i < items; i+=2)
11858 {
11859 attribute=(char *) SvPV(ST(i-1),na);
11860 switch (*attribute)
11861 {
11862 case 'F':
11863 case 'f':
11864 {
11865 if (LocaleCompare(attribute,"frames") == 0)
11866 {
11867 number_frames=SvIV(ST(i));
11868 break;
11869 }
11870 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11871 attribute);
11872 break;
11873 }
11874 default:
11875 {
11876 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11877 attribute);
11878 break;
11879 }
11880 }
11881 }
11882 image=MorphImages(image,number_frames,exception);
11883 if (image == (Image *) NULL)
11884 goto PerlException;
11885 for ( ; image; image=image->next)
11886 {
11887 AddImageToRegistry(sv,image);
11888 rv=newRV(sv);
11889 av_push(av,sv_bless(rv,hv));
11890 SvREFCNT_dec(sv);
11891 }
11892 exception=DestroyExceptionInfo(exception);
11893 ST(0)=av_reference;
11894 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11895 XSRETURN(1);
11896
11897 PerlException:
11898 InheritPerlException(exception,perl_exception);
11899 exception=DestroyExceptionInfo(exception);
11900 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11901 SvPOK_on(perl_exception);
11902 ST(0)=sv_2mortal(perl_exception);
11903 XSRETURN(1);
11904 }
11905
11906#
11907###############################################################################
11908# #
11909# #
11910# #
11911# M o s a i c #
11912# #
11913# #
11914# #
11915###############################################################################
11916#
11917#
11918void
11919Mosaic(ref)
11920 Image::Magick ref=NO_INIT
11921 ALIAS:
11922 MosaicImage = 1
11923 mosaic = 2
11924 mosaicimage = 3
11925 PPCODE:
11926 {
11927 AV
11928 *av;
11929
11930 ExceptionInfo
11931 *exception;
11932
11933 HV
11934 *hv;
11935
11936 Image
11937 *image;
11938
11939 struct PackageInfo
11940 *info;
11941
11942 SV
11943 *perl_exception,
11944 *reference,
11945 *rv,
11946 *sv;
11947
11948 PERL_UNUSED_VAR(ref);
11949 PERL_UNUSED_VAR(ix);
11950 exception=AcquireExceptionInfo();
11951 perl_exception=newSVpv("",0);
11952 sv=NULL;
11953 if (sv_isobject(ST(0)) == 0)
11954 {
11955 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11956 PackageName);
11957 goto PerlException;
11958 }
11959 reference=SvRV(ST(0));
11960 hv=SvSTASH(reference);
11961 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11962 if (image == (Image *) NULL)
11963 {
11964 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11965 PackageName);
11966 goto PerlException;
11967 }
11968 image=MergeImageLayers(image,MosaicLayer,exception);
11969 /*
11970 Create blessed Perl array for the returned image.
11971 */
11972 av=newAV();
11973 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11974 SvREFCNT_dec(av);
11975 AddImageToRegistry(sv,image);
11976 rv=newRV(sv);
11977 av_push(av,sv_bless(rv,hv));
11978 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000011979 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000011980 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000011981 SetImageInfo(info->image_info,0,exception);
11982 exception=DestroyExceptionInfo(exception);
11983 SvREFCNT_dec(perl_exception);
11984 XSRETURN(1);
11985
11986 PerlException:
11987 InheritPerlException(exception,perl_exception);
11988 exception=DestroyExceptionInfo(exception);
11989 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11990 SvPOK_on(perl_exception); /* return messages in string context */
11991 ST(0)=sv_2mortal(perl_exception);
11992 XSRETURN(1);
11993 }
11994
11995#
11996###############################################################################
11997# #
11998# #
11999# #
12000# P i n g #
12001# #
12002# #
12003# #
12004###############################################################################
12005#
12006#
12007void
12008Ping(ref,...)
12009 Image::Magick ref=NO_INIT
12010 ALIAS:
12011 PingImage = 1
12012 ping = 2
12013 pingimage = 3
12014 PPCODE:
12015 {
12016 AV
12017 *av;
12018
12019 char
12020 **keep,
12021 **list;
12022
12023 ExceptionInfo
12024 *exception;
12025
12026 Image
12027 *image,
12028 *next;
12029
12030 int
12031 n;
12032
12033 MagickBooleanType
12034 status;
12035
12036 register char
12037 **p;
12038
12039 register ssize_t
12040 i;
12041
12042 ssize_t
12043 ac;
12044
12045 STRLEN
12046 *length;
12047
12048 struct PackageInfo
12049 *info,
12050 *package_info;
12051
12052 SV
12053 *perl_exception,
12054 *reference;
12055
12056 size_t
12057 count;
12058
12059 PERL_UNUSED_VAR(ref);
12060 PERL_UNUSED_VAR(ix);
12061 exception=AcquireExceptionInfo();
12062 perl_exception=newSVpv("",0);
12063 package_info=(struct PackageInfo *) NULL;
12064 ac=(items < 2) ? 1 : items-1;
12065 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12066 keep=list;
12067 length=(STRLEN *) NULL;
12068 if (list == (char **) NULL)
12069 {
12070 ThrowPerlException(exception,ResourceLimitError,
12071 "MemoryAllocationFailed",PackageName);
12072 goto PerlException;
12073 }
12074 keep=list;
12075 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12076 if (length == (STRLEN *) NULL)
12077 {
12078 ThrowPerlException(exception,ResourceLimitError,
12079 "MemoryAllocationFailed",PackageName);
12080 goto PerlException;
12081 }
12082 if (sv_isobject(ST(0)) == 0)
12083 {
12084 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12085 PackageName);
12086 goto PerlException;
12087 }
12088 reference=SvRV(ST(0));
12089 if (SvTYPE(reference) != SVt_PVAV)
12090 {
12091 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12092 PackageName);
12093 goto PerlException;
12094 }
12095 av=(AV *) reference;
12096 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12097 exception);
12098 package_info=ClonePackageInfo(info,exception);
12099 n=1;
12100 if (items <= 1)
12101 *list=(char *) (*package_info->image_info->filename ?
12102 package_info->image_info->filename : "XC:black");
12103 else
12104 for (n=0, i=0; i < ac; i++)
12105 {
12106 list[n]=(char *) SvPV(ST(i+1),length[n]);
12107 if ((items >= 3) && strEQcase(list[n],"blob"))
12108 {
12109 void
12110 *blob;
12111
12112 i++;
12113 blob=(void *) (SvPV(ST(i+1),length[n]));
12114 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12115 }
12116 if ((items >= 3) && strEQcase(list[n],"filename"))
12117 continue;
12118 if ((items >= 3) && strEQcase(list[n],"file"))
12119 {
12120 FILE
12121 *file;
12122
12123 PerlIO
12124 *io_info;
12125
12126 i++;
12127 io_info=IoIFP(sv_2io(ST(i+1)));
12128 if (io_info == (PerlIO *) NULL)
12129 {
12130 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12131 PackageName);
12132 continue;
12133 }
12134 file=PerlIO_findFILE(io_info);
12135 if (file == (FILE *) NULL)
12136 {
12137 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12138 PackageName);
12139 continue;
12140 }
12141 SetImageInfoFile(package_info->image_info,file);
12142 }
12143 if ((items >= 3) && strEQcase(list[n],"magick"))
12144 continue;
12145 n++;
12146 }
12147 list[n]=(char *) NULL;
12148 keep=list;
12149 status=ExpandFilenames(&n,&list);
12150 if (status == MagickFalse)
12151 {
12152 ThrowPerlException(exception,ResourceLimitError,
12153 "MemoryAllocationFailed",PackageName);
12154 goto PerlException;
12155 }
12156 count=0;
12157 for (i=0; i < n; i++)
12158 {
12159 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012160 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012161 image=PingImage(package_info->image_info,exception);
12162 if (image == (Image *) NULL)
12163 break;
12164 if ((package_info->image_info->file != (FILE *) NULL) ||
12165 (package_info->image_info->blob != (void *) NULL))
12166 DisassociateImageStream(image);
12167 count+=GetImageListLength(image);
12168 EXTEND(sp,4*count);
12169 for (next=image; next; next=next->next)
12170 {
12171 PUSHs(sv_2mortal(newSViv(next->columns)));
12172 PUSHs(sv_2mortal(newSViv(next->rows)));
12173 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12174 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12175 }
12176 image=DestroyImageList(image);
12177 }
12178 /*
12179 Free resources.
12180 */
12181 for (i=0; i < n; i++)
12182 if (list[i] != (char *) NULL)
12183 for (p=keep; list[i] != *p++; )
12184 if (*p == NULL)
12185 {
12186 list[i]=(char *) RelinquishMagickMemory(list[i]);
12187 break;
12188 }
12189
12190 PerlException:
12191 if (package_info != (struct PackageInfo *) NULL)
12192 DestroyPackageInfo(package_info);
12193 if (list && (list != keep))
12194 list=(char **) RelinquishMagickMemory(list);
12195 if (keep)
12196 keep=(char **) RelinquishMagickMemory(keep);
12197 if (length)
12198 length=(STRLEN *) RelinquishMagickMemory(length);
12199 InheritPerlException(exception,perl_exception);
12200 exception=DestroyExceptionInfo(exception);
12201 SvREFCNT_dec(perl_exception); /* throw away all errors */
12202 }
12203
12204#
12205###############################################################################
12206# #
12207# #
12208# #
12209# P r e v i e w #
12210# #
12211# #
12212# #
12213###############################################################################
12214#
12215#
12216void
12217Preview(ref,...)
12218 Image::Magick ref=NO_INIT
12219 ALIAS:
12220 PreviewImage = 1
12221 preview = 2
12222 previewimage = 3
12223 PPCODE:
12224 {
12225 AV
12226 *av;
12227
12228 ExceptionInfo
12229 *exception;
12230
12231 HV
12232 *hv;
12233
12234 Image
12235 *image,
12236 *preview_image;
12237
12238 PreviewType
12239 preview_type;
12240
12241 struct PackageInfo
12242 *info;
12243
12244 SV
12245 *av_reference,
12246 *perl_exception,
12247 *reference,
12248 *rv,
12249 *sv;
12250
12251 PERL_UNUSED_VAR(ref);
12252 PERL_UNUSED_VAR(ix);
12253 exception=AcquireExceptionInfo();
12254 perl_exception=newSVpv("",0);
12255 sv=NULL;
12256 av=NULL;
12257 if (sv_isobject(ST(0)) == 0)
12258 {
12259 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12260 PackageName);
12261 goto PerlException;
12262 }
12263 reference=SvRV(ST(0));
12264 hv=SvSTASH(reference);
12265 av=newAV();
12266 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12267 SvREFCNT_dec(av);
12268 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12269 if (image == (Image *) NULL)
12270 {
12271 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12272 PackageName);
12273 goto PerlException;
12274 }
12275 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12276 preview_type=GammaPreview;
12277 if (items > 1)
12278 preview_type=(PreviewType)
12279 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12280 for ( ; image; image=image->next)
12281 {
12282 preview_image=PreviewImage(image,preview_type,exception);
12283 if (preview_image == (Image *) NULL)
12284 goto PerlException;
12285 AddImageToRegistry(sv,preview_image);
12286 rv=newRV(sv);
12287 av_push(av,sv_bless(rv,hv));
12288 SvREFCNT_dec(sv);
12289 }
12290 exception=DestroyExceptionInfo(exception);
12291 ST(0)=av_reference;
12292 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12293 XSRETURN(1);
12294
12295 PerlException:
12296 InheritPerlException(exception,perl_exception);
12297 exception=DestroyExceptionInfo(exception);
12298 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12299 SvPOK_on(perl_exception);
12300 ST(0)=sv_2mortal(perl_exception);
12301 XSRETURN(1);
12302 }
12303
12304#
12305###############################################################################
12306# #
12307# #
12308# #
12309# Q u e r y C o l o r #
12310# #
12311# #
12312# #
12313###############################################################################
12314#
12315#
12316void
12317QueryColor(ref,...)
12318 Image::Magick ref=NO_INIT
12319 ALIAS:
12320 querycolor = 1
12321 PPCODE:
12322 {
12323 char
12324 *name;
12325
12326 ExceptionInfo
12327 *exception;
12328
12329 PixelInfo
12330 color;
12331
12332 register ssize_t
12333 i;
12334
12335 SV
12336 *perl_exception;
12337
12338 PERL_UNUSED_VAR(ref);
12339 PERL_UNUSED_VAR(ix);
12340 exception=AcquireExceptionInfo();
12341 perl_exception=newSVpv("",0);
12342 if (items == 1)
12343 {
12344 const ColorInfo
12345 **colorlist;
12346
12347 size_t
12348 colors;
12349
12350 colorlist=GetColorInfoList("*",&colors,exception);
12351 EXTEND(sp,colors);
12352 for (i=0; i < (ssize_t) colors; i++)
12353 {
12354 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12355 }
12356 colorlist=(const ColorInfo **)
12357 RelinquishMagickMemory((ColorInfo **) colorlist);
12358 goto PerlException;
12359 }
12360 EXTEND(sp,5*items);
12361 for (i=1; i < items; i++)
12362 {
12363 name=(char *) SvPV(ST(i),na);
12364 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12365 {
12366 PUSHs(&sv_undef);
12367 continue;
12368 }
12369 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12370 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12371 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12372 if (color.colorspace == CMYKColorspace)
12373 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012374 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012375 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12376 }
12377
12378 PerlException:
12379 InheritPerlException(exception,perl_exception);
12380 exception=DestroyExceptionInfo(exception);
12381 SvREFCNT_dec(perl_exception);
12382 }
12383
12384#
12385###############################################################################
12386# #
12387# #
12388# #
12389# Q u e r y C o l o r N a m e #
12390# #
12391# #
12392# #
12393###############################################################################
12394#
12395#
12396void
12397QueryColorname(ref,...)
12398 Image::Magick ref=NO_INIT
12399 ALIAS:
12400 querycolorname = 1
12401 PPCODE:
12402 {
12403 AV
12404 *av;
12405
12406 char
cristy151b66d2015-04-15 10:50:31 +000012407 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012408
12409 ExceptionInfo
12410 *exception;
12411
12412 Image
12413 *image;
12414
12415 PixelInfo
12416 target_color;
12417
12418 register ssize_t
12419 i;
12420
12421 struct PackageInfo
12422 *info;
12423
12424 SV
12425 *perl_exception,
12426 *reference; /* reference is the SV* of ref=SvIV(reference) */
12427
12428 PERL_UNUSED_VAR(ref);
12429 PERL_UNUSED_VAR(ix);
12430 exception=AcquireExceptionInfo();
12431 perl_exception=newSVpv("",0);
12432 reference=SvRV(ST(0));
12433 av=(AV *) reference;
12434 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12435 exception);
12436 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12437 if (image == (Image *) NULL)
12438 {
12439 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12440 PackageName);
12441 goto PerlException;
12442 }
12443 EXTEND(sp,items);
12444 for (i=1; i < items; i++)
12445 {
12446 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12447 exception);
12448 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12449 exception);
12450 PUSHs(sv_2mortal(newSVpv(message,0)));
12451 }
12452
12453 PerlException:
12454 InheritPerlException(exception,perl_exception);
12455 exception=DestroyExceptionInfo(exception);
12456 SvREFCNT_dec(perl_exception);
12457 }
12458
12459#
12460###############################################################################
12461# #
12462# #
12463# #
12464# Q u e r y F o n t #
12465# #
12466# #
12467# #
12468###############################################################################
12469#
12470#
12471void
12472QueryFont(ref,...)
12473 Image::Magick ref=NO_INIT
12474 ALIAS:
12475 queryfont = 1
12476 PPCODE:
12477 {
12478 char
12479 *name,
cristy151b66d2015-04-15 10:50:31 +000012480 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012481
12482 ExceptionInfo
12483 *exception;
12484
12485 register ssize_t
12486 i;
12487
12488 SV
12489 *perl_exception;
12490
12491 volatile const TypeInfo
12492 *type_info;
12493
12494 PERL_UNUSED_VAR(ref);
12495 PERL_UNUSED_VAR(ix);
12496 exception=AcquireExceptionInfo();
12497 perl_exception=newSVpv("",0);
12498 if (items == 1)
12499 {
12500 const TypeInfo
12501 **typelist;
12502
12503 size_t
12504 types;
12505
12506 typelist=GetTypeInfoList("*",&types,exception);
12507 EXTEND(sp,types);
12508 for (i=0; i < (ssize_t) types; i++)
12509 {
12510 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12511 }
12512 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12513 typelist);
12514 goto PerlException;
12515 }
12516 EXTEND(sp,10*items);
12517 for (i=1; i < items; i++)
12518 {
12519 name=(char *) SvPV(ST(i),na);
12520 type_info=GetTypeInfo(name,exception);
12521 if (type_info == (TypeInfo *) NULL)
12522 {
12523 PUSHs(&sv_undef);
12524 continue;
12525 }
12526 if (type_info->name == (char *) NULL)
12527 PUSHs(&sv_undef);
12528 else
12529 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12530 if (type_info->description == (char *) NULL)
12531 PUSHs(&sv_undef);
12532 else
12533 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12534 if (type_info->family == (char *) NULL)
12535 PUSHs(&sv_undef);
12536 else
12537 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12538 if (type_info->style == UndefinedStyle)
12539 PUSHs(&sv_undef);
12540 else
12541 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12542 type_info->style),0)));
12543 if (type_info->stretch == UndefinedStretch)
12544 PUSHs(&sv_undef);
12545 else
12546 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12547 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012548 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012549 type_info->weight);
12550 PUSHs(sv_2mortal(newSVpv(message,0)));
12551 if (type_info->encoding == (char *) NULL)
12552 PUSHs(&sv_undef);
12553 else
12554 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12555 if (type_info->foundry == (char *) NULL)
12556 PUSHs(&sv_undef);
12557 else
12558 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12559 if (type_info->format == (char *) NULL)
12560 PUSHs(&sv_undef);
12561 else
12562 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12563 if (type_info->metrics == (char *) NULL)
12564 PUSHs(&sv_undef);
12565 else
12566 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12567 if (type_info->glyphs == (char *) NULL)
12568 PUSHs(&sv_undef);
12569 else
12570 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12571 }
12572
12573 PerlException:
12574 InheritPerlException(exception,perl_exception);
12575 exception=DestroyExceptionInfo(exception);
12576 SvREFCNT_dec(perl_exception);
12577 }
12578
12579#
12580###############################################################################
12581# #
12582# #
12583# #
12584# Q u e r y F o n t M e t r i c s #
12585# #
12586# #
12587# #
12588###############################################################################
12589#
12590#
12591void
12592QueryFontMetrics(ref,...)
12593 Image::Magick ref=NO_INIT
12594 ALIAS:
12595 queryfontmetrics = 1
12596 PPCODE:
12597 {
12598 AffineMatrix
12599 affine,
12600 current;
12601
12602 AV
12603 *av;
12604
12605 char
12606 *attribute;
12607
12608 double
12609 x,
12610 y;
12611
12612 DrawInfo
12613 *draw_info;
12614
12615 ExceptionInfo
12616 *exception;
12617
12618 GeometryInfo
12619 geometry_info;
12620
12621 Image
12622 *image;
12623
12624 MagickBooleanType
12625 status;
12626
12627 MagickStatusType
12628 flags;
12629
12630 register ssize_t
12631 i;
12632
12633 ssize_t
12634 type;
12635
12636 struct PackageInfo
12637 *info,
12638 *package_info;
12639
12640 SV
12641 *perl_exception,
12642 *reference; /* reference is the SV* of ref=SvIV(reference) */
12643
12644 TypeMetric
12645 metrics;
12646
12647 PERL_UNUSED_VAR(ref);
12648 PERL_UNUSED_VAR(ix);
12649 exception=AcquireExceptionInfo();
12650 package_info=(struct PackageInfo *) NULL;
12651 perl_exception=newSVpv("",0);
12652 reference=SvRV(ST(0));
12653 av=(AV *) reference;
12654 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12655 exception);
12656 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12657 if (image == (Image *) NULL)
12658 {
12659 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12660 PackageName);
12661 goto PerlException;
12662 }
12663 package_info=ClonePackageInfo(info,exception);
12664 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12665 CloneString(&draw_info->text,"");
12666 current=draw_info->affine;
12667 GetAffineMatrix(&affine);
12668 x=0.0;
12669 y=0.0;
12670 EXTEND(sp,7*items);
12671 for (i=2; i < items; i+=2)
12672 {
12673 attribute=(char *) SvPV(ST(i-1),na);
12674 switch (*attribute)
12675 {
12676 case 'A':
12677 case 'a':
12678 {
12679 if (LocaleCompare(attribute,"antialias") == 0)
12680 {
12681 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12682 SvPV(ST(i),na));
12683 if (type < 0)
12684 {
12685 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12686 SvPV(ST(i),na));
12687 break;
12688 }
12689 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12690 break;
12691 }
12692 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12693 attribute);
12694 break;
12695 }
12696 case 'd':
12697 case 'D':
12698 {
12699 if (LocaleCompare(attribute,"density") == 0)
12700 {
12701 CloneString(&draw_info->density,SvPV(ST(i),na));
12702 break;
12703 }
12704 if (LocaleCompare(attribute,"direction") == 0)
12705 {
12706 draw_info->direction=(DirectionType) ParseCommandOption(
12707 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12708 break;
12709 }
12710 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12711 attribute);
12712 break;
12713 }
12714 case 'e':
12715 case 'E':
12716 {
12717 if (LocaleCompare(attribute,"encoding") == 0)
12718 {
12719 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12720 break;
12721 }
12722 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12723 attribute);
12724 break;
12725 }
12726 case 'f':
12727 case 'F':
12728 {
12729 if (LocaleCompare(attribute,"family") == 0)
12730 {
12731 CloneString(&draw_info->family,SvPV(ST(i),na));
12732 break;
12733 }
12734 if (LocaleCompare(attribute,"fill") == 0)
12735 {
12736 if (info)
12737 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12738 &draw_info->fill,exception);
12739 break;
12740 }
12741 if (LocaleCompare(attribute,"font") == 0)
12742 {
12743 CloneString(&draw_info->font,SvPV(ST(i),na));
12744 break;
12745 }
12746 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12747 attribute);
12748 break;
12749 }
12750 case 'g':
12751 case 'G':
12752 {
12753 if (LocaleCompare(attribute,"geometry") == 0)
12754 {
12755 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12756 break;
12757 }
12758 if (LocaleCompare(attribute,"gravity") == 0)
12759 {
12760 draw_info->gravity=(GravityType) ParseCommandOption(
12761 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12762 break;
12763 }
12764 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12765 attribute);
12766 break;
12767 }
12768 case 'i':
12769 case 'I':
12770 {
12771 if (LocaleCompare(attribute,"interline-spacing") == 0)
12772 {
12773 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12774 draw_info->interline_spacing=geometry_info.rho;
12775 break;
12776 }
12777 if (LocaleCompare(attribute,"interword-spacing") == 0)
12778 {
12779 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12780 draw_info->interword_spacing=geometry_info.rho;
12781 break;
12782 }
12783 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12784 attribute);
12785 break;
12786 }
12787 case 'k':
12788 case 'K':
12789 {
12790 if (LocaleCompare(attribute,"kerning") == 0)
12791 {
12792 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12793 draw_info->kerning=geometry_info.rho;
12794 break;
12795 }
12796 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12797 attribute);
12798 break;
12799 }
12800 case 'p':
12801 case 'P':
12802 {
12803 if (LocaleCompare(attribute,"pointsize") == 0)
12804 {
12805 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12806 draw_info->pointsize=geometry_info.rho;
12807 break;
12808 }
12809 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12810 attribute);
12811 break;
12812 }
12813 case 'r':
12814 case 'R':
12815 {
12816 if (LocaleCompare(attribute,"rotate") == 0)
12817 {
12818 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12819 affine.rx=geometry_info.rho;
12820 affine.ry=geometry_info.sigma;
12821 if ((flags & SigmaValue) == 0)
12822 affine.ry=affine.rx;
12823 break;
12824 }
12825 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12826 attribute);
12827 break;
12828 }
12829 case 's':
12830 case 'S':
12831 {
12832 if (LocaleCompare(attribute,"scale") == 0)
12833 {
12834 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12835 affine.sx=geometry_info.rho;
12836 affine.sy=geometry_info.sigma;
12837 if ((flags & SigmaValue) == 0)
12838 affine.sy=affine.sx;
12839 break;
12840 }
12841 if (LocaleCompare(attribute,"skew") == 0)
12842 {
12843 double
12844 x_angle,
12845 y_angle;
12846
12847 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12848 x_angle=geometry_info.rho;
12849 y_angle=geometry_info.sigma;
12850 if ((flags & SigmaValue) == 0)
12851 y_angle=x_angle;
12852 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12853 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12854 break;
12855 }
12856 if (LocaleCompare(attribute,"stroke") == 0)
12857 {
12858 if (info)
12859 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12860 &draw_info->stroke,exception);
12861 break;
12862 }
12863 if (LocaleCompare(attribute,"style") == 0)
12864 {
12865 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12866 SvPV(ST(i),na));
12867 if (type < 0)
12868 {
12869 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12870 SvPV(ST(i),na));
12871 break;
12872 }
12873 draw_info->style=(StyleType) type;
12874 break;
12875 }
12876 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12877 attribute);
12878 break;
12879 }
12880 case 't':
12881 case 'T':
12882 {
12883 if (LocaleCompare(attribute,"text") == 0)
12884 {
12885 CloneString(&draw_info->text,SvPV(ST(i),na));
12886 break;
12887 }
12888 if (LocaleCompare(attribute,"translate") == 0)
12889 {
12890 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12891 affine.tx=geometry_info.rho;
12892 affine.ty=geometry_info.sigma;
12893 if ((flags & SigmaValue) == 0)
12894 affine.ty=affine.tx;
12895 break;
12896 }
12897 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12898 attribute);
12899 break;
12900 }
12901 case 'w':
12902 case 'W':
12903 {
12904 if (LocaleCompare(attribute,"weight") == 0)
12905 {
12906 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12907 draw_info->weight=(size_t) geometry_info.rho;
12908 break;
12909 }
12910 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12911 attribute);
12912 break;
12913 }
12914 case 'x':
12915 case 'X':
12916 {
12917 if (LocaleCompare(attribute,"x") == 0)
12918 {
12919 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12920 x=geometry_info.rho;
12921 break;
12922 }
12923 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12924 attribute);
12925 break;
12926 }
12927 case 'y':
12928 case 'Y':
12929 {
12930 if (LocaleCompare(attribute,"y") == 0)
12931 {
12932 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12933 y=geometry_info.rho;
12934 break;
12935 }
12936 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12937 attribute);
12938 break;
12939 }
12940 default:
12941 {
12942 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12943 attribute);
12944 break;
12945 }
12946 }
12947 }
12948 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12949 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12950 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12951 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12952 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12953 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12954 if (draw_info->geometry == (char *) NULL)
12955 {
12956 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000012957 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000012958 "%.15g,%.15g",x,y);
12959 }
12960 status=GetTypeMetrics(image,draw_info,&metrics,exception);
12961 (void) CatchImageException(image);
12962 if (status == MagickFalse)
12963 PUSHs(&sv_undef);
12964 else
12965 {
12966 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12967 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12968 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12969 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12970 PUSHs(sv_2mortal(newSVnv(metrics.width)));
12971 PUSHs(sv_2mortal(newSVnv(metrics.height)));
12972 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12973 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
12974 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
12975 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
12976 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
12977 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
12978 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
12979 }
12980 draw_info=DestroyDrawInfo(draw_info);
12981
12982 PerlException:
12983 if (package_info != (struct PackageInfo *) NULL)
12984 DestroyPackageInfo(package_info);
12985 InheritPerlException(exception,perl_exception);
12986 exception=DestroyExceptionInfo(exception);
12987 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12988 }
12989
12990#
12991###############################################################################
12992# #
12993# #
12994# #
12995# 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 #
12996# #
12997# #
12998# #
12999###############################################################################
13000#
13001#
13002void
13003QueryMultilineFontMetrics(ref,...)
13004 Image::Magick ref=NO_INIT
13005 ALIAS:
13006 querymultilinefontmetrics = 1
13007 PPCODE:
13008 {
13009 AffineMatrix
13010 affine,
13011 current;
13012
13013 AV
13014 *av;
13015
13016 char
13017 *attribute;
13018
13019 double
13020 x,
13021 y;
13022
13023 DrawInfo
13024 *draw_info;
13025
13026 ExceptionInfo
13027 *exception;
13028
13029 GeometryInfo
13030 geometry_info;
13031
13032 Image
13033 *image;
13034
13035 MagickBooleanType
13036 status;
13037
13038 MagickStatusType
13039 flags;
13040
13041 register ssize_t
13042 i;
13043
13044 ssize_t
13045 type;
13046
13047 struct PackageInfo
13048 *info,
13049 *package_info;
13050
13051 SV
13052 *perl_exception,
13053 *reference; /* reference is the SV* of ref=SvIV(reference) */
13054
13055 TypeMetric
13056 metrics;
13057
13058 PERL_UNUSED_VAR(ref);
13059 PERL_UNUSED_VAR(ix);
13060 exception=AcquireExceptionInfo();
13061 package_info=(struct PackageInfo *) NULL;
13062 perl_exception=newSVpv("",0);
13063 reference=SvRV(ST(0));
13064 av=(AV *) reference;
13065 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13066 exception);
13067 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13068 if (image == (Image *) NULL)
13069 {
13070 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13071 PackageName);
13072 goto PerlException;
13073 }
13074 package_info=ClonePackageInfo(info,exception);
13075 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13076 CloneString(&draw_info->text,"");
13077 current=draw_info->affine;
13078 GetAffineMatrix(&affine);
13079 x=0.0;
13080 y=0.0;
13081 EXTEND(sp,7*items);
13082 for (i=2; i < items; i+=2)
13083 {
13084 attribute=(char *) SvPV(ST(i-1),na);
13085 switch (*attribute)
13086 {
13087 case 'A':
13088 case 'a':
13089 {
13090 if (LocaleCompare(attribute,"antialias") == 0)
13091 {
13092 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13093 SvPV(ST(i),na));
13094 if (type < 0)
13095 {
13096 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13097 SvPV(ST(i),na));
13098 break;
13099 }
13100 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13101 break;
13102 }
13103 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13104 attribute);
13105 break;
13106 }
13107 case 'd':
13108 case 'D':
13109 {
13110 if (LocaleCompare(attribute,"density") == 0)
13111 {
13112 CloneString(&draw_info->density,SvPV(ST(i),na));
13113 break;
13114 }
13115 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13116 attribute);
13117 break;
13118 }
13119 case 'e':
13120 case 'E':
13121 {
13122 if (LocaleCompare(attribute,"encoding") == 0)
13123 {
13124 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13125 break;
13126 }
13127 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13128 attribute);
13129 break;
13130 }
13131 case 'f':
13132 case 'F':
13133 {
13134 if (LocaleCompare(attribute,"family") == 0)
13135 {
13136 CloneString(&draw_info->family,SvPV(ST(i),na));
13137 break;
13138 }
13139 if (LocaleCompare(attribute,"fill") == 0)
13140 {
13141 if (info)
13142 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13143 &draw_info->fill,exception);
13144 break;
13145 }
13146 if (LocaleCompare(attribute,"font") == 0)
13147 {
13148 CloneString(&draw_info->font,SvPV(ST(i),na));
13149 break;
13150 }
13151 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13152 attribute);
13153 break;
13154 }
13155 case 'g':
13156 case 'G':
13157 {
13158 if (LocaleCompare(attribute,"geometry") == 0)
13159 {
13160 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13161 break;
13162 }
13163 if (LocaleCompare(attribute,"gravity") == 0)
13164 {
13165 draw_info->gravity=(GravityType) ParseCommandOption(
13166 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13167 break;
13168 }
13169 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13170 attribute);
13171 break;
13172 }
13173 case 'p':
13174 case 'P':
13175 {
13176 if (LocaleCompare(attribute,"pointsize") == 0)
13177 {
13178 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13179 draw_info->pointsize=geometry_info.rho;
13180 break;
13181 }
13182 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13183 attribute);
13184 break;
13185 }
13186 case 'r':
13187 case 'R':
13188 {
13189 if (LocaleCompare(attribute,"rotate") == 0)
13190 {
13191 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13192 affine.rx=geometry_info.rho;
13193 affine.ry=geometry_info.sigma;
13194 if ((flags & SigmaValue) == 0)
13195 affine.ry=affine.rx;
13196 break;
13197 }
13198 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13199 attribute);
13200 break;
13201 }
13202 case 's':
13203 case 'S':
13204 {
13205 if (LocaleCompare(attribute,"scale") == 0)
13206 {
13207 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13208 affine.sx=geometry_info.rho;
13209 affine.sy=geometry_info.sigma;
13210 if ((flags & SigmaValue) == 0)
13211 affine.sy=affine.sx;
13212 break;
13213 }
13214 if (LocaleCompare(attribute,"skew") == 0)
13215 {
13216 double
13217 x_angle,
13218 y_angle;
13219
13220 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13221 x_angle=geometry_info.rho;
13222 y_angle=geometry_info.sigma;
13223 if ((flags & SigmaValue) == 0)
13224 y_angle=x_angle;
13225 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13226 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13227 break;
13228 }
13229 if (LocaleCompare(attribute,"stroke") == 0)
13230 {
13231 if (info)
13232 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13233 &draw_info->stroke,exception);
13234 break;
13235 }
13236 if (LocaleCompare(attribute,"style") == 0)
13237 {
13238 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13239 SvPV(ST(i),na));
13240 if (type < 0)
13241 {
13242 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13243 SvPV(ST(i),na));
13244 break;
13245 }
13246 draw_info->style=(StyleType) type;
13247 break;
13248 }
13249 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13250 attribute);
13251 break;
13252 }
13253 case 't':
13254 case 'T':
13255 {
13256 if (LocaleCompare(attribute,"text") == 0)
13257 {
13258 CloneString(&draw_info->text,SvPV(ST(i),na));
13259 break;
13260 }
13261 if (LocaleCompare(attribute,"translate") == 0)
13262 {
13263 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13264 affine.tx=geometry_info.rho;
13265 affine.ty=geometry_info.sigma;
13266 if ((flags & SigmaValue) == 0)
13267 affine.ty=affine.tx;
13268 break;
13269 }
13270 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13271 attribute);
13272 break;
13273 }
13274 case 'w':
13275 case 'W':
13276 {
13277 if (LocaleCompare(attribute,"weight") == 0)
13278 {
13279 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13280 draw_info->weight=(size_t) geometry_info.rho;
13281 break;
13282 }
13283 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13284 attribute);
13285 break;
13286 }
13287 case 'x':
13288 case 'X':
13289 {
13290 if (LocaleCompare(attribute,"x") == 0)
13291 {
13292 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13293 x=geometry_info.rho;
13294 break;
13295 }
13296 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13297 attribute);
13298 break;
13299 }
13300 case 'y':
13301 case 'Y':
13302 {
13303 if (LocaleCompare(attribute,"y") == 0)
13304 {
13305 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13306 y=geometry_info.rho;
13307 break;
13308 }
13309 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13310 attribute);
13311 break;
13312 }
13313 default:
13314 {
13315 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13316 attribute);
13317 break;
13318 }
13319 }
13320 }
13321 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13322 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13323 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13324 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13325 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13326 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13327 if (draw_info->geometry == (char *) NULL)
13328 {
13329 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013330 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013331 "%.15g,%.15g",x,y);
13332 }
13333 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13334 (void) CatchException(exception);
13335 if (status == MagickFalse)
13336 PUSHs(&sv_undef);
13337 else
13338 {
13339 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13340 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13341 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13342 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13343 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13344 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13345 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13346 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13347 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13348 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13349 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13350 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13351 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13352 }
13353 draw_info=DestroyDrawInfo(draw_info);
13354
13355 PerlException:
13356 if (package_info != (struct PackageInfo *) NULL)
13357 DestroyPackageInfo(package_info);
13358 InheritPerlException(exception,perl_exception);
13359 exception=DestroyExceptionInfo(exception);
13360 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13361 }
13362
13363#
13364###############################################################################
13365# #
13366# #
13367# #
13368# Q u e r y F o r m a t #
13369# #
13370# #
13371# #
13372###############################################################################
13373#
13374#
13375void
13376QueryFormat(ref,...)
13377 Image::Magick ref=NO_INIT
13378 ALIAS:
13379 queryformat = 1
13380 PPCODE:
13381 {
13382 char
13383 *name;
13384
13385 ExceptionInfo
13386 *exception;
13387
13388 register ssize_t
13389 i;
13390
13391 SV
13392 *perl_exception;
13393
13394 volatile const MagickInfo
13395 *magick_info;
13396
13397 PERL_UNUSED_VAR(ref);
13398 PERL_UNUSED_VAR(ix);
13399 exception=AcquireExceptionInfo();
13400 perl_exception=newSVpv("",0);
13401 if (items == 1)
13402 {
13403 char
cristy151b66d2015-04-15 10:50:31 +000013404 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013405
13406 const MagickInfo
13407 **format_list;
13408
13409 size_t
13410 types;
13411
13412 format_list=GetMagickInfoList("*",&types,exception);
13413 EXTEND(sp,types);
13414 for (i=0; i < (ssize_t) types; i++)
13415 {
cristy151b66d2015-04-15 10:50:31 +000013416 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013417 LocaleLower(format);
13418 PUSHs(sv_2mortal(newSVpv(format,0)));
13419 }
13420 format_list=(const MagickInfo **)
13421 RelinquishMagickMemory((MagickInfo *) format_list);
13422 goto PerlException;
13423 }
13424 EXTEND(sp,8*items);
13425 for (i=1; i < items; i++)
13426 {
13427 name=(char *) SvPV(ST(i),na);
13428 magick_info=GetMagickInfo(name,exception);
13429 if (magick_info == (const MagickInfo *) NULL)
13430 {
13431 PUSHs(&sv_undef);
13432 continue;
13433 }
cristy4a3ce0a2013-08-03 20:06:59 +000013434 if (magick_info->description == (char *) NULL)
13435 PUSHs(&sv_undef);
13436 else
13437 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13438 if (magick_info->module == (char *) NULL)
13439 PUSHs(&sv_undef);
13440 else
13441 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13442 }
13443
13444 PerlException:
13445 InheritPerlException(exception,perl_exception);
13446 exception=DestroyExceptionInfo(exception);
13447 SvREFCNT_dec(perl_exception);
13448 }
13449
13450#
13451###############################################################################
13452# #
13453# #
13454# #
13455# Q u e r y O p t i o n #
13456# #
13457# #
13458# #
13459###############################################################################
13460#
13461#
13462void
13463QueryOption(ref,...)
13464 Image::Magick ref=NO_INIT
13465 ALIAS:
13466 queryoption = 1
13467 PPCODE:
13468 {
13469 char
13470 **options;
13471
13472 ExceptionInfo
13473 *exception;
13474
13475 register ssize_t
13476 i;
13477
13478 ssize_t
13479 j,
13480 option;
13481
13482 SV
13483 *perl_exception;
13484
13485 PERL_UNUSED_VAR(ref);
13486 PERL_UNUSED_VAR(ix);
13487 exception=AcquireExceptionInfo();
13488 perl_exception=newSVpv("",0);
13489 EXTEND(sp,8*items);
13490 for (i=1; i < items; i++)
13491 {
13492 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13493 SvPV(ST(i),na));
13494 options=GetCommandOptions((CommandOption) option);
13495 if (options == (char **) NULL)
13496 PUSHs(&sv_undef);
13497 else
13498 {
13499 for (j=0; options[j] != (char *) NULL; j++)
13500 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13501 options=DestroyStringList(options);
13502 }
13503 }
13504
13505 InheritPerlException(exception,perl_exception);
13506 exception=DestroyExceptionInfo(exception);
13507 SvREFCNT_dec(perl_exception);
13508 }
13509
13510#
13511###############################################################################
13512# #
13513# #
13514# #
13515# R e a d #
13516# #
13517# #
13518# #
13519###############################################################################
13520#
13521#
13522void
13523Read(ref,...)
13524 Image::Magick ref=NO_INIT
13525 ALIAS:
13526 ReadImage = 1
13527 read = 2
13528 readimage = 3
13529 PPCODE:
13530 {
13531 AV
13532 *av;
13533
13534 char
13535 **keep,
13536 **list;
13537
13538 ExceptionInfo
13539 *exception;
13540
13541 HV
13542 *hv;
13543
13544 Image
13545 *image;
13546
13547 int
13548 n;
13549
13550 MagickBooleanType
13551 status;
13552
13553 register char
13554 **p;
13555
13556 register ssize_t
13557 i;
13558
13559 ssize_t
13560 ac,
13561 number_images;
13562
13563 STRLEN
13564 *length;
13565
13566 struct PackageInfo
13567 *info,
13568 *package_info;
13569
13570 SV
13571 *perl_exception, /* Perl variable for storing messages */
13572 *reference,
13573 *rv,
13574 *sv;
13575
13576 PERL_UNUSED_VAR(ref);
13577 PERL_UNUSED_VAR(ix);
13578 exception=AcquireExceptionInfo();
13579 perl_exception=newSVpv("",0);
13580 sv=NULL;
13581 package_info=(struct PackageInfo *) NULL;
13582 number_images=0;
13583 ac=(items < 2) ? 1 : items-1;
13584 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13585 keep=list;
13586 length=(STRLEN *) NULL;
13587 if (list == (char **) NULL)
13588 {
13589 ThrowPerlException(exception,ResourceLimitError,
13590 "MemoryAllocationFailed",PackageName);
13591 goto PerlException;
13592 }
13593 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13594 if (length == (STRLEN *) NULL)
13595 {
13596 ThrowPerlException(exception,ResourceLimitError,
13597 "MemoryAllocationFailed",PackageName);
13598 goto PerlException;
13599 }
13600 if (sv_isobject(ST(0)) == 0)
13601 {
13602 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13603 PackageName);
13604 goto PerlException;
13605 }
13606 reference=SvRV(ST(0));
13607 hv=SvSTASH(reference);
13608 if (SvTYPE(reference) != SVt_PVAV)
13609 {
13610 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13611 PackageName);
13612 goto PerlException;
13613 }
13614 av=(AV *) reference;
13615 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13616 exception);
13617 package_info=ClonePackageInfo(info,exception);
13618 n=1;
13619 if (items <= 1)
13620 *list=(char *) (*package_info->image_info->filename ?
13621 package_info->image_info->filename : "XC:black");
13622 else
13623 for (n=0, i=0; i < ac; i++)
13624 {
13625 list[n]=(char *) SvPV(ST(i+1),length[n]);
13626 if ((items >= 3) && strEQcase(list[n],"blob"))
13627 {
13628 void
13629 *blob;
13630
13631 i++;
13632 blob=(void *) (SvPV(ST(i+1),length[n]));
13633 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13634 }
13635 if ((items >= 3) && strEQcase(list[n],"filename"))
13636 continue;
13637 if ((items >= 3) && strEQcase(list[n],"file"))
13638 {
13639 FILE
13640 *file;
13641
13642 PerlIO
13643 *io_info;
13644
13645 i++;
13646 io_info=IoIFP(sv_2io(ST(i+1)));
13647 if (io_info == (PerlIO *) NULL)
13648 {
13649 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13650 PackageName);
13651 continue;
13652 }
13653 file=PerlIO_findFILE(io_info);
13654 if (file == (FILE *) NULL)
13655 {
13656 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13657 PackageName);
13658 continue;
13659 }
13660 SetImageInfoFile(package_info->image_info,file);
13661 }
13662 if ((items >= 3) && strEQcase(list[n],"magick"))
13663 continue;
13664 n++;
13665 }
13666 list[n]=(char *) NULL;
13667 keep=list;
13668 status=ExpandFilenames(&n,&list);
13669 if (status == MagickFalse)
13670 {
13671 ThrowPerlException(exception,ResourceLimitError,
13672 "MemoryAllocationFailed",PackageName);
13673 goto PerlException;
13674 }
13675 number_images=0;
13676 for (i=0; i < n; i++)
13677 {
13678 if ((package_info->image_info->file == (FILE *) NULL) &&
13679 (package_info->image_info->blob == (void *) NULL))
13680 image=ReadImages(package_info->image_info,list[i],exception);
13681 else
13682 {
13683 image=ReadImages(package_info->image_info,
13684 package_info->image_info->filename,exception);
13685 if (image != (Image *) NULL)
13686 DisassociateImageStream(image);
13687 }
13688 if (image == (Image *) NULL)
13689 break;
13690 for ( ; image; image=image->next)
13691 {
13692 AddImageToRegistry(sv,image);
13693 rv=newRV(sv);
13694 av_push(av,sv_bless(rv,hv));
13695 SvREFCNT_dec(sv);
13696 number_images++;
13697 }
13698 }
13699 /*
13700 Free resources.
13701 */
13702 for (i=0; i < n; i++)
13703 if (list[i] != (char *) NULL)
13704 for (p=keep; list[i] != *p++; )
13705 if (*p == (char *) NULL)
13706 {
13707 list[i]=(char *) RelinquishMagickMemory(list[i]);
13708 break;
13709 }
13710
13711 PerlException:
13712 if (package_info != (struct PackageInfo *) NULL)
13713 DestroyPackageInfo(package_info);
13714 if (list && (list != keep))
13715 list=(char **) RelinquishMagickMemory(list);
13716 if (keep)
13717 keep=(char **) RelinquishMagickMemory(keep);
13718 if (length)
13719 length=(STRLEN *) RelinquishMagickMemory(length);
13720 InheritPerlException(exception,perl_exception);
13721 exception=DestroyExceptionInfo(exception);
13722 sv_setiv(perl_exception,(IV) number_images);
13723 SvPOK_on(perl_exception);
13724 ST(0)=sv_2mortal(perl_exception);
13725 XSRETURN(1);
13726 }
13727
13728#
13729###############################################################################
13730# #
13731# #
13732# #
13733# R e m o t e #
13734# #
13735# #
13736# #
13737###############################################################################
13738#
13739#
13740void
13741Remote(ref,...)
13742 Image::Magick ref=NO_INIT
13743 ALIAS:
13744 RemoteCommand = 1
13745 remote = 2
13746 remoteCommand = 3
13747 PPCODE:
13748 {
13749 AV
13750 *av;
13751
13752 ExceptionInfo
13753 *exception;
13754
13755 register ssize_t
13756 i;
13757
13758 SV
13759 *perl_exception,
13760 *reference;
13761
13762 struct PackageInfo
13763 *info;
13764
13765 PERL_UNUSED_VAR(ref);
13766 PERL_UNUSED_VAR(ix);
13767 exception=AcquireExceptionInfo();
13768 perl_exception=newSVpv("",0);
13769 reference=SvRV(ST(0));
13770 av=(AV *) reference;
13771 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13772 exception);
13773 for (i=1; i < items; i++)
13774 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13775 SvPV(ST(i),na),exception);
13776 InheritPerlException(exception,perl_exception);
13777 exception=DestroyExceptionInfo(exception);
13778 SvREFCNT_dec(perl_exception); /* throw away all errors */
13779 }
13780
13781#
13782###############################################################################
13783# #
13784# #
13785# #
13786# S e t #
13787# #
13788# #
13789# #
13790###############################################################################
13791#
13792#
13793void
13794Set(ref,...)
13795 Image::Magick ref=NO_INIT
13796 ALIAS:
13797 SetAttributes = 1
13798 SetAttribute = 2
13799 set = 3
13800 setattributes = 4
13801 setattribute = 5
13802 PPCODE:
13803 {
13804 ExceptionInfo
13805 *exception;
13806
13807 Image
13808 *image;
13809
13810 register ssize_t
13811 i;
13812
13813 struct PackageInfo
13814 *info;
13815
13816 SV
13817 *perl_exception,
13818 *reference; /* reference is the SV* of ref=SvIV(reference) */
13819
13820 PERL_UNUSED_VAR(ref);
13821 PERL_UNUSED_VAR(ix);
13822 exception=AcquireExceptionInfo();
13823 perl_exception=newSVpv("",0);
13824 if (sv_isobject(ST(0)) == 0)
13825 {
13826 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13827 PackageName);
13828 goto PerlException;
13829 }
13830 reference=SvRV(ST(0));
13831 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13832 if (items == 2)
13833 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13834 else
13835 for (i=2; i < items; i+=2)
13836 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13837
13838 PerlException:
13839 InheritPerlException(exception,perl_exception);
13840 exception=DestroyExceptionInfo(exception);
13841 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13842 SvPOK_on(perl_exception);
13843 ST(0)=sv_2mortal(perl_exception);
13844 XSRETURN(1);
13845 }
13846
13847#
13848###############################################################################
13849# #
13850# #
13851# #
13852# S e t P i x e l #
13853# #
13854# #
13855# #
13856###############################################################################
13857#
13858#
13859void
13860SetPixel(ref,...)
13861 Image::Magick ref=NO_INIT
13862 ALIAS:
13863 setpixel = 1
13864 setPixel = 2
13865 PPCODE:
13866 {
13867 AV
13868 *av;
13869
13870 char
13871 *attribute;
13872
13873 ChannelType
13874 channel,
13875 channel_mask;
13876
13877 ExceptionInfo
13878 *exception;
13879
13880 Image
13881 *image;
13882
13883 MagickBooleanType
13884 normalize;
13885
13886 RectangleInfo
13887 region;
13888
13889 register ssize_t
13890 i;
13891
13892 register Quantum
13893 *q;
13894
13895 ssize_t
13896 option;
13897
13898 struct PackageInfo
13899 *info;
13900
13901 SV
13902 *perl_exception,
13903 *reference; /* reference is the SV* of ref=SvIV(reference) */
13904
13905 PERL_UNUSED_VAR(ref);
13906 PERL_UNUSED_VAR(ix);
13907 exception=AcquireExceptionInfo();
13908 perl_exception=newSVpv("",0);
13909 reference=SvRV(ST(0));
13910 av=(AV *) reference;
13911 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13912 exception);
13913 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13914 if (image == (Image *) NULL)
13915 {
13916 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13917 PackageName);
13918 goto PerlException;
13919 }
13920 av=(AV *) NULL;
13921 normalize=MagickTrue;
13922 region.x=0;
13923 region.y=0;
13924 region.width=image->columns;
13925 region.height=1;
13926 if (items == 1)
13927 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
13928 channel=DefaultChannels;
13929 for (i=2; i < items; i+=2)
13930 {
13931 attribute=(char *) SvPV(ST(i-1),na);
13932 switch (*attribute)
13933 {
13934 case 'C':
13935 case 'c':
13936 {
13937 if (LocaleCompare(attribute,"channel") == 0)
13938 {
13939 ssize_t
13940 option;
13941
13942 option=ParseChannelOption(SvPV(ST(i),na));
13943 if (option < 0)
13944 {
13945 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13946 SvPV(ST(i),na));
13947 return;
13948 }
13949 channel=(ChannelType) option;
13950 break;
13951 }
13952 if (LocaleCompare(attribute,"color") == 0)
13953 {
13954 if (SvTYPE(ST(i)) != SVt_RV)
13955 {
13956 char
cristy151b66d2015-04-15 10:50:31 +000013957 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013958
cristy151b66d2015-04-15 10:50:31 +000013959 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013960 "invalid %.60s value",attribute);
13961 ThrowPerlException(exception,OptionError,message,
13962 SvPV(ST(i),na));
13963 }
13964 av=(AV *) SvRV(ST(i));
13965 break;
13966 }
13967 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13968 attribute);
13969 break;
13970 }
13971 case 'g':
13972 case 'G':
13973 {
13974 if (LocaleCompare(attribute,"geometry") == 0)
13975 {
13976 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
13977 break;
13978 }
13979 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13980 attribute);
13981 break;
13982 }
13983 case 'N':
13984 case 'n':
13985 {
13986 if (LocaleCompare(attribute,"normalize") == 0)
13987 {
13988 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13989 SvPV(ST(i),na));
13990 if (option < 0)
13991 {
13992 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13993 SvPV(ST(i),na));
13994 break;
13995 }
13996 normalize=option != 0 ? MagickTrue : MagickFalse;
13997 break;
13998 }
13999 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14000 attribute);
14001 break;
14002 }
14003 case 'x':
14004 case 'X':
14005 {
14006 if (LocaleCompare(attribute,"x") == 0)
14007 {
14008 region.x=SvIV(ST(i));
14009 break;
14010 }
14011 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14012 attribute);
14013 break;
14014 }
14015 case 'y':
14016 case 'Y':
14017 {
14018 if (LocaleCompare(attribute,"y") == 0)
14019 {
14020 region.y=SvIV(ST(i));
14021 break;
14022 }
14023 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14024 attribute);
14025 break;
14026 }
14027 default:
14028 {
14029 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14030 attribute);
14031 break;
14032 }
14033 }
14034 }
14035 (void) SetImageStorageClass(image,DirectClass,exception);
14036 channel_mask=SetImageChannelMask(image,channel);
14037 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14038 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14039 (SvTYPE(av) != SVt_PVAV))
14040 PUSHs(&sv_undef);
14041 else
14042 {
14043 double
14044 scale;
14045
14046 register ssize_t
14047 i;
14048
14049 i=0;
14050 scale=1.0;
14051 if (normalize != MagickFalse)
14052 scale=QuantumRange;
14053 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14054 (i <= av_len(av)))
14055 {
14056 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14057 av_fetch(av,i,0)))),q);
14058 i++;
14059 }
14060 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14061 (i <= av_len(av)))
14062 {
14063 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14064 av_fetch(av,i,0)))),q);
14065 i++;
14066 }
14067 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14068 (i <= av_len(av)))
14069 {
14070 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14071 av_fetch(av,i,0)))),q);
14072 i++;
14073 }
14074 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14075 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14076 {
14077 SetPixelBlack(image,ClampToQuantum(scale*
14078 SvNV(*(av_fetch(av,i,0)))),q);
14079 i++;
14080 }
14081 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14082 (i <= av_len(av)))
14083 {
14084 SetPixelAlpha(image,ClampToQuantum(scale*
14085 SvNV(*(av_fetch(av,i,0)))),q);
14086 i++;
14087 }
14088 (void) SyncAuthenticPixels(image,exception);
14089 }
14090 (void) SetImageChannelMask(image,channel_mask);
14091
14092 PerlException:
14093 InheritPerlException(exception,perl_exception);
14094 exception=DestroyExceptionInfo(exception);
14095 SvREFCNT_dec(perl_exception);
14096 }
14097
14098#
14099###############################################################################
14100# #
14101# #
14102# #
14103# S m u s h #
14104# #
14105# #
14106# #
14107###############################################################################
14108#
14109#
14110void
14111Smush(ref,...)
14112 Image::Magick ref=NO_INIT
14113 ALIAS:
14114 SmushImage = 1
14115 smush = 2
14116 smushimage = 3
14117 PPCODE:
14118 {
14119 AV
14120 *av;
14121
14122 char
14123 *attribute;
14124
14125 ExceptionInfo
14126 *exception;
14127
14128 HV
14129 *hv;
14130
14131 Image
14132 *image;
14133
14134 register ssize_t
14135 i;
14136
14137 ssize_t
14138 offset,
14139 stack;
14140
14141 struct PackageInfo
14142 *info;
14143
14144 SV
14145 *av_reference,
14146 *perl_exception,
14147 *reference,
14148 *rv,
14149 *sv;
14150
14151 PERL_UNUSED_VAR(ref);
14152 PERL_UNUSED_VAR(ix);
14153 exception=AcquireExceptionInfo();
14154 perl_exception=newSVpv("",0);
14155 sv=NULL;
14156 attribute=NULL;
14157 av=NULL;
14158 if (sv_isobject(ST(0)) == 0)
14159 {
14160 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14161 PackageName);
14162 goto PerlException;
14163 }
14164 reference=SvRV(ST(0));
14165 hv=SvSTASH(reference);
14166 av=newAV();
14167 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14168 SvREFCNT_dec(av);
14169 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14170 if (image == (Image *) NULL)
14171 {
14172 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14173 PackageName);
14174 goto PerlException;
14175 }
14176 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14177 /*
14178 Get options.
14179 */
14180 offset=0;
14181 stack=MagickTrue;
14182 for (i=2; i < items; i+=2)
14183 {
14184 attribute=(char *) SvPV(ST(i-1),na);
14185 switch (*attribute)
14186 {
14187 case 'O':
14188 case 'o':
14189 {
14190 if (LocaleCompare(attribute,"offset") == 0)
14191 {
14192 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14193 break;
14194 }
14195 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14196 attribute);
14197 break;
14198 }
14199 case 'S':
14200 case 's':
14201 {
14202 if (LocaleCompare(attribute,"stack") == 0)
14203 {
14204 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14205 SvPV(ST(i),na));
14206 if (stack < 0)
14207 {
14208 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14209 SvPV(ST(i),na));
14210 return;
14211 }
14212 break;
14213 }
14214 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14215 attribute);
14216 break;
14217 }
14218 default:
14219 {
14220 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14221 attribute);
14222 break;
14223 }
14224 }
14225 }
14226 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14227 exception);
14228 if (image == (Image *) NULL)
14229 goto PerlException;
14230 for ( ; image; image=image->next)
14231 {
14232 AddImageToRegistry(sv,image);
14233 rv=newRV(sv);
14234 av_push(av,sv_bless(rv,hv));
14235 SvREFCNT_dec(sv);
14236 }
14237 exception=DestroyExceptionInfo(exception);
14238 ST(0)=av_reference;
14239 SvREFCNT_dec(perl_exception);
14240 XSRETURN(1);
14241
14242 PerlException:
14243 InheritPerlException(exception,perl_exception);
14244 exception=DestroyExceptionInfo(exception);
14245 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14246 SvPOK_on(perl_exception);
14247 ST(0)=sv_2mortal(perl_exception);
14248 XSRETURN(1);
14249 }
14250
14251#
14252###############################################################################
14253# #
14254# #
14255# #
14256# S t a t i s t i c s #
14257# #
14258# #
14259# #
14260###############################################################################
14261#
14262#
14263void
14264Statistics(ref,...)
14265 Image::Magick ref=NO_INIT
14266 ALIAS:
14267 StatisticsImage = 1
14268 statistics = 2
14269 statisticsimage = 3
14270 PPCODE:
14271 {
14272#define ChannelStatistics(channel) \
14273{ \
cristy151b66d2015-04-15 10:50:31 +000014274 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014275 (double) channel_statistics[channel].depth); \
14276 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014277 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014278 channel_statistics[channel].minima/scale); \
14279 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014280 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014281 channel_statistics[channel].maxima/scale); \
14282 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014283 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014284 channel_statistics[channel].mean/scale); \
14285 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014286 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014287 channel_statistics[channel].standard_deviation/scale); \
14288 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014289 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014290 channel_statistics[channel].kurtosis); \
14291 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014292 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014293 channel_statistics[channel].skewness); \
14294 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014295 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy275bdd92014-11-08 23:45:03 +000014296 channel_statistics[channel].entropy); \
14297 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014298}
14299
14300 AV
14301 *av;
14302
14303 char
cristy151b66d2015-04-15 10:50:31 +000014304 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014305
14306 ChannelStatistics
14307 *channel_statistics;
14308
14309 double
14310 scale;
14311
14312 ExceptionInfo
14313 *exception;
14314
14315 Image
14316 *image;
14317
14318 ssize_t
14319 count;
14320
14321 struct PackageInfo
14322 *info;
14323
14324 SV
14325 *perl_exception,
14326 *reference;
14327
14328 PERL_UNUSED_VAR(ref);
14329 PERL_UNUSED_VAR(ix);
14330 exception=AcquireExceptionInfo();
14331 perl_exception=newSVpv("",0);
14332 av=NULL;
14333 if (sv_isobject(ST(0)) == 0)
14334 {
14335 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14336 PackageName);
14337 goto PerlException;
14338 }
14339 reference=SvRV(ST(0));
14340 av=newAV();
14341 SvREFCNT_dec(av);
14342 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14343 if (image == (Image *) NULL)
14344 {
14345 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14346 PackageName);
14347 goto PerlException;
14348 }
cristy4a3ce0a2013-08-03 20:06:59 +000014349 count=0;
14350 for ( ; image; image=image->next)
14351 {
14352 channel_statistics=GetImageStatistics(image,exception);
14353 if (channel_statistics == (ChannelStatistics *) NULL)
14354 continue;
14355 count++;
14356 EXTEND(sp,35*count);
14357 scale=(double) QuantumRange;
14358 ChannelStatistics(RedChannel);
14359 ChannelStatistics(GreenChannel);
14360 ChannelStatistics(BlueChannel);
14361 if (image->colorspace == CMYKColorspace)
14362 ChannelStatistics(BlackChannel);
cristy17f11b02014-12-20 19:37:04 +000014363 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000014364 ChannelStatistics(AlphaChannel);
14365 channel_statistics=(ChannelStatistics *)
14366 RelinquishMagickMemory(channel_statistics);
14367 }
14368
14369 PerlException:
14370 InheritPerlException(exception,perl_exception);
14371 exception=DestroyExceptionInfo(exception);
14372 SvREFCNT_dec(perl_exception);
14373 }
14374
14375#
14376###############################################################################
14377# #
14378# #
14379# #
14380# S y n c A u t h e n t i c P i x e l s #
14381# #
14382# #
14383# #
14384###############################################################################
14385#
14386#
14387void
14388SyncAuthenticPixels(ref,...)
14389 Image::Magick ref = NO_INIT
14390 ALIAS:
14391 Syncauthenticpixels = 1
14392 SyncImagePixels = 2
14393 syncimagepixels = 3
14394 CODE:
14395 {
14396 ExceptionInfo
14397 *exception;
14398
14399 Image
14400 *image;
14401
14402 MagickBooleanType
14403 status;
14404
14405 struct PackageInfo
14406 *info;
14407
14408 SV
14409 *perl_exception,
14410 *reference;
14411
14412 PERL_UNUSED_VAR(ref);
14413 PERL_UNUSED_VAR(ix);
14414 exception=AcquireExceptionInfo();
14415 perl_exception=newSVpv("",0);
14416 if (sv_isobject(ST(0)) == 0)
14417 {
14418 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14419 PackageName);
14420 goto PerlException;
14421 }
14422
14423 reference=SvRV(ST(0));
14424 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14425 if (image == (Image *) NULL)
14426 {
14427 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14428 PackageName);
14429 goto PerlException;
14430 }
14431
14432 status=SyncAuthenticPixels(image,exception);
14433 if (status != MagickFalse)
14434 return;
14435
14436 PerlException:
14437 InheritPerlException(exception,perl_exception);
14438 exception=DestroyExceptionInfo(exception);
14439 SvREFCNT_dec(perl_exception); /* throw away all errors */
14440 }
14441
14442#
14443###############################################################################
14444# #
14445# #
14446# #
14447# T r a n s f o r m #
14448# #
14449# #
14450# #
14451###############################################################################
14452#
14453#
14454void
14455Transform(ref,...)
14456 Image::Magick ref=NO_INIT
14457 ALIAS:
14458 TransformImage = 1
14459 transform = 2
14460 transformimage = 3
14461 PPCODE:
14462 {
14463 AV
14464 *av;
14465
14466 char
14467 *attribute,
14468 *crop_geometry,
14469 *geometry;
14470
14471 ExceptionInfo
14472 *exception;
14473
14474 HV
14475 *hv;
14476
14477 Image
14478 *clone,
14479 *image;
14480
14481 register ssize_t
14482 i;
14483
14484 struct PackageInfo
14485 *info;
14486
14487 SV
14488 *av_reference,
14489 *perl_exception,
14490 *reference,
14491 *rv,
14492 *sv;
14493
14494 PERL_UNUSED_VAR(ref);
14495 PERL_UNUSED_VAR(ix);
14496 exception=AcquireExceptionInfo();
14497 perl_exception=newSVpv("",0);
14498 sv=NULL;
14499 av=NULL;
14500 attribute=NULL;
14501 if (sv_isobject(ST(0)) == 0)
14502 {
14503 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14504 PackageName);
14505 goto PerlException;
14506 }
14507 reference=SvRV(ST(0));
14508 hv=SvSTASH(reference);
14509 av=newAV();
14510 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14511 SvREFCNT_dec(av);
14512 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14513 if (image == (Image *) NULL)
14514 {
14515 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14516 PackageName);
14517 goto PerlException;
14518 }
14519 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14520 /*
14521 Get attribute.
14522 */
14523 crop_geometry=(char *) NULL;
14524 geometry=(char *) NULL;
14525 for (i=2; i < items; i+=2)
14526 {
14527 attribute=(char *) SvPV(ST(i-1),na);
14528 switch (*attribute)
14529 {
14530 case 'c':
14531 case 'C':
14532 {
14533 if (LocaleCompare(attribute,"crop") == 0)
14534 {
14535 crop_geometry=SvPV(ST(i),na);
14536 break;
14537 }
14538 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14539 attribute);
14540 break;
14541 }
14542 case 'g':
14543 case 'G':
14544 {
14545 if (LocaleCompare(attribute,"geometry") == 0)
14546 {
14547 geometry=SvPV(ST(i),na);
14548 break;
14549 }
14550 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14551 attribute);
14552 break;
14553 }
14554 default:
14555 {
14556 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14557 attribute);
14558 break;
14559 }
14560 }
14561 }
14562 for ( ; image; image=image->next)
14563 {
14564 clone=CloneImage(image,0,0,MagickTrue,exception);
14565 if (clone == (Image *) NULL)
14566 goto PerlException;
14567 TransformImage(&clone,crop_geometry,geometry,exception);
14568 for ( ; clone; clone=clone->next)
14569 {
14570 AddImageToRegistry(sv,clone);
14571 rv=newRV(sv);
14572 av_push(av,sv_bless(rv,hv));
14573 SvREFCNT_dec(sv);
14574 }
14575 }
14576 exception=DestroyExceptionInfo(exception);
14577 ST(0)=av_reference;
14578 SvREFCNT_dec(perl_exception); /* can't return warning messages */
14579 XSRETURN(1);
14580
14581 PerlException:
14582 InheritPerlException(exception,perl_exception);
14583 exception=DestroyExceptionInfo(exception);
14584 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14585 SvPOK_on(perl_exception);
14586 ST(0)=sv_2mortal(perl_exception);
14587 XSRETURN(1);
14588 }
14589
14590#
14591###############################################################################
14592# #
14593# #
14594# #
14595# W r i t e #
14596# #
14597# #
14598# #
14599###############################################################################
14600#
14601#
14602void
14603Write(ref,...)
14604 Image::Magick ref=NO_INIT
14605 ALIAS:
14606 WriteImage = 1
14607 write = 2
14608 writeimage = 3
14609 PPCODE:
14610 {
14611 char
cristy151b66d2015-04-15 10:50:31 +000014612 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014613
14614 ExceptionInfo
14615 *exception;
14616
14617 Image
14618 *image,
14619 *next;
14620
14621 register ssize_t
14622 i;
14623
14624 ssize_t
14625 number_images,
14626 scene;
14627
14628 struct PackageInfo
14629 *info,
14630 *package_info;
14631
14632 SV
14633 *perl_exception,
14634 *reference;
14635
14636 PERL_UNUSED_VAR(ref);
14637 PERL_UNUSED_VAR(ix);
14638 exception=AcquireExceptionInfo();
14639 perl_exception=newSVpv("",0);
14640 number_images=0;
14641 package_info=(struct PackageInfo *) NULL;
14642 if (sv_isobject(ST(0)) == 0)
14643 {
14644 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14645 PackageName);
14646 goto PerlException;
14647 }
14648 reference=SvRV(ST(0));
14649 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14650 if (image == (Image *) NULL)
14651 {
14652 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14653 PackageName);
14654 goto PerlException;
14655 }
14656 package_info=ClonePackageInfo(info,exception);
14657 if (items == 2)
14658 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14659 else
14660 if (items > 2)
14661 for (i=2; i < items; i+=2)
14662 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14663 exception);
14664 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014665 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014666 scene=0;
14667 for (next=image; next; next=next->next)
14668 {
cristy151b66d2015-04-15 10:50:31 +000014669 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014670 next->scene=scene++;
14671 }
cristy68bd79a2015-02-25 12:23:36 +000014672 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014673 SetImageInfo(package_info->image_info,(unsigned int)
14674 GetImageListLength(image),exception);
14675 for (next=image; next; next=next->next)
14676 {
14677 (void) WriteImage(package_info->image_info,next,exception);
14678 number_images++;
14679 if (package_info->image_info->adjoin)
14680 break;
14681 }
14682
14683 PerlException:
14684 if (package_info != (struct PackageInfo *) NULL)
14685 DestroyPackageInfo(package_info);
14686 InheritPerlException(exception,perl_exception);
14687 exception=DestroyExceptionInfo(exception);
14688 sv_setiv(perl_exception,(IV) number_images);
14689 SvPOK_on(perl_exception);
14690 ST(0)=sv_2mortal(perl_exception);
14691 XSRETURN(1);
14692 }