blob: 9d6ebcc3db4539b67a101900cc440f55c513842d [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 }
2201 if (LocaleCompare(attribute,"view") == 0)
2202 {
2203 if (info)
2204 (void) CloneString(&info->image_info->view,SvPV(sval,na));
2205 break;
2206 }
2207 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2208 {
2209 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2210 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2211 if (sp < 0)
2212 {
2213 ThrowPerlException(exception,OptionError,
2214 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2215 break;
2216 }
2217 for ( ; image; image=image->next)
2218 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2219 break;
2220 }
2221 if (info)
2222 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2223 for ( ; image; image=image->next)
2224 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2225 break;
2226 }
2227 case 'W':
2228 case 'w':
2229 {
2230 if (LocaleCompare(attribute,"white-point") == 0)
2231 {
2232 for ( ; image; image=image->next)
2233 {
2234 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2235 image->chromaticity.white_point.x=geometry_info.rho;
2236 image->chromaticity.white_point.y=geometry_info.sigma;
2237 if ((flags & SigmaValue) == 0)
2238 image->chromaticity.white_point.y=
2239 image->chromaticity.white_point.x;
2240 }
2241 break;
2242 }
cristyc0fe4752015-07-27 18:02:39 +00002243 if (LocaleCompare(attribute,"write-mask") == 0)
2244 {
2245 Image
2246 *mask;
2247
2248 mask=(Image *) NULL;
2249 if (SvPOK(sval))
2250 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2251 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002252 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002253 break;
2254 }
cristy4a3ce0a2013-08-03 20:06:59 +00002255 if (info)
2256 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2257 for ( ; image; image=image->next)
2258 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2259 break;
2260 }
2261 default:
2262 {
2263 if (info)
2264 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2265 for ( ; image; image=image->next)
2266 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2267 break;
2268 }
2269 }
2270}
2271
2272/*
2273%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2274% %
2275% %
2276% %
2277% S e t u p L i s t %
2278% %
2279% %
2280% %
2281%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2282%
2283% Method SetupList returns the list of all the images linked by their
2284% image->next and image->previous link lists for use with ImageMagick. If
2285% info is non-NULL, an info structure is returned in *info. If
2286% reference_vector is non-NULL,an array of SV* are returned in
2287% *reference_vector. Reference_vector is used when the images are going to be
2288% replaced with new Image*'s.
2289%
2290% The format of the SetupList routine is:
2291%
2292% Image *SetupList(SV *reference,struct PackageInfo **info,
2293% SV ***reference_vector,ExceptionInfo *exception)
2294%
2295% A description of each parameter follows:
2296%
2297% o list: a list of strings.
2298%
2299% o string: a character string.
2300%
2301% o exception: Return any errors or warnings in this structure.
2302%
2303*/
2304static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2305 SV ***reference_vector,ExceptionInfo *exception)
2306{
2307 Image
2308 *image;
2309
2310 ssize_t
2311 current,
2312 last;
2313
2314 if (reference_vector)
2315 *reference_vector=NULL;
2316 if (info)
2317 *info=NULL;
2318 current=0;
2319 last=0;
2320 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2321 if (info && (SvTYPE(reference) == SVt_PVAV))
2322 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2323 exception);
2324 return(image);
2325}
2326
2327/*
2328%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2329% %
2330% %
2331% %
2332% s t r E Q c a s e %
2333% %
2334% %
2335% %
2336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2337%
2338% strEQcase() compares two strings and returns 0 if they are the
2339% same or if the second string runs out first. The comparison is case
2340% insensitive.
2341%
2342% The format of the strEQcase routine is:
2343%
2344% ssize_t strEQcase(const char *p,const char *q)
2345%
2346% A description of each parameter follows:
2347%
2348% o p: a character string.
2349%
2350% o q: a character string.
2351%
2352%
2353*/
2354static ssize_t strEQcase(const char *p,const char *q)
2355{
2356 char
2357 c;
2358
2359 register ssize_t
2360 i;
2361
2362 for (i=0 ; (c=(*q)) != 0; i++)
2363 {
2364 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2365 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2366 return(0);
2367 p++;
2368 q++;
2369 }
2370 return(((*q == 0) && (*p == 0)) ? i : 0);
2371}
2372
2373/*
2374%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2375% %
2376% %
2377% %
2378% I m a g e : : M a g i c k %
2379% %
2380% %
2381% %
2382%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2383%
2384%
2385*/
2386MODULE = Image::Magick PACKAGE = Image::Magick
2387
2388PROTOTYPES: ENABLE
2389
2390BOOT:
2391 MagickCoreGenesis("PerlMagick",MagickFalse);
2392 SetWarningHandler(NULL);
2393 SetErrorHandler(NULL);
2394 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2395 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2396
2397void
2398UNLOAD()
2399 PPCODE:
2400 {
2401 if (magick_registry != (SplayTreeInfo *) NULL)
2402 magick_registry=DestroySplayTree(magick_registry);
2403 MagickCoreTerminus();
2404 }
2405
2406double
2407constant(name,argument)
2408 char *name
2409 ssize_t argument
2410
2411#
2412###############################################################################
2413# #
2414# #
2415# #
2416# A n i m a t e #
2417# #
2418# #
2419# #
2420###############################################################################
2421#
2422#
2423void
2424Animate(ref,...)
2425 Image::Magick ref=NO_INIT
2426 ALIAS:
2427 AnimateImage = 1
2428 animate = 2
2429 animateimage = 3
2430 PPCODE:
2431 {
2432 ExceptionInfo
2433 *exception;
2434
2435 Image
2436 *image;
2437
2438 register ssize_t
2439 i;
2440
2441 struct PackageInfo
2442 *info,
2443 *package_info;
2444
2445 SV
2446 *perl_exception,
2447 *reference;
2448
2449 PERL_UNUSED_VAR(ref);
2450 PERL_UNUSED_VAR(ix);
2451 exception=AcquireExceptionInfo();
2452 perl_exception=newSVpv("",0);
2453 package_info=(struct PackageInfo *) NULL;
2454 if (sv_isobject(ST(0)) == 0)
2455 {
2456 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2457 PackageName);
2458 goto PerlException;
2459 }
2460 reference=SvRV(ST(0));
2461 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2462 if (image == (Image *) NULL)
2463 {
2464 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2465 PackageName);
2466 goto PerlException;
2467 }
2468 package_info=ClonePackageInfo(info,exception);
2469 if (items == 2)
2470 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2471 else
2472 if (items > 2)
2473 for (i=2; i < items; i+=2)
2474 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2475 exception);
2476 (void) AnimateImages(package_info->image_info,image,exception);
2477 (void) CatchImageException(image);
2478
2479 PerlException:
2480 if (package_info != (struct PackageInfo *) NULL)
2481 DestroyPackageInfo(package_info);
2482 InheritPerlException(exception,perl_exception);
2483 exception=DestroyExceptionInfo(exception);
2484 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2485 SvPOK_on(perl_exception);
2486 ST(0)=sv_2mortal(perl_exception);
2487 XSRETURN(1);
2488 }
2489
2490#
2491###############################################################################
2492# #
2493# #
2494# #
2495# A p p e n d #
2496# #
2497# #
2498# #
2499###############################################################################
2500#
2501#
2502void
2503Append(ref,...)
2504 Image::Magick ref=NO_INIT
2505 ALIAS:
2506 AppendImage = 1
2507 append = 2
2508 appendimage = 3
2509 PPCODE:
2510 {
2511 AV
2512 *av;
2513
2514 char
2515 *attribute;
2516
2517 ExceptionInfo
2518 *exception;
2519
2520 HV
2521 *hv;
2522
2523 Image
2524 *image;
2525
2526 register ssize_t
2527 i;
2528
2529 ssize_t
2530 stack;
2531
2532 struct PackageInfo
2533 *info;
2534
2535 SV
2536 *av_reference,
2537 *perl_exception,
2538 *reference,
2539 *rv,
2540 *sv;
2541
2542 PERL_UNUSED_VAR(ref);
2543 PERL_UNUSED_VAR(ix);
2544 exception=AcquireExceptionInfo();
2545 perl_exception=newSVpv("",0);
2546 sv=NULL;
2547 attribute=NULL;
2548 av=NULL;
2549 if (sv_isobject(ST(0)) == 0)
2550 {
2551 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2552 PackageName);
2553 goto PerlException;
2554 }
2555 reference=SvRV(ST(0));
2556 hv=SvSTASH(reference);
2557 av=newAV();
2558 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2559 SvREFCNT_dec(av);
2560 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2561 if (image == (Image *) NULL)
2562 {
2563 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2564 PackageName);
2565 goto PerlException;
2566 }
2567 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2568 /*
2569 Get options.
2570 */
2571 stack=MagickTrue;
2572 for (i=2; i < items; i+=2)
2573 {
2574 attribute=(char *) SvPV(ST(i-1),na);
2575 switch (*attribute)
2576 {
2577 case 'S':
2578 case 's':
2579 {
2580 if (LocaleCompare(attribute,"stack") == 0)
2581 {
2582 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2583 SvPV(ST(i),na));
2584 if (stack < 0)
2585 {
2586 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2587 SvPV(ST(i),na));
2588 return;
2589 }
2590 break;
2591 }
2592 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2593 attribute);
2594 break;
2595 }
2596 default:
2597 {
2598 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2599 attribute);
2600 break;
2601 }
2602 }
2603 }
2604 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2605 if (image == (Image *) NULL)
2606 goto PerlException;
2607 for ( ; image; image=image->next)
2608 {
2609 AddImageToRegistry(sv,image);
2610 rv=newRV(sv);
2611 av_push(av,sv_bless(rv,hv));
2612 SvREFCNT_dec(sv);
2613 }
2614 exception=DestroyExceptionInfo(exception);
2615 ST(0)=av_reference;
2616 SvREFCNT_dec(perl_exception);
2617 XSRETURN(1);
2618
2619 PerlException:
2620 InheritPerlException(exception,perl_exception);
2621 exception=DestroyExceptionInfo(exception);
2622 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2623 SvPOK_on(perl_exception);
2624 ST(0)=sv_2mortal(perl_exception);
2625 XSRETURN(1);
2626 }
2627
2628#
2629###############################################################################
2630# #
2631# #
2632# #
2633# A v e r a g e #
2634# #
2635# #
2636# #
2637###############################################################################
2638#
2639#
2640void
2641Average(ref)
2642 Image::Magick ref=NO_INIT
2643 ALIAS:
2644 AverageImage = 1
2645 average = 2
2646 averageimage = 3
2647 PPCODE:
2648 {
2649 AV
2650 *av;
2651
2652 char
2653 *p;
2654
2655 ExceptionInfo
2656 *exception;
2657
2658 HV
2659 *hv;
2660
2661 Image
2662 *image;
2663
2664 struct PackageInfo
2665 *info;
2666
2667 SV
2668 *perl_exception,
2669 *reference,
2670 *rv,
2671 *sv;
2672
2673 PERL_UNUSED_VAR(ref);
2674 PERL_UNUSED_VAR(ix);
2675 exception=AcquireExceptionInfo();
2676 perl_exception=newSVpv("",0);
2677 sv=NULL;
2678 if (sv_isobject(ST(0)) == 0)
2679 {
2680 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2681 PackageName);
2682 goto PerlException;
2683 }
2684 reference=SvRV(ST(0));
2685 hv=SvSTASH(reference);
2686 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2687 if (image == (Image *) NULL)
2688 {
2689 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2690 PackageName);
2691 goto PerlException;
2692 }
2693 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2694 if (image == (Image *) NULL)
2695 goto PerlException;
2696 /*
2697 Create blessed Perl array for the returned image.
2698 */
2699 av=newAV();
2700 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2701 SvREFCNT_dec(av);
2702 AddImageToRegistry(sv,image);
2703 rv=newRV(sv);
2704 av_push(av,sv_bless(rv,hv));
2705 SvREFCNT_dec(sv);
2706 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002707 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2708 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002709 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2710 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002711 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002712 SetImageInfo(info->image_info,0,exception);
2713 exception=DestroyExceptionInfo(exception);
2714 SvREFCNT_dec(perl_exception);
2715 XSRETURN(1);
2716
2717 PerlException:
2718 InheritPerlException(exception,perl_exception);
2719 exception=DestroyExceptionInfo(exception);
2720 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2721 SvPOK_on(perl_exception);
2722 ST(0)=sv_2mortal(perl_exception);
2723 XSRETURN(1);
2724 }
2725
2726#
2727###############################################################################
2728# #
2729# #
2730# #
2731# B l o b T o I m a g e #
2732# #
2733# #
2734# #
2735###############################################################################
2736#
2737#
2738void
2739BlobToImage(ref,...)
2740 Image::Magick ref=NO_INIT
2741 ALIAS:
2742 BlobToImage = 1
2743 blobtoimage = 2
2744 blobto = 3
2745 PPCODE:
2746 {
2747 AV
2748 *av;
2749
2750 char
2751 **keep,
2752 **list;
2753
2754 ExceptionInfo
2755 *exception;
2756
2757 HV
2758 *hv;
2759
2760 Image
2761 *image;
2762
2763 register char
2764 **p;
2765
2766 register ssize_t
2767 i;
2768
2769 ssize_t
2770 ac,
2771 n,
2772 number_images;
2773
2774 STRLEN
2775 *length;
2776
2777 struct PackageInfo
2778 *info;
2779
2780 SV
2781 *perl_exception,
2782 *reference,
2783 *rv,
2784 *sv;
2785
2786 PERL_UNUSED_VAR(ref);
2787 PERL_UNUSED_VAR(ix);
2788 exception=AcquireExceptionInfo();
2789 perl_exception=newSVpv("",0);
2790 sv=NULL;
2791 number_images=0;
2792 ac=(items < 2) ? 1 : items-1;
2793 length=(STRLEN *) NULL;
2794 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2795 if (list == (char **) NULL)
2796 {
2797 ThrowPerlException(exception,ResourceLimitError,
2798 "MemoryAllocationFailed",PackageName);
2799 goto PerlException;
2800 }
2801 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2802 if (length == (STRLEN *) NULL)
2803 {
2804 ThrowPerlException(exception,ResourceLimitError,
2805 "MemoryAllocationFailed",PackageName);
2806 goto PerlException;
2807 }
2808 if (sv_isobject(ST(0)) == 0)
2809 {
2810 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2811 PackageName);
2812 goto PerlException;
2813 }
2814 reference=SvRV(ST(0));
2815 hv=SvSTASH(reference);
2816 if (SvTYPE(reference) != SVt_PVAV)
2817 {
2818 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2819 PackageName);
2820 goto PerlException;
2821 }
2822 av=(AV *) reference;
2823 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2824 exception);
2825 n=1;
2826 if (items <= 1)
2827 {
2828 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2829 goto PerlException;
2830 }
2831 for (n=0, i=0; i < ac; i++)
2832 {
2833 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2834 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2835 {
2836 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2837 continue;
2838 }
2839 n++;
2840 }
2841 list[n]=(char *) NULL;
2842 keep=list;
2843 for (i=number_images=0; i < n; i++)
2844 {
2845 image=BlobToImage(info->image_info,list[i],length[i],exception);
2846 if (image == (Image *) NULL)
2847 break;
2848 for ( ; image; image=image->next)
2849 {
2850 AddImageToRegistry(sv,image);
2851 rv=newRV(sv);
2852 av_push(av,sv_bless(rv,hv));
2853 SvREFCNT_dec(sv);
2854 number_images++;
2855 }
2856 }
2857 /*
2858 Free resources.
2859 */
2860 for (i=0; i < n; i++)
2861 if (list[i] != (char *) NULL)
2862 for (p=keep; list[i] != *p++; )
2863 if (*p == (char *) NULL)
2864 {
2865 list[i]=(char *) RelinquishMagickMemory(list[i]);
2866 break;
2867 }
2868
2869 PerlException:
2870 if (list)
2871 list=(char **) RelinquishMagickMemory(list);
2872 if (length)
2873 length=(STRLEN *) RelinquishMagickMemory(length);
2874 InheritPerlException(exception,perl_exception);
2875 exception=DestroyExceptionInfo(exception);
2876 sv_setiv(perl_exception,(IV) number_images);
2877 SvPOK_on(perl_exception);
2878 ST(0)=sv_2mortal(perl_exception);
2879 XSRETURN(1);
2880 }
2881
2882#
2883###############################################################################
2884# #
2885# #
2886# #
2887# C h a n n e l F x #
2888# #
2889# #
2890# #
2891###############################################################################
2892#
2893#
2894void
2895ChannelFx(ref,...)
2896 Image::Magick ref=NO_INIT
2897 ALIAS:
2898 ChannelFxImage = 1
2899 channelfx = 2
2900 channelfximage = 3
2901 PPCODE:
2902 {
2903 AV
2904 *av;
2905
2906 char
2907 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002908 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002909
2910 ChannelType
2911 channel,
2912 channel_mask;
2913
2914 ExceptionInfo
2915 *exception;
2916
2917 HV
2918 *hv;
2919
2920 Image
2921 *image;
2922
2923 register ssize_t
2924 i;
2925
2926 struct PackageInfo
2927 *info;
2928
2929 SV
2930 *av_reference,
2931 *perl_exception,
2932 *reference,
2933 *rv,
2934 *sv;
2935
2936 PERL_UNUSED_VAR(ref);
2937 PERL_UNUSED_VAR(ix);
2938 exception=AcquireExceptionInfo();
2939 perl_exception=newSVpv("",0);
2940 sv=NULL;
2941 attribute=NULL;
2942 av=NULL;
2943 if (sv_isobject(ST(0)) == 0)
2944 {
2945 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2946 PackageName);
2947 goto PerlException;
2948 }
2949 reference=SvRV(ST(0));
2950 hv=SvSTASH(reference);
2951 av=newAV();
2952 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2953 SvREFCNT_dec(av);
2954 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2955 if (image == (Image *) NULL)
2956 {
2957 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2958 PackageName);
2959 goto PerlException;
2960 }
2961 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2962 /*
2963 Get options.
2964 */
2965 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00002966 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002967 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00002968 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002969 else
2970 for (i=2; i < items; i+=2)
2971 {
2972 attribute=(char *) SvPV(ST(i-1),na);
2973 switch (*attribute)
2974 {
2975 case 'C':
2976 case 'c':
2977 {
2978 if (LocaleCompare(attribute,"channel") == 0)
2979 {
2980 ssize_t
2981 option;
2982
2983 option=ParseChannelOption(SvPV(ST(i),na));
2984 if (option < 0)
2985 {
2986 ThrowPerlException(exception,OptionError,
2987 "UnrecognizedType",SvPV(ST(i),na));
2988 return;
2989 }
2990 channel=(ChannelType) option;
2991 break;
2992 }
2993 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2994 attribute);
2995 break;
2996 }
2997 case 'E':
2998 case 'e':
2999 {
3000 if (LocaleCompare(attribute,"expression") == 0)
3001 {
3002 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00003003 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003004 break;
3005 }
3006 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3007 attribute);
3008 break;
3009 }
3010 default:
3011 {
3012 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3013 attribute);
3014 break;
3015 }
3016 }
3017 }
3018 channel_mask=SetImageChannelMask(image,channel);
3019 image=ChannelFxImage(image,expression,exception);
3020 if (image != (Image *) NULL)
3021 (void) SetImageChannelMask(image,channel_mask);
3022 if (image == (Image *) NULL)
3023 goto PerlException;
3024 for ( ; image; image=image->next)
3025 {
3026 AddImageToRegistry(sv,image);
3027 rv=newRV(sv);
3028 av_push(av,sv_bless(rv,hv));
3029 SvREFCNT_dec(sv);
3030 }
3031 exception=DestroyExceptionInfo(exception);
3032 ST(0)=av_reference;
3033 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3034 XSRETURN(1);
3035
3036 PerlException:
3037 InheritPerlException(exception,perl_exception);
3038 exception=DestroyExceptionInfo(exception);
3039 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3040 SvPOK_on(perl_exception);
3041 ST(0)=sv_2mortal(perl_exception);
3042 XSRETURN(1);
3043 }
3044
3045#
3046###############################################################################
3047# #
3048# #
3049# #
3050# C l o n e #
3051# #
3052# #
3053# #
3054###############################################################################
3055#
3056#
3057void
3058Clone(ref)
3059 Image::Magick ref=NO_INIT
3060 ALIAS:
3061 CopyImage = 1
3062 copy = 2
3063 copyimage = 3
3064 CloneImage = 4
3065 clone = 5
3066 cloneimage = 6
3067 Clone = 7
3068 PPCODE:
3069 {
3070 AV
3071 *av;
3072
3073 ExceptionInfo
3074 *exception;
3075
3076 HV
3077 *hv;
3078
3079 Image
3080 *clone,
3081 *image;
3082
3083 struct PackageInfo
3084 *info;
3085
3086 SV
3087 *perl_exception,
3088 *reference,
3089 *rv,
3090 *sv;
3091
3092 PERL_UNUSED_VAR(ref);
3093 PERL_UNUSED_VAR(ix);
3094 exception=AcquireExceptionInfo();
3095 perl_exception=newSVpv("",0);
3096 sv=NULL;
3097 if (sv_isobject(ST(0)) == 0)
3098 {
3099 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3100 PackageName);
3101 goto PerlException;
3102 }
3103 reference=SvRV(ST(0));
3104 hv=SvSTASH(reference);
3105 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3106 if (image == (Image *) NULL)
3107 {
3108 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3109 PackageName);
3110 goto PerlException;
3111 }
3112 /*
3113 Create blessed Perl array for the returned image.
3114 */
3115 av=newAV();
3116 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3117 SvREFCNT_dec(av);
3118 for ( ; image; image=image->next)
3119 {
3120 clone=CloneImage(image,0,0,MagickTrue,exception);
3121 if (clone == (Image *) NULL)
3122 break;
3123 AddImageToRegistry(sv,clone);
3124 rv=newRV(sv);
3125 av_push(av,sv_bless(rv,hv));
3126 SvREFCNT_dec(sv);
3127 }
3128 exception=DestroyExceptionInfo(exception);
3129 SvREFCNT_dec(perl_exception);
3130 XSRETURN(1);
3131
3132 PerlException:
3133 InheritPerlException(exception,perl_exception);
3134 exception=DestroyExceptionInfo(exception);
3135 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3136 SvPOK_on(perl_exception);
3137 ST(0)=sv_2mortal(perl_exception);
3138 XSRETURN(1);
3139 }
3140
3141#
3142###############################################################################
3143# #
3144# #
3145# #
3146# C L O N E #
3147# #
3148# #
3149# #
3150###############################################################################
3151#
3152#
3153void
3154CLONE(ref,...)
3155 SV *ref;
3156 CODE:
3157 {
3158 PERL_UNUSED_VAR(ref);
3159 if (magick_registry != (SplayTreeInfo *) NULL)
3160 {
3161 register Image
3162 *p;
3163
3164 ResetSplayTreeIterator(magick_registry);
3165 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3166 while (p != (Image *) NULL)
3167 {
3168 ReferenceImage(p);
3169 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3170 }
3171 }
3172 }
3173
3174#
3175###############################################################################
3176# #
3177# #
3178# #
3179# C o a l e s c e #
3180# #
3181# #
3182# #
3183###############################################################################
3184#
3185#
3186void
3187Coalesce(ref)
3188 Image::Magick ref=NO_INIT
3189 ALIAS:
3190 CoalesceImage = 1
3191 coalesce = 2
3192 coalesceimage = 3
3193 PPCODE:
3194 {
3195 AV
3196 *av;
3197
3198 ExceptionInfo
3199 *exception;
3200
3201 HV
3202 *hv;
3203
3204 Image
3205 *image;
3206
3207 struct PackageInfo
3208 *info;
3209
3210 SV
3211 *av_reference,
3212 *perl_exception,
3213 *reference,
3214 *rv,
3215 *sv;
3216
3217 PERL_UNUSED_VAR(ref);
3218 PERL_UNUSED_VAR(ix);
3219 exception=AcquireExceptionInfo();
3220 perl_exception=newSVpv("",0);
3221 sv=NULL;
3222 if (sv_isobject(ST(0)) == 0)
3223 {
3224 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3225 PackageName);
3226 goto PerlException;
3227 }
3228 reference=SvRV(ST(0));
3229 hv=SvSTASH(reference);
3230 av=newAV();
3231 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3232 SvREFCNT_dec(av);
3233 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3234 if (image == (Image *) NULL)
3235 {
3236 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3237 PackageName);
3238 goto PerlException;
3239 }
3240 image=CoalesceImages(image,exception);
3241 if (image == (Image *) NULL)
3242 goto PerlException;
3243 for ( ; image; image=image->next)
3244 {
3245 AddImageToRegistry(sv,image);
3246 rv=newRV(sv);
3247 av_push(av,sv_bless(rv,hv));
3248 SvREFCNT_dec(sv);
3249 }
3250 exception=DestroyExceptionInfo(exception);
3251 ST(0)=av_reference;
3252 SvREFCNT_dec(perl_exception);
3253 XSRETURN(1);
3254
3255 PerlException:
3256 InheritPerlException(exception,perl_exception);
3257 exception=DestroyExceptionInfo(exception);
3258 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3259 SvPOK_on(perl_exception);
3260 ST(0)=sv_2mortal(perl_exception);
3261 XSRETURN(1);
3262 }
3263
3264#
3265###############################################################################
3266# #
3267# #
3268# #
3269# C o m p a r e #
3270# #
3271# #
3272# #
3273###############################################################################
3274#
3275#
3276void
3277Compare(ref,...)
3278 Image::Magick ref=NO_INIT
3279 ALIAS:
3280 CompareImages = 1
3281 compare = 2
3282 compareimage = 3
3283 PPCODE:
3284 {
3285 AV
3286 *av;
3287
3288 char
3289 *attribute;
3290
3291 double
3292 distortion;
3293
3294 ExceptionInfo
3295 *exception;
3296
3297 HV
3298 *hv;
3299
3300 Image
3301 *difference_image,
3302 *image,
3303 *reconstruct_image;
3304
3305 MetricType
3306 metric;
3307
3308 register ssize_t
3309 i;
3310
3311 ssize_t
3312 option;
3313
3314 struct PackageInfo
3315 *info;
3316
3317 SV
3318 *av_reference,
3319 *perl_exception,
3320 *reference,
3321 *rv,
3322 *sv;
3323
3324 PERL_UNUSED_VAR(ref);
3325 PERL_UNUSED_VAR(ix);
3326 exception=AcquireExceptionInfo();
3327 perl_exception=newSVpv("",0);
3328 sv=NULL;
3329 av=NULL;
3330 attribute=NULL;
3331 if (sv_isobject(ST(0)) == 0)
3332 {
3333 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3334 PackageName);
3335 goto PerlException;
3336 }
3337 reference=SvRV(ST(0));
3338 hv=SvSTASH(reference);
3339 av=newAV();
3340 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3341 SvREFCNT_dec(av);
3342 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3343 if (image == (Image *) NULL)
3344 {
3345 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3346 PackageName);
3347 goto PerlException;
3348 }
3349 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3350 /*
3351 Get attribute.
3352 */
3353 reconstruct_image=image;
3354 metric=RootMeanSquaredErrorMetric;
3355 for (i=2; i < items; i+=2)
3356 {
3357 attribute=(char *) SvPV(ST(i-1),na);
3358 switch (*attribute)
3359 {
3360 case 'C':
3361 case 'c':
3362 {
3363 if (LocaleCompare(attribute,"channel") == 0)
3364 {
3365 ssize_t
3366 option;
3367
3368 option=ParseChannelOption(SvPV(ST(i),na));
3369 if (option < 0)
3370 {
3371 ThrowPerlException(exception,OptionError,
3372 "UnrecognizedType",SvPV(ST(i),na));
3373 return;
3374 }
cristybcd59342015-06-07 14:07:19 +00003375 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003376 break;
3377 }
3378 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3379 attribute);
3380 break;
3381 }
3382 case 'F':
3383 case 'f':
3384 {
3385 if (LocaleCompare(attribute,"fuzz") == 0)
3386 {
3387 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3388 break;
3389 }
3390 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3391 attribute);
3392 break;
3393 }
3394 case 'I':
3395 case 'i':
3396 {
3397 if (LocaleCompare(attribute,"image") == 0)
3398 {
3399 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3400 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3401 break;
3402 }
3403 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3404 attribute);
3405 break;
3406 }
3407 case 'M':
3408 case 'm':
3409 {
3410 if (LocaleCompare(attribute,"metric") == 0)
3411 {
3412 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3413 SvPV(ST(i),na));
3414 if (option < 0)
3415 {
3416 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3417 SvPV(ST(i),na));
3418 break;
3419 }
3420 metric=(MetricType) option;
3421 break;
3422 }
3423 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3424 attribute);
3425 break;
3426 }
3427 default:
3428 {
3429 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3430 attribute);
3431 break;
3432 }
3433 }
3434 }
3435 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3436 exception);
3437 if (difference_image != (Image *) NULL)
3438 {
3439 difference_image->error.mean_error_per_pixel=distortion;
3440 AddImageToRegistry(sv,difference_image);
3441 rv=newRV(sv);
3442 av_push(av,sv_bless(rv,hv));
3443 SvREFCNT_dec(sv);
3444 }
3445 exception=DestroyExceptionInfo(exception);
3446 ST(0)=av_reference;
3447 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3448 XSRETURN(1);
3449
3450 PerlException:
3451 InheritPerlException(exception,perl_exception);
3452 exception=DestroyExceptionInfo(exception);
3453 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3454 SvPOK_on(perl_exception);
3455 ST(0)=sv_2mortal(perl_exception);
3456 XSRETURN(1);
3457 }
3458
3459#
3460###############################################################################
3461# #
3462# #
3463# #
cristy15655332013-10-06 00:27:33 +00003464# C o m p l e x I m a g e s #
3465# #
3466# #
3467# #
3468###############################################################################
3469#
3470#
3471void
3472ComplexImages(ref)
3473 Image::Magick ref=NO_INIT
3474 ALIAS:
3475 ComplexImages = 1
3476 compleximages = 2
3477 PPCODE:
3478 {
3479 AV
3480 *av;
3481
3482 char
3483 *attribute,
3484 *p;
3485
cristyfa21e9e2013-10-07 10:37:38 +00003486 ComplexOperator
3487 op;
3488
cristy15655332013-10-06 00:27:33 +00003489 ExceptionInfo
3490 *exception;
3491
3492 HV
3493 *hv;
3494
3495 Image
3496 *image;
3497
cristy15655332013-10-06 00:27:33 +00003498 register ssize_t
3499 i;
3500
3501 struct PackageInfo
3502 *info;
3503
3504 SV
3505 *perl_exception,
3506 *reference,
3507 *rv,
3508 *sv;
3509
3510 PERL_UNUSED_VAR(ref);
3511 PERL_UNUSED_VAR(ix);
3512 exception=AcquireExceptionInfo();
3513 perl_exception=newSVpv("",0);
3514 sv=NULL;
3515 if (sv_isobject(ST(0)) == 0)
3516 {
3517 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3518 PackageName);
3519 goto PerlException;
3520 }
3521 reference=SvRV(ST(0));
3522 hv=SvSTASH(reference);
3523 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3524 if (image == (Image *) NULL)
3525 {
3526 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3527 PackageName);
3528 goto PerlException;
3529 }
cristyfd168722013-10-07 15:59:31 +00003530 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003531 if (items == 2)
3532 {
3533 ssize_t
3534 in;
3535
3536 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3537 SvPV(ST(1),na));
3538 if (in < 0)
3539 {
3540 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3541 SvPV(ST(1),na));
3542 return;
3543 }
cristyfa21e9e2013-10-07 10:37:38 +00003544 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003545 }
3546 else
3547 for (i=2; i < items; i+=2)
3548 {
3549 attribute=(char *) SvPV(ST(i-1),na);
3550 switch (*attribute)
3551 {
3552 case 'O':
3553 case 'o':
3554 {
3555 if (LocaleCompare(attribute,"operator") == 0)
3556 {
3557 ssize_t
3558 in;
3559
3560 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3561 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3562 if (in < 0)
3563 {
3564 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3565 SvPV(ST(i),na));
3566 return;
3567 }
cristyfa21e9e2013-10-07 10:37:38 +00003568 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003569 break;
3570 }
3571 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3572 attribute);
3573 break;
3574 }
3575 default:
3576 {
3577 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3578 attribute);
3579 break;
3580 }
3581 }
3582 }
3583 image=ComplexImages(image,op,exception);
3584 if (image == (Image *) NULL)
3585 goto PerlException;
3586 /*
3587 Create blessed Perl array for the returned image.
3588 */
3589 av=newAV();
3590 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3591 SvREFCNT_dec(av);
3592 AddImageToRegistry(sv,image);
3593 rv=newRV(sv);
3594 av_push(av,sv_bless(rv,hv));
3595 SvREFCNT_dec(sv);
3596 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003597 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3598 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003599 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3600 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003601 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003602 SetImageInfo(info->image_info,0,exception);
3603 exception=DestroyExceptionInfo(exception);
3604 SvREFCNT_dec(perl_exception);
3605 XSRETURN(1);
3606
3607 PerlException:
3608 InheritPerlException(exception,perl_exception);
3609 exception=DestroyExceptionInfo(exception);
3610 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3611 SvPOK_on(perl_exception);
3612 ST(0)=sv_2mortal(perl_exception);
3613 XSRETURN(1);
3614 }
3615
3616#
3617###############################################################################
3618# #
3619# #
3620# #
cristy4a3ce0a2013-08-03 20:06:59 +00003621# C o m p a r e L a y e r s #
3622# #
3623# #
3624# #
3625###############################################################################
3626#
3627#
3628void
3629CompareLayers(ref)
3630 Image::Magick ref=NO_INIT
3631 ALIAS:
3632 CompareImagesLayers = 1
3633 comparelayers = 2
3634 compareimagelayers = 3
3635 PPCODE:
3636 {
3637 AV
3638 *av;
3639
3640 char
3641 *attribute;
3642
3643 ExceptionInfo
3644 *exception;
3645
3646 HV
3647 *hv;
3648
3649 Image
3650 *image;
3651
3652 LayerMethod
3653 method;
3654
3655 register ssize_t
3656 i;
3657
3658 ssize_t
3659 option;
3660
3661 struct PackageInfo
3662 *info;
3663
3664 SV
3665 *av_reference,
3666 *perl_exception,
3667 *reference,
3668 *rv,
3669 *sv;
3670
3671 PERL_UNUSED_VAR(ref);
3672 PERL_UNUSED_VAR(ix);
3673 exception=AcquireExceptionInfo();
3674 perl_exception=newSVpv("",0);
3675 sv=NULL;
3676 if (sv_isobject(ST(0)) == 0)
3677 {
3678 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3679 PackageName);
3680 goto PerlException;
3681 }
3682 reference=SvRV(ST(0));
3683 hv=SvSTASH(reference);
3684 av=newAV();
3685 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3686 SvREFCNT_dec(av);
3687 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3688 if (image == (Image *) NULL)
3689 {
3690 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3691 PackageName);
3692 goto PerlException;
3693 }
3694 method=CompareAnyLayer;
3695 for (i=2; i < items; i+=2)
3696 {
3697 attribute=(char *) SvPV(ST(i-1),na);
3698 switch (*attribute)
3699 {
3700 case 'M':
3701 case 'm':
3702 {
3703 if (LocaleCompare(attribute,"method") == 0)
3704 {
3705 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3706 SvPV(ST(i),na));
3707 if (option < 0)
3708 {
3709 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3710 SvPV(ST(i),na));
3711 break;
3712 }
3713 method=(LayerMethod) option;
3714 break;
3715 }
3716 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3717 attribute);
3718 break;
3719 }
3720 default:
3721 {
3722 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3723 attribute);
3724 break;
3725 }
3726 }
3727 }
3728 image=CompareImagesLayers(image,method,exception);
3729 if (image == (Image *) NULL)
3730 goto PerlException;
3731 for ( ; image; image=image->next)
3732 {
3733 AddImageToRegistry(sv,image);
3734 rv=newRV(sv);
3735 av_push(av,sv_bless(rv,hv));
3736 SvREFCNT_dec(sv);
3737 }
3738 exception=DestroyExceptionInfo(exception);
3739 ST(0)=av_reference;
3740 SvREFCNT_dec(perl_exception);
3741 XSRETURN(1);
3742
3743 PerlException:
3744 InheritPerlException(exception,perl_exception);
3745 exception=DestroyExceptionInfo(exception);
3746 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3747 SvPOK_on(perl_exception);
3748 ST(0)=sv_2mortal(perl_exception);
3749 XSRETURN(1);
3750 }
3751
3752#
3753###############################################################################
3754# #
3755# #
3756# #
3757# D e s t r o y #
3758# #
3759# #
3760# #
3761###############################################################################
3762#
3763#
3764void
3765DESTROY(ref)
3766 Image::Magick ref=NO_INIT
3767 PPCODE:
3768 {
3769 SV
3770 *reference;
3771
3772 PERL_UNUSED_VAR(ref);
3773 if (sv_isobject(ST(0)) == 0)
3774 croak("ReferenceIsNotMyType");
3775 reference=SvRV(ST(0));
3776 switch (SvTYPE(reference))
3777 {
3778 case SVt_PVAV:
3779 {
3780 char
cristy151b66d2015-04-15 10:50:31 +00003781 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003782
3783 const SV
3784 *key;
3785
3786 HV
3787 *hv;
3788
3789 GV
3790 **gvp;
3791
3792 struct PackageInfo
3793 *info;
3794
3795 SV
3796 *sv;
3797
3798 /*
3799 Array (AV *) reference
3800 */
cristy151b66d2015-04-15 10:50:31 +00003801 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003802 XS_VERSION,reference);
3803 hv=gv_stashpv(PackageName, FALSE);
3804 if (!hv)
3805 break;
3806 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3807 if (!gvp)
3808 break;
3809 sv=GvSV(*gvp);
3810 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3811 {
3812 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3813 DestroyPackageInfo(info);
3814 }
3815 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3816 (void) key;
3817 break;
3818 }
3819 case SVt_PVMG:
3820 {
3821 Image
3822 *image;
3823
3824 /*
3825 Blessed scalar = (Image *) SvIV(reference)
3826 */
3827 image=INT2PTR(Image *,SvIV(reference));
3828 if (image != (Image *) NULL)
3829 DeleteImageFromRegistry(reference,image);
3830 break;
3831 }
3832 default:
3833 break;
3834 }
3835 }
3836
3837#
3838###############################################################################
3839# #
3840# #
3841# #
3842# D i s p l a y #
3843# #
3844# #
3845# #
3846###############################################################################
3847#
3848#
3849void
3850Display(ref,...)
3851 Image::Magick ref=NO_INIT
3852 ALIAS:
3853 DisplayImage = 1
3854 display = 2
3855 displayimage = 3
3856 PPCODE:
3857 {
3858 ExceptionInfo
3859 *exception;
3860
3861 Image
3862 *image;
3863
3864 register ssize_t
3865 i;
3866
3867 struct PackageInfo
3868 *info,
3869 *package_info;
3870
3871 SV
3872 *perl_exception,
3873 *reference;
3874
3875 PERL_UNUSED_VAR(ref);
3876 PERL_UNUSED_VAR(ix);
3877 exception=AcquireExceptionInfo();
3878 perl_exception=newSVpv("",0);
3879 package_info=(struct PackageInfo *) NULL;
3880 if (sv_isobject(ST(0)) == 0)
3881 {
3882 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3883 PackageName);
3884 goto PerlException;
3885 }
3886 reference=SvRV(ST(0));
3887 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3888 if (image == (Image *) NULL)
3889 {
3890 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3891 PackageName);
3892 goto PerlException;
3893 }
3894 package_info=ClonePackageInfo(info,exception);
3895 if (items == 2)
3896 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3897 else
3898 if (items > 2)
3899 for (i=2; i < items; i+=2)
3900 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3901 exception);
3902 (void) DisplayImages(package_info->image_info,image,exception);
3903 (void) CatchImageException(image);
3904
3905 PerlException:
3906 if (package_info != (struct PackageInfo *) NULL)
3907 DestroyPackageInfo(package_info);
3908 InheritPerlException(exception,perl_exception);
3909 exception=DestroyExceptionInfo(exception);
3910 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3911 SvPOK_on(perl_exception);
3912 ST(0)=sv_2mortal(perl_exception);
3913 XSRETURN(1);
3914 }
3915
3916#
3917###############################################################################
3918# #
3919# #
3920# #
3921# E v a l u a t e I m a g e s #
3922# #
3923# #
3924# #
3925###############################################################################
3926#
3927#
3928void
3929EvaluateImages(ref)
3930 Image::Magick ref=NO_INIT
3931 ALIAS:
3932 EvaluateImages = 1
3933 evaluateimages = 2
3934 PPCODE:
3935 {
3936 AV
3937 *av;
3938
3939 char
3940 *attribute,
3941 *p;
3942
3943 ExceptionInfo
3944 *exception;
3945
3946 HV
3947 *hv;
3948
3949 Image
3950 *image;
3951
3952 MagickEvaluateOperator
3953 op;
3954
3955 register ssize_t
3956 i;
3957
3958 struct PackageInfo
3959 *info;
3960
3961 SV
3962 *perl_exception,
3963 *reference,
3964 *rv,
3965 *sv;
3966
3967 PERL_UNUSED_VAR(ref);
3968 PERL_UNUSED_VAR(ix);
3969 exception=AcquireExceptionInfo();
3970 perl_exception=newSVpv("",0);
3971 sv=NULL;
3972 if (sv_isobject(ST(0)) == 0)
3973 {
3974 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3975 PackageName);
3976 goto PerlException;
3977 }
3978 reference=SvRV(ST(0));
3979 hv=SvSTASH(reference);
3980 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3981 if (image == (Image *) NULL)
3982 {
3983 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3984 PackageName);
3985 goto PerlException;
3986 }
3987 op=MeanEvaluateOperator;
3988 if (items == 2)
3989 {
3990 ssize_t
3991 in;
3992
3993 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
3994 SvPV(ST(1),na));
3995 if (in < 0)
3996 {
3997 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3998 SvPV(ST(1),na));
3999 return;
4000 }
4001 op=(MagickEvaluateOperator) in;
4002 }
4003 else
4004 for (i=2; i < items; i+=2)
4005 {
4006 attribute=(char *) SvPV(ST(i-1),na);
4007 switch (*attribute)
4008 {
4009 case 'O':
4010 case 'o':
4011 {
4012 if (LocaleCompare(attribute,"operator") == 0)
4013 {
4014 ssize_t
4015 in;
4016
4017 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4018 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4019 if (in < 0)
4020 {
4021 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4022 SvPV(ST(i),na));
4023 return;
4024 }
4025 op=(MagickEvaluateOperator) in;
4026 break;
4027 }
4028 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4029 attribute);
4030 break;
4031 }
4032 default:
4033 {
4034 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4035 attribute);
4036 break;
4037 }
4038 }
4039 }
4040 image=EvaluateImages(image,op,exception);
4041 if (image == (Image *) NULL)
4042 goto PerlException;
4043 /*
4044 Create blessed Perl array for the returned image.
4045 */
4046 av=newAV();
4047 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4048 SvREFCNT_dec(av);
4049 AddImageToRegistry(sv,image);
4050 rv=newRV(sv);
4051 av_push(av,sv_bless(rv,hv));
4052 SvREFCNT_dec(sv);
4053 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004054 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4055 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004056 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4057 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004058 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004059 SetImageInfo(info->image_info,0,exception);
4060 exception=DestroyExceptionInfo(exception);
4061 SvREFCNT_dec(perl_exception);
4062 XSRETURN(1);
4063
4064 PerlException:
4065 InheritPerlException(exception,perl_exception);
4066 exception=DestroyExceptionInfo(exception);
4067 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4068 SvPOK_on(perl_exception);
4069 ST(0)=sv_2mortal(perl_exception);
4070 XSRETURN(1);
4071 }
4072
4073#
4074###############################################################################
4075# #
4076# #
4077# #
4078# F e a t u r e s #
4079# #
4080# #
4081# #
4082###############################################################################
4083#
4084#
4085void
4086Features(ref,...)
4087 Image::Magick ref=NO_INIT
4088 ALIAS:
4089 FeaturesImage = 1
4090 features = 2
4091 featuresimage = 3
4092 PPCODE:
4093 {
4094#define ChannelFeatures(channel,direction) \
4095{ \
cristy151b66d2015-04-15 10:50:31 +00004096 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004097 channel_features[channel].angular_second_moment[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].contrast[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].contrast[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].variance_sum_of_squares[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].inverse_difference_moment[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_average[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].sum_variance[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].sum_entropy[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].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].difference_variance[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].difference_entropy[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].measure_of_correlation_1[direction]); \
4131 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004132 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004133 channel_features[channel].measure_of_correlation_2[direction]); \
4134 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004135 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004136 channel_features[channel].maximum_correlation_coefficient[direction]); \
4137 PUSHs(sv_2mortal(newSVpv(message,0))); \
4138}
4139
4140 AV
4141 *av;
4142
4143 char
4144 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004145 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004146
4147 ChannelFeatures
4148 *channel_features;
4149
4150 double
4151 distance;
4152
4153 ExceptionInfo
4154 *exception;
4155
4156 Image
4157 *image;
4158
4159 register ssize_t
4160 i;
4161
4162 ssize_t
4163 count;
4164
4165 struct PackageInfo
4166 *info;
4167
4168 SV
4169 *perl_exception,
4170 *reference;
4171
4172 PERL_UNUSED_VAR(ref);
4173 PERL_UNUSED_VAR(ix);
4174 exception=AcquireExceptionInfo();
4175 perl_exception=newSVpv("",0);
4176 av=NULL;
4177 if (sv_isobject(ST(0)) == 0)
4178 {
4179 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4180 PackageName);
4181 goto PerlException;
4182 }
4183 reference=SvRV(ST(0));
4184 av=newAV();
4185 SvREFCNT_dec(av);
4186 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4187 if (image == (Image *) NULL)
4188 {
4189 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4190 PackageName);
4191 goto PerlException;
4192 }
cristy7dbd9262014-07-02 17:53:42 +00004193 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004194 for (i=2; i < items; i+=2)
4195 {
4196 attribute=(char *) SvPV(ST(i-1),na);
4197 switch (*attribute)
4198 {
4199 case 'D':
4200 case 'd':
4201 {
4202 if (LocaleCompare(attribute,"distance") == 0)
4203 {
4204 distance=StringToLong((char *) SvPV(ST(1),na));
4205 break;
4206 }
4207 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4208 attribute);
4209 break;
4210 }
4211 default:
4212 {
4213 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4214 attribute);
4215 break;
4216 }
4217 }
4218 }
4219 count=0;
4220 for ( ; image; image=image->next)
4221 {
4222 channel_features=GetImageFeatures(image,distance,exception);
4223 if (channel_features == (ChannelFeatures *) NULL)
4224 continue;
4225 count++;
cristyfcf3bdf2014-07-02 14:35:58 +00004226 EXTEND(sp,280*count);
cristy4a3ce0a2013-08-03 20:06:59 +00004227 for (i=0; i < 4; i++)
4228 {
4229 ChannelFeatures(RedChannel,i);
4230 ChannelFeatures(GreenChannel,i);
4231 ChannelFeatures(BlueChannel,i);
4232 if (image->colorspace == CMYKColorspace)
4233 ChannelFeatures(BlackChannel,i);
cristy17f11b02014-12-20 19:37:04 +00004234 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00004235 ChannelFeatures(AlphaChannel,i);
4236 }
4237 channel_features=(ChannelFeatures *)
4238 RelinquishMagickMemory(channel_features);
4239 }
4240
4241 PerlException:
4242 InheritPerlException(exception,perl_exception);
4243 exception=DestroyExceptionInfo(exception);
4244 SvREFCNT_dec(perl_exception);
4245 }
4246
4247#
4248###############################################################################
4249# #
4250# #
4251# #
4252# F l a t t e n #
4253# #
4254# #
4255# #
4256###############################################################################
4257#
4258#
4259void
4260Flatten(ref)
4261 Image::Magick ref=NO_INIT
4262 ALIAS:
4263 FlattenImage = 1
4264 flatten = 2
4265 flattenimage = 3
4266 PPCODE:
4267 {
4268 AV
4269 *av;
4270
4271 char
4272 *attribute,
4273 *p;
4274
4275 ExceptionInfo
4276 *exception;
4277
4278 HV
4279 *hv;
4280
4281 Image
4282 *image;
4283
4284 PixelInfo
4285 background_color;
4286
4287 register ssize_t
4288 i;
4289
4290 struct PackageInfo
4291 *info;
4292
4293 SV
4294 *perl_exception,
4295 *reference,
4296 *rv,
4297 *sv;
4298
4299 PERL_UNUSED_VAR(ref);
4300 PERL_UNUSED_VAR(ix);
4301 exception=AcquireExceptionInfo();
4302 perl_exception=newSVpv("",0);
4303 sv=NULL;
4304 if (sv_isobject(ST(0)) == 0)
4305 {
4306 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4307 PackageName);
4308 goto PerlException;
4309 }
4310 reference=SvRV(ST(0));
4311 hv=SvSTASH(reference);
4312 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4313 if (image == (Image *) NULL)
4314 {
4315 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4316 PackageName);
4317 goto PerlException;
4318 }
4319 background_color=image->background_color;
4320 if (items == 2)
4321 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4322 &background_color,exception);
4323 else
4324 for (i=2; i < items; i+=2)
4325 {
4326 attribute=(char *) SvPV(ST(i-1),na);
4327 switch (*attribute)
4328 {
4329 case 'B':
4330 case 'b':
4331 {
4332 if (LocaleCompare(attribute,"background") == 0)
4333 {
4334 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4335 AllCompliance,&background_color,exception);
4336 break;
4337 }
4338 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4339 attribute);
4340 break;
4341 }
4342 default:
4343 {
4344 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4345 attribute);
4346 break;
4347 }
4348 }
4349 }
4350 image->background_color=background_color;
4351 image=MergeImageLayers(image,FlattenLayer,exception);
4352 if (image == (Image *) NULL)
4353 goto PerlException;
4354 /*
4355 Create blessed Perl array for the returned image.
4356 */
4357 av=newAV();
4358 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4359 SvREFCNT_dec(av);
4360 AddImageToRegistry(sv,image);
4361 rv=newRV(sv);
4362 av_push(av,sv_bless(rv,hv));
4363 SvREFCNT_dec(sv);
4364 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004365 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4366 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004367 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4368 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004369 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004370 SetImageInfo(info->image_info,0,exception);
4371 exception=DestroyExceptionInfo(exception);
4372 SvREFCNT_dec(perl_exception);
4373 XSRETURN(1);
4374
4375 PerlException:
4376 InheritPerlException(exception,perl_exception);
4377 exception=DestroyExceptionInfo(exception);
4378 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4379 SvPOK_on(perl_exception); /* return messages in string context */
4380 ST(0)=sv_2mortal(perl_exception);
4381 XSRETURN(1);
4382 }
4383
4384#
4385###############################################################################
4386# #
4387# #
4388# #
4389# F x #
4390# #
4391# #
4392# #
4393###############################################################################
4394#
4395#
4396void
4397Fx(ref,...)
4398 Image::Magick ref=NO_INIT
4399 ALIAS:
4400 FxImage = 1
4401 fx = 2
4402 fximage = 3
4403 PPCODE:
4404 {
4405 AV
4406 *av;
4407
4408 char
4409 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004410 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004411
4412 ChannelType
4413 channel,
4414 channel_mask;
4415
4416 ExceptionInfo
4417 *exception;
4418
4419 HV
4420 *hv;
4421
4422 Image
4423 *image;
4424
4425 register ssize_t
4426 i;
4427
4428 struct PackageInfo
4429 *info;
4430
4431 SV
4432 *av_reference,
4433 *perl_exception,
4434 *reference,
4435 *rv,
4436 *sv;
4437
4438 PERL_UNUSED_VAR(ref);
4439 PERL_UNUSED_VAR(ix);
4440 exception=AcquireExceptionInfo();
4441 perl_exception=newSVpv("",0);
4442 sv=NULL;
4443 attribute=NULL;
4444 av=NULL;
4445 if (sv_isobject(ST(0)) == 0)
4446 {
4447 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4448 PackageName);
4449 goto PerlException;
4450 }
4451 reference=SvRV(ST(0));
4452 hv=SvSTASH(reference);
4453 av=newAV();
4454 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4455 SvREFCNT_dec(av);
4456 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4457 if (image == (Image *) NULL)
4458 {
4459 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4460 PackageName);
4461 goto PerlException;
4462 }
4463 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4464 /*
4465 Get options.
4466 */
4467 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004468 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004469 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004470 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004471 else
4472 for (i=2; i < items; i+=2)
4473 {
4474 attribute=(char *) SvPV(ST(i-1),na);
4475 switch (*attribute)
4476 {
4477 case 'C':
4478 case 'c':
4479 {
4480 if (LocaleCompare(attribute,"channel") == 0)
4481 {
4482 ssize_t
4483 option;
4484
4485 option=ParseChannelOption(SvPV(ST(i),na));
4486 if (option < 0)
4487 {
4488 ThrowPerlException(exception,OptionError,
4489 "UnrecognizedType",SvPV(ST(i),na));
4490 return;
4491 }
4492 channel=(ChannelType) option;
4493 break;
4494 }
4495 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4496 attribute);
4497 break;
4498 }
4499 case 'E':
4500 case 'e':
4501 {
4502 if (LocaleCompare(attribute,"expression") == 0)
4503 {
4504 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004505 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004506 break;
4507 }
4508 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4509 attribute);
4510 break;
4511 }
4512 default:
4513 {
4514 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4515 attribute);
4516 break;
4517 }
4518 }
4519 }
4520 channel_mask=SetImageChannelMask(image,channel);
4521 image=FxImage(image,expression,exception);
4522 if (image != (Image *) NULL)
4523 (void) SetImageChannelMask(image,channel_mask);
4524 if (image == (Image *) NULL)
4525 goto PerlException;
4526 for ( ; image; image=image->next)
4527 {
4528 AddImageToRegistry(sv,image);
4529 rv=newRV(sv);
4530 av_push(av,sv_bless(rv,hv));
4531 SvREFCNT_dec(sv);
4532 }
4533 exception=DestroyExceptionInfo(exception);
4534 ST(0)=av_reference;
4535 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4536 XSRETURN(1);
4537
4538 PerlException:
4539 InheritPerlException(exception,perl_exception);
4540 exception=DestroyExceptionInfo(exception);
4541 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4542 SvPOK_on(perl_exception);
4543 ST(0)=sv_2mortal(perl_exception);
4544 XSRETURN(1);
4545 }
4546
4547#
4548###############################################################################
4549# #
4550# #
4551# #
4552# G e t #
4553# #
4554# #
4555# #
4556###############################################################################
4557#
4558#
4559void
4560Get(ref,...)
4561 Image::Magick ref=NO_INIT
4562 ALIAS:
4563 GetAttributes = 1
4564 GetAttribute = 2
4565 get = 3
4566 getattributes = 4
4567 getattribute = 5
4568 PPCODE:
4569 {
4570 char
4571 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004572 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004573
4574 const char
4575 *value;
4576
4577 ExceptionInfo
4578 *exception;
4579
4580 Image
4581 *image;
4582
4583 long
4584 j;
4585
4586 register ssize_t
4587 i;
4588
4589 struct PackageInfo
4590 *info;
4591
4592 SV
4593 *perl_exception,
4594 *reference,
4595 *s;
4596
4597 PERL_UNUSED_VAR(ref);
4598 PERL_UNUSED_VAR(ix);
4599 exception=AcquireExceptionInfo();
4600 perl_exception=newSVpv("",0);
4601 if (sv_isobject(ST(0)) == 0)
4602 {
4603 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4604 PackageName);
4605 XSRETURN_EMPTY;
4606 }
4607 reference=SvRV(ST(0));
4608 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4609 if (image == (Image *) NULL && !info)
4610 XSRETURN_EMPTY;
4611 EXTEND(sp,items);
4612 for (i=1; i < items; i++)
4613 {
4614 attribute=(char *) SvPV(ST(i),na);
4615 s=NULL;
4616 switch (*attribute)
4617 {
4618 case 'A':
4619 case 'a':
4620 {
4621 if (LocaleCompare(attribute,"adjoin") == 0)
4622 {
4623 if (info)
4624 s=newSViv((ssize_t) info->image_info->adjoin);
4625 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4626 continue;
4627 }
4628 if (LocaleCompare(attribute,"antialias") == 0)
4629 {
4630 if (info)
4631 s=newSViv((ssize_t) info->image_info->antialias);
4632 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4633 continue;
4634 }
4635 if (LocaleCompare(attribute,"area") == 0)
4636 {
4637 s=newSViv(GetMagickResource(AreaResource));
4638 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4639 continue;
4640 }
4641 if (LocaleCompare(attribute,"attenuate") == 0)
4642 {
4643 const char
4644 *value;
4645
4646 value=GetImageProperty(image,attribute,exception);
4647 if (value != (const char *) NULL)
4648 s=newSVpv(value,0);
4649 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4650 continue;
4651 }
4652 if (LocaleCompare(attribute,"authenticate") == 0)
4653 {
4654 if (info)
4655 {
4656 const char
4657 *option;
4658
4659 option=GetImageOption(info->image_info,attribute);
4660 if (option != (const char *) NULL)
4661 s=newSVpv(option,0);
4662 }
4663 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4664 continue;
4665 }
4666 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4667 attribute);
4668 break;
4669 }
4670 case 'B':
4671 case 'b':
4672 {
4673 if (LocaleCompare(attribute,"background") == 0)
4674 {
4675 if (image == (Image *) NULL)
4676 break;
cristy151b66d2015-04-15 10:50:31 +00004677 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004678 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4679 (double) image->background_color.green,
4680 (double) image->background_color.blue,
4681 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004682 s=newSVpv(color,0);
4683 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4684 continue;
4685 }
4686 if (LocaleCompare(attribute,"base-columns") == 0)
4687 {
4688 if (image != (Image *) NULL)
4689 s=newSViv((ssize_t) image->magick_columns);
4690 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4691 continue;
4692 }
4693 if (LocaleCompare(attribute,"base-filename") == 0)
4694 {
4695 if (image != (Image *) NULL)
4696 s=newSVpv(image->magick_filename,0);
4697 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4698 continue;
4699 }
4700 if (LocaleCompare(attribute,"base-height") == 0)
4701 {
4702 if (image != (Image *) NULL)
4703 s=newSViv((ssize_t) image->magick_rows);
4704 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4705 continue;
4706 }
4707 if (LocaleCompare(attribute,"base-rows") == 0)
4708 {
4709 if (image != (Image *) NULL)
4710 s=newSViv((ssize_t) image->magick_rows);
4711 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4712 continue;
4713 }
4714 if (LocaleCompare(attribute,"base-width") == 0)
4715 {
4716 if (image != (Image *) NULL)
4717 s=newSViv((ssize_t) image->magick_columns);
4718 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4719 continue;
4720 }
4721 if (LocaleCompare(attribute,"blue-primary") == 0)
4722 {
4723 if (image == (Image *) NULL)
4724 break;
cristy151b66d2015-04-15 10:50:31 +00004725 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00004726 image->chromaticity.blue_primary.x,
4727 image->chromaticity.blue_primary.y);
4728 s=newSVpv(color,0);
4729 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4730 continue;
4731 }
4732 if (LocaleCompare(attribute,"bordercolor") == 0)
4733 {
4734 if (image == (Image *) NULL)
4735 break;
cristy151b66d2015-04-15 10:50:31 +00004736 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004737 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4738 (double) image->border_color.green,
4739 (double) image->border_color.blue,
4740 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004741 s=newSVpv(color,0);
4742 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4743 continue;
4744 }
4745 if (LocaleCompare(attribute,"bounding-box") == 0)
4746 {
4747 char
cristy151b66d2015-04-15 10:50:31 +00004748 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004749
4750 RectangleInfo
4751 page;
4752
4753 if (image == (Image *) NULL)
4754 break;
4755 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004756 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004757 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4758 page.height,(double) page.x,(double) page.y);
4759 s=newSVpv(geometry,0);
4760 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4761 continue;
4762 }
4763 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4764 attribute);
4765 break;
4766 }
4767 case 'C':
4768 case 'c':
4769 {
4770 if (LocaleCompare(attribute,"class") == 0)
4771 {
4772 if (image == (Image *) NULL)
4773 break;
4774 s=newSViv(image->storage_class);
4775 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4776 image->storage_class));
4777 SvIOK_on(s);
4778 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4779 continue;
4780 }
4781 if (LocaleCompare(attribute,"clip-mask") == 0)
4782 {
4783 if (image != (Image *) NULL)
4784 {
4785 Image
4786 *mask_image;
4787
4788 SV
4789 *sv;
4790
4791 sv=NULL;
4792 if (image->read_mask == MagickFalse)
4793 ClipImage(image,exception);
4794 mask_image=GetImageMask(image,exception);
4795 if (mask_image != (Image *) NULL)
4796 {
4797 AddImageToRegistry(sv,mask_image);
4798 s=sv_bless(newRV(sv),SvSTASH(reference));
4799 }
4800 }
4801 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4802 continue;
4803 }
4804 if (LocaleCompare(attribute,"clip-path") == 0)
4805 {
4806 if (image != (Image *) NULL)
4807 {
4808 Image
4809 *mask_image;
4810
4811 SV
4812 *sv;
4813
4814 sv=NULL;
4815 if (image->read_mask != MagickFalse)
4816 ClipImage(image,exception);
4817 mask_image=GetImageMask(image,exception);
4818 if (mask_image != (Image *) NULL)
4819 {
4820 AddImageToRegistry(sv,mask_image);
4821 s=sv_bless(newRV(sv),SvSTASH(reference));
4822 }
4823 }
4824 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4825 continue;
4826 }
4827 if (LocaleCompare(attribute,"compression") == 0)
4828 {
4829 j=info ? info->image_info->compression : image ?
4830 image->compression : UndefinedCompression;
4831 if (info)
4832 if (info->image_info->compression == UndefinedCompression)
4833 j=image->compression;
4834 s=newSViv(j);
4835 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4836 j));
4837 SvIOK_on(s);
4838 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4839 continue;
4840 }
4841 if (LocaleCompare(attribute,"colorspace") == 0)
4842 {
4843 j=image ? image->colorspace : RGBColorspace;
4844 s=newSViv(j);
4845 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4846 j));
4847 SvIOK_on(s);
4848 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4849 continue;
4850 }
4851 if (LocaleCompare(attribute,"colors") == 0)
4852 {
4853 if (image != (Image *) NULL)
4854 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4855 exception));
4856 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4857 continue;
4858 }
4859 if (LocaleNCompare(attribute,"colormap",8) == 0)
4860 {
4861 int
4862 items;
4863
4864 if (image == (Image *) NULL || !image->colormap)
4865 break;
4866 j=0;
4867 items=sscanf(attribute,"%*[^[][%ld",&j);
4868 (void) items;
4869 if (j > (ssize_t) image->colors)
4870 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004871 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004872 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4873 (double) image->colormap[j].green,
4874 (double) image->colormap[j].blue,
4875 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004876 s=newSVpv(color,0);
4877 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4878 continue;
4879 }
4880 if (LocaleCompare(attribute,"columns") == 0)
4881 {
4882 if (image != (Image *) NULL)
4883 s=newSViv((ssize_t) image->columns);
4884 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4885 continue;
4886 }
4887 if (LocaleCompare(attribute,"comment") == 0)
4888 {
4889 const char
4890 *value;
4891
4892 value=GetImageProperty(image,attribute,exception);
4893 if (value != (const char *) NULL)
4894 s=newSVpv(value,0);
4895 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4896 continue;
4897 }
4898 if (LocaleCompare(attribute,"copyright") == 0)
4899 {
4900 s=newSVpv(GetMagickCopyright(),0);
4901 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4902 continue;
4903 }
4904 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4905 attribute);
4906 break;
4907 }
4908 case 'D':
4909 case 'd':
4910 {
4911 if (LocaleCompare(attribute,"density") == 0)
4912 {
4913 char
cristy151b66d2015-04-15 10:50:31 +00004914 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004915
4916 if (image == (Image *) NULL)
4917 break;
cristy151b66d2015-04-15 10:50:31 +00004918 (void) FormatLocaleString(geometry,MagickPathExtent,"%.15gx%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00004919 image->resolution.x,image->resolution.y);
4920 s=newSVpv(geometry,0);
4921 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4922 continue;
4923 }
4924 if (LocaleCompare(attribute,"delay") == 0)
4925 {
4926 if (image != (Image *) NULL)
4927 s=newSViv((ssize_t) image->delay);
4928 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4929 continue;
4930 }
4931 if (LocaleCompare(attribute,"depth") == 0)
4932 {
4933 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4934 if (image != (Image *) NULL)
4935 s=newSViv((ssize_t) GetImageDepth(image,exception));
4936 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4937 continue;
4938 }
4939 if (LocaleCompare(attribute,"directory") == 0)
4940 {
4941 if (image && image->directory)
4942 s=newSVpv(image->directory,0);
4943 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4944 continue;
4945 }
4946 if (LocaleCompare(attribute,"dispose") == 0)
4947 {
4948 if (image == (Image *) NULL)
4949 break;
4950
4951 s=newSViv(image->dispose);
4952 (void) sv_setpv(s,
4953 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
4954 SvIOK_on(s);
4955 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4956 continue;
4957 }
4958 if (LocaleCompare(attribute,"disk") == 0)
4959 {
4960 s=newSViv(GetMagickResource(DiskResource));
4961 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4962 continue;
4963 }
4964 if (LocaleCompare(attribute,"dither") == 0)
4965 {
4966 if (info)
4967 s=newSViv((ssize_t) info->image_info->dither);
4968 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4969 continue;
4970 }
4971 if (LocaleCompare(attribute,"display") == 0) /* same as server */
4972 {
4973 if (info && info->image_info->server_name)
4974 s=newSVpv(info->image_info->server_name,0);
4975 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4976 continue;
4977 }
4978 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4979 attribute);
4980 break;
4981 }
4982 case 'E':
4983 case 'e':
4984 {
4985 if (LocaleCompare(attribute,"elapsed-time") == 0)
4986 {
4987 if (image != (Image *) NULL)
4988 s=newSVnv(GetElapsedTime(&image->timer));
4989 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4990 continue;
4991 }
4992 if (LocaleCompare(attribute,"endian") == 0)
4993 {
4994 j=info ? info->image_info->endian : image ? image->endian :
4995 UndefinedEndian;
4996 s=newSViv(j);
4997 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
4998 SvIOK_on(s);
4999 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5000 continue;
5001 }
5002 if (LocaleCompare(attribute,"error") == 0)
5003 {
5004 if (image != (Image *) NULL)
5005 s=newSVnv(image->error.mean_error_per_pixel);
5006 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5007 continue;
5008 }
5009 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5010 attribute);
5011 break;
5012 }
5013 case 'F':
5014 case 'f':
5015 {
5016 if (LocaleCompare(attribute,"filesize") == 0)
5017 {
5018 if (image != (Image *) NULL)
5019 s=newSViv((ssize_t) GetBlobSize(image));
5020 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5021 continue;
5022 }
5023 if (LocaleCompare(attribute,"filename") == 0)
5024 {
5025 if (info && info->image_info->filename &&
5026 *info->image_info->filename)
5027 s=newSVpv(info->image_info->filename,0);
5028 if (image != (Image *) NULL)
5029 s=newSVpv(image->filename,0);
5030 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5031 continue;
5032 }
5033 if (LocaleCompare(attribute,"filter") == 0)
5034 {
5035 s=image ? newSViv(image->filter) : newSViv(0);
5036 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5037 image->filter));
5038 SvIOK_on(s);
5039 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5040 continue;
5041 }
5042 if (LocaleCompare(attribute,"font") == 0)
5043 {
5044 if (info && info->image_info->font)
5045 s=newSVpv(info->image_info->font,0);
5046 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5047 continue;
5048 }
5049 if (LocaleCompare(attribute,"foreground") == 0)
5050 continue;
5051 if (LocaleCompare(attribute,"format") == 0)
5052 {
5053 const MagickInfo
5054 *magick_info;
5055
5056 magick_info=(const MagickInfo *) NULL;
5057 if (info && (*info->image_info->magick != '\0'))
5058 magick_info=GetMagickInfo(info->image_info->magick,exception);
5059 if (image != (Image *) NULL)
5060 magick_info=GetMagickInfo(image->magick,exception);
5061 if ((magick_info != (const MagickInfo *) NULL) &&
5062 (*magick_info->description != '\0'))
5063 s=newSVpv((char *) magick_info->description,0);
5064 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5065 continue;
5066 }
5067 if (LocaleCompare(attribute,"fuzz") == 0)
5068 {
5069 if (info)
5070 s=newSVnv(info->image_info->fuzz);
5071 if (image != (Image *) NULL)
5072 s=newSVnv(image->fuzz);
5073 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5074 continue;
5075 }
5076 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5077 attribute);
5078 break;
5079 }
5080 case 'G':
5081 case 'g':
5082 {
5083 if (LocaleCompare(attribute,"gamma") == 0)
5084 {
5085 if (image != (Image *) NULL)
5086 s=newSVnv(image->gamma);
5087 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5088 continue;
5089 }
5090 if (LocaleCompare(attribute,"geometry") == 0)
5091 {
5092 if (image && image->geometry)
5093 s=newSVpv(image->geometry,0);
5094 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5095 continue;
5096 }
5097 if (LocaleCompare(attribute,"gravity") == 0)
5098 {
5099 s=image ? newSViv(image->gravity) : newSViv(0);
5100 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5101 image->gravity));
5102 SvIOK_on(s);
5103 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5104 continue;
5105 }
5106 if (LocaleCompare(attribute,"green-primary") == 0)
5107 {
5108 if (image == (Image *) NULL)
5109 break;
cristy151b66d2015-04-15 10:50:31 +00005110 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005111 image->chromaticity.green_primary.x,
5112 image->chromaticity.green_primary.y);
5113 s=newSVpv(color,0);
5114 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5115 continue;
5116 }
5117 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5118 attribute);
5119 break;
5120 }
5121 case 'H':
5122 case 'h':
5123 {
5124 if (LocaleCompare(attribute,"height") == 0)
5125 {
5126 if (image != (Image *) NULL)
5127 s=newSViv((ssize_t) image->rows);
5128 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5129 continue;
5130 }
5131 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5132 attribute);
5133 break;
5134 }
5135 case 'I':
5136 case 'i':
5137 {
5138 if (LocaleCompare(attribute,"icc") == 0)
5139 {
5140 if (image != (Image *) NULL)
5141 {
5142 const StringInfo
5143 *profile;
5144
5145 profile=GetImageProfile(image,"icc");
5146 if (profile != (StringInfo *) NULL)
5147 s=newSVpv((const char *) GetStringInfoDatum(profile),
5148 GetStringInfoLength(profile));
5149 }
5150 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5151 continue;
5152 }
5153 if (LocaleCompare(attribute,"icm") == 0)
5154 {
5155 if (image != (Image *) NULL)
5156 {
5157 const StringInfo
5158 *profile;
5159
5160 profile=GetImageProfile(image,"icm");
5161 if (profile != (const StringInfo *) NULL)
5162 s=newSVpv((const char *) GetStringInfoDatum(profile),
5163 GetStringInfoLength(profile));
5164 }
5165 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5166 continue;
5167 }
5168 if (LocaleCompare(attribute,"id") == 0)
5169 {
5170 if (image != (Image *) NULL)
5171 {
5172 char
cristy151b66d2015-04-15 10:50:31 +00005173 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005174
5175 MagickBooleanType
5176 status;
5177
5178 static ssize_t
5179 id = 0;
5180
cristy151b66d2015-04-15 10:50:31 +00005181 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005182 id);
5183 status=SetImageRegistry(ImageRegistryType,key,image,
5184 exception);
5185 (void) status;
5186 s=newSViv(id++);
5187 }
5188 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5189 continue;
5190 }
5191 if (LocaleNCompare(attribute,"index",5) == 0)
5192 {
5193 char
cristy151b66d2015-04-15 10:50:31 +00005194 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005195
5196 int
5197 items;
5198
5199 long
5200 x,
5201 y;
5202
5203 register const Quantum
5204 *p;
5205
5206 CacheView
5207 *image_view;
5208
5209 if (image == (Image *) NULL)
5210 break;
5211 if (image->storage_class != PseudoClass)
5212 break;
5213 x=0;
5214 y=0;
5215 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5216 (void) items;
5217 image_view=AcquireVirtualCacheView(image,exception);
5218 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5219 if (p != (const Quantum *) NULL)
5220 {
cristy151b66d2015-04-15 10:50:31 +00005221 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005222 GetPixelIndex(image,p));
5223 s=newSVpv(name,0);
5224 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5225 }
5226 image_view=DestroyCacheView(image_view);
5227 continue;
5228 }
5229 if (LocaleCompare(attribute,"iptc") == 0)
5230 {
5231 if (image != (Image *) NULL)
5232 {
5233 const StringInfo
5234 *profile;
5235
5236 profile=GetImageProfile(image,"iptc");
5237 if (profile != (const StringInfo *) NULL)
5238 s=newSVpv((const char *) GetStringInfoDatum(profile),
5239 GetStringInfoLength(profile));
5240 }
5241 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5242 continue;
5243 }
5244 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5245 {
5246 if (image != (Image *) NULL)
5247 s=newSViv((ssize_t) image->iterations);
5248 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5249 continue;
5250 }
5251 if (LocaleCompare(attribute,"interlace") == 0)
5252 {
5253 j=info ? info->image_info->interlace : image ? image->interlace :
5254 UndefinedInterlace;
5255 s=newSViv(j);
5256 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5257 j));
5258 SvIOK_on(s);
5259 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5260 continue;
5261 }
5262 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5263 attribute);
5264 break;
5265 }
5266 case 'L':
5267 case 'l':
5268 {
5269 if (LocaleCompare(attribute,"label") == 0)
5270 {
5271 const char
5272 *value;
5273
5274 if (image == (Image *) NULL)
5275 break;
5276 value=GetImageProperty(image,"Label",exception);
5277 if (value != (const char *) NULL)
5278 s=newSVpv(value,0);
5279 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5280 continue;
5281 }
5282 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5283 {
5284 if (image != (Image *) NULL)
5285 s=newSViv((ssize_t) image->iterations);
5286 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5287 continue;
5288 }
5289 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5290 attribute);
5291 break;
5292 }
5293 case 'M':
5294 case 'm':
5295 {
5296 if (LocaleCompare(attribute,"magick") == 0)
5297 {
5298 if (info && *info->image_info->magick)
5299 s=newSVpv(info->image_info->magick,0);
5300 if (image != (Image *) NULL)
5301 s=newSVpv(image->magick,0);
5302 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5303 continue;
5304 }
5305 if (LocaleCompare(attribute,"map") == 0)
5306 {
5307 s=newSViv(GetMagickResource(MapResource));
5308 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5309 continue;
5310 }
5311 if (LocaleCompare(attribute,"maximum-error") == 0)
5312 {
5313 if (image != (Image *) NULL)
5314 s=newSVnv(image->error.normalized_maximum_error);
5315 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5316 continue;
5317 }
5318 if (LocaleCompare(attribute,"memory") == 0)
5319 {
5320 s=newSViv(GetMagickResource(MemoryResource));
5321 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5322 continue;
5323 }
5324 if (LocaleCompare(attribute,"mean-error") == 0)
5325 {
5326 if (image != (Image *) NULL)
5327 s=newSVnv(image->error.normalized_mean_error);
5328 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5329 continue;
5330 }
5331 if (LocaleCompare(attribute,"mime") == 0)
5332 {
5333 if (info && *info->image_info->magick)
5334 s=newSVpv(MagickToMime(info->image_info->magick),0);
5335 if (image != (Image *) NULL)
5336 s=newSVpv(MagickToMime(image->magick),0);
5337 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5338 continue;
5339 }
5340 if (LocaleCompare(attribute,"mattecolor") == 0)
5341 {
5342 if (image == (Image *) NULL)
5343 break;
cristy151b66d2015-04-15 10:50:31 +00005344 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005345 "%.20g,%.20g,%.20g,%.20g",(double) image->matte_color.red,
5346 (double) image->matte_color.green,
5347 (double) image->matte_color.blue,
5348 (double) image->matte_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005349 s=newSVpv(color,0);
5350 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5351 continue;
5352 }
5353 if (LocaleCompare(attribute,"matte") == 0)
5354 {
5355 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005356 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005357 1 : 0);
5358 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5359 continue;
5360 }
5361 if (LocaleCompare(attribute,"mime") == 0)
5362 {
5363 const char
5364 *magick;
5365
5366 magick=NULL;
5367 if (info && *info->image_info->magick)
5368 magick=info->image_info->magick;
5369 if (image != (Image *) NULL)
5370 magick=image->magick;
5371 if (magick)
5372 {
5373 char
5374 *mime;
5375
5376 mime=MagickToMime(magick);
5377 s=newSVpv(mime,0);
5378 mime=(char *) RelinquishMagickMemory(mime);
5379 }
5380 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5381 continue;
5382 }
5383 if (LocaleCompare(attribute,"monochrome") == 0)
5384 {
5385 if (image == (Image *) NULL)
5386 continue;
5387 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005388 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005389 s=newSViv(j);
5390 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5391 continue;
5392 }
5393 if (LocaleCompare(attribute,"montage") == 0)
5394 {
5395 if (image && image->montage)
5396 s=newSVpv(image->montage,0);
5397 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5398 continue;
5399 }
5400 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5401 attribute);
5402 break;
5403 }
5404 case 'O':
5405 case 'o':
5406 {
5407 if (LocaleCompare(attribute,"orientation") == 0)
5408 {
5409 j=info ? info->image_info->orientation : image ?
5410 image->orientation : UndefinedOrientation;
5411 s=newSViv(j);
5412 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5413 j));
5414 SvIOK_on(s);
5415 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5416 continue;
5417 }
5418 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5419 attribute);
5420 break;
5421 }
5422 case 'P':
5423 case 'p':
5424 {
5425 if (LocaleCompare(attribute,"page") == 0)
5426 {
5427 if (info && info->image_info->page)
5428 s=newSVpv(info->image_info->page,0);
5429 if (image != (Image *) NULL)
5430 {
5431 char
cristy151b66d2015-04-15 10:50:31 +00005432 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005433
cristy151b66d2015-04-15 10:50:31 +00005434 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005435 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5436 (double) image->page.height,(double) image->page.x,(double)
5437 image->page.y);
5438 s=newSVpv(geometry,0);
5439 }
5440 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5441 continue;
5442 }
5443 if (LocaleCompare(attribute,"page.x") == 0)
5444 {
5445 if (image != (Image *) NULL)
5446 s=newSViv((ssize_t) image->page.x);
5447 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5448 continue;
5449 }
5450 if (LocaleCompare(attribute,"page.y") == 0)
5451 {
5452 if (image != (Image *) NULL)
5453 s=newSViv((ssize_t) image->page.y);
5454 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5455 continue;
5456 }
5457 if (LocaleNCompare(attribute,"pixel",5) == 0)
5458 {
5459 char
cristy151b66d2015-04-15 10:50:31 +00005460 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005461
5462 int
5463 items;
5464
5465 long
5466 x,
5467 y;
5468
5469 register const Quantum
5470 *p;
5471
5472 if (image == (Image *) NULL)
5473 break;
5474 x=0;
5475 y=0;
5476 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5477 (void) items;
5478 p=GetVirtualPixels(image,x,y,1,1,exception);
5479 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005480 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005481 QuantumFormat "," QuantumFormat "," QuantumFormat,
5482 GetPixelRed(image,p),GetPixelGreen(image,p),
5483 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5484 else
cristy151b66d2015-04-15 10:50:31 +00005485 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005486 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5487 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5488 GetPixelBlue(image,p),GetPixelBlack(image,p),
5489 GetPixelAlpha(image,p));
5490 s=newSVpv(tuple,0);
5491 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5492 continue;
5493 }
5494 if (LocaleCompare(attribute,"pointsize") == 0)
5495 {
5496 if (info)
5497 s=newSViv((ssize_t) info->image_info->pointsize);
5498 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5499 continue;
5500 }
5501 if (LocaleCompare(attribute,"preview") == 0)
5502 {
5503 s=newSViv(info->image_info->preview_type);
5504 (void) sv_setpv(s,CommandOptionToMnemonic(MagickPreviewOptions,
5505 info->image_info->preview_type));
5506 SvIOK_on(s);
5507 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5508 continue;
5509 }
5510 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5511 attribute);
5512 break;
5513 }
5514 case 'Q':
5515 case 'q':
5516 {
5517 if (LocaleCompare(attribute,"quality") == 0)
5518 {
5519 if (info)
5520 s=newSViv((ssize_t) info->image_info->quality);
5521 if (image != (Image *) NULL)
5522 s=newSViv((ssize_t) image->quality);
5523 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5524 continue;
5525 }
5526 if (LocaleCompare(attribute,"quantum") == 0)
5527 {
5528 if (info)
5529 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5530 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5531 continue;
5532 }
5533 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5534 attribute);
5535 break;
5536 }
5537 case 'R':
5538 case 'r':
5539 {
5540 if (LocaleCompare(attribute,"rendering-intent") == 0)
5541 {
5542 s=newSViv(image->rendering_intent);
5543 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5544 image->rendering_intent));
5545 SvIOK_on(s);
5546 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5547 continue;
5548 }
5549 if (LocaleCompare(attribute,"red-primary") == 0)
5550 {
5551 if (image == (Image *) NULL)
5552 break;
cristy151b66d2015-04-15 10:50:31 +00005553 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005554 image->chromaticity.red_primary.x,
5555 image->chromaticity.red_primary.y);
5556 s=newSVpv(color,0);
5557 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5558 continue;
5559 }
5560 if (LocaleCompare(attribute,"rows") == 0)
5561 {
5562 if (image != (Image *) NULL)
5563 s=newSViv((ssize_t) image->rows);
5564 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5565 continue;
5566 }
5567 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5568 attribute);
5569 break;
5570 }
5571 case 'S':
5572 case 's':
5573 {
5574 if (LocaleCompare(attribute,"sampling-factor") == 0)
5575 {
5576 if (info && info->image_info->sampling_factor)
5577 s=newSVpv(info->image_info->sampling_factor,0);
5578 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5579 continue;
5580 }
5581 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5582 {
5583 if (info && info->image_info->server_name)
5584 s=newSVpv(info->image_info->server_name,0);
5585 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5586 continue;
5587 }
5588 if (LocaleCompare(attribute,"size") == 0)
5589 {
5590 if (info && info->image_info->size)
5591 s=newSVpv(info->image_info->size,0);
5592 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5593 continue;
5594 }
5595 if (LocaleCompare(attribute,"scene") == 0)
5596 {
5597 if (image != (Image *) NULL)
5598 s=newSViv((ssize_t) image->scene);
5599 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5600 continue;
5601 }
5602 if (LocaleCompare(attribute,"scenes") == 0)
5603 {
5604 if (image != (Image *) NULL)
5605 s=newSViv((ssize_t) info->image_info->number_scenes);
5606 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5607 continue;
5608 }
5609 if (LocaleCompare(attribute,"signature") == 0)
5610 {
5611 const char
5612 *value;
5613
5614 if (image == (Image *) NULL)
5615 break;
5616 (void) SignatureImage(image,exception);
5617 value=GetImageProperty(image,"Signature",exception);
5618 if (value != (const char *) NULL)
5619 s=newSVpv(value,0);
5620 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5621 continue;
5622 }
5623 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5624 attribute);
5625 break;
5626 }
5627 case 'T':
5628 case 't':
5629 {
5630 if (LocaleCompare(attribute,"taint") == 0)
5631 {
5632 if (image != (Image *) NULL)
5633 s=newSViv((ssize_t) IsTaintImage(image));
5634 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5635 continue;
5636 }
5637 if (LocaleCompare(attribute,"texture") == 0)
5638 {
5639 if (info && info->image_info->texture)
5640 s=newSVpv(info->image_info->texture,0);
5641 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5642 continue;
5643 }
5644 if (LocaleCompare(attribute,"total-ink-density") == 0)
5645 {
5646 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5647 if (image != (Image *) NULL)
5648 s=newSVnv(GetImageTotalInkDensity(image,exception));
5649 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5650 continue;
5651 }
5652 if (LocaleCompare(attribute,"transparent-color") == 0)
5653 {
5654 if (image == (Image *) NULL)
5655 break;
cristy151b66d2015-04-15 10:50:31 +00005656 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005657 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5658 (double) image->transparent_color.green,
5659 (double) image->transparent_color.blue,
5660 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005661 s=newSVpv(color,0);
5662 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5663 continue;
5664 }
5665 if (LocaleCompare(attribute,"type") == 0)
5666 {
5667 if (image == (Image *) NULL)
5668 break;
cristya26f54c2015-07-29 12:26:12 +00005669 j=(ssize_t) GetImageType(image);
cristy4a3ce0a2013-08-03 20:06:59 +00005670 s=newSViv(j);
5671 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5672 SvIOK_on(s);
5673 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5674 continue;
5675 }
5676 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5677 attribute);
5678 break;
5679 }
5680 case 'U':
5681 case 'u':
5682 {
5683 if (LocaleCompare(attribute,"units") == 0)
5684 {
5685 j=info ? info->image_info->units : image ? image->units :
5686 UndefinedResolution;
5687 if (info && (info->image_info->units == UndefinedResolution))
5688 if (image)
5689 j=image->units;
5690 if (j == UndefinedResolution)
5691 s=newSVpv("undefined units",0);
5692 else
5693 if (j == PixelsPerInchResolution)
5694 s=newSVpv("pixels / inch",0);
5695 else
5696 s=newSVpv("pixels / centimeter",0);
5697 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5698 continue;
5699 }
5700 if (LocaleCompare(attribute,"user-time") == 0)
5701 {
5702 if (image != (Image *) NULL)
5703 s=newSVnv(GetUserTime(&image->timer));
5704 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5705 continue;
5706 }
5707 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5708 attribute);
5709 break;
5710 }
5711 case 'V':
5712 case 'v':
5713 {
5714 if (LocaleCompare(attribute,"verbose") == 0)
5715 {
5716 if (info)
5717 s=newSViv((ssize_t) info->image_info->verbose);
5718 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5719 continue;
5720 }
5721 if (LocaleCompare(attribute,"version") == 0)
5722 {
5723 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5724 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5725 continue;
5726 }
5727 if (LocaleCompare(attribute,"view") == 0)
5728 {
5729 if (info && info->image_info->view)
5730 s=newSVpv(info->image_info->view,0);
5731 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5732 continue;
5733 }
5734 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5735 {
5736 if (image == (Image *) NULL)
5737 break;
5738 j=(ssize_t) GetImageVirtualPixelMethod(image);
5739 s=newSViv(j);
5740 (void) sv_setpv(s,CommandOptionToMnemonic(
5741 MagickVirtualPixelOptions,j));
5742 SvIOK_on(s);
5743 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5744 continue;
5745 }
5746 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5747 attribute);
5748 break;
5749 }
5750 case 'W':
5751 case 'w':
5752 {
5753 if (LocaleCompare(attribute,"white-point") == 0)
5754 {
5755 if (image == (Image *) NULL)
5756 break;
cristy151b66d2015-04-15 10:50:31 +00005757 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005758 image->chromaticity.white_point.x,
5759 image->chromaticity.white_point.y);
5760 s=newSVpv(color,0);
5761 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5762 continue;
5763 }
5764 if (LocaleCompare(attribute,"width") == 0)
5765 {
5766 if (image != (Image *) NULL)
5767 s=newSViv((ssize_t) image->columns);
5768 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5769 continue;
5770 }
5771 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5772 attribute);
5773 break;
5774 }
5775 case 'X':
5776 case 'x':
5777 {
Cristyc1f9f9f2016-01-05 08:19:28 -05005778 if (LocaleCompare(attribute,"xmp") == 0)
5779 {
5780 if (image != (Image *) NULL)
5781 {
5782 const StringInfo
5783 *profile;
5784
5785 profile=GetImageProfile(image,"xmp");
5786 if (profile != (StringInfo *) NULL)
5787 s=newSVpv((const char *) GetStringInfoDatum(profile),
5788 GetStringInfoLength(profile));
5789 }
5790 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5791 continue;
5792 }
cristy4a3ce0a2013-08-03 20:06:59 +00005793 if (LocaleCompare(attribute,"x-resolution") == 0)
5794 {
5795 if (image != (Image *) NULL)
5796 s=newSVnv(image->resolution.x);
5797 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5798 continue;
5799 }
5800 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5801 attribute);
5802 break;
5803 }
5804 case 'Y':
5805 case 'y':
5806 {
5807 if (LocaleCompare(attribute,"y-resolution") == 0)
5808 {
5809 if (image != (Image *) NULL)
5810 s=newSVnv(image->resolution.y);
5811 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5812 continue;
5813 }
5814 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5815 attribute);
5816 break;
5817 }
5818 default:
5819 break;
5820 }
5821 if (image == (Image *) NULL)
5822 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5823 attribute)
5824 else
5825 {
5826 value=GetImageProperty(image,attribute,exception);
5827 if (value != (const char *) NULL)
5828 {
5829 s=newSVpv(value,0);
5830 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5831 }
5832 else
5833 if (*attribute != '%')
5834 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5835 attribute)
5836 else
5837 {
5838 char
5839 *meta;
5840
5841 meta=InterpretImageProperties(info ? info->image_info :
5842 (ImageInfo *) NULL,image,attribute,exception);
5843 s=newSVpv(meta,0);
5844 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5845 meta=(char *) RelinquishMagickMemory(meta);
5846 }
5847 }
5848 }
5849 exception=DestroyExceptionInfo(exception);
5850 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5851 }
5852
5853#
5854###############################################################################
5855# #
5856# #
5857# #
5858# G e t A u t h e n t i c P i x e l s #
5859# #
5860# #
5861# #
5862###############################################################################
5863#
5864#
5865void *
5866GetAuthenticPixels(ref,...)
5867 Image::Magick ref = NO_INIT
5868 ALIAS:
5869 getauthenticpixels = 1
5870 GetImagePixels = 2
5871 getimagepixels = 3
5872 CODE:
5873 {
5874 char
5875 *attribute;
5876
5877 ExceptionInfo
5878 *exception;
5879
5880 Image
5881 *image;
5882
5883 RectangleInfo
5884 region;
5885
5886 ssize_t
5887 i;
5888
5889 struct PackageInfo
5890 *info;
5891
5892 SV
5893 *perl_exception,
5894 *reference;
5895
5896 void
5897 *blob = NULL;
5898
5899 PERL_UNUSED_VAR(ref);
5900 PERL_UNUSED_VAR(ix);
5901 exception=AcquireExceptionInfo();
5902 perl_exception=newSVpv("",0);
5903 if (sv_isobject(ST(0)) == 0)
5904 {
5905 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5906 PackageName);
5907 goto PerlException;
5908 }
5909 reference=SvRV(ST(0));
5910
5911 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5912 if (image == (Image *) NULL)
5913 {
5914 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5915 PackageName);
5916 goto PerlException;
5917 }
5918
5919 region.x=0;
5920 region.y=0;
5921 region.width=image->columns;
5922 region.height=1;
5923 if (items == 1)
5924 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5925 for (i=2; i < items; i+=2)
5926 {
5927 attribute=(char *) SvPV(ST(i-1),na);
5928 switch (*attribute)
5929 {
5930 case 'g':
5931 case 'G':
5932 {
5933 if (LocaleCompare(attribute,"geometry") == 0)
5934 {
5935 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5936 break;
5937 }
5938 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5939 attribute);
5940 break;
5941 }
5942 case 'H':
5943 case 'h':
5944 {
5945 if (LocaleCompare(attribute,"height") == 0)
5946 {
5947 region.height=SvIV(ST(i));
5948 continue;
5949 }
5950 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5951 attribute);
5952 break;
5953 }
5954 case 'X':
5955 case 'x':
5956 {
5957 if (LocaleCompare(attribute,"x") == 0)
5958 {
5959 region.x=SvIV(ST(i));
5960 continue;
5961 }
5962 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5963 attribute);
5964 break;
5965 }
5966 case 'Y':
5967 case 'y':
5968 {
5969 if (LocaleCompare(attribute,"y") == 0)
5970 {
5971 region.y=SvIV(ST(i));
5972 continue;
5973 }
5974 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5975 attribute);
5976 break;
5977 }
5978 case 'W':
5979 case 'w':
5980 {
5981 if (LocaleCompare(attribute,"width") == 0)
5982 {
5983 region.width=SvIV(ST(i));
5984 continue;
5985 }
5986 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5987 attribute);
5988 break;
5989 }
5990 }
5991 }
5992 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5993 region.height,exception);
5994 if (blob != (void *) NULL)
5995 goto PerlEnd;
5996
5997 PerlException:
5998 InheritPerlException(exception,perl_exception);
5999 exception=DestroyExceptionInfo(exception);
6000 SvREFCNT_dec(perl_exception); /* throw away all errors */
6001
6002 PerlEnd:
6003 RETVAL = blob;
6004 }
6005 OUTPUT:
6006 RETVAL
6007
6008#
6009###############################################################################
6010# #
6011# #
6012# #
6013# G e t V i r t u a l P i x e l s #
6014# #
6015# #
6016# #
6017###############################################################################
6018#
6019#
6020void *
6021GetVirtualPixels(ref,...)
6022 Image::Magick ref = NO_INIT
6023 ALIAS:
6024 getvirtualpixels = 1
6025 AcquireImagePixels = 2
6026 acquireimagepixels = 3
6027 CODE:
6028 {
6029 char
6030 *attribute;
6031
6032 const void
6033 *blob = NULL;
6034
6035 ExceptionInfo
6036 *exception;
6037
6038 Image
6039 *image;
6040
6041 RectangleInfo
6042 region;
6043
6044 ssize_t
6045 i;
6046
6047 struct PackageInfo
6048 *info;
6049
6050 SV
6051 *perl_exception,
6052 *reference;
6053
6054 PERL_UNUSED_VAR(ref);
6055 PERL_UNUSED_VAR(ix);
6056 exception=AcquireExceptionInfo();
6057 perl_exception=newSVpv("",0);
6058 if (sv_isobject(ST(0)) == 0)
6059 {
6060 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6061 PackageName);
6062 goto PerlException;
6063 }
6064 reference=SvRV(ST(0));
6065
6066 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6067 if (image == (Image *) NULL)
6068 {
6069 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6070 PackageName);
6071 goto PerlException;
6072 }
6073
6074 region.x=0;
6075 region.y=0;
6076 region.width=image->columns;
6077 region.height=1;
6078 if (items == 1)
6079 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6080 for (i=2; i < items; i+=2)
6081 {
6082 attribute=(char *) SvPV(ST(i-1),na);
6083 switch (*attribute)
6084 {
6085 case 'g':
6086 case 'G':
6087 {
6088 if (LocaleCompare(attribute,"geometry") == 0)
6089 {
6090 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6091 break;
6092 }
6093 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6094 attribute);
6095 break;
6096 }
6097 case 'H':
6098 case 'h':
6099 {
6100 if (LocaleCompare(attribute,"height") == 0)
6101 {
6102 region.height=SvIV(ST(i));
6103 continue;
6104 }
6105 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6106 attribute);
6107 break;
6108 }
6109 case 'X':
6110 case 'x':
6111 {
6112 if (LocaleCompare(attribute,"x") == 0)
6113 {
6114 region.x=SvIV(ST(i));
6115 continue;
6116 }
6117 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6118 attribute);
6119 break;
6120 }
6121 case 'Y':
6122 case 'y':
6123 {
6124 if (LocaleCompare(attribute,"y") == 0)
6125 {
6126 region.y=SvIV(ST(i));
6127 continue;
6128 }
6129 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6130 attribute);
6131 break;
6132 }
6133 case 'W':
6134 case 'w':
6135 {
6136 if (LocaleCompare(attribute,"width") == 0)
6137 {
6138 region.width=SvIV(ST(i));
6139 continue;
6140 }
6141 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6142 attribute);
6143 break;
6144 }
6145 }
6146 }
6147 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6148 region.height,exception);
6149 if (blob != (void *) NULL)
6150 goto PerlEnd;
6151
6152 PerlException:
6153 InheritPerlException(exception,perl_exception);
6154 exception=DestroyExceptionInfo(exception);
6155 SvREFCNT_dec(perl_exception); /* throw away all errors */
6156
6157 PerlEnd:
6158 RETVAL = (void *) blob;
6159 }
6160 OUTPUT:
6161 RETVAL
6162
6163#
6164###############################################################################
6165# #
6166# #
6167# #
6168# G e t A u t h e n t i c M e t a c o n t e n t #
6169# #
6170# #
6171# #
6172###############################################################################
6173#
6174#
6175void *
6176GetAuthenticMetacontent(ref,...)
6177 Image::Magick ref = NO_INIT
6178 ALIAS:
6179 getauthenticmetacontent = 1
6180 GetMetacontent = 2
6181 getmetacontent = 3
6182 CODE:
6183 {
6184 ExceptionInfo
6185 *exception;
6186
6187 Image
6188 *image;
6189
6190 struct PackageInfo
6191 *info;
6192
6193 SV
6194 *perl_exception,
6195 *reference;
6196
6197 void
6198 *blob = NULL;
6199
6200 PERL_UNUSED_VAR(ref);
6201 PERL_UNUSED_VAR(ix);
6202 exception=AcquireExceptionInfo();
6203 perl_exception=newSVpv("",0);
6204 if (sv_isobject(ST(0)) == 0)
6205 {
6206 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6207 PackageName);
6208 goto PerlException;
6209 }
6210 reference=SvRV(ST(0));
6211
6212 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6213 if (image == (Image *) NULL)
6214 {
6215 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6216 PackageName);
6217 goto PerlException;
6218 }
6219
6220 blob=(void *) GetAuthenticMetacontent(image);
6221 if (blob != (void *) NULL)
6222 goto PerlEnd;
6223
6224 PerlException:
6225 InheritPerlException(exception,perl_exception);
6226 exception=DestroyExceptionInfo(exception);
6227 SvREFCNT_dec(perl_exception); /* throw away all errors */
6228
6229 PerlEnd:
6230 RETVAL = blob;
6231 }
6232 OUTPUT:
6233 RETVAL
6234
6235#
6236###############################################################################
6237# #
6238# #
6239# #
6240# G e t V i r t u a l M e t a c o n t e n t #
6241# #
6242# #
6243# #
6244###############################################################################
6245#
6246#
6247void *
6248GetVirtualMetacontent(ref,...)
6249 Image::Magick ref = NO_INIT
6250 ALIAS:
6251 getvirtualmetacontent = 1
6252 CODE:
6253 {
6254 ExceptionInfo
6255 *exception;
6256
6257 Image
6258 *image;
6259
6260 struct PackageInfo
6261 *info;
6262
6263 SV
6264 *perl_exception,
6265 *reference;
6266
6267 void
6268 *blob = NULL;
6269
6270 PERL_UNUSED_VAR(ref);
6271 PERL_UNUSED_VAR(ix);
6272 exception=AcquireExceptionInfo();
6273 perl_exception=newSVpv("",0);
6274 if (sv_isobject(ST(0)) == 0)
6275 {
6276 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6277 PackageName);
6278 goto PerlException;
6279 }
6280 reference=SvRV(ST(0));
6281
6282 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6283 if (image == (Image *) NULL)
6284 {
6285 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6286 PackageName);
6287 goto PerlException;
6288 }
6289
6290 blob=(void *) GetVirtualMetacontent(image);
6291 if (blob != (void *) NULL)
6292 goto PerlEnd;
6293
6294 PerlException:
6295 InheritPerlException(exception,perl_exception);
6296 exception=DestroyExceptionInfo(exception);
6297 SvREFCNT_dec(perl_exception); /* throw away all errors */
6298
6299 PerlEnd:
6300 RETVAL = blob;
6301 }
6302 OUTPUT:
6303 RETVAL
6304
6305#
6306###############################################################################
6307# #
6308# #
6309# #
6310# H i s t o g r a m #
6311# #
6312# #
6313# #
6314###############################################################################
6315#
6316#
6317void
6318Histogram(ref,...)
6319 Image::Magick ref=NO_INIT
6320 ALIAS:
6321 HistogramImage = 1
6322 histogram = 2
6323 histogramimage = 3
6324 PPCODE:
6325 {
6326 AV
6327 *av;
6328
6329 char
cristy151b66d2015-04-15 10:50:31 +00006330 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006331
6332 PixelInfo
6333 *histogram;
6334
6335 ExceptionInfo
6336 *exception;
6337
6338 Image
6339 *image;
6340
6341 register ssize_t
6342 i;
6343
6344 ssize_t
6345 count;
6346
6347 struct PackageInfo
6348 *info;
6349
6350 SV
6351 *perl_exception,
6352 *reference;
6353
6354 size_t
6355 number_colors;
6356
6357 PERL_UNUSED_VAR(ref);
6358 PERL_UNUSED_VAR(ix);
6359 exception=AcquireExceptionInfo();
6360 perl_exception=newSVpv("",0);
6361 av=NULL;
6362 if (sv_isobject(ST(0)) == 0)
6363 {
6364 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6365 PackageName);
6366 goto PerlException;
6367 }
6368 reference=SvRV(ST(0));
6369 av=newAV();
6370 SvREFCNT_dec(av);
6371 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6372 if (image == (Image *) NULL)
6373 {
6374 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6375 PackageName);
6376 goto PerlException;
6377 }
cristy4a3ce0a2013-08-03 20:06:59 +00006378 count=0;
6379 for ( ; image; image=image->next)
6380 {
6381 histogram=GetImageHistogram(image,&number_colors,exception);
6382 if (histogram == (PixelInfo *) NULL)
6383 continue;
6384 count+=(ssize_t) number_colors;
6385 EXTEND(sp,6*count);
6386 for (i=0; i < (ssize_t) number_colors; i++)
6387 {
cristy151b66d2015-04-15 10:50:31 +00006388 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006389 histogram[i].red);
6390 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006391 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006392 histogram[i].green);
6393 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006394 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006395 histogram[i].blue);
6396 PUSHs(sv_2mortal(newSVpv(message,0)));
6397 if (image->colorspace == CMYKColorspace)
6398 {
cristy151b66d2015-04-15 10:50:31 +00006399 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006400 histogram[i].black);
6401 PUSHs(sv_2mortal(newSVpv(message,0)));
6402 }
cristy151b66d2015-04-15 10:50:31 +00006403 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006404 histogram[i].alpha);
6405 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006406 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006407 histogram[i].count);
6408 PUSHs(sv_2mortal(newSVpv(message,0)));
6409 }
6410 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6411 }
6412
6413 PerlException:
6414 InheritPerlException(exception,perl_exception);
6415 exception=DestroyExceptionInfo(exception);
6416 SvREFCNT_dec(perl_exception);
6417 }
6418
6419#
6420###############################################################################
6421# #
6422# #
6423# #
6424# G e t P i x e l #
6425# #
6426# #
6427# #
6428###############################################################################
6429#
6430#
6431void
6432GetPixel(ref,...)
6433 Image::Magick ref=NO_INIT
6434 ALIAS:
6435 getpixel = 1
6436 getPixel = 2
6437 PPCODE:
6438 {
6439 AV
6440 *av;
6441
6442 char
6443 *attribute;
6444
6445 ExceptionInfo
6446 *exception;
6447
6448 Image
6449 *image;
6450
6451 MagickBooleanType
6452 normalize;
6453
6454 RectangleInfo
6455 region;
6456
6457 register const Quantum
6458 *p;
6459
6460 register ssize_t
6461 i;
6462
6463 ssize_t
6464 option;
6465
6466 struct PackageInfo
6467 *info;
6468
6469 SV
6470 *perl_exception,
6471 *reference; /* reference is the SV* of ref=SvIV(reference) */
6472
6473 PERL_UNUSED_VAR(ref);
6474 PERL_UNUSED_VAR(ix);
6475 exception=AcquireExceptionInfo();
6476 perl_exception=newSVpv("",0);
6477 reference=SvRV(ST(0));
6478 av=(AV *) reference;
6479 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6480 exception);
6481 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6482 if (image == (Image *) NULL)
6483 {
6484 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6485 PackageName);
6486 goto PerlException;
6487 }
6488 normalize=MagickTrue;
6489 region.x=0;
6490 region.y=0;
6491 region.width=image->columns;
6492 region.height=1;
6493 if (items == 1)
6494 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6495 for (i=2; i < items; i+=2)
6496 {
6497 attribute=(char *) SvPV(ST(i-1),na);
6498 switch (*attribute)
6499 {
6500 case 'C':
6501 case 'c':
6502 {
6503 if (LocaleCompare(attribute,"channel") == 0)
6504 {
6505 ssize_t
6506 option;
6507
6508 option=ParseChannelOption(SvPV(ST(i),na));
6509 if (option < 0)
6510 {
6511 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6512 SvPV(ST(i),na));
6513 return;
6514 }
cristybcd59342015-06-07 14:07:19 +00006515 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00006516 break;
6517 }
6518 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6519 attribute);
6520 break;
6521 }
6522 case 'g':
6523 case 'G':
6524 {
6525 if (LocaleCompare(attribute,"geometry") == 0)
6526 {
6527 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6528 break;
6529 }
6530 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6531 attribute);
6532 break;
6533 }
6534 case 'N':
6535 case 'n':
6536 {
6537 if (LocaleCompare(attribute,"normalize") == 0)
6538 {
6539 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6540 SvPV(ST(i),na));
6541 if (option < 0)
6542 {
6543 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6544 SvPV(ST(i),na));
6545 break;
6546 }
6547 normalize=option != 0 ? MagickTrue : MagickFalse;
6548 break;
6549 }
6550 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6551 attribute);
6552 break;
6553 }
6554 case 'x':
6555 case 'X':
6556 {
6557 if (LocaleCompare(attribute,"x") == 0)
6558 {
6559 region.x=SvIV(ST(i));
6560 break;
6561 }
6562 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6563 attribute);
6564 break;
6565 }
6566 case 'y':
6567 case 'Y':
6568 {
6569 if (LocaleCompare(attribute,"y") == 0)
6570 {
6571 region.y=SvIV(ST(i));
6572 break;
6573 }
6574 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6575 attribute);
6576 break;
6577 }
6578 default:
6579 {
6580 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6581 attribute);
6582 break;
6583 }
6584 }
6585 }
6586 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6587 if (p == (const Quantum *) NULL)
6588 PUSHs(&sv_undef);
6589 else
6590 {
6591 double
6592 scale;
6593
6594 scale=1.0;
6595 if (normalize != MagickFalse)
6596 scale=1.0/QuantumRange;
6597 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6598 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6599 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6600 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6601 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6602 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6603 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6604 (image->colorspace == CMYKColorspace))
6605 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6606 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6607 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6608 }
6609
6610 PerlException:
6611 InheritPerlException(exception,perl_exception);
6612 exception=DestroyExceptionInfo(exception);
6613 SvREFCNT_dec(perl_exception);
6614 }
6615
6616#
6617###############################################################################
6618# #
6619# #
6620# #
6621# G e t P i x e l s #
6622# #
6623# #
6624# #
6625###############################################################################
6626#
6627#
6628void
6629GetPixels(ref,...)
6630 Image::Magick ref=NO_INIT
6631 ALIAS:
6632 getpixels = 1
6633 getPixels = 2
6634 PPCODE:
6635 {
6636 AV
6637 *av;
6638
6639 char
6640 *attribute;
6641
6642 const char
6643 *map;
6644
6645 ExceptionInfo
6646 *exception;
6647
6648 Image
6649 *image;
6650
6651 MagickBooleanType
6652 normalize,
6653 status;
6654
6655 RectangleInfo
6656 region;
6657
6658 register ssize_t
6659 i;
6660
6661 ssize_t
6662 option;
6663
6664 struct PackageInfo
6665 *info;
6666
6667 SV
6668 *perl_exception,
6669 *reference; /* reference is the SV* of ref=SvIV(reference) */
6670
6671 PERL_UNUSED_VAR(ref);
6672 PERL_UNUSED_VAR(ix);
6673 exception=AcquireExceptionInfo();
6674 perl_exception=newSVpv("",0);
6675 reference=SvRV(ST(0));
6676 av=(AV *) reference;
6677 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6678 exception);
6679 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6680 if (image == (Image *) NULL)
6681 {
6682 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6683 PackageName);
6684 goto PerlException;
6685 }
6686 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006687 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006688 map="RGBA";
6689 if (image->colorspace == CMYKColorspace)
6690 {
6691 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006692 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006693 map="CMYKA";
6694 }
6695 normalize=MagickFalse;
6696 region.x=0;
6697 region.y=0;
6698 region.width=image->columns;
6699 region.height=1;
6700 if (items == 1)
6701 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6702 for (i=2; i < items; i+=2)
6703 {
6704 attribute=(char *) SvPV(ST(i-1),na);
6705 switch (*attribute)
6706 {
6707 case 'g':
6708 case 'G':
6709 {
6710 if (LocaleCompare(attribute,"geometry") == 0)
6711 {
6712 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6713 break;
6714 }
6715 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6716 attribute);
6717 break;
6718 }
6719 case 'H':
6720 case 'h':
6721 {
6722 if (LocaleCompare(attribute,"height") == 0)
6723 {
6724 region.height=SvIV(ST(i));
6725 break;
6726 }
6727 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6728 attribute);
6729 break;
6730 }
6731 case 'M':
6732 case 'm':
6733 {
6734 if (LocaleCompare(attribute,"map") == 0)
6735 {
6736 map=SvPV(ST(i),na);
6737 break;
6738 }
6739 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6740 attribute);
6741 break;
6742 }
6743 case 'N':
6744 case 'n':
6745 {
6746 if (LocaleCompare(attribute,"normalize") == 0)
6747 {
6748 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6749 SvPV(ST(i),na));
6750 if (option < 0)
6751 {
6752 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6753 SvPV(ST(i),na));
6754 break;
6755 }
6756 normalize=option != 0 ? MagickTrue : MagickFalse;
6757 break;
6758 }
6759 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6760 attribute);
6761 break;
6762 }
6763 case 'W':
6764 case 'w':
6765 {
6766 if (LocaleCompare(attribute,"width") == 0)
6767 {
6768 region.width=SvIV(ST(i));
6769 break;
6770 }
6771 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6772 attribute);
6773 break;
6774 }
6775 case 'x':
6776 case 'X':
6777 {
6778 if (LocaleCompare(attribute,"x") == 0)
6779 {
6780 region.x=SvIV(ST(i));
6781 break;
6782 }
6783 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6784 attribute);
6785 break;
6786 }
6787 case 'y':
6788 case 'Y':
6789 {
6790 if (LocaleCompare(attribute,"y") == 0)
6791 {
6792 region.y=SvIV(ST(i));
6793 break;
6794 }
6795 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6796 attribute);
6797 break;
6798 }
6799 default:
6800 {
6801 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6802 attribute);
6803 break;
6804 }
6805 }
6806 }
6807 if (normalize != MagickFalse)
6808 {
6809 float
6810 *pixels;
6811
6812 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6813 region.height*sizeof(*pixels));
6814 if (pixels == (float *) NULL)
6815 {
6816 ThrowPerlException(exception,ResourceLimitError,
6817 "MemoryAllocationFailed",PackageName);
6818 goto PerlException;
6819 }
6820 status=ExportImagePixels(image,region.x,region.y,region.width,
6821 region.height,map,FloatPixel,pixels,exception);
6822 if (status == MagickFalse)
6823 PUSHs(&sv_undef);
6824 else
6825 {
6826 EXTEND(sp,strlen(map)*region.width*region.height);
6827 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6828 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6829 }
6830 pixels=(float *) RelinquishMagickMemory(pixels);
6831 }
6832 else
6833 {
6834 Quantum
6835 *pixels;
6836
6837 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6838 region.height*sizeof(*pixels));
6839 if (pixels == (Quantum *) NULL)
6840 {
6841 ThrowPerlException(exception,ResourceLimitError,
6842 "MemoryAllocationFailed",PackageName);
6843 goto PerlException;
6844 }
6845 status=ExportImagePixels(image,region.x,region.y,region.width,
6846 region.height,map,QuantumPixel,pixels,exception);
6847 if (status == MagickFalse)
6848 PUSHs(&sv_undef);
6849 else
6850 {
6851 EXTEND(sp,strlen(map)*region.width*region.height);
6852 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6853 PUSHs(sv_2mortal(newSViv(pixels[i])));
6854 }
6855 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6856 }
6857
6858 PerlException:
6859 InheritPerlException(exception,perl_exception);
6860 exception=DestroyExceptionInfo(exception);
6861 SvREFCNT_dec(perl_exception);
6862 }
6863
6864#
6865###############################################################################
6866# #
6867# #
6868# #
6869# I m a g e T o B l o b #
6870# #
6871# #
6872# #
6873###############################################################################
6874#
6875#
6876void
6877ImageToBlob(ref,...)
6878 Image::Magick ref=NO_INIT
6879 ALIAS:
6880 ImageToBlob = 1
6881 imagetoblob = 2
6882 toblob = 3
6883 blob = 4
6884 PPCODE:
6885 {
6886 char
cristy151b66d2015-04-15 10:50:31 +00006887 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006888
6889 ExceptionInfo
6890 *exception;
6891
6892 Image
6893 *image,
6894 *next;
6895
6896 register ssize_t
6897 i;
6898
6899 struct PackageInfo
6900 *info,
6901 *package_info;
6902
6903 size_t
6904 length;
6905
6906 ssize_t
6907 scene;
6908
6909 SV
6910 *perl_exception,
6911 *reference;
6912
6913 void
6914 *blob;
6915
6916 PERL_UNUSED_VAR(ref);
6917 PERL_UNUSED_VAR(ix);
6918 exception=AcquireExceptionInfo();
6919 perl_exception=newSVpv("",0);
6920 package_info=(struct PackageInfo *) NULL;
6921 if (sv_isobject(ST(0)) == 0)
6922 {
6923 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6924 PackageName);
6925 goto PerlException;
6926 }
6927 reference=SvRV(ST(0));
6928 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6929 if (image == (Image *) NULL)
6930 {
6931 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6932 PackageName);
6933 goto PerlException;
6934 }
6935 package_info=ClonePackageInfo(info,exception);
6936 for (i=2; i < items; i+=2)
6937 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6938 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006939 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006940 scene=0;
6941 for (next=image; next; next=next->next)
6942 {
cristy151b66d2015-04-15 10:50:31 +00006943 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006944 next->scene=scene++;
6945 }
6946 SetImageInfo(package_info->image_info,(unsigned int)
6947 GetImageListLength(image),exception);
6948 EXTEND(sp,(ssize_t) GetImageListLength(image));
6949 for ( ; image; image=image->next)
6950 {
6951 length=0;
6952 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6953 if (blob != (char *) NULL)
6954 {
6955 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6956 blob=(unsigned char *) RelinquishMagickMemory(blob);
6957 }
6958 if (package_info->image_info->adjoin)
6959 break;
6960 }
6961
6962 PerlException:
6963 if (package_info != (struct PackageInfo *) NULL)
6964 DestroyPackageInfo(package_info);
6965 InheritPerlException(exception,perl_exception);
6966 exception=DestroyExceptionInfo(exception);
6967 SvREFCNT_dec(perl_exception); /* throw away all errors */
6968 }
6969
6970#
6971###############################################################################
6972# #
6973# #
6974# #
6975# L a y e r s #
6976# #
6977# #
6978# #
6979###############################################################################
6980#
6981#
6982void
6983Layers(ref,...)
6984 Image::Magick ref=NO_INIT
6985 ALIAS:
6986 Layers = 1
6987 layers = 2
6988 OptimizeImageLayers = 3
6989 optimizelayers = 4
6990 optimizeimagelayers = 5
6991 PPCODE:
6992 {
6993 AV
6994 *av;
6995
6996 char
6997 *attribute;
6998
6999 CompositeOperator
7000 compose;
7001
7002 ExceptionInfo
7003 *exception;
7004
7005 HV
7006 *hv;
7007
7008 Image
7009 *image,
7010 *layers;
7011
7012 LayerMethod
7013 method;
7014
7015 register ssize_t
7016 i;
7017
7018 ssize_t
7019 option,
7020 sp;
7021
7022 struct PackageInfo
7023 *info;
7024
7025 SV
7026 *av_reference,
7027 *perl_exception,
7028 *reference,
7029 *rv,
7030 *sv;
7031
7032 PERL_UNUSED_VAR(ref);
7033 PERL_UNUSED_VAR(ix);
7034 exception=AcquireExceptionInfo();
7035 perl_exception=newSVpv("",0);
7036 sv=NULL;
7037 if (sv_isobject(ST(0)) == 0)
7038 {
7039 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7040 PackageName);
7041 goto PerlException;
7042 }
7043 reference=SvRV(ST(0));
7044 hv=SvSTASH(reference);
7045 av=newAV();
7046 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7047 SvREFCNT_dec(av);
7048 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7049 if (image == (Image *) NULL)
7050 {
7051 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7052 PackageName);
7053 goto PerlException;
7054 }
7055 compose=image->compose;
7056 method=OptimizeLayer;
7057 for (i=2; i < items; i+=2)
7058 {
7059 attribute=(char *) SvPV(ST(i-1),na);
7060 switch (*attribute)
7061 {
7062 case 'C':
7063 case 'c':
7064 {
7065 if (LocaleCompare(attribute,"compose") == 0)
7066 {
7067 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7068 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7069 if (sp < 0)
7070 {
7071 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7072 SvPV(ST(i),na));
7073 break;
7074 }
7075 compose=(CompositeOperator) sp;
7076 break;
7077 }
7078 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7079 attribute);
7080 break;
7081 }
7082 case 'M':
7083 case 'm':
7084 {
7085 if (LocaleCompare(attribute,"method") == 0)
7086 {
7087 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7088 SvPV(ST(i),na));
7089 if (option < 0)
7090 {
7091 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7092 SvPV(ST(i),na));
7093 break;
7094 }
7095 method=(LayerMethod) option;
7096 break;
7097 }
7098 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7099 attribute);
7100 break;
7101 }
7102 default:
7103 {
7104 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7105 attribute);
7106 break;
7107 }
7108 }
7109 }
7110 layers=(Image *) NULL;
7111 switch (method)
7112 {
7113 case CompareAnyLayer:
7114 case CompareClearLayer:
7115 case CompareOverlayLayer:
7116 default:
7117 {
7118 layers=CompareImagesLayers(image,method,exception);
7119 break;
7120 }
7121 case MergeLayer:
7122 case FlattenLayer:
7123 case MosaicLayer:
7124 {
7125 layers=MergeImageLayers(image,method,exception);
7126 break;
7127 }
7128 case DisposeLayer:
7129 {
7130 layers=DisposeImages(image,exception);
7131 break;
7132 }
7133 case OptimizeImageLayer:
7134 {
7135 layers=OptimizeImageLayers(image,exception);
7136 break;
7137 }
7138 case OptimizePlusLayer:
7139 {
7140 layers=OptimizePlusImageLayers(image,exception);
7141 break;
7142 }
7143 case OptimizeTransLayer:
7144 {
7145 OptimizeImageTransparency(image,exception);
7146 break;
7147 }
7148 case RemoveDupsLayer:
7149 {
7150 RemoveDuplicateLayers(&image,exception);
7151 break;
7152 }
7153 case RemoveZeroLayer:
7154 {
7155 RemoveZeroDelayLayers(&image,exception);
7156 break;
7157 }
7158 case OptimizeLayer:
7159 {
7160 QuantizeInfo
7161 *quantize_info;
7162
7163 /*
7164 General Purpose, GIF Animation Optimizer.
7165 */
7166 layers=CoalesceImages(image,exception);
7167 if (layers == (Image *) NULL)
7168 break;
7169 image=layers;
7170 layers=OptimizeImageLayers(image,exception);
7171 if (layers == (Image *) NULL)
7172 break;
7173 image=DestroyImageList(image);
7174 image=layers;
7175 layers=(Image *) NULL;
7176 OptimizeImageTransparency(image,exception);
7177 quantize_info=AcquireQuantizeInfo(info->image_info);
7178 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7179 quantize_info=DestroyQuantizeInfo(quantize_info);
7180 break;
7181 }
7182 case CompositeLayer:
7183 {
7184 Image
7185 *source;
7186
7187 RectangleInfo
7188 geometry;
7189
7190 /*
7191 Split image sequence at the first 'NULL:' image.
7192 */
7193 source=image;
7194 while (source != (Image *) NULL)
7195 {
7196 source=GetNextImageInList(source);
7197 if ((source != (Image *) NULL) &&
7198 (LocaleCompare(source->magick,"NULL") == 0))
7199 break;
7200 }
7201 if (source != (Image *) NULL)
7202 {
7203 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7204 (GetNextImageInList(source) == (Image *) NULL))
7205 source=(Image *) NULL;
7206 else
7207 {
7208 /*
7209 Separate the two lists, junk the null: image.
7210 */
7211 source=SplitImageList(source->previous);
7212 DeleteImageFromList(&source);
7213 }
7214 }
7215 if (source == (Image *) NULL)
7216 {
7217 (void) ThrowMagickException(exception,GetMagickModule(),
7218 OptionError,"MissingNullSeparator","layers Composite");
7219 break;
7220 }
7221 /*
7222 Adjust offset with gravity and virtual canvas.
7223 */
7224 SetGeometry(image,&geometry);
7225 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7226 geometry.width=source->page.width != 0 ? source->page.width :
7227 source->columns;
7228 geometry.height=source->page.height != 0 ? source->page.height :
7229 source->rows;
7230 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7231 image->columns,image->page.height != 0 ? image->page.height :
7232 image->rows,image->gravity,&geometry);
7233 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7234 source=DestroyImageList(source);
7235 break;
7236 }
7237 }
7238 if (layers != (Image *) NULL)
7239 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007240 else
7241 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007242 if (image == (Image *) NULL)
7243 goto PerlException;
7244 for ( ; image; image=image->next)
7245 {
7246 AddImageToRegistry(sv,image);
7247 rv=newRV(sv);
7248 av_push(av,sv_bless(rv,hv));
7249 SvREFCNT_dec(sv);
7250 }
7251 exception=DestroyExceptionInfo(exception);
7252 ST(0)=av_reference;
7253 SvREFCNT_dec(perl_exception);
7254 XSRETURN(1);
7255
7256 PerlException:
7257 InheritPerlException(exception,perl_exception);
7258 exception=DestroyExceptionInfo(exception);
7259 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7260 SvPOK_on(perl_exception);
7261 ST(0)=sv_2mortal(perl_exception);
7262 XSRETURN(1);
7263 }
7264
7265#
7266###############################################################################
7267# #
7268# #
7269# #
7270# M a g i c k T o M i m e #
7271# #
7272# #
7273# #
7274###############################################################################
7275#
7276#
7277SV *
7278MagickToMime(ref,name)
7279 Image::Magick ref=NO_INIT
7280 char *name
7281 ALIAS:
7282 magicktomime = 1
7283 CODE:
7284 {
7285 char
7286 *mime;
7287
7288 PERL_UNUSED_VAR(ref);
7289 PERL_UNUSED_VAR(ix);
7290 mime=MagickToMime(name);
7291 RETVAL=newSVpv(mime,0);
7292 mime=(char *) RelinquishMagickMemory(mime);
7293 }
7294 OUTPUT:
7295 RETVAL
7296
7297#
7298###############################################################################
7299# #
7300# #
7301# #
7302# M o g r i f y #
7303# #
7304# #
7305# #
7306###############################################################################
7307#
7308#
7309void
7310Mogrify(ref,...)
7311 Image::Magick ref=NO_INIT
7312 ALIAS:
7313 Comment = 1
7314 CommentImage = 2
7315 Label = 3
7316 LabelImage = 4
7317 AddNoise = 5
7318 AddNoiseImage = 6
7319 Colorize = 7
7320 ColorizeImage = 8
7321 Border = 9
7322 BorderImage = 10
7323 Blur = 11
7324 BlurImage = 12
7325 Chop = 13
7326 ChopImage = 14
7327 Crop = 15
7328 CropImage = 16
7329 Despeckle = 17
7330 DespeckleImage = 18
7331 Edge = 19
7332 EdgeImage = 20
7333 Emboss = 21
7334 EmbossImage = 22
7335 Enhance = 23
7336 EnhanceImage = 24
7337 Flip = 25
7338 FlipImage = 26
7339 Flop = 27
7340 FlopImage = 28
7341 Frame = 29
7342 FrameImage = 30
7343 Implode = 31
7344 ImplodeImage = 32
7345 Magnify = 33
7346 MagnifyImage = 34
7347 MedianFilter = 35
7348 MedianConvolveImage = 36
7349 Minify = 37
7350 MinifyImage = 38
7351 OilPaint = 39
7352 OilPaintImage = 40
7353 ReduceNoise = 41
7354 ReduceNoiseImage = 42
7355 Roll = 43
7356 RollImage = 44
7357 Rotate = 45
7358 RotateImage = 46
7359 Sample = 47
7360 SampleImage = 48
7361 Scale = 49
7362 ScaleImage = 50
7363 Shade = 51
7364 ShadeImage = 52
7365 Sharpen = 53
7366 SharpenImage = 54
7367 Shear = 55
7368 ShearImage = 56
7369 Spread = 57
7370 SpreadImage = 58
7371 Swirl = 59
7372 SwirlImage = 60
7373 Resize = 61
7374 ResizeImage = 62
7375 Zoom = 63
7376 ZoomImage = 64
7377 Annotate = 65
7378 AnnotateImage = 66
7379 ColorFloodfill = 67
7380 ColorFloodfillImage= 68
7381 Composite = 69
7382 CompositeImage = 70
7383 Contrast = 71
7384 ContrastImage = 72
7385 CycleColormap = 73
7386 CycleColormapImage = 74
7387 Draw = 75
7388 DrawImage = 76
7389 Equalize = 77
7390 EqualizeImage = 78
7391 Gamma = 79
7392 GammaImage = 80
7393 Map = 81
7394 MapImage = 82
7395 MatteFloodfill = 83
7396 MatteFloodfillImage= 84
7397 Modulate = 85
7398 ModulateImage = 86
7399 Negate = 87
7400 NegateImage = 88
7401 Normalize = 89
7402 NormalizeImage = 90
7403 NumberColors = 91
7404 NumberColorsImage = 92
7405 Opaque = 93
7406 OpaqueImage = 94
7407 Quantize = 95
7408 QuantizeImage = 96
7409 Raise = 97
7410 RaiseImage = 98
7411 Segment = 99
7412 SegmentImage = 100
7413 Signature = 101
7414 SignatureImage = 102
7415 Solarize = 103
7416 SolarizeImage = 104
7417 Sync = 105
7418 SyncImage = 106
7419 Texture = 107
7420 TextureImage = 108
7421 Evaluate = 109
7422 EvaluateImage = 110
7423 Transparent = 111
7424 TransparentImage = 112
7425 Threshold = 113
7426 ThresholdImage = 114
7427 Charcoal = 115
7428 CharcoalImage = 116
7429 Trim = 117
7430 TrimImage = 118
7431 Wave = 119
7432 WaveImage = 120
7433 Separate = 121
7434 SeparateImage = 122
7435 Stereo = 125
7436 StereoImage = 126
7437 Stegano = 127
7438 SteganoImage = 128
7439 Deconstruct = 129
7440 DeconstructImage = 130
7441 GaussianBlur = 131
7442 GaussianBlurImage = 132
7443 Convolve = 133
7444 ConvolveImage = 134
7445 Profile = 135
7446 ProfileImage = 136
7447 UnsharpMask = 137
7448 UnsharpMaskImage = 138
7449 MotionBlur = 139
7450 MotionBlurImage = 140
7451 OrderedDither = 141
7452 OrderedDitherImage = 142
7453 Shave = 143
7454 ShaveImage = 144
7455 Level = 145
7456 LevelImage = 146
7457 Clip = 147
7458 ClipImage = 148
7459 AffineTransform = 149
7460 AffineTransformImage = 150
7461 Difference = 151
7462 DifferenceImage = 152
7463 AdaptiveThreshold = 153
7464 AdaptiveThresholdImage = 154
7465 Resample = 155
7466 ResampleImage = 156
7467 Describe = 157
7468 DescribeImage = 158
7469 BlackThreshold = 159
7470 BlackThresholdImage= 160
7471 WhiteThreshold = 161
7472 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007473 RotationalBlur = 163
7474 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007475 Thumbnail = 165
7476 ThumbnailImage = 166
7477 Strip = 167
7478 StripImage = 168
7479 Tint = 169
7480 TintImage = 170
7481 Channel = 171
7482 ChannelImage = 172
7483 Splice = 173
7484 SpliceImage = 174
7485 Posterize = 175
7486 PosterizeImage = 176
7487 Shadow = 177
7488 ShadowImage = 178
7489 Identify = 179
7490 IdentifyImage = 180
7491 SepiaTone = 181
7492 SepiaToneImage = 182
7493 SigmoidalContrast = 183
7494 SigmoidalContrastImage = 184
7495 Extent = 185
7496 ExtentImage = 186
7497 Vignette = 187
7498 VignetteImage = 188
7499 ContrastStretch = 189
7500 ContrastStretchImage = 190
7501 Sans0 = 191
7502 Sans0Image = 192
7503 Sans1 = 193
7504 Sans1Image = 194
7505 AdaptiveSharpen = 195
7506 AdaptiveSharpenImage = 196
7507 Transpose = 197
7508 TransposeImage = 198
7509 Transverse = 199
7510 TransverseImage = 200
7511 AutoOrient = 201
7512 AutoOrientImage = 202
7513 AdaptiveBlur = 203
7514 AdaptiveBlurImage = 204
7515 Sketch = 205
7516 SketchImage = 206
7517 UniqueColors = 207
7518 UniqueColorsImage = 208
7519 AdaptiveResize = 209
7520 AdaptiveResizeImage= 210
7521 ClipMask = 211
7522 ClipMaskImage = 212
7523 LinearStretch = 213
7524 LinearStretchImage = 214
7525 ColorMatrix = 215
7526 ColorMatrixImage = 216
7527 Mask = 217
7528 MaskImage = 218
7529 Polaroid = 219
7530 PolaroidImage = 220
7531 FloodfillPaint = 221
7532 FloodfillPaintImage= 222
7533 Distort = 223
7534 DistortImage = 224
7535 Clut = 225
7536 ClutImage = 226
7537 LiquidRescale = 227
7538 LiquidRescaleImage = 228
7539 Encipher = 229
7540 EncipherImage = 230
7541 Decipher = 231
7542 DecipherImage = 232
7543 Deskew = 233
7544 DeskewImage = 234
7545 Remap = 235
7546 RemapImage = 236
7547 SparseColor = 237
7548 SparseColorImage = 238
7549 Function = 239
7550 FunctionImage = 240
7551 SelectiveBlur = 241
7552 SelectiveBlurImage = 242
7553 HaldClut = 243
7554 HaldClutImage = 244
7555 BlueShift = 245
7556 BlueShiftImage = 246
7557 ForwardFourierTransform = 247
7558 ForwardFourierTransformImage = 248
7559 InverseFourierTransform = 249
7560 InverseFourierTransformImage = 250
7561 ColorDecisionList = 251
7562 ColorDecisionListImage = 252
7563 AutoGamma = 253
7564 AutoGammaImage = 254
7565 AutoLevel = 255
7566 AutoLevelImage = 256
7567 LevelColors = 257
7568 LevelImageColors = 258
7569 Clamp = 259
7570 ClampImage = 260
7571 BrightnessContrast = 261
7572 BrightnessContrastImage = 262
7573 Morphology = 263
7574 MorphologyImage = 264
7575 Color = 265
7576 ColorImage = 266
7577 Mode = 267
7578 ModeImage = 268
7579 Statistic = 269
7580 StatisticImage = 270
7581 Perceptible = 271
7582 PerceptibleImage = 272
7583 Poly = 273
7584 PolyImage = 274
7585 Grayscale = 275
7586 GrayscaleImage = 276
cristy4ceadb82014-03-29 15:30:43 +00007587 CannyEdge = 278
7588 CannyEdgeImage = 279
cristy2fc10e52014-04-26 14:13:53 +00007589 HoughLine = 280
7590 HoughLineImage = 281
7591 MeanShift = 282
7592 MeanShiftImage = 283
cristy3b207f82014-09-27 14:21:20 +00007593 Kuwahara = 284
7594 KuwaharaImage = 285
cristy6e0b3bc2014-10-19 17:51:42 +00007595 ConnectedComponent = 286
7596 ConnectedComponentImage = 287
cristy0b94b392015-06-22 18:56:37 +00007597 CopyPixels = 288
7598 CopyImagePixels = 289
cristy4a3ce0a2013-08-03 20:06:59 +00007599 MogrifyRegion = 666
7600 PPCODE:
7601 {
7602 AffineMatrix
7603 affine,
7604 current;
7605
7606 char
7607 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007608 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007609
7610 ChannelType
7611 channel,
7612 channel_mask;
7613
7614 CompositeOperator
7615 compose;
7616
7617 const char
7618 *attribute,
7619 *value;
7620
7621 double
7622 angle;
7623
7624 ExceptionInfo
7625 *exception;
7626
7627 GeometryInfo
7628 geometry_info;
7629
7630 Image
7631 *image,
7632 *next,
7633 *region_image;
7634
7635 MagickBooleanType
7636 status;
7637
7638 MagickStatusType
7639 flags;
7640
7641 PixelInfo
7642 fill_color;
7643
7644 RectangleInfo
7645 geometry,
7646 region_info;
7647
7648 register ssize_t
7649 i;
7650
7651 ssize_t
7652 base,
7653 j,
7654 number_images;
7655
7656 struct Methods
7657 *rp;
7658
7659 struct PackageInfo
7660 *info;
7661
7662 SV
7663 *perl_exception,
7664 **pv,
7665 *reference,
7666 **reference_vector;
7667
7668 struct ArgumentList
7669 argument_list[MaxArguments];
7670
7671 PERL_UNUSED_VAR(ref);
7672 PERL_UNUSED_VAR(ix);
7673 exception=AcquireExceptionInfo();
7674 perl_exception=newSVpv("",0);
7675 reference_vector=NULL;
7676 region_image=NULL;
7677 number_images=0;
7678 base=2;
7679 if (sv_isobject(ST(0)) == 0)
7680 {
7681 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7682 PackageName);
7683 goto PerlException;
7684 }
7685 reference=SvRV(ST(0));
7686 region_info.width=0;
7687 region_info.height=0;
7688 region_info.x=0;
7689 region_info.y=0;
7690 region_image=(Image *) NULL;
7691 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7692 if (ix && (ix != 666))
7693 {
7694 /*
7695 Called as Method(...)
7696 */
7697 ix=(ix+1)/2;
7698 rp=(&Methods[ix-1]);
7699 attribute=rp->name;
7700 }
7701 else
7702 {
7703 /*
7704 Called as Mogrify("Method",...)
7705 */
7706 attribute=(char *) SvPV(ST(1),na);
7707 if (ix)
7708 {
7709 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7710 attribute=(char *) SvPV(ST(2),na);
7711 base++;
7712 }
7713 for (rp=Methods; ; rp++)
7714 {
7715 if (rp >= EndOf(Methods))
7716 {
7717 ThrowPerlException(exception,OptionError,
7718 "UnrecognizedPerlMagickMethod",attribute);
7719 goto PerlException;
7720 }
7721 if (strEQcase(attribute,rp->name))
7722 break;
7723 }
7724 ix=rp-Methods+1;
7725 base++;
7726 }
7727 if (image == (Image *) NULL)
7728 {
7729 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7730 goto PerlException;
7731 }
7732 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7733 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7734 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7735 {
7736 Arguments
7737 *pp,
7738 *qq;
7739
7740 ssize_t
7741 ssize_test;
7742
7743 struct ArgumentList
7744 *al;
7745
7746 SV
7747 *sv;
7748
7749 sv=NULL;
7750 ssize_test=0;
7751 pp=(Arguments *) NULL;
7752 qq=rp->arguments;
7753 if (i == items)
7754 {
7755 pp=rp->arguments,
7756 sv=ST(i-1);
7757 }
7758 else
7759 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7760 {
7761 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7762 break;
7763 if (strEQcase(attribute,qq->method) > ssize_test)
7764 {
7765 pp=qq;
7766 ssize_test=strEQcase(attribute,qq->method);
7767 }
7768 }
7769 if (pp == (Arguments *) NULL)
7770 {
7771 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7772 attribute);
7773 goto continue_outer_loop;
7774 }
7775 al=(&argument_list[pp-rp->arguments]);
7776 switch (pp->type)
7777 {
7778 case ArrayReference:
7779 {
7780 if (SvTYPE(sv) != SVt_RV)
7781 {
cristy151b66d2015-04-15 10:50:31 +00007782 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007783 "invalid %.60s value",pp->method);
7784 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7785 goto continue_outer_loop;
7786 }
7787 al->array_reference=SvRV(sv);
7788 break;
7789 }
7790 case RealReference:
7791 {
7792 al->real_reference=SvNV(sv);
7793 break;
7794 }
7795 case FileReference:
7796 {
7797 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7798 break;
7799 }
7800 case ImageReference:
7801 {
7802 if (!sv_isobject(sv) ||
7803 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7804 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7805 {
7806 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7807 PackageName);
7808 goto PerlException;
7809 }
7810 break;
7811 }
7812 case IntegerReference:
7813 {
7814 al->integer_reference=SvIV(sv);
7815 break;
7816 }
7817 case StringReference:
7818 {
7819 al->string_reference=(char *) SvPV(sv,al->length);
7820 if (sv_isobject(sv))
7821 al->image_reference=SetupList(aTHX_ SvRV(sv),
7822 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7823 break;
7824 }
7825 default:
7826 {
7827 /*
7828 Is a string; look up name.
7829 */
7830 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7831 {
7832 al->string_reference=(char *) SvPV(sv,al->length);
7833 al->integer_reference=(-1);
7834 break;
7835 }
7836 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7837 MagickFalse,SvPV(sv,na));
7838 if (pp->type == MagickChannelOptions)
7839 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7840 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7841 {
cristy151b66d2015-04-15 10:50:31 +00007842 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007843 "invalid %.60s value",pp->method);
7844 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7845 goto continue_outer_loop;
7846 }
7847 break;
7848 }
7849 }
7850 attribute_flag[pp-rp->arguments]++;
7851 continue_outer_loop: ;
7852 }
7853 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7854 pv=reference_vector;
7855 SetGeometryInfo(&geometry_info);
7856 channel=DefaultChannels;
7857 for (next=image; next; next=next->next)
7858 {
7859 image=next;
7860 SetGeometry(image,&geometry);
7861 if ((region_info.width*region_info.height) != 0)
7862 {
7863 region_image=image;
7864 image=CropImage(image,&region_info,exception);
7865 }
7866 switch (ix)
7867 {
7868 default:
7869 {
cristy151b66d2015-04-15 10:50:31 +00007870 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007871 ThrowPerlException(exception,OptionError,
7872 "UnrecognizedPerlMagickMethod",message);
7873 goto PerlException;
7874 }
7875 case 1: /* Comment */
7876 {
7877 if (attribute_flag[0] == 0)
7878 argument_list[0].string_reference=(char *) NULL;
7879 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7880 info ? info->image_info : (ImageInfo *) NULL,image,
7881 argument_list[0].string_reference,exception),exception);
7882 break;
7883 }
7884 case 2: /* Label */
7885 {
7886 if (attribute_flag[0] == 0)
7887 argument_list[0].string_reference=(char *) NULL;
7888 (void) SetImageProperty(image,"label",InterpretImageProperties(
7889 info ? info->image_info : (ImageInfo *) NULL,image,
7890 argument_list[0].string_reference,exception),exception);
7891 break;
7892 }
7893 case 3: /* AddNoise */
7894 {
7895 double
7896 attenuate;
7897
7898 if (attribute_flag[0] == 0)
7899 argument_list[0].integer_reference=UniformNoise;
7900 attenuate=1.0;
7901 if (attribute_flag[1] != 0)
7902 attenuate=argument_list[1].real_reference;
7903 if (attribute_flag[2] != 0)
7904 channel=(ChannelType) argument_list[2].integer_reference;
7905 channel_mask=SetImageChannelMask(image,channel);
7906 image=AddNoiseImage(image,(NoiseType)
7907 argument_list[0].integer_reference,attenuate,exception);
7908 if (image != (Image *) NULL)
7909 (void) SetImageChannelMask(image,channel_mask);
7910 break;
7911 }
7912 case 4: /* Colorize */
7913 {
7914 PixelInfo
7915 target;
7916
7917 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7918 0,0,&target,exception);
7919 if (attribute_flag[0] != 0)
7920 (void) QueryColorCompliance(argument_list[0].string_reference,
7921 AllCompliance,&target,exception);
7922 if (attribute_flag[1] == 0)
7923 argument_list[1].string_reference="100%";
7924 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7925 exception);
7926 break;
7927 }
7928 case 5: /* Border */
7929 {
7930 CompositeOperator
7931 compose;
7932
7933 geometry.width=0;
7934 geometry.height=0;
7935 if (attribute_flag[0] != 0)
7936 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7937 &geometry,exception);
7938 if (attribute_flag[1] != 0)
7939 geometry.width=argument_list[1].integer_reference;
7940 if (attribute_flag[2] != 0)
7941 geometry.height=argument_list[2].integer_reference;
7942 if (attribute_flag[3] != 0)
7943 QueryColorCompliance(argument_list[3].string_reference,
7944 AllCompliance,&image->border_color,exception);
7945 if (attribute_flag[4] != 0)
7946 QueryColorCompliance(argument_list[4].string_reference,
7947 AllCompliance,&image->border_color,exception);
7948 if (attribute_flag[5] != 0)
7949 QueryColorCompliance(argument_list[5].string_reference,
7950 AllCompliance,&image->border_color,exception);
7951 compose=image->compose;
7952 if (attribute_flag[6] != 0)
7953 compose=(CompositeOperator) argument_list[6].integer_reference;
7954 image=BorderImage(image,&geometry,compose,exception);
7955 break;
7956 }
7957 case 6: /* Blur */
7958 {
7959 if (attribute_flag[0] != 0)
7960 {
7961 flags=ParseGeometry(argument_list[0].string_reference,
7962 &geometry_info);
7963 if ((flags & SigmaValue) == 0)
7964 geometry_info.sigma=1.0;
7965 }
7966 if (attribute_flag[1] != 0)
7967 geometry_info.rho=argument_list[1].real_reference;
7968 if (attribute_flag[2] != 0)
7969 geometry_info.sigma=argument_list[2].real_reference;
7970 if (attribute_flag[3] != 0)
7971 channel=(ChannelType) argument_list[3].integer_reference;
7972 channel_mask=SetImageChannelMask(image,channel);
7973 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
7974 exception);
7975 if (image != (Image *) NULL)
7976 (void) SetImageChannelMask(image,channel_mask);
7977 break;
7978 }
7979 case 7: /* Chop */
7980 {
cristy260bd762014-08-15 12:46:34 +00007981 if (attribute_flag[5] != 0)
7982 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00007983 if (attribute_flag[0] != 0)
7984 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7985 &geometry,exception);
7986 if (attribute_flag[1] != 0)
7987 geometry.width=argument_list[1].integer_reference;
7988 if (attribute_flag[2] != 0)
7989 geometry.height=argument_list[2].integer_reference;
7990 if (attribute_flag[3] != 0)
7991 geometry.x=argument_list[3].integer_reference;
7992 if (attribute_flag[4] != 0)
7993 geometry.y=argument_list[4].integer_reference;
7994 image=ChopImage(image,&geometry,exception);
7995 break;
7996 }
7997 case 8: /* Crop */
7998 {
7999 if (attribute_flag[6] != 0)
8000 image->gravity=(GravityType) argument_list[6].integer_reference;
8001 if (attribute_flag[0] != 0)
8002 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8003 &geometry,exception);
8004 if (attribute_flag[1] != 0)
8005 geometry.width=argument_list[1].integer_reference;
8006 if (attribute_flag[2] != 0)
8007 geometry.height=argument_list[2].integer_reference;
8008 if (attribute_flag[3] != 0)
8009 geometry.x=argument_list[3].integer_reference;
8010 if (attribute_flag[4] != 0)
8011 geometry.y=argument_list[4].integer_reference;
8012 if (attribute_flag[5] != 0)
8013 image->fuzz=StringToDoubleInterval(
8014 argument_list[5].string_reference,(double) QuantumRange+1.0);
8015 image=CropImage(image,&geometry,exception);
8016 break;
8017 }
8018 case 9: /* Despeckle */
8019 {
8020 image=DespeckleImage(image,exception);
8021 break;
8022 }
8023 case 10: /* Edge */
8024 {
8025 if (attribute_flag[0] != 0)
8026 geometry_info.rho=argument_list[0].real_reference;
8027 image=EdgeImage(image,geometry_info.rho,exception);
8028 break;
8029 }
8030 case 11: /* Emboss */
8031 {
8032 if (attribute_flag[0] != 0)
8033 {
8034 flags=ParseGeometry(argument_list[0].string_reference,
8035 &geometry_info);
8036 if ((flags & SigmaValue) == 0)
8037 geometry_info.sigma=1.0;
8038 }
8039 if (attribute_flag[1] != 0)
8040 geometry_info.rho=argument_list[1].real_reference;
8041 if (attribute_flag[2] != 0)
8042 geometry_info.sigma=argument_list[2].real_reference;
8043 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8044 exception);
8045 break;
8046 }
8047 case 12: /* Enhance */
8048 {
8049 image=EnhanceImage(image,exception);
8050 break;
8051 }
8052 case 13: /* Flip */
8053 {
8054 image=FlipImage(image,exception);
8055 break;
8056 }
8057 case 14: /* Flop */
8058 {
8059 image=FlopImage(image,exception);
8060 break;
8061 }
8062 case 15: /* Frame */
8063 {
8064 CompositeOperator
8065 compose;
8066
8067 FrameInfo
8068 frame_info;
8069
8070 if (attribute_flag[0] != 0)
8071 {
8072 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8073 &geometry,exception);
8074 frame_info.width=geometry.width;
8075 frame_info.height=geometry.height;
8076 frame_info.outer_bevel=geometry.x;
8077 frame_info.inner_bevel=geometry.y;
8078 }
8079 if (attribute_flag[1] != 0)
8080 frame_info.width=argument_list[1].integer_reference;
8081 if (attribute_flag[2] != 0)
8082 frame_info.height=argument_list[2].integer_reference;
8083 if (attribute_flag[3] != 0)
8084 frame_info.inner_bevel=argument_list[3].integer_reference;
8085 if (attribute_flag[4] != 0)
8086 frame_info.outer_bevel=argument_list[4].integer_reference;
8087 if (attribute_flag[5] != 0)
8088 QueryColorCompliance(argument_list[5].string_reference,
8089 AllCompliance,&fill_color,exception);
8090 if (attribute_flag[6] != 0)
8091 QueryColorCompliance(argument_list[6].string_reference,
8092 AllCompliance,&fill_color,exception);
8093 frame_info.x=(ssize_t) frame_info.width;
8094 frame_info.y=(ssize_t) frame_info.height;
8095 frame_info.width=image->columns+2*frame_info.x;
8096 frame_info.height=image->rows+2*frame_info.y;
8097 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
8098 image->matte_color=fill_color;
8099 compose=image->compose;
8100 if (attribute_flag[7] != 0)
8101 compose=(CompositeOperator) argument_list[7].integer_reference;
8102 image=FrameImage(image,&frame_info,compose,exception);
8103 break;
8104 }
8105 case 16: /* Implode */
8106 {
8107 PixelInterpolateMethod
8108 method;
8109
8110 if (attribute_flag[0] == 0)
8111 argument_list[0].real_reference=0.5;
8112 method=UndefinedInterpolatePixel;
8113 if (attribute_flag[1] != 0)
8114 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8115 image=ImplodeImage(image,argument_list[0].real_reference,
8116 method,exception);
8117 break;
8118 }
8119 case 17: /* Magnify */
8120 {
8121 image=MagnifyImage(image,exception);
8122 break;
8123 }
8124 case 18: /* MedianFilter */
8125 {
8126 if (attribute_flag[0] != 0)
8127 {
8128 flags=ParseGeometry(argument_list[0].string_reference,
8129 &geometry_info);
8130 if ((flags & SigmaValue) == 0)
8131 geometry_info.sigma=geometry_info.rho;
8132 }
8133 if (attribute_flag[1] != 0)
8134 geometry_info.rho=argument_list[1].real_reference;
8135 if (attribute_flag[2] != 0)
8136 geometry_info.sigma=argument_list[2].real_reference;
8137 if (attribute_flag[3] != 0)
8138 channel=(ChannelType) argument_list[3].integer_reference;
8139 channel_mask=SetImageChannelMask(image,channel);
8140 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8141 (size_t) geometry_info.sigma,exception);
8142 if (image != (Image *) NULL)
8143 (void) SetImageChannelMask(image,channel_mask);
8144 break;
8145 }
8146 case 19: /* Minify */
8147 {
8148 image=MinifyImage(image,exception);
8149 break;
8150 }
8151 case 20: /* OilPaint */
8152 {
8153 if (attribute_flag[0] == 0)
8154 argument_list[0].real_reference=0.0;
8155 if (attribute_flag[1] == 0)
8156 argument_list[1].real_reference=1.0;
8157 image=OilPaintImage(image,argument_list[0].real_reference,
8158 argument_list[1].real_reference,exception);
8159 break;
8160 }
8161 case 21: /* ReduceNoise */
8162 {
8163 if (attribute_flag[0] != 0)
8164 {
8165 flags=ParseGeometry(argument_list[0].string_reference,
8166 &geometry_info);
8167 if ((flags & SigmaValue) == 0)
8168 geometry_info.sigma=1.0;
8169 }
8170 if (attribute_flag[1] != 0)
8171 geometry_info.rho=argument_list[1].real_reference;
8172 if (attribute_flag[2] != 0)
8173 geometry_info.sigma=argument_list[2].real_reference;
8174 if (attribute_flag[3] != 0)
8175 channel=(ChannelType) argument_list[3].integer_reference;
8176 channel_mask=SetImageChannelMask(image,channel);
8177 image=StatisticImage(image,NonpeakStatistic,(size_t)
8178 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8179 if (image != (Image *) NULL)
8180 (void) SetImageChannelMask(image,channel_mask);
8181 break;
8182 }
8183 case 22: /* Roll */
8184 {
8185 if (attribute_flag[0] != 0)
8186 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8187 &geometry,exception);
8188 if (attribute_flag[1] != 0)
8189 geometry.x=argument_list[1].integer_reference;
8190 if (attribute_flag[2] != 0)
8191 geometry.y=argument_list[2].integer_reference;
8192 image=RollImage(image,geometry.x,geometry.y,exception);
8193 break;
8194 }
8195 case 23: /* Rotate */
8196 {
8197 if (attribute_flag[0] == 0)
8198 argument_list[0].real_reference=90.0;
8199 if (attribute_flag[1] != 0)
8200 {
8201 QueryColorCompliance(argument_list[1].string_reference,
8202 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008203 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8204 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008205 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8206 }
8207 image=RotateImage(image,argument_list[0].real_reference,exception);
8208 break;
8209 }
8210 case 24: /* Sample */
8211 {
8212 if (attribute_flag[0] != 0)
8213 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8214 &geometry,exception);
8215 if (attribute_flag[1] != 0)
8216 geometry.width=argument_list[1].integer_reference;
8217 if (attribute_flag[2] != 0)
8218 geometry.height=argument_list[2].integer_reference;
8219 image=SampleImage(image,geometry.width,geometry.height,exception);
8220 break;
8221 }
8222 case 25: /* Scale */
8223 {
8224 if (attribute_flag[0] != 0)
8225 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8226 &geometry,exception);
8227 if (attribute_flag[1] != 0)
8228 geometry.width=argument_list[1].integer_reference;
8229 if (attribute_flag[2] != 0)
8230 geometry.height=argument_list[2].integer_reference;
8231 image=ScaleImage(image,geometry.width,geometry.height,exception);
8232 break;
8233 }
8234 case 26: /* Shade */
8235 {
8236 if (attribute_flag[0] != 0)
8237 {
8238 flags=ParseGeometry(argument_list[0].string_reference,
8239 &geometry_info);
8240 if ((flags & SigmaValue) == 0)
8241 geometry_info.sigma=0.0;
8242 }
8243 if (attribute_flag[1] != 0)
8244 geometry_info.rho=argument_list[1].real_reference;
8245 if (attribute_flag[2] != 0)
8246 geometry_info.sigma=argument_list[2].real_reference;
8247 image=ShadeImage(image,
8248 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8249 geometry_info.rho,geometry_info.sigma,exception);
8250 break;
8251 }
8252 case 27: /* Sharpen */
8253 {
8254 if (attribute_flag[0] != 0)
8255 {
8256 flags=ParseGeometry(argument_list[0].string_reference,
8257 &geometry_info);
8258 if ((flags & SigmaValue) == 0)
8259 geometry_info.sigma=1.0;
8260 }
8261 if (attribute_flag[1] != 0)
8262 geometry_info.rho=argument_list[1].real_reference;
8263 if (attribute_flag[2] != 0)
8264 geometry_info.sigma=argument_list[2].real_reference;
8265 if (attribute_flag[3] != 0)
8266 channel=(ChannelType) argument_list[3].integer_reference;
8267 channel_mask=SetImageChannelMask(image,channel);
8268 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8269 exception);
8270 if (image != (Image *) NULL)
8271 (void) SetImageChannelMask(image,channel_mask);
8272 break;
8273 }
8274 case 28: /* Shear */
8275 {
8276 if (attribute_flag[0] != 0)
8277 {
8278 flags=ParseGeometry(argument_list[0].string_reference,
8279 &geometry_info);
8280 if ((flags & SigmaValue) == 0)
8281 geometry_info.sigma=geometry_info.rho;
8282 }
8283 if (attribute_flag[1] != 0)
8284 geometry_info.rho=argument_list[1].real_reference;
8285 if (attribute_flag[2] != 0)
8286 geometry_info.sigma=argument_list[2].real_reference;
8287 if (attribute_flag[3] != 0)
8288 QueryColorCompliance(argument_list[3].string_reference,
8289 AllCompliance,&image->background_color,exception);
8290 if (attribute_flag[4] != 0)
8291 QueryColorCompliance(argument_list[4].string_reference,
8292 AllCompliance,&image->background_color,exception);
8293 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8294 exception);
8295 break;
8296 }
8297 case 29: /* Spread */
8298 {
Cristye3319c12015-08-24 07:11:48 -04008299 PixelInterpolateMethod
8300 method;
8301
cristy4a3ce0a2013-08-03 20:06:59 +00008302 if (attribute_flag[0] == 0)
8303 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008304 method=UndefinedInterpolatePixel;
8305 if (attribute_flag[1] != 0)
8306 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8307 image=SpreadImage(image,method,argument_list[0].real_reference,
8308 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008309 break;
8310 }
8311 case 30: /* Swirl */
8312 {
8313 PixelInterpolateMethod
8314 method;
8315
8316 if (attribute_flag[0] == 0)
8317 argument_list[0].real_reference=50.0;
8318 method=UndefinedInterpolatePixel;
8319 if (attribute_flag[1] != 0)
8320 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8321 image=SwirlImage(image,argument_list[0].real_reference,
8322 method,exception);
8323 break;
8324 }
8325 case 31: /* Resize */
8326 case 32: /* Zoom */
8327 {
8328 if (attribute_flag[0] != 0)
8329 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8330 &geometry,exception);
8331 if (attribute_flag[1] != 0)
8332 geometry.width=argument_list[1].integer_reference;
8333 if (attribute_flag[2] != 0)
8334 geometry.height=argument_list[2].integer_reference;
8335 if (attribute_flag[3] == 0)
8336 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8337 if (attribute_flag[4] != 0)
8338 SetImageArtifact(image,"filter:support",
8339 argument_list[4].string_reference);
8340 image=ResizeImage(image,geometry.width,geometry.height,
8341 (FilterTypes) argument_list[3].integer_reference,
8342 exception);
8343 break;
8344 }
8345 case 33: /* Annotate */
8346 {
8347 DrawInfo
8348 *draw_info;
8349
8350 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8351 (DrawInfo *) NULL);
8352 if (attribute_flag[0] != 0)
8353 {
8354 char
8355 *text;
8356
8357 text=InterpretImageProperties(info ? info->image_info :
8358 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8359 exception);
8360 (void) CloneString(&draw_info->text,text);
8361 text=DestroyString(text);
8362 }
8363 if (attribute_flag[1] != 0)
8364 (void) CloneString(&draw_info->font,
8365 argument_list[1].string_reference);
8366 if (attribute_flag[2] != 0)
8367 draw_info->pointsize=argument_list[2].real_reference;
8368 if (attribute_flag[3] != 0)
8369 (void) CloneString(&draw_info->density,
8370 argument_list[3].string_reference);
8371 if (attribute_flag[4] != 0)
8372 (void) QueryColorCompliance(argument_list[4].string_reference,
8373 AllCompliance,&draw_info->undercolor,exception);
8374 if (attribute_flag[5] != 0)
8375 {
8376 (void) QueryColorCompliance(argument_list[5].string_reference,
8377 AllCompliance,&draw_info->stroke,exception);
8378 if (argument_list[5].image_reference != (Image *) NULL)
8379 draw_info->stroke_pattern=CloneImage(
8380 argument_list[5].image_reference,0,0,MagickTrue,exception);
8381 }
8382 if (attribute_flag[6] != 0)
8383 {
8384 (void) QueryColorCompliance(argument_list[6].string_reference,
8385 AllCompliance,&draw_info->fill,exception);
8386 if (argument_list[6].image_reference != (Image *) NULL)
8387 draw_info->fill_pattern=CloneImage(
8388 argument_list[6].image_reference,0,0,MagickTrue,exception);
8389 }
8390 if (attribute_flag[7] != 0)
8391 {
8392 (void) CloneString(&draw_info->geometry,
8393 argument_list[7].string_reference);
8394 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8395 &geometry,exception);
8396 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8397 geometry_info.sigma=geometry_info.xi;
8398 }
8399 if (attribute_flag[8] != 0)
8400 (void) QueryColorCompliance(argument_list[8].string_reference,
8401 AllCompliance,&draw_info->fill,exception);
8402 if (attribute_flag[11] != 0)
8403 draw_info->gravity=(GravityType)
8404 argument_list[11].integer_reference;
8405 if (attribute_flag[25] != 0)
8406 {
8407 AV
8408 *av;
8409
8410 av=(AV *) argument_list[25].array_reference;
8411 if ((av_len(av) != 3) && (av_len(av) != 5))
8412 {
8413 ThrowPerlException(exception,OptionError,
8414 "affine matrix must have 4 or 6 elements",PackageName);
8415 goto PerlException;
8416 }
8417 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8418 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8419 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8420 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8421 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8422 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8423 {
8424 ThrowPerlException(exception,OptionError,
8425 "affine matrix is singular",PackageName);
8426 goto PerlException;
8427 }
8428 if (av_len(av) == 5)
8429 {
8430 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8431 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8432 }
8433 }
8434 for (j=12; j < 17; j++)
8435 {
8436 if (attribute_flag[j] == 0)
8437 continue;
8438 value=argument_list[j].string_reference;
8439 angle=argument_list[j].real_reference;
8440 current=draw_info->affine;
8441 GetAffineMatrix(&affine);
8442 switch (j)
8443 {
8444 case 12:
8445 {
8446 /*
8447 Translate.
8448 */
8449 flags=ParseGeometry(value,&geometry_info);
8450 affine.tx=geometry_info.xi;
8451 affine.ty=geometry_info.psi;
8452 if ((flags & PsiValue) == 0)
8453 affine.ty=affine.tx;
8454 break;
8455 }
8456 case 13:
8457 {
8458 /*
8459 Scale.
8460 */
8461 flags=ParseGeometry(value,&geometry_info);
8462 affine.sx=geometry_info.rho;
8463 affine.sy=geometry_info.sigma;
8464 if ((flags & SigmaValue) == 0)
8465 affine.sy=affine.sx;
8466 break;
8467 }
8468 case 14:
8469 {
8470 /*
8471 Rotate.
8472 */
8473 if (angle == 0.0)
8474 break;
8475 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8476 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8477 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8478 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8479 break;
8480 }
8481 case 15:
8482 {
8483 /*
8484 SkewX.
8485 */
8486 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8487 break;
8488 }
8489 case 16:
8490 {
8491 /*
8492 SkewY.
8493 */
8494 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8495 break;
8496 }
8497 }
8498 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8499 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8500 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8501 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8502 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8503 current.tx;
8504 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8505 current.ty;
8506 }
8507 if (attribute_flag[9] == 0)
8508 argument_list[9].real_reference=0.0;
8509 if (attribute_flag[10] == 0)
8510 argument_list[10].real_reference=0.0;
8511 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8512 {
8513 char
cristy151b66d2015-04-15 10:50:31 +00008514 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008515
cristy151b66d2015-04-15 10:50:31 +00008516 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008517 (double) argument_list[9].real_reference+draw_info->affine.tx,
8518 (double) argument_list[10].real_reference+draw_info->affine.ty);
8519 (void) CloneString(&draw_info->geometry,geometry);
8520 }
8521 if (attribute_flag[17] != 0)
8522 draw_info->stroke_width=argument_list[17].real_reference;
8523 if (attribute_flag[18] != 0)
8524 {
8525 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8526 MagickTrue : MagickFalse;
8527 draw_info->stroke_antialias=draw_info->text_antialias;
8528 }
8529 if (attribute_flag[19] != 0)
8530 (void) CloneString(&draw_info->family,
8531 argument_list[19].string_reference);
8532 if (attribute_flag[20] != 0)
8533 draw_info->style=(StyleType) argument_list[20].integer_reference;
8534 if (attribute_flag[21] != 0)
8535 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8536 if (attribute_flag[22] != 0)
8537 draw_info->weight=argument_list[22].integer_reference;
8538 if (attribute_flag[23] != 0)
8539 draw_info->align=(AlignType) argument_list[23].integer_reference;
8540 if (attribute_flag[24] != 0)
8541 (void) CloneString(&draw_info->encoding,
8542 argument_list[24].string_reference);
8543 if (attribute_flag[25] != 0)
8544 draw_info->fill_pattern=CloneImage(
8545 argument_list[25].image_reference,0,0,MagickTrue,exception);
8546 if (attribute_flag[26] != 0)
8547 draw_info->fill_pattern=CloneImage(
8548 argument_list[26].image_reference,0,0,MagickTrue,exception);
8549 if (attribute_flag[27] != 0)
8550 draw_info->stroke_pattern=CloneImage(
8551 argument_list[27].image_reference,0,0,MagickTrue,exception);
8552 if (attribute_flag[29] != 0)
8553 draw_info->kerning=argument_list[29].real_reference;
8554 if (attribute_flag[30] != 0)
8555 draw_info->interline_spacing=argument_list[30].real_reference;
8556 if (attribute_flag[31] != 0)
8557 draw_info->interword_spacing=argument_list[31].real_reference;
8558 if (attribute_flag[32] != 0)
8559 draw_info->direction=(DirectionType)
8560 argument_list[32].integer_reference;
8561 (void) AnnotateImage(image,draw_info,exception);
8562 draw_info=DestroyDrawInfo(draw_info);
8563 break;
8564 }
8565 case 34: /* ColorFloodfill */
8566 {
8567 DrawInfo
8568 *draw_info;
8569
8570 MagickBooleanType
8571 invert;
8572
8573 PixelInfo
8574 target;
8575
8576 draw_info=CloneDrawInfo(info ? info->image_info :
8577 (ImageInfo *) NULL,(DrawInfo *) NULL);
8578 if (attribute_flag[0] != 0)
8579 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8580 &geometry,exception);
8581 if (attribute_flag[1] != 0)
8582 geometry.x=argument_list[1].integer_reference;
8583 if (attribute_flag[2] != 0)
8584 geometry.y=argument_list[2].integer_reference;
8585 if (attribute_flag[3] != 0)
8586 (void) QueryColorCompliance(argument_list[3].string_reference,
8587 AllCompliance,&draw_info->fill,exception);
8588 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8589 geometry.x,geometry.y,&target,exception);
8590 invert=MagickFalse;
8591 if (attribute_flag[4] != 0)
8592 {
8593 QueryColorCompliance(argument_list[4].string_reference,
8594 AllCompliance,&target,exception);
8595 invert=MagickTrue;
8596 }
8597 if (attribute_flag[5] != 0)
8598 image->fuzz=StringToDoubleInterval(
8599 argument_list[5].string_reference,(double) QuantumRange+1.0);
8600 if (attribute_flag[6] != 0)
8601 invert=(MagickBooleanType) argument_list[6].integer_reference;
8602 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8603 geometry.y,invert,exception);
8604 draw_info=DestroyDrawInfo(draw_info);
8605 break;
8606 }
8607 case 35: /* Composite */
8608 {
8609 char
cristy151b66d2015-04-15 10:50:31 +00008610 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008611
8612 Image
8613 *composite_image,
8614 *rotate_image;
8615
8616 MagickBooleanType
8617 clip_to_self;
8618
8619 compose=OverCompositeOp;
8620 if (attribute_flag[0] != 0)
8621 composite_image=argument_list[0].image_reference;
8622 else
8623 {
8624 ThrowPerlException(exception,OptionError,
8625 "CompositeImageRequired",PackageName);
8626 goto PerlException;
8627 }
8628 /*
8629 Parameter Handling used for BOTH normal and tiled composition.
8630 */
8631 if (attribute_flag[1] != 0) /* compose */
8632 compose=(CompositeOperator) argument_list[1].integer_reference;
8633 if (attribute_flag[6] != 0) /* opacity */
8634 {
8635 if (compose != DissolveCompositeOp)
8636 (void) SetImageAlpha(composite_image,(Quantum)
8637 StringToDoubleInterval(argument_list[6].string_reference,
8638 (double) QuantumRange+1.0),exception);
8639 else
8640 {
8641 CacheView
8642 *composite_view;
8643
8644 double
8645 opacity;
8646
8647 MagickBooleanType
8648 sync;
8649
8650 register ssize_t
8651 x;
8652
8653 register Quantum
8654 *q;
8655
8656 ssize_t
8657 y;
8658
8659 /*
8660 Handle dissolve composite operator (patch by
8661 Kevin A. McGrail).
8662 */
8663 (void) CloneString(&image->geometry,
8664 argument_list[6].string_reference);
8665 opacity=(Quantum) StringToDoubleInterval(
8666 argument_list[6].string_reference,(double) QuantumRange+
8667 1.0);
cristy17f11b02014-12-20 19:37:04 +00008668 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008669 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8670 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8671 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8672 {
8673 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8674 composite_image->columns,1,exception);
8675 for (x=0; x < (ssize_t) composite_image->columns; x++)
8676 {
8677 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8678 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8679 q);
8680 q+=GetPixelChannels(composite_image);
8681 }
8682 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8683 if (sync == MagickFalse)
8684 break;
8685 }
8686 composite_view=DestroyCacheView(composite_view);
8687 }
8688 }
8689 if (attribute_flag[9] != 0) /* "color=>" */
8690 QueryColorCompliance(argument_list[9].string_reference,
8691 AllCompliance,&composite_image->background_color,exception);
8692 if (attribute_flag[12] != 0) /* "interpolate=>" */
8693 image->interpolate=(PixelInterpolateMethod)
8694 argument_list[12].integer_reference;
8695 if (attribute_flag[13] != 0) /* "args=>" */
8696 (void) SetImageArtifact(composite_image,"compose:args",
8697 argument_list[13].string_reference);
8698 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8699 (void) SetImageArtifact(composite_image,"compose:args",
8700 argument_list[14].string_reference);
8701 clip_to_self=MagickTrue;
8702 if (attribute_flag[15] != 0)
8703 clip_to_self=(MagickBooleanType)
8704 argument_list[15].integer_reference;
8705 /*
8706 Tiling Composition (with orthogonal rotate).
8707 */
8708 rotate_image=(Image *) NULL;
8709 if (attribute_flag[8] != 0) /* "rotate=>" */
8710 {
8711 /*
8712 Rotate image.
8713 */
8714 rotate_image=RotateImage(composite_image,
8715 argument_list[8].real_reference,exception);
8716 if (rotate_image == (Image *) NULL)
8717 break;
8718 }
8719 if ((attribute_flag[7] != 0) &&
8720 (argument_list[7].integer_reference != 0)) /* tile */
8721 {
8722 ssize_t
8723 x,
8724 y;
8725
8726 /*
8727 Tile the composite image.
8728 */
8729 if (attribute_flag[8] != 0) /* "tile=>" */
8730 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8731 "false");
8732 else
8733 (void) SetImageArtifact(composite_image,
8734 "compose:outside-overlay","false");
8735 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8736 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8737 {
8738 if (attribute_flag[8] != 0) /* rotate */
8739 (void) CompositeImage(image,rotate_image,compose,
8740 MagickTrue,x,y,exception);
8741 else
8742 (void) CompositeImage(image,composite_image,compose,
8743 MagickTrue,x,y,exception);
8744 }
8745 if (attribute_flag[8] != 0) /* rotate */
8746 rotate_image=DestroyImage(rotate_image);
8747 break;
8748 }
8749 /*
8750 Parameter Handling used used ONLY for normal composition.
8751 */
8752 if (attribute_flag[5] != 0) /* gravity */
8753 image->gravity=(GravityType) argument_list[5].integer_reference;
8754 if (attribute_flag[2] != 0) /* geometry offset */
8755 {
8756 SetGeometry(image,&geometry);
8757 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8758 &geometry);
8759 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8760 &geometry);
8761 }
8762 if (attribute_flag[3] != 0) /* x offset */
8763 geometry.x=argument_list[3].integer_reference;
8764 if (attribute_flag[4] != 0) /* y offset */
8765 geometry.y=argument_list[4].integer_reference;
8766 if (attribute_flag[10] != 0) /* mask */
8767 {
8768 if ((image->compose == DisplaceCompositeOp) ||
8769 (image->compose == DistortCompositeOp))
8770 {
8771 /*
8772 Merge Y displacement into X displacement image.
8773 */
8774 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8775 exception);
8776 (void) CompositeImage(composite_image,
8777 argument_list[10].image_reference,CopyGreenCompositeOp,
8778 MagickTrue,0,0,exception);
8779 }
8780 else
8781 {
8782 Image
8783 *mask_image;
8784
8785 /*
8786 Set a blending mask for the composition.
8787 */
8788 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8789 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008790 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008791 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008792 mask_image=DestroyImage(mask_image);
8793 }
8794 }
8795 if (attribute_flag[11] != 0) /* channel */
8796 channel=(ChannelType) argument_list[11].integer_reference;
8797 /*
8798 Composite two images (normal composition).
8799 */
cristy151b66d2015-04-15 10:50:31 +00008800 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008801 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8802 (double) composite_image->rows,(double) geometry.x,(double)
8803 geometry.y);
8804 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8805 exception);
8806 channel_mask=SetImageChannelMask(image,channel);
8807 if (attribute_flag[8] == 0) /* no rotate */
8808 CompositeImage(image,composite_image,compose,clip_to_self,
8809 geometry.x,geometry.y,exception);
8810 else
8811 {
8812 /*
8813 Position adjust rotated image then composite.
8814 */
8815 geometry.x-=(ssize_t) (rotate_image->columns-
8816 composite_image->columns)/2;
8817 geometry.y-=(ssize_t) (rotate_image->rows-
8818 composite_image->rows)/2;
8819 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8820 geometry.y,exception);
8821 rotate_image=DestroyImage(rotate_image);
8822 }
8823 if (attribute_flag[10] != 0) /* mask */
8824 {
8825 if ((image->compose == DisplaceCompositeOp) ||
8826 (image->compose == DistortCompositeOp))
8827 composite_image=DestroyImage(composite_image);
8828 else
cristy1f7ffb72015-07-29 11:07:03 +00008829 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008830 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008831 }
8832 (void) SetImageChannelMask(image,channel_mask);
8833 break;
8834 }
8835 case 36: /* Contrast */
8836 {
8837 if (attribute_flag[0] == 0)
8838 argument_list[0].integer_reference=0;
8839 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8840 MagickTrue : MagickFalse,exception);
8841 break;
8842 }
8843 case 37: /* CycleColormap */
8844 {
8845 if (attribute_flag[0] == 0)
8846 argument_list[0].integer_reference=6;
8847 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8848 exception);
8849 break;
8850 }
8851 case 38: /* Draw */
8852 {
8853 DrawInfo
8854 *draw_info;
8855
8856 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8857 (DrawInfo *) NULL);
8858 (void) CloneString(&draw_info->primitive,"point");
8859 if (attribute_flag[0] != 0)
8860 {
8861 if (argument_list[0].integer_reference < 0)
8862 (void) CloneString(&draw_info->primitive,
8863 argument_list[0].string_reference);
8864 else
8865 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8866 MagickPrimitiveOptions,argument_list[0].integer_reference));
8867 }
8868 if (attribute_flag[1] != 0)
8869 {
8870 if (LocaleCompare(draw_info->primitive,"path") == 0)
8871 {
8872 (void) ConcatenateString(&draw_info->primitive," '");
8873 ConcatenateString(&draw_info->primitive,
8874 argument_list[1].string_reference);
8875 (void) ConcatenateString(&draw_info->primitive,"'");
8876 }
8877 else
8878 {
8879 (void) ConcatenateString(&draw_info->primitive," ");
8880 ConcatenateString(&draw_info->primitive,
8881 argument_list[1].string_reference);
8882 }
8883 }
8884 if (attribute_flag[2] != 0)
8885 {
8886 (void) ConcatenateString(&draw_info->primitive," ");
8887 (void) ConcatenateString(&draw_info->primitive,
8888 CommandOptionToMnemonic(MagickMethodOptions,
8889 argument_list[2].integer_reference));
8890 }
8891 if (attribute_flag[3] != 0)
8892 {
8893 (void) QueryColorCompliance(argument_list[3].string_reference,
8894 AllCompliance,&draw_info->stroke,exception);
8895 if (argument_list[3].image_reference != (Image *) NULL)
8896 draw_info->stroke_pattern=CloneImage(
8897 argument_list[3].image_reference,0,0,MagickTrue,exception);
8898 }
8899 if (attribute_flag[4] != 0)
8900 {
8901 (void) QueryColorCompliance(argument_list[4].string_reference,
8902 AllCompliance,&draw_info->fill,exception);
8903 if (argument_list[4].image_reference != (Image *) NULL)
8904 draw_info->fill_pattern=CloneImage(
8905 argument_list[4].image_reference,0,0,MagickTrue,exception);
8906 }
8907 if (attribute_flag[5] != 0)
8908 draw_info->stroke_width=argument_list[5].real_reference;
8909 if (attribute_flag[6] != 0)
8910 (void) CloneString(&draw_info->font,
8911 argument_list[6].string_reference);
8912 if (attribute_flag[7] != 0)
8913 (void) QueryColorCompliance(argument_list[7].string_reference,
8914 AllCompliance,&draw_info->border_color,exception);
8915 if (attribute_flag[8] != 0)
8916 draw_info->affine.tx=argument_list[8].real_reference;
8917 if (attribute_flag[9] != 0)
8918 draw_info->affine.ty=argument_list[9].real_reference;
8919 if (attribute_flag[20] != 0)
8920 {
8921 AV
8922 *av;
8923
8924 av=(AV *) argument_list[20].array_reference;
8925 if ((av_len(av) != 3) && (av_len(av) != 5))
8926 {
8927 ThrowPerlException(exception,OptionError,
8928 "affine matrix must have 4 or 6 elements",PackageName);
8929 goto PerlException;
8930 }
8931 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8932 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8933 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8934 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8935 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8936 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8937 {
8938 ThrowPerlException(exception,OptionError,
8939 "affine matrix is singular",PackageName);
8940 goto PerlException;
8941 }
8942 if (av_len(av) == 5)
8943 {
8944 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8945 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8946 }
8947 }
8948 for (j=10; j < 15; j++)
8949 {
8950 if (attribute_flag[j] == 0)
8951 continue;
8952 value=argument_list[j].string_reference;
8953 angle=argument_list[j].real_reference;
8954 current=draw_info->affine;
8955 GetAffineMatrix(&affine);
8956 switch (j)
8957 {
8958 case 10:
8959 {
8960 /*
8961 Translate.
8962 */
8963 flags=ParseGeometry(value,&geometry_info);
8964 affine.tx=geometry_info.xi;
8965 affine.ty=geometry_info.psi;
8966 if ((flags & PsiValue) == 0)
8967 affine.ty=affine.tx;
8968 break;
8969 }
8970 case 11:
8971 {
8972 /*
8973 Scale.
8974 */
8975 flags=ParseGeometry(value,&geometry_info);
8976 affine.sx=geometry_info.rho;
8977 affine.sy=geometry_info.sigma;
8978 if ((flags & SigmaValue) == 0)
8979 affine.sy=affine.sx;
8980 break;
8981 }
8982 case 12:
8983 {
8984 /*
8985 Rotate.
8986 */
8987 if (angle == 0.0)
8988 break;
8989 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8990 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8991 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8992 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8993 break;
8994 }
8995 case 13:
8996 {
8997 /*
8998 SkewX.
8999 */
9000 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9001 break;
9002 }
9003 case 14:
9004 {
9005 /*
9006 SkewY.
9007 */
9008 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9009 break;
9010 }
9011 }
9012 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9013 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9014 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9015 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9016 draw_info->affine.tx=
9017 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9018 draw_info->affine.ty=
9019 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9020 }
9021 if (attribute_flag[15] != 0)
9022 draw_info->fill_pattern=CloneImage(
9023 argument_list[15].image_reference,0,0,MagickTrue,exception);
9024 if (attribute_flag[16] != 0)
9025 draw_info->pointsize=argument_list[16].real_reference;
9026 if (attribute_flag[17] != 0)
9027 {
9028 draw_info->stroke_antialias=argument_list[17].integer_reference != 0
9029 ? MagickTrue : MagickFalse;
9030 draw_info->text_antialias=draw_info->stroke_antialias;
9031 }
9032 if (attribute_flag[18] != 0)
9033 (void) CloneString(&draw_info->density,
9034 argument_list[18].string_reference);
9035 if (attribute_flag[19] != 0)
9036 draw_info->stroke_width=argument_list[19].real_reference;
9037 if (attribute_flag[21] != 0)
9038 draw_info->dash_offset=argument_list[21].real_reference;
9039 if (attribute_flag[22] != 0)
9040 {
9041 AV
9042 *av;
9043
9044 av=(AV *) argument_list[22].array_reference;
9045 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9046 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9047 if (draw_info->dash_pattern != (double *) NULL)
9048 {
9049 for (i=0; i <= av_len(av); i++)
9050 draw_info->dash_pattern[i]=(double)
9051 SvNV(*(av_fetch(av,i,0)));
9052 draw_info->dash_pattern[i]=0.0;
9053 }
9054 }
9055 if (attribute_flag[23] != 0)
9056 image->interpolate=(PixelInterpolateMethod)
9057 argument_list[23].integer_reference;
9058 if ((attribute_flag[24] != 0) &&
9059 (draw_info->fill_pattern != (Image *) NULL))
9060 flags=ParsePageGeometry(draw_info->fill_pattern,
9061 argument_list[24].string_reference,
9062 &draw_info->fill_pattern->tile_offset,exception);
9063 if (attribute_flag[25] != 0)
9064 {
9065 (void) ConcatenateString(&draw_info->primitive," '");
9066 (void) ConcatenateString(&draw_info->primitive,
9067 argument_list[25].string_reference);
9068 (void) ConcatenateString(&draw_info->primitive,"'");
9069 }
9070 if (attribute_flag[26] != 0)
9071 draw_info->fill_pattern=CloneImage(
9072 argument_list[26].image_reference,0,0,MagickTrue,exception);
9073 if (attribute_flag[27] != 0)
9074 draw_info->stroke_pattern=CloneImage(
9075 argument_list[27].image_reference,0,0,MagickTrue,exception);
9076 if (attribute_flag[28] != 0)
9077 (void) CloneString(&draw_info->primitive,
9078 argument_list[28].string_reference);
9079 if (attribute_flag[29] != 0)
9080 draw_info->kerning=argument_list[29].real_reference;
9081 if (attribute_flag[30] != 0)
9082 draw_info->interline_spacing=argument_list[30].real_reference;
9083 if (attribute_flag[31] != 0)
9084 draw_info->interword_spacing=argument_list[31].real_reference;
9085 if (attribute_flag[32] != 0)
9086 draw_info->direction=(DirectionType)
9087 argument_list[32].integer_reference;
9088 DrawImage(image,draw_info,exception);
9089 draw_info=DestroyDrawInfo(draw_info);
9090 break;
9091 }
9092 case 39: /* Equalize */
9093 {
9094 if (attribute_flag[0] != 0)
9095 channel=(ChannelType) argument_list[0].integer_reference;
9096 channel_mask=SetImageChannelMask(image,channel);
9097 EqualizeImage(image,exception);
9098 (void) SetImageChannelMask(image,channel_mask);
9099 break;
9100 }
9101 case 40: /* Gamma */
9102 {
9103 if (attribute_flag[1] != 0)
9104 channel=(ChannelType) argument_list[1].integer_reference;
9105 if (attribute_flag[2] == 0)
9106 argument_list[2].real_reference=1.0;
9107 if (attribute_flag[3] == 0)
9108 argument_list[3].real_reference=1.0;
9109 if (attribute_flag[4] == 0)
9110 argument_list[4].real_reference=1.0;
9111 if (attribute_flag[0] == 0)
9112 {
cristy151b66d2015-04-15 10:50:31 +00009113 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00009114 "%.15g,%.15g,%.15g",(double) argument_list[2].real_reference,
9115 (double) argument_list[3].real_reference,
9116 (double) argument_list[4].real_reference);
9117 argument_list[0].string_reference=message;
9118 }
9119 (void) GammaImage(image,StringToDouble(
9120 argument_list[0].string_reference,(char **) NULL),exception);
9121 break;
9122 }
9123 case 41: /* Map */
9124 {
9125 QuantizeInfo
9126 *quantize_info;
9127
9128 if (attribute_flag[0] == 0)
9129 {
9130 ThrowPerlException(exception,OptionError,"MapImageRequired",
9131 PackageName);
9132 goto PerlException;
9133 }
9134 quantize_info=AcquireQuantizeInfo(info->image_info);
9135 if (attribute_flag[1] != 0)
9136 quantize_info->dither_method=(DitherMethod)
9137 argument_list[1].integer_reference;
9138 (void) RemapImages(quantize_info,image,
9139 argument_list[0].image_reference,exception);
9140 quantize_info=DestroyQuantizeInfo(quantize_info);
9141 break;
9142 }
9143 case 42: /* MatteFloodfill */
9144 {
9145 DrawInfo
9146 *draw_info;
9147
9148 MagickBooleanType
9149 invert;
9150
9151 PixelInfo
9152 target;
9153
9154 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9155 (DrawInfo *) NULL);
9156 if (attribute_flag[0] != 0)
9157 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9158 &geometry,exception);
9159 if (attribute_flag[1] != 0)
9160 geometry.x=argument_list[1].integer_reference;
9161 if (attribute_flag[2] != 0)
9162 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009163 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009164 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9165 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9166 geometry.x,geometry.y,&target,exception);
9167 if (attribute_flag[4] != 0)
9168 QueryColorCompliance(argument_list[4].string_reference,
9169 AllCompliance,&target,exception);
9170 if (attribute_flag[3] != 0)
9171 target.alpha=StringToDoubleInterval(
9172 argument_list[3].string_reference,(double) (double) QuantumRange+
9173 1.0);
9174 if (attribute_flag[5] != 0)
9175 image->fuzz=StringToDoubleInterval(
9176 argument_list[5].string_reference,(double) QuantumRange+1.0);
9177 invert=MagickFalse;
9178 if (attribute_flag[6] != 0)
9179 invert=(MagickBooleanType) argument_list[6].integer_reference;
9180 channel_mask=SetImageChannelMask(image,AlphaChannel);
9181 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9182 geometry.y,invert,exception);
9183 (void) SetImageChannelMask(image,channel_mask);
9184 draw_info=DestroyDrawInfo(draw_info);
9185 break;
9186 }
9187 case 43: /* Modulate */
9188 {
9189 char
cristy151b66d2015-04-15 10:50:31 +00009190 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009191
9192 geometry_info.rho=100.0;
9193 geometry_info.sigma=100.0;
9194 geometry_info.xi=100.0;
9195 if (attribute_flag[0] != 0)
9196 (void)ParseGeometry(argument_list[0].string_reference,
9197 &geometry_info);
9198 if (attribute_flag[1] != 0)
9199 geometry_info.xi=argument_list[1].real_reference;
9200 if (attribute_flag[2] != 0)
9201 geometry_info.sigma=argument_list[2].real_reference;
9202 if (attribute_flag[3] != 0)
9203 {
9204 geometry_info.sigma=argument_list[3].real_reference;
9205 SetImageArtifact(image,"modulate:colorspace","HWB");
9206 }
9207 if (attribute_flag[4] != 0)
9208 {
9209 geometry_info.rho=argument_list[4].real_reference;
9210 SetImageArtifact(image,"modulate:colorspace","HSB");
9211 }
9212 if (attribute_flag[5] != 0)
9213 {
9214 geometry_info.sigma=argument_list[5].real_reference;
9215 SetImageArtifact(image,"modulate:colorspace","HSL");
9216 }
9217 if (attribute_flag[6] != 0)
9218 {
9219 geometry_info.rho=argument_list[6].real_reference;
9220 SetImageArtifact(image,"modulate:colorspace","HWB");
9221 }
cristy151b66d2015-04-15 10:50:31 +00009222 (void) FormatLocaleString(modulate,MagickPathExtent,"%.15g,%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00009223 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
9224 (void) ModulateImage(image,modulate,exception);
9225 break;
9226 }
9227 case 44: /* Negate */
9228 {
9229 if (attribute_flag[0] == 0)
9230 argument_list[0].integer_reference=0;
9231 if (attribute_flag[1] != 0)
9232 channel=(ChannelType) argument_list[1].integer_reference;
9233 channel_mask=SetImageChannelMask(image,channel);
9234 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9235 MagickTrue : MagickFalse,exception);
9236 (void) SetImageChannelMask(image,channel_mask);
9237 break;
9238 }
9239 case 45: /* Normalize */
9240 {
9241 if (attribute_flag[0] != 0)
9242 channel=(ChannelType) argument_list[0].integer_reference;
9243 channel_mask=SetImageChannelMask(image,channel);
9244 NormalizeImage(image,exception);
9245 (void) SetImageChannelMask(image,channel_mask);
9246 break;
9247 }
9248 case 46: /* NumberColors */
9249 break;
9250 case 47: /* Opaque */
9251 {
9252 MagickBooleanType
9253 invert;
9254
9255 PixelInfo
9256 fill_color,
9257 target;
9258
9259 (void) QueryColorCompliance("none",AllCompliance,&target,
9260 exception);
9261 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9262 exception);
9263 if (attribute_flag[0] != 0)
9264 (void) QueryColorCompliance(argument_list[0].string_reference,
9265 AllCompliance,&target,exception);
9266 if (attribute_flag[1] != 0)
9267 (void) QueryColorCompliance(argument_list[1].string_reference,
9268 AllCompliance,&fill_color,exception);
9269 if (attribute_flag[2] != 0)
9270 image->fuzz=StringToDoubleInterval(
9271 argument_list[2].string_reference,(double) QuantumRange+1.0);
9272 if (attribute_flag[3] != 0)
9273 channel=(ChannelType) argument_list[3].integer_reference;
9274 invert=MagickFalse;
9275 if (attribute_flag[4] != 0)
9276 invert=(MagickBooleanType) argument_list[4].integer_reference;
9277 channel_mask=SetImageChannelMask(image,channel);
9278 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9279 (void) SetImageChannelMask(image,channel_mask);
9280 break;
9281 }
9282 case 48: /* Quantize */
9283 {
9284 QuantizeInfo
9285 *quantize_info;
9286
9287 quantize_info=AcquireQuantizeInfo(info->image_info);
9288 if (attribute_flag[0] != 0)
9289 quantize_info->number_colors=(size_t)
9290 argument_list[0].integer_reference;
9291 if (attribute_flag[1] != 0)
9292 quantize_info->tree_depth=(size_t)
9293 argument_list[1].integer_reference;
9294 if (attribute_flag[2] != 0)
9295 quantize_info->colorspace=(ColorspaceType)
9296 argument_list[2].integer_reference;
9297 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009298 quantize_info->dither_method=(DitherMethod)
9299 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009300 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009301 quantize_info->measure_error=
9302 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009303 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009304 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009305 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009306 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009307 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009308 argument_list[7].integer_reference;
9309 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009310 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009311 else
cristyf7563392014-03-25 13:54:04 +00009312 if ((image->storage_class == DirectClass) ||
9313 (image->colors > quantize_info->number_colors) ||
9314 (quantize_info->colorspace == GRAYColorspace))
9315 (void) QuantizeImage(quantize_info,image,exception);
9316 else
9317 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009318 quantize_info=DestroyQuantizeInfo(quantize_info);
9319 break;
9320 }
9321 case 49: /* Raise */
9322 {
9323 if (attribute_flag[0] != 0)
9324 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9325 &geometry,exception);
9326 if (attribute_flag[1] != 0)
9327 geometry.width=argument_list[1].integer_reference;
9328 if (attribute_flag[2] != 0)
9329 geometry.height=argument_list[2].integer_reference;
9330 if (attribute_flag[3] == 0)
9331 argument_list[3].integer_reference=1;
9332 (void) RaiseImage(image,&geometry,
9333 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9334 exception);
9335 break;
9336 }
9337 case 50: /* Segment */
9338 {
9339 ColorspaceType
9340 colorspace;
9341
9342 double
9343 cluster_threshold,
9344 smoothing_threshold;
9345
9346 MagickBooleanType
9347 verbose;
9348
9349 cluster_threshold=1.0;
9350 smoothing_threshold=1.5;
9351 colorspace=sRGBColorspace;
9352 verbose=MagickFalse;
9353 if (attribute_flag[0] != 0)
9354 {
9355 flags=ParseGeometry(argument_list[0].string_reference,
9356 &geometry_info);
9357 cluster_threshold=geometry_info.rho;
9358 if (flags & SigmaValue)
9359 smoothing_threshold=geometry_info.sigma;
9360 }
9361 if (attribute_flag[1] != 0)
9362 cluster_threshold=argument_list[1].real_reference;
9363 if (attribute_flag[2] != 0)
9364 smoothing_threshold=argument_list[2].real_reference;
9365 if (attribute_flag[3] != 0)
9366 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9367 if (attribute_flag[4] != 0)
9368 verbose=argument_list[4].integer_reference != 0 ?
9369 MagickTrue : MagickFalse;
9370 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9371 smoothing_threshold,exception);
9372 break;
9373 }
9374 case 51: /* Signature */
9375 {
9376 (void) SignatureImage(image,exception);
9377 break;
9378 }
9379 case 52: /* Solarize */
9380 {
9381 geometry_info.rho=QuantumRange/2.0;
9382 if (attribute_flag[0] != 0)
9383 flags=ParseGeometry(argument_list[0].string_reference,
9384 &geometry_info);
9385 if (attribute_flag[1] != 0)
9386 geometry_info.rho=StringToDoubleInterval(
9387 argument_list[1].string_reference,(double) QuantumRange+1.0);
9388 (void) SolarizeImage(image,geometry_info.rho,exception);
9389 break;
9390 }
9391 case 53: /* Sync */
9392 {
9393 (void) SyncImage(image,exception);
9394 break;
9395 }
9396 case 54: /* Texture */
9397 {
9398 if (attribute_flag[0] == 0)
9399 break;
9400 TextureImage(image,argument_list[0].image_reference,exception);
9401 break;
9402 }
9403 case 55: /* Evalute */
9404 {
9405 MagickEvaluateOperator
9406 op;
9407
9408 op=SetEvaluateOperator;
9409 if (attribute_flag[0] == MagickFalse)
9410 argument_list[0].real_reference=0.0;
9411 if (attribute_flag[1] != MagickFalse)
9412 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9413 if (attribute_flag[2] != MagickFalse)
9414 channel=(ChannelType) argument_list[2].integer_reference;
9415 channel_mask=SetImageChannelMask(image,channel);
9416 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9417 exception);
9418 (void) SetImageChannelMask(image,channel_mask);
9419 break;
9420 }
9421 case 56: /* Transparent */
9422 {
9423 double
9424 opacity;
9425
9426 MagickBooleanType
9427 invert;
9428
9429 PixelInfo
9430 target;
9431
9432 (void) QueryColorCompliance("none",AllCompliance,&target,
9433 exception);
9434 if (attribute_flag[0] != 0)
9435 (void) QueryColorCompliance(argument_list[0].string_reference,
9436 AllCompliance,&target,exception);
9437 opacity=TransparentAlpha;
9438 if (attribute_flag[1] != 0)
9439 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9440 (double) QuantumRange+1.0);
9441 if (attribute_flag[2] != 0)
9442 image->fuzz=StringToDoubleInterval(
9443 argument_list[2].string_reference,(double) QuantumRange+1.0);
9444 if (attribute_flag[3] == 0)
9445 argument_list[3].integer_reference=0;
9446 invert=MagickFalse;
9447 if (attribute_flag[3] != 0)
9448 invert=(MagickBooleanType) argument_list[3].integer_reference;
9449 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9450 invert,exception);
9451 break;
9452 }
9453 case 57: /* Threshold */
9454 {
9455 double
9456 threshold;
9457
9458 if (attribute_flag[0] == 0)
9459 argument_list[0].string_reference="50%";
9460 if (attribute_flag[1] != 0)
9461 channel=(ChannelType) argument_list[1].integer_reference;
9462 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9463 (double) QuantumRange+1.0);
9464 channel_mask=SetImageChannelMask(image,channel);
9465 (void) BilevelImage(image,threshold,exception);
9466 (void) SetImageChannelMask(image,channel_mask);
9467 break;
9468 }
9469 case 58: /* Charcoal */
9470 {
9471 if (attribute_flag[0] != 0)
9472 {
9473 flags=ParseGeometry(argument_list[0].string_reference,
9474 &geometry_info);
9475 if ((flags & SigmaValue) == 0)
9476 geometry_info.sigma=1.0;
9477 }
9478 if (attribute_flag[1] != 0)
9479 geometry_info.rho=argument_list[1].real_reference;
9480 if (attribute_flag[2] != 0)
9481 geometry_info.sigma=argument_list[2].real_reference;
9482 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9483 exception);
9484 break;
9485 }
9486 case 59: /* Trim */
9487 {
9488 if (attribute_flag[0] != 0)
9489 image->fuzz=StringToDoubleInterval(
9490 argument_list[0].string_reference,(double) QuantumRange+1.0);
9491 image=TrimImage(image,exception);
9492 break;
9493 }
9494 case 60: /* Wave */
9495 {
9496 PixelInterpolateMethod
9497 method;
9498
9499 if (attribute_flag[0] != 0)
9500 {
9501 flags=ParseGeometry(argument_list[0].string_reference,
9502 &geometry_info);
9503 if ((flags & SigmaValue) == 0)
9504 geometry_info.sigma=1.0;
9505 }
9506 if (attribute_flag[1] != 0)
9507 geometry_info.rho=argument_list[1].real_reference;
9508 if (attribute_flag[2] != 0)
9509 geometry_info.sigma=argument_list[2].real_reference;
9510 method=UndefinedInterpolatePixel;
9511 if (attribute_flag[3] != 0)
9512 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9513 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9514 method,exception);
9515 break;
9516 }
9517 case 61: /* Separate */
9518 {
9519 if (attribute_flag[0] != 0)
9520 channel=(ChannelType) argument_list[0].integer_reference;
9521 image=SeparateImage(image,channel,exception);
9522 break;
9523 }
9524 case 63: /* Stereo */
9525 {
9526 if (attribute_flag[0] == 0)
9527 {
9528 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9529 PackageName);
9530 goto PerlException;
9531 }
9532 if (attribute_flag[1] != 0)
9533 geometry.x=argument_list[1].integer_reference;
9534 if (attribute_flag[2] != 0)
9535 geometry.y=argument_list[2].integer_reference;
9536 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9537 geometry.x,geometry.y,exception);
9538 break;
9539 }
9540 case 64: /* Stegano */
9541 {
9542 if (attribute_flag[0] == 0)
9543 {
9544 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9545 PackageName);
9546 goto PerlException;
9547 }
9548 if (attribute_flag[1] == 0)
9549 argument_list[1].integer_reference=0;
9550 image->offset=argument_list[1].integer_reference;
9551 image=SteganoImage(image,argument_list[0].image_reference,exception);
9552 break;
9553 }
9554 case 65: /* Deconstruct */
9555 {
9556 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9557 break;
9558 }
9559 case 66: /* GaussianBlur */
9560 {
9561 if (attribute_flag[0] != 0)
9562 {
9563 flags=ParseGeometry(argument_list[0].string_reference,
9564 &geometry_info);
9565 if ((flags & SigmaValue) == 0)
9566 geometry_info.sigma=1.0;
9567 }
9568 if (attribute_flag[1] != 0)
9569 geometry_info.rho=argument_list[1].real_reference;
9570 if (attribute_flag[2] != 0)
9571 geometry_info.sigma=argument_list[2].real_reference;
9572 if (attribute_flag[3] != 0)
9573 channel=(ChannelType) argument_list[3].integer_reference;
9574 channel_mask=SetImageChannelMask(image,channel);
9575 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9576 exception);
9577 if (image != (Image *) NULL)
9578 (void) SetImageChannelMask(image,channel_mask);
9579 break;
9580 }
9581 case 67: /* Convolve */
9582 {
9583 KernelInfo
9584 *kernel;
9585
9586 kernel=(KernelInfo *) NULL;
9587 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9588 break;
9589 if (attribute_flag[0] != 0)
9590 {
9591 AV
9592 *av;
9593
9594 size_t
9595 order;
9596
cristy2c57b742014-10-31 00:40:34 +00009597 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009598 if (kernel == (KernelInfo *) NULL)
9599 break;
9600 av=(AV *) argument_list[0].array_reference;
9601 order=(size_t) sqrt(av_len(av)+1);
9602 kernel->width=order;
9603 kernel->height=order;
9604 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9605 order*sizeof(*kernel->values));
9606 if (kernel->values == (MagickRealType *) NULL)
9607 {
9608 kernel=DestroyKernelInfo(kernel);
9609 ThrowPerlException(exception,ResourceLimitFatalError,
9610 "MemoryAllocationFailed",PackageName);
9611 goto PerlException;
9612 }
9613 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9614 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9615 for ( ; j < (ssize_t) (order*order); j++)
9616 kernel->values[j]=0.0;
9617 }
9618 if (attribute_flag[1] != 0)
9619 channel=(ChannelType) argument_list[1].integer_reference;
9620 if (attribute_flag[2] != 0)
9621 SetImageArtifact(image,"filter:blur",
9622 argument_list[2].string_reference);
9623 if (attribute_flag[3] != 0)
9624 {
cristy2c57b742014-10-31 00:40:34 +00009625 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9626 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009627 if (kernel == (KernelInfo *) NULL)
9628 break;
9629 }
9630 channel_mask=SetImageChannelMask(image,channel);
9631 image=ConvolveImage(image,kernel,exception);
9632 if (image != (Image *) NULL)
9633 (void) SetImageChannelMask(image,channel_mask);
9634 kernel=DestroyKernelInfo(kernel);
9635 break;
9636 }
9637 case 68: /* Profile */
9638 {
9639 const char
9640 *name;
9641
9642 Image
9643 *profile_image;
9644
9645 ImageInfo
9646 *profile_info;
9647
9648 StringInfo
9649 *profile;
9650
9651 name="*";
9652 if (attribute_flag[0] != 0)
9653 name=argument_list[0].string_reference;
9654 if (attribute_flag[2] != 0)
9655 image->rendering_intent=(RenderingIntent)
9656 argument_list[2].integer_reference;
9657 if (attribute_flag[3] != 0)
9658 image->black_point_compensation=
9659 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9660 if (attribute_flag[1] != 0)
9661 {
9662 if (argument_list[1].length == 0)
9663 {
9664 /*
9665 Remove a profile from the image.
9666 */
9667 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9668 exception);
9669 break;
9670 }
9671 /*
9672 Associate user supplied profile with the image.
9673 */
9674 profile=AcquireStringInfo(argument_list[1].length);
9675 SetStringInfoDatum(profile,(const unsigned char *)
9676 argument_list[1].string_reference);
9677 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9678 (size_t) GetStringInfoLength(profile),exception);
9679 profile=DestroyStringInfo(profile);
9680 break;
9681 }
9682 /*
9683 Associate a profile with the image.
9684 */
9685 profile_info=CloneImageInfo(info ? info->image_info :
9686 (ImageInfo *) NULL);
9687 profile_image=ReadImages(profile_info,name,exception);
9688 if (profile_image == (Image *) NULL)
9689 break;
9690 ResetImageProfileIterator(profile_image);
9691 name=GetNextImageProfile(profile_image);
9692 while (name != (const char *) NULL)
9693 {
9694 const StringInfo
9695 *profile;
9696
9697 profile=GetImageProfile(profile_image,name);
9698 if (profile != (const StringInfo *) NULL)
9699 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9700 (size_t) GetStringInfoLength(profile),exception);
9701 name=GetNextImageProfile(profile_image);
9702 }
9703 profile_image=DestroyImage(profile_image);
9704 profile_info=DestroyImageInfo(profile_info);
9705 break;
9706 }
9707 case 69: /* UnsharpMask */
9708 {
9709 if (attribute_flag[0] != 0)
9710 {
9711 flags=ParseGeometry(argument_list[0].string_reference,
9712 &geometry_info);
9713 if ((flags & SigmaValue) == 0)
9714 geometry_info.sigma=1.0;
9715 if ((flags & XiValue) == 0)
9716 geometry_info.xi=1.0;
9717 if ((flags & PsiValue) == 0)
9718 geometry_info.psi=0.5;
9719 }
9720 if (attribute_flag[1] != 0)
9721 geometry_info.rho=argument_list[1].real_reference;
9722 if (attribute_flag[2] != 0)
9723 geometry_info.sigma=argument_list[2].real_reference;
9724 if (attribute_flag[3] != 0)
9725 geometry_info.xi=argument_list[3].real_reference;
9726 if (attribute_flag[4] != 0)
9727 geometry_info.psi=argument_list[4].real_reference;
9728 if (attribute_flag[5] != 0)
9729 channel=(ChannelType) argument_list[5].integer_reference;
9730 channel_mask=SetImageChannelMask(image,channel);
9731 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9732 geometry_info.xi,geometry_info.psi,exception);
9733 if (image != (Image *) NULL)
9734 (void) SetImageChannelMask(image,channel_mask);
9735 break;
9736 }
9737 case 70: /* MotionBlur */
9738 {
9739 if (attribute_flag[0] != 0)
9740 {
9741 flags=ParseGeometry(argument_list[0].string_reference,
9742 &geometry_info);
9743 if ((flags & SigmaValue) == 0)
9744 geometry_info.sigma=1.0;
9745 if ((flags & XiValue) == 0)
9746 geometry_info.xi=1.0;
9747 }
9748 if (attribute_flag[1] != 0)
9749 geometry_info.rho=argument_list[1].real_reference;
9750 if (attribute_flag[2] != 0)
9751 geometry_info.sigma=argument_list[2].real_reference;
9752 if (attribute_flag[3] != 0)
9753 geometry_info.xi=argument_list[3].real_reference;
9754 if (attribute_flag[4] != 0)
9755 channel=(ChannelType) argument_list[4].integer_reference;
9756 channel_mask=SetImageChannelMask(image,channel);
9757 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9758 geometry_info.xi,exception);
9759 if (image != (Image *) NULL)
9760 (void) SetImageChannelMask(image,channel_mask);
9761 break;
9762 }
9763 case 71: /* OrderedDither */
9764 {
9765 if (attribute_flag[0] == 0)
9766 argument_list[0].string_reference="o8x8";
9767 if (attribute_flag[1] != 0)
9768 channel=(ChannelType) argument_list[1].integer_reference;
9769 channel_mask=SetImageChannelMask(image,channel);
9770 (void) OrderedPosterizeImage(image,argument_list[0].string_reference,
9771 exception);
9772 (void) SetImageChannelMask(image,channel_mask);
9773 break;
9774 }
9775 case 72: /* Shave */
9776 {
9777 if (attribute_flag[0] != 0)
9778 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9779 &geometry,exception);
9780 if (attribute_flag[1] != 0)
9781 geometry.width=argument_list[1].integer_reference;
9782 if (attribute_flag[2] != 0)
9783 geometry.height=argument_list[2].integer_reference;
9784 image=ShaveImage(image,&geometry,exception);
9785 break;
9786 }
9787 case 73: /* Level */
9788 {
9789 double
9790 black_point,
9791 gamma,
9792 white_point;
9793
9794 black_point=0.0;
9795 white_point=(double) image->columns*image->rows;
9796 gamma=1.0;
9797 if (attribute_flag[0] != 0)
9798 {
9799 flags=ParseGeometry(argument_list[0].string_reference,
9800 &geometry_info);
9801 black_point=geometry_info.rho;
9802 if ((flags & SigmaValue) != 0)
9803 white_point=geometry_info.sigma;
9804 if ((flags & XiValue) != 0)
9805 gamma=geometry_info.xi;
9806 if ((flags & PercentValue) != 0)
9807 {
9808 black_point*=(double) (QuantumRange/100.0);
9809 white_point*=(double) (QuantumRange/100.0);
9810 }
9811 if ((flags & SigmaValue) == 0)
9812 white_point=(double) QuantumRange-black_point;
9813 }
9814 if (attribute_flag[1] != 0)
9815 black_point=argument_list[1].real_reference;
9816 if (attribute_flag[2] != 0)
9817 white_point=argument_list[2].real_reference;
9818 if (attribute_flag[3] != 0)
9819 gamma=argument_list[3].real_reference;
9820 if (attribute_flag[4] != 0)
9821 channel=(ChannelType) argument_list[4].integer_reference;
9822 if (attribute_flag[5] != 0)
9823 {
9824 argument_list[0].real_reference=argument_list[5].real_reference;
9825 attribute_flag[0]=attribute_flag[5];
9826 }
9827 channel_mask=SetImageChannelMask(image,channel);
9828 (void) LevelImage(image,black_point,white_point,gamma,exception);
9829 (void) SetImageChannelMask(image,channel_mask);
9830 break;
9831 }
9832 case 74: /* Clip */
9833 {
9834 if (attribute_flag[0] == 0)
9835 argument_list[0].string_reference="#1";
9836 if (attribute_flag[1] == 0)
9837 argument_list[1].integer_reference=MagickTrue;
9838 (void) ClipImagePath(image,argument_list[0].string_reference,
9839 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9840 exception);
9841 break;
9842 }
9843 case 75: /* AffineTransform */
9844 {
9845 DrawInfo
9846 *draw_info;
9847
9848 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9849 (DrawInfo *) NULL);
9850 if (attribute_flag[0] != 0)
9851 {
9852 AV
9853 *av;
9854
9855 av=(AV *) argument_list[0].array_reference;
9856 if ((av_len(av) != 3) && (av_len(av) != 5))
9857 {
9858 ThrowPerlException(exception,OptionError,
9859 "affine matrix must have 4 or 6 elements",PackageName);
9860 goto PerlException;
9861 }
9862 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9863 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9864 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9865 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9866 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9867 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9868 {
9869 ThrowPerlException(exception,OptionError,
9870 "affine matrix is singular",PackageName);
9871 goto PerlException;
9872 }
9873 if (av_len(av) == 5)
9874 {
9875 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9876 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9877 }
9878 }
9879 for (j=1; j < 6; j++)
9880 {
9881 if (attribute_flag[j] == 0)
9882 continue;
9883 value=argument_list[j].string_reference;
9884 angle=argument_list[j].real_reference;
9885 current=draw_info->affine;
9886 GetAffineMatrix(&affine);
9887 switch (j)
9888 {
9889 case 1:
9890 {
9891 /*
9892 Translate.
9893 */
9894 flags=ParseGeometry(value,&geometry_info);
9895 affine.tx=geometry_info.xi;
9896 affine.ty=geometry_info.psi;
9897 if ((flags & PsiValue) == 0)
9898 affine.ty=affine.tx;
9899 break;
9900 }
9901 case 2:
9902 {
9903 /*
9904 Scale.
9905 */
9906 flags=ParseGeometry(value,&geometry_info);
9907 affine.sx=geometry_info.rho;
9908 affine.sy=geometry_info.sigma;
9909 if ((flags & SigmaValue) == 0)
9910 affine.sy=affine.sx;
9911 break;
9912 }
9913 case 3:
9914 {
9915 /*
9916 Rotate.
9917 */
9918 if (angle == 0.0)
9919 break;
9920 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9921 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9922 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9923 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9924 break;
9925 }
9926 case 4:
9927 {
9928 /*
9929 SkewX.
9930 */
9931 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9932 break;
9933 }
9934 case 5:
9935 {
9936 /*
9937 SkewY.
9938 */
9939 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9940 break;
9941 }
9942 }
9943 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9944 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9945 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9946 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9947 draw_info->affine.tx=
9948 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9949 draw_info->affine.ty=
9950 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9951 }
9952 if (attribute_flag[6] != 0)
9953 image->interpolate=(PixelInterpolateMethod)
9954 argument_list[6].integer_reference;
9955 if (attribute_flag[7] != 0)
9956 QueryColorCompliance(argument_list[7].string_reference,
9957 AllCompliance,&image->background_color,exception);
9958 image=AffineTransformImage(image,&draw_info->affine,exception);
9959 draw_info=DestroyDrawInfo(draw_info);
9960 break;
9961 }
9962 case 76: /* Difference */
9963 {
9964 if (attribute_flag[0] == 0)
9965 {
9966 ThrowPerlException(exception,OptionError,
9967 "ReferenceImageRequired",PackageName);
9968 goto PerlException;
9969 }
9970 if (attribute_flag[1] != 0)
9971 image->fuzz=StringToDoubleInterval(
9972 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -05009973 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009974 exception);
9975 break;
9976 }
9977 case 77: /* AdaptiveThreshold */
9978 {
9979 if (attribute_flag[0] != 0)
9980 {
9981 flags=ParseGeometry(argument_list[0].string_reference,
9982 &geometry_info);
9983 if ((flags & PercentValue) != 0)
9984 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9985 }
9986 if (attribute_flag[1] != 0)
9987 geometry_info.rho=argument_list[1].integer_reference;
9988 if (attribute_flag[2] != 0)
9989 geometry_info.sigma=argument_list[2].integer_reference;
9990 if (attribute_flag[3] != 0)
9991 geometry_info.xi=argument_list[3].integer_reference;;
9992 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9993 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9994 break;
9995 }
9996 case 78: /* Resample */
9997 {
9998 size_t
9999 height,
10000 width;
10001
10002 if (attribute_flag[0] != 0)
10003 {
10004 flags=ParseGeometry(argument_list[0].string_reference,
10005 &geometry_info);
10006 if ((flags & SigmaValue) == 0)
10007 geometry_info.sigma=geometry_info.rho;
10008 }
10009 if (attribute_flag[1] != 0)
10010 geometry_info.rho=argument_list[1].real_reference;
10011 if (attribute_flag[2] != 0)
10012 geometry_info.sigma=argument_list[2].real_reference;
10013 if (attribute_flag[3] == 0)
10014 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10015 if (attribute_flag[4] == 0)
10016 SetImageArtifact(image,"filter:support",
10017 argument_list[4].string_reference);
10018 width=(size_t) (geometry_info.rho*image->columns/
10019 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10020 height=(size_t) (geometry_info.sigma*image->rows/
10021 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
10022 image=ResizeImage(image,width,height,(FilterTypes)
10023 argument_list[3].integer_reference,exception);
10024 if (image != (Image *) NULL)
10025 {
10026 image->resolution.x=geometry_info.rho;
10027 image->resolution.y=geometry_info.sigma;
10028 }
10029 break;
10030 }
10031 case 79: /* Describe */
10032 {
10033 if (attribute_flag[0] == 0)
10034 argument_list[0].file_reference=(FILE *) NULL;
10035 if (attribute_flag[1] != 0)
10036 (void) SetImageArtifact(image,"identify:features",
10037 argument_list[1].string_reference);
10038 (void) IdentifyImage(image,argument_list[0].file_reference,
10039 MagickTrue,exception);
10040 break;
10041 }
10042 case 80: /* BlackThreshold */
10043 {
10044 if (attribute_flag[0] == 0)
10045 argument_list[0].string_reference="50%";
10046 if (attribute_flag[2] != 0)
10047 channel=(ChannelType) argument_list[2].integer_reference;
10048 channel_mask=SetImageChannelMask(image,channel);
10049 BlackThresholdImage(image,argument_list[0].string_reference,
10050 exception);
10051 (void) SetImageChannelMask(image,channel_mask);
10052 break;
10053 }
10054 case 81: /* WhiteThreshold */
10055 {
10056 if (attribute_flag[0] == 0)
10057 argument_list[0].string_reference="50%";
10058 if (attribute_flag[2] != 0)
10059 channel=(ChannelType) argument_list[2].integer_reference;
10060 channel_mask=SetImageChannelMask(image,channel);
10061 WhiteThresholdImage(image,argument_list[0].string_reference,
10062 exception);
10063 (void) SetImageChannelMask(image,channel_mask);
10064 break;
10065 }
cristy60c73c02014-03-25 12:09:58 +000010066 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010067 {
10068 if (attribute_flag[0] != 0)
10069 {
10070 flags=ParseGeometry(argument_list[0].string_reference,
10071 &geometry_info);
10072 }
10073 if (attribute_flag[1] != 0)
10074 geometry_info.rho=argument_list[1].real_reference;
10075 if (attribute_flag[2] != 0)
10076 channel=(ChannelType) argument_list[2].integer_reference;
10077 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010078 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010079 if (image != (Image *) NULL)
10080 (void) SetImageChannelMask(image,channel_mask);
10081 break;
10082 }
10083 case 83: /* Thumbnail */
10084 {
10085 if (attribute_flag[0] != 0)
10086 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10087 &geometry,exception);
10088 if (attribute_flag[1] != 0)
10089 geometry.width=argument_list[1].integer_reference;
10090 if (attribute_flag[2] != 0)
10091 geometry.height=argument_list[2].integer_reference;
10092 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10093 break;
10094 }
10095 case 84: /* Strip */
10096 {
10097 (void) StripImage(image,exception);
10098 break;
10099 }
10100 case 85: /* Tint */
10101 {
10102 PixelInfo
10103 tint;
10104
10105 GetPixelInfo(image,&tint);
10106 if (attribute_flag[0] != 0)
10107 (void) QueryColorCompliance(argument_list[0].string_reference,
10108 AllCompliance,&tint,exception);
10109 if (attribute_flag[1] == 0)
10110 argument_list[1].string_reference="100";
10111 image=TintImage(image,argument_list[1].string_reference,&tint,
10112 exception);
10113 break;
10114 }
10115 case 86: /* Channel */
10116 {
10117 if (attribute_flag[0] != 0)
10118 channel=(ChannelType) argument_list[0].integer_reference;
10119 image=SeparateImage(image,channel,exception);
10120 break;
10121 }
10122 case 87: /* Splice */
10123 {
cristy260bd762014-08-15 12:46:34 +000010124 if (attribute_flag[7] != 0)
10125 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010126 if (attribute_flag[0] != 0)
10127 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10128 &geometry,exception);
10129 if (attribute_flag[1] != 0)
10130 geometry.width=argument_list[1].integer_reference;
10131 if (attribute_flag[2] != 0)
10132 geometry.height=argument_list[2].integer_reference;
10133 if (attribute_flag[3] != 0)
10134 geometry.x=argument_list[3].integer_reference;
10135 if (attribute_flag[4] != 0)
10136 geometry.y=argument_list[4].integer_reference;
10137 if (attribute_flag[5] != 0)
10138 image->fuzz=StringToDoubleInterval(
10139 argument_list[5].string_reference,(double) QuantumRange+1.0);
10140 if (attribute_flag[6] != 0)
10141 (void) QueryColorCompliance(argument_list[6].string_reference,
10142 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010143 image=SpliceImage(image,&geometry,exception);
10144 break;
10145 }
10146 case 88: /* Posterize */
10147 {
10148 if (attribute_flag[0] == 0)
10149 argument_list[0].integer_reference=3;
10150 if (attribute_flag[1] == 0)
10151 argument_list[1].integer_reference=0;
10152 (void) PosterizeImage(image,argument_list[0].integer_reference,
10153 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10154 NoDitherMethod,exception);
10155 break;
10156 }
10157 case 89: /* Shadow */
10158 {
10159 if (attribute_flag[0] != 0)
10160 {
10161 flags=ParseGeometry(argument_list[0].string_reference,
10162 &geometry_info);
10163 if ((flags & SigmaValue) == 0)
10164 geometry_info.sigma=1.0;
10165 if ((flags & XiValue) == 0)
10166 geometry_info.xi=4.0;
10167 if ((flags & PsiValue) == 0)
10168 geometry_info.psi=4.0;
10169 }
10170 if (attribute_flag[1] != 0)
10171 geometry_info.rho=argument_list[1].real_reference;
10172 if (attribute_flag[2] != 0)
10173 geometry_info.sigma=argument_list[2].real_reference;
10174 if (attribute_flag[3] != 0)
10175 geometry_info.xi=argument_list[3].integer_reference;
10176 if (attribute_flag[4] != 0)
10177 geometry_info.psi=argument_list[4].integer_reference;
10178 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10179 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10180 ceil(geometry_info.psi-0.5),exception);
10181 break;
10182 }
10183 case 90: /* Identify */
10184 {
10185 if (attribute_flag[0] == 0)
10186 argument_list[0].file_reference=(FILE *) NULL;
10187 if (attribute_flag[1] != 0)
10188 (void) SetImageArtifact(image,"identify:features",
10189 argument_list[1].string_reference);
10190 if ((attribute_flag[2] != 0) &&
10191 (argument_list[2].integer_reference != 0))
10192 (void) SetImageArtifact(image,"identify:unique","true");
10193 (void) IdentifyImage(image,argument_list[0].file_reference,
10194 MagickTrue,exception);
10195 break;
10196 }
10197 case 91: /* SepiaTone */
10198 {
10199 if (attribute_flag[0] == 0)
10200 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10201 image=SepiaToneImage(image,argument_list[0].real_reference,
10202 exception);
10203 break;
10204 }
10205 case 92: /* SigmoidalContrast */
10206 {
10207 MagickBooleanType
10208 sharpen;
10209
10210 if (attribute_flag[0] != 0)
10211 {
10212 flags=ParseGeometry(argument_list[0].string_reference,
10213 &geometry_info);
10214 if ((flags & SigmaValue) == 0)
10215 geometry_info.sigma=QuantumRange/2.0;
10216 if ((flags & PercentValue) != 0)
10217 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10218 }
10219 if (attribute_flag[1] != 0)
10220 geometry_info.rho=argument_list[1].real_reference;
10221 if (attribute_flag[2] != 0)
10222 geometry_info.sigma=argument_list[2].real_reference;
10223 if (attribute_flag[3] != 0)
10224 channel=(ChannelType) argument_list[3].integer_reference;
10225 sharpen=MagickTrue;
10226 if (attribute_flag[4] != 0)
10227 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10228 MagickFalse;
10229 channel_mask=SetImageChannelMask(image,channel);
10230 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10231 geometry_info.sigma,exception);
10232 (void) SetImageChannelMask(image,channel_mask);
10233 break;
10234 }
10235 case 93: /* Extent */
10236 {
10237 if (attribute_flag[7] != 0)
10238 image->gravity=(GravityType) argument_list[7].integer_reference;
10239 if (attribute_flag[0] != 0)
10240 {
10241 int
10242 flags;
10243
10244 flags=ParseGravityGeometry(image,
10245 argument_list[0].string_reference,&geometry,exception);
10246 (void) flags;
10247 if (geometry.width == 0)
10248 geometry.width=image->columns;
10249 if (geometry.height == 0)
10250 geometry.height=image->rows;
10251 }
10252 if (attribute_flag[1] != 0)
10253 geometry.width=argument_list[1].integer_reference;
10254 if (attribute_flag[2] != 0)
10255 geometry.height=argument_list[2].integer_reference;
10256 if (attribute_flag[3] != 0)
10257 geometry.x=argument_list[3].integer_reference;
10258 if (attribute_flag[4] != 0)
10259 geometry.y=argument_list[4].integer_reference;
10260 if (attribute_flag[5] != 0)
10261 image->fuzz=StringToDoubleInterval(
10262 argument_list[5].string_reference,(double) QuantumRange+1.0);
10263 if (attribute_flag[6] != 0)
10264 (void) QueryColorCompliance(argument_list[6].string_reference,
10265 AllCompliance,&image->background_color,exception);
10266 image=ExtentImage(image,&geometry,exception);
10267 break;
10268 }
10269 case 94: /* Vignette */
10270 {
10271 if (attribute_flag[0] != 0)
10272 {
10273 flags=ParseGeometry(argument_list[0].string_reference,
10274 &geometry_info);
10275 if ((flags & SigmaValue) == 0)
10276 geometry_info.sigma=1.0;
10277 if ((flags & XiValue) == 0)
10278 geometry_info.xi=0.1*image->columns;
10279 if ((flags & PsiValue) == 0)
10280 geometry_info.psi=0.1*image->rows;
10281 }
10282 if (attribute_flag[1] != 0)
10283 geometry_info.rho=argument_list[1].real_reference;
10284 if (attribute_flag[2] != 0)
10285 geometry_info.sigma=argument_list[2].real_reference;
10286 if (attribute_flag[3] != 0)
10287 geometry_info.xi=argument_list[3].integer_reference;
10288 if (attribute_flag[4] != 0)
10289 geometry_info.psi=argument_list[4].integer_reference;
10290 if (attribute_flag[5] != 0)
10291 (void) QueryColorCompliance(argument_list[5].string_reference,
10292 AllCompliance,&image->background_color,exception);
10293 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10294 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10295 ceil(geometry_info.psi-0.5),exception);
10296 break;
10297 }
10298 case 95: /* ContrastStretch */
10299 {
10300 double
10301 black_point,
10302 white_point;
10303
10304 black_point=0.0;
10305 white_point=(double) image->columns*image->rows;
10306 if (attribute_flag[0] != 0)
10307 {
10308 flags=ParseGeometry(argument_list[0].string_reference,
10309 &geometry_info);
10310 black_point=geometry_info.rho;
10311 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10312 black_point;
10313 if ((flags & PercentValue) != 0)
10314 {
10315 black_point*=(double) image->columns*image->rows/100.0;
10316 white_point*=(double) image->columns*image->rows/100.0;
10317 }
10318 white_point=(double) image->columns*image->rows-
10319 white_point;
10320 }
10321 if (attribute_flag[1] != 0)
10322 black_point=argument_list[1].real_reference;
10323 if (attribute_flag[2] != 0)
10324 white_point=argument_list[2].real_reference;
10325 if (attribute_flag[4] != 0)
10326 channel=(ChannelType) argument_list[4].integer_reference;
10327 channel_mask=SetImageChannelMask(image,channel);
10328 (void) ContrastStretchImage(image,black_point,white_point,exception);
10329 (void) SetImageChannelMask(image,channel_mask);
10330 break;
10331 }
10332 case 96: /* Sans0 */
10333 {
10334 break;
10335 }
10336 case 97: /* Sans1 */
10337 {
10338 break;
10339 }
10340 case 98: /* AdaptiveSharpen */
10341 {
10342 if (attribute_flag[0] != 0)
10343 {
10344 flags=ParseGeometry(argument_list[0].string_reference,
10345 &geometry_info);
10346 if ((flags & SigmaValue) == 0)
10347 geometry_info.sigma=1.0;
10348 if ((flags & XiValue) == 0)
10349 geometry_info.xi=0.0;
10350 }
10351 if (attribute_flag[1] != 0)
10352 geometry_info.rho=argument_list[1].real_reference;
10353 if (attribute_flag[2] != 0)
10354 geometry_info.sigma=argument_list[2].real_reference;
10355 if (attribute_flag[3] != 0)
10356 geometry_info.xi=argument_list[3].real_reference;
10357 if (attribute_flag[4] != 0)
10358 channel=(ChannelType) argument_list[4].integer_reference;
10359 channel_mask=SetImageChannelMask(image,channel);
10360 image=AdaptiveSharpenImage(image,geometry_info.rho,
10361 geometry_info.sigma,exception);
10362 if (image != (Image *) NULL)
10363 (void) SetImageChannelMask(image,channel_mask);
10364 break;
10365 }
10366 case 99: /* Transpose */
10367 {
10368 image=TransposeImage(image,exception);
10369 break;
10370 }
10371 case 100: /* Tranverse */
10372 {
10373 image=TransverseImage(image,exception);
10374 break;
10375 }
10376 case 101: /* AutoOrient */
10377 {
10378 image=AutoOrientImage(image,image->orientation,exception);
10379 break;
10380 }
10381 case 102: /* AdaptiveBlur */
10382 {
10383 if (attribute_flag[0] != 0)
10384 {
10385 flags=ParseGeometry(argument_list[0].string_reference,
10386 &geometry_info);
10387 if ((flags & SigmaValue) == 0)
10388 geometry_info.sigma=1.0;
10389 if ((flags & XiValue) == 0)
10390 geometry_info.xi=0.0;
10391 }
10392 if (attribute_flag[1] != 0)
10393 geometry_info.rho=argument_list[1].real_reference;
10394 if (attribute_flag[2] != 0)
10395 geometry_info.sigma=argument_list[2].real_reference;
10396 if (attribute_flag[3] != 0)
10397 channel=(ChannelType) argument_list[3].integer_reference;
10398 channel_mask=SetImageChannelMask(image,channel);
10399 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10400 exception);
10401 if (image != (Image *) NULL)
10402 (void) SetImageChannelMask(image,channel_mask);
10403 break;
10404 }
10405 case 103: /* Sketch */
10406 {
10407 if (attribute_flag[0] != 0)
10408 {
10409 flags=ParseGeometry(argument_list[0].string_reference,
10410 &geometry_info);
10411 if ((flags & SigmaValue) == 0)
10412 geometry_info.sigma=1.0;
10413 if ((flags & XiValue) == 0)
10414 geometry_info.xi=1.0;
10415 }
10416 if (attribute_flag[1] != 0)
10417 geometry_info.rho=argument_list[1].real_reference;
10418 if (attribute_flag[2] != 0)
10419 geometry_info.sigma=argument_list[2].real_reference;
10420 if (attribute_flag[3] != 0)
10421 geometry_info.xi=argument_list[3].real_reference;
10422 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10423 geometry_info.xi,exception);
10424 break;
10425 }
10426 case 104: /* UniqueColors */
10427 {
10428 image=UniqueImageColors(image,exception);
10429 break;
10430 }
10431 case 105: /* AdaptiveResize */
10432 {
10433 if (attribute_flag[0] != 0)
10434 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10435 &geometry,exception);
10436 if (attribute_flag[1] != 0)
10437 geometry.width=argument_list[1].integer_reference;
10438 if (attribute_flag[2] != 0)
10439 geometry.height=argument_list[2].integer_reference;
10440 if (attribute_flag[3] != 0)
10441 image->filter=(FilterTypes) argument_list[4].integer_reference;
10442 if (attribute_flag[4] != 0)
10443 SetImageArtifact(image,"filter:support",
10444 argument_list[4].string_reference);
10445 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10446 exception);
10447 break;
10448 }
10449 case 106: /* ClipMask */
10450 {
10451 Image
10452 *mask_image;
10453
10454 if (attribute_flag[0] == 0)
10455 {
10456 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10457 PackageName);
10458 goto PerlException;
10459 }
10460 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10461 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010462 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010463 mask_image=DestroyImage(mask_image);
10464 break;
10465 }
10466 case 107: /* LinearStretch */
10467 {
10468 double
10469 black_point,
10470 white_point;
10471
10472 black_point=0.0;
10473 white_point=(double) image->columns*image->rows;
10474 if (attribute_flag[0] != 0)
10475 {
10476 flags=ParseGeometry(argument_list[0].string_reference,
10477 &geometry_info);
10478 if ((flags & SigmaValue) != 0)
10479 white_point=geometry_info.sigma;
10480 if ((flags & PercentValue) != 0)
10481 {
10482 black_point*=(double) image->columns*image->rows/100.0;
10483 white_point*=(double) image->columns*image->rows/100.0;
10484 }
10485 if ((flags & SigmaValue) == 0)
10486 white_point=(double) image->columns*image->rows-black_point;
10487 }
10488 if (attribute_flag[1] != 0)
10489 black_point=argument_list[1].real_reference;
10490 if (attribute_flag[2] != 0)
10491 white_point=argument_list[2].real_reference;
10492 (void) LinearStretchImage(image,black_point,white_point,exception);
10493 break;
10494 }
10495 case 108: /* ColorMatrix */
10496 {
10497 AV
10498 *av;
10499
10500 double
10501 *color_matrix;
10502
10503 KernelInfo
10504 *kernel_info;
10505
10506 size_t
10507 order;
10508
10509 if (attribute_flag[0] == 0)
10510 break;
10511 av=(AV *) argument_list[0].array_reference;
10512 order=(size_t) sqrt(av_len(av)+1);
10513 color_matrix=(double *) AcquireQuantumMemory(order,order*
10514 sizeof(*color_matrix));
10515 if (color_matrix == (double *) NULL)
10516 {
10517 ThrowPerlException(exception,ResourceLimitFatalError,
10518 "MemoryAllocationFailed",PackageName);
10519 goto PerlException;
10520 }
10521 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10522 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10523 for ( ; j < (ssize_t) (order*order); j++)
10524 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010525 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010526 if (kernel_info == (KernelInfo *) NULL)
10527 break;
10528 kernel_info->width=order;
10529 kernel_info->height=order;
10530 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10531 order*sizeof(*kernel_info->values));
10532 if (kernel_info->values != (MagickRealType *) NULL)
10533 {
10534 for (i=0; i < (ssize_t) (order*order); i++)
10535 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10536 image=ColorMatrixImage(image,kernel_info,exception);
10537 }
10538 kernel_info=DestroyKernelInfo(kernel_info);
10539 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10540 break;
10541 }
10542 case 109: /* Mask */
10543 {
10544 Image
10545 *mask_image;
10546
10547 if (attribute_flag[0] == 0)
10548 {
10549 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10550 PackageName);
10551 goto PerlException;
10552 }
10553 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10554 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010555 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010556 mask_image=DestroyImage(mask_image);
10557 break;
10558 }
10559 case 110: /* Polaroid */
10560 {
10561 char
10562 *caption;
10563
10564 DrawInfo
10565 *draw_info;
10566
10567 double
10568 angle;
10569
10570 PixelInterpolateMethod
10571 method;
10572
10573 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10574 (DrawInfo *) NULL);
10575 caption=(char *) NULL;
10576 if (attribute_flag[0] != 0)
10577 caption=InterpretImageProperties(info ? info->image_info :
10578 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10579 exception);
10580 angle=0.0;
10581 if (attribute_flag[1] != 0)
10582 angle=argument_list[1].real_reference;
10583 if (attribute_flag[2] != 0)
10584 (void) CloneString(&draw_info->font,
10585 argument_list[2].string_reference);
10586 if (attribute_flag[3] != 0)
10587 (void) QueryColorCompliance(argument_list[3].string_reference,
10588 AllCompliance,&draw_info->stroke,exception);
10589 if (attribute_flag[4] != 0)
10590 (void) QueryColorCompliance(argument_list[4].string_reference,
10591 AllCompliance,&draw_info->fill,exception);
10592 if (attribute_flag[5] != 0)
10593 draw_info->stroke_width=argument_list[5].real_reference;
10594 if (attribute_flag[6] != 0)
10595 draw_info->pointsize=argument_list[6].real_reference;
10596 if (attribute_flag[7] != 0)
10597 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10598 if (attribute_flag[8] != 0)
10599 (void) QueryColorCompliance(argument_list[8].string_reference,
10600 AllCompliance,&image->background_color,exception);
10601 method=UndefinedInterpolatePixel;
10602 if (attribute_flag[9] != 0)
10603 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10604 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10605 draw_info=DestroyDrawInfo(draw_info);
10606 if (caption != (char *) NULL)
10607 caption=DestroyString(caption);
10608 break;
10609 }
10610 case 111: /* FloodfillPaint */
10611 {
10612 DrawInfo
10613 *draw_info;
10614
10615 MagickBooleanType
10616 invert;
10617
10618 PixelInfo
10619 target;
10620
10621 draw_info=CloneDrawInfo(info ? info->image_info :
10622 (ImageInfo *) NULL,(DrawInfo *) NULL);
10623 if (attribute_flag[0] != 0)
10624 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10625 &geometry,exception);
10626 if (attribute_flag[1] != 0)
10627 geometry.x=argument_list[1].integer_reference;
10628 if (attribute_flag[2] != 0)
10629 geometry.y=argument_list[2].integer_reference;
10630 if (attribute_flag[3] != 0)
10631 (void) QueryColorCompliance(argument_list[3].string_reference,
10632 AllCompliance,&draw_info->fill,exception);
10633 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10634 geometry.x,geometry.y,&target,exception);
10635 if (attribute_flag[4] != 0)
10636 QueryColorCompliance(argument_list[4].string_reference,
10637 AllCompliance,&target,exception);
10638 if (attribute_flag[5] != 0)
10639 image->fuzz=StringToDoubleInterval(
10640 argument_list[5].string_reference,(double) QuantumRange+1.0);
10641 if (attribute_flag[6] != 0)
10642 channel=(ChannelType) argument_list[6].integer_reference;
10643 invert=MagickFalse;
10644 if (attribute_flag[7] != 0)
10645 invert=(MagickBooleanType) argument_list[7].integer_reference;
10646 channel_mask=SetImageChannelMask(image,channel);
10647 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10648 geometry.y,invert,exception);
10649 (void) SetImageChannelMask(image,channel_mask);
10650 draw_info=DestroyDrawInfo(draw_info);
10651 break;
10652 }
10653 case 112: /* Distort */
10654 {
10655 AV
10656 *av;
10657
10658 double
10659 *coordinates;
10660
10661 DistortImageMethod
10662 method;
10663
10664 size_t
10665 number_coordinates;
10666
10667 VirtualPixelMethod
10668 virtual_pixel;
10669
10670 if (attribute_flag[0] == 0)
10671 break;
10672 method=UndefinedDistortion;
10673 if (attribute_flag[1] != 0)
10674 method=(DistortImageMethod) argument_list[1].integer_reference;
10675 av=(AV *) argument_list[0].array_reference;
10676 number_coordinates=(size_t) av_len(av)+1;
10677 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10678 sizeof(*coordinates));
10679 if (coordinates == (double *) NULL)
10680 {
10681 ThrowPerlException(exception,ResourceLimitFatalError,
10682 "MemoryAllocationFailed",PackageName);
10683 goto PerlException;
10684 }
10685 for (j=0; j < (ssize_t) number_coordinates; j++)
10686 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10687 virtual_pixel=UndefinedVirtualPixelMethod;
10688 if (attribute_flag[2] != 0)
10689 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10690 argument_list[2].integer_reference,exception);
10691 image=DistortImage(image,method,number_coordinates,coordinates,
10692 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10693 exception);
10694 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10695 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10696 exception);
10697 coordinates=(double *) RelinquishMagickMemory(coordinates);
10698 break;
10699 }
10700 case 113: /* Clut */
10701 {
10702 PixelInterpolateMethod
10703 method;
10704
10705 if (attribute_flag[0] == 0)
10706 {
10707 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10708 PackageName);
10709 goto PerlException;
10710 }
10711 method=UndefinedInterpolatePixel;
10712 if (attribute_flag[1] != 0)
10713 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10714 if (attribute_flag[2] != 0)
10715 channel=(ChannelType) argument_list[2].integer_reference;
10716 channel_mask=SetImageChannelMask(image,channel);
10717 (void) ClutImage(image,argument_list[0].image_reference,method,
10718 exception);
10719 (void) SetImageChannelMask(image,channel_mask);
10720 break;
10721 }
10722 case 114: /* LiquidRescale */
10723 {
10724 if (attribute_flag[0] != 0)
10725 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10726 &geometry,exception);
10727 if (attribute_flag[1] != 0)
10728 geometry.width=argument_list[1].integer_reference;
10729 if (attribute_flag[2] != 0)
10730 geometry.height=argument_list[2].integer_reference;
10731 if (attribute_flag[3] == 0)
10732 argument_list[3].real_reference=1.0;
10733 if (attribute_flag[4] == 0)
10734 argument_list[4].real_reference=0.0;
10735 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10736 argument_list[3].real_reference,argument_list[4].real_reference,
10737 exception);
10738 break;
10739 }
10740 case 115: /* EncipherImage */
10741 {
10742 (void) EncipherImage(image,argument_list[0].string_reference,
10743 exception);
10744 break;
10745 }
10746 case 116: /* DecipherImage */
10747 {
10748 (void) DecipherImage(image,argument_list[0].string_reference,
10749 exception);
10750 break;
10751 }
10752 case 117: /* Deskew */
10753 {
10754 geometry_info.rho=QuantumRange/2.0;
10755 if (attribute_flag[0] != 0)
10756 flags=ParseGeometry(argument_list[0].string_reference,
10757 &geometry_info);
10758 if (attribute_flag[1] != 0)
10759 geometry_info.rho=StringToDoubleInterval(
10760 argument_list[1].string_reference,(double) QuantumRange+1.0);
10761 image=DeskewImage(image,geometry_info.rho,exception);
10762 break;
10763 }
10764 case 118: /* Remap */
10765 {
10766 QuantizeInfo
10767 *quantize_info;
10768
10769 if (attribute_flag[0] == 0)
10770 {
10771 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10772 PackageName);
10773 goto PerlException;
10774 }
10775 quantize_info=AcquireQuantizeInfo(info->image_info);
10776 if (attribute_flag[1] != 0)
10777 quantize_info->dither_method=(DitherMethod)
10778 argument_list[1].integer_reference;
10779 (void) RemapImages(quantize_info,image,
10780 argument_list[0].image_reference,exception);
10781 quantize_info=DestroyQuantizeInfo(quantize_info);
10782 break;
10783 }
10784 case 119: /* SparseColor */
10785 {
10786 AV
10787 *av;
10788
10789 double
10790 *coordinates;
10791
10792 SparseColorMethod
10793 method;
10794
10795 size_t
10796 number_coordinates;
10797
10798 VirtualPixelMethod
10799 virtual_pixel;
10800
10801 if (attribute_flag[0] == 0)
10802 break;
10803 method=UndefinedColorInterpolate;
10804 if (attribute_flag[1] != 0)
10805 method=(SparseColorMethod) argument_list[1].integer_reference;
10806 av=(AV *) argument_list[0].array_reference;
10807 number_coordinates=(size_t) av_len(av)+1;
10808 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10809 sizeof(*coordinates));
10810 if (coordinates == (double *) NULL)
10811 {
10812 ThrowPerlException(exception,ResourceLimitFatalError,
10813 "MemoryAllocationFailed",PackageName);
10814 goto PerlException;
10815 }
10816 for (j=0; j < (ssize_t) number_coordinates; j++)
10817 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10818 virtual_pixel=UndefinedVirtualPixelMethod;
10819 if (attribute_flag[2] != 0)
10820 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10821 argument_list[2].integer_reference,exception);
10822 if (attribute_flag[3] != 0)
10823 channel=(ChannelType) argument_list[3].integer_reference;
10824 channel_mask=SetImageChannelMask(image,channel);
10825 image=SparseColorImage(image,method,number_coordinates,coordinates,
10826 exception);
10827 if (image != (Image *) NULL)
10828 (void) SetImageChannelMask(image,channel_mask);
10829 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10830 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10831 exception);
10832 coordinates=(double *) RelinquishMagickMemory(coordinates);
10833 break;
10834 }
10835 case 120: /* Function */
10836 {
10837 AV
10838 *av;
10839
10840 double
10841 *parameters;
10842
10843 MagickFunction
10844 function;
10845
10846 size_t
10847 number_parameters;
10848
10849 VirtualPixelMethod
10850 virtual_pixel;
10851
10852 if (attribute_flag[0] == 0)
10853 break;
10854 function=UndefinedFunction;
10855 if (attribute_flag[1] != 0)
10856 function=(MagickFunction) argument_list[1].integer_reference;
10857 av=(AV *) argument_list[0].array_reference;
10858 number_parameters=(size_t) av_len(av)+1;
10859 parameters=(double *) AcquireQuantumMemory(number_parameters,
10860 sizeof(*parameters));
10861 if (parameters == (double *) NULL)
10862 {
10863 ThrowPerlException(exception,ResourceLimitFatalError,
10864 "MemoryAllocationFailed",PackageName);
10865 goto PerlException;
10866 }
10867 for (j=0; j < (ssize_t) number_parameters; j++)
10868 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10869 virtual_pixel=UndefinedVirtualPixelMethod;
10870 if (attribute_flag[2] != 0)
10871 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10872 argument_list[2].integer_reference,exception);
10873 (void) FunctionImage(image,function,number_parameters,parameters,
10874 exception);
10875 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10876 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10877 exception);
10878 parameters=(double *) RelinquishMagickMemory(parameters);
10879 break;
10880 }
10881 case 121: /* SelectiveBlur */
10882 {
10883 if (attribute_flag[0] != 0)
10884 {
10885 flags=ParseGeometry(argument_list[0].string_reference,
10886 &geometry_info);
10887 if ((flags & SigmaValue) == 0)
10888 geometry_info.sigma=1.0;
10889 if ((flags & PercentValue) != 0)
10890 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10891 }
10892 if (attribute_flag[1] != 0)
10893 geometry_info.rho=argument_list[1].real_reference;
10894 if (attribute_flag[2] != 0)
10895 geometry_info.sigma=argument_list[2].real_reference;
10896 if (attribute_flag[3] != 0)
10897 geometry_info.xi=argument_list[3].integer_reference;;
10898 if (attribute_flag[5] != 0)
10899 channel=(ChannelType) argument_list[5].integer_reference;
10900 channel_mask=SetImageChannelMask(image,channel);
10901 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10902 geometry_info.xi,exception);
10903 if (image != (Image *) NULL)
10904 (void) SetImageChannelMask(image,channel_mask);
10905 break;
10906 }
10907 case 122: /* HaldClut */
10908 {
10909 if (attribute_flag[0] == 0)
10910 {
10911 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10912 PackageName);
10913 goto PerlException;
10914 }
10915 if (attribute_flag[1] != 0)
10916 channel=(ChannelType) argument_list[1].integer_reference;
10917 channel_mask=SetImageChannelMask(image,channel);
10918 (void) HaldClutImage(image,argument_list[0].image_reference,
10919 exception);
10920 (void) SetImageChannelMask(image,channel_mask);
10921 break;
10922 }
10923 case 123: /* BlueShift */
10924 {
10925 if (attribute_flag[0] != 0)
10926 (void) ParseGeometry(argument_list[0].string_reference,
10927 &geometry_info);
10928 image=BlueShiftImage(image,geometry_info.rho,exception);
10929 break;
10930 }
10931 case 124: /* ForwardFourierTransformImage */
10932 {
10933 image=ForwardFourierTransformImage(image,
10934 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10935 exception);
10936 break;
10937 }
10938 case 125: /* InverseFourierTransformImage */
10939 {
10940 image=InverseFourierTransformImage(image,image->next,
10941 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10942 exception);
10943 break;
10944 }
10945 case 126: /* ColorDecisionList */
10946 {
10947 if (attribute_flag[0] == 0)
10948 argument_list[0].string_reference=(char *) NULL;
10949 (void) ColorDecisionListImage(image,
10950 argument_list[0].string_reference,exception);
10951 break;
10952 }
10953 case 127: /* AutoGamma */
10954 {
10955 if (attribute_flag[0] != 0)
10956 channel=(ChannelType) argument_list[0].integer_reference;
10957 channel_mask=SetImageChannelMask(image,channel);
10958 (void) AutoGammaImage(image,exception);
10959 (void) SetImageChannelMask(image,channel_mask);
10960 break;
10961 }
10962 case 128: /* AutoLevel */
10963 {
10964 if (attribute_flag[0] != 0)
10965 channel=(ChannelType) argument_list[0].integer_reference;
10966 channel_mask=SetImageChannelMask(image,channel);
10967 (void) AutoLevelImage(image,exception);
10968 (void) SetImageChannelMask(image,channel_mask);
10969 break;
10970 }
10971 case 129: /* LevelColors */
10972 {
10973 PixelInfo
10974 black_point,
10975 white_point;
10976
10977 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10978 exception);
10979 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10980 exception);
10981 if (attribute_flag[1] != 0)
10982 (void) QueryColorCompliance(
10983 argument_list[1].string_reference,AllCompliance,&black_point,
10984 exception);
10985 if (attribute_flag[2] != 0)
10986 (void) QueryColorCompliance(
10987 argument_list[2].string_reference,AllCompliance,&white_point,
10988 exception);
10989 if (attribute_flag[3] != 0)
10990 channel=(ChannelType) argument_list[3].integer_reference;
10991 channel_mask=SetImageChannelMask(image,channel);
10992 (void) LevelImageColors(image,&black_point,&white_point,
10993 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10994 exception);
10995 (void) SetImageChannelMask(image,channel_mask);
10996 break;
10997 }
10998 case 130: /* Clamp */
10999 {
11000 if (attribute_flag[0] != 0)
11001 channel=(ChannelType) argument_list[0].integer_reference;
11002 channel_mask=SetImageChannelMask(image,channel);
11003 (void) ClampImage(image,exception);
11004 (void) SetImageChannelMask(image,channel_mask);
11005 break;
11006 }
11007 case 131: /* BrightnessContrast */
11008 {
11009 double
11010 brightness,
11011 contrast;
11012
11013 brightness=0.0;
11014 contrast=0.0;
11015 if (attribute_flag[0] != 0)
11016 {
11017 flags=ParseGeometry(argument_list[0].string_reference,
11018 &geometry_info);
11019 brightness=geometry_info.rho;
11020 if ((flags & SigmaValue) == 0)
11021 contrast=geometry_info.sigma;
11022 }
11023 if (attribute_flag[1] != 0)
11024 brightness=argument_list[1].real_reference;
11025 if (attribute_flag[2] != 0)
11026 contrast=argument_list[2].real_reference;
11027 if (attribute_flag[4] != 0)
11028 channel=(ChannelType) argument_list[4].integer_reference;
11029 channel_mask=SetImageChannelMask(image,channel);
11030 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11031 (void) SetImageChannelMask(image,channel_mask);
11032 break;
11033 }
11034 case 132: /* Morphology */
11035 {
11036 KernelInfo
11037 *kernel;
11038
11039 MorphologyMethod
11040 method;
11041
11042 ssize_t
11043 iterations;
11044
11045 if (attribute_flag[0] == 0)
11046 break;
cristy2c57b742014-10-31 00:40:34 +000011047 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011048 if (kernel == (KernelInfo *) NULL)
11049 break;
11050 if (attribute_flag[1] != 0)
11051 channel=(ChannelType) argument_list[1].integer_reference;
11052 method=UndefinedMorphology;
11053 if (attribute_flag[2] != 0)
11054 method=argument_list[2].integer_reference;
11055 iterations=1;
11056 if (attribute_flag[3] != 0)
11057 iterations=argument_list[3].integer_reference;
11058 channel_mask=SetImageChannelMask(image,channel);
11059 image=MorphologyImage(image,method,iterations,kernel,exception);
11060 if (image != (Image *) NULL)
11061 (void) SetImageChannelMask(image,channel_mask);
11062 kernel=DestroyKernelInfo(kernel);
11063 break;
11064 }
11065 case 133: /* Mode */
11066 {
11067 if (attribute_flag[0] != 0)
11068 {
11069 flags=ParseGeometry(argument_list[0].string_reference,
11070 &geometry_info);
11071 if ((flags & SigmaValue) == 0)
11072 geometry_info.sigma=1.0;
11073 }
11074 if (attribute_flag[1] != 0)
11075 geometry_info.rho=argument_list[1].real_reference;
11076 if (attribute_flag[2] != 0)
11077 geometry_info.sigma=argument_list[2].real_reference;
11078 if (attribute_flag[3] != 0)
11079 channel=(ChannelType) argument_list[3].integer_reference;
11080 channel_mask=SetImageChannelMask(image,channel);
11081 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11082 (size_t) geometry_info.sigma,exception);
11083 if (image != (Image *) NULL)
11084 (void) SetImageChannelMask(image,channel_mask);
11085 break;
11086 }
11087 case 134: /* Statistic */
11088 {
11089 StatisticType
11090 statistic;
11091
11092 statistic=UndefinedStatistic;
11093 if (attribute_flag[0] != 0)
11094 {
11095 flags=ParseGeometry(argument_list[0].string_reference,
11096 &geometry_info);
11097 if ((flags & SigmaValue) == 0)
11098 geometry_info.sigma=1.0;
11099 }
11100 if (attribute_flag[1] != 0)
11101 geometry_info.rho=argument_list[1].real_reference;
11102 if (attribute_flag[2] != 0)
11103 geometry_info.sigma=argument_list[2].real_reference;
11104 if (attribute_flag[3] != 0)
11105 channel=(ChannelType) argument_list[3].integer_reference;
11106 if (attribute_flag[4] != 0)
11107 statistic=(StatisticType) argument_list[4].integer_reference;
11108 channel_mask=SetImageChannelMask(image,channel);
11109 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11110 (size_t) geometry_info.sigma,exception);
11111 if (image != (Image *) NULL)
11112 (void) SetImageChannelMask(image,channel_mask);
11113 break;
11114 }
11115 case 135: /* Perceptible */
11116 {
11117 double
11118 epsilon;
11119
11120 epsilon=MagickEpsilon;
11121 if (attribute_flag[0] != 0)
11122 epsilon=argument_list[0].real_reference;
11123 if (attribute_flag[1] != 0)
11124 channel=(ChannelType) argument_list[1].integer_reference;
11125 channel_mask=SetImageChannelMask(image,channel);
11126 (void) PerceptibleImage(image,epsilon,exception);
11127 (void) SetImageChannelMask(image,channel_mask);
11128 break;
11129 }
11130 case 136: /* Poly */
11131 {
11132 AV
11133 *av;
11134
11135 double
11136 *terms;
11137
11138 size_t
11139 number_terms;
11140
11141 if (attribute_flag[0] == 0)
11142 break;
11143 if (attribute_flag[1] != 0)
11144 channel=(ChannelType) argument_list[1].integer_reference;
11145 av=(AV *) argument_list[0].array_reference;
11146 number_terms=(size_t) av_len(av);
11147 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11148 if (terms == (double *) NULL)
11149 {
11150 ThrowPerlException(exception,ResourceLimitFatalError,
11151 "MemoryAllocationFailed",PackageName);
11152 goto PerlException;
11153 }
11154 for (j=0; j < av_len(av); j++)
11155 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11156 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11157 terms=(double *) RelinquishMagickMemory(terms);
11158 break;
11159 }
11160 case 137: /* Grayscale */
11161 {
11162 PixelIntensityMethod
11163 method;
11164
11165 method=UndefinedPixelIntensityMethod;
11166 if (attribute_flag[0] != 0)
11167 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11168 (void) GrayscaleImage(image,method,exception);
11169 break;
11170 }
cristy4ceadb82014-03-29 15:30:43 +000011171 case 138: /* Canny */
11172 {
11173 if (attribute_flag[0] != 0)
11174 {
11175 flags=ParseGeometry(argument_list[0].string_reference,
11176 &geometry_info);
11177 if ((flags & SigmaValue) == 0)
11178 geometry_info.sigma=1.0;
11179 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011180 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011181 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011182 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011183 if ((flags & PercentValue) != 0)
11184 {
11185 geometry_info.xi/=100.0;
11186 geometry_info.psi/=100.0;
11187 }
cristy4ceadb82014-03-29 15:30:43 +000011188 }
11189 if (attribute_flag[1] != 0)
11190 geometry_info.rho=argument_list[1].real_reference;
11191 if (attribute_flag[2] != 0)
11192 geometry_info.sigma=argument_list[2].real_reference;
11193 if (attribute_flag[3] != 0)
11194 geometry_info.xi=argument_list[3].real_reference;
11195 if (attribute_flag[4] != 0)
11196 geometry_info.psi=argument_list[4].real_reference;
11197 if (attribute_flag[5] != 0)
11198 channel=(ChannelType) argument_list[5].integer_reference;
11199 channel_mask=SetImageChannelMask(image,channel);
11200 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11201 geometry_info.xi,geometry_info.psi,exception);
11202 if (image != (Image *) NULL)
11203 (void) SetImageChannelMask(image,channel_mask);
11204 break;
11205 }
cristy2fc10e52014-04-26 14:13:53 +000011206 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011207 {
11208 if (attribute_flag[0] != 0)
11209 {
11210 flags=ParseGeometry(argument_list[0].string_reference,
11211 &geometry_info);
11212 if ((flags & SigmaValue) == 0)
11213 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011214 if ((flags & XiValue) == 0)
11215 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011216 }
11217 if (attribute_flag[1] != 0)
11218 geometry_info.rho=(double) argument_list[1].integer_reference;
11219 if (attribute_flag[2] != 0)
11220 geometry_info.sigma=(double) argument_list[2].integer_reference;
11221 if (attribute_flag[3] != 0)
11222 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011223 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11224 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11225 break;
11226 }
11227 case 140: /* MeanShift */
11228 {
11229 if (attribute_flag[0] != 0)
11230 {
11231 flags=ParseGeometry(argument_list[0].string_reference,
11232 &geometry_info);
11233 if ((flags & SigmaValue) == 0)
11234 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011235 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011236 geometry_info.xi=0.10*QuantumRange;
11237 if ((flags & PercentValue) != 0)
11238 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011239 }
11240 if (attribute_flag[1] != 0)
11241 geometry_info.rho=(double) argument_list[1].integer_reference;
11242 if (attribute_flag[2] != 0)
11243 geometry_info.sigma=(double) argument_list[2].integer_reference;
11244 if (attribute_flag[3] != 0)
11245 geometry_info.xi=(double) argument_list[3].integer_reference;
11246 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011247 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011248 break;
11249 }
cristy3b207f82014-09-27 14:21:20 +000011250 case 141: /* Kuwahara */
11251 {
11252 if (attribute_flag[0] != 0)
11253 {
11254 flags=ParseGeometry(argument_list[0].string_reference,
11255 &geometry_info);
11256 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011257 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011258 }
11259 if (attribute_flag[1] != 0)
11260 geometry_info.rho=argument_list[1].real_reference;
11261 if (attribute_flag[2] != 0)
11262 geometry_info.sigma=argument_list[2].real_reference;
11263 if (attribute_flag[3] != 0)
11264 channel=(ChannelType) argument_list[3].integer_reference;
11265 channel_mask=SetImageChannelMask(image,channel);
11266 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11267 exception);
11268 if (image != (Image *) NULL)
11269 (void) SetImageChannelMask(image,channel_mask);
11270 break;
11271 }
cristy6e0b3bc2014-10-19 17:51:42 +000011272 case 142: /* ConnectedComponent */
11273 {
11274 size_t
11275 connectivity;
11276
11277 connectivity=4;
11278 if (attribute_flag[0] != 0)
11279 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011280 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011281 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011282 break;
11283 }
cristy0b94b392015-06-22 18:56:37 +000011284 case 143: /* Copy */
11285 {
11286 Image
11287 *source_image;
11288
11289 OffsetInfo
11290 offset;
11291
cristy2ffdb092015-06-25 14:31:20 +000011292 RectangleInfo
11293 offset_geometry;
11294
cristyf3a724a2015-06-25 13:02:53 +000011295 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011296 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011297 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011298 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011299 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011300 flags=ParseGravityGeometry(source_image,
11301 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011302 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011303 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011304 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011305 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011306 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011307 geometry.x=argument_list[4].integer_reference;
11308 if (attribute_flag[5] != 0)
11309 geometry.y=argument_list[5].integer_reference;
11310 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011311 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011312 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011313 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011314 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11315 &offset_geometry,exception);
11316 offset.x=offset_geometry.x;
11317 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011318 if (attribute_flag[8] != 0)
11319 offset.x=argument_list[8].integer_reference;
11320 if (attribute_flag[9] != 0)
11321 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011322 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11323 exception);
cristy0b94b392015-06-22 18:56:37 +000011324 break;
11325 }
cristy4a3ce0a2013-08-03 20:06:59 +000011326 }
11327 if (next != (Image *) NULL)
11328 (void) CatchImageException(next);
11329 if (region_image != (Image *) NULL)
11330 {
11331 /*
11332 Composite region.
cristy83a28a02013-08-03 20:25:48 +000011333 */
cristy4a3ce0a2013-08-03 20:06:59 +000011334 status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11335 region_info.x,region_info.y,exception);
11336 (void) status;
11337 (void) CatchImageException(region_image);
11338 image=DestroyImage(image);
11339 image=region_image;
11340 }
11341 if (image != (Image *) NULL)
11342 {
11343 number_images++;
11344 if (next && (next != image))
11345 {
11346 image->next=next->next;
11347 if (image->next != (Image *) NULL)
11348 image->next->previous=image;
11349 DeleteImageFromRegistry(*pv,next);
11350 }
11351 sv_setiv(*pv,PTR2IV(image));
11352 next=image;
11353 }
11354 if (*pv)
11355 pv++;
11356 }
11357
11358 PerlException:
11359 if (reference_vector)
11360 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11361 InheritPerlException(exception,perl_exception);
11362 exception=DestroyExceptionInfo(exception);
11363 sv_setiv(perl_exception,(IV) number_images);
11364 SvPOK_on(perl_exception);
11365 ST(0)=sv_2mortal(perl_exception);
11366 XSRETURN(1);
11367 }
11368
11369#
11370###############################################################################
11371# #
11372# #
11373# #
11374# M o n t a g e #
11375# #
11376# #
11377# #
11378###############################################################################
11379#
11380#
11381void
11382Montage(ref,...)
11383 Image::Magick ref=NO_INIT
11384 ALIAS:
11385 MontageImage = 1
11386 montage = 2
11387 montageimage = 3
11388 PPCODE:
11389 {
11390 AV
11391 *av;
11392
11393 char
11394 *attribute;
11395
11396 ExceptionInfo
11397 *exception;
11398
11399 HV
11400 *hv;
11401
11402 Image
11403 *image,
11404 *next;
11405
11406 PixelInfo
11407 transparent_color;
11408
11409 MontageInfo
11410 *montage_info;
11411
11412 register ssize_t
11413 i;
11414
11415 ssize_t
11416 sp;
11417
11418 struct PackageInfo
11419 *info;
11420
11421 SV
11422 *av_reference,
11423 *perl_exception,
11424 *reference,
11425 *rv,
11426 *sv;
11427
11428 PERL_UNUSED_VAR(ref);
11429 PERL_UNUSED_VAR(ix);
11430 exception=AcquireExceptionInfo();
11431 perl_exception=newSVpv("",0);
11432 sv=NULL;
11433 attribute=NULL;
11434 if (sv_isobject(ST(0)) == 0)
11435 {
11436 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11437 PackageName);
11438 goto PerlException;
11439 }
11440 reference=SvRV(ST(0));
11441 hv=SvSTASH(reference);
11442 av=newAV();
11443 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11444 SvREFCNT_dec(av);
11445 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11446 if (image == (Image *) NULL)
11447 {
11448 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11449 PackageName);
11450 goto PerlException;
11451 }
11452 /*
11453 Get options.
11454 */
11455 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11456 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11457 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11458 exception);
11459 for (i=2; i < items; i+=2)
11460 {
11461 attribute=(char *) SvPV(ST(i-1),na);
11462 switch (*attribute)
11463 {
11464 case 'B':
11465 case 'b':
11466 {
11467 if (LocaleCompare(attribute,"background") == 0)
11468 {
11469 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11470 &montage_info->background_color,exception);
11471 for (next=image; next; next=next->next)
11472 next->background_color=montage_info->background_color;
11473 break;
11474 }
11475 if (LocaleCompare(attribute,"border") == 0)
11476 {
11477 montage_info->border_width=SvIV(ST(i));
11478 break;
11479 }
11480 if (LocaleCompare(attribute,"bordercolor") == 0)
11481 {
11482 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11483 &montage_info->border_color,exception);
11484 for (next=image; next; next=next->next)
11485 next->border_color=montage_info->border_color;
11486 break;
11487 }
11488 if (LocaleCompare(attribute,"borderwidth") == 0)
11489 {
11490 montage_info->border_width=SvIV(ST(i));
11491 break;
11492 }
11493 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11494 attribute);
11495 break;
11496 }
11497 case 'C':
11498 case 'c':
11499 {
11500 if (LocaleCompare(attribute,"compose") == 0)
11501 {
11502 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11503 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11504 if (sp < 0)
11505 {
11506 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11507 SvPV(ST(i),na));
11508 break;
11509 }
11510 for (next=image; next; next=next->next)
11511 next->compose=(CompositeOperator) sp;
11512 break;
11513 }
11514 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11515 attribute);
11516 break;
11517 }
11518 case 'F':
11519 case 'f':
11520 {
11521 if (LocaleCompare(attribute,"fill") == 0)
11522 {
11523 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11524 &montage_info->fill,exception);
11525 break;
11526 }
11527 if (LocaleCompare(attribute,"font") == 0)
11528 {
11529 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11530 break;
11531 }
11532 if (LocaleCompare(attribute,"frame") == 0)
11533 {
11534 char
11535 *p;
11536
11537 p=SvPV(ST(i),na);
11538 if (IsGeometry(p) == MagickFalse)
11539 {
11540 ThrowPerlException(exception,OptionError,"MissingGeometry",
11541 p);
11542 break;
11543 }
11544 (void) CloneString(&montage_info->frame,p);
11545 if (*p == '\0')
11546 montage_info->frame=(char *) NULL;
11547 break;
11548 }
11549 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11550 attribute);
11551 break;
11552 }
11553 case 'G':
11554 case 'g':
11555 {
11556 if (LocaleCompare(attribute,"geometry") == 0)
11557 {
11558 char
11559 *p;
11560
11561 p=SvPV(ST(i),na);
11562 if (IsGeometry(p) == MagickFalse)
11563 {
11564 ThrowPerlException(exception,OptionError,"MissingGeometry",
11565 p);
11566 break;
11567 }
11568 (void) CloneString(&montage_info->geometry,p);
11569 if (*p == '\0')
11570 montage_info->geometry=(char *) NULL;
11571 break;
11572 }
11573 if (LocaleCompare(attribute,"gravity") == 0)
11574 {
11575 ssize_t
11576 in;
11577
11578 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11579 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11580 if (in < 0)
11581 {
11582 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11583 SvPV(ST(i),na));
11584 return;
11585 }
11586 montage_info->gravity=(GravityType) in;
11587 for (next=image; next; next=next->next)
11588 next->gravity=(GravityType) in;
11589 break;
11590 }
11591 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11592 attribute);
11593 break;
11594 }
11595 case 'L':
11596 case 'l':
11597 {
11598 if (LocaleCompare(attribute,"label") == 0)
11599 {
11600 for (next=image; next; next=next->next)
11601 (void) SetImageProperty(next,"label",InterpretImageProperties(
11602 info ? info->image_info : (ImageInfo *) NULL,next,
11603 SvPV(ST(i),na),exception),exception);
11604 break;
11605 }
11606 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11607 attribute);
11608 break;
11609 }
11610 case 'M':
11611 case 'm':
11612 {
11613 if (LocaleCompare(attribute,"mattecolor") == 0)
11614 {
11615 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11616 &montage_info->matte_color,exception);
11617 for (next=image; next; next=next->next)
11618 next->matte_color=montage_info->matte_color;
11619 break;
11620 }
11621 if (LocaleCompare(attribute,"mode") == 0)
11622 {
11623 ssize_t
11624 in;
11625
11626 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11627 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11628 switch (in)
11629 {
11630 default:
11631 {
11632 ThrowPerlException(exception,OptionError,
11633 "UnrecognizedModeType",SvPV(ST(i),na));
11634 break;
11635 }
11636 case FrameMode:
11637 {
11638 (void) CloneString(&montage_info->frame,"15x15+3+3");
11639 montage_info->shadow=MagickTrue;
11640 break;
11641 }
11642 case UnframeMode:
11643 {
11644 montage_info->frame=(char *) NULL;
11645 montage_info->shadow=MagickFalse;
11646 montage_info->border_width=0;
11647 break;
11648 }
11649 case ConcatenateMode:
11650 {
11651 montage_info->frame=(char *) NULL;
11652 montage_info->shadow=MagickFalse;
11653 (void) CloneString(&montage_info->geometry,"+0+0");
11654 montage_info->border_width=0;
11655 }
11656 }
11657 break;
11658 }
11659 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11660 attribute);
11661 break;
11662 }
11663 case 'P':
11664 case 'p':
11665 {
11666 if (LocaleCompare(attribute,"pointsize") == 0)
11667 {
11668 montage_info->pointsize=SvIV(ST(i));
11669 break;
11670 }
11671 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11672 attribute);
11673 break;
11674 }
11675 case 'S':
11676 case 's':
11677 {
11678 if (LocaleCompare(attribute,"shadow") == 0)
11679 {
11680 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11681 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11682 if (sp < 0)
11683 {
11684 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11685 SvPV(ST(i),na));
11686 break;
11687 }
11688 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11689 break;
11690 }
11691 if (LocaleCompare(attribute,"stroke") == 0)
11692 {
11693 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11694 &montage_info->stroke,exception);
11695 break;
11696 }
11697 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11698 attribute);
11699 break;
11700 }
11701 case 'T':
11702 case 't':
11703 {
11704 if (LocaleCompare(attribute,"texture") == 0)
11705 {
11706 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11707 break;
11708 }
11709 if (LocaleCompare(attribute,"tile") == 0)
11710 {
11711 char *p=SvPV(ST(i),na);
11712 if (IsGeometry(p) == MagickFalse)
11713 {
11714 ThrowPerlException(exception,OptionError,"MissingGeometry",
11715 p);
11716 break;
11717 }
11718 (void) CloneString(&montage_info->tile,p);
11719 if (*p == '\0')
11720 montage_info->tile=(char *) NULL;
11721 break;
11722 }
11723 if (LocaleCompare(attribute,"title") == 0)
11724 {
11725 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11726 break;
11727 }
11728 if (LocaleCompare(attribute,"transparent") == 0)
11729 {
11730 PixelInfo
11731 transparent_color;
11732
11733 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11734 &transparent_color,exception);
11735 for (next=image; next; next=next->next)
11736 (void) TransparentPaintImage(next,&transparent_color,
11737 TransparentAlpha,MagickFalse,exception);
11738 break;
11739 }
11740 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11741 attribute);
11742 break;
11743 }
11744 default:
11745 {
11746 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11747 attribute);
11748 break;
11749 }
11750 }
11751 }
11752 image=MontageImageList(info->image_info,montage_info,image,exception);
11753 montage_info=DestroyMontageInfo(montage_info);
11754 if (image == (Image *) NULL)
11755 goto PerlException;
11756 if (transparent_color.alpha != TransparentAlpha)
11757 for (next=image; next; next=next->next)
11758 (void) TransparentPaintImage(next,&transparent_color,
11759 TransparentAlpha,MagickFalse,exception);
11760 for ( ; image; image=image->next)
11761 {
11762 AddImageToRegistry(sv,image);
11763 rv=newRV(sv);
11764 av_push(av,sv_bless(rv,hv));
11765 SvREFCNT_dec(sv);
11766 }
11767 exception=DestroyExceptionInfo(exception);
11768 ST(0)=av_reference;
11769 SvREFCNT_dec(perl_exception);
11770 XSRETURN(1);
11771
11772 PerlException:
11773 InheritPerlException(exception,perl_exception);
11774 exception=DestroyExceptionInfo(exception);
11775 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11776 SvPOK_on(perl_exception);
11777 ST(0)=sv_2mortal(perl_exception);
11778 XSRETURN(1);
11779 }
11780
11781#
11782###############################################################################
11783# #
11784# #
11785# #
11786# M o r p h #
11787# #
11788# #
11789# #
11790###############################################################################
11791#
11792#
11793void
11794Morph(ref,...)
11795 Image::Magick ref=NO_INIT
11796 ALIAS:
11797 MorphImage = 1
11798 morph = 2
11799 morphimage = 3
11800 PPCODE:
11801 {
11802 AV
11803 *av;
11804
11805 char
11806 *attribute;
11807
11808 ExceptionInfo
11809 *exception;
11810
11811 HV
11812 *hv;
11813
11814 Image
11815 *image;
11816
11817 register ssize_t
11818 i;
11819
11820 ssize_t
11821 number_frames;
11822
11823 struct PackageInfo
11824 *info;
11825
11826 SV
11827 *av_reference,
11828 *perl_exception,
11829 *reference,
11830 *rv,
11831 *sv;
11832
11833 PERL_UNUSED_VAR(ref);
11834 PERL_UNUSED_VAR(ix);
11835 exception=AcquireExceptionInfo();
11836 perl_exception=newSVpv("",0);
11837 sv=NULL;
11838 av=NULL;
11839 attribute=NULL;
11840 if (sv_isobject(ST(0)) == 0)
11841 {
11842 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11843 PackageName);
11844 goto PerlException;
11845 }
11846 reference=SvRV(ST(0));
11847 hv=SvSTASH(reference);
11848 av=newAV();
11849 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11850 SvREFCNT_dec(av);
11851 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11852 if (image == (Image *) NULL)
11853 {
11854 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11855 PackageName);
11856 goto PerlException;
11857 }
11858 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11859 /*
11860 Get attribute.
11861 */
11862 number_frames=30;
11863 for (i=2; i < items; i+=2)
11864 {
11865 attribute=(char *) SvPV(ST(i-1),na);
11866 switch (*attribute)
11867 {
11868 case 'F':
11869 case 'f':
11870 {
11871 if (LocaleCompare(attribute,"frames") == 0)
11872 {
11873 number_frames=SvIV(ST(i));
11874 break;
11875 }
11876 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11877 attribute);
11878 break;
11879 }
11880 default:
11881 {
11882 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11883 attribute);
11884 break;
11885 }
11886 }
11887 }
11888 image=MorphImages(image,number_frames,exception);
11889 if (image == (Image *) NULL)
11890 goto PerlException;
11891 for ( ; image; image=image->next)
11892 {
11893 AddImageToRegistry(sv,image);
11894 rv=newRV(sv);
11895 av_push(av,sv_bless(rv,hv));
11896 SvREFCNT_dec(sv);
11897 }
11898 exception=DestroyExceptionInfo(exception);
11899 ST(0)=av_reference;
11900 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11901 XSRETURN(1);
11902
11903 PerlException:
11904 InheritPerlException(exception,perl_exception);
11905 exception=DestroyExceptionInfo(exception);
11906 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11907 SvPOK_on(perl_exception);
11908 ST(0)=sv_2mortal(perl_exception);
11909 XSRETURN(1);
11910 }
11911
11912#
11913###############################################################################
11914# #
11915# #
11916# #
11917# M o s a i c #
11918# #
11919# #
11920# #
11921###############################################################################
11922#
11923#
11924void
11925Mosaic(ref)
11926 Image::Magick ref=NO_INIT
11927 ALIAS:
11928 MosaicImage = 1
11929 mosaic = 2
11930 mosaicimage = 3
11931 PPCODE:
11932 {
11933 AV
11934 *av;
11935
11936 ExceptionInfo
11937 *exception;
11938
11939 HV
11940 *hv;
11941
11942 Image
11943 *image;
11944
11945 struct PackageInfo
11946 *info;
11947
11948 SV
11949 *perl_exception,
11950 *reference,
11951 *rv,
11952 *sv;
11953
11954 PERL_UNUSED_VAR(ref);
11955 PERL_UNUSED_VAR(ix);
11956 exception=AcquireExceptionInfo();
11957 perl_exception=newSVpv("",0);
11958 sv=NULL;
11959 if (sv_isobject(ST(0)) == 0)
11960 {
11961 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11962 PackageName);
11963 goto PerlException;
11964 }
11965 reference=SvRV(ST(0));
11966 hv=SvSTASH(reference);
11967 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11968 if (image == (Image *) NULL)
11969 {
11970 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11971 PackageName);
11972 goto PerlException;
11973 }
11974 image=MergeImageLayers(image,MosaicLayer,exception);
11975 /*
11976 Create blessed Perl array for the returned image.
11977 */
11978 av=newAV();
11979 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11980 SvREFCNT_dec(av);
11981 AddImageToRegistry(sv,image);
11982 rv=newRV(sv);
11983 av_push(av,sv_bless(rv,hv));
11984 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000011985 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000011986 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000011987 SetImageInfo(info->image_info,0,exception);
11988 exception=DestroyExceptionInfo(exception);
11989 SvREFCNT_dec(perl_exception);
11990 XSRETURN(1);
11991
11992 PerlException:
11993 InheritPerlException(exception,perl_exception);
11994 exception=DestroyExceptionInfo(exception);
11995 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11996 SvPOK_on(perl_exception); /* return messages in string context */
11997 ST(0)=sv_2mortal(perl_exception);
11998 XSRETURN(1);
11999 }
12000
12001#
12002###############################################################################
12003# #
12004# #
12005# #
12006# P i n g #
12007# #
12008# #
12009# #
12010###############################################################################
12011#
12012#
12013void
12014Ping(ref,...)
12015 Image::Magick ref=NO_INIT
12016 ALIAS:
12017 PingImage = 1
12018 ping = 2
12019 pingimage = 3
12020 PPCODE:
12021 {
12022 AV
12023 *av;
12024
12025 char
12026 **keep,
12027 **list;
12028
12029 ExceptionInfo
12030 *exception;
12031
12032 Image
12033 *image,
12034 *next;
12035
12036 int
12037 n;
12038
12039 MagickBooleanType
12040 status;
12041
12042 register char
12043 **p;
12044
12045 register ssize_t
12046 i;
12047
12048 ssize_t
12049 ac;
12050
12051 STRLEN
12052 *length;
12053
12054 struct PackageInfo
12055 *info,
12056 *package_info;
12057
12058 SV
12059 *perl_exception,
12060 *reference;
12061
12062 size_t
12063 count;
12064
12065 PERL_UNUSED_VAR(ref);
12066 PERL_UNUSED_VAR(ix);
12067 exception=AcquireExceptionInfo();
12068 perl_exception=newSVpv("",0);
12069 package_info=(struct PackageInfo *) NULL;
12070 ac=(items < 2) ? 1 : items-1;
12071 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12072 keep=list;
12073 length=(STRLEN *) NULL;
12074 if (list == (char **) NULL)
12075 {
12076 ThrowPerlException(exception,ResourceLimitError,
12077 "MemoryAllocationFailed",PackageName);
12078 goto PerlException;
12079 }
12080 keep=list;
12081 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12082 if (length == (STRLEN *) NULL)
12083 {
12084 ThrowPerlException(exception,ResourceLimitError,
12085 "MemoryAllocationFailed",PackageName);
12086 goto PerlException;
12087 }
12088 if (sv_isobject(ST(0)) == 0)
12089 {
12090 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12091 PackageName);
12092 goto PerlException;
12093 }
12094 reference=SvRV(ST(0));
12095 if (SvTYPE(reference) != SVt_PVAV)
12096 {
12097 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12098 PackageName);
12099 goto PerlException;
12100 }
12101 av=(AV *) reference;
12102 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12103 exception);
12104 package_info=ClonePackageInfo(info,exception);
12105 n=1;
12106 if (items <= 1)
12107 *list=(char *) (*package_info->image_info->filename ?
12108 package_info->image_info->filename : "XC:black");
12109 else
12110 for (n=0, i=0; i < ac; i++)
12111 {
12112 list[n]=(char *) SvPV(ST(i+1),length[n]);
12113 if ((items >= 3) && strEQcase(list[n],"blob"))
12114 {
12115 void
12116 *blob;
12117
12118 i++;
12119 blob=(void *) (SvPV(ST(i+1),length[n]));
12120 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12121 }
12122 if ((items >= 3) && strEQcase(list[n],"filename"))
12123 continue;
12124 if ((items >= 3) && strEQcase(list[n],"file"))
12125 {
12126 FILE
12127 *file;
12128
12129 PerlIO
12130 *io_info;
12131
12132 i++;
12133 io_info=IoIFP(sv_2io(ST(i+1)));
12134 if (io_info == (PerlIO *) NULL)
12135 {
12136 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12137 PackageName);
12138 continue;
12139 }
12140 file=PerlIO_findFILE(io_info);
12141 if (file == (FILE *) NULL)
12142 {
12143 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12144 PackageName);
12145 continue;
12146 }
12147 SetImageInfoFile(package_info->image_info,file);
12148 }
12149 if ((items >= 3) && strEQcase(list[n],"magick"))
12150 continue;
12151 n++;
12152 }
12153 list[n]=(char *) NULL;
12154 keep=list;
12155 status=ExpandFilenames(&n,&list);
12156 if (status == MagickFalse)
12157 {
12158 ThrowPerlException(exception,ResourceLimitError,
12159 "MemoryAllocationFailed",PackageName);
12160 goto PerlException;
12161 }
12162 count=0;
12163 for (i=0; i < n; i++)
12164 {
12165 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012166 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012167 image=PingImage(package_info->image_info,exception);
12168 if (image == (Image *) NULL)
12169 break;
12170 if ((package_info->image_info->file != (FILE *) NULL) ||
12171 (package_info->image_info->blob != (void *) NULL))
12172 DisassociateImageStream(image);
12173 count+=GetImageListLength(image);
12174 EXTEND(sp,4*count);
12175 for (next=image; next; next=next->next)
12176 {
12177 PUSHs(sv_2mortal(newSViv(next->columns)));
12178 PUSHs(sv_2mortal(newSViv(next->rows)));
12179 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12180 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12181 }
12182 image=DestroyImageList(image);
12183 }
12184 /*
12185 Free resources.
12186 */
12187 for (i=0; i < n; i++)
12188 if (list[i] != (char *) NULL)
12189 for (p=keep; list[i] != *p++; )
12190 if (*p == NULL)
12191 {
12192 list[i]=(char *) RelinquishMagickMemory(list[i]);
12193 break;
12194 }
12195
12196 PerlException:
12197 if (package_info != (struct PackageInfo *) NULL)
12198 DestroyPackageInfo(package_info);
12199 if (list && (list != keep))
12200 list=(char **) RelinquishMagickMemory(list);
12201 if (keep)
12202 keep=(char **) RelinquishMagickMemory(keep);
12203 if (length)
12204 length=(STRLEN *) RelinquishMagickMemory(length);
12205 InheritPerlException(exception,perl_exception);
12206 exception=DestroyExceptionInfo(exception);
12207 SvREFCNT_dec(perl_exception); /* throw away all errors */
12208 }
12209
12210#
12211###############################################################################
12212# #
12213# #
12214# #
12215# P r e v i e w #
12216# #
12217# #
12218# #
12219###############################################################################
12220#
12221#
12222void
12223Preview(ref,...)
12224 Image::Magick ref=NO_INIT
12225 ALIAS:
12226 PreviewImage = 1
12227 preview = 2
12228 previewimage = 3
12229 PPCODE:
12230 {
12231 AV
12232 *av;
12233
12234 ExceptionInfo
12235 *exception;
12236
12237 HV
12238 *hv;
12239
12240 Image
12241 *image,
12242 *preview_image;
12243
12244 PreviewType
12245 preview_type;
12246
12247 struct PackageInfo
12248 *info;
12249
12250 SV
12251 *av_reference,
12252 *perl_exception,
12253 *reference,
12254 *rv,
12255 *sv;
12256
12257 PERL_UNUSED_VAR(ref);
12258 PERL_UNUSED_VAR(ix);
12259 exception=AcquireExceptionInfo();
12260 perl_exception=newSVpv("",0);
12261 sv=NULL;
12262 av=NULL;
12263 if (sv_isobject(ST(0)) == 0)
12264 {
12265 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12266 PackageName);
12267 goto PerlException;
12268 }
12269 reference=SvRV(ST(0));
12270 hv=SvSTASH(reference);
12271 av=newAV();
12272 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12273 SvREFCNT_dec(av);
12274 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12275 if (image == (Image *) NULL)
12276 {
12277 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12278 PackageName);
12279 goto PerlException;
12280 }
12281 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12282 preview_type=GammaPreview;
12283 if (items > 1)
12284 preview_type=(PreviewType)
12285 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12286 for ( ; image; image=image->next)
12287 {
12288 preview_image=PreviewImage(image,preview_type,exception);
12289 if (preview_image == (Image *) NULL)
12290 goto PerlException;
12291 AddImageToRegistry(sv,preview_image);
12292 rv=newRV(sv);
12293 av_push(av,sv_bless(rv,hv));
12294 SvREFCNT_dec(sv);
12295 }
12296 exception=DestroyExceptionInfo(exception);
12297 ST(0)=av_reference;
12298 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12299 XSRETURN(1);
12300
12301 PerlException:
12302 InheritPerlException(exception,perl_exception);
12303 exception=DestroyExceptionInfo(exception);
12304 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12305 SvPOK_on(perl_exception);
12306 ST(0)=sv_2mortal(perl_exception);
12307 XSRETURN(1);
12308 }
12309
12310#
12311###############################################################################
12312# #
12313# #
12314# #
12315# Q u e r y C o l o r #
12316# #
12317# #
12318# #
12319###############################################################################
12320#
12321#
12322void
12323QueryColor(ref,...)
12324 Image::Magick ref=NO_INIT
12325 ALIAS:
12326 querycolor = 1
12327 PPCODE:
12328 {
12329 char
12330 *name;
12331
12332 ExceptionInfo
12333 *exception;
12334
12335 PixelInfo
12336 color;
12337
12338 register ssize_t
12339 i;
12340
12341 SV
12342 *perl_exception;
12343
12344 PERL_UNUSED_VAR(ref);
12345 PERL_UNUSED_VAR(ix);
12346 exception=AcquireExceptionInfo();
12347 perl_exception=newSVpv("",0);
12348 if (items == 1)
12349 {
12350 const ColorInfo
12351 **colorlist;
12352
12353 size_t
12354 colors;
12355
12356 colorlist=GetColorInfoList("*",&colors,exception);
12357 EXTEND(sp,colors);
12358 for (i=0; i < (ssize_t) colors; i++)
12359 {
12360 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12361 }
12362 colorlist=(const ColorInfo **)
12363 RelinquishMagickMemory((ColorInfo **) colorlist);
12364 goto PerlException;
12365 }
12366 EXTEND(sp,5*items);
12367 for (i=1; i < items; i++)
12368 {
12369 name=(char *) SvPV(ST(i),na);
12370 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12371 {
12372 PUSHs(&sv_undef);
12373 continue;
12374 }
12375 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12376 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12377 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12378 if (color.colorspace == CMYKColorspace)
12379 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012380 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012381 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12382 }
12383
12384 PerlException:
12385 InheritPerlException(exception,perl_exception);
12386 exception=DestroyExceptionInfo(exception);
12387 SvREFCNT_dec(perl_exception);
12388 }
12389
12390#
12391###############################################################################
12392# #
12393# #
12394# #
12395# Q u e r y C o l o r N a m e #
12396# #
12397# #
12398# #
12399###############################################################################
12400#
12401#
12402void
12403QueryColorname(ref,...)
12404 Image::Magick ref=NO_INIT
12405 ALIAS:
12406 querycolorname = 1
12407 PPCODE:
12408 {
12409 AV
12410 *av;
12411
12412 char
cristy151b66d2015-04-15 10:50:31 +000012413 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012414
12415 ExceptionInfo
12416 *exception;
12417
12418 Image
12419 *image;
12420
12421 PixelInfo
12422 target_color;
12423
12424 register ssize_t
12425 i;
12426
12427 struct PackageInfo
12428 *info;
12429
12430 SV
12431 *perl_exception,
12432 *reference; /* reference is the SV* of ref=SvIV(reference) */
12433
12434 PERL_UNUSED_VAR(ref);
12435 PERL_UNUSED_VAR(ix);
12436 exception=AcquireExceptionInfo();
12437 perl_exception=newSVpv("",0);
12438 reference=SvRV(ST(0));
12439 av=(AV *) reference;
12440 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12441 exception);
12442 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12443 if (image == (Image *) NULL)
12444 {
12445 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12446 PackageName);
12447 goto PerlException;
12448 }
12449 EXTEND(sp,items);
12450 for (i=1; i < items; i++)
12451 {
12452 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12453 exception);
12454 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12455 exception);
12456 PUSHs(sv_2mortal(newSVpv(message,0)));
12457 }
12458
12459 PerlException:
12460 InheritPerlException(exception,perl_exception);
12461 exception=DestroyExceptionInfo(exception);
12462 SvREFCNT_dec(perl_exception);
12463 }
12464
12465#
12466###############################################################################
12467# #
12468# #
12469# #
12470# Q u e r y F o n t #
12471# #
12472# #
12473# #
12474###############################################################################
12475#
12476#
12477void
12478QueryFont(ref,...)
12479 Image::Magick ref=NO_INIT
12480 ALIAS:
12481 queryfont = 1
12482 PPCODE:
12483 {
12484 char
12485 *name,
cristy151b66d2015-04-15 10:50:31 +000012486 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012487
12488 ExceptionInfo
12489 *exception;
12490
12491 register ssize_t
12492 i;
12493
12494 SV
12495 *perl_exception;
12496
12497 volatile const TypeInfo
12498 *type_info;
12499
12500 PERL_UNUSED_VAR(ref);
12501 PERL_UNUSED_VAR(ix);
12502 exception=AcquireExceptionInfo();
12503 perl_exception=newSVpv("",0);
12504 if (items == 1)
12505 {
12506 const TypeInfo
12507 **typelist;
12508
12509 size_t
12510 types;
12511
12512 typelist=GetTypeInfoList("*",&types,exception);
12513 EXTEND(sp,types);
12514 for (i=0; i < (ssize_t) types; i++)
12515 {
12516 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12517 }
12518 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12519 typelist);
12520 goto PerlException;
12521 }
12522 EXTEND(sp,10*items);
12523 for (i=1; i < items; i++)
12524 {
12525 name=(char *) SvPV(ST(i),na);
12526 type_info=GetTypeInfo(name,exception);
12527 if (type_info == (TypeInfo *) NULL)
12528 {
12529 PUSHs(&sv_undef);
12530 continue;
12531 }
12532 if (type_info->name == (char *) NULL)
12533 PUSHs(&sv_undef);
12534 else
12535 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12536 if (type_info->description == (char *) NULL)
12537 PUSHs(&sv_undef);
12538 else
12539 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12540 if (type_info->family == (char *) NULL)
12541 PUSHs(&sv_undef);
12542 else
12543 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12544 if (type_info->style == UndefinedStyle)
12545 PUSHs(&sv_undef);
12546 else
12547 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12548 type_info->style),0)));
12549 if (type_info->stretch == UndefinedStretch)
12550 PUSHs(&sv_undef);
12551 else
12552 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12553 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012554 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012555 type_info->weight);
12556 PUSHs(sv_2mortal(newSVpv(message,0)));
12557 if (type_info->encoding == (char *) NULL)
12558 PUSHs(&sv_undef);
12559 else
12560 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12561 if (type_info->foundry == (char *) NULL)
12562 PUSHs(&sv_undef);
12563 else
12564 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12565 if (type_info->format == (char *) NULL)
12566 PUSHs(&sv_undef);
12567 else
12568 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12569 if (type_info->metrics == (char *) NULL)
12570 PUSHs(&sv_undef);
12571 else
12572 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12573 if (type_info->glyphs == (char *) NULL)
12574 PUSHs(&sv_undef);
12575 else
12576 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12577 }
12578
12579 PerlException:
12580 InheritPerlException(exception,perl_exception);
12581 exception=DestroyExceptionInfo(exception);
12582 SvREFCNT_dec(perl_exception);
12583 }
12584
12585#
12586###############################################################################
12587# #
12588# #
12589# #
12590# Q u e r y F o n t M e t r i c s #
12591# #
12592# #
12593# #
12594###############################################################################
12595#
12596#
12597void
12598QueryFontMetrics(ref,...)
12599 Image::Magick ref=NO_INIT
12600 ALIAS:
12601 queryfontmetrics = 1
12602 PPCODE:
12603 {
12604 AffineMatrix
12605 affine,
12606 current;
12607
12608 AV
12609 *av;
12610
12611 char
12612 *attribute;
12613
12614 double
12615 x,
12616 y;
12617
12618 DrawInfo
12619 *draw_info;
12620
12621 ExceptionInfo
12622 *exception;
12623
12624 GeometryInfo
12625 geometry_info;
12626
12627 Image
12628 *image;
12629
12630 MagickBooleanType
12631 status;
12632
12633 MagickStatusType
12634 flags;
12635
12636 register ssize_t
12637 i;
12638
12639 ssize_t
12640 type;
12641
12642 struct PackageInfo
12643 *info,
12644 *package_info;
12645
12646 SV
12647 *perl_exception,
12648 *reference; /* reference is the SV* of ref=SvIV(reference) */
12649
12650 TypeMetric
12651 metrics;
12652
12653 PERL_UNUSED_VAR(ref);
12654 PERL_UNUSED_VAR(ix);
12655 exception=AcquireExceptionInfo();
12656 package_info=(struct PackageInfo *) NULL;
12657 perl_exception=newSVpv("",0);
12658 reference=SvRV(ST(0));
12659 av=(AV *) reference;
12660 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12661 exception);
12662 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12663 if (image == (Image *) NULL)
12664 {
12665 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12666 PackageName);
12667 goto PerlException;
12668 }
12669 package_info=ClonePackageInfo(info,exception);
12670 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12671 CloneString(&draw_info->text,"");
12672 current=draw_info->affine;
12673 GetAffineMatrix(&affine);
12674 x=0.0;
12675 y=0.0;
12676 EXTEND(sp,7*items);
12677 for (i=2; i < items; i+=2)
12678 {
12679 attribute=(char *) SvPV(ST(i-1),na);
12680 switch (*attribute)
12681 {
12682 case 'A':
12683 case 'a':
12684 {
12685 if (LocaleCompare(attribute,"antialias") == 0)
12686 {
12687 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12688 SvPV(ST(i),na));
12689 if (type < 0)
12690 {
12691 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12692 SvPV(ST(i),na));
12693 break;
12694 }
12695 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12696 break;
12697 }
12698 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12699 attribute);
12700 break;
12701 }
12702 case 'd':
12703 case 'D':
12704 {
12705 if (LocaleCompare(attribute,"density") == 0)
12706 {
12707 CloneString(&draw_info->density,SvPV(ST(i),na));
12708 break;
12709 }
12710 if (LocaleCompare(attribute,"direction") == 0)
12711 {
12712 draw_info->direction=(DirectionType) ParseCommandOption(
12713 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12714 break;
12715 }
12716 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12717 attribute);
12718 break;
12719 }
12720 case 'e':
12721 case 'E':
12722 {
12723 if (LocaleCompare(attribute,"encoding") == 0)
12724 {
12725 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12726 break;
12727 }
12728 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12729 attribute);
12730 break;
12731 }
12732 case 'f':
12733 case 'F':
12734 {
12735 if (LocaleCompare(attribute,"family") == 0)
12736 {
12737 CloneString(&draw_info->family,SvPV(ST(i),na));
12738 break;
12739 }
12740 if (LocaleCompare(attribute,"fill") == 0)
12741 {
12742 if (info)
12743 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12744 &draw_info->fill,exception);
12745 break;
12746 }
12747 if (LocaleCompare(attribute,"font") == 0)
12748 {
12749 CloneString(&draw_info->font,SvPV(ST(i),na));
12750 break;
12751 }
12752 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12753 attribute);
12754 break;
12755 }
12756 case 'g':
12757 case 'G':
12758 {
12759 if (LocaleCompare(attribute,"geometry") == 0)
12760 {
12761 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12762 break;
12763 }
12764 if (LocaleCompare(attribute,"gravity") == 0)
12765 {
12766 draw_info->gravity=(GravityType) ParseCommandOption(
12767 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12768 break;
12769 }
12770 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12771 attribute);
12772 break;
12773 }
12774 case 'i':
12775 case 'I':
12776 {
12777 if (LocaleCompare(attribute,"interline-spacing") == 0)
12778 {
12779 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12780 draw_info->interline_spacing=geometry_info.rho;
12781 break;
12782 }
12783 if (LocaleCompare(attribute,"interword-spacing") == 0)
12784 {
12785 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12786 draw_info->interword_spacing=geometry_info.rho;
12787 break;
12788 }
12789 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12790 attribute);
12791 break;
12792 }
12793 case 'k':
12794 case 'K':
12795 {
12796 if (LocaleCompare(attribute,"kerning") == 0)
12797 {
12798 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12799 draw_info->kerning=geometry_info.rho;
12800 break;
12801 }
12802 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12803 attribute);
12804 break;
12805 }
12806 case 'p':
12807 case 'P':
12808 {
12809 if (LocaleCompare(attribute,"pointsize") == 0)
12810 {
12811 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12812 draw_info->pointsize=geometry_info.rho;
12813 break;
12814 }
12815 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12816 attribute);
12817 break;
12818 }
12819 case 'r':
12820 case 'R':
12821 {
12822 if (LocaleCompare(attribute,"rotate") == 0)
12823 {
12824 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12825 affine.rx=geometry_info.rho;
12826 affine.ry=geometry_info.sigma;
12827 if ((flags & SigmaValue) == 0)
12828 affine.ry=affine.rx;
12829 break;
12830 }
12831 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12832 attribute);
12833 break;
12834 }
12835 case 's':
12836 case 'S':
12837 {
12838 if (LocaleCompare(attribute,"scale") == 0)
12839 {
12840 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12841 affine.sx=geometry_info.rho;
12842 affine.sy=geometry_info.sigma;
12843 if ((flags & SigmaValue) == 0)
12844 affine.sy=affine.sx;
12845 break;
12846 }
12847 if (LocaleCompare(attribute,"skew") == 0)
12848 {
12849 double
12850 x_angle,
12851 y_angle;
12852
12853 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12854 x_angle=geometry_info.rho;
12855 y_angle=geometry_info.sigma;
12856 if ((flags & SigmaValue) == 0)
12857 y_angle=x_angle;
12858 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12859 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12860 break;
12861 }
12862 if (LocaleCompare(attribute,"stroke") == 0)
12863 {
12864 if (info)
12865 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12866 &draw_info->stroke,exception);
12867 break;
12868 }
12869 if (LocaleCompare(attribute,"style") == 0)
12870 {
12871 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12872 SvPV(ST(i),na));
12873 if (type < 0)
12874 {
12875 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12876 SvPV(ST(i),na));
12877 break;
12878 }
12879 draw_info->style=(StyleType) type;
12880 break;
12881 }
12882 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12883 attribute);
12884 break;
12885 }
12886 case 't':
12887 case 'T':
12888 {
12889 if (LocaleCompare(attribute,"text") == 0)
12890 {
12891 CloneString(&draw_info->text,SvPV(ST(i),na));
12892 break;
12893 }
12894 if (LocaleCompare(attribute,"translate") == 0)
12895 {
12896 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12897 affine.tx=geometry_info.rho;
12898 affine.ty=geometry_info.sigma;
12899 if ((flags & SigmaValue) == 0)
12900 affine.ty=affine.tx;
12901 break;
12902 }
12903 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12904 attribute);
12905 break;
12906 }
12907 case 'w':
12908 case 'W':
12909 {
12910 if (LocaleCompare(attribute,"weight") == 0)
12911 {
12912 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12913 draw_info->weight=(size_t) geometry_info.rho;
12914 break;
12915 }
12916 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12917 attribute);
12918 break;
12919 }
12920 case 'x':
12921 case 'X':
12922 {
12923 if (LocaleCompare(attribute,"x") == 0)
12924 {
12925 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12926 x=geometry_info.rho;
12927 break;
12928 }
12929 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12930 attribute);
12931 break;
12932 }
12933 case 'y':
12934 case 'Y':
12935 {
12936 if (LocaleCompare(attribute,"y") == 0)
12937 {
12938 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12939 y=geometry_info.rho;
12940 break;
12941 }
12942 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12943 attribute);
12944 break;
12945 }
12946 default:
12947 {
12948 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12949 attribute);
12950 break;
12951 }
12952 }
12953 }
12954 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12955 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12956 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12957 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12958 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12959 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12960 if (draw_info->geometry == (char *) NULL)
12961 {
12962 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000012963 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000012964 "%.15g,%.15g",x,y);
12965 }
12966 status=GetTypeMetrics(image,draw_info,&metrics,exception);
12967 (void) CatchImageException(image);
12968 if (status == MagickFalse)
12969 PUSHs(&sv_undef);
12970 else
12971 {
12972 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12973 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12974 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12975 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12976 PUSHs(sv_2mortal(newSVnv(metrics.width)));
12977 PUSHs(sv_2mortal(newSVnv(metrics.height)));
12978 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12979 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
12980 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
12981 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
12982 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
12983 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
12984 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
12985 }
12986 draw_info=DestroyDrawInfo(draw_info);
12987
12988 PerlException:
12989 if (package_info != (struct PackageInfo *) NULL)
12990 DestroyPackageInfo(package_info);
12991 InheritPerlException(exception,perl_exception);
12992 exception=DestroyExceptionInfo(exception);
12993 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12994 }
12995
12996#
12997###############################################################################
12998# #
12999# #
13000# #
13001# 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 #
13002# #
13003# #
13004# #
13005###############################################################################
13006#
13007#
13008void
13009QueryMultilineFontMetrics(ref,...)
13010 Image::Magick ref=NO_INIT
13011 ALIAS:
13012 querymultilinefontmetrics = 1
13013 PPCODE:
13014 {
13015 AffineMatrix
13016 affine,
13017 current;
13018
13019 AV
13020 *av;
13021
13022 char
13023 *attribute;
13024
13025 double
13026 x,
13027 y;
13028
13029 DrawInfo
13030 *draw_info;
13031
13032 ExceptionInfo
13033 *exception;
13034
13035 GeometryInfo
13036 geometry_info;
13037
13038 Image
13039 *image;
13040
13041 MagickBooleanType
13042 status;
13043
13044 MagickStatusType
13045 flags;
13046
13047 register ssize_t
13048 i;
13049
13050 ssize_t
13051 type;
13052
13053 struct PackageInfo
13054 *info,
13055 *package_info;
13056
13057 SV
13058 *perl_exception,
13059 *reference; /* reference is the SV* of ref=SvIV(reference) */
13060
13061 TypeMetric
13062 metrics;
13063
13064 PERL_UNUSED_VAR(ref);
13065 PERL_UNUSED_VAR(ix);
13066 exception=AcquireExceptionInfo();
13067 package_info=(struct PackageInfo *) NULL;
13068 perl_exception=newSVpv("",0);
13069 reference=SvRV(ST(0));
13070 av=(AV *) reference;
13071 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13072 exception);
13073 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13074 if (image == (Image *) NULL)
13075 {
13076 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13077 PackageName);
13078 goto PerlException;
13079 }
13080 package_info=ClonePackageInfo(info,exception);
13081 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13082 CloneString(&draw_info->text,"");
13083 current=draw_info->affine;
13084 GetAffineMatrix(&affine);
13085 x=0.0;
13086 y=0.0;
13087 EXTEND(sp,7*items);
13088 for (i=2; i < items; i+=2)
13089 {
13090 attribute=(char *) SvPV(ST(i-1),na);
13091 switch (*attribute)
13092 {
13093 case 'A':
13094 case 'a':
13095 {
13096 if (LocaleCompare(attribute,"antialias") == 0)
13097 {
13098 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13099 SvPV(ST(i),na));
13100 if (type < 0)
13101 {
13102 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13103 SvPV(ST(i),na));
13104 break;
13105 }
13106 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13107 break;
13108 }
13109 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13110 attribute);
13111 break;
13112 }
13113 case 'd':
13114 case 'D':
13115 {
13116 if (LocaleCompare(attribute,"density") == 0)
13117 {
13118 CloneString(&draw_info->density,SvPV(ST(i),na));
13119 break;
13120 }
13121 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13122 attribute);
13123 break;
13124 }
13125 case 'e':
13126 case 'E':
13127 {
13128 if (LocaleCompare(attribute,"encoding") == 0)
13129 {
13130 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13131 break;
13132 }
13133 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13134 attribute);
13135 break;
13136 }
13137 case 'f':
13138 case 'F':
13139 {
13140 if (LocaleCompare(attribute,"family") == 0)
13141 {
13142 CloneString(&draw_info->family,SvPV(ST(i),na));
13143 break;
13144 }
13145 if (LocaleCompare(attribute,"fill") == 0)
13146 {
13147 if (info)
13148 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13149 &draw_info->fill,exception);
13150 break;
13151 }
13152 if (LocaleCompare(attribute,"font") == 0)
13153 {
13154 CloneString(&draw_info->font,SvPV(ST(i),na));
13155 break;
13156 }
13157 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13158 attribute);
13159 break;
13160 }
13161 case 'g':
13162 case 'G':
13163 {
13164 if (LocaleCompare(attribute,"geometry") == 0)
13165 {
13166 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13167 break;
13168 }
13169 if (LocaleCompare(attribute,"gravity") == 0)
13170 {
13171 draw_info->gravity=(GravityType) ParseCommandOption(
13172 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13173 break;
13174 }
13175 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13176 attribute);
13177 break;
13178 }
13179 case 'p':
13180 case 'P':
13181 {
13182 if (LocaleCompare(attribute,"pointsize") == 0)
13183 {
13184 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13185 draw_info->pointsize=geometry_info.rho;
13186 break;
13187 }
13188 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13189 attribute);
13190 break;
13191 }
13192 case 'r':
13193 case 'R':
13194 {
13195 if (LocaleCompare(attribute,"rotate") == 0)
13196 {
13197 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13198 affine.rx=geometry_info.rho;
13199 affine.ry=geometry_info.sigma;
13200 if ((flags & SigmaValue) == 0)
13201 affine.ry=affine.rx;
13202 break;
13203 }
13204 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13205 attribute);
13206 break;
13207 }
13208 case 's':
13209 case 'S':
13210 {
13211 if (LocaleCompare(attribute,"scale") == 0)
13212 {
13213 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13214 affine.sx=geometry_info.rho;
13215 affine.sy=geometry_info.sigma;
13216 if ((flags & SigmaValue) == 0)
13217 affine.sy=affine.sx;
13218 break;
13219 }
13220 if (LocaleCompare(attribute,"skew") == 0)
13221 {
13222 double
13223 x_angle,
13224 y_angle;
13225
13226 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13227 x_angle=geometry_info.rho;
13228 y_angle=geometry_info.sigma;
13229 if ((flags & SigmaValue) == 0)
13230 y_angle=x_angle;
13231 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13232 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13233 break;
13234 }
13235 if (LocaleCompare(attribute,"stroke") == 0)
13236 {
13237 if (info)
13238 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13239 &draw_info->stroke,exception);
13240 break;
13241 }
13242 if (LocaleCompare(attribute,"style") == 0)
13243 {
13244 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13245 SvPV(ST(i),na));
13246 if (type < 0)
13247 {
13248 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13249 SvPV(ST(i),na));
13250 break;
13251 }
13252 draw_info->style=(StyleType) type;
13253 break;
13254 }
13255 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13256 attribute);
13257 break;
13258 }
13259 case 't':
13260 case 'T':
13261 {
13262 if (LocaleCompare(attribute,"text") == 0)
13263 {
13264 CloneString(&draw_info->text,SvPV(ST(i),na));
13265 break;
13266 }
13267 if (LocaleCompare(attribute,"translate") == 0)
13268 {
13269 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13270 affine.tx=geometry_info.rho;
13271 affine.ty=geometry_info.sigma;
13272 if ((flags & SigmaValue) == 0)
13273 affine.ty=affine.tx;
13274 break;
13275 }
13276 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13277 attribute);
13278 break;
13279 }
13280 case 'w':
13281 case 'W':
13282 {
13283 if (LocaleCompare(attribute,"weight") == 0)
13284 {
13285 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13286 draw_info->weight=(size_t) geometry_info.rho;
13287 break;
13288 }
13289 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13290 attribute);
13291 break;
13292 }
13293 case 'x':
13294 case 'X':
13295 {
13296 if (LocaleCompare(attribute,"x") == 0)
13297 {
13298 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13299 x=geometry_info.rho;
13300 break;
13301 }
13302 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13303 attribute);
13304 break;
13305 }
13306 case 'y':
13307 case 'Y':
13308 {
13309 if (LocaleCompare(attribute,"y") == 0)
13310 {
13311 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13312 y=geometry_info.rho;
13313 break;
13314 }
13315 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13316 attribute);
13317 break;
13318 }
13319 default:
13320 {
13321 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13322 attribute);
13323 break;
13324 }
13325 }
13326 }
13327 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13328 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13329 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13330 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13331 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13332 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13333 if (draw_info->geometry == (char *) NULL)
13334 {
13335 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013336 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013337 "%.15g,%.15g",x,y);
13338 }
13339 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13340 (void) CatchException(exception);
13341 if (status == MagickFalse)
13342 PUSHs(&sv_undef);
13343 else
13344 {
13345 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13346 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13347 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13348 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13349 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13350 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13351 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13352 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13353 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13354 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13355 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13356 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13357 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13358 }
13359 draw_info=DestroyDrawInfo(draw_info);
13360
13361 PerlException:
13362 if (package_info != (struct PackageInfo *) NULL)
13363 DestroyPackageInfo(package_info);
13364 InheritPerlException(exception,perl_exception);
13365 exception=DestroyExceptionInfo(exception);
13366 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13367 }
13368
13369#
13370###############################################################################
13371# #
13372# #
13373# #
13374# Q u e r y F o r m a t #
13375# #
13376# #
13377# #
13378###############################################################################
13379#
13380#
13381void
13382QueryFormat(ref,...)
13383 Image::Magick ref=NO_INIT
13384 ALIAS:
13385 queryformat = 1
13386 PPCODE:
13387 {
13388 char
13389 *name;
13390
13391 ExceptionInfo
13392 *exception;
13393
13394 register ssize_t
13395 i;
13396
13397 SV
13398 *perl_exception;
13399
13400 volatile const MagickInfo
13401 *magick_info;
13402
13403 PERL_UNUSED_VAR(ref);
13404 PERL_UNUSED_VAR(ix);
13405 exception=AcquireExceptionInfo();
13406 perl_exception=newSVpv("",0);
13407 if (items == 1)
13408 {
13409 char
cristy151b66d2015-04-15 10:50:31 +000013410 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013411
13412 const MagickInfo
13413 **format_list;
13414
13415 size_t
13416 types;
13417
13418 format_list=GetMagickInfoList("*",&types,exception);
13419 EXTEND(sp,types);
13420 for (i=0; i < (ssize_t) types; i++)
13421 {
cristy151b66d2015-04-15 10:50:31 +000013422 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013423 LocaleLower(format);
13424 PUSHs(sv_2mortal(newSVpv(format,0)));
13425 }
13426 format_list=(const MagickInfo **)
13427 RelinquishMagickMemory((MagickInfo *) format_list);
13428 goto PerlException;
13429 }
13430 EXTEND(sp,8*items);
13431 for (i=1; i < items; i++)
13432 {
13433 name=(char *) SvPV(ST(i),na);
13434 magick_info=GetMagickInfo(name,exception);
13435 if (magick_info == (const MagickInfo *) NULL)
13436 {
13437 PUSHs(&sv_undef);
13438 continue;
13439 }
cristy4a3ce0a2013-08-03 20:06:59 +000013440 if (magick_info->description == (char *) NULL)
13441 PUSHs(&sv_undef);
13442 else
13443 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13444 if (magick_info->module == (char *) NULL)
13445 PUSHs(&sv_undef);
13446 else
13447 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13448 }
13449
13450 PerlException:
13451 InheritPerlException(exception,perl_exception);
13452 exception=DestroyExceptionInfo(exception);
13453 SvREFCNT_dec(perl_exception);
13454 }
13455
13456#
13457###############################################################################
13458# #
13459# #
13460# #
13461# Q u e r y O p t i o n #
13462# #
13463# #
13464# #
13465###############################################################################
13466#
13467#
13468void
13469QueryOption(ref,...)
13470 Image::Magick ref=NO_INIT
13471 ALIAS:
13472 queryoption = 1
13473 PPCODE:
13474 {
13475 char
13476 **options;
13477
13478 ExceptionInfo
13479 *exception;
13480
13481 register ssize_t
13482 i;
13483
13484 ssize_t
13485 j,
13486 option;
13487
13488 SV
13489 *perl_exception;
13490
13491 PERL_UNUSED_VAR(ref);
13492 PERL_UNUSED_VAR(ix);
13493 exception=AcquireExceptionInfo();
13494 perl_exception=newSVpv("",0);
13495 EXTEND(sp,8*items);
13496 for (i=1; i < items; i++)
13497 {
13498 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13499 SvPV(ST(i),na));
13500 options=GetCommandOptions((CommandOption) option);
13501 if (options == (char **) NULL)
13502 PUSHs(&sv_undef);
13503 else
13504 {
13505 for (j=0; options[j] != (char *) NULL; j++)
13506 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13507 options=DestroyStringList(options);
13508 }
13509 }
13510
13511 InheritPerlException(exception,perl_exception);
13512 exception=DestroyExceptionInfo(exception);
13513 SvREFCNT_dec(perl_exception);
13514 }
13515
13516#
13517###############################################################################
13518# #
13519# #
13520# #
13521# R e a d #
13522# #
13523# #
13524# #
13525###############################################################################
13526#
13527#
13528void
13529Read(ref,...)
13530 Image::Magick ref=NO_INIT
13531 ALIAS:
13532 ReadImage = 1
13533 read = 2
13534 readimage = 3
13535 PPCODE:
13536 {
13537 AV
13538 *av;
13539
13540 char
13541 **keep,
13542 **list;
13543
13544 ExceptionInfo
13545 *exception;
13546
13547 HV
13548 *hv;
13549
13550 Image
13551 *image;
13552
13553 int
13554 n;
13555
13556 MagickBooleanType
13557 status;
13558
13559 register char
13560 **p;
13561
13562 register ssize_t
13563 i;
13564
13565 ssize_t
13566 ac,
13567 number_images;
13568
13569 STRLEN
13570 *length;
13571
13572 struct PackageInfo
13573 *info,
13574 *package_info;
13575
13576 SV
13577 *perl_exception, /* Perl variable for storing messages */
13578 *reference,
13579 *rv,
13580 *sv;
13581
13582 PERL_UNUSED_VAR(ref);
13583 PERL_UNUSED_VAR(ix);
13584 exception=AcquireExceptionInfo();
13585 perl_exception=newSVpv("",0);
13586 sv=NULL;
13587 package_info=(struct PackageInfo *) NULL;
13588 number_images=0;
13589 ac=(items < 2) ? 1 : items-1;
13590 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13591 keep=list;
13592 length=(STRLEN *) NULL;
13593 if (list == (char **) NULL)
13594 {
13595 ThrowPerlException(exception,ResourceLimitError,
13596 "MemoryAllocationFailed",PackageName);
13597 goto PerlException;
13598 }
13599 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13600 if (length == (STRLEN *) NULL)
13601 {
13602 ThrowPerlException(exception,ResourceLimitError,
13603 "MemoryAllocationFailed",PackageName);
13604 goto PerlException;
13605 }
13606 if (sv_isobject(ST(0)) == 0)
13607 {
13608 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13609 PackageName);
13610 goto PerlException;
13611 }
13612 reference=SvRV(ST(0));
13613 hv=SvSTASH(reference);
13614 if (SvTYPE(reference) != SVt_PVAV)
13615 {
13616 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13617 PackageName);
13618 goto PerlException;
13619 }
13620 av=(AV *) reference;
13621 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13622 exception);
13623 package_info=ClonePackageInfo(info,exception);
13624 n=1;
13625 if (items <= 1)
13626 *list=(char *) (*package_info->image_info->filename ?
13627 package_info->image_info->filename : "XC:black");
13628 else
13629 for (n=0, i=0; i < ac; i++)
13630 {
13631 list[n]=(char *) SvPV(ST(i+1),length[n]);
13632 if ((items >= 3) && strEQcase(list[n],"blob"))
13633 {
13634 void
13635 *blob;
13636
13637 i++;
13638 blob=(void *) (SvPV(ST(i+1),length[n]));
13639 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13640 }
13641 if ((items >= 3) && strEQcase(list[n],"filename"))
13642 continue;
13643 if ((items >= 3) && strEQcase(list[n],"file"))
13644 {
13645 FILE
13646 *file;
13647
13648 PerlIO
13649 *io_info;
13650
13651 i++;
13652 io_info=IoIFP(sv_2io(ST(i+1)));
13653 if (io_info == (PerlIO *) NULL)
13654 {
13655 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13656 PackageName);
13657 continue;
13658 }
13659 file=PerlIO_findFILE(io_info);
13660 if (file == (FILE *) NULL)
13661 {
13662 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13663 PackageName);
13664 continue;
13665 }
13666 SetImageInfoFile(package_info->image_info,file);
13667 }
13668 if ((items >= 3) && strEQcase(list[n],"magick"))
13669 continue;
13670 n++;
13671 }
13672 list[n]=(char *) NULL;
13673 keep=list;
13674 status=ExpandFilenames(&n,&list);
13675 if (status == MagickFalse)
13676 {
13677 ThrowPerlException(exception,ResourceLimitError,
13678 "MemoryAllocationFailed",PackageName);
13679 goto PerlException;
13680 }
13681 number_images=0;
13682 for (i=0; i < n; i++)
13683 {
13684 if ((package_info->image_info->file == (FILE *) NULL) &&
13685 (package_info->image_info->blob == (void *) NULL))
13686 image=ReadImages(package_info->image_info,list[i],exception);
13687 else
13688 {
13689 image=ReadImages(package_info->image_info,
13690 package_info->image_info->filename,exception);
13691 if (image != (Image *) NULL)
13692 DisassociateImageStream(image);
13693 }
13694 if (image == (Image *) NULL)
13695 break;
13696 for ( ; image; image=image->next)
13697 {
13698 AddImageToRegistry(sv,image);
13699 rv=newRV(sv);
13700 av_push(av,sv_bless(rv,hv));
13701 SvREFCNT_dec(sv);
13702 number_images++;
13703 }
13704 }
13705 /*
13706 Free resources.
13707 */
13708 for (i=0; i < n; i++)
13709 if (list[i] != (char *) NULL)
13710 for (p=keep; list[i] != *p++; )
13711 if (*p == (char *) NULL)
13712 {
13713 list[i]=(char *) RelinquishMagickMemory(list[i]);
13714 break;
13715 }
13716
13717 PerlException:
13718 if (package_info != (struct PackageInfo *) NULL)
13719 DestroyPackageInfo(package_info);
13720 if (list && (list != keep))
13721 list=(char **) RelinquishMagickMemory(list);
13722 if (keep)
13723 keep=(char **) RelinquishMagickMemory(keep);
13724 if (length)
13725 length=(STRLEN *) RelinquishMagickMemory(length);
13726 InheritPerlException(exception,perl_exception);
13727 exception=DestroyExceptionInfo(exception);
13728 sv_setiv(perl_exception,(IV) number_images);
13729 SvPOK_on(perl_exception);
13730 ST(0)=sv_2mortal(perl_exception);
13731 XSRETURN(1);
13732 }
13733
13734#
13735###############################################################################
13736# #
13737# #
13738# #
13739# R e m o t e #
13740# #
13741# #
13742# #
13743###############################################################################
13744#
13745#
13746void
13747Remote(ref,...)
13748 Image::Magick ref=NO_INIT
13749 ALIAS:
13750 RemoteCommand = 1
13751 remote = 2
13752 remoteCommand = 3
13753 PPCODE:
13754 {
13755 AV
13756 *av;
13757
13758 ExceptionInfo
13759 *exception;
13760
13761 register ssize_t
13762 i;
13763
13764 SV
13765 *perl_exception,
13766 *reference;
13767
13768 struct PackageInfo
13769 *info;
13770
13771 PERL_UNUSED_VAR(ref);
13772 PERL_UNUSED_VAR(ix);
13773 exception=AcquireExceptionInfo();
13774 perl_exception=newSVpv("",0);
13775 reference=SvRV(ST(0));
13776 av=(AV *) reference;
13777 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13778 exception);
13779 for (i=1; i < items; i++)
13780 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13781 SvPV(ST(i),na),exception);
13782 InheritPerlException(exception,perl_exception);
13783 exception=DestroyExceptionInfo(exception);
13784 SvREFCNT_dec(perl_exception); /* throw away all errors */
13785 }
13786
13787#
13788###############################################################################
13789# #
13790# #
13791# #
13792# S e t #
13793# #
13794# #
13795# #
13796###############################################################################
13797#
13798#
13799void
13800Set(ref,...)
13801 Image::Magick ref=NO_INIT
13802 ALIAS:
13803 SetAttributes = 1
13804 SetAttribute = 2
13805 set = 3
13806 setattributes = 4
13807 setattribute = 5
13808 PPCODE:
13809 {
13810 ExceptionInfo
13811 *exception;
13812
13813 Image
13814 *image;
13815
13816 register ssize_t
13817 i;
13818
13819 struct PackageInfo
13820 *info;
13821
13822 SV
13823 *perl_exception,
13824 *reference; /* reference is the SV* of ref=SvIV(reference) */
13825
13826 PERL_UNUSED_VAR(ref);
13827 PERL_UNUSED_VAR(ix);
13828 exception=AcquireExceptionInfo();
13829 perl_exception=newSVpv("",0);
13830 if (sv_isobject(ST(0)) == 0)
13831 {
13832 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13833 PackageName);
13834 goto PerlException;
13835 }
13836 reference=SvRV(ST(0));
13837 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13838 if (items == 2)
13839 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13840 else
13841 for (i=2; i < items; i+=2)
13842 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13843
13844 PerlException:
13845 InheritPerlException(exception,perl_exception);
13846 exception=DestroyExceptionInfo(exception);
13847 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13848 SvPOK_on(perl_exception);
13849 ST(0)=sv_2mortal(perl_exception);
13850 XSRETURN(1);
13851 }
13852
13853#
13854###############################################################################
13855# #
13856# #
13857# #
13858# S e t P i x e l #
13859# #
13860# #
13861# #
13862###############################################################################
13863#
13864#
13865void
13866SetPixel(ref,...)
13867 Image::Magick ref=NO_INIT
13868 ALIAS:
13869 setpixel = 1
13870 setPixel = 2
13871 PPCODE:
13872 {
13873 AV
13874 *av;
13875
13876 char
13877 *attribute;
13878
13879 ChannelType
13880 channel,
13881 channel_mask;
13882
13883 ExceptionInfo
13884 *exception;
13885
13886 Image
13887 *image;
13888
13889 MagickBooleanType
13890 normalize;
13891
13892 RectangleInfo
13893 region;
13894
13895 register ssize_t
13896 i;
13897
13898 register Quantum
13899 *q;
13900
13901 ssize_t
13902 option;
13903
13904 struct PackageInfo
13905 *info;
13906
13907 SV
13908 *perl_exception,
13909 *reference; /* reference is the SV* of ref=SvIV(reference) */
13910
13911 PERL_UNUSED_VAR(ref);
13912 PERL_UNUSED_VAR(ix);
13913 exception=AcquireExceptionInfo();
13914 perl_exception=newSVpv("",0);
13915 reference=SvRV(ST(0));
13916 av=(AV *) reference;
13917 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13918 exception);
13919 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13920 if (image == (Image *) NULL)
13921 {
13922 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13923 PackageName);
13924 goto PerlException;
13925 }
13926 av=(AV *) NULL;
13927 normalize=MagickTrue;
13928 region.x=0;
13929 region.y=0;
13930 region.width=image->columns;
13931 region.height=1;
13932 if (items == 1)
13933 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
13934 channel=DefaultChannels;
13935 for (i=2; i < items; i+=2)
13936 {
13937 attribute=(char *) SvPV(ST(i-1),na);
13938 switch (*attribute)
13939 {
13940 case 'C':
13941 case 'c':
13942 {
13943 if (LocaleCompare(attribute,"channel") == 0)
13944 {
13945 ssize_t
13946 option;
13947
13948 option=ParseChannelOption(SvPV(ST(i),na));
13949 if (option < 0)
13950 {
13951 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13952 SvPV(ST(i),na));
13953 return;
13954 }
13955 channel=(ChannelType) option;
13956 break;
13957 }
13958 if (LocaleCompare(attribute,"color") == 0)
13959 {
13960 if (SvTYPE(ST(i)) != SVt_RV)
13961 {
13962 char
cristy151b66d2015-04-15 10:50:31 +000013963 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013964
cristy151b66d2015-04-15 10:50:31 +000013965 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013966 "invalid %.60s value",attribute);
13967 ThrowPerlException(exception,OptionError,message,
13968 SvPV(ST(i),na));
13969 }
13970 av=(AV *) SvRV(ST(i));
13971 break;
13972 }
13973 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13974 attribute);
13975 break;
13976 }
13977 case 'g':
13978 case 'G':
13979 {
13980 if (LocaleCompare(attribute,"geometry") == 0)
13981 {
13982 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
13983 break;
13984 }
13985 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13986 attribute);
13987 break;
13988 }
13989 case 'N':
13990 case 'n':
13991 {
13992 if (LocaleCompare(attribute,"normalize") == 0)
13993 {
13994 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13995 SvPV(ST(i),na));
13996 if (option < 0)
13997 {
13998 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13999 SvPV(ST(i),na));
14000 break;
14001 }
14002 normalize=option != 0 ? MagickTrue : MagickFalse;
14003 break;
14004 }
14005 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14006 attribute);
14007 break;
14008 }
14009 case 'x':
14010 case 'X':
14011 {
14012 if (LocaleCompare(attribute,"x") == 0)
14013 {
14014 region.x=SvIV(ST(i));
14015 break;
14016 }
14017 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14018 attribute);
14019 break;
14020 }
14021 case 'y':
14022 case 'Y':
14023 {
14024 if (LocaleCompare(attribute,"y") == 0)
14025 {
14026 region.y=SvIV(ST(i));
14027 break;
14028 }
14029 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14030 attribute);
14031 break;
14032 }
14033 default:
14034 {
14035 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14036 attribute);
14037 break;
14038 }
14039 }
14040 }
14041 (void) SetImageStorageClass(image,DirectClass,exception);
14042 channel_mask=SetImageChannelMask(image,channel);
14043 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14044 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14045 (SvTYPE(av) != SVt_PVAV))
14046 PUSHs(&sv_undef);
14047 else
14048 {
14049 double
14050 scale;
14051
14052 register ssize_t
14053 i;
14054
14055 i=0;
14056 scale=1.0;
14057 if (normalize != MagickFalse)
14058 scale=QuantumRange;
14059 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14060 (i <= av_len(av)))
14061 {
14062 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14063 av_fetch(av,i,0)))),q);
14064 i++;
14065 }
14066 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14067 (i <= av_len(av)))
14068 {
14069 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14070 av_fetch(av,i,0)))),q);
14071 i++;
14072 }
14073 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14074 (i <= av_len(av)))
14075 {
14076 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14077 av_fetch(av,i,0)))),q);
14078 i++;
14079 }
14080 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14081 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14082 {
14083 SetPixelBlack(image,ClampToQuantum(scale*
14084 SvNV(*(av_fetch(av,i,0)))),q);
14085 i++;
14086 }
14087 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14088 (i <= av_len(av)))
14089 {
14090 SetPixelAlpha(image,ClampToQuantum(scale*
14091 SvNV(*(av_fetch(av,i,0)))),q);
14092 i++;
14093 }
14094 (void) SyncAuthenticPixels(image,exception);
14095 }
14096 (void) SetImageChannelMask(image,channel_mask);
14097
14098 PerlException:
14099 InheritPerlException(exception,perl_exception);
14100 exception=DestroyExceptionInfo(exception);
14101 SvREFCNT_dec(perl_exception);
14102 }
14103
14104#
14105###############################################################################
14106# #
14107# #
14108# #
14109# S m u s h #
14110# #
14111# #
14112# #
14113###############################################################################
14114#
14115#
14116void
14117Smush(ref,...)
14118 Image::Magick ref=NO_INIT
14119 ALIAS:
14120 SmushImage = 1
14121 smush = 2
14122 smushimage = 3
14123 PPCODE:
14124 {
14125 AV
14126 *av;
14127
14128 char
14129 *attribute;
14130
14131 ExceptionInfo
14132 *exception;
14133
14134 HV
14135 *hv;
14136
14137 Image
14138 *image;
14139
14140 register ssize_t
14141 i;
14142
14143 ssize_t
14144 offset,
14145 stack;
14146
14147 struct PackageInfo
14148 *info;
14149
14150 SV
14151 *av_reference,
14152 *perl_exception,
14153 *reference,
14154 *rv,
14155 *sv;
14156
14157 PERL_UNUSED_VAR(ref);
14158 PERL_UNUSED_VAR(ix);
14159 exception=AcquireExceptionInfo();
14160 perl_exception=newSVpv("",0);
14161 sv=NULL;
14162 attribute=NULL;
14163 av=NULL;
14164 if (sv_isobject(ST(0)) == 0)
14165 {
14166 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14167 PackageName);
14168 goto PerlException;
14169 }
14170 reference=SvRV(ST(0));
14171 hv=SvSTASH(reference);
14172 av=newAV();
14173 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14174 SvREFCNT_dec(av);
14175 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14176 if (image == (Image *) NULL)
14177 {
14178 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14179 PackageName);
14180 goto PerlException;
14181 }
14182 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14183 /*
14184 Get options.
14185 */
14186 offset=0;
14187 stack=MagickTrue;
14188 for (i=2; i < items; i+=2)
14189 {
14190 attribute=(char *) SvPV(ST(i-1),na);
14191 switch (*attribute)
14192 {
14193 case 'O':
14194 case 'o':
14195 {
14196 if (LocaleCompare(attribute,"offset") == 0)
14197 {
14198 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14199 break;
14200 }
14201 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14202 attribute);
14203 break;
14204 }
14205 case 'S':
14206 case 's':
14207 {
14208 if (LocaleCompare(attribute,"stack") == 0)
14209 {
14210 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14211 SvPV(ST(i),na));
14212 if (stack < 0)
14213 {
14214 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14215 SvPV(ST(i),na));
14216 return;
14217 }
14218 break;
14219 }
14220 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14221 attribute);
14222 break;
14223 }
14224 default:
14225 {
14226 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14227 attribute);
14228 break;
14229 }
14230 }
14231 }
14232 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14233 exception);
14234 if (image == (Image *) NULL)
14235 goto PerlException;
14236 for ( ; image; image=image->next)
14237 {
14238 AddImageToRegistry(sv,image);
14239 rv=newRV(sv);
14240 av_push(av,sv_bless(rv,hv));
14241 SvREFCNT_dec(sv);
14242 }
14243 exception=DestroyExceptionInfo(exception);
14244 ST(0)=av_reference;
14245 SvREFCNT_dec(perl_exception);
14246 XSRETURN(1);
14247
14248 PerlException:
14249 InheritPerlException(exception,perl_exception);
14250 exception=DestroyExceptionInfo(exception);
14251 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14252 SvPOK_on(perl_exception);
14253 ST(0)=sv_2mortal(perl_exception);
14254 XSRETURN(1);
14255 }
14256
14257#
14258###############################################################################
14259# #
14260# #
14261# #
14262# S t a t i s t i c s #
14263# #
14264# #
14265# #
14266###############################################################################
14267#
14268#
14269void
14270Statistics(ref,...)
14271 Image::Magick ref=NO_INIT
14272 ALIAS:
14273 StatisticsImage = 1
14274 statistics = 2
14275 statisticsimage = 3
14276 PPCODE:
14277 {
14278#define ChannelStatistics(channel) \
14279{ \
cristy151b66d2015-04-15 10:50:31 +000014280 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014281 (double) channel_statistics[channel].depth); \
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].minima/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].maxima/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].mean/scale); \
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].standard_deviation/scale); \
14294 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014295 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014296 channel_statistics[channel].kurtosis); \
14297 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014298 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014299 channel_statistics[channel].skewness); \
14300 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014301 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy275bdd92014-11-08 23:45:03 +000014302 channel_statistics[channel].entropy); \
14303 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014304}
14305
14306 AV
14307 *av;
14308
14309 char
cristy151b66d2015-04-15 10:50:31 +000014310 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014311
14312 ChannelStatistics
14313 *channel_statistics;
14314
14315 double
14316 scale;
14317
14318 ExceptionInfo
14319 *exception;
14320
14321 Image
14322 *image;
14323
14324 ssize_t
14325 count;
14326
14327 struct PackageInfo
14328 *info;
14329
14330 SV
14331 *perl_exception,
14332 *reference;
14333
14334 PERL_UNUSED_VAR(ref);
14335 PERL_UNUSED_VAR(ix);
14336 exception=AcquireExceptionInfo();
14337 perl_exception=newSVpv("",0);
14338 av=NULL;
14339 if (sv_isobject(ST(0)) == 0)
14340 {
14341 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14342 PackageName);
14343 goto PerlException;
14344 }
14345 reference=SvRV(ST(0));
14346 av=newAV();
14347 SvREFCNT_dec(av);
14348 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14349 if (image == (Image *) NULL)
14350 {
14351 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14352 PackageName);
14353 goto PerlException;
14354 }
cristy4a3ce0a2013-08-03 20:06:59 +000014355 count=0;
14356 for ( ; image; image=image->next)
14357 {
14358 channel_statistics=GetImageStatistics(image,exception);
14359 if (channel_statistics == (ChannelStatistics *) NULL)
14360 continue;
14361 count++;
14362 EXTEND(sp,35*count);
14363 scale=(double) QuantumRange;
14364 ChannelStatistics(RedChannel);
14365 ChannelStatistics(GreenChannel);
14366 ChannelStatistics(BlueChannel);
14367 if (image->colorspace == CMYKColorspace)
14368 ChannelStatistics(BlackChannel);
cristy17f11b02014-12-20 19:37:04 +000014369 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000014370 ChannelStatistics(AlphaChannel);
14371 channel_statistics=(ChannelStatistics *)
14372 RelinquishMagickMemory(channel_statistics);
14373 }
14374
14375 PerlException:
14376 InheritPerlException(exception,perl_exception);
14377 exception=DestroyExceptionInfo(exception);
14378 SvREFCNT_dec(perl_exception);
14379 }
14380
14381#
14382###############################################################################
14383# #
14384# #
14385# #
14386# S y n c A u t h e n t i c P i x e l s #
14387# #
14388# #
14389# #
14390###############################################################################
14391#
14392#
14393void
14394SyncAuthenticPixels(ref,...)
14395 Image::Magick ref = NO_INIT
14396 ALIAS:
14397 Syncauthenticpixels = 1
14398 SyncImagePixels = 2
14399 syncimagepixels = 3
14400 CODE:
14401 {
14402 ExceptionInfo
14403 *exception;
14404
14405 Image
14406 *image;
14407
14408 MagickBooleanType
14409 status;
14410
14411 struct PackageInfo
14412 *info;
14413
14414 SV
14415 *perl_exception,
14416 *reference;
14417
14418 PERL_UNUSED_VAR(ref);
14419 PERL_UNUSED_VAR(ix);
14420 exception=AcquireExceptionInfo();
14421 perl_exception=newSVpv("",0);
14422 if (sv_isobject(ST(0)) == 0)
14423 {
14424 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14425 PackageName);
14426 goto PerlException;
14427 }
14428
14429 reference=SvRV(ST(0));
14430 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14431 if (image == (Image *) NULL)
14432 {
14433 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14434 PackageName);
14435 goto PerlException;
14436 }
14437
14438 status=SyncAuthenticPixels(image,exception);
14439 if (status != MagickFalse)
14440 return;
14441
14442 PerlException:
14443 InheritPerlException(exception,perl_exception);
14444 exception=DestroyExceptionInfo(exception);
14445 SvREFCNT_dec(perl_exception); /* throw away all errors */
14446 }
14447
14448#
14449###############################################################################
14450# #
14451# #
14452# #
14453# T r a n s f o r m #
14454# #
14455# #
14456# #
14457###############################################################################
14458#
14459#
14460void
14461Transform(ref,...)
14462 Image::Magick ref=NO_INIT
14463 ALIAS:
14464 TransformImage = 1
14465 transform = 2
14466 transformimage = 3
14467 PPCODE:
14468 {
14469 AV
14470 *av;
14471
14472 char
14473 *attribute,
14474 *crop_geometry,
14475 *geometry;
14476
14477 ExceptionInfo
14478 *exception;
14479
14480 HV
14481 *hv;
14482
14483 Image
14484 *clone,
14485 *image;
14486
14487 register ssize_t
14488 i;
14489
14490 struct PackageInfo
14491 *info;
14492
14493 SV
14494 *av_reference,
14495 *perl_exception,
14496 *reference,
14497 *rv,
14498 *sv;
14499
14500 PERL_UNUSED_VAR(ref);
14501 PERL_UNUSED_VAR(ix);
14502 exception=AcquireExceptionInfo();
14503 perl_exception=newSVpv("",0);
14504 sv=NULL;
14505 av=NULL;
14506 attribute=NULL;
14507 if (sv_isobject(ST(0)) == 0)
14508 {
14509 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14510 PackageName);
14511 goto PerlException;
14512 }
14513 reference=SvRV(ST(0));
14514 hv=SvSTASH(reference);
14515 av=newAV();
14516 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14517 SvREFCNT_dec(av);
14518 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14519 if (image == (Image *) NULL)
14520 {
14521 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14522 PackageName);
14523 goto PerlException;
14524 }
14525 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14526 /*
14527 Get attribute.
14528 */
14529 crop_geometry=(char *) NULL;
14530 geometry=(char *) NULL;
14531 for (i=2; i < items; i+=2)
14532 {
14533 attribute=(char *) SvPV(ST(i-1),na);
14534 switch (*attribute)
14535 {
14536 case 'c':
14537 case 'C':
14538 {
14539 if (LocaleCompare(attribute,"crop") == 0)
14540 {
14541 crop_geometry=SvPV(ST(i),na);
14542 break;
14543 }
14544 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14545 attribute);
14546 break;
14547 }
14548 case 'g':
14549 case 'G':
14550 {
14551 if (LocaleCompare(attribute,"geometry") == 0)
14552 {
14553 geometry=SvPV(ST(i),na);
14554 break;
14555 }
14556 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14557 attribute);
14558 break;
14559 }
14560 default:
14561 {
14562 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14563 attribute);
14564 break;
14565 }
14566 }
14567 }
14568 for ( ; image; image=image->next)
14569 {
14570 clone=CloneImage(image,0,0,MagickTrue,exception);
14571 if (clone == (Image *) NULL)
14572 goto PerlException;
14573 TransformImage(&clone,crop_geometry,geometry,exception);
14574 for ( ; clone; clone=clone->next)
14575 {
14576 AddImageToRegistry(sv,clone);
14577 rv=newRV(sv);
14578 av_push(av,sv_bless(rv,hv));
14579 SvREFCNT_dec(sv);
14580 }
14581 }
14582 exception=DestroyExceptionInfo(exception);
14583 ST(0)=av_reference;
14584 SvREFCNT_dec(perl_exception); /* can't return warning messages */
14585 XSRETURN(1);
14586
14587 PerlException:
14588 InheritPerlException(exception,perl_exception);
14589 exception=DestroyExceptionInfo(exception);
14590 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14591 SvPOK_on(perl_exception);
14592 ST(0)=sv_2mortal(perl_exception);
14593 XSRETURN(1);
14594 }
14595
14596#
14597###############################################################################
14598# #
14599# #
14600# #
14601# W r i t e #
14602# #
14603# #
14604# #
14605###############################################################################
14606#
14607#
14608void
14609Write(ref,...)
14610 Image::Magick ref=NO_INIT
14611 ALIAS:
14612 WriteImage = 1
14613 write = 2
14614 writeimage = 3
14615 PPCODE:
14616 {
14617 char
cristy151b66d2015-04-15 10:50:31 +000014618 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014619
14620 ExceptionInfo
14621 *exception;
14622
14623 Image
14624 *image,
14625 *next;
14626
14627 register ssize_t
14628 i;
14629
14630 ssize_t
14631 number_images,
14632 scene;
14633
14634 struct PackageInfo
14635 *info,
14636 *package_info;
14637
14638 SV
14639 *perl_exception,
14640 *reference;
14641
14642 PERL_UNUSED_VAR(ref);
14643 PERL_UNUSED_VAR(ix);
14644 exception=AcquireExceptionInfo();
14645 perl_exception=newSVpv("",0);
14646 number_images=0;
14647 package_info=(struct PackageInfo *) NULL;
14648 if (sv_isobject(ST(0)) == 0)
14649 {
14650 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14651 PackageName);
14652 goto PerlException;
14653 }
14654 reference=SvRV(ST(0));
14655 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14656 if (image == (Image *) NULL)
14657 {
14658 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14659 PackageName);
14660 goto PerlException;
14661 }
14662 package_info=ClonePackageInfo(info,exception);
14663 if (items == 2)
14664 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14665 else
14666 if (items > 2)
14667 for (i=2; i < items; i+=2)
14668 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14669 exception);
14670 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014671 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014672 scene=0;
14673 for (next=image; next; next=next->next)
14674 {
cristy151b66d2015-04-15 10:50:31 +000014675 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014676 next->scene=scene++;
14677 }
cristy68bd79a2015-02-25 12:23:36 +000014678 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014679 SetImageInfo(package_info->image_info,(unsigned int)
14680 GetImageListLength(image),exception);
14681 for (next=image; next; next=next->next)
14682 {
14683 (void) WriteImage(package_info->image_info,next,exception);
14684 number_images++;
14685 if (package_info->image_info->adjoin)
14686 break;
14687 }
14688
14689 PerlException:
14690 if (package_info != (struct PackageInfo *) NULL)
14691 DestroyPackageInfo(package_info);
14692 InheritPerlException(exception,perl_exception);
14693 exception=DestroyExceptionInfo(exception);
14694 sv_setiv(perl_exception,(IV) number_images);
14695 SvPOK_on(perl_exception);
14696 ST(0)=sv_2mortal(perl_exception);
14697 XSRETURN(1);
14698 }