blob: 6ab79f49b53054d821845d0f81b270f53159508c [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% %
cristyb56bb242014-11-25 17:12:48 +000026% Copyright 1999-2015 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
56#include "EXTERN.h"
57#include "perl.h"
58#include "XSUB.h"
59#include <math.h>
60#include <MagickCore/MagickCore.h>
61#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} } },
263 { "Spread", { {"radius", RealReference},
264 {"interpolate", MagickInterpolateOptions} } },
265 { "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} } },
cristy6e0b3bc2014-10-19 17:51:42 +0000558 { "ConnectedComponents", { {"connectivity", IntegerReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000559 };
560
561static SplayTreeInfo
562 *magick_registry = (SplayTreeInfo *) NULL;
563
564/*
565 Forward declarations.
566*/
567static Image
568 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
569
570static ssize_t
571 strEQcase(const char *,const char *);
572
573/*
574%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
575% %
576% %
577% %
578% C l o n e P a c k a g e I n f o %
579% %
580% %
581% %
582%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
583%
584% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
585% a new one.
586%
587% The format of the ClonePackageInfo routine is:
588%
589% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
590% exception)
591%
592% A description of each parameter follows:
593%
594% o info: a structure of type info.
595%
596% o exception: Return any errors or warnings in this structure.
597%
598*/
599static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
600 ExceptionInfo *exception)
601{
602 struct PackageInfo
603 *clone_info;
604
605 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
606 if (clone_info == (struct PackageInfo *) NULL)
607 {
608 ThrowPerlException(exception,ResourceLimitError,
609 "UnableToClonePackageInfo",PackageName);
610 return((struct PackageInfo *) NULL);
611 }
612 if (info == (struct PackageInfo *) NULL)
613 {
614 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
615 return(clone_info);
616 }
617 *clone_info=(*info);
618 clone_info->image_info=CloneImageInfo(info->image_info);
619 return(clone_info);
620}
621
622/*
623%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
624% %
625% %
626% %
627% c o n s t a n t %
628% %
629% %
630% %
631%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
632%
633% constant() returns a double value for the specified name.
634%
635% The format of the constant routine is:
636%
637% double constant(char *name,ssize_t sans)
638%
639% A description of each parameter follows:
640%
641% o value: Method constant returns a double value for the specified name.
642%
643% o name: The name of the constant.
644%
645% o sans: This integer value is not used.
646%
647*/
648static double constant(char *name,ssize_t sans)
649{
650 (void) sans;
651 errno=0;
652 switch (*name)
653 {
654 case 'B':
655 {
656 if (strEQ(name,"BlobError"))
657 return(BlobError);
658 if (strEQ(name,"BlobWarning"))
659 return(BlobWarning);
660 break;
661 }
662 case 'C':
663 {
664 if (strEQ(name,"CacheError"))
665 return(CacheError);
666 if (strEQ(name,"CacheWarning"))
667 return(CacheWarning);
668 if (strEQ(name,"CoderError"))
669 return(CoderError);
670 if (strEQ(name,"CoderWarning"))
671 return(CoderWarning);
672 if (strEQ(name,"ConfigureError"))
673 return(ConfigureError);
674 if (strEQ(name,"ConfigureWarning"))
675 return(ConfigureWarning);
676 if (strEQ(name,"CorruptImageError"))
677 return(CorruptImageError);
678 if (strEQ(name,"CorruptImageWarning"))
679 return(CorruptImageWarning);
680 break;
681 }
682 case 'D':
683 {
684 if (strEQ(name,"DelegateError"))
685 return(DelegateError);
686 if (strEQ(name,"DelegateWarning"))
687 return(DelegateWarning);
688 if (strEQ(name,"DrawError"))
689 return(DrawError);
690 if (strEQ(name,"DrawWarning"))
691 return(DrawWarning);
692 break;
693 }
694 case 'E':
695 {
696 if (strEQ(name,"ErrorException"))
697 return(ErrorException);
698 if (strEQ(name,"ExceptionError"))
699 return(CoderError);
700 if (strEQ(name,"ExceptionWarning"))
701 return(CoderWarning);
702 break;
703 }
704 case 'F':
705 {
706 if (strEQ(name,"FatalErrorException"))
707 return(FatalErrorException);
708 if (strEQ(name,"FileOpenError"))
709 return(FileOpenError);
710 if (strEQ(name,"FileOpenWarning"))
711 return(FileOpenWarning);
712 break;
713 }
714 case 'I':
715 {
716 if (strEQ(name,"ImageError"))
717 return(ImageError);
718 if (strEQ(name,"ImageWarning"))
719 return(ImageWarning);
720 break;
721 }
722 case 'M':
723 {
724 if (strEQ(name,"MaxRGB"))
725 return(QuantumRange);
726 if (strEQ(name,"MissingDelegateError"))
727 return(MissingDelegateError);
728 if (strEQ(name,"MissingDelegateWarning"))
729 return(MissingDelegateWarning);
730 if (strEQ(name,"ModuleError"))
731 return(ModuleError);
732 if (strEQ(name,"ModuleWarning"))
733 return(ModuleWarning);
734 break;
735 }
736 case 'O':
737 {
738 if (strEQ(name,"Opaque"))
739 return(OpaqueAlpha);
740 if (strEQ(name,"OptionError"))
741 return(OptionError);
742 if (strEQ(name,"OptionWarning"))
743 return(OptionWarning);
744 break;
745 }
746 case 'Q':
747 {
748 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
749 return(MAGICKCORE_QUANTUM_DEPTH);
750 if (strEQ(name,"QuantumDepth"))
751 return(MAGICKCORE_QUANTUM_DEPTH);
752 if (strEQ(name,"QuantumRange"))
753 return(QuantumRange);
754 break;
755 }
756 case 'R':
757 {
758 if (strEQ(name,"ResourceLimitError"))
759 return(ResourceLimitError);
760 if (strEQ(name,"ResourceLimitWarning"))
761 return(ResourceLimitWarning);
762 if (strEQ(name,"RegistryError"))
763 return(RegistryError);
764 if (strEQ(name,"RegistryWarning"))
765 return(RegistryWarning);
766 break;
767 }
768 case 'S':
769 {
770 if (strEQ(name,"StreamError"))
771 return(StreamError);
772 if (strEQ(name,"StreamWarning"))
773 return(StreamWarning);
774 if (strEQ(name,"Success"))
775 return(0);
776 break;
777 }
778 case 'T':
779 {
780 if (strEQ(name,"Transparent"))
781 return(TransparentAlpha);
782 if (strEQ(name,"TypeError"))
783 return(TypeError);
784 if (strEQ(name,"TypeWarning"))
785 return(TypeWarning);
786 break;
787 }
788 case 'W':
789 {
790 if (strEQ(name,"WarningException"))
791 return(WarningException);
792 break;
793 }
794 case 'X':
795 {
796 if (strEQ(name,"XServerError"))
797 return(XServerError);
798 if (strEQ(name,"XServerWarning"))
799 return(XServerWarning);
800 break;
801 }
802 }
803 errno=EINVAL;
804 return(0);
805}
806
807/*
808%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
809% %
810% %
811% %
812% D e s t r o y P a c k a g e I n f o %
813% %
814% %
815% %
816%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
817%
818% Method DestroyPackageInfo frees a previously created info structure.
819%
820% The format of the DestroyPackageInfo routine is:
821%
822% DestroyPackageInfo(struct PackageInfo *info)
823%
824% A description of each parameter follows:
825%
826% o info: a structure of type info.
827%
828*/
829static void DestroyPackageInfo(struct PackageInfo *info)
830{
831 info->image_info=DestroyImageInfo(info->image_info);
832 info=(struct PackageInfo *) RelinquishMagickMemory(info);
833}
834
835/*
836%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
837% %
838% %
839% %
840% G e t L i s t %
841% %
842% %
843% %
844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
845%
846% Method GetList is recursively called by SetupList to traverse the
847% Image__Magick reference. If building an reference_vector (see SetupList),
848% *current is the current position in *reference_vector and *last is the final
849% entry in *reference_vector.
850%
851% The format of the GetList routine is:
852%
853% GetList(info)
854%
855% A description of each parameter follows:
856%
857% o info: a structure of type info.
858%
859*/
860static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
861 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
862{
863 Image
864 *image;
865
866 if (reference == (SV *) NULL)
867 return(NULL);
868 switch (SvTYPE(reference))
869 {
870 case SVt_PVAV:
871 {
872 AV
873 *av;
874
875 Image
876 *head,
877 *previous;
878
879 register ssize_t
880 i;
881
882 ssize_t
883 n;
884
885 /*
886 Array of images.
887 */
888 previous=(Image *) NULL;
889 head=(Image *) NULL;
890 av=(AV *) reference;
891 n=av_len(av);
892 for (i=0; i <= n; i++)
893 {
894 SV
895 **rv;
896
897 rv=av_fetch(av,i,0);
898 if (rv && *rv && sv_isobject(*rv))
899 {
900 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
901 exception);
902 if (image == (Image *) NULL)
903 continue;
904 if (image == previous)
905 {
906 image=CloneImage(image,0,0,MagickTrue,exception);
907 if (image == (Image *) NULL)
908 return(NULL);
909 }
910 image->previous=previous;
911 *(previous ? &previous->next : &head)=image;
912 for (previous=image; previous->next; previous=previous->next) ;
913 }
914 }
915 return(head);
916 }
917 case SVt_PVMG:
918 {
919 /*
920 Blessed scalar, one image.
921 */
922 image=INT2PTR(Image *,SvIV(reference));
923 if (image == (Image *) NULL)
924 return(NULL);
925 image->previous=(Image *) NULL;
926 image->next=(Image *) NULL;
927 if (reference_vector)
928 {
929 if (*current == *last)
930 {
931 *last+=256;
932 if (*reference_vector == (SV **) NULL)
933 *reference_vector=(SV **) AcquireQuantumMemory(*last,
934 sizeof(*reference_vector));
935 else
936 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
937 *last,sizeof(*reference_vector));
938 }
939 if (*reference_vector == (SV **) NULL)
940 {
941 ThrowPerlException(exception,ResourceLimitError,
942 "MemoryAllocationFailed",PackageName);
943 return((Image *) NULL);
944 }
945 (*reference_vector)[*current]=reference;
946 (*reference_vector)[++(*current)]=NULL;
947 }
948 return(image);
949 }
950 default:
951 break;
952 }
953 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
954 (double) SvTYPE(reference));
955 return((Image *) NULL);
956}
957
958/*
959%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
960% %
961% %
962% %
963% G e t P a c k a g e I n f o %
964% %
965% %
966% %
967%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
968%
969% Method GetPackageInfo looks up or creates an info structure for the given
970% Image__Magick reference. If it does create a new one, the information in
971% package_info is used to initialize it.
972%
973% The format of the GetPackageInfo routine is:
974%
975% struct PackageInfo *GetPackageInfo(void *reference,
976% struct PackageInfo *package_info,ExceptionInfo *exception)
977%
978% A description of each parameter follows:
979%
980% o info: a structure of type info.
981%
982% o exception: Return any errors or warnings in this structure.
983%
984*/
985static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
986 struct PackageInfo *package_info,ExceptionInfo *exception)
987{
988 char
cristy151b66d2015-04-15 10:50:31 +0000989 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +0000990
991 struct PackageInfo
992 *clone_info;
993
994 SV
995 *sv;
996
cristy151b66d2015-04-15 10:50:31 +0000997 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +0000998 PackageName,XS_VERSION,reference);
999 sv=perl_get_sv(message,(TRUE | 0x02));
1000 if (sv == (SV *) NULL)
1001 {
1002 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1003 message);
1004 return(package_info);
1005 }
1006 if (SvREFCNT(sv) == 0)
1007 (void) SvREFCNT_inc(sv);
1008 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1009 return(clone_info);
1010 clone_info=ClonePackageInfo(package_info,exception);
1011 sv_setiv(sv,PTR2IV(clone_info));
1012 return(clone_info);
1013}
1014
1015/*
1016%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1017% %
1018% %
1019% %
1020% S e t A t t r i b u t e %
1021% %
1022% %
1023% %
1024%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1025%
1026% SetAttribute() sets the attribute to the value in sval. This can change
1027% either or both of image or info.
1028%
1029% The format of the SetAttribute routine is:
1030%
1031% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1032% SV *sval,ExceptionInfo *exception)
1033%
1034% A description of each parameter follows:
1035%
1036% o list: a list of strings.
1037%
1038% o string: a character string.
1039%
1040*/
1041
1042static double SiPrefixToDoubleInterval(const char *string,const double interval)
1043{
1044 char
1045 *q;
1046
1047 double
1048 value;
1049
1050 value=InterpretSiPrefixValue(string,&q);
1051 if (*q == '%')
1052 value*=interval/100.0;
1053 return(value);
1054}
1055
1056static inline double StringToDouble(const char *string,char **sentinal)
1057{
1058 return(InterpretLocaleValue(string,sentinal));
1059}
1060
1061static double StringToDoubleInterval(const char *string,const double interval)
1062{
1063 char
1064 *q;
1065
1066 double
1067 value;
1068
1069 value=InterpretLocaleValue(string,&q);
1070 if (*q == '%')
1071 value*=interval/100.0;
1072 return(value);
1073}
1074
1075static inline ssize_t StringToLong(const char *value)
1076{
1077 return(strtol(value,(char **) NULL,10));
1078}
1079
1080static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1081 const char *attribute,SV *sval,ExceptionInfo *exception)
1082{
1083 GeometryInfo
1084 geometry_info;
1085
1086 long
1087 x,
1088 y;
1089
1090 PixelInfo
1091 pixel;
1092
1093 MagickStatusType
1094 flags;
1095
1096 PixelInfo
1097 *color,
1098 target_color;
1099
1100 ssize_t
1101 sp;
1102
1103 switch (*attribute)
1104 {
1105 case 'A':
1106 case 'a':
1107 {
1108 if (LocaleCompare(attribute,"adjoin") == 0)
1109 {
1110 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1111 SvPV(sval,na)) : SvIV(sval);
1112 if (sp < 0)
1113 {
1114 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1115 SvPV(sval,na));
1116 break;
1117 }
1118 if (info)
1119 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1120 break;
1121 }
1122 if (LocaleCompare(attribute,"alpha") == 0)
1123 {
1124 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1125 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1126 if (sp < 0)
1127 {
1128 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1129 SvPV(sval,na));
1130 break;
1131 }
1132 for ( ; image; image=image->next)
1133 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1134 exception);
1135 break;
1136 }
1137 if (LocaleCompare(attribute,"antialias") == 0)
1138 {
1139 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1140 SvPV(sval,na)) : SvIV(sval);
1141 if (sp < 0)
1142 {
1143 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1144 SvPV(sval,na));
1145 break;
1146 }
1147 if (info)
1148 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1149 break;
1150 }
1151 if (LocaleCompare(attribute,"area-limit") == 0)
1152 {
1153 MagickSizeType
1154 limit;
1155
1156 limit=MagickResourceInfinity;
1157 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1158 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1159 100.0);
1160 (void) SetMagickResourceLimit(AreaResource,limit);
1161 break;
1162 }
1163 if (LocaleCompare(attribute,"attenuate") == 0)
1164 {
1165 if (info)
1166 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1167 break;
1168 }
1169 if (LocaleCompare(attribute,"authenticate") == 0)
1170 {
1171 if (info)
1172 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1173 break;
1174 }
1175 if (info)
1176 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1177 for ( ; image; image=image->next)
1178 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1179 break;
1180 }
1181 case 'B':
1182 case 'b':
1183 {
1184 if (LocaleCompare(attribute,"background") == 0)
1185 {
1186 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1187 exception);
1188 if (info)
1189 info->image_info->background_color=target_color;
1190 for ( ; image; image=image->next)
1191 image->background_color=target_color;
1192 break;
1193 }
1194 if (LocaleCompare(attribute,"blue-primary") == 0)
1195 {
1196 for ( ; image; image=image->next)
1197 {
1198 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1199 image->chromaticity.blue_primary.x=geometry_info.rho;
1200 image->chromaticity.blue_primary.y=geometry_info.sigma;
1201 if ((flags & SigmaValue) == 0)
1202 image->chromaticity.blue_primary.y=
1203 image->chromaticity.blue_primary.x;
1204 }
1205 break;
1206 }
1207 if (LocaleCompare(attribute,"bordercolor") == 0)
1208 {
1209 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1210 exception);
1211 if (info)
1212 info->image_info->border_color=target_color;
1213 for ( ; image; image=image->next)
1214 image->border_color=target_color;
1215 break;
1216 }
1217 if (info)
1218 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1219 for ( ; image; image=image->next)
1220 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1221 break;
1222 }
1223 case 'C':
1224 case 'c':
1225 {
1226 if (LocaleCompare(attribute,"cache-threshold") == 0)
1227 {
1228 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1229 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1230 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1231 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1232 break;
1233 }
1234 if (LocaleCompare(attribute,"clip-mask") == 0)
1235 {
1236 Image
1237 *clip_mask;
1238
1239 clip_mask=(Image *) NULL;
1240 if (SvPOK(sval))
1241 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1242 for ( ; image; image=image->next)
1243 SetImageMask(image,clip_mask,exception);
1244 break;
1245 }
1246 if (LocaleNCompare(attribute,"colormap",8) == 0)
1247 {
1248 for ( ; image; image=image->next)
1249 {
1250 int
1251 items;
1252
1253 long
1254 i;
1255
1256 if (image->storage_class == DirectClass)
1257 continue;
1258 i=0;
1259 items=sscanf(attribute,"%*[^[][%ld",&i);
1260 (void) items;
1261 if (i > (ssize_t) image->colors)
1262 i%=image->colors;
1263 if ((strchr(SvPV(sval,na),',') == 0) ||
1264 (strchr(SvPV(sval,na),')') != 0))
1265 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1266 image->colormap+i,exception);
1267 else
1268 {
1269 color=image->colormap+i;
1270 pixel.red=color->red;
1271 pixel.green=color->green;
1272 pixel.blue=color->blue;
1273 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1274 pixel.red=geometry_info.rho;
1275 pixel.green=geometry_info.sigma;
1276 pixel.blue=geometry_info.xi;
1277 color->red=ClampToQuantum(pixel.red);
1278 color->green=ClampToQuantum(pixel.green);
1279 color->blue=ClampToQuantum(pixel.blue);
1280 }
1281 }
1282 break;
1283 }
1284 if (LocaleCompare(attribute,"colorspace") == 0)
1285 {
1286 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1287 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1288 if (sp < 0)
1289 {
1290 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1291 SvPV(sval,na));
1292 break;
1293 }
1294 for ( ; image; image=image->next)
1295 (void) TransformImageColorspace(image,(ColorspaceType) sp,
1296 exception);
1297 break;
1298 }
1299 if (LocaleCompare(attribute,"comment") == 0)
1300 {
1301 for ( ; image; image=image->next)
1302 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1303 info ? info->image_info : (ImageInfo *) NULL,image,
1304 SvPV(sval,na),exception),exception);
1305 break;
1306 }
1307 if (LocaleCompare(attribute,"compression") == 0)
1308 {
1309 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1310 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1311 if (sp < 0)
1312 {
1313 ThrowPerlException(exception,OptionError,
1314 "UnrecognizedImageCompression",SvPV(sval,na));
1315 break;
1316 }
1317 if (info)
1318 info->image_info->compression=(CompressionType) sp;
1319 for ( ; image; image=image->next)
1320 image->compression=(CompressionType) sp;
1321 break;
1322 }
1323 if (info)
1324 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1325 for ( ; image; image=image->next)
1326 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1327 break;
1328 }
1329 case 'D':
1330 case 'd':
1331 {
1332 if (LocaleCompare(attribute,"debug") == 0)
1333 {
1334 SetLogEventMask(SvPV(sval,na));
1335 break;
1336 }
1337 if (LocaleCompare(attribute,"delay") == 0)
1338 {
1339 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1340 for ( ; image; image=image->next)
1341 {
1342 image->delay=(size_t) floor(geometry_info.rho+0.5);
1343 if ((flags & SigmaValue) != 0)
1344 image->ticks_per_second=(ssize_t)
1345 floor(geometry_info.sigma+0.5);
1346 }
1347 break;
1348 }
1349 if (LocaleCompare(attribute,"disk-limit") == 0)
1350 {
1351 MagickSizeType
1352 limit;
1353
1354 limit=MagickResourceInfinity;
1355 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1356 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1357 100.0);
1358 (void) SetMagickResourceLimit(DiskResource,limit);
1359 break;
1360 }
1361 if (LocaleCompare(attribute,"density") == 0)
1362 {
1363 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1364 {
1365 ThrowPerlException(exception,OptionError,"MissingGeometry",
1366 SvPV(sval,na));
1367 break;
1368 }
1369 if (info)
1370 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1371 for ( ; image; image=image->next)
1372 {
1373 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1374 image->resolution.x=geometry_info.rho;
1375 image->resolution.y=geometry_info.sigma;
1376 if ((flags & SigmaValue) == 0)
1377 image->resolution.y=image->resolution.x;
1378 }
1379 break;
1380 }
1381 if (LocaleCompare(attribute,"depth") == 0)
1382 {
1383 if (info)
1384 info->image_info->depth=SvIV(sval);
1385 for ( ; image; image=image->next)
1386 (void) SetImageDepth(image,SvIV(sval),exception);
1387 break;
1388 }
1389 if (LocaleCompare(attribute,"dispose") == 0)
1390 {
1391 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1392 SvPV(sval,na)) : SvIV(sval);
1393 if (sp < 0)
1394 {
1395 ThrowPerlException(exception,OptionError,
1396 "UnrecognizedDisposeMethod",SvPV(sval,na));
1397 break;
1398 }
1399 for ( ; image; image=image->next)
1400 image->dispose=(DisposeType) sp;
1401 break;
1402 }
1403 if (LocaleCompare(attribute,"dither") == 0)
1404 {
1405 if (info)
1406 {
1407 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1408 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1409 if (sp < 0)
1410 {
1411 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1412 SvPV(sval,na));
1413 break;
1414 }
1415 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1416 }
1417 break;
1418 }
1419 if (LocaleCompare(attribute,"display") == 0)
1420 {
1421 display:
1422 if (info)
1423 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1424 break;
1425 }
1426 if (info)
1427 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1428 for ( ; image; image=image->next)
1429 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1430 break;
1431 }
1432 case 'E':
1433 case 'e':
1434 {
1435 if (LocaleCompare(attribute,"endian") == 0)
1436 {
1437 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1438 SvPV(sval,na)) : SvIV(sval);
1439 if (sp < 0)
1440 {
1441 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1442 SvPV(sval,na));
1443 break;
1444 }
1445 if (info)
1446 info->image_info->endian=(EndianType) sp;
1447 for ( ; image; image=image->next)
1448 image->endian=(EndianType) sp;
1449 break;
1450 }
1451 if (LocaleCompare(attribute,"extract") == 0)
1452 {
1453 /*
1454 Set image extract geometry.
1455 */
1456 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1457 break;
1458 }
1459 if (info)
1460 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1461 for ( ; image; image=image->next)
1462 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1463 break;
1464 }
1465 case 'F':
1466 case 'f':
1467 {
1468 if (LocaleCompare(attribute,"filename") == 0)
1469 {
1470 if (info)
1471 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001472 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001473 for ( ; image; image=image->next)
1474 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001475 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001476 break;
1477 }
1478 if (LocaleCompare(attribute,"file") == 0)
1479 {
1480 FILE
1481 *file;
1482
1483 PerlIO
1484 *io_info;
1485
1486 if (info == (struct PackageInfo *) NULL)
1487 break;
1488 io_info=IoIFP(sv_2io(sval));
1489 if (io_info == (PerlIO *) NULL)
1490 {
1491 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1492 PackageName);
1493 break;
1494 }
1495 file=PerlIO_findFILE(io_info);
1496 if (file == (FILE *) NULL)
1497 {
1498 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1499 PackageName);
1500 break;
1501 }
1502 SetImageInfoFile(info->image_info,file);
1503 break;
1504 }
1505 if (LocaleCompare(attribute,"fill") == 0)
1506 {
1507 if (info)
1508 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1509 break;
1510 }
1511 if (LocaleCompare(attribute,"font") == 0)
1512 {
1513 if (info)
1514 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1515 break;
1516 }
1517 if (LocaleCompare(attribute,"foreground") == 0)
1518 break;
1519 if (LocaleCompare(attribute,"fuzz") == 0)
1520 {
1521 if (info)
1522 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1523 QuantumRange+1.0);
1524 for ( ; image; image=image->next)
1525 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1526 QuantumRange+1.0);
1527 break;
1528 }
1529 if (info)
1530 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1531 for ( ; image; image=image->next)
1532 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1533 break;
1534 }
1535 case 'G':
1536 case 'g':
1537 {
1538 if (LocaleCompare(attribute,"gamma") == 0)
1539 {
1540 for ( ; image; image=image->next)
1541 image->gamma=SvNV(sval);
1542 break;
1543 }
1544 if (LocaleCompare(attribute,"gravity") == 0)
1545 {
1546 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1547 SvPV(sval,na)) : SvIV(sval);
1548 if (sp < 0)
1549 {
1550 ThrowPerlException(exception,OptionError,
1551 "UnrecognizedGravityType",SvPV(sval,na));
1552 break;
1553 }
1554 if (info)
1555 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1556 for ( ; image; image=image->next)
1557 image->gravity=(GravityType) sp;
1558 break;
1559 }
1560 if (LocaleCompare(attribute,"green-primary") == 0)
1561 {
1562 for ( ; image; image=image->next)
1563 {
1564 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1565 image->chromaticity.green_primary.x=geometry_info.rho;
1566 image->chromaticity.green_primary.y=geometry_info.sigma;
1567 if ((flags & SigmaValue) == 0)
1568 image->chromaticity.green_primary.y=
1569 image->chromaticity.green_primary.x;
1570 }
1571 break;
1572 }
1573 if (info)
1574 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1575 for ( ; image; image=image->next)
1576 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1577 break;
1578 }
1579 case 'I':
1580 case 'i':
1581 {
1582 if (LocaleNCompare(attribute,"index",5) == 0)
1583 {
1584 int
1585 items;
1586
1587 long
1588 index;
1589
1590 register Quantum
1591 *q;
1592
1593 CacheView
1594 *image_view;
1595
1596 for ( ; image; image=image->next)
1597 {
1598 if (image->storage_class != PseudoClass)
1599 continue;
1600 x=0;
1601 y=0;
1602 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1603 (void) items;
1604 image_view=AcquireAuthenticCacheView(image,exception);
1605 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1606 if (q != (Quantum *) NULL)
1607 {
1608 items=sscanf(SvPV(sval,na),"%ld",&index);
1609 if ((index >= 0) && (index < (ssize_t) image->colors))
1610 SetPixelIndex(image,index,q);
1611 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1612 }
1613 image_view=DestroyCacheView(image_view);
1614 }
1615 break;
1616 }
1617 if (LocaleCompare(attribute,"iterations") == 0)
1618 {
1619 iterations:
1620 for ( ; image; image=image->next)
1621 image->iterations=SvIV(sval);
1622 break;
1623 }
1624 if (LocaleCompare(attribute,"interlace") == 0)
1625 {
1626 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1627 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1628 if (sp < 0)
1629 {
1630 ThrowPerlException(exception,OptionError,
1631 "UnrecognizedInterlaceType",SvPV(sval,na));
1632 break;
1633 }
1634 if (info)
1635 info->image_info->interlace=(InterlaceType) sp;
1636 for ( ; image; image=image->next)
1637 image->interlace=(InterlaceType) sp;
1638 break;
1639 }
1640 if (info)
1641 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1642 for ( ; image; image=image->next)
1643 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1644 break;
1645 }
1646 case 'L':
1647 case 'l':
1648 {
1649 if (LocaleCompare(attribute,"label") == 0)
1650 {
1651 for ( ; image; image=image->next)
1652 (void) SetImageProperty(image,"label",InterpretImageProperties(
1653 info ? info->image_info : (ImageInfo *) NULL,image,
1654 SvPV(sval,na),exception),exception);
1655 break;
1656 }
1657 if (LocaleCompare(attribute,"loop") == 0)
1658 goto iterations;
1659 if (info)
1660 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1661 for ( ; image; image=image->next)
1662 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1663 break;
1664 }
1665 case 'M':
1666 case 'm':
1667 {
1668 if (LocaleCompare(attribute,"magick") == 0)
1669 {
1670 if (info)
cristy151b66d2015-04-15 10:50:31 +00001671 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00001672 "%s:",SvPV(sval,na));
1673 for ( ; image; image=image->next)
cristy151b66d2015-04-15 10:50:31 +00001674 (void) CopyMagickString(image->magick,SvPV(sval,na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001675 break;
1676 }
1677 if (LocaleCompare(attribute,"map-limit") == 0)
1678 {
1679 MagickSizeType
1680 limit;
1681
1682 limit=MagickResourceInfinity;
1683 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1684 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1685 100.0);
1686 (void) SetMagickResourceLimit(MapResource,limit);
1687 break;
1688 }
1689 if (LocaleCompare(attribute,"mask") == 0)
1690 {
1691 Image
1692 *mask;
1693
1694 mask=(Image *) NULL;
1695 if (SvPOK(sval))
1696 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1697 for ( ; image; image=image->next)
1698 SetImageMask(image,mask,exception);
1699 break;
1700 }
1701 if (LocaleCompare(attribute,"mattecolor") == 0)
1702 {
1703 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1704 exception);
1705 if (info)
1706 info->image_info->matte_color=target_color;
1707 for ( ; image; image=image->next)
1708 image->matte_color=target_color;
1709 break;
1710 }
1711 if (LocaleCompare(attribute,"matte") == 0)
1712 {
1713 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1714 SvPV(sval,na)) : SvIV(sval);
1715 if (sp < 0)
1716 {
1717 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1718 SvPV(sval,na));
1719 break;
1720 }
1721 for ( ; image; image=image->next)
1722 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1723 break;
1724 }
1725 if (LocaleCompare(attribute,"memory-limit") == 0)
1726 {
1727 MagickSizeType
1728 limit;
1729
1730 limit=MagickResourceInfinity;
1731 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1732 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1733 100.0);
1734 (void) SetMagickResourceLimit(MemoryResource,limit);
1735 break;
1736 }
1737 if (LocaleCompare(attribute,"monochrome") == 0)
1738 {
1739 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1740 SvPV(sval,na)) : SvIV(sval);
1741 if (sp < 0)
1742 {
1743 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1744 SvPV(sval,na));
1745 break;
1746 }
1747 if (info)
1748 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1749 for ( ; image; image=image->next)
1750 (void) SetImageType(image,BilevelType,exception);
1751 break;
1752 }
1753 if (info)
1754 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1755 for ( ; image; image=image->next)
1756 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1757 break;
1758 }
1759 case 'O':
1760 case 'o':
1761 {
1762 if (LocaleCompare(attribute,"option") == 0)
1763 {
1764 if (info)
1765 DefineImageOption(info->image_info,SvPV(sval,na));
1766 break;
1767 }
1768 if (LocaleCompare(attribute,"orientation") == 0)
1769 {
1770 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1771 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1772 if (sp < 0)
1773 {
1774 ThrowPerlException(exception,OptionError,
1775 "UnrecognizedOrientationType",SvPV(sval,na));
1776 break;
1777 }
1778 if (info)
1779 info->image_info->orientation=(OrientationType) sp;
1780 for ( ; image; image=image->next)
1781 image->orientation=(OrientationType) sp;
1782 break;
1783 }
1784 if (info)
1785 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1786 for ( ; image; image=image->next)
1787 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1788 break;
1789 }
1790 case 'P':
1791 case 'p':
1792 {
1793 if (LocaleCompare(attribute,"page") == 0)
1794 {
1795 char
1796 *geometry;
1797
1798 geometry=GetPageGeometry(SvPV(sval,na));
1799 if (info)
1800 (void) CloneString(&info->image_info->page,geometry);
1801 for ( ; image; image=image->next)
1802 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1803 geometry=(char *) RelinquishMagickMemory(geometry);
1804 break;
1805 }
1806 if (LocaleNCompare(attribute,"pixel",5) == 0)
1807 {
1808 int
1809 items;
1810
1811 PixelInfo
1812 pixel;
1813
1814 register Quantum
1815 *q;
1816
1817 CacheView
1818 *image_view;
1819
1820 for ( ; image; image=image->next)
1821 {
1822 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1823 break;
1824 x=0;
1825 y=0;
1826 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1827 (void) items;
1828 image_view=AcquireVirtualCacheView(image,exception);
1829 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1830 if (q != (Quantum *) NULL)
1831 {
1832 if ((strchr(SvPV(sval,na),',') == 0) ||
1833 (strchr(SvPV(sval,na),')') != 0))
1834 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1835 &pixel,exception);
1836 else
1837 {
1838 GetPixelInfo(image,&pixel);
1839 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1840 pixel.red=geometry_info.rho;
1841 if ((flags & SigmaValue) != 0)
1842 pixel.green=geometry_info.sigma;
1843 if ((flags & XiValue) != 0)
1844 pixel.blue=geometry_info.xi;
1845 if ((flags & PsiValue) != 0)
1846 pixel.alpha=geometry_info.psi;
1847 if ((flags & ChiValue) != 0)
1848 pixel.black=geometry_info.chi;
1849 }
1850 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1851 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1852 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1853 if (image->colorspace == CMYKColorspace)
1854 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1855 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1856 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1857 }
1858 image_view=DestroyCacheView(image_view);
1859 }
1860 break;
1861 }
1862 if (LocaleCompare(attribute,"pointsize") == 0)
1863 {
1864 if (info)
1865 {
1866 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1867 info->image_info->pointsize=geometry_info.rho;
1868 }
1869 break;
1870 }
1871 if (LocaleCompare(attribute,"preview") == 0)
1872 {
1873 sp=SvPOK(sval) ? ParseCommandOption(MagickPreviewOptions,MagickFalse,
1874 SvPV(sval,na)) : SvIV(sval);
1875 if (sp < 0)
1876 {
1877 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1878 SvPV(sval,na));
1879 break;
1880 }
1881 if (info)
1882 info->image_info->preview_type=(PreviewType) sp;
1883 break;
1884 }
1885 if (info)
1886 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1887 for ( ; image; image=image->next)
1888 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1889 break;
1890 }
1891 case 'Q':
1892 case 'q':
1893 {
1894 if (LocaleCompare(attribute,"quality") == 0)
1895 {
1896 if (info)
1897 info->image_info->quality=SvIV(sval);
1898 for ( ; image; image=image->next)
1899 image->quality=SvIV(sval);
1900 break;
1901 }
1902 if (info)
1903 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1904 for ( ; image; image=image->next)
1905 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1906 break;
1907 }
1908 case 'R':
1909 case 'r':
1910 {
1911 if (LocaleCompare(attribute,"red-primary") == 0)
1912 {
1913 for ( ; image; image=image->next)
1914 {
1915 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1916 image->chromaticity.red_primary.x=geometry_info.rho;
1917 image->chromaticity.red_primary.y=geometry_info.sigma;
1918 if ((flags & SigmaValue) == 0)
1919 image->chromaticity.red_primary.y=
1920 image->chromaticity.red_primary.x;
1921 }
1922 break;
1923 }
1924 if (LocaleCompare(attribute,"render") == 0)
1925 {
1926 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1927 SvPV(sval,na)) : SvIV(sval);
1928 if (sp < 0)
1929 {
1930 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1931 SvPV(sval,na));
1932 break;
1933 }
1934 for ( ; image; image=image->next)
1935 image->rendering_intent=(RenderingIntent) sp;
1936 break;
1937 }
1938 if (LocaleCompare(attribute,"repage") == 0)
1939 {
1940 RectangleInfo
1941 geometry;
1942
1943 for ( ; image; image=image->next)
1944 {
1945 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1946 if ((flags & WidthValue) != 0)
1947 {
1948 if ((flags & HeightValue) == 0)
1949 geometry.height=geometry.width;
1950 image->page.width=geometry.width;
1951 image->page.height=geometry.height;
1952 }
1953 if ((flags & AspectValue) != 0)
1954 {
1955 if ((flags & XValue) != 0)
1956 image->page.x+=geometry.x;
1957 if ((flags & YValue) != 0)
1958 image->page.y+=geometry.y;
1959 }
1960 else
1961 {
1962 if ((flags & XValue) != 0)
1963 {
1964 image->page.x=geometry.x;
1965 if (((flags & WidthValue) != 0) && (geometry.x > 0))
1966 image->page.width=image->columns+geometry.x;
1967 }
1968 if ((flags & YValue) != 0)
1969 {
1970 image->page.y=geometry.y;
1971 if (((flags & HeightValue) != 0) && (geometry.y > 0))
1972 image->page.height=image->rows+geometry.y;
1973 }
1974 }
1975 }
1976 break;
1977 }
1978 if (info)
1979 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1980 for ( ; image; image=image->next)
1981 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1982 break;
1983 }
1984 case 'S':
1985 case 's':
1986 {
1987 if (LocaleCompare(attribute,"sampling-factor") == 0)
1988 {
1989 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1990 {
1991 ThrowPerlException(exception,OptionError,"MissingGeometry",
1992 SvPV(sval,na));
1993 break;
1994 }
1995 if (info)
1996 (void) CloneString(&info->image_info->sampling_factor,
1997 SvPV(sval,na));
1998 break;
1999 }
2000 if (LocaleCompare(attribute,"scene") == 0)
2001 {
2002 for ( ; image; image=image->next)
2003 image->scene=SvIV(sval);
2004 break;
2005 }
2006 if (LocaleCompare(attribute,"server") == 0)
2007 goto display;
2008 if (LocaleCompare(attribute,"size") == 0)
2009 {
2010 if (info)
2011 {
2012 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2013 {
2014 ThrowPerlException(exception,OptionError,"MissingGeometry",
2015 SvPV(sval,na));
2016 break;
2017 }
2018 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2019 }
2020 break;
2021 }
2022 if (LocaleCompare(attribute,"stroke") == 0)
2023 {
2024 if (info)
2025 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2026 break;
2027 }
2028 if (info)
2029 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2030 for ( ; image; image=image->next)
2031 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2032 break;
2033 }
2034 case 'T':
2035 case 't':
2036 {
2037 if (LocaleCompare(attribute,"texture") == 0)
2038 {
2039 if (info)
2040 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2041 break;
2042 }
2043 if (LocaleCompare(attribute,"thread-limit") == 0)
2044 {
2045 MagickSizeType
2046 limit;
2047
2048 limit=MagickResourceInfinity;
2049 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2050 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2051 100.0);
2052 (void) SetMagickResourceLimit(ThreadResource,limit);
2053 break;
2054 }
2055 if (LocaleCompare(attribute,"tile-offset") == 0)
2056 {
2057 char
2058 *geometry;
2059
2060 geometry=GetPageGeometry(SvPV(sval,na));
2061 if (info)
2062 (void) CloneString(&info->image_info->page,geometry);
2063 for ( ; image; image=image->next)
2064 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2065 exception);
2066 geometry=(char *) RelinquishMagickMemory(geometry);
2067 break;
2068 }
2069 if (LocaleCompare(attribute,"time-limit") == 0)
2070 {
2071 MagickSizeType
2072 limit;
2073
2074 limit=MagickResourceInfinity;
2075 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2076 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2077 100.0);
2078 (void) SetMagickResourceLimit(TimeResource,limit);
2079 break;
2080 }
2081 if (LocaleCompare(attribute,"transparent-color") == 0)
2082 {
2083 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2084 exception);
2085 if (info)
2086 info->image_info->transparent_color=target_color;
2087 for ( ; image; image=image->next)
2088 image->transparent_color=target_color;
2089 break;
2090 }
2091 if (LocaleCompare(attribute,"type") == 0)
2092 {
2093 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2094 SvPV(sval,na)) : SvIV(sval);
2095 if (sp < 0)
2096 {
2097 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2098 SvPV(sval,na));
2099 break;
2100 }
2101 if (info)
2102 info->image_info->type=(ImageType) sp;
2103 for ( ; image; image=image->next)
2104 SetImageType(image,(ImageType) sp,exception);
2105 break;
2106 }
2107 if (info)
2108 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2109 for ( ; image; image=image->next)
2110 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2111 break;
2112 }
2113 case 'U':
2114 case 'u':
2115 {
2116 if (LocaleCompare(attribute,"units") == 0)
2117 {
2118 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2119 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2120 if (sp < 0)
2121 {
2122 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2123 SvPV(sval,na));
2124 break;
2125 }
2126 if (info)
2127 info->image_info->units=(ResolutionType) sp;
2128 for ( ; image; image=image->next)
2129 {
2130 ResolutionType
2131 units;
2132
2133 units=(ResolutionType) sp;
2134 if (image->units != units)
2135 switch (image->units)
2136 {
2137 case UndefinedResolution:
2138 case PixelsPerInchResolution:
2139 {
2140 if (units == PixelsPerCentimeterResolution)
2141 {
2142 image->resolution.x*=2.54;
2143 image->resolution.y*=2.54;
2144 }
2145 break;
2146 }
2147 case PixelsPerCentimeterResolution:
2148 {
2149 if (units == PixelsPerInchResolution)
2150 {
2151 image->resolution.x/=2.54;
2152 image->resolution.y/=2.54;
2153 }
2154 break;
2155 }
2156 }
2157 image->units=units;
2158 }
2159 break;
2160 }
2161 if (info)
2162 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2163 for ( ; image; image=image->next)
2164 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2165 break;
2166 }
2167 case 'V':
2168 case 'v':
2169 {
2170 if (LocaleCompare(attribute,"verbose") == 0)
2171 {
2172 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2173 SvPV(sval,na)) : SvIV(sval);
2174 if (sp < 0)
2175 {
2176 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2177 SvPV(sval,na));
2178 break;
2179 }
2180 if (info)
2181 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2182 break;
2183 }
2184 if (LocaleCompare(attribute,"view") == 0)
2185 {
2186 if (info)
2187 (void) CloneString(&info->image_info->view,SvPV(sval,na));
2188 break;
2189 }
2190 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2191 {
2192 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2193 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2194 if (sp < 0)
2195 {
2196 ThrowPerlException(exception,OptionError,
2197 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2198 break;
2199 }
2200 for ( ; image; image=image->next)
2201 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2202 break;
2203 }
2204 if (info)
2205 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2206 for ( ; image; image=image->next)
2207 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2208 break;
2209 }
2210 case 'W':
2211 case 'w':
2212 {
2213 if (LocaleCompare(attribute,"white-point") == 0)
2214 {
2215 for ( ; image; image=image->next)
2216 {
2217 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2218 image->chromaticity.white_point.x=geometry_info.rho;
2219 image->chromaticity.white_point.y=geometry_info.sigma;
2220 if ((flags & SigmaValue) == 0)
2221 image->chromaticity.white_point.y=
2222 image->chromaticity.white_point.x;
2223 }
2224 break;
2225 }
2226 if (info)
2227 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2228 for ( ; image; image=image->next)
2229 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2230 break;
2231 }
2232 default:
2233 {
2234 if (info)
2235 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2236 for ( ; image; image=image->next)
2237 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2238 break;
2239 }
2240 }
2241}
2242
2243/*
2244%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2245% %
2246% %
2247% %
2248% S e t u p L i s t %
2249% %
2250% %
2251% %
2252%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2253%
2254% Method SetupList returns the list of all the images linked by their
2255% image->next and image->previous link lists for use with ImageMagick. If
2256% info is non-NULL, an info structure is returned in *info. If
2257% reference_vector is non-NULL,an array of SV* are returned in
2258% *reference_vector. Reference_vector is used when the images are going to be
2259% replaced with new Image*'s.
2260%
2261% The format of the SetupList routine is:
2262%
2263% Image *SetupList(SV *reference,struct PackageInfo **info,
2264% SV ***reference_vector,ExceptionInfo *exception)
2265%
2266% A description of each parameter follows:
2267%
2268% o list: a list of strings.
2269%
2270% o string: a character string.
2271%
2272% o exception: Return any errors or warnings in this structure.
2273%
2274*/
2275static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2276 SV ***reference_vector,ExceptionInfo *exception)
2277{
2278 Image
2279 *image;
2280
2281 ssize_t
2282 current,
2283 last;
2284
2285 if (reference_vector)
2286 *reference_vector=NULL;
2287 if (info)
2288 *info=NULL;
2289 current=0;
2290 last=0;
2291 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2292 if (info && (SvTYPE(reference) == SVt_PVAV))
2293 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2294 exception);
2295 return(image);
2296}
2297
2298/*
2299%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2300% %
2301% %
2302% %
2303% s t r E Q c a s e %
2304% %
2305% %
2306% %
2307%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2308%
2309% strEQcase() compares two strings and returns 0 if they are the
2310% same or if the second string runs out first. The comparison is case
2311% insensitive.
2312%
2313% The format of the strEQcase routine is:
2314%
2315% ssize_t strEQcase(const char *p,const char *q)
2316%
2317% A description of each parameter follows:
2318%
2319% o p: a character string.
2320%
2321% o q: a character string.
2322%
2323%
2324*/
2325static ssize_t strEQcase(const char *p,const char *q)
2326{
2327 char
2328 c;
2329
2330 register ssize_t
2331 i;
2332
2333 for (i=0 ; (c=(*q)) != 0; i++)
2334 {
2335 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2336 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2337 return(0);
2338 p++;
2339 q++;
2340 }
2341 return(((*q == 0) && (*p == 0)) ? i : 0);
2342}
2343
2344/*
2345%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2346% %
2347% %
2348% %
2349% I m a g e : : M a g i c k %
2350% %
2351% %
2352% %
2353%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2354%
2355%
2356*/
2357MODULE = Image::Magick PACKAGE = Image::Magick
2358
2359PROTOTYPES: ENABLE
2360
2361BOOT:
2362 MagickCoreGenesis("PerlMagick",MagickFalse);
2363 SetWarningHandler(NULL);
2364 SetErrorHandler(NULL);
2365 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2366 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2367
2368void
2369UNLOAD()
2370 PPCODE:
2371 {
2372 if (magick_registry != (SplayTreeInfo *) NULL)
2373 magick_registry=DestroySplayTree(magick_registry);
2374 MagickCoreTerminus();
2375 }
2376
2377double
2378constant(name,argument)
2379 char *name
2380 ssize_t argument
2381
2382#
2383###############################################################################
2384# #
2385# #
2386# #
2387# A n i m a t e #
2388# #
2389# #
2390# #
2391###############################################################################
2392#
2393#
2394void
2395Animate(ref,...)
2396 Image::Magick ref=NO_INIT
2397 ALIAS:
2398 AnimateImage = 1
2399 animate = 2
2400 animateimage = 3
2401 PPCODE:
2402 {
2403 ExceptionInfo
2404 *exception;
2405
2406 Image
2407 *image;
2408
2409 register ssize_t
2410 i;
2411
2412 struct PackageInfo
2413 *info,
2414 *package_info;
2415
2416 SV
2417 *perl_exception,
2418 *reference;
2419
2420 PERL_UNUSED_VAR(ref);
2421 PERL_UNUSED_VAR(ix);
2422 exception=AcquireExceptionInfo();
2423 perl_exception=newSVpv("",0);
2424 package_info=(struct PackageInfo *) NULL;
2425 if (sv_isobject(ST(0)) == 0)
2426 {
2427 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2428 PackageName);
2429 goto PerlException;
2430 }
2431 reference=SvRV(ST(0));
2432 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2433 if (image == (Image *) NULL)
2434 {
2435 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2436 PackageName);
2437 goto PerlException;
2438 }
2439 package_info=ClonePackageInfo(info,exception);
2440 if (items == 2)
2441 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2442 else
2443 if (items > 2)
2444 for (i=2; i < items; i+=2)
2445 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2446 exception);
2447 (void) AnimateImages(package_info->image_info,image,exception);
2448 (void) CatchImageException(image);
2449
2450 PerlException:
2451 if (package_info != (struct PackageInfo *) NULL)
2452 DestroyPackageInfo(package_info);
2453 InheritPerlException(exception,perl_exception);
2454 exception=DestroyExceptionInfo(exception);
2455 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2456 SvPOK_on(perl_exception);
2457 ST(0)=sv_2mortal(perl_exception);
2458 XSRETURN(1);
2459 }
2460
2461#
2462###############################################################################
2463# #
2464# #
2465# #
2466# A p p e n d #
2467# #
2468# #
2469# #
2470###############################################################################
2471#
2472#
2473void
2474Append(ref,...)
2475 Image::Magick ref=NO_INIT
2476 ALIAS:
2477 AppendImage = 1
2478 append = 2
2479 appendimage = 3
2480 PPCODE:
2481 {
2482 AV
2483 *av;
2484
2485 char
2486 *attribute;
2487
2488 ExceptionInfo
2489 *exception;
2490
2491 HV
2492 *hv;
2493
2494 Image
2495 *image;
2496
2497 register ssize_t
2498 i;
2499
2500 ssize_t
2501 stack;
2502
2503 struct PackageInfo
2504 *info;
2505
2506 SV
2507 *av_reference,
2508 *perl_exception,
2509 *reference,
2510 *rv,
2511 *sv;
2512
2513 PERL_UNUSED_VAR(ref);
2514 PERL_UNUSED_VAR(ix);
2515 exception=AcquireExceptionInfo();
2516 perl_exception=newSVpv("",0);
2517 sv=NULL;
2518 attribute=NULL;
2519 av=NULL;
2520 if (sv_isobject(ST(0)) == 0)
2521 {
2522 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2523 PackageName);
2524 goto PerlException;
2525 }
2526 reference=SvRV(ST(0));
2527 hv=SvSTASH(reference);
2528 av=newAV();
2529 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2530 SvREFCNT_dec(av);
2531 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2532 if (image == (Image *) NULL)
2533 {
2534 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2535 PackageName);
2536 goto PerlException;
2537 }
2538 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2539 /*
2540 Get options.
2541 */
2542 stack=MagickTrue;
2543 for (i=2; i < items; i+=2)
2544 {
2545 attribute=(char *) SvPV(ST(i-1),na);
2546 switch (*attribute)
2547 {
2548 case 'S':
2549 case 's':
2550 {
2551 if (LocaleCompare(attribute,"stack") == 0)
2552 {
2553 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2554 SvPV(ST(i),na));
2555 if (stack < 0)
2556 {
2557 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2558 SvPV(ST(i),na));
2559 return;
2560 }
2561 break;
2562 }
2563 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2564 attribute);
2565 break;
2566 }
2567 default:
2568 {
2569 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2570 attribute);
2571 break;
2572 }
2573 }
2574 }
2575 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2576 if (image == (Image *) NULL)
2577 goto PerlException;
2578 for ( ; image; image=image->next)
2579 {
2580 AddImageToRegistry(sv,image);
2581 rv=newRV(sv);
2582 av_push(av,sv_bless(rv,hv));
2583 SvREFCNT_dec(sv);
2584 }
2585 exception=DestroyExceptionInfo(exception);
2586 ST(0)=av_reference;
2587 SvREFCNT_dec(perl_exception);
2588 XSRETURN(1);
2589
2590 PerlException:
2591 InheritPerlException(exception,perl_exception);
2592 exception=DestroyExceptionInfo(exception);
2593 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2594 SvPOK_on(perl_exception);
2595 ST(0)=sv_2mortal(perl_exception);
2596 XSRETURN(1);
2597 }
2598
2599#
2600###############################################################################
2601# #
2602# #
2603# #
2604# A v e r a g e #
2605# #
2606# #
2607# #
2608###############################################################################
2609#
2610#
2611void
2612Average(ref)
2613 Image::Magick ref=NO_INIT
2614 ALIAS:
2615 AverageImage = 1
2616 average = 2
2617 averageimage = 3
2618 PPCODE:
2619 {
2620 AV
2621 *av;
2622
2623 char
2624 *p;
2625
2626 ExceptionInfo
2627 *exception;
2628
2629 HV
2630 *hv;
2631
2632 Image
2633 *image;
2634
2635 struct PackageInfo
2636 *info;
2637
2638 SV
2639 *perl_exception,
2640 *reference,
2641 *rv,
2642 *sv;
2643
2644 PERL_UNUSED_VAR(ref);
2645 PERL_UNUSED_VAR(ix);
2646 exception=AcquireExceptionInfo();
2647 perl_exception=newSVpv("",0);
2648 sv=NULL;
2649 if (sv_isobject(ST(0)) == 0)
2650 {
2651 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2652 PackageName);
2653 goto PerlException;
2654 }
2655 reference=SvRV(ST(0));
2656 hv=SvSTASH(reference);
2657 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2658 if (image == (Image *) NULL)
2659 {
2660 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2661 PackageName);
2662 goto PerlException;
2663 }
2664 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2665 if (image == (Image *) NULL)
2666 goto PerlException;
2667 /*
2668 Create blessed Perl array for the returned image.
2669 */
2670 av=newAV();
2671 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2672 SvREFCNT_dec(av);
2673 AddImageToRegistry(sv,image);
2674 rv=newRV(sv);
2675 av_push(av,sv_bless(rv,hv));
2676 SvREFCNT_dec(sv);
2677 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002678 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2679 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002680 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2681 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002682 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002683 SetImageInfo(info->image_info,0,exception);
2684 exception=DestroyExceptionInfo(exception);
2685 SvREFCNT_dec(perl_exception);
2686 XSRETURN(1);
2687
2688 PerlException:
2689 InheritPerlException(exception,perl_exception);
2690 exception=DestroyExceptionInfo(exception);
2691 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2692 SvPOK_on(perl_exception);
2693 ST(0)=sv_2mortal(perl_exception);
2694 XSRETURN(1);
2695 }
2696
2697#
2698###############################################################################
2699# #
2700# #
2701# #
2702# B l o b T o I m a g e #
2703# #
2704# #
2705# #
2706###############################################################################
2707#
2708#
2709void
2710BlobToImage(ref,...)
2711 Image::Magick ref=NO_INIT
2712 ALIAS:
2713 BlobToImage = 1
2714 blobtoimage = 2
2715 blobto = 3
2716 PPCODE:
2717 {
2718 AV
2719 *av;
2720
2721 char
2722 **keep,
2723 **list;
2724
2725 ExceptionInfo
2726 *exception;
2727
2728 HV
2729 *hv;
2730
2731 Image
2732 *image;
2733
2734 register char
2735 **p;
2736
2737 register ssize_t
2738 i;
2739
2740 ssize_t
2741 ac,
2742 n,
2743 number_images;
2744
2745 STRLEN
2746 *length;
2747
2748 struct PackageInfo
2749 *info;
2750
2751 SV
2752 *perl_exception,
2753 *reference,
2754 *rv,
2755 *sv;
2756
2757 PERL_UNUSED_VAR(ref);
2758 PERL_UNUSED_VAR(ix);
2759 exception=AcquireExceptionInfo();
2760 perl_exception=newSVpv("",0);
2761 sv=NULL;
2762 number_images=0;
2763 ac=(items < 2) ? 1 : items-1;
2764 length=(STRLEN *) NULL;
2765 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2766 if (list == (char **) NULL)
2767 {
2768 ThrowPerlException(exception,ResourceLimitError,
2769 "MemoryAllocationFailed",PackageName);
2770 goto PerlException;
2771 }
2772 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2773 if (length == (STRLEN *) NULL)
2774 {
2775 ThrowPerlException(exception,ResourceLimitError,
2776 "MemoryAllocationFailed",PackageName);
2777 goto PerlException;
2778 }
2779 if (sv_isobject(ST(0)) == 0)
2780 {
2781 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2782 PackageName);
2783 goto PerlException;
2784 }
2785 reference=SvRV(ST(0));
2786 hv=SvSTASH(reference);
2787 if (SvTYPE(reference) != SVt_PVAV)
2788 {
2789 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2790 PackageName);
2791 goto PerlException;
2792 }
2793 av=(AV *) reference;
2794 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2795 exception);
2796 n=1;
2797 if (items <= 1)
2798 {
2799 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2800 goto PerlException;
2801 }
2802 for (n=0, i=0; i < ac; i++)
2803 {
2804 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2805 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2806 {
2807 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2808 continue;
2809 }
2810 n++;
2811 }
2812 list[n]=(char *) NULL;
2813 keep=list;
2814 for (i=number_images=0; i < n; i++)
2815 {
2816 image=BlobToImage(info->image_info,list[i],length[i],exception);
2817 if (image == (Image *) NULL)
2818 break;
2819 for ( ; image; image=image->next)
2820 {
2821 AddImageToRegistry(sv,image);
2822 rv=newRV(sv);
2823 av_push(av,sv_bless(rv,hv));
2824 SvREFCNT_dec(sv);
2825 number_images++;
2826 }
2827 }
2828 /*
2829 Free resources.
2830 */
2831 for (i=0; i < n; i++)
2832 if (list[i] != (char *) NULL)
2833 for (p=keep; list[i] != *p++; )
2834 if (*p == (char *) NULL)
2835 {
2836 list[i]=(char *) RelinquishMagickMemory(list[i]);
2837 break;
2838 }
2839
2840 PerlException:
2841 if (list)
2842 list=(char **) RelinquishMagickMemory(list);
2843 if (length)
2844 length=(STRLEN *) RelinquishMagickMemory(length);
2845 InheritPerlException(exception,perl_exception);
2846 exception=DestroyExceptionInfo(exception);
2847 sv_setiv(perl_exception,(IV) number_images);
2848 SvPOK_on(perl_exception);
2849 ST(0)=sv_2mortal(perl_exception);
2850 XSRETURN(1);
2851 }
2852
2853#
2854###############################################################################
2855# #
2856# #
2857# #
2858# C h a n n e l F x #
2859# #
2860# #
2861# #
2862###############################################################################
2863#
2864#
2865void
2866ChannelFx(ref,...)
2867 Image::Magick ref=NO_INIT
2868 ALIAS:
2869 ChannelFxImage = 1
2870 channelfx = 2
2871 channelfximage = 3
2872 PPCODE:
2873 {
2874 AV
2875 *av;
2876
2877 char
2878 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002879 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002880
2881 ChannelType
2882 channel,
2883 channel_mask;
2884
2885 ExceptionInfo
2886 *exception;
2887
2888 HV
2889 *hv;
2890
2891 Image
2892 *image;
2893
2894 register ssize_t
2895 i;
2896
2897 struct PackageInfo
2898 *info;
2899
2900 SV
2901 *av_reference,
2902 *perl_exception,
2903 *reference,
2904 *rv,
2905 *sv;
2906
2907 PERL_UNUSED_VAR(ref);
2908 PERL_UNUSED_VAR(ix);
2909 exception=AcquireExceptionInfo();
2910 perl_exception=newSVpv("",0);
2911 sv=NULL;
2912 attribute=NULL;
2913 av=NULL;
2914 if (sv_isobject(ST(0)) == 0)
2915 {
2916 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2917 PackageName);
2918 goto PerlException;
2919 }
2920 reference=SvRV(ST(0));
2921 hv=SvSTASH(reference);
2922 av=newAV();
2923 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2924 SvREFCNT_dec(av);
2925 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2926 if (image == (Image *) NULL)
2927 {
2928 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2929 PackageName);
2930 goto PerlException;
2931 }
2932 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2933 /*
2934 Get options.
2935 */
2936 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00002937 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002938 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00002939 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002940 else
2941 for (i=2; i < items; i+=2)
2942 {
2943 attribute=(char *) SvPV(ST(i-1),na);
2944 switch (*attribute)
2945 {
2946 case 'C':
2947 case 'c':
2948 {
2949 if (LocaleCompare(attribute,"channel") == 0)
2950 {
2951 ssize_t
2952 option;
2953
2954 option=ParseChannelOption(SvPV(ST(i),na));
2955 if (option < 0)
2956 {
2957 ThrowPerlException(exception,OptionError,
2958 "UnrecognizedType",SvPV(ST(i),na));
2959 return;
2960 }
2961 channel=(ChannelType) option;
2962 break;
2963 }
2964 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2965 attribute);
2966 break;
2967 }
2968 case 'E':
2969 case 'e':
2970 {
2971 if (LocaleCompare(attribute,"expression") == 0)
2972 {
2973 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00002974 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002975 break;
2976 }
2977 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2978 attribute);
2979 break;
2980 }
2981 default:
2982 {
2983 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2984 attribute);
2985 break;
2986 }
2987 }
2988 }
2989 channel_mask=SetImageChannelMask(image,channel);
2990 image=ChannelFxImage(image,expression,exception);
2991 if (image != (Image *) NULL)
2992 (void) SetImageChannelMask(image,channel_mask);
2993 if (image == (Image *) NULL)
2994 goto PerlException;
2995 for ( ; image; image=image->next)
2996 {
2997 AddImageToRegistry(sv,image);
2998 rv=newRV(sv);
2999 av_push(av,sv_bless(rv,hv));
3000 SvREFCNT_dec(sv);
3001 }
3002 exception=DestroyExceptionInfo(exception);
3003 ST(0)=av_reference;
3004 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3005 XSRETURN(1);
3006
3007 PerlException:
3008 InheritPerlException(exception,perl_exception);
3009 exception=DestroyExceptionInfo(exception);
3010 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3011 SvPOK_on(perl_exception);
3012 ST(0)=sv_2mortal(perl_exception);
3013 XSRETURN(1);
3014 }
3015
3016#
3017###############################################################################
3018# #
3019# #
3020# #
3021# C l o n e #
3022# #
3023# #
3024# #
3025###############################################################################
3026#
3027#
3028void
3029Clone(ref)
3030 Image::Magick ref=NO_INIT
3031 ALIAS:
3032 CopyImage = 1
3033 copy = 2
3034 copyimage = 3
3035 CloneImage = 4
3036 clone = 5
3037 cloneimage = 6
3038 Clone = 7
3039 PPCODE:
3040 {
3041 AV
3042 *av;
3043
3044 ExceptionInfo
3045 *exception;
3046
3047 HV
3048 *hv;
3049
3050 Image
3051 *clone,
3052 *image;
3053
3054 struct PackageInfo
3055 *info;
3056
3057 SV
3058 *perl_exception,
3059 *reference,
3060 *rv,
3061 *sv;
3062
3063 PERL_UNUSED_VAR(ref);
3064 PERL_UNUSED_VAR(ix);
3065 exception=AcquireExceptionInfo();
3066 perl_exception=newSVpv("",0);
3067 sv=NULL;
3068 if (sv_isobject(ST(0)) == 0)
3069 {
3070 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3071 PackageName);
3072 goto PerlException;
3073 }
3074 reference=SvRV(ST(0));
3075 hv=SvSTASH(reference);
3076 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3077 if (image == (Image *) NULL)
3078 {
3079 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3080 PackageName);
3081 goto PerlException;
3082 }
3083 /*
3084 Create blessed Perl array for the returned image.
3085 */
3086 av=newAV();
3087 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3088 SvREFCNT_dec(av);
3089 for ( ; image; image=image->next)
3090 {
3091 clone=CloneImage(image,0,0,MagickTrue,exception);
3092 if (clone == (Image *) NULL)
3093 break;
3094 AddImageToRegistry(sv,clone);
3095 rv=newRV(sv);
3096 av_push(av,sv_bless(rv,hv));
3097 SvREFCNT_dec(sv);
3098 }
3099 exception=DestroyExceptionInfo(exception);
3100 SvREFCNT_dec(perl_exception);
3101 XSRETURN(1);
3102
3103 PerlException:
3104 InheritPerlException(exception,perl_exception);
3105 exception=DestroyExceptionInfo(exception);
3106 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3107 SvPOK_on(perl_exception);
3108 ST(0)=sv_2mortal(perl_exception);
3109 XSRETURN(1);
3110 }
3111
3112#
3113###############################################################################
3114# #
3115# #
3116# #
3117# C L O N E #
3118# #
3119# #
3120# #
3121###############################################################################
3122#
3123#
3124void
3125CLONE(ref,...)
3126 SV *ref;
3127 CODE:
3128 {
3129 PERL_UNUSED_VAR(ref);
3130 if (magick_registry != (SplayTreeInfo *) NULL)
3131 {
3132 register Image
3133 *p;
3134
3135 ResetSplayTreeIterator(magick_registry);
3136 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3137 while (p != (Image *) NULL)
3138 {
3139 ReferenceImage(p);
3140 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3141 }
3142 }
3143 }
3144
3145#
3146###############################################################################
3147# #
3148# #
3149# #
3150# C o a l e s c e #
3151# #
3152# #
3153# #
3154###############################################################################
3155#
3156#
3157void
3158Coalesce(ref)
3159 Image::Magick ref=NO_INIT
3160 ALIAS:
3161 CoalesceImage = 1
3162 coalesce = 2
3163 coalesceimage = 3
3164 PPCODE:
3165 {
3166 AV
3167 *av;
3168
3169 ExceptionInfo
3170 *exception;
3171
3172 HV
3173 *hv;
3174
3175 Image
3176 *image;
3177
3178 struct PackageInfo
3179 *info;
3180
3181 SV
3182 *av_reference,
3183 *perl_exception,
3184 *reference,
3185 *rv,
3186 *sv;
3187
3188 PERL_UNUSED_VAR(ref);
3189 PERL_UNUSED_VAR(ix);
3190 exception=AcquireExceptionInfo();
3191 perl_exception=newSVpv("",0);
3192 sv=NULL;
3193 if (sv_isobject(ST(0)) == 0)
3194 {
3195 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3196 PackageName);
3197 goto PerlException;
3198 }
3199 reference=SvRV(ST(0));
3200 hv=SvSTASH(reference);
3201 av=newAV();
3202 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3203 SvREFCNT_dec(av);
3204 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3205 if (image == (Image *) NULL)
3206 {
3207 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3208 PackageName);
3209 goto PerlException;
3210 }
3211 image=CoalesceImages(image,exception);
3212 if (image == (Image *) NULL)
3213 goto PerlException;
3214 for ( ; image; image=image->next)
3215 {
3216 AddImageToRegistry(sv,image);
3217 rv=newRV(sv);
3218 av_push(av,sv_bless(rv,hv));
3219 SvREFCNT_dec(sv);
3220 }
3221 exception=DestroyExceptionInfo(exception);
3222 ST(0)=av_reference;
3223 SvREFCNT_dec(perl_exception);
3224 XSRETURN(1);
3225
3226 PerlException:
3227 InheritPerlException(exception,perl_exception);
3228 exception=DestroyExceptionInfo(exception);
3229 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3230 SvPOK_on(perl_exception);
3231 ST(0)=sv_2mortal(perl_exception);
3232 XSRETURN(1);
3233 }
3234
3235#
3236###############################################################################
3237# #
3238# #
3239# #
3240# C o m p a r e #
3241# #
3242# #
3243# #
3244###############################################################################
3245#
3246#
3247void
3248Compare(ref,...)
3249 Image::Magick ref=NO_INIT
3250 ALIAS:
3251 CompareImages = 1
3252 compare = 2
3253 compareimage = 3
3254 PPCODE:
3255 {
3256 AV
3257 *av;
3258
3259 char
3260 *attribute;
3261
3262 double
3263 distortion;
3264
3265 ExceptionInfo
3266 *exception;
3267
3268 HV
3269 *hv;
3270
3271 Image
3272 *difference_image,
3273 *image,
3274 *reconstruct_image;
3275
3276 MetricType
3277 metric;
3278
3279 register ssize_t
3280 i;
3281
3282 ssize_t
3283 option;
3284
3285 struct PackageInfo
3286 *info;
3287
3288 SV
3289 *av_reference,
3290 *perl_exception,
3291 *reference,
3292 *rv,
3293 *sv;
3294
3295 PERL_UNUSED_VAR(ref);
3296 PERL_UNUSED_VAR(ix);
3297 exception=AcquireExceptionInfo();
3298 perl_exception=newSVpv("",0);
3299 sv=NULL;
3300 av=NULL;
3301 attribute=NULL;
3302 if (sv_isobject(ST(0)) == 0)
3303 {
3304 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3305 PackageName);
3306 goto PerlException;
3307 }
3308 reference=SvRV(ST(0));
3309 hv=SvSTASH(reference);
3310 av=newAV();
3311 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3312 SvREFCNT_dec(av);
3313 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3314 if (image == (Image *) NULL)
3315 {
3316 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3317 PackageName);
3318 goto PerlException;
3319 }
3320 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3321 /*
3322 Get attribute.
3323 */
3324 reconstruct_image=image;
3325 metric=RootMeanSquaredErrorMetric;
3326 for (i=2; i < items; i+=2)
3327 {
3328 attribute=(char *) SvPV(ST(i-1),na);
3329 switch (*attribute)
3330 {
3331 case 'C':
3332 case 'c':
3333 {
3334 if (LocaleCompare(attribute,"channel") == 0)
3335 {
3336 ssize_t
3337 option;
3338
3339 option=ParseChannelOption(SvPV(ST(i),na));
3340 if (option < 0)
3341 {
3342 ThrowPerlException(exception,OptionError,
3343 "UnrecognizedType",SvPV(ST(i),na));
3344 return;
3345 }
3346 SetPixelChannelMask(image,(ChannelType) option);
3347 break;
3348 }
3349 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3350 attribute);
3351 break;
3352 }
3353 case 'F':
3354 case 'f':
3355 {
3356 if (LocaleCompare(attribute,"fuzz") == 0)
3357 {
3358 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3359 break;
3360 }
3361 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3362 attribute);
3363 break;
3364 }
3365 case 'I':
3366 case 'i':
3367 {
3368 if (LocaleCompare(attribute,"image") == 0)
3369 {
3370 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3371 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3372 break;
3373 }
3374 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3375 attribute);
3376 break;
3377 }
3378 case 'M':
3379 case 'm':
3380 {
3381 if (LocaleCompare(attribute,"metric") == 0)
3382 {
3383 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3384 SvPV(ST(i),na));
3385 if (option < 0)
3386 {
3387 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3388 SvPV(ST(i),na));
3389 break;
3390 }
3391 metric=(MetricType) option;
3392 break;
3393 }
3394 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3395 attribute);
3396 break;
3397 }
3398 default:
3399 {
3400 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3401 attribute);
3402 break;
3403 }
3404 }
3405 }
3406 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3407 exception);
3408 if (difference_image != (Image *) NULL)
3409 {
3410 difference_image->error.mean_error_per_pixel=distortion;
3411 AddImageToRegistry(sv,difference_image);
3412 rv=newRV(sv);
3413 av_push(av,sv_bless(rv,hv));
3414 SvREFCNT_dec(sv);
3415 }
3416 exception=DestroyExceptionInfo(exception);
3417 ST(0)=av_reference;
3418 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3419 XSRETURN(1);
3420
3421 PerlException:
3422 InheritPerlException(exception,perl_exception);
3423 exception=DestroyExceptionInfo(exception);
3424 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3425 SvPOK_on(perl_exception);
3426 ST(0)=sv_2mortal(perl_exception);
3427 XSRETURN(1);
3428 }
3429
3430#
3431###############################################################################
3432# #
3433# #
3434# #
cristy15655332013-10-06 00:27:33 +00003435# C o m p l e x I m a g e s #
3436# #
3437# #
3438# #
3439###############################################################################
3440#
3441#
3442void
3443ComplexImages(ref)
3444 Image::Magick ref=NO_INIT
3445 ALIAS:
3446 ComplexImages = 1
3447 compleximages = 2
3448 PPCODE:
3449 {
3450 AV
3451 *av;
3452
3453 char
3454 *attribute,
3455 *p;
3456
cristyfa21e9e2013-10-07 10:37:38 +00003457 ComplexOperator
3458 op;
3459
cristy15655332013-10-06 00:27:33 +00003460 ExceptionInfo
3461 *exception;
3462
3463 HV
3464 *hv;
3465
3466 Image
3467 *image;
3468
cristy15655332013-10-06 00:27:33 +00003469 register ssize_t
3470 i;
3471
3472 struct PackageInfo
3473 *info;
3474
3475 SV
3476 *perl_exception,
3477 *reference,
3478 *rv,
3479 *sv;
3480
3481 PERL_UNUSED_VAR(ref);
3482 PERL_UNUSED_VAR(ix);
3483 exception=AcquireExceptionInfo();
3484 perl_exception=newSVpv("",0);
3485 sv=NULL;
3486 if (sv_isobject(ST(0)) == 0)
3487 {
3488 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3489 PackageName);
3490 goto PerlException;
3491 }
3492 reference=SvRV(ST(0));
3493 hv=SvSTASH(reference);
3494 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3495 if (image == (Image *) NULL)
3496 {
3497 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3498 PackageName);
3499 goto PerlException;
3500 }
cristyfd168722013-10-07 15:59:31 +00003501 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003502 if (items == 2)
3503 {
3504 ssize_t
3505 in;
3506
3507 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3508 SvPV(ST(1),na));
3509 if (in < 0)
3510 {
3511 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3512 SvPV(ST(1),na));
3513 return;
3514 }
cristyfa21e9e2013-10-07 10:37:38 +00003515 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003516 }
3517 else
3518 for (i=2; i < items; i+=2)
3519 {
3520 attribute=(char *) SvPV(ST(i-1),na);
3521 switch (*attribute)
3522 {
3523 case 'O':
3524 case 'o':
3525 {
3526 if (LocaleCompare(attribute,"operator") == 0)
3527 {
3528 ssize_t
3529 in;
3530
3531 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3532 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3533 if (in < 0)
3534 {
3535 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3536 SvPV(ST(i),na));
3537 return;
3538 }
cristyfa21e9e2013-10-07 10:37:38 +00003539 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003540 break;
3541 }
3542 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3543 attribute);
3544 break;
3545 }
3546 default:
3547 {
3548 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3549 attribute);
3550 break;
3551 }
3552 }
3553 }
3554 image=ComplexImages(image,op,exception);
3555 if (image == (Image *) NULL)
3556 goto PerlException;
3557 /*
3558 Create blessed Perl array for the returned image.
3559 */
3560 av=newAV();
3561 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3562 SvREFCNT_dec(av);
3563 AddImageToRegistry(sv,image);
3564 rv=newRV(sv);
3565 av_push(av,sv_bless(rv,hv));
3566 SvREFCNT_dec(sv);
3567 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003568 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3569 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003570 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3571 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003572 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003573 SetImageInfo(info->image_info,0,exception);
3574 exception=DestroyExceptionInfo(exception);
3575 SvREFCNT_dec(perl_exception);
3576 XSRETURN(1);
3577
3578 PerlException:
3579 InheritPerlException(exception,perl_exception);
3580 exception=DestroyExceptionInfo(exception);
3581 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3582 SvPOK_on(perl_exception);
3583 ST(0)=sv_2mortal(perl_exception);
3584 XSRETURN(1);
3585 }
3586
3587#
3588###############################################################################
3589# #
3590# #
3591# #
cristy4a3ce0a2013-08-03 20:06:59 +00003592# C o m p a r e L a y e r s #
3593# #
3594# #
3595# #
3596###############################################################################
3597#
3598#
3599void
3600CompareLayers(ref)
3601 Image::Magick ref=NO_INIT
3602 ALIAS:
3603 CompareImagesLayers = 1
3604 comparelayers = 2
3605 compareimagelayers = 3
3606 PPCODE:
3607 {
3608 AV
3609 *av;
3610
3611 char
3612 *attribute;
3613
3614 ExceptionInfo
3615 *exception;
3616
3617 HV
3618 *hv;
3619
3620 Image
3621 *image;
3622
3623 LayerMethod
3624 method;
3625
3626 register ssize_t
3627 i;
3628
3629 ssize_t
3630 option;
3631
3632 struct PackageInfo
3633 *info;
3634
3635 SV
3636 *av_reference,
3637 *perl_exception,
3638 *reference,
3639 *rv,
3640 *sv;
3641
3642 PERL_UNUSED_VAR(ref);
3643 PERL_UNUSED_VAR(ix);
3644 exception=AcquireExceptionInfo();
3645 perl_exception=newSVpv("",0);
3646 sv=NULL;
3647 if (sv_isobject(ST(0)) == 0)
3648 {
3649 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3650 PackageName);
3651 goto PerlException;
3652 }
3653 reference=SvRV(ST(0));
3654 hv=SvSTASH(reference);
3655 av=newAV();
3656 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3657 SvREFCNT_dec(av);
3658 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3659 if (image == (Image *) NULL)
3660 {
3661 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3662 PackageName);
3663 goto PerlException;
3664 }
3665 method=CompareAnyLayer;
3666 for (i=2; i < items; i+=2)
3667 {
3668 attribute=(char *) SvPV(ST(i-1),na);
3669 switch (*attribute)
3670 {
3671 case 'M':
3672 case 'm':
3673 {
3674 if (LocaleCompare(attribute,"method") == 0)
3675 {
3676 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3677 SvPV(ST(i),na));
3678 if (option < 0)
3679 {
3680 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3681 SvPV(ST(i),na));
3682 break;
3683 }
3684 method=(LayerMethod) option;
3685 break;
3686 }
3687 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3688 attribute);
3689 break;
3690 }
3691 default:
3692 {
3693 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3694 attribute);
3695 break;
3696 }
3697 }
3698 }
3699 image=CompareImagesLayers(image,method,exception);
3700 if (image == (Image *) NULL)
3701 goto PerlException;
3702 for ( ; image; image=image->next)
3703 {
3704 AddImageToRegistry(sv,image);
3705 rv=newRV(sv);
3706 av_push(av,sv_bless(rv,hv));
3707 SvREFCNT_dec(sv);
3708 }
3709 exception=DestroyExceptionInfo(exception);
3710 ST(0)=av_reference;
3711 SvREFCNT_dec(perl_exception);
3712 XSRETURN(1);
3713
3714 PerlException:
3715 InheritPerlException(exception,perl_exception);
3716 exception=DestroyExceptionInfo(exception);
3717 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3718 SvPOK_on(perl_exception);
3719 ST(0)=sv_2mortal(perl_exception);
3720 XSRETURN(1);
3721 }
3722
3723#
3724###############################################################################
3725# #
3726# #
3727# #
3728# D e s t r o y #
3729# #
3730# #
3731# #
3732###############################################################################
3733#
3734#
3735void
3736DESTROY(ref)
3737 Image::Magick ref=NO_INIT
3738 PPCODE:
3739 {
3740 SV
3741 *reference;
3742
3743 PERL_UNUSED_VAR(ref);
3744 if (sv_isobject(ST(0)) == 0)
3745 croak("ReferenceIsNotMyType");
3746 reference=SvRV(ST(0));
3747 switch (SvTYPE(reference))
3748 {
3749 case SVt_PVAV:
3750 {
3751 char
cristy151b66d2015-04-15 10:50:31 +00003752 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003753
3754 const SV
3755 *key;
3756
3757 HV
3758 *hv;
3759
3760 GV
3761 **gvp;
3762
3763 struct PackageInfo
3764 *info;
3765
3766 SV
3767 *sv;
3768
3769 /*
3770 Array (AV *) reference
3771 */
cristy151b66d2015-04-15 10:50:31 +00003772 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003773 XS_VERSION,reference);
3774 hv=gv_stashpv(PackageName, FALSE);
3775 if (!hv)
3776 break;
3777 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3778 if (!gvp)
3779 break;
3780 sv=GvSV(*gvp);
3781 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3782 {
3783 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3784 DestroyPackageInfo(info);
3785 }
3786 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3787 (void) key;
3788 break;
3789 }
3790 case SVt_PVMG:
3791 {
3792 Image
3793 *image;
3794
3795 /*
3796 Blessed scalar = (Image *) SvIV(reference)
3797 */
3798 image=INT2PTR(Image *,SvIV(reference));
3799 if (image != (Image *) NULL)
3800 DeleteImageFromRegistry(reference,image);
3801 break;
3802 }
3803 default:
3804 break;
3805 }
3806 }
3807
3808#
3809###############################################################################
3810# #
3811# #
3812# #
3813# D i s p l a y #
3814# #
3815# #
3816# #
3817###############################################################################
3818#
3819#
3820void
3821Display(ref,...)
3822 Image::Magick ref=NO_INIT
3823 ALIAS:
3824 DisplayImage = 1
3825 display = 2
3826 displayimage = 3
3827 PPCODE:
3828 {
3829 ExceptionInfo
3830 *exception;
3831
3832 Image
3833 *image;
3834
3835 register ssize_t
3836 i;
3837
3838 struct PackageInfo
3839 *info,
3840 *package_info;
3841
3842 SV
3843 *perl_exception,
3844 *reference;
3845
3846 PERL_UNUSED_VAR(ref);
3847 PERL_UNUSED_VAR(ix);
3848 exception=AcquireExceptionInfo();
3849 perl_exception=newSVpv("",0);
3850 package_info=(struct PackageInfo *) NULL;
3851 if (sv_isobject(ST(0)) == 0)
3852 {
3853 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3854 PackageName);
3855 goto PerlException;
3856 }
3857 reference=SvRV(ST(0));
3858 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3859 if (image == (Image *) NULL)
3860 {
3861 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3862 PackageName);
3863 goto PerlException;
3864 }
3865 package_info=ClonePackageInfo(info,exception);
3866 if (items == 2)
3867 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3868 else
3869 if (items > 2)
3870 for (i=2; i < items; i+=2)
3871 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3872 exception);
3873 (void) DisplayImages(package_info->image_info,image,exception);
3874 (void) CatchImageException(image);
3875
3876 PerlException:
3877 if (package_info != (struct PackageInfo *) NULL)
3878 DestroyPackageInfo(package_info);
3879 InheritPerlException(exception,perl_exception);
3880 exception=DestroyExceptionInfo(exception);
3881 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3882 SvPOK_on(perl_exception);
3883 ST(0)=sv_2mortal(perl_exception);
3884 XSRETURN(1);
3885 }
3886
3887#
3888###############################################################################
3889# #
3890# #
3891# #
3892# E v a l u a t e I m a g e s #
3893# #
3894# #
3895# #
3896###############################################################################
3897#
3898#
3899void
3900EvaluateImages(ref)
3901 Image::Magick ref=NO_INIT
3902 ALIAS:
3903 EvaluateImages = 1
3904 evaluateimages = 2
3905 PPCODE:
3906 {
3907 AV
3908 *av;
3909
3910 char
3911 *attribute,
3912 *p;
3913
3914 ExceptionInfo
3915 *exception;
3916
3917 HV
3918 *hv;
3919
3920 Image
3921 *image;
3922
3923 MagickEvaluateOperator
3924 op;
3925
3926 register ssize_t
3927 i;
3928
3929 struct PackageInfo
3930 *info;
3931
3932 SV
3933 *perl_exception,
3934 *reference,
3935 *rv,
3936 *sv;
3937
3938 PERL_UNUSED_VAR(ref);
3939 PERL_UNUSED_VAR(ix);
3940 exception=AcquireExceptionInfo();
3941 perl_exception=newSVpv("",0);
3942 sv=NULL;
3943 if (sv_isobject(ST(0)) == 0)
3944 {
3945 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3946 PackageName);
3947 goto PerlException;
3948 }
3949 reference=SvRV(ST(0));
3950 hv=SvSTASH(reference);
3951 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3952 if (image == (Image *) NULL)
3953 {
3954 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3955 PackageName);
3956 goto PerlException;
3957 }
3958 op=MeanEvaluateOperator;
3959 if (items == 2)
3960 {
3961 ssize_t
3962 in;
3963
3964 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
3965 SvPV(ST(1),na));
3966 if (in < 0)
3967 {
3968 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3969 SvPV(ST(1),na));
3970 return;
3971 }
3972 op=(MagickEvaluateOperator) in;
3973 }
3974 else
3975 for (i=2; i < items; i+=2)
3976 {
3977 attribute=(char *) SvPV(ST(i-1),na);
3978 switch (*attribute)
3979 {
3980 case 'O':
3981 case 'o':
3982 {
3983 if (LocaleCompare(attribute,"operator") == 0)
3984 {
3985 ssize_t
3986 in;
3987
3988 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3989 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
3990 if (in < 0)
3991 {
3992 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3993 SvPV(ST(i),na));
3994 return;
3995 }
3996 op=(MagickEvaluateOperator) in;
3997 break;
3998 }
3999 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4000 attribute);
4001 break;
4002 }
4003 default:
4004 {
4005 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4006 attribute);
4007 break;
4008 }
4009 }
4010 }
4011 image=EvaluateImages(image,op,exception);
4012 if (image == (Image *) NULL)
4013 goto PerlException;
4014 /*
4015 Create blessed Perl array for the returned image.
4016 */
4017 av=newAV();
4018 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4019 SvREFCNT_dec(av);
4020 AddImageToRegistry(sv,image);
4021 rv=newRV(sv);
4022 av_push(av,sv_bless(rv,hv));
4023 SvREFCNT_dec(sv);
4024 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004025 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4026 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004027 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4028 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004029 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004030 SetImageInfo(info->image_info,0,exception);
4031 exception=DestroyExceptionInfo(exception);
4032 SvREFCNT_dec(perl_exception);
4033 XSRETURN(1);
4034
4035 PerlException:
4036 InheritPerlException(exception,perl_exception);
4037 exception=DestroyExceptionInfo(exception);
4038 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4039 SvPOK_on(perl_exception);
4040 ST(0)=sv_2mortal(perl_exception);
4041 XSRETURN(1);
4042 }
4043
4044#
4045###############################################################################
4046# #
4047# #
4048# #
4049# F e a t u r e s #
4050# #
4051# #
4052# #
4053###############################################################################
4054#
4055#
4056void
4057Features(ref,...)
4058 Image::Magick ref=NO_INIT
4059 ALIAS:
4060 FeaturesImage = 1
4061 features = 2
4062 featuresimage = 3
4063 PPCODE:
4064 {
4065#define ChannelFeatures(channel,direction) \
4066{ \
cristy151b66d2015-04-15 10:50:31 +00004067 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004068 channel_features[channel].angular_second_moment[direction]); \
4069 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004070 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004071 channel_features[channel].contrast[direction]); \
4072 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004073 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004074 channel_features[channel].contrast[direction]); \
4075 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004076 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004077 channel_features[channel].variance_sum_of_squares[direction]); \
4078 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004079 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004080 channel_features[channel].inverse_difference_moment[direction]); \
4081 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004082 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004083 channel_features[channel].sum_average[direction]); \
4084 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004085 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004086 channel_features[channel].sum_variance[direction]); \
4087 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004088 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004089 channel_features[channel].sum_entropy[direction]); \
4090 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004091 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004092 channel_features[channel].entropy[direction]); \
4093 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004094 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004095 channel_features[channel].difference_variance[direction]); \
4096 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004097 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004098 channel_features[channel].difference_entropy[direction]); \
4099 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004100 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004101 channel_features[channel].measure_of_correlation_1[direction]); \
4102 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004103 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004104 channel_features[channel].measure_of_correlation_2[direction]); \
4105 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +00004106 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004107 channel_features[channel].maximum_correlation_coefficient[direction]); \
4108 PUSHs(sv_2mortal(newSVpv(message,0))); \
4109}
4110
4111 AV
4112 *av;
4113
4114 char
4115 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004116 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004117
4118 ChannelFeatures
4119 *channel_features;
4120
4121 double
4122 distance;
4123
4124 ExceptionInfo
4125 *exception;
4126
4127 Image
4128 *image;
4129
4130 register ssize_t
4131 i;
4132
4133 ssize_t
4134 count;
4135
4136 struct PackageInfo
4137 *info;
4138
4139 SV
4140 *perl_exception,
4141 *reference;
4142
4143 PERL_UNUSED_VAR(ref);
4144 PERL_UNUSED_VAR(ix);
4145 exception=AcquireExceptionInfo();
4146 perl_exception=newSVpv("",0);
4147 av=NULL;
4148 if (sv_isobject(ST(0)) == 0)
4149 {
4150 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4151 PackageName);
4152 goto PerlException;
4153 }
4154 reference=SvRV(ST(0));
4155 av=newAV();
4156 SvREFCNT_dec(av);
4157 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4158 if (image == (Image *) NULL)
4159 {
4160 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4161 PackageName);
4162 goto PerlException;
4163 }
cristy7dbd9262014-07-02 17:53:42 +00004164 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004165 for (i=2; i < items; i+=2)
4166 {
4167 attribute=(char *) SvPV(ST(i-1),na);
4168 switch (*attribute)
4169 {
4170 case 'D':
4171 case 'd':
4172 {
4173 if (LocaleCompare(attribute,"distance") == 0)
4174 {
4175 distance=StringToLong((char *) SvPV(ST(1),na));
4176 break;
4177 }
4178 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4179 attribute);
4180 break;
4181 }
4182 default:
4183 {
4184 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4185 attribute);
4186 break;
4187 }
4188 }
4189 }
4190 count=0;
4191 for ( ; image; image=image->next)
4192 {
4193 channel_features=GetImageFeatures(image,distance,exception);
4194 if (channel_features == (ChannelFeatures *) NULL)
4195 continue;
4196 count++;
cristyfcf3bdf2014-07-02 14:35:58 +00004197 EXTEND(sp,280*count);
cristy4a3ce0a2013-08-03 20:06:59 +00004198 for (i=0; i < 4; i++)
4199 {
4200 ChannelFeatures(RedChannel,i);
4201 ChannelFeatures(GreenChannel,i);
4202 ChannelFeatures(BlueChannel,i);
4203 if (image->colorspace == CMYKColorspace)
4204 ChannelFeatures(BlackChannel,i);
cristy17f11b02014-12-20 19:37:04 +00004205 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00004206 ChannelFeatures(AlphaChannel,i);
4207 }
4208 channel_features=(ChannelFeatures *)
4209 RelinquishMagickMemory(channel_features);
4210 }
4211
4212 PerlException:
4213 InheritPerlException(exception,perl_exception);
4214 exception=DestroyExceptionInfo(exception);
4215 SvREFCNT_dec(perl_exception);
4216 }
4217
4218#
4219###############################################################################
4220# #
4221# #
4222# #
4223# F l a t t e n #
4224# #
4225# #
4226# #
4227###############################################################################
4228#
4229#
4230void
4231Flatten(ref)
4232 Image::Magick ref=NO_INIT
4233 ALIAS:
4234 FlattenImage = 1
4235 flatten = 2
4236 flattenimage = 3
4237 PPCODE:
4238 {
4239 AV
4240 *av;
4241
4242 char
4243 *attribute,
4244 *p;
4245
4246 ExceptionInfo
4247 *exception;
4248
4249 HV
4250 *hv;
4251
4252 Image
4253 *image;
4254
4255 PixelInfo
4256 background_color;
4257
4258 register ssize_t
4259 i;
4260
4261 struct PackageInfo
4262 *info;
4263
4264 SV
4265 *perl_exception,
4266 *reference,
4267 *rv,
4268 *sv;
4269
4270 PERL_UNUSED_VAR(ref);
4271 PERL_UNUSED_VAR(ix);
4272 exception=AcquireExceptionInfo();
4273 perl_exception=newSVpv("",0);
4274 sv=NULL;
4275 if (sv_isobject(ST(0)) == 0)
4276 {
4277 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4278 PackageName);
4279 goto PerlException;
4280 }
4281 reference=SvRV(ST(0));
4282 hv=SvSTASH(reference);
4283 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4284 if (image == (Image *) NULL)
4285 {
4286 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4287 PackageName);
4288 goto PerlException;
4289 }
4290 background_color=image->background_color;
4291 if (items == 2)
4292 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4293 &background_color,exception);
4294 else
4295 for (i=2; i < items; i+=2)
4296 {
4297 attribute=(char *) SvPV(ST(i-1),na);
4298 switch (*attribute)
4299 {
4300 case 'B':
4301 case 'b':
4302 {
4303 if (LocaleCompare(attribute,"background") == 0)
4304 {
4305 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4306 AllCompliance,&background_color,exception);
4307 break;
4308 }
4309 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4310 attribute);
4311 break;
4312 }
4313 default:
4314 {
4315 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4316 attribute);
4317 break;
4318 }
4319 }
4320 }
4321 image->background_color=background_color;
4322 image=MergeImageLayers(image,FlattenLayer,exception);
4323 if (image == (Image *) NULL)
4324 goto PerlException;
4325 /*
4326 Create blessed Perl array for the returned image.
4327 */
4328 av=newAV();
4329 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4330 SvREFCNT_dec(av);
4331 AddImageToRegistry(sv,image);
4332 rv=newRV(sv);
4333 av_push(av,sv_bless(rv,hv));
4334 SvREFCNT_dec(sv);
4335 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004336 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4337 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004338 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4339 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004340 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004341 SetImageInfo(info->image_info,0,exception);
4342 exception=DestroyExceptionInfo(exception);
4343 SvREFCNT_dec(perl_exception);
4344 XSRETURN(1);
4345
4346 PerlException:
4347 InheritPerlException(exception,perl_exception);
4348 exception=DestroyExceptionInfo(exception);
4349 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4350 SvPOK_on(perl_exception); /* return messages in string context */
4351 ST(0)=sv_2mortal(perl_exception);
4352 XSRETURN(1);
4353 }
4354
4355#
4356###############################################################################
4357# #
4358# #
4359# #
4360# F x #
4361# #
4362# #
4363# #
4364###############################################################################
4365#
4366#
4367void
4368Fx(ref,...)
4369 Image::Magick ref=NO_INIT
4370 ALIAS:
4371 FxImage = 1
4372 fx = 2
4373 fximage = 3
4374 PPCODE:
4375 {
4376 AV
4377 *av;
4378
4379 char
4380 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004381 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004382
4383 ChannelType
4384 channel,
4385 channel_mask;
4386
4387 ExceptionInfo
4388 *exception;
4389
4390 HV
4391 *hv;
4392
4393 Image
4394 *image;
4395
4396 register ssize_t
4397 i;
4398
4399 struct PackageInfo
4400 *info;
4401
4402 SV
4403 *av_reference,
4404 *perl_exception,
4405 *reference,
4406 *rv,
4407 *sv;
4408
4409 PERL_UNUSED_VAR(ref);
4410 PERL_UNUSED_VAR(ix);
4411 exception=AcquireExceptionInfo();
4412 perl_exception=newSVpv("",0);
4413 sv=NULL;
4414 attribute=NULL;
4415 av=NULL;
4416 if (sv_isobject(ST(0)) == 0)
4417 {
4418 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4419 PackageName);
4420 goto PerlException;
4421 }
4422 reference=SvRV(ST(0));
4423 hv=SvSTASH(reference);
4424 av=newAV();
4425 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4426 SvREFCNT_dec(av);
4427 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4428 if (image == (Image *) NULL)
4429 {
4430 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4431 PackageName);
4432 goto PerlException;
4433 }
4434 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4435 /*
4436 Get options.
4437 */
4438 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004439 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004440 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004441 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004442 else
4443 for (i=2; i < items; i+=2)
4444 {
4445 attribute=(char *) SvPV(ST(i-1),na);
4446 switch (*attribute)
4447 {
4448 case 'C':
4449 case 'c':
4450 {
4451 if (LocaleCompare(attribute,"channel") == 0)
4452 {
4453 ssize_t
4454 option;
4455
4456 option=ParseChannelOption(SvPV(ST(i),na));
4457 if (option < 0)
4458 {
4459 ThrowPerlException(exception,OptionError,
4460 "UnrecognizedType",SvPV(ST(i),na));
4461 return;
4462 }
4463 channel=(ChannelType) option;
4464 break;
4465 }
4466 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4467 attribute);
4468 break;
4469 }
4470 case 'E':
4471 case 'e':
4472 {
4473 if (LocaleCompare(attribute,"expression") == 0)
4474 {
4475 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004476 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004477 break;
4478 }
4479 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4480 attribute);
4481 break;
4482 }
4483 default:
4484 {
4485 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4486 attribute);
4487 break;
4488 }
4489 }
4490 }
4491 channel_mask=SetImageChannelMask(image,channel);
4492 image=FxImage(image,expression,exception);
4493 if (image != (Image *) NULL)
4494 (void) SetImageChannelMask(image,channel_mask);
4495 if (image == (Image *) NULL)
4496 goto PerlException;
4497 for ( ; image; image=image->next)
4498 {
4499 AddImageToRegistry(sv,image);
4500 rv=newRV(sv);
4501 av_push(av,sv_bless(rv,hv));
4502 SvREFCNT_dec(sv);
4503 }
4504 exception=DestroyExceptionInfo(exception);
4505 ST(0)=av_reference;
4506 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4507 XSRETURN(1);
4508
4509 PerlException:
4510 InheritPerlException(exception,perl_exception);
4511 exception=DestroyExceptionInfo(exception);
4512 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4513 SvPOK_on(perl_exception);
4514 ST(0)=sv_2mortal(perl_exception);
4515 XSRETURN(1);
4516 }
4517
4518#
4519###############################################################################
4520# #
4521# #
4522# #
4523# G e t #
4524# #
4525# #
4526# #
4527###############################################################################
4528#
4529#
4530void
4531Get(ref,...)
4532 Image::Magick ref=NO_INIT
4533 ALIAS:
4534 GetAttributes = 1
4535 GetAttribute = 2
4536 get = 3
4537 getattributes = 4
4538 getattribute = 5
4539 PPCODE:
4540 {
4541 char
4542 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004543 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004544
4545 const char
4546 *value;
4547
4548 ExceptionInfo
4549 *exception;
4550
4551 Image
4552 *image;
4553
4554 long
4555 j;
4556
4557 register ssize_t
4558 i;
4559
4560 struct PackageInfo
4561 *info;
4562
4563 SV
4564 *perl_exception,
4565 *reference,
4566 *s;
4567
4568 PERL_UNUSED_VAR(ref);
4569 PERL_UNUSED_VAR(ix);
4570 exception=AcquireExceptionInfo();
4571 perl_exception=newSVpv("",0);
4572 if (sv_isobject(ST(0)) == 0)
4573 {
4574 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4575 PackageName);
4576 XSRETURN_EMPTY;
4577 }
4578 reference=SvRV(ST(0));
4579 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4580 if (image == (Image *) NULL && !info)
4581 XSRETURN_EMPTY;
4582 EXTEND(sp,items);
4583 for (i=1; i < items; i++)
4584 {
4585 attribute=(char *) SvPV(ST(i),na);
4586 s=NULL;
4587 switch (*attribute)
4588 {
4589 case 'A':
4590 case 'a':
4591 {
4592 if (LocaleCompare(attribute,"adjoin") == 0)
4593 {
4594 if (info)
4595 s=newSViv((ssize_t) info->image_info->adjoin);
4596 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4597 continue;
4598 }
4599 if (LocaleCompare(attribute,"antialias") == 0)
4600 {
4601 if (info)
4602 s=newSViv((ssize_t) info->image_info->antialias);
4603 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4604 continue;
4605 }
4606 if (LocaleCompare(attribute,"area") == 0)
4607 {
4608 s=newSViv(GetMagickResource(AreaResource));
4609 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4610 continue;
4611 }
4612 if (LocaleCompare(attribute,"attenuate") == 0)
4613 {
4614 const char
4615 *value;
4616
4617 value=GetImageProperty(image,attribute,exception);
4618 if (value != (const char *) NULL)
4619 s=newSVpv(value,0);
4620 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4621 continue;
4622 }
4623 if (LocaleCompare(attribute,"authenticate") == 0)
4624 {
4625 if (info)
4626 {
4627 const char
4628 *option;
4629
4630 option=GetImageOption(info->image_info,attribute);
4631 if (option != (const char *) NULL)
4632 s=newSVpv(option,0);
4633 }
4634 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4635 continue;
4636 }
4637 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4638 attribute);
4639 break;
4640 }
4641 case 'B':
4642 case 'b':
4643 {
4644 if (LocaleCompare(attribute,"background") == 0)
4645 {
4646 if (image == (Image *) NULL)
4647 break;
cristy151b66d2015-04-15 10:50:31 +00004648 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004649 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4650 (double) image->background_color.green,
4651 (double) image->background_color.blue,
4652 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004653 s=newSVpv(color,0);
4654 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4655 continue;
4656 }
4657 if (LocaleCompare(attribute,"base-columns") == 0)
4658 {
4659 if (image != (Image *) NULL)
4660 s=newSViv((ssize_t) image->magick_columns);
4661 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4662 continue;
4663 }
4664 if (LocaleCompare(attribute,"base-filename") == 0)
4665 {
4666 if (image != (Image *) NULL)
4667 s=newSVpv(image->magick_filename,0);
4668 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4669 continue;
4670 }
4671 if (LocaleCompare(attribute,"base-height") == 0)
4672 {
4673 if (image != (Image *) NULL)
4674 s=newSViv((ssize_t) image->magick_rows);
4675 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4676 continue;
4677 }
4678 if (LocaleCompare(attribute,"base-rows") == 0)
4679 {
4680 if (image != (Image *) NULL)
4681 s=newSViv((ssize_t) image->magick_rows);
4682 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4683 continue;
4684 }
4685 if (LocaleCompare(attribute,"base-width") == 0)
4686 {
4687 if (image != (Image *) NULL)
4688 s=newSViv((ssize_t) image->magick_columns);
4689 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4690 continue;
4691 }
4692 if (LocaleCompare(attribute,"blue-primary") == 0)
4693 {
4694 if (image == (Image *) NULL)
4695 break;
cristy151b66d2015-04-15 10:50:31 +00004696 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00004697 image->chromaticity.blue_primary.x,
4698 image->chromaticity.blue_primary.y);
4699 s=newSVpv(color,0);
4700 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4701 continue;
4702 }
4703 if (LocaleCompare(attribute,"bordercolor") == 0)
4704 {
4705 if (image == (Image *) NULL)
4706 break;
cristy151b66d2015-04-15 10:50:31 +00004707 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004708 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4709 (double) image->border_color.green,
4710 (double) image->border_color.blue,
4711 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004712 s=newSVpv(color,0);
4713 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4714 continue;
4715 }
4716 if (LocaleCompare(attribute,"bounding-box") == 0)
4717 {
4718 char
cristy151b66d2015-04-15 10:50:31 +00004719 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004720
4721 RectangleInfo
4722 page;
4723
4724 if (image == (Image *) NULL)
4725 break;
4726 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004727 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004728 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4729 page.height,(double) page.x,(double) page.y);
4730 s=newSVpv(geometry,0);
4731 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4732 continue;
4733 }
4734 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4735 attribute);
4736 break;
4737 }
4738 case 'C':
4739 case 'c':
4740 {
4741 if (LocaleCompare(attribute,"class") == 0)
4742 {
4743 if (image == (Image *) NULL)
4744 break;
4745 s=newSViv(image->storage_class);
4746 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4747 image->storage_class));
4748 SvIOK_on(s);
4749 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4750 continue;
4751 }
4752 if (LocaleCompare(attribute,"clip-mask") == 0)
4753 {
4754 if (image != (Image *) NULL)
4755 {
4756 Image
4757 *mask_image;
4758
4759 SV
4760 *sv;
4761
4762 sv=NULL;
4763 if (image->read_mask == MagickFalse)
4764 ClipImage(image,exception);
4765 mask_image=GetImageMask(image,exception);
4766 if (mask_image != (Image *) NULL)
4767 {
4768 AddImageToRegistry(sv,mask_image);
4769 s=sv_bless(newRV(sv),SvSTASH(reference));
4770 }
4771 }
4772 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4773 continue;
4774 }
4775 if (LocaleCompare(attribute,"clip-path") == 0)
4776 {
4777 if (image != (Image *) NULL)
4778 {
4779 Image
4780 *mask_image;
4781
4782 SV
4783 *sv;
4784
4785 sv=NULL;
4786 if (image->read_mask != MagickFalse)
4787 ClipImage(image,exception);
4788 mask_image=GetImageMask(image,exception);
4789 if (mask_image != (Image *) NULL)
4790 {
4791 AddImageToRegistry(sv,mask_image);
4792 s=sv_bless(newRV(sv),SvSTASH(reference));
4793 }
4794 }
4795 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4796 continue;
4797 }
4798 if (LocaleCompare(attribute,"compression") == 0)
4799 {
4800 j=info ? info->image_info->compression : image ?
4801 image->compression : UndefinedCompression;
4802 if (info)
4803 if (info->image_info->compression == UndefinedCompression)
4804 j=image->compression;
4805 s=newSViv(j);
4806 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4807 j));
4808 SvIOK_on(s);
4809 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4810 continue;
4811 }
4812 if (LocaleCompare(attribute,"colorspace") == 0)
4813 {
4814 j=image ? image->colorspace : RGBColorspace;
4815 s=newSViv(j);
4816 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4817 j));
4818 SvIOK_on(s);
4819 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4820 continue;
4821 }
4822 if (LocaleCompare(attribute,"colors") == 0)
4823 {
4824 if (image != (Image *) NULL)
4825 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4826 exception));
4827 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4828 continue;
4829 }
4830 if (LocaleNCompare(attribute,"colormap",8) == 0)
4831 {
4832 int
4833 items;
4834
4835 if (image == (Image *) NULL || !image->colormap)
4836 break;
4837 j=0;
4838 items=sscanf(attribute,"%*[^[][%ld",&j);
4839 (void) items;
4840 if (j > (ssize_t) image->colors)
4841 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004842 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004843 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4844 (double) image->colormap[j].green,
4845 (double) image->colormap[j].blue,
4846 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004847 s=newSVpv(color,0);
4848 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4849 continue;
4850 }
4851 if (LocaleCompare(attribute,"columns") == 0)
4852 {
4853 if (image != (Image *) NULL)
4854 s=newSViv((ssize_t) image->columns);
4855 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4856 continue;
4857 }
4858 if (LocaleCompare(attribute,"comment") == 0)
4859 {
4860 const char
4861 *value;
4862
4863 value=GetImageProperty(image,attribute,exception);
4864 if (value != (const char *) NULL)
4865 s=newSVpv(value,0);
4866 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4867 continue;
4868 }
4869 if (LocaleCompare(attribute,"copyright") == 0)
4870 {
4871 s=newSVpv(GetMagickCopyright(),0);
4872 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4873 continue;
4874 }
4875 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4876 attribute);
4877 break;
4878 }
4879 case 'D':
4880 case 'd':
4881 {
4882 if (LocaleCompare(attribute,"density") == 0)
4883 {
4884 char
cristy151b66d2015-04-15 10:50:31 +00004885 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004886
4887 if (image == (Image *) NULL)
4888 break;
cristy151b66d2015-04-15 10:50:31 +00004889 (void) FormatLocaleString(geometry,MagickPathExtent,"%.15gx%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00004890 image->resolution.x,image->resolution.y);
4891 s=newSVpv(geometry,0);
4892 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4893 continue;
4894 }
4895 if (LocaleCompare(attribute,"delay") == 0)
4896 {
4897 if (image != (Image *) NULL)
4898 s=newSViv((ssize_t) image->delay);
4899 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4900 continue;
4901 }
4902 if (LocaleCompare(attribute,"depth") == 0)
4903 {
4904 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4905 if (image != (Image *) NULL)
4906 s=newSViv((ssize_t) GetImageDepth(image,exception));
4907 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4908 continue;
4909 }
4910 if (LocaleCompare(attribute,"directory") == 0)
4911 {
4912 if (image && image->directory)
4913 s=newSVpv(image->directory,0);
4914 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4915 continue;
4916 }
4917 if (LocaleCompare(attribute,"dispose") == 0)
4918 {
4919 if (image == (Image *) NULL)
4920 break;
4921
4922 s=newSViv(image->dispose);
4923 (void) sv_setpv(s,
4924 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
4925 SvIOK_on(s);
4926 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4927 continue;
4928 }
4929 if (LocaleCompare(attribute,"disk") == 0)
4930 {
4931 s=newSViv(GetMagickResource(DiskResource));
4932 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4933 continue;
4934 }
4935 if (LocaleCompare(attribute,"dither") == 0)
4936 {
4937 if (info)
4938 s=newSViv((ssize_t) info->image_info->dither);
4939 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4940 continue;
4941 }
4942 if (LocaleCompare(attribute,"display") == 0) /* same as server */
4943 {
4944 if (info && info->image_info->server_name)
4945 s=newSVpv(info->image_info->server_name,0);
4946 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4947 continue;
4948 }
4949 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4950 attribute);
4951 break;
4952 }
4953 case 'E':
4954 case 'e':
4955 {
4956 if (LocaleCompare(attribute,"elapsed-time") == 0)
4957 {
4958 if (image != (Image *) NULL)
4959 s=newSVnv(GetElapsedTime(&image->timer));
4960 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4961 continue;
4962 }
4963 if (LocaleCompare(attribute,"endian") == 0)
4964 {
4965 j=info ? info->image_info->endian : image ? image->endian :
4966 UndefinedEndian;
4967 s=newSViv(j);
4968 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
4969 SvIOK_on(s);
4970 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4971 continue;
4972 }
4973 if (LocaleCompare(attribute,"error") == 0)
4974 {
4975 if (image != (Image *) NULL)
4976 s=newSVnv(image->error.mean_error_per_pixel);
4977 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4978 continue;
4979 }
4980 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4981 attribute);
4982 break;
4983 }
4984 case 'F':
4985 case 'f':
4986 {
4987 if (LocaleCompare(attribute,"filesize") == 0)
4988 {
4989 if (image != (Image *) NULL)
4990 s=newSViv((ssize_t) GetBlobSize(image));
4991 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4992 continue;
4993 }
4994 if (LocaleCompare(attribute,"filename") == 0)
4995 {
4996 if (info && info->image_info->filename &&
4997 *info->image_info->filename)
4998 s=newSVpv(info->image_info->filename,0);
4999 if (image != (Image *) NULL)
5000 s=newSVpv(image->filename,0);
5001 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5002 continue;
5003 }
5004 if (LocaleCompare(attribute,"filter") == 0)
5005 {
5006 s=image ? newSViv(image->filter) : newSViv(0);
5007 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5008 image->filter));
5009 SvIOK_on(s);
5010 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5011 continue;
5012 }
5013 if (LocaleCompare(attribute,"font") == 0)
5014 {
5015 if (info && info->image_info->font)
5016 s=newSVpv(info->image_info->font,0);
5017 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5018 continue;
5019 }
5020 if (LocaleCompare(attribute,"foreground") == 0)
5021 continue;
5022 if (LocaleCompare(attribute,"format") == 0)
5023 {
5024 const MagickInfo
5025 *magick_info;
5026
5027 magick_info=(const MagickInfo *) NULL;
5028 if (info && (*info->image_info->magick != '\0'))
5029 magick_info=GetMagickInfo(info->image_info->magick,exception);
5030 if (image != (Image *) NULL)
5031 magick_info=GetMagickInfo(image->magick,exception);
5032 if ((magick_info != (const MagickInfo *) NULL) &&
5033 (*magick_info->description != '\0'))
5034 s=newSVpv((char *) magick_info->description,0);
5035 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5036 continue;
5037 }
5038 if (LocaleCompare(attribute,"fuzz") == 0)
5039 {
5040 if (info)
5041 s=newSVnv(info->image_info->fuzz);
5042 if (image != (Image *) NULL)
5043 s=newSVnv(image->fuzz);
5044 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5045 continue;
5046 }
5047 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5048 attribute);
5049 break;
5050 }
5051 case 'G':
5052 case 'g':
5053 {
5054 if (LocaleCompare(attribute,"gamma") == 0)
5055 {
5056 if (image != (Image *) NULL)
5057 s=newSVnv(image->gamma);
5058 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5059 continue;
5060 }
5061 if (LocaleCompare(attribute,"geometry") == 0)
5062 {
5063 if (image && image->geometry)
5064 s=newSVpv(image->geometry,0);
5065 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5066 continue;
5067 }
5068 if (LocaleCompare(attribute,"gravity") == 0)
5069 {
5070 s=image ? newSViv(image->gravity) : newSViv(0);
5071 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5072 image->gravity));
5073 SvIOK_on(s);
5074 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5075 continue;
5076 }
5077 if (LocaleCompare(attribute,"green-primary") == 0)
5078 {
5079 if (image == (Image *) NULL)
5080 break;
cristy151b66d2015-04-15 10:50:31 +00005081 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005082 image->chromaticity.green_primary.x,
5083 image->chromaticity.green_primary.y);
5084 s=newSVpv(color,0);
5085 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5086 continue;
5087 }
5088 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5089 attribute);
5090 break;
5091 }
5092 case 'H':
5093 case 'h':
5094 {
5095 if (LocaleCompare(attribute,"height") == 0)
5096 {
5097 if (image != (Image *) NULL)
5098 s=newSViv((ssize_t) image->rows);
5099 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5100 continue;
5101 }
5102 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5103 attribute);
5104 break;
5105 }
5106 case 'I':
5107 case 'i':
5108 {
5109 if (LocaleCompare(attribute,"icc") == 0)
5110 {
5111 if (image != (Image *) NULL)
5112 {
5113 const StringInfo
5114 *profile;
5115
5116 profile=GetImageProfile(image,"icc");
5117 if (profile != (StringInfo *) NULL)
5118 s=newSVpv((const char *) GetStringInfoDatum(profile),
5119 GetStringInfoLength(profile));
5120 }
5121 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5122 continue;
5123 }
5124 if (LocaleCompare(attribute,"icm") == 0)
5125 {
5126 if (image != (Image *) NULL)
5127 {
5128 const StringInfo
5129 *profile;
5130
5131 profile=GetImageProfile(image,"icm");
5132 if (profile != (const StringInfo *) NULL)
5133 s=newSVpv((const char *) GetStringInfoDatum(profile),
5134 GetStringInfoLength(profile));
5135 }
5136 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5137 continue;
5138 }
5139 if (LocaleCompare(attribute,"id") == 0)
5140 {
5141 if (image != (Image *) NULL)
5142 {
5143 char
cristy151b66d2015-04-15 10:50:31 +00005144 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005145
5146 MagickBooleanType
5147 status;
5148
5149 static ssize_t
5150 id = 0;
5151
cristy151b66d2015-04-15 10:50:31 +00005152 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005153 id);
5154 status=SetImageRegistry(ImageRegistryType,key,image,
5155 exception);
5156 (void) status;
5157 s=newSViv(id++);
5158 }
5159 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5160 continue;
5161 }
5162 if (LocaleNCompare(attribute,"index",5) == 0)
5163 {
5164 char
cristy151b66d2015-04-15 10:50:31 +00005165 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005166
5167 int
5168 items;
5169
5170 long
5171 x,
5172 y;
5173
5174 register const Quantum
5175 *p;
5176
5177 CacheView
5178 *image_view;
5179
5180 if (image == (Image *) NULL)
5181 break;
5182 if (image->storage_class != PseudoClass)
5183 break;
5184 x=0;
5185 y=0;
5186 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5187 (void) items;
5188 image_view=AcquireVirtualCacheView(image,exception);
5189 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5190 if (p != (const Quantum *) NULL)
5191 {
cristy151b66d2015-04-15 10:50:31 +00005192 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005193 GetPixelIndex(image,p));
5194 s=newSVpv(name,0);
5195 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5196 }
5197 image_view=DestroyCacheView(image_view);
5198 continue;
5199 }
5200 if (LocaleCompare(attribute,"iptc") == 0)
5201 {
5202 if (image != (Image *) NULL)
5203 {
5204 const StringInfo
5205 *profile;
5206
5207 profile=GetImageProfile(image,"iptc");
5208 if (profile != (const StringInfo *) NULL)
5209 s=newSVpv((const char *) GetStringInfoDatum(profile),
5210 GetStringInfoLength(profile));
5211 }
5212 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5213 continue;
5214 }
5215 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5216 {
5217 if (image != (Image *) NULL)
5218 s=newSViv((ssize_t) image->iterations);
5219 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5220 continue;
5221 }
5222 if (LocaleCompare(attribute,"interlace") == 0)
5223 {
5224 j=info ? info->image_info->interlace : image ? image->interlace :
5225 UndefinedInterlace;
5226 s=newSViv(j);
5227 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5228 j));
5229 SvIOK_on(s);
5230 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5231 continue;
5232 }
5233 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5234 attribute);
5235 break;
5236 }
5237 case 'L':
5238 case 'l':
5239 {
5240 if (LocaleCompare(attribute,"label") == 0)
5241 {
5242 const char
5243 *value;
5244
5245 if (image == (Image *) NULL)
5246 break;
5247 value=GetImageProperty(image,"Label",exception);
5248 if (value != (const char *) NULL)
5249 s=newSVpv(value,0);
5250 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5251 continue;
5252 }
5253 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5254 {
5255 if (image != (Image *) NULL)
5256 s=newSViv((ssize_t) image->iterations);
5257 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5258 continue;
5259 }
5260 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5261 attribute);
5262 break;
5263 }
5264 case 'M':
5265 case 'm':
5266 {
5267 if (LocaleCompare(attribute,"magick") == 0)
5268 {
5269 if (info && *info->image_info->magick)
5270 s=newSVpv(info->image_info->magick,0);
5271 if (image != (Image *) NULL)
5272 s=newSVpv(image->magick,0);
5273 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5274 continue;
5275 }
5276 if (LocaleCompare(attribute,"map") == 0)
5277 {
5278 s=newSViv(GetMagickResource(MapResource));
5279 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5280 continue;
5281 }
5282 if (LocaleCompare(attribute,"maximum-error") == 0)
5283 {
5284 if (image != (Image *) NULL)
5285 s=newSVnv(image->error.normalized_maximum_error);
5286 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5287 continue;
5288 }
5289 if (LocaleCompare(attribute,"memory") == 0)
5290 {
5291 s=newSViv(GetMagickResource(MemoryResource));
5292 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5293 continue;
5294 }
5295 if (LocaleCompare(attribute,"mean-error") == 0)
5296 {
5297 if (image != (Image *) NULL)
5298 s=newSVnv(image->error.normalized_mean_error);
5299 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5300 continue;
5301 }
5302 if (LocaleCompare(attribute,"mime") == 0)
5303 {
5304 if (info && *info->image_info->magick)
5305 s=newSVpv(MagickToMime(info->image_info->magick),0);
5306 if (image != (Image *) NULL)
5307 s=newSVpv(MagickToMime(image->magick),0);
5308 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5309 continue;
5310 }
5311 if (LocaleCompare(attribute,"mattecolor") == 0)
5312 {
5313 if (image == (Image *) NULL)
5314 break;
cristy151b66d2015-04-15 10:50:31 +00005315 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005316 "%.20g,%.20g,%.20g,%.20g",(double) image->matte_color.red,
5317 (double) image->matte_color.green,
5318 (double) image->matte_color.blue,
5319 (double) image->matte_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005320 s=newSVpv(color,0);
5321 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5322 continue;
5323 }
5324 if (LocaleCompare(attribute,"matte") == 0)
5325 {
5326 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005327 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005328 1 : 0);
5329 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5330 continue;
5331 }
5332 if (LocaleCompare(attribute,"mime") == 0)
5333 {
5334 const char
5335 *magick;
5336
5337 magick=NULL;
5338 if (info && *info->image_info->magick)
5339 magick=info->image_info->magick;
5340 if (image != (Image *) NULL)
5341 magick=image->magick;
5342 if (magick)
5343 {
5344 char
5345 *mime;
5346
5347 mime=MagickToMime(magick);
5348 s=newSVpv(mime,0);
5349 mime=(char *) RelinquishMagickMemory(mime);
5350 }
5351 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5352 continue;
5353 }
5354 if (LocaleCompare(attribute,"monochrome") == 0)
5355 {
5356 if (image == (Image *) NULL)
5357 continue;
5358 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005359 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005360 s=newSViv(j);
5361 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5362 continue;
5363 }
5364 if (LocaleCompare(attribute,"montage") == 0)
5365 {
5366 if (image && image->montage)
5367 s=newSVpv(image->montage,0);
5368 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5369 continue;
5370 }
5371 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5372 attribute);
5373 break;
5374 }
5375 case 'O':
5376 case 'o':
5377 {
5378 if (LocaleCompare(attribute,"orientation") == 0)
5379 {
5380 j=info ? info->image_info->orientation : image ?
5381 image->orientation : UndefinedOrientation;
5382 s=newSViv(j);
5383 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5384 j));
5385 SvIOK_on(s);
5386 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5387 continue;
5388 }
5389 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5390 attribute);
5391 break;
5392 }
5393 case 'P':
5394 case 'p':
5395 {
5396 if (LocaleCompare(attribute,"page") == 0)
5397 {
5398 if (info && info->image_info->page)
5399 s=newSVpv(info->image_info->page,0);
5400 if (image != (Image *) NULL)
5401 {
5402 char
cristy151b66d2015-04-15 10:50:31 +00005403 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005404
cristy151b66d2015-04-15 10:50:31 +00005405 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005406 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5407 (double) image->page.height,(double) image->page.x,(double)
5408 image->page.y);
5409 s=newSVpv(geometry,0);
5410 }
5411 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5412 continue;
5413 }
5414 if (LocaleCompare(attribute,"page.x") == 0)
5415 {
5416 if (image != (Image *) NULL)
5417 s=newSViv((ssize_t) image->page.x);
5418 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5419 continue;
5420 }
5421 if (LocaleCompare(attribute,"page.y") == 0)
5422 {
5423 if (image != (Image *) NULL)
5424 s=newSViv((ssize_t) image->page.y);
5425 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5426 continue;
5427 }
5428 if (LocaleNCompare(attribute,"pixel",5) == 0)
5429 {
5430 char
cristy151b66d2015-04-15 10:50:31 +00005431 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005432
5433 int
5434 items;
5435
5436 long
5437 x,
5438 y;
5439
5440 register const Quantum
5441 *p;
5442
5443 if (image == (Image *) NULL)
5444 break;
5445 x=0;
5446 y=0;
5447 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5448 (void) items;
5449 p=GetVirtualPixels(image,x,y,1,1,exception);
5450 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005451 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005452 QuantumFormat "," QuantumFormat "," QuantumFormat,
5453 GetPixelRed(image,p),GetPixelGreen(image,p),
5454 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5455 else
cristy151b66d2015-04-15 10:50:31 +00005456 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005457 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5458 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5459 GetPixelBlue(image,p),GetPixelBlack(image,p),
5460 GetPixelAlpha(image,p));
5461 s=newSVpv(tuple,0);
5462 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5463 continue;
5464 }
5465 if (LocaleCompare(attribute,"pointsize") == 0)
5466 {
5467 if (info)
5468 s=newSViv((ssize_t) info->image_info->pointsize);
5469 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5470 continue;
5471 }
5472 if (LocaleCompare(attribute,"preview") == 0)
5473 {
5474 s=newSViv(info->image_info->preview_type);
5475 (void) sv_setpv(s,CommandOptionToMnemonic(MagickPreviewOptions,
5476 info->image_info->preview_type));
5477 SvIOK_on(s);
5478 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5479 continue;
5480 }
5481 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5482 attribute);
5483 break;
5484 }
5485 case 'Q':
5486 case 'q':
5487 {
5488 if (LocaleCompare(attribute,"quality") == 0)
5489 {
5490 if (info)
5491 s=newSViv((ssize_t) info->image_info->quality);
5492 if (image != (Image *) NULL)
5493 s=newSViv((ssize_t) image->quality);
5494 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5495 continue;
5496 }
5497 if (LocaleCompare(attribute,"quantum") == 0)
5498 {
5499 if (info)
5500 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5501 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5502 continue;
5503 }
5504 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5505 attribute);
5506 break;
5507 }
5508 case 'R':
5509 case 'r':
5510 {
5511 if (LocaleCompare(attribute,"rendering-intent") == 0)
5512 {
5513 s=newSViv(image->rendering_intent);
5514 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5515 image->rendering_intent));
5516 SvIOK_on(s);
5517 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5518 continue;
5519 }
5520 if (LocaleCompare(attribute,"red-primary") == 0)
5521 {
5522 if (image == (Image *) NULL)
5523 break;
cristy151b66d2015-04-15 10:50:31 +00005524 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005525 image->chromaticity.red_primary.x,
5526 image->chromaticity.red_primary.y);
5527 s=newSVpv(color,0);
5528 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5529 continue;
5530 }
5531 if (LocaleCompare(attribute,"rows") == 0)
5532 {
5533 if (image != (Image *) NULL)
5534 s=newSViv((ssize_t) image->rows);
5535 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5536 continue;
5537 }
5538 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5539 attribute);
5540 break;
5541 }
5542 case 'S':
5543 case 's':
5544 {
5545 if (LocaleCompare(attribute,"sampling-factor") == 0)
5546 {
5547 if (info && info->image_info->sampling_factor)
5548 s=newSVpv(info->image_info->sampling_factor,0);
5549 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5550 continue;
5551 }
5552 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5553 {
5554 if (info && info->image_info->server_name)
5555 s=newSVpv(info->image_info->server_name,0);
5556 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5557 continue;
5558 }
5559 if (LocaleCompare(attribute,"size") == 0)
5560 {
5561 if (info && info->image_info->size)
5562 s=newSVpv(info->image_info->size,0);
5563 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5564 continue;
5565 }
5566 if (LocaleCompare(attribute,"scene") == 0)
5567 {
5568 if (image != (Image *) NULL)
5569 s=newSViv((ssize_t) image->scene);
5570 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5571 continue;
5572 }
5573 if (LocaleCompare(attribute,"scenes") == 0)
5574 {
5575 if (image != (Image *) NULL)
5576 s=newSViv((ssize_t) info->image_info->number_scenes);
5577 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5578 continue;
5579 }
5580 if (LocaleCompare(attribute,"signature") == 0)
5581 {
5582 const char
5583 *value;
5584
5585 if (image == (Image *) NULL)
5586 break;
5587 (void) SignatureImage(image,exception);
5588 value=GetImageProperty(image,"Signature",exception);
5589 if (value != (const char *) NULL)
5590 s=newSVpv(value,0);
5591 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5592 continue;
5593 }
5594 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5595 attribute);
5596 break;
5597 }
5598 case 'T':
5599 case 't':
5600 {
5601 if (LocaleCompare(attribute,"taint") == 0)
5602 {
5603 if (image != (Image *) NULL)
5604 s=newSViv((ssize_t) IsTaintImage(image));
5605 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5606 continue;
5607 }
5608 if (LocaleCompare(attribute,"texture") == 0)
5609 {
5610 if (info && info->image_info->texture)
5611 s=newSVpv(info->image_info->texture,0);
5612 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5613 continue;
5614 }
5615 if (LocaleCompare(attribute,"total-ink-density") == 0)
5616 {
5617 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5618 if (image != (Image *) NULL)
5619 s=newSVnv(GetImageTotalInkDensity(image,exception));
5620 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5621 continue;
5622 }
5623 if (LocaleCompare(attribute,"transparent-color") == 0)
5624 {
5625 if (image == (Image *) NULL)
5626 break;
cristy151b66d2015-04-15 10:50:31 +00005627 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005628 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5629 (double) image->transparent_color.green,
5630 (double) image->transparent_color.blue,
5631 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005632 s=newSVpv(color,0);
5633 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5634 continue;
5635 }
5636 if (LocaleCompare(attribute,"type") == 0)
5637 {
5638 if (image == (Image *) NULL)
5639 break;
5640 j=(ssize_t) GetImageType(image,exception);
5641 s=newSViv(j);
5642 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5643 SvIOK_on(s);
5644 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5645 continue;
5646 }
5647 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5648 attribute);
5649 break;
5650 }
5651 case 'U':
5652 case 'u':
5653 {
5654 if (LocaleCompare(attribute,"units") == 0)
5655 {
5656 j=info ? info->image_info->units : image ? image->units :
5657 UndefinedResolution;
5658 if (info && (info->image_info->units == UndefinedResolution))
5659 if (image)
5660 j=image->units;
5661 if (j == UndefinedResolution)
5662 s=newSVpv("undefined units",0);
5663 else
5664 if (j == PixelsPerInchResolution)
5665 s=newSVpv("pixels / inch",0);
5666 else
5667 s=newSVpv("pixels / centimeter",0);
5668 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5669 continue;
5670 }
5671 if (LocaleCompare(attribute,"user-time") == 0)
5672 {
5673 if (image != (Image *) NULL)
5674 s=newSVnv(GetUserTime(&image->timer));
5675 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5676 continue;
5677 }
5678 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5679 attribute);
5680 break;
5681 }
5682 case 'V':
5683 case 'v':
5684 {
5685 if (LocaleCompare(attribute,"verbose") == 0)
5686 {
5687 if (info)
5688 s=newSViv((ssize_t) info->image_info->verbose);
5689 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5690 continue;
5691 }
5692 if (LocaleCompare(attribute,"version") == 0)
5693 {
5694 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5695 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5696 continue;
5697 }
5698 if (LocaleCompare(attribute,"view") == 0)
5699 {
5700 if (info && info->image_info->view)
5701 s=newSVpv(info->image_info->view,0);
5702 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5703 continue;
5704 }
5705 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5706 {
5707 if (image == (Image *) NULL)
5708 break;
5709 j=(ssize_t) GetImageVirtualPixelMethod(image);
5710 s=newSViv(j);
5711 (void) sv_setpv(s,CommandOptionToMnemonic(
5712 MagickVirtualPixelOptions,j));
5713 SvIOK_on(s);
5714 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5715 continue;
5716 }
5717 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5718 attribute);
5719 break;
5720 }
5721 case 'W':
5722 case 'w':
5723 {
5724 if (LocaleCompare(attribute,"white-point") == 0)
5725 {
5726 if (image == (Image *) NULL)
5727 break;
cristy151b66d2015-04-15 10:50:31 +00005728 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00005729 image->chromaticity.white_point.x,
5730 image->chromaticity.white_point.y);
5731 s=newSVpv(color,0);
5732 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5733 continue;
5734 }
5735 if (LocaleCompare(attribute,"width") == 0)
5736 {
5737 if (image != (Image *) NULL)
5738 s=newSViv((ssize_t) image->columns);
5739 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5740 continue;
5741 }
5742 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5743 attribute);
5744 break;
5745 }
5746 case 'X':
5747 case 'x':
5748 {
5749 if (LocaleCompare(attribute,"x-resolution") == 0)
5750 {
5751 if (image != (Image *) NULL)
5752 s=newSVnv(image->resolution.x);
5753 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5754 continue;
5755 }
5756 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5757 attribute);
5758 break;
5759 }
5760 case 'Y':
5761 case 'y':
5762 {
5763 if (LocaleCompare(attribute,"y-resolution") == 0)
5764 {
5765 if (image != (Image *) NULL)
5766 s=newSVnv(image->resolution.y);
5767 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5768 continue;
5769 }
5770 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5771 attribute);
5772 break;
5773 }
5774 default:
5775 break;
5776 }
5777 if (image == (Image *) NULL)
5778 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5779 attribute)
5780 else
5781 {
5782 value=GetImageProperty(image,attribute,exception);
5783 if (value != (const char *) NULL)
5784 {
5785 s=newSVpv(value,0);
5786 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5787 }
5788 else
5789 if (*attribute != '%')
5790 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5791 attribute)
5792 else
5793 {
5794 char
5795 *meta;
5796
5797 meta=InterpretImageProperties(info ? info->image_info :
5798 (ImageInfo *) NULL,image,attribute,exception);
5799 s=newSVpv(meta,0);
5800 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5801 meta=(char *) RelinquishMagickMemory(meta);
5802 }
5803 }
5804 }
5805 exception=DestroyExceptionInfo(exception);
5806 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5807 }
5808
5809#
5810###############################################################################
5811# #
5812# #
5813# #
5814# G e t A u t h e n t i c P i x e l s #
5815# #
5816# #
5817# #
5818###############################################################################
5819#
5820#
5821void *
5822GetAuthenticPixels(ref,...)
5823 Image::Magick ref = NO_INIT
5824 ALIAS:
5825 getauthenticpixels = 1
5826 GetImagePixels = 2
5827 getimagepixels = 3
5828 CODE:
5829 {
5830 char
5831 *attribute;
5832
5833 ExceptionInfo
5834 *exception;
5835
5836 Image
5837 *image;
5838
5839 RectangleInfo
5840 region;
5841
5842 ssize_t
5843 i;
5844
5845 struct PackageInfo
5846 *info;
5847
5848 SV
5849 *perl_exception,
5850 *reference;
5851
5852 void
5853 *blob = NULL;
5854
5855 PERL_UNUSED_VAR(ref);
5856 PERL_UNUSED_VAR(ix);
5857 exception=AcquireExceptionInfo();
5858 perl_exception=newSVpv("",0);
5859 if (sv_isobject(ST(0)) == 0)
5860 {
5861 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5862 PackageName);
5863 goto PerlException;
5864 }
5865 reference=SvRV(ST(0));
5866
5867 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5868 if (image == (Image *) NULL)
5869 {
5870 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5871 PackageName);
5872 goto PerlException;
5873 }
5874
5875 region.x=0;
5876 region.y=0;
5877 region.width=image->columns;
5878 region.height=1;
5879 if (items == 1)
5880 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5881 for (i=2; i < items; i+=2)
5882 {
5883 attribute=(char *) SvPV(ST(i-1),na);
5884 switch (*attribute)
5885 {
5886 case 'g':
5887 case 'G':
5888 {
5889 if (LocaleCompare(attribute,"geometry") == 0)
5890 {
5891 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5892 break;
5893 }
5894 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5895 attribute);
5896 break;
5897 }
5898 case 'H':
5899 case 'h':
5900 {
5901 if (LocaleCompare(attribute,"height") == 0)
5902 {
5903 region.height=SvIV(ST(i));
5904 continue;
5905 }
5906 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5907 attribute);
5908 break;
5909 }
5910 case 'X':
5911 case 'x':
5912 {
5913 if (LocaleCompare(attribute,"x") == 0)
5914 {
5915 region.x=SvIV(ST(i));
5916 continue;
5917 }
5918 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5919 attribute);
5920 break;
5921 }
5922 case 'Y':
5923 case 'y':
5924 {
5925 if (LocaleCompare(attribute,"y") == 0)
5926 {
5927 region.y=SvIV(ST(i));
5928 continue;
5929 }
5930 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5931 attribute);
5932 break;
5933 }
5934 case 'W':
5935 case 'w':
5936 {
5937 if (LocaleCompare(attribute,"width") == 0)
5938 {
5939 region.width=SvIV(ST(i));
5940 continue;
5941 }
5942 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5943 attribute);
5944 break;
5945 }
5946 }
5947 }
5948 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5949 region.height,exception);
5950 if (blob != (void *) NULL)
5951 goto PerlEnd;
5952
5953 PerlException:
5954 InheritPerlException(exception,perl_exception);
5955 exception=DestroyExceptionInfo(exception);
5956 SvREFCNT_dec(perl_exception); /* throw away all errors */
5957
5958 PerlEnd:
5959 RETVAL = blob;
5960 }
5961 OUTPUT:
5962 RETVAL
5963
5964#
5965###############################################################################
5966# #
5967# #
5968# #
5969# G e t V i r t u a l P i x e l s #
5970# #
5971# #
5972# #
5973###############################################################################
5974#
5975#
5976void *
5977GetVirtualPixels(ref,...)
5978 Image::Magick ref = NO_INIT
5979 ALIAS:
5980 getvirtualpixels = 1
5981 AcquireImagePixels = 2
5982 acquireimagepixels = 3
5983 CODE:
5984 {
5985 char
5986 *attribute;
5987
5988 const void
5989 *blob = NULL;
5990
5991 ExceptionInfo
5992 *exception;
5993
5994 Image
5995 *image;
5996
5997 RectangleInfo
5998 region;
5999
6000 ssize_t
6001 i;
6002
6003 struct PackageInfo
6004 *info;
6005
6006 SV
6007 *perl_exception,
6008 *reference;
6009
6010 PERL_UNUSED_VAR(ref);
6011 PERL_UNUSED_VAR(ix);
6012 exception=AcquireExceptionInfo();
6013 perl_exception=newSVpv("",0);
6014 if (sv_isobject(ST(0)) == 0)
6015 {
6016 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6017 PackageName);
6018 goto PerlException;
6019 }
6020 reference=SvRV(ST(0));
6021
6022 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6023 if (image == (Image *) NULL)
6024 {
6025 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6026 PackageName);
6027 goto PerlException;
6028 }
6029
6030 region.x=0;
6031 region.y=0;
6032 region.width=image->columns;
6033 region.height=1;
6034 if (items == 1)
6035 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6036 for (i=2; i < items; i+=2)
6037 {
6038 attribute=(char *) SvPV(ST(i-1),na);
6039 switch (*attribute)
6040 {
6041 case 'g':
6042 case 'G':
6043 {
6044 if (LocaleCompare(attribute,"geometry") == 0)
6045 {
6046 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6047 break;
6048 }
6049 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6050 attribute);
6051 break;
6052 }
6053 case 'H':
6054 case 'h':
6055 {
6056 if (LocaleCompare(attribute,"height") == 0)
6057 {
6058 region.height=SvIV(ST(i));
6059 continue;
6060 }
6061 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6062 attribute);
6063 break;
6064 }
6065 case 'X':
6066 case 'x':
6067 {
6068 if (LocaleCompare(attribute,"x") == 0)
6069 {
6070 region.x=SvIV(ST(i));
6071 continue;
6072 }
6073 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6074 attribute);
6075 break;
6076 }
6077 case 'Y':
6078 case 'y':
6079 {
6080 if (LocaleCompare(attribute,"y") == 0)
6081 {
6082 region.y=SvIV(ST(i));
6083 continue;
6084 }
6085 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6086 attribute);
6087 break;
6088 }
6089 case 'W':
6090 case 'w':
6091 {
6092 if (LocaleCompare(attribute,"width") == 0)
6093 {
6094 region.width=SvIV(ST(i));
6095 continue;
6096 }
6097 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6098 attribute);
6099 break;
6100 }
6101 }
6102 }
6103 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6104 region.height,exception);
6105 if (blob != (void *) NULL)
6106 goto PerlEnd;
6107
6108 PerlException:
6109 InheritPerlException(exception,perl_exception);
6110 exception=DestroyExceptionInfo(exception);
6111 SvREFCNT_dec(perl_exception); /* throw away all errors */
6112
6113 PerlEnd:
6114 RETVAL = (void *) blob;
6115 }
6116 OUTPUT:
6117 RETVAL
6118
6119#
6120###############################################################################
6121# #
6122# #
6123# #
6124# G e t A u t h e n t i c M e t a c o n t e n t #
6125# #
6126# #
6127# #
6128###############################################################################
6129#
6130#
6131void *
6132GetAuthenticMetacontent(ref,...)
6133 Image::Magick ref = NO_INIT
6134 ALIAS:
6135 getauthenticmetacontent = 1
6136 GetMetacontent = 2
6137 getmetacontent = 3
6138 CODE:
6139 {
6140 ExceptionInfo
6141 *exception;
6142
6143 Image
6144 *image;
6145
6146 struct PackageInfo
6147 *info;
6148
6149 SV
6150 *perl_exception,
6151 *reference;
6152
6153 void
6154 *blob = NULL;
6155
6156 PERL_UNUSED_VAR(ref);
6157 PERL_UNUSED_VAR(ix);
6158 exception=AcquireExceptionInfo();
6159 perl_exception=newSVpv("",0);
6160 if (sv_isobject(ST(0)) == 0)
6161 {
6162 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6163 PackageName);
6164 goto PerlException;
6165 }
6166 reference=SvRV(ST(0));
6167
6168 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6169 if (image == (Image *) NULL)
6170 {
6171 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6172 PackageName);
6173 goto PerlException;
6174 }
6175
6176 blob=(void *) GetAuthenticMetacontent(image);
6177 if (blob != (void *) NULL)
6178 goto PerlEnd;
6179
6180 PerlException:
6181 InheritPerlException(exception,perl_exception);
6182 exception=DestroyExceptionInfo(exception);
6183 SvREFCNT_dec(perl_exception); /* throw away all errors */
6184
6185 PerlEnd:
6186 RETVAL = blob;
6187 }
6188 OUTPUT:
6189 RETVAL
6190
6191#
6192###############################################################################
6193# #
6194# #
6195# #
6196# G e t V i r t u a l M e t a c o n t e n t #
6197# #
6198# #
6199# #
6200###############################################################################
6201#
6202#
6203void *
6204GetVirtualMetacontent(ref,...)
6205 Image::Magick ref = NO_INIT
6206 ALIAS:
6207 getvirtualmetacontent = 1
6208 CODE:
6209 {
6210 ExceptionInfo
6211 *exception;
6212
6213 Image
6214 *image;
6215
6216 struct PackageInfo
6217 *info;
6218
6219 SV
6220 *perl_exception,
6221 *reference;
6222
6223 void
6224 *blob = NULL;
6225
6226 PERL_UNUSED_VAR(ref);
6227 PERL_UNUSED_VAR(ix);
6228 exception=AcquireExceptionInfo();
6229 perl_exception=newSVpv("",0);
6230 if (sv_isobject(ST(0)) == 0)
6231 {
6232 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6233 PackageName);
6234 goto PerlException;
6235 }
6236 reference=SvRV(ST(0));
6237
6238 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6239 if (image == (Image *) NULL)
6240 {
6241 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6242 PackageName);
6243 goto PerlException;
6244 }
6245
6246 blob=(void *) GetVirtualMetacontent(image);
6247 if (blob != (void *) NULL)
6248 goto PerlEnd;
6249
6250 PerlException:
6251 InheritPerlException(exception,perl_exception);
6252 exception=DestroyExceptionInfo(exception);
6253 SvREFCNT_dec(perl_exception); /* throw away all errors */
6254
6255 PerlEnd:
6256 RETVAL = blob;
6257 }
6258 OUTPUT:
6259 RETVAL
6260
6261#
6262###############################################################################
6263# #
6264# #
6265# #
6266# H i s t o g r a m #
6267# #
6268# #
6269# #
6270###############################################################################
6271#
6272#
6273void
6274Histogram(ref,...)
6275 Image::Magick ref=NO_INIT
6276 ALIAS:
6277 HistogramImage = 1
6278 histogram = 2
6279 histogramimage = 3
6280 PPCODE:
6281 {
6282 AV
6283 *av;
6284
6285 char
cristy151b66d2015-04-15 10:50:31 +00006286 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006287
6288 PixelInfo
6289 *histogram;
6290
6291 ExceptionInfo
6292 *exception;
6293
6294 Image
6295 *image;
6296
6297 register ssize_t
6298 i;
6299
6300 ssize_t
6301 count;
6302
6303 struct PackageInfo
6304 *info;
6305
6306 SV
6307 *perl_exception,
6308 *reference;
6309
6310 size_t
6311 number_colors;
6312
6313 PERL_UNUSED_VAR(ref);
6314 PERL_UNUSED_VAR(ix);
6315 exception=AcquireExceptionInfo();
6316 perl_exception=newSVpv("",0);
6317 av=NULL;
6318 if (sv_isobject(ST(0)) == 0)
6319 {
6320 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6321 PackageName);
6322 goto PerlException;
6323 }
6324 reference=SvRV(ST(0));
6325 av=newAV();
6326 SvREFCNT_dec(av);
6327 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6328 if (image == (Image *) NULL)
6329 {
6330 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6331 PackageName);
6332 goto PerlException;
6333 }
cristy4a3ce0a2013-08-03 20:06:59 +00006334 count=0;
6335 for ( ; image; image=image->next)
6336 {
6337 histogram=GetImageHistogram(image,&number_colors,exception);
6338 if (histogram == (PixelInfo *) NULL)
6339 continue;
6340 count+=(ssize_t) number_colors;
6341 EXTEND(sp,6*count);
6342 for (i=0; i < (ssize_t) number_colors; i++)
6343 {
cristy151b66d2015-04-15 10:50:31 +00006344 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006345 histogram[i].red);
6346 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006347 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006348 histogram[i].green);
6349 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006350 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006351 histogram[i].blue);
6352 PUSHs(sv_2mortal(newSVpv(message,0)));
6353 if (image->colorspace == CMYKColorspace)
6354 {
cristy151b66d2015-04-15 10:50:31 +00006355 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006356 histogram[i].black);
6357 PUSHs(sv_2mortal(newSVpv(message,0)));
6358 }
cristy151b66d2015-04-15 10:50:31 +00006359 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006360 histogram[i].alpha);
6361 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006362 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006363 histogram[i].count);
6364 PUSHs(sv_2mortal(newSVpv(message,0)));
6365 }
6366 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6367 }
6368
6369 PerlException:
6370 InheritPerlException(exception,perl_exception);
6371 exception=DestroyExceptionInfo(exception);
6372 SvREFCNT_dec(perl_exception);
6373 }
6374
6375#
6376###############################################################################
6377# #
6378# #
6379# #
6380# G e t P i x e l #
6381# #
6382# #
6383# #
6384###############################################################################
6385#
6386#
6387void
6388GetPixel(ref,...)
6389 Image::Magick ref=NO_INIT
6390 ALIAS:
6391 getpixel = 1
6392 getPixel = 2
6393 PPCODE:
6394 {
6395 AV
6396 *av;
6397
6398 char
6399 *attribute;
6400
6401 ExceptionInfo
6402 *exception;
6403
6404 Image
6405 *image;
6406
6407 MagickBooleanType
6408 normalize;
6409
6410 RectangleInfo
6411 region;
6412
6413 register const Quantum
6414 *p;
6415
6416 register ssize_t
6417 i;
6418
6419 ssize_t
6420 option;
6421
6422 struct PackageInfo
6423 *info;
6424
6425 SV
6426 *perl_exception,
6427 *reference; /* reference is the SV* of ref=SvIV(reference) */
6428
6429 PERL_UNUSED_VAR(ref);
6430 PERL_UNUSED_VAR(ix);
6431 exception=AcquireExceptionInfo();
6432 perl_exception=newSVpv("",0);
6433 reference=SvRV(ST(0));
6434 av=(AV *) reference;
6435 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6436 exception);
6437 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6438 if (image == (Image *) NULL)
6439 {
6440 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6441 PackageName);
6442 goto PerlException;
6443 }
6444 normalize=MagickTrue;
6445 region.x=0;
6446 region.y=0;
6447 region.width=image->columns;
6448 region.height=1;
6449 if (items == 1)
6450 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6451 for (i=2; i < items; i+=2)
6452 {
6453 attribute=(char *) SvPV(ST(i-1),na);
6454 switch (*attribute)
6455 {
6456 case 'C':
6457 case 'c':
6458 {
6459 if (LocaleCompare(attribute,"channel") == 0)
6460 {
6461 ssize_t
6462 option;
6463
6464 option=ParseChannelOption(SvPV(ST(i),na));
6465 if (option < 0)
6466 {
6467 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6468 SvPV(ST(i),na));
6469 return;
6470 }
6471 SetPixelChannelMask(image,(ChannelType) option);
6472 break;
6473 }
6474 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6475 attribute);
6476 break;
6477 }
6478 case 'g':
6479 case 'G':
6480 {
6481 if (LocaleCompare(attribute,"geometry") == 0)
6482 {
6483 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6484 break;
6485 }
6486 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6487 attribute);
6488 break;
6489 }
6490 case 'N':
6491 case 'n':
6492 {
6493 if (LocaleCompare(attribute,"normalize") == 0)
6494 {
6495 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6496 SvPV(ST(i),na));
6497 if (option < 0)
6498 {
6499 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6500 SvPV(ST(i),na));
6501 break;
6502 }
6503 normalize=option != 0 ? MagickTrue : MagickFalse;
6504 break;
6505 }
6506 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6507 attribute);
6508 break;
6509 }
6510 case 'x':
6511 case 'X':
6512 {
6513 if (LocaleCompare(attribute,"x") == 0)
6514 {
6515 region.x=SvIV(ST(i));
6516 break;
6517 }
6518 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6519 attribute);
6520 break;
6521 }
6522 case 'y':
6523 case 'Y':
6524 {
6525 if (LocaleCompare(attribute,"y") == 0)
6526 {
6527 region.y=SvIV(ST(i));
6528 break;
6529 }
6530 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6531 attribute);
6532 break;
6533 }
6534 default:
6535 {
6536 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6537 attribute);
6538 break;
6539 }
6540 }
6541 }
6542 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6543 if (p == (const Quantum *) NULL)
6544 PUSHs(&sv_undef);
6545 else
6546 {
6547 double
6548 scale;
6549
6550 scale=1.0;
6551 if (normalize != MagickFalse)
6552 scale=1.0/QuantumRange;
6553 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6554 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6555 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6556 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6557 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6558 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6559 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6560 (image->colorspace == CMYKColorspace))
6561 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6562 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6563 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6564 }
6565
6566 PerlException:
6567 InheritPerlException(exception,perl_exception);
6568 exception=DestroyExceptionInfo(exception);
6569 SvREFCNT_dec(perl_exception);
6570 }
6571
6572#
6573###############################################################################
6574# #
6575# #
6576# #
6577# G e t P i x e l s #
6578# #
6579# #
6580# #
6581###############################################################################
6582#
6583#
6584void
6585GetPixels(ref,...)
6586 Image::Magick ref=NO_INIT
6587 ALIAS:
6588 getpixels = 1
6589 getPixels = 2
6590 PPCODE:
6591 {
6592 AV
6593 *av;
6594
6595 char
6596 *attribute;
6597
6598 const char
6599 *map;
6600
6601 ExceptionInfo
6602 *exception;
6603
6604 Image
6605 *image;
6606
6607 MagickBooleanType
6608 normalize,
6609 status;
6610
6611 RectangleInfo
6612 region;
6613
6614 register ssize_t
6615 i;
6616
6617 ssize_t
6618 option;
6619
6620 struct PackageInfo
6621 *info;
6622
6623 SV
6624 *perl_exception,
6625 *reference; /* reference is the SV* of ref=SvIV(reference) */
6626
6627 PERL_UNUSED_VAR(ref);
6628 PERL_UNUSED_VAR(ix);
6629 exception=AcquireExceptionInfo();
6630 perl_exception=newSVpv("",0);
6631 reference=SvRV(ST(0));
6632 av=(AV *) reference;
6633 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6634 exception);
6635 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6636 if (image == (Image *) NULL)
6637 {
6638 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6639 PackageName);
6640 goto PerlException;
6641 }
6642 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006643 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006644 map="RGBA";
6645 if (image->colorspace == CMYKColorspace)
6646 {
6647 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006648 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006649 map="CMYKA";
6650 }
6651 normalize=MagickFalse;
6652 region.x=0;
6653 region.y=0;
6654 region.width=image->columns;
6655 region.height=1;
6656 if (items == 1)
6657 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6658 for (i=2; i < items; i+=2)
6659 {
6660 attribute=(char *) SvPV(ST(i-1),na);
6661 switch (*attribute)
6662 {
6663 case 'g':
6664 case 'G':
6665 {
6666 if (LocaleCompare(attribute,"geometry") == 0)
6667 {
6668 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6669 break;
6670 }
6671 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6672 attribute);
6673 break;
6674 }
6675 case 'H':
6676 case 'h':
6677 {
6678 if (LocaleCompare(attribute,"height") == 0)
6679 {
6680 region.height=SvIV(ST(i));
6681 break;
6682 }
6683 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6684 attribute);
6685 break;
6686 }
6687 case 'M':
6688 case 'm':
6689 {
6690 if (LocaleCompare(attribute,"map") == 0)
6691 {
6692 map=SvPV(ST(i),na);
6693 break;
6694 }
6695 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6696 attribute);
6697 break;
6698 }
6699 case 'N':
6700 case 'n':
6701 {
6702 if (LocaleCompare(attribute,"normalize") == 0)
6703 {
6704 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6705 SvPV(ST(i),na));
6706 if (option < 0)
6707 {
6708 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6709 SvPV(ST(i),na));
6710 break;
6711 }
6712 normalize=option != 0 ? MagickTrue : MagickFalse;
6713 break;
6714 }
6715 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6716 attribute);
6717 break;
6718 }
6719 case 'W':
6720 case 'w':
6721 {
6722 if (LocaleCompare(attribute,"width") == 0)
6723 {
6724 region.width=SvIV(ST(i));
6725 break;
6726 }
6727 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6728 attribute);
6729 break;
6730 }
6731 case 'x':
6732 case 'X':
6733 {
6734 if (LocaleCompare(attribute,"x") == 0)
6735 {
6736 region.x=SvIV(ST(i));
6737 break;
6738 }
6739 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6740 attribute);
6741 break;
6742 }
6743 case 'y':
6744 case 'Y':
6745 {
6746 if (LocaleCompare(attribute,"y") == 0)
6747 {
6748 region.y=SvIV(ST(i));
6749 break;
6750 }
6751 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6752 attribute);
6753 break;
6754 }
6755 default:
6756 {
6757 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6758 attribute);
6759 break;
6760 }
6761 }
6762 }
6763 if (normalize != MagickFalse)
6764 {
6765 float
6766 *pixels;
6767
6768 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6769 region.height*sizeof(*pixels));
6770 if (pixels == (float *) NULL)
6771 {
6772 ThrowPerlException(exception,ResourceLimitError,
6773 "MemoryAllocationFailed",PackageName);
6774 goto PerlException;
6775 }
6776 status=ExportImagePixels(image,region.x,region.y,region.width,
6777 region.height,map,FloatPixel,pixels,exception);
6778 if (status == MagickFalse)
6779 PUSHs(&sv_undef);
6780 else
6781 {
6782 EXTEND(sp,strlen(map)*region.width*region.height);
6783 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6784 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6785 }
6786 pixels=(float *) RelinquishMagickMemory(pixels);
6787 }
6788 else
6789 {
6790 Quantum
6791 *pixels;
6792
6793 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6794 region.height*sizeof(*pixels));
6795 if (pixels == (Quantum *) NULL)
6796 {
6797 ThrowPerlException(exception,ResourceLimitError,
6798 "MemoryAllocationFailed",PackageName);
6799 goto PerlException;
6800 }
6801 status=ExportImagePixels(image,region.x,region.y,region.width,
6802 region.height,map,QuantumPixel,pixels,exception);
6803 if (status == MagickFalse)
6804 PUSHs(&sv_undef);
6805 else
6806 {
6807 EXTEND(sp,strlen(map)*region.width*region.height);
6808 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6809 PUSHs(sv_2mortal(newSViv(pixels[i])));
6810 }
6811 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6812 }
6813
6814 PerlException:
6815 InheritPerlException(exception,perl_exception);
6816 exception=DestroyExceptionInfo(exception);
6817 SvREFCNT_dec(perl_exception);
6818 }
6819
6820#
6821###############################################################################
6822# #
6823# #
6824# #
6825# I m a g e T o B l o b #
6826# #
6827# #
6828# #
6829###############################################################################
6830#
6831#
6832void
6833ImageToBlob(ref,...)
6834 Image::Magick ref=NO_INIT
6835 ALIAS:
6836 ImageToBlob = 1
6837 imagetoblob = 2
6838 toblob = 3
6839 blob = 4
6840 PPCODE:
6841 {
6842 char
cristy151b66d2015-04-15 10:50:31 +00006843 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006844
6845 ExceptionInfo
6846 *exception;
6847
6848 Image
6849 *image,
6850 *next;
6851
6852 register ssize_t
6853 i;
6854
6855 struct PackageInfo
6856 *info,
6857 *package_info;
6858
6859 size_t
6860 length;
6861
6862 ssize_t
6863 scene;
6864
6865 SV
6866 *perl_exception,
6867 *reference;
6868
6869 void
6870 *blob;
6871
6872 PERL_UNUSED_VAR(ref);
6873 PERL_UNUSED_VAR(ix);
6874 exception=AcquireExceptionInfo();
6875 perl_exception=newSVpv("",0);
6876 package_info=(struct PackageInfo *) NULL;
6877 if (sv_isobject(ST(0)) == 0)
6878 {
6879 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6880 PackageName);
6881 goto PerlException;
6882 }
6883 reference=SvRV(ST(0));
6884 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6885 if (image == (Image *) NULL)
6886 {
6887 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6888 PackageName);
6889 goto PerlException;
6890 }
6891 package_info=ClonePackageInfo(info,exception);
6892 for (i=2; i < items; i+=2)
6893 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6894 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006895 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006896 scene=0;
6897 for (next=image; next; next=next->next)
6898 {
cristy151b66d2015-04-15 10:50:31 +00006899 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006900 next->scene=scene++;
6901 }
6902 SetImageInfo(package_info->image_info,(unsigned int)
6903 GetImageListLength(image),exception);
6904 EXTEND(sp,(ssize_t) GetImageListLength(image));
6905 for ( ; image; image=image->next)
6906 {
6907 length=0;
6908 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6909 if (blob != (char *) NULL)
6910 {
6911 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6912 blob=(unsigned char *) RelinquishMagickMemory(blob);
6913 }
6914 if (package_info->image_info->adjoin)
6915 break;
6916 }
6917
6918 PerlException:
6919 if (package_info != (struct PackageInfo *) NULL)
6920 DestroyPackageInfo(package_info);
6921 InheritPerlException(exception,perl_exception);
6922 exception=DestroyExceptionInfo(exception);
6923 SvREFCNT_dec(perl_exception); /* throw away all errors */
6924 }
6925
6926#
6927###############################################################################
6928# #
6929# #
6930# #
6931# L a y e r s #
6932# #
6933# #
6934# #
6935###############################################################################
6936#
6937#
6938void
6939Layers(ref,...)
6940 Image::Magick ref=NO_INIT
6941 ALIAS:
6942 Layers = 1
6943 layers = 2
6944 OptimizeImageLayers = 3
6945 optimizelayers = 4
6946 optimizeimagelayers = 5
6947 PPCODE:
6948 {
6949 AV
6950 *av;
6951
6952 char
6953 *attribute;
6954
6955 CompositeOperator
6956 compose;
6957
6958 ExceptionInfo
6959 *exception;
6960
6961 HV
6962 *hv;
6963
6964 Image
6965 *image,
6966 *layers;
6967
6968 LayerMethod
6969 method;
6970
6971 register ssize_t
6972 i;
6973
6974 ssize_t
6975 option,
6976 sp;
6977
6978 struct PackageInfo
6979 *info;
6980
6981 SV
6982 *av_reference,
6983 *perl_exception,
6984 *reference,
6985 *rv,
6986 *sv;
6987
6988 PERL_UNUSED_VAR(ref);
6989 PERL_UNUSED_VAR(ix);
6990 exception=AcquireExceptionInfo();
6991 perl_exception=newSVpv("",0);
6992 sv=NULL;
6993 if (sv_isobject(ST(0)) == 0)
6994 {
6995 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6996 PackageName);
6997 goto PerlException;
6998 }
6999 reference=SvRV(ST(0));
7000 hv=SvSTASH(reference);
7001 av=newAV();
7002 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7003 SvREFCNT_dec(av);
7004 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7005 if (image == (Image *) NULL)
7006 {
7007 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7008 PackageName);
7009 goto PerlException;
7010 }
7011 compose=image->compose;
7012 method=OptimizeLayer;
7013 for (i=2; i < items; i+=2)
7014 {
7015 attribute=(char *) SvPV(ST(i-1),na);
7016 switch (*attribute)
7017 {
7018 case 'C':
7019 case 'c':
7020 {
7021 if (LocaleCompare(attribute,"compose") == 0)
7022 {
7023 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7024 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7025 if (sp < 0)
7026 {
7027 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7028 SvPV(ST(i),na));
7029 break;
7030 }
7031 compose=(CompositeOperator) sp;
7032 break;
7033 }
7034 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7035 attribute);
7036 break;
7037 }
7038 case 'M':
7039 case 'm':
7040 {
7041 if (LocaleCompare(attribute,"method") == 0)
7042 {
7043 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7044 SvPV(ST(i),na));
7045 if (option < 0)
7046 {
7047 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7048 SvPV(ST(i),na));
7049 break;
7050 }
7051 method=(LayerMethod) option;
7052 break;
7053 }
7054 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7055 attribute);
7056 break;
7057 }
7058 default:
7059 {
7060 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7061 attribute);
7062 break;
7063 }
7064 }
7065 }
7066 layers=(Image *) NULL;
7067 switch (method)
7068 {
7069 case CompareAnyLayer:
7070 case CompareClearLayer:
7071 case CompareOverlayLayer:
7072 default:
7073 {
7074 layers=CompareImagesLayers(image,method,exception);
7075 break;
7076 }
7077 case MergeLayer:
7078 case FlattenLayer:
7079 case MosaicLayer:
7080 {
7081 layers=MergeImageLayers(image,method,exception);
7082 break;
7083 }
7084 case DisposeLayer:
7085 {
7086 layers=DisposeImages(image,exception);
7087 break;
7088 }
7089 case OptimizeImageLayer:
7090 {
7091 layers=OptimizeImageLayers(image,exception);
7092 break;
7093 }
7094 case OptimizePlusLayer:
7095 {
7096 layers=OptimizePlusImageLayers(image,exception);
7097 break;
7098 }
7099 case OptimizeTransLayer:
7100 {
7101 OptimizeImageTransparency(image,exception);
7102 break;
7103 }
7104 case RemoveDupsLayer:
7105 {
7106 RemoveDuplicateLayers(&image,exception);
7107 break;
7108 }
7109 case RemoveZeroLayer:
7110 {
7111 RemoveZeroDelayLayers(&image,exception);
7112 break;
7113 }
7114 case OptimizeLayer:
7115 {
7116 QuantizeInfo
7117 *quantize_info;
7118
7119 /*
7120 General Purpose, GIF Animation Optimizer.
7121 */
7122 layers=CoalesceImages(image,exception);
7123 if (layers == (Image *) NULL)
7124 break;
7125 image=layers;
7126 layers=OptimizeImageLayers(image,exception);
7127 if (layers == (Image *) NULL)
7128 break;
7129 image=DestroyImageList(image);
7130 image=layers;
7131 layers=(Image *) NULL;
7132 OptimizeImageTransparency(image,exception);
7133 quantize_info=AcquireQuantizeInfo(info->image_info);
7134 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7135 quantize_info=DestroyQuantizeInfo(quantize_info);
7136 break;
7137 }
7138 case CompositeLayer:
7139 {
7140 Image
7141 *source;
7142
7143 RectangleInfo
7144 geometry;
7145
7146 /*
7147 Split image sequence at the first 'NULL:' image.
7148 */
7149 source=image;
7150 while (source != (Image *) NULL)
7151 {
7152 source=GetNextImageInList(source);
7153 if ((source != (Image *) NULL) &&
7154 (LocaleCompare(source->magick,"NULL") == 0))
7155 break;
7156 }
7157 if (source != (Image *) NULL)
7158 {
7159 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7160 (GetNextImageInList(source) == (Image *) NULL))
7161 source=(Image *) NULL;
7162 else
7163 {
7164 /*
7165 Separate the two lists, junk the null: image.
7166 */
7167 source=SplitImageList(source->previous);
7168 DeleteImageFromList(&source);
7169 }
7170 }
7171 if (source == (Image *) NULL)
7172 {
7173 (void) ThrowMagickException(exception,GetMagickModule(),
7174 OptionError,"MissingNullSeparator","layers Composite");
7175 break;
7176 }
7177 /*
7178 Adjust offset with gravity and virtual canvas.
7179 */
7180 SetGeometry(image,&geometry);
7181 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7182 geometry.width=source->page.width != 0 ? source->page.width :
7183 source->columns;
7184 geometry.height=source->page.height != 0 ? source->page.height :
7185 source->rows;
7186 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7187 image->columns,image->page.height != 0 ? image->page.height :
7188 image->rows,image->gravity,&geometry);
7189 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7190 source=DestroyImageList(source);
7191 break;
7192 }
7193 }
7194 if (layers != (Image *) NULL)
7195 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007196 else
7197 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007198 if (image == (Image *) NULL)
7199 goto PerlException;
7200 for ( ; image; image=image->next)
7201 {
7202 AddImageToRegistry(sv,image);
7203 rv=newRV(sv);
7204 av_push(av,sv_bless(rv,hv));
7205 SvREFCNT_dec(sv);
7206 }
7207 exception=DestroyExceptionInfo(exception);
7208 ST(0)=av_reference;
7209 SvREFCNT_dec(perl_exception);
7210 XSRETURN(1);
7211
7212 PerlException:
7213 InheritPerlException(exception,perl_exception);
7214 exception=DestroyExceptionInfo(exception);
7215 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7216 SvPOK_on(perl_exception);
7217 ST(0)=sv_2mortal(perl_exception);
7218 XSRETURN(1);
7219 }
7220
7221#
7222###############################################################################
7223# #
7224# #
7225# #
7226# M a g i c k T o M i m e #
7227# #
7228# #
7229# #
7230###############################################################################
7231#
7232#
7233SV *
7234MagickToMime(ref,name)
7235 Image::Magick ref=NO_INIT
7236 char *name
7237 ALIAS:
7238 magicktomime = 1
7239 CODE:
7240 {
7241 char
7242 *mime;
7243
7244 PERL_UNUSED_VAR(ref);
7245 PERL_UNUSED_VAR(ix);
7246 mime=MagickToMime(name);
7247 RETVAL=newSVpv(mime,0);
7248 mime=(char *) RelinquishMagickMemory(mime);
7249 }
7250 OUTPUT:
7251 RETVAL
7252
7253#
7254###############################################################################
7255# #
7256# #
7257# #
7258# M o g r i f y #
7259# #
7260# #
7261# #
7262###############################################################################
7263#
7264#
7265void
7266Mogrify(ref,...)
7267 Image::Magick ref=NO_INIT
7268 ALIAS:
7269 Comment = 1
7270 CommentImage = 2
7271 Label = 3
7272 LabelImage = 4
7273 AddNoise = 5
7274 AddNoiseImage = 6
7275 Colorize = 7
7276 ColorizeImage = 8
7277 Border = 9
7278 BorderImage = 10
7279 Blur = 11
7280 BlurImage = 12
7281 Chop = 13
7282 ChopImage = 14
7283 Crop = 15
7284 CropImage = 16
7285 Despeckle = 17
7286 DespeckleImage = 18
7287 Edge = 19
7288 EdgeImage = 20
7289 Emboss = 21
7290 EmbossImage = 22
7291 Enhance = 23
7292 EnhanceImage = 24
7293 Flip = 25
7294 FlipImage = 26
7295 Flop = 27
7296 FlopImage = 28
7297 Frame = 29
7298 FrameImage = 30
7299 Implode = 31
7300 ImplodeImage = 32
7301 Magnify = 33
7302 MagnifyImage = 34
7303 MedianFilter = 35
7304 MedianConvolveImage = 36
7305 Minify = 37
7306 MinifyImage = 38
7307 OilPaint = 39
7308 OilPaintImage = 40
7309 ReduceNoise = 41
7310 ReduceNoiseImage = 42
7311 Roll = 43
7312 RollImage = 44
7313 Rotate = 45
7314 RotateImage = 46
7315 Sample = 47
7316 SampleImage = 48
7317 Scale = 49
7318 ScaleImage = 50
7319 Shade = 51
7320 ShadeImage = 52
7321 Sharpen = 53
7322 SharpenImage = 54
7323 Shear = 55
7324 ShearImage = 56
7325 Spread = 57
7326 SpreadImage = 58
7327 Swirl = 59
7328 SwirlImage = 60
7329 Resize = 61
7330 ResizeImage = 62
7331 Zoom = 63
7332 ZoomImage = 64
7333 Annotate = 65
7334 AnnotateImage = 66
7335 ColorFloodfill = 67
7336 ColorFloodfillImage= 68
7337 Composite = 69
7338 CompositeImage = 70
7339 Contrast = 71
7340 ContrastImage = 72
7341 CycleColormap = 73
7342 CycleColormapImage = 74
7343 Draw = 75
7344 DrawImage = 76
7345 Equalize = 77
7346 EqualizeImage = 78
7347 Gamma = 79
7348 GammaImage = 80
7349 Map = 81
7350 MapImage = 82
7351 MatteFloodfill = 83
7352 MatteFloodfillImage= 84
7353 Modulate = 85
7354 ModulateImage = 86
7355 Negate = 87
7356 NegateImage = 88
7357 Normalize = 89
7358 NormalizeImage = 90
7359 NumberColors = 91
7360 NumberColorsImage = 92
7361 Opaque = 93
7362 OpaqueImage = 94
7363 Quantize = 95
7364 QuantizeImage = 96
7365 Raise = 97
7366 RaiseImage = 98
7367 Segment = 99
7368 SegmentImage = 100
7369 Signature = 101
7370 SignatureImage = 102
7371 Solarize = 103
7372 SolarizeImage = 104
7373 Sync = 105
7374 SyncImage = 106
7375 Texture = 107
7376 TextureImage = 108
7377 Evaluate = 109
7378 EvaluateImage = 110
7379 Transparent = 111
7380 TransparentImage = 112
7381 Threshold = 113
7382 ThresholdImage = 114
7383 Charcoal = 115
7384 CharcoalImage = 116
7385 Trim = 117
7386 TrimImage = 118
7387 Wave = 119
7388 WaveImage = 120
7389 Separate = 121
7390 SeparateImage = 122
7391 Stereo = 125
7392 StereoImage = 126
7393 Stegano = 127
7394 SteganoImage = 128
7395 Deconstruct = 129
7396 DeconstructImage = 130
7397 GaussianBlur = 131
7398 GaussianBlurImage = 132
7399 Convolve = 133
7400 ConvolveImage = 134
7401 Profile = 135
7402 ProfileImage = 136
7403 UnsharpMask = 137
7404 UnsharpMaskImage = 138
7405 MotionBlur = 139
7406 MotionBlurImage = 140
7407 OrderedDither = 141
7408 OrderedDitherImage = 142
7409 Shave = 143
7410 ShaveImage = 144
7411 Level = 145
7412 LevelImage = 146
7413 Clip = 147
7414 ClipImage = 148
7415 AffineTransform = 149
7416 AffineTransformImage = 150
7417 Difference = 151
7418 DifferenceImage = 152
7419 AdaptiveThreshold = 153
7420 AdaptiveThresholdImage = 154
7421 Resample = 155
7422 ResampleImage = 156
7423 Describe = 157
7424 DescribeImage = 158
7425 BlackThreshold = 159
7426 BlackThresholdImage= 160
7427 WhiteThreshold = 161
7428 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007429 RotationalBlur = 163
7430 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007431 Thumbnail = 165
7432 ThumbnailImage = 166
7433 Strip = 167
7434 StripImage = 168
7435 Tint = 169
7436 TintImage = 170
7437 Channel = 171
7438 ChannelImage = 172
7439 Splice = 173
7440 SpliceImage = 174
7441 Posterize = 175
7442 PosterizeImage = 176
7443 Shadow = 177
7444 ShadowImage = 178
7445 Identify = 179
7446 IdentifyImage = 180
7447 SepiaTone = 181
7448 SepiaToneImage = 182
7449 SigmoidalContrast = 183
7450 SigmoidalContrastImage = 184
7451 Extent = 185
7452 ExtentImage = 186
7453 Vignette = 187
7454 VignetteImage = 188
7455 ContrastStretch = 189
7456 ContrastStretchImage = 190
7457 Sans0 = 191
7458 Sans0Image = 192
7459 Sans1 = 193
7460 Sans1Image = 194
7461 AdaptiveSharpen = 195
7462 AdaptiveSharpenImage = 196
7463 Transpose = 197
7464 TransposeImage = 198
7465 Transverse = 199
7466 TransverseImage = 200
7467 AutoOrient = 201
7468 AutoOrientImage = 202
7469 AdaptiveBlur = 203
7470 AdaptiveBlurImage = 204
7471 Sketch = 205
7472 SketchImage = 206
7473 UniqueColors = 207
7474 UniqueColorsImage = 208
7475 AdaptiveResize = 209
7476 AdaptiveResizeImage= 210
7477 ClipMask = 211
7478 ClipMaskImage = 212
7479 LinearStretch = 213
7480 LinearStretchImage = 214
7481 ColorMatrix = 215
7482 ColorMatrixImage = 216
7483 Mask = 217
7484 MaskImage = 218
7485 Polaroid = 219
7486 PolaroidImage = 220
7487 FloodfillPaint = 221
7488 FloodfillPaintImage= 222
7489 Distort = 223
7490 DistortImage = 224
7491 Clut = 225
7492 ClutImage = 226
7493 LiquidRescale = 227
7494 LiquidRescaleImage = 228
7495 Encipher = 229
7496 EncipherImage = 230
7497 Decipher = 231
7498 DecipherImage = 232
7499 Deskew = 233
7500 DeskewImage = 234
7501 Remap = 235
7502 RemapImage = 236
7503 SparseColor = 237
7504 SparseColorImage = 238
7505 Function = 239
7506 FunctionImage = 240
7507 SelectiveBlur = 241
7508 SelectiveBlurImage = 242
7509 HaldClut = 243
7510 HaldClutImage = 244
7511 BlueShift = 245
7512 BlueShiftImage = 246
7513 ForwardFourierTransform = 247
7514 ForwardFourierTransformImage = 248
7515 InverseFourierTransform = 249
7516 InverseFourierTransformImage = 250
7517 ColorDecisionList = 251
7518 ColorDecisionListImage = 252
7519 AutoGamma = 253
7520 AutoGammaImage = 254
7521 AutoLevel = 255
7522 AutoLevelImage = 256
7523 LevelColors = 257
7524 LevelImageColors = 258
7525 Clamp = 259
7526 ClampImage = 260
7527 BrightnessContrast = 261
7528 BrightnessContrastImage = 262
7529 Morphology = 263
7530 MorphologyImage = 264
7531 Color = 265
7532 ColorImage = 266
7533 Mode = 267
7534 ModeImage = 268
7535 Statistic = 269
7536 StatisticImage = 270
7537 Perceptible = 271
7538 PerceptibleImage = 272
7539 Poly = 273
7540 PolyImage = 274
7541 Grayscale = 275
7542 GrayscaleImage = 276
cristy4ceadb82014-03-29 15:30:43 +00007543 CannyEdge = 278
7544 CannyEdgeImage = 279
cristy2fc10e52014-04-26 14:13:53 +00007545 HoughLine = 280
7546 HoughLineImage = 281
7547 MeanShift = 282
7548 MeanShiftImage = 283
cristy3b207f82014-09-27 14:21:20 +00007549 Kuwahara = 284
7550 KuwaharaImage = 285
cristy6e0b3bc2014-10-19 17:51:42 +00007551 ConnectedComponent = 286
7552 ConnectedComponentImage = 287
cristy4a3ce0a2013-08-03 20:06:59 +00007553 MogrifyRegion = 666
7554 PPCODE:
7555 {
7556 AffineMatrix
7557 affine,
7558 current;
7559
7560 char
7561 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007562 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007563
7564 ChannelType
7565 channel,
7566 channel_mask;
7567
7568 CompositeOperator
7569 compose;
7570
7571 const char
7572 *attribute,
7573 *value;
7574
7575 double
7576 angle;
7577
7578 ExceptionInfo
7579 *exception;
7580
7581 GeometryInfo
7582 geometry_info;
7583
7584 Image
7585 *image,
7586 *next,
7587 *region_image;
7588
7589 MagickBooleanType
7590 status;
7591
7592 MagickStatusType
7593 flags;
7594
7595 PixelInfo
7596 fill_color;
7597
7598 RectangleInfo
7599 geometry,
7600 region_info;
7601
7602 register ssize_t
7603 i;
7604
7605 ssize_t
7606 base,
7607 j,
7608 number_images;
7609
7610 struct Methods
7611 *rp;
7612
7613 struct PackageInfo
7614 *info;
7615
7616 SV
7617 *perl_exception,
7618 **pv,
7619 *reference,
7620 **reference_vector;
7621
7622 struct ArgumentList
7623 argument_list[MaxArguments];
7624
7625 PERL_UNUSED_VAR(ref);
7626 PERL_UNUSED_VAR(ix);
7627 exception=AcquireExceptionInfo();
7628 perl_exception=newSVpv("",0);
7629 reference_vector=NULL;
7630 region_image=NULL;
7631 number_images=0;
7632 base=2;
7633 if (sv_isobject(ST(0)) == 0)
7634 {
7635 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7636 PackageName);
7637 goto PerlException;
7638 }
7639 reference=SvRV(ST(0));
7640 region_info.width=0;
7641 region_info.height=0;
7642 region_info.x=0;
7643 region_info.y=0;
7644 region_image=(Image *) NULL;
7645 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7646 if (ix && (ix != 666))
7647 {
7648 /*
7649 Called as Method(...)
7650 */
7651 ix=(ix+1)/2;
7652 rp=(&Methods[ix-1]);
7653 attribute=rp->name;
7654 }
7655 else
7656 {
7657 /*
7658 Called as Mogrify("Method",...)
7659 */
7660 attribute=(char *) SvPV(ST(1),na);
7661 if (ix)
7662 {
7663 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7664 attribute=(char *) SvPV(ST(2),na);
7665 base++;
7666 }
7667 for (rp=Methods; ; rp++)
7668 {
7669 if (rp >= EndOf(Methods))
7670 {
7671 ThrowPerlException(exception,OptionError,
7672 "UnrecognizedPerlMagickMethod",attribute);
7673 goto PerlException;
7674 }
7675 if (strEQcase(attribute,rp->name))
7676 break;
7677 }
7678 ix=rp-Methods+1;
7679 base++;
7680 }
7681 if (image == (Image *) NULL)
7682 {
7683 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7684 goto PerlException;
7685 }
7686 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7687 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7688 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7689 {
7690 Arguments
7691 *pp,
7692 *qq;
7693
7694 ssize_t
7695 ssize_test;
7696
7697 struct ArgumentList
7698 *al;
7699
7700 SV
7701 *sv;
7702
7703 sv=NULL;
7704 ssize_test=0;
7705 pp=(Arguments *) NULL;
7706 qq=rp->arguments;
7707 if (i == items)
7708 {
7709 pp=rp->arguments,
7710 sv=ST(i-1);
7711 }
7712 else
7713 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7714 {
7715 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7716 break;
7717 if (strEQcase(attribute,qq->method) > ssize_test)
7718 {
7719 pp=qq;
7720 ssize_test=strEQcase(attribute,qq->method);
7721 }
7722 }
7723 if (pp == (Arguments *) NULL)
7724 {
7725 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7726 attribute);
7727 goto continue_outer_loop;
7728 }
7729 al=(&argument_list[pp-rp->arguments]);
7730 switch (pp->type)
7731 {
7732 case ArrayReference:
7733 {
7734 if (SvTYPE(sv) != SVt_RV)
7735 {
cristy151b66d2015-04-15 10:50:31 +00007736 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007737 "invalid %.60s value",pp->method);
7738 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7739 goto continue_outer_loop;
7740 }
7741 al->array_reference=SvRV(sv);
7742 break;
7743 }
7744 case RealReference:
7745 {
7746 al->real_reference=SvNV(sv);
7747 break;
7748 }
7749 case FileReference:
7750 {
7751 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7752 break;
7753 }
7754 case ImageReference:
7755 {
7756 if (!sv_isobject(sv) ||
7757 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7758 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7759 {
7760 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7761 PackageName);
7762 goto PerlException;
7763 }
7764 break;
7765 }
7766 case IntegerReference:
7767 {
7768 al->integer_reference=SvIV(sv);
7769 break;
7770 }
7771 case StringReference:
7772 {
7773 al->string_reference=(char *) SvPV(sv,al->length);
7774 if (sv_isobject(sv))
7775 al->image_reference=SetupList(aTHX_ SvRV(sv),
7776 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7777 break;
7778 }
7779 default:
7780 {
7781 /*
7782 Is a string; look up name.
7783 */
7784 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7785 {
7786 al->string_reference=(char *) SvPV(sv,al->length);
7787 al->integer_reference=(-1);
7788 break;
7789 }
7790 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7791 MagickFalse,SvPV(sv,na));
7792 if (pp->type == MagickChannelOptions)
7793 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7794 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7795 {
cristy151b66d2015-04-15 10:50:31 +00007796 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007797 "invalid %.60s value",pp->method);
7798 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7799 goto continue_outer_loop;
7800 }
7801 break;
7802 }
7803 }
7804 attribute_flag[pp-rp->arguments]++;
7805 continue_outer_loop: ;
7806 }
7807 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7808 pv=reference_vector;
7809 SetGeometryInfo(&geometry_info);
7810 channel=DefaultChannels;
7811 for (next=image; next; next=next->next)
7812 {
7813 image=next;
7814 SetGeometry(image,&geometry);
7815 if ((region_info.width*region_info.height) != 0)
7816 {
7817 region_image=image;
7818 image=CropImage(image,&region_info,exception);
7819 }
7820 switch (ix)
7821 {
7822 default:
7823 {
cristy151b66d2015-04-15 10:50:31 +00007824 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007825 ThrowPerlException(exception,OptionError,
7826 "UnrecognizedPerlMagickMethod",message);
7827 goto PerlException;
7828 }
7829 case 1: /* Comment */
7830 {
7831 if (attribute_flag[0] == 0)
7832 argument_list[0].string_reference=(char *) NULL;
7833 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7834 info ? info->image_info : (ImageInfo *) NULL,image,
7835 argument_list[0].string_reference,exception),exception);
7836 break;
7837 }
7838 case 2: /* Label */
7839 {
7840 if (attribute_flag[0] == 0)
7841 argument_list[0].string_reference=(char *) NULL;
7842 (void) SetImageProperty(image,"label",InterpretImageProperties(
7843 info ? info->image_info : (ImageInfo *) NULL,image,
7844 argument_list[0].string_reference,exception),exception);
7845 break;
7846 }
7847 case 3: /* AddNoise */
7848 {
7849 double
7850 attenuate;
7851
7852 if (attribute_flag[0] == 0)
7853 argument_list[0].integer_reference=UniformNoise;
7854 attenuate=1.0;
7855 if (attribute_flag[1] != 0)
7856 attenuate=argument_list[1].real_reference;
7857 if (attribute_flag[2] != 0)
7858 channel=(ChannelType) argument_list[2].integer_reference;
7859 channel_mask=SetImageChannelMask(image,channel);
7860 image=AddNoiseImage(image,(NoiseType)
7861 argument_list[0].integer_reference,attenuate,exception);
7862 if (image != (Image *) NULL)
7863 (void) SetImageChannelMask(image,channel_mask);
7864 break;
7865 }
7866 case 4: /* Colorize */
7867 {
7868 PixelInfo
7869 target;
7870
7871 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7872 0,0,&target,exception);
7873 if (attribute_flag[0] != 0)
7874 (void) QueryColorCompliance(argument_list[0].string_reference,
7875 AllCompliance,&target,exception);
7876 if (attribute_flag[1] == 0)
7877 argument_list[1].string_reference="100%";
7878 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7879 exception);
7880 break;
7881 }
7882 case 5: /* Border */
7883 {
7884 CompositeOperator
7885 compose;
7886
7887 geometry.width=0;
7888 geometry.height=0;
7889 if (attribute_flag[0] != 0)
7890 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7891 &geometry,exception);
7892 if (attribute_flag[1] != 0)
7893 geometry.width=argument_list[1].integer_reference;
7894 if (attribute_flag[2] != 0)
7895 geometry.height=argument_list[2].integer_reference;
7896 if (attribute_flag[3] != 0)
7897 QueryColorCompliance(argument_list[3].string_reference,
7898 AllCompliance,&image->border_color,exception);
7899 if (attribute_flag[4] != 0)
7900 QueryColorCompliance(argument_list[4].string_reference,
7901 AllCompliance,&image->border_color,exception);
7902 if (attribute_flag[5] != 0)
7903 QueryColorCompliance(argument_list[5].string_reference,
7904 AllCompliance,&image->border_color,exception);
7905 compose=image->compose;
7906 if (attribute_flag[6] != 0)
7907 compose=(CompositeOperator) argument_list[6].integer_reference;
7908 image=BorderImage(image,&geometry,compose,exception);
7909 break;
7910 }
7911 case 6: /* Blur */
7912 {
7913 if (attribute_flag[0] != 0)
7914 {
7915 flags=ParseGeometry(argument_list[0].string_reference,
7916 &geometry_info);
7917 if ((flags & SigmaValue) == 0)
7918 geometry_info.sigma=1.0;
7919 }
7920 if (attribute_flag[1] != 0)
7921 geometry_info.rho=argument_list[1].real_reference;
7922 if (attribute_flag[2] != 0)
7923 geometry_info.sigma=argument_list[2].real_reference;
7924 if (attribute_flag[3] != 0)
7925 channel=(ChannelType) argument_list[3].integer_reference;
7926 channel_mask=SetImageChannelMask(image,channel);
7927 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
7928 exception);
7929 if (image != (Image *) NULL)
7930 (void) SetImageChannelMask(image,channel_mask);
7931 break;
7932 }
7933 case 7: /* Chop */
7934 {
cristy260bd762014-08-15 12:46:34 +00007935 if (attribute_flag[5] != 0)
7936 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00007937 if (attribute_flag[0] != 0)
7938 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7939 &geometry,exception);
7940 if (attribute_flag[1] != 0)
7941 geometry.width=argument_list[1].integer_reference;
7942 if (attribute_flag[2] != 0)
7943 geometry.height=argument_list[2].integer_reference;
7944 if (attribute_flag[3] != 0)
7945 geometry.x=argument_list[3].integer_reference;
7946 if (attribute_flag[4] != 0)
7947 geometry.y=argument_list[4].integer_reference;
7948 image=ChopImage(image,&geometry,exception);
7949 break;
7950 }
7951 case 8: /* Crop */
7952 {
7953 if (attribute_flag[6] != 0)
7954 image->gravity=(GravityType) argument_list[6].integer_reference;
7955 if (attribute_flag[0] != 0)
7956 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7957 &geometry,exception);
7958 if (attribute_flag[1] != 0)
7959 geometry.width=argument_list[1].integer_reference;
7960 if (attribute_flag[2] != 0)
7961 geometry.height=argument_list[2].integer_reference;
7962 if (attribute_flag[3] != 0)
7963 geometry.x=argument_list[3].integer_reference;
7964 if (attribute_flag[4] != 0)
7965 geometry.y=argument_list[4].integer_reference;
7966 if (attribute_flag[5] != 0)
7967 image->fuzz=StringToDoubleInterval(
7968 argument_list[5].string_reference,(double) QuantumRange+1.0);
7969 image=CropImage(image,&geometry,exception);
7970 break;
7971 }
7972 case 9: /* Despeckle */
7973 {
7974 image=DespeckleImage(image,exception);
7975 break;
7976 }
7977 case 10: /* Edge */
7978 {
7979 if (attribute_flag[0] != 0)
7980 geometry_info.rho=argument_list[0].real_reference;
7981 image=EdgeImage(image,geometry_info.rho,exception);
7982 break;
7983 }
7984 case 11: /* Emboss */
7985 {
7986 if (attribute_flag[0] != 0)
7987 {
7988 flags=ParseGeometry(argument_list[0].string_reference,
7989 &geometry_info);
7990 if ((flags & SigmaValue) == 0)
7991 geometry_info.sigma=1.0;
7992 }
7993 if (attribute_flag[1] != 0)
7994 geometry_info.rho=argument_list[1].real_reference;
7995 if (attribute_flag[2] != 0)
7996 geometry_info.sigma=argument_list[2].real_reference;
7997 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
7998 exception);
7999 break;
8000 }
8001 case 12: /* Enhance */
8002 {
8003 image=EnhanceImage(image,exception);
8004 break;
8005 }
8006 case 13: /* Flip */
8007 {
8008 image=FlipImage(image,exception);
8009 break;
8010 }
8011 case 14: /* Flop */
8012 {
8013 image=FlopImage(image,exception);
8014 break;
8015 }
8016 case 15: /* Frame */
8017 {
8018 CompositeOperator
8019 compose;
8020
8021 FrameInfo
8022 frame_info;
8023
8024 if (attribute_flag[0] != 0)
8025 {
8026 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8027 &geometry,exception);
8028 frame_info.width=geometry.width;
8029 frame_info.height=geometry.height;
8030 frame_info.outer_bevel=geometry.x;
8031 frame_info.inner_bevel=geometry.y;
8032 }
8033 if (attribute_flag[1] != 0)
8034 frame_info.width=argument_list[1].integer_reference;
8035 if (attribute_flag[2] != 0)
8036 frame_info.height=argument_list[2].integer_reference;
8037 if (attribute_flag[3] != 0)
8038 frame_info.inner_bevel=argument_list[3].integer_reference;
8039 if (attribute_flag[4] != 0)
8040 frame_info.outer_bevel=argument_list[4].integer_reference;
8041 if (attribute_flag[5] != 0)
8042 QueryColorCompliance(argument_list[5].string_reference,
8043 AllCompliance,&fill_color,exception);
8044 if (attribute_flag[6] != 0)
8045 QueryColorCompliance(argument_list[6].string_reference,
8046 AllCompliance,&fill_color,exception);
8047 frame_info.x=(ssize_t) frame_info.width;
8048 frame_info.y=(ssize_t) frame_info.height;
8049 frame_info.width=image->columns+2*frame_info.x;
8050 frame_info.height=image->rows+2*frame_info.y;
8051 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
8052 image->matte_color=fill_color;
8053 compose=image->compose;
8054 if (attribute_flag[7] != 0)
8055 compose=(CompositeOperator) argument_list[7].integer_reference;
8056 image=FrameImage(image,&frame_info,compose,exception);
8057 break;
8058 }
8059 case 16: /* Implode */
8060 {
8061 PixelInterpolateMethod
8062 method;
8063
8064 if (attribute_flag[0] == 0)
8065 argument_list[0].real_reference=0.5;
8066 method=UndefinedInterpolatePixel;
8067 if (attribute_flag[1] != 0)
8068 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8069 image=ImplodeImage(image,argument_list[0].real_reference,
8070 method,exception);
8071 break;
8072 }
8073 case 17: /* Magnify */
8074 {
8075 image=MagnifyImage(image,exception);
8076 break;
8077 }
8078 case 18: /* MedianFilter */
8079 {
8080 if (attribute_flag[0] != 0)
8081 {
8082 flags=ParseGeometry(argument_list[0].string_reference,
8083 &geometry_info);
8084 if ((flags & SigmaValue) == 0)
8085 geometry_info.sigma=geometry_info.rho;
8086 }
8087 if (attribute_flag[1] != 0)
8088 geometry_info.rho=argument_list[1].real_reference;
8089 if (attribute_flag[2] != 0)
8090 geometry_info.sigma=argument_list[2].real_reference;
8091 if (attribute_flag[3] != 0)
8092 channel=(ChannelType) argument_list[3].integer_reference;
8093 channel_mask=SetImageChannelMask(image,channel);
8094 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8095 (size_t) geometry_info.sigma,exception);
8096 if (image != (Image *) NULL)
8097 (void) SetImageChannelMask(image,channel_mask);
8098 break;
8099 }
8100 case 19: /* Minify */
8101 {
8102 image=MinifyImage(image,exception);
8103 break;
8104 }
8105 case 20: /* OilPaint */
8106 {
8107 if (attribute_flag[0] == 0)
8108 argument_list[0].real_reference=0.0;
8109 if (attribute_flag[1] == 0)
8110 argument_list[1].real_reference=1.0;
8111 image=OilPaintImage(image,argument_list[0].real_reference,
8112 argument_list[1].real_reference,exception);
8113 break;
8114 }
8115 case 21: /* ReduceNoise */
8116 {
8117 if (attribute_flag[0] != 0)
8118 {
8119 flags=ParseGeometry(argument_list[0].string_reference,
8120 &geometry_info);
8121 if ((flags & SigmaValue) == 0)
8122 geometry_info.sigma=1.0;
8123 }
8124 if (attribute_flag[1] != 0)
8125 geometry_info.rho=argument_list[1].real_reference;
8126 if (attribute_flag[2] != 0)
8127 geometry_info.sigma=argument_list[2].real_reference;
8128 if (attribute_flag[3] != 0)
8129 channel=(ChannelType) argument_list[3].integer_reference;
8130 channel_mask=SetImageChannelMask(image,channel);
8131 image=StatisticImage(image,NonpeakStatistic,(size_t)
8132 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8133 if (image != (Image *) NULL)
8134 (void) SetImageChannelMask(image,channel_mask);
8135 break;
8136 }
8137 case 22: /* Roll */
8138 {
8139 if (attribute_flag[0] != 0)
8140 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8141 &geometry,exception);
8142 if (attribute_flag[1] != 0)
8143 geometry.x=argument_list[1].integer_reference;
8144 if (attribute_flag[2] != 0)
8145 geometry.y=argument_list[2].integer_reference;
8146 image=RollImage(image,geometry.x,geometry.y,exception);
8147 break;
8148 }
8149 case 23: /* Rotate */
8150 {
8151 if (attribute_flag[0] == 0)
8152 argument_list[0].real_reference=90.0;
8153 if (attribute_flag[1] != 0)
8154 {
8155 QueryColorCompliance(argument_list[1].string_reference,
8156 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008157 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8158 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008159 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8160 }
8161 image=RotateImage(image,argument_list[0].real_reference,exception);
8162 break;
8163 }
8164 case 24: /* Sample */
8165 {
8166 if (attribute_flag[0] != 0)
8167 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8168 &geometry,exception);
8169 if (attribute_flag[1] != 0)
8170 geometry.width=argument_list[1].integer_reference;
8171 if (attribute_flag[2] != 0)
8172 geometry.height=argument_list[2].integer_reference;
8173 image=SampleImage(image,geometry.width,geometry.height,exception);
8174 break;
8175 }
8176 case 25: /* Scale */
8177 {
8178 if (attribute_flag[0] != 0)
8179 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8180 &geometry,exception);
8181 if (attribute_flag[1] != 0)
8182 geometry.width=argument_list[1].integer_reference;
8183 if (attribute_flag[2] != 0)
8184 geometry.height=argument_list[2].integer_reference;
8185 image=ScaleImage(image,geometry.width,geometry.height,exception);
8186 break;
8187 }
8188 case 26: /* Shade */
8189 {
8190 if (attribute_flag[0] != 0)
8191 {
8192 flags=ParseGeometry(argument_list[0].string_reference,
8193 &geometry_info);
8194 if ((flags & SigmaValue) == 0)
8195 geometry_info.sigma=0.0;
8196 }
8197 if (attribute_flag[1] != 0)
8198 geometry_info.rho=argument_list[1].real_reference;
8199 if (attribute_flag[2] != 0)
8200 geometry_info.sigma=argument_list[2].real_reference;
8201 image=ShadeImage(image,
8202 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8203 geometry_info.rho,geometry_info.sigma,exception);
8204 break;
8205 }
8206 case 27: /* Sharpen */
8207 {
8208 if (attribute_flag[0] != 0)
8209 {
8210 flags=ParseGeometry(argument_list[0].string_reference,
8211 &geometry_info);
8212 if ((flags & SigmaValue) == 0)
8213 geometry_info.sigma=1.0;
8214 }
8215 if (attribute_flag[1] != 0)
8216 geometry_info.rho=argument_list[1].real_reference;
8217 if (attribute_flag[2] != 0)
8218 geometry_info.sigma=argument_list[2].real_reference;
8219 if (attribute_flag[3] != 0)
8220 channel=(ChannelType) argument_list[3].integer_reference;
8221 channel_mask=SetImageChannelMask(image,channel);
8222 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8223 exception);
8224 if (image != (Image *) NULL)
8225 (void) SetImageChannelMask(image,channel_mask);
8226 break;
8227 }
8228 case 28: /* Shear */
8229 {
8230 if (attribute_flag[0] != 0)
8231 {
8232 flags=ParseGeometry(argument_list[0].string_reference,
8233 &geometry_info);
8234 if ((flags & SigmaValue) == 0)
8235 geometry_info.sigma=geometry_info.rho;
8236 }
8237 if (attribute_flag[1] != 0)
8238 geometry_info.rho=argument_list[1].real_reference;
8239 if (attribute_flag[2] != 0)
8240 geometry_info.sigma=argument_list[2].real_reference;
8241 if (attribute_flag[3] != 0)
8242 QueryColorCompliance(argument_list[3].string_reference,
8243 AllCompliance,&image->background_color,exception);
8244 if (attribute_flag[4] != 0)
8245 QueryColorCompliance(argument_list[4].string_reference,
8246 AllCompliance,&image->background_color,exception);
8247 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8248 exception);
8249 break;
8250 }
8251 case 29: /* Spread */
8252 {
8253 PixelInterpolateMethod
8254 method;
8255
8256 if (attribute_flag[0] == 0)
8257 argument_list[0].real_reference=1.0;
8258 method=UndefinedInterpolatePixel;
8259 if (attribute_flag[1] != 0)
8260 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8261 image=SpreadImage(image,argument_list[0].real_reference,method,
8262 exception);
8263 break;
8264 }
8265 case 30: /* Swirl */
8266 {
8267 PixelInterpolateMethod
8268 method;
8269
8270 if (attribute_flag[0] == 0)
8271 argument_list[0].real_reference=50.0;
8272 method=UndefinedInterpolatePixel;
8273 if (attribute_flag[1] != 0)
8274 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8275 image=SwirlImage(image,argument_list[0].real_reference,
8276 method,exception);
8277 break;
8278 }
8279 case 31: /* Resize */
8280 case 32: /* Zoom */
8281 {
8282 if (attribute_flag[0] != 0)
8283 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8284 &geometry,exception);
8285 if (attribute_flag[1] != 0)
8286 geometry.width=argument_list[1].integer_reference;
8287 if (attribute_flag[2] != 0)
8288 geometry.height=argument_list[2].integer_reference;
8289 if (attribute_flag[3] == 0)
8290 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8291 if (attribute_flag[4] != 0)
8292 SetImageArtifact(image,"filter:support",
8293 argument_list[4].string_reference);
8294 image=ResizeImage(image,geometry.width,geometry.height,
8295 (FilterTypes) argument_list[3].integer_reference,
8296 exception);
8297 break;
8298 }
8299 case 33: /* Annotate */
8300 {
8301 DrawInfo
8302 *draw_info;
8303
8304 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8305 (DrawInfo *) NULL);
8306 if (attribute_flag[0] != 0)
8307 {
8308 char
8309 *text;
8310
8311 text=InterpretImageProperties(info ? info->image_info :
8312 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8313 exception);
8314 (void) CloneString(&draw_info->text,text);
8315 text=DestroyString(text);
8316 }
8317 if (attribute_flag[1] != 0)
8318 (void) CloneString(&draw_info->font,
8319 argument_list[1].string_reference);
8320 if (attribute_flag[2] != 0)
8321 draw_info->pointsize=argument_list[2].real_reference;
8322 if (attribute_flag[3] != 0)
8323 (void) CloneString(&draw_info->density,
8324 argument_list[3].string_reference);
8325 if (attribute_flag[4] != 0)
8326 (void) QueryColorCompliance(argument_list[4].string_reference,
8327 AllCompliance,&draw_info->undercolor,exception);
8328 if (attribute_flag[5] != 0)
8329 {
8330 (void) QueryColorCompliance(argument_list[5].string_reference,
8331 AllCompliance,&draw_info->stroke,exception);
8332 if (argument_list[5].image_reference != (Image *) NULL)
8333 draw_info->stroke_pattern=CloneImage(
8334 argument_list[5].image_reference,0,0,MagickTrue,exception);
8335 }
8336 if (attribute_flag[6] != 0)
8337 {
8338 (void) QueryColorCompliance(argument_list[6].string_reference,
8339 AllCompliance,&draw_info->fill,exception);
8340 if (argument_list[6].image_reference != (Image *) NULL)
8341 draw_info->fill_pattern=CloneImage(
8342 argument_list[6].image_reference,0,0,MagickTrue,exception);
8343 }
8344 if (attribute_flag[7] != 0)
8345 {
8346 (void) CloneString(&draw_info->geometry,
8347 argument_list[7].string_reference);
8348 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8349 &geometry,exception);
8350 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8351 geometry_info.sigma=geometry_info.xi;
8352 }
8353 if (attribute_flag[8] != 0)
8354 (void) QueryColorCompliance(argument_list[8].string_reference,
8355 AllCompliance,&draw_info->fill,exception);
8356 if (attribute_flag[11] != 0)
8357 draw_info->gravity=(GravityType)
8358 argument_list[11].integer_reference;
8359 if (attribute_flag[25] != 0)
8360 {
8361 AV
8362 *av;
8363
8364 av=(AV *) argument_list[25].array_reference;
8365 if ((av_len(av) != 3) && (av_len(av) != 5))
8366 {
8367 ThrowPerlException(exception,OptionError,
8368 "affine matrix must have 4 or 6 elements",PackageName);
8369 goto PerlException;
8370 }
8371 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8372 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8373 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8374 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8375 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8376 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8377 {
8378 ThrowPerlException(exception,OptionError,
8379 "affine matrix is singular",PackageName);
8380 goto PerlException;
8381 }
8382 if (av_len(av) == 5)
8383 {
8384 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8385 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8386 }
8387 }
8388 for (j=12; j < 17; j++)
8389 {
8390 if (attribute_flag[j] == 0)
8391 continue;
8392 value=argument_list[j].string_reference;
8393 angle=argument_list[j].real_reference;
8394 current=draw_info->affine;
8395 GetAffineMatrix(&affine);
8396 switch (j)
8397 {
8398 case 12:
8399 {
8400 /*
8401 Translate.
8402 */
8403 flags=ParseGeometry(value,&geometry_info);
8404 affine.tx=geometry_info.xi;
8405 affine.ty=geometry_info.psi;
8406 if ((flags & PsiValue) == 0)
8407 affine.ty=affine.tx;
8408 break;
8409 }
8410 case 13:
8411 {
8412 /*
8413 Scale.
8414 */
8415 flags=ParseGeometry(value,&geometry_info);
8416 affine.sx=geometry_info.rho;
8417 affine.sy=geometry_info.sigma;
8418 if ((flags & SigmaValue) == 0)
8419 affine.sy=affine.sx;
8420 break;
8421 }
8422 case 14:
8423 {
8424 /*
8425 Rotate.
8426 */
8427 if (angle == 0.0)
8428 break;
8429 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8430 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8431 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8432 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8433 break;
8434 }
8435 case 15:
8436 {
8437 /*
8438 SkewX.
8439 */
8440 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8441 break;
8442 }
8443 case 16:
8444 {
8445 /*
8446 SkewY.
8447 */
8448 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8449 break;
8450 }
8451 }
8452 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8453 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8454 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8455 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8456 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8457 current.tx;
8458 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8459 current.ty;
8460 }
8461 if (attribute_flag[9] == 0)
8462 argument_list[9].real_reference=0.0;
8463 if (attribute_flag[10] == 0)
8464 argument_list[10].real_reference=0.0;
8465 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8466 {
8467 char
cristy151b66d2015-04-15 10:50:31 +00008468 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008469
cristy151b66d2015-04-15 10:50:31 +00008470 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008471 (double) argument_list[9].real_reference+draw_info->affine.tx,
8472 (double) argument_list[10].real_reference+draw_info->affine.ty);
8473 (void) CloneString(&draw_info->geometry,geometry);
8474 }
8475 if (attribute_flag[17] != 0)
8476 draw_info->stroke_width=argument_list[17].real_reference;
8477 if (attribute_flag[18] != 0)
8478 {
8479 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8480 MagickTrue : MagickFalse;
8481 draw_info->stroke_antialias=draw_info->text_antialias;
8482 }
8483 if (attribute_flag[19] != 0)
8484 (void) CloneString(&draw_info->family,
8485 argument_list[19].string_reference);
8486 if (attribute_flag[20] != 0)
8487 draw_info->style=(StyleType) argument_list[20].integer_reference;
8488 if (attribute_flag[21] != 0)
8489 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8490 if (attribute_flag[22] != 0)
8491 draw_info->weight=argument_list[22].integer_reference;
8492 if (attribute_flag[23] != 0)
8493 draw_info->align=(AlignType) argument_list[23].integer_reference;
8494 if (attribute_flag[24] != 0)
8495 (void) CloneString(&draw_info->encoding,
8496 argument_list[24].string_reference);
8497 if (attribute_flag[25] != 0)
8498 draw_info->fill_pattern=CloneImage(
8499 argument_list[25].image_reference,0,0,MagickTrue,exception);
8500 if (attribute_flag[26] != 0)
8501 draw_info->fill_pattern=CloneImage(
8502 argument_list[26].image_reference,0,0,MagickTrue,exception);
8503 if (attribute_flag[27] != 0)
8504 draw_info->stroke_pattern=CloneImage(
8505 argument_list[27].image_reference,0,0,MagickTrue,exception);
8506 if (attribute_flag[29] != 0)
8507 draw_info->kerning=argument_list[29].real_reference;
8508 if (attribute_flag[30] != 0)
8509 draw_info->interline_spacing=argument_list[30].real_reference;
8510 if (attribute_flag[31] != 0)
8511 draw_info->interword_spacing=argument_list[31].real_reference;
8512 if (attribute_flag[32] != 0)
8513 draw_info->direction=(DirectionType)
8514 argument_list[32].integer_reference;
8515 (void) AnnotateImage(image,draw_info,exception);
8516 draw_info=DestroyDrawInfo(draw_info);
8517 break;
8518 }
8519 case 34: /* ColorFloodfill */
8520 {
8521 DrawInfo
8522 *draw_info;
8523
8524 MagickBooleanType
8525 invert;
8526
8527 PixelInfo
8528 target;
8529
8530 draw_info=CloneDrawInfo(info ? info->image_info :
8531 (ImageInfo *) NULL,(DrawInfo *) NULL);
8532 if (attribute_flag[0] != 0)
8533 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8534 &geometry,exception);
8535 if (attribute_flag[1] != 0)
8536 geometry.x=argument_list[1].integer_reference;
8537 if (attribute_flag[2] != 0)
8538 geometry.y=argument_list[2].integer_reference;
8539 if (attribute_flag[3] != 0)
8540 (void) QueryColorCompliance(argument_list[3].string_reference,
8541 AllCompliance,&draw_info->fill,exception);
8542 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8543 geometry.x,geometry.y,&target,exception);
8544 invert=MagickFalse;
8545 if (attribute_flag[4] != 0)
8546 {
8547 QueryColorCompliance(argument_list[4].string_reference,
8548 AllCompliance,&target,exception);
8549 invert=MagickTrue;
8550 }
8551 if (attribute_flag[5] != 0)
8552 image->fuzz=StringToDoubleInterval(
8553 argument_list[5].string_reference,(double) QuantumRange+1.0);
8554 if (attribute_flag[6] != 0)
8555 invert=(MagickBooleanType) argument_list[6].integer_reference;
8556 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8557 geometry.y,invert,exception);
8558 draw_info=DestroyDrawInfo(draw_info);
8559 break;
8560 }
8561 case 35: /* Composite */
8562 {
8563 char
cristy151b66d2015-04-15 10:50:31 +00008564 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008565
8566 Image
8567 *composite_image,
8568 *rotate_image;
8569
8570 MagickBooleanType
8571 clip_to_self;
8572
8573 compose=OverCompositeOp;
8574 if (attribute_flag[0] != 0)
8575 composite_image=argument_list[0].image_reference;
8576 else
8577 {
8578 ThrowPerlException(exception,OptionError,
8579 "CompositeImageRequired",PackageName);
8580 goto PerlException;
8581 }
8582 /*
8583 Parameter Handling used for BOTH normal and tiled composition.
8584 */
8585 if (attribute_flag[1] != 0) /* compose */
8586 compose=(CompositeOperator) argument_list[1].integer_reference;
8587 if (attribute_flag[6] != 0) /* opacity */
8588 {
8589 if (compose != DissolveCompositeOp)
8590 (void) SetImageAlpha(composite_image,(Quantum)
8591 StringToDoubleInterval(argument_list[6].string_reference,
8592 (double) QuantumRange+1.0),exception);
8593 else
8594 {
8595 CacheView
8596 *composite_view;
8597
8598 double
8599 opacity;
8600
8601 MagickBooleanType
8602 sync;
8603
8604 register ssize_t
8605 x;
8606
8607 register Quantum
8608 *q;
8609
8610 ssize_t
8611 y;
8612
8613 /*
8614 Handle dissolve composite operator (patch by
8615 Kevin A. McGrail).
8616 */
8617 (void) CloneString(&image->geometry,
8618 argument_list[6].string_reference);
8619 opacity=(Quantum) StringToDoubleInterval(
8620 argument_list[6].string_reference,(double) QuantumRange+
8621 1.0);
cristy17f11b02014-12-20 19:37:04 +00008622 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008623 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8624 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8625 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8626 {
8627 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8628 composite_image->columns,1,exception);
8629 for (x=0; x < (ssize_t) composite_image->columns; x++)
8630 {
8631 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8632 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8633 q);
8634 q+=GetPixelChannels(composite_image);
8635 }
8636 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8637 if (sync == MagickFalse)
8638 break;
8639 }
8640 composite_view=DestroyCacheView(composite_view);
8641 }
8642 }
8643 if (attribute_flag[9] != 0) /* "color=>" */
8644 QueryColorCompliance(argument_list[9].string_reference,
8645 AllCompliance,&composite_image->background_color,exception);
8646 if (attribute_flag[12] != 0) /* "interpolate=>" */
8647 image->interpolate=(PixelInterpolateMethod)
8648 argument_list[12].integer_reference;
8649 if (attribute_flag[13] != 0) /* "args=>" */
8650 (void) SetImageArtifact(composite_image,"compose:args",
8651 argument_list[13].string_reference);
8652 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8653 (void) SetImageArtifact(composite_image,"compose:args",
8654 argument_list[14].string_reference);
8655 clip_to_self=MagickTrue;
8656 if (attribute_flag[15] != 0)
8657 clip_to_self=(MagickBooleanType)
8658 argument_list[15].integer_reference;
8659 /*
8660 Tiling Composition (with orthogonal rotate).
8661 */
8662 rotate_image=(Image *) NULL;
8663 if (attribute_flag[8] != 0) /* "rotate=>" */
8664 {
8665 /*
8666 Rotate image.
8667 */
8668 rotate_image=RotateImage(composite_image,
8669 argument_list[8].real_reference,exception);
8670 if (rotate_image == (Image *) NULL)
8671 break;
8672 }
8673 if ((attribute_flag[7] != 0) &&
8674 (argument_list[7].integer_reference != 0)) /* tile */
8675 {
8676 ssize_t
8677 x,
8678 y;
8679
8680 /*
8681 Tile the composite image.
8682 */
8683 if (attribute_flag[8] != 0) /* "tile=>" */
8684 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8685 "false");
8686 else
8687 (void) SetImageArtifact(composite_image,
8688 "compose:outside-overlay","false");
8689 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8690 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8691 {
8692 if (attribute_flag[8] != 0) /* rotate */
8693 (void) CompositeImage(image,rotate_image,compose,
8694 MagickTrue,x,y,exception);
8695 else
8696 (void) CompositeImage(image,composite_image,compose,
8697 MagickTrue,x,y,exception);
8698 }
8699 if (attribute_flag[8] != 0) /* rotate */
8700 rotate_image=DestroyImage(rotate_image);
8701 break;
8702 }
8703 /*
8704 Parameter Handling used used ONLY for normal composition.
8705 */
8706 if (attribute_flag[5] != 0) /* gravity */
8707 image->gravity=(GravityType) argument_list[5].integer_reference;
8708 if (attribute_flag[2] != 0) /* geometry offset */
8709 {
8710 SetGeometry(image,&geometry);
8711 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8712 &geometry);
8713 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8714 &geometry);
8715 }
8716 if (attribute_flag[3] != 0) /* x offset */
8717 geometry.x=argument_list[3].integer_reference;
8718 if (attribute_flag[4] != 0) /* y offset */
8719 geometry.y=argument_list[4].integer_reference;
8720 if (attribute_flag[10] != 0) /* mask */
8721 {
8722 if ((image->compose == DisplaceCompositeOp) ||
8723 (image->compose == DistortCompositeOp))
8724 {
8725 /*
8726 Merge Y displacement into X displacement image.
8727 */
8728 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8729 exception);
8730 (void) CompositeImage(composite_image,
8731 argument_list[10].image_reference,CopyGreenCompositeOp,
8732 MagickTrue,0,0,exception);
8733 }
8734 else
8735 {
8736 Image
8737 *mask_image;
8738
8739 /*
8740 Set a blending mask for the composition.
8741 */
8742 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8743 MagickTrue,exception);
8744 (void) SetImageMask(composite_image,mask_image,exception);
8745 mask_image=DestroyImage(mask_image);
8746 }
8747 }
8748 if (attribute_flag[11] != 0) /* channel */
8749 channel=(ChannelType) argument_list[11].integer_reference;
8750 /*
8751 Composite two images (normal composition).
8752 */
cristy151b66d2015-04-15 10:50:31 +00008753 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008754 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8755 (double) composite_image->rows,(double) geometry.x,(double)
8756 geometry.y);
8757 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8758 exception);
8759 channel_mask=SetImageChannelMask(image,channel);
8760 if (attribute_flag[8] == 0) /* no rotate */
8761 CompositeImage(image,composite_image,compose,clip_to_self,
8762 geometry.x,geometry.y,exception);
8763 else
8764 {
8765 /*
8766 Position adjust rotated image then composite.
8767 */
8768 geometry.x-=(ssize_t) (rotate_image->columns-
8769 composite_image->columns)/2;
8770 geometry.y-=(ssize_t) (rotate_image->rows-
8771 composite_image->rows)/2;
8772 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8773 geometry.y,exception);
8774 rotate_image=DestroyImage(rotate_image);
8775 }
8776 if (attribute_flag[10] != 0) /* mask */
8777 {
8778 if ((image->compose == DisplaceCompositeOp) ||
8779 (image->compose == DistortCompositeOp))
8780 composite_image=DestroyImage(composite_image);
8781 else
8782 (void) SetImageMask(image,(Image *) NULL,exception);
8783 }
8784 (void) SetImageChannelMask(image,channel_mask);
8785 break;
8786 }
8787 case 36: /* Contrast */
8788 {
8789 if (attribute_flag[0] == 0)
8790 argument_list[0].integer_reference=0;
8791 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8792 MagickTrue : MagickFalse,exception);
8793 break;
8794 }
8795 case 37: /* CycleColormap */
8796 {
8797 if (attribute_flag[0] == 0)
8798 argument_list[0].integer_reference=6;
8799 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8800 exception);
8801 break;
8802 }
8803 case 38: /* Draw */
8804 {
8805 DrawInfo
8806 *draw_info;
8807
8808 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8809 (DrawInfo *) NULL);
8810 (void) CloneString(&draw_info->primitive,"point");
8811 if (attribute_flag[0] != 0)
8812 {
8813 if (argument_list[0].integer_reference < 0)
8814 (void) CloneString(&draw_info->primitive,
8815 argument_list[0].string_reference);
8816 else
8817 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8818 MagickPrimitiveOptions,argument_list[0].integer_reference));
8819 }
8820 if (attribute_flag[1] != 0)
8821 {
8822 if (LocaleCompare(draw_info->primitive,"path") == 0)
8823 {
8824 (void) ConcatenateString(&draw_info->primitive," '");
8825 ConcatenateString(&draw_info->primitive,
8826 argument_list[1].string_reference);
8827 (void) ConcatenateString(&draw_info->primitive,"'");
8828 }
8829 else
8830 {
8831 (void) ConcatenateString(&draw_info->primitive," ");
8832 ConcatenateString(&draw_info->primitive,
8833 argument_list[1].string_reference);
8834 }
8835 }
8836 if (attribute_flag[2] != 0)
8837 {
8838 (void) ConcatenateString(&draw_info->primitive," ");
8839 (void) ConcatenateString(&draw_info->primitive,
8840 CommandOptionToMnemonic(MagickMethodOptions,
8841 argument_list[2].integer_reference));
8842 }
8843 if (attribute_flag[3] != 0)
8844 {
8845 (void) QueryColorCompliance(argument_list[3].string_reference,
8846 AllCompliance,&draw_info->stroke,exception);
8847 if (argument_list[3].image_reference != (Image *) NULL)
8848 draw_info->stroke_pattern=CloneImage(
8849 argument_list[3].image_reference,0,0,MagickTrue,exception);
8850 }
8851 if (attribute_flag[4] != 0)
8852 {
8853 (void) QueryColorCompliance(argument_list[4].string_reference,
8854 AllCompliance,&draw_info->fill,exception);
8855 if (argument_list[4].image_reference != (Image *) NULL)
8856 draw_info->fill_pattern=CloneImage(
8857 argument_list[4].image_reference,0,0,MagickTrue,exception);
8858 }
8859 if (attribute_flag[5] != 0)
8860 draw_info->stroke_width=argument_list[5].real_reference;
8861 if (attribute_flag[6] != 0)
8862 (void) CloneString(&draw_info->font,
8863 argument_list[6].string_reference);
8864 if (attribute_flag[7] != 0)
8865 (void) QueryColorCompliance(argument_list[7].string_reference,
8866 AllCompliance,&draw_info->border_color,exception);
8867 if (attribute_flag[8] != 0)
8868 draw_info->affine.tx=argument_list[8].real_reference;
8869 if (attribute_flag[9] != 0)
8870 draw_info->affine.ty=argument_list[9].real_reference;
8871 if (attribute_flag[20] != 0)
8872 {
8873 AV
8874 *av;
8875
8876 av=(AV *) argument_list[20].array_reference;
8877 if ((av_len(av) != 3) && (av_len(av) != 5))
8878 {
8879 ThrowPerlException(exception,OptionError,
8880 "affine matrix must have 4 or 6 elements",PackageName);
8881 goto PerlException;
8882 }
8883 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8884 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8885 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8886 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8887 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8888 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8889 {
8890 ThrowPerlException(exception,OptionError,
8891 "affine matrix is singular",PackageName);
8892 goto PerlException;
8893 }
8894 if (av_len(av) == 5)
8895 {
8896 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8897 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8898 }
8899 }
8900 for (j=10; j < 15; j++)
8901 {
8902 if (attribute_flag[j] == 0)
8903 continue;
8904 value=argument_list[j].string_reference;
8905 angle=argument_list[j].real_reference;
8906 current=draw_info->affine;
8907 GetAffineMatrix(&affine);
8908 switch (j)
8909 {
8910 case 10:
8911 {
8912 /*
8913 Translate.
8914 */
8915 flags=ParseGeometry(value,&geometry_info);
8916 affine.tx=geometry_info.xi;
8917 affine.ty=geometry_info.psi;
8918 if ((flags & PsiValue) == 0)
8919 affine.ty=affine.tx;
8920 break;
8921 }
8922 case 11:
8923 {
8924 /*
8925 Scale.
8926 */
8927 flags=ParseGeometry(value,&geometry_info);
8928 affine.sx=geometry_info.rho;
8929 affine.sy=geometry_info.sigma;
8930 if ((flags & SigmaValue) == 0)
8931 affine.sy=affine.sx;
8932 break;
8933 }
8934 case 12:
8935 {
8936 /*
8937 Rotate.
8938 */
8939 if (angle == 0.0)
8940 break;
8941 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8942 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8943 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8944 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8945 break;
8946 }
8947 case 13:
8948 {
8949 /*
8950 SkewX.
8951 */
8952 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8953 break;
8954 }
8955 case 14:
8956 {
8957 /*
8958 SkewY.
8959 */
8960 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8961 break;
8962 }
8963 }
8964 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8965 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8966 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8967 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8968 draw_info->affine.tx=
8969 current.sx*affine.tx+current.ry*affine.ty+current.tx;
8970 draw_info->affine.ty=
8971 current.rx*affine.tx+current.sy*affine.ty+current.ty;
8972 }
8973 if (attribute_flag[15] != 0)
8974 draw_info->fill_pattern=CloneImage(
8975 argument_list[15].image_reference,0,0,MagickTrue,exception);
8976 if (attribute_flag[16] != 0)
8977 draw_info->pointsize=argument_list[16].real_reference;
8978 if (attribute_flag[17] != 0)
8979 {
8980 draw_info->stroke_antialias=argument_list[17].integer_reference != 0
8981 ? MagickTrue : MagickFalse;
8982 draw_info->text_antialias=draw_info->stroke_antialias;
8983 }
8984 if (attribute_flag[18] != 0)
8985 (void) CloneString(&draw_info->density,
8986 argument_list[18].string_reference);
8987 if (attribute_flag[19] != 0)
8988 draw_info->stroke_width=argument_list[19].real_reference;
8989 if (attribute_flag[21] != 0)
8990 draw_info->dash_offset=argument_list[21].real_reference;
8991 if (attribute_flag[22] != 0)
8992 {
8993 AV
8994 *av;
8995
8996 av=(AV *) argument_list[22].array_reference;
8997 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
8998 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
8999 if (draw_info->dash_pattern != (double *) NULL)
9000 {
9001 for (i=0; i <= av_len(av); i++)
9002 draw_info->dash_pattern[i]=(double)
9003 SvNV(*(av_fetch(av,i,0)));
9004 draw_info->dash_pattern[i]=0.0;
9005 }
9006 }
9007 if (attribute_flag[23] != 0)
9008 image->interpolate=(PixelInterpolateMethod)
9009 argument_list[23].integer_reference;
9010 if ((attribute_flag[24] != 0) &&
9011 (draw_info->fill_pattern != (Image *) NULL))
9012 flags=ParsePageGeometry(draw_info->fill_pattern,
9013 argument_list[24].string_reference,
9014 &draw_info->fill_pattern->tile_offset,exception);
9015 if (attribute_flag[25] != 0)
9016 {
9017 (void) ConcatenateString(&draw_info->primitive," '");
9018 (void) ConcatenateString(&draw_info->primitive,
9019 argument_list[25].string_reference);
9020 (void) ConcatenateString(&draw_info->primitive,"'");
9021 }
9022 if (attribute_flag[26] != 0)
9023 draw_info->fill_pattern=CloneImage(
9024 argument_list[26].image_reference,0,0,MagickTrue,exception);
9025 if (attribute_flag[27] != 0)
9026 draw_info->stroke_pattern=CloneImage(
9027 argument_list[27].image_reference,0,0,MagickTrue,exception);
9028 if (attribute_flag[28] != 0)
9029 (void) CloneString(&draw_info->primitive,
9030 argument_list[28].string_reference);
9031 if (attribute_flag[29] != 0)
9032 draw_info->kerning=argument_list[29].real_reference;
9033 if (attribute_flag[30] != 0)
9034 draw_info->interline_spacing=argument_list[30].real_reference;
9035 if (attribute_flag[31] != 0)
9036 draw_info->interword_spacing=argument_list[31].real_reference;
9037 if (attribute_flag[32] != 0)
9038 draw_info->direction=(DirectionType)
9039 argument_list[32].integer_reference;
9040 DrawImage(image,draw_info,exception);
9041 draw_info=DestroyDrawInfo(draw_info);
9042 break;
9043 }
9044 case 39: /* Equalize */
9045 {
9046 if (attribute_flag[0] != 0)
9047 channel=(ChannelType) argument_list[0].integer_reference;
9048 channel_mask=SetImageChannelMask(image,channel);
9049 EqualizeImage(image,exception);
9050 (void) SetImageChannelMask(image,channel_mask);
9051 break;
9052 }
9053 case 40: /* Gamma */
9054 {
9055 if (attribute_flag[1] != 0)
9056 channel=(ChannelType) argument_list[1].integer_reference;
9057 if (attribute_flag[2] == 0)
9058 argument_list[2].real_reference=1.0;
9059 if (attribute_flag[3] == 0)
9060 argument_list[3].real_reference=1.0;
9061 if (attribute_flag[4] == 0)
9062 argument_list[4].real_reference=1.0;
9063 if (attribute_flag[0] == 0)
9064 {
cristy151b66d2015-04-15 10:50:31 +00009065 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00009066 "%.15g,%.15g,%.15g",(double) argument_list[2].real_reference,
9067 (double) argument_list[3].real_reference,
9068 (double) argument_list[4].real_reference);
9069 argument_list[0].string_reference=message;
9070 }
9071 (void) GammaImage(image,StringToDouble(
9072 argument_list[0].string_reference,(char **) NULL),exception);
9073 break;
9074 }
9075 case 41: /* Map */
9076 {
9077 QuantizeInfo
9078 *quantize_info;
9079
9080 if (attribute_flag[0] == 0)
9081 {
9082 ThrowPerlException(exception,OptionError,"MapImageRequired",
9083 PackageName);
9084 goto PerlException;
9085 }
9086 quantize_info=AcquireQuantizeInfo(info->image_info);
9087 if (attribute_flag[1] != 0)
9088 quantize_info->dither_method=(DitherMethod)
9089 argument_list[1].integer_reference;
9090 (void) RemapImages(quantize_info,image,
9091 argument_list[0].image_reference,exception);
9092 quantize_info=DestroyQuantizeInfo(quantize_info);
9093 break;
9094 }
9095 case 42: /* MatteFloodfill */
9096 {
9097 DrawInfo
9098 *draw_info;
9099
9100 MagickBooleanType
9101 invert;
9102
9103 PixelInfo
9104 target;
9105
9106 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9107 (DrawInfo *) NULL);
9108 if (attribute_flag[0] != 0)
9109 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9110 &geometry,exception);
9111 if (attribute_flag[1] != 0)
9112 geometry.x=argument_list[1].integer_reference;
9113 if (attribute_flag[2] != 0)
9114 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009115 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009116 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9117 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9118 geometry.x,geometry.y,&target,exception);
9119 if (attribute_flag[4] != 0)
9120 QueryColorCompliance(argument_list[4].string_reference,
9121 AllCompliance,&target,exception);
9122 if (attribute_flag[3] != 0)
9123 target.alpha=StringToDoubleInterval(
9124 argument_list[3].string_reference,(double) (double) QuantumRange+
9125 1.0);
9126 if (attribute_flag[5] != 0)
9127 image->fuzz=StringToDoubleInterval(
9128 argument_list[5].string_reference,(double) QuantumRange+1.0);
9129 invert=MagickFalse;
9130 if (attribute_flag[6] != 0)
9131 invert=(MagickBooleanType) argument_list[6].integer_reference;
9132 channel_mask=SetImageChannelMask(image,AlphaChannel);
9133 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9134 geometry.y,invert,exception);
9135 (void) SetImageChannelMask(image,channel_mask);
9136 draw_info=DestroyDrawInfo(draw_info);
9137 break;
9138 }
9139 case 43: /* Modulate */
9140 {
9141 char
cristy151b66d2015-04-15 10:50:31 +00009142 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009143
9144 geometry_info.rho=100.0;
9145 geometry_info.sigma=100.0;
9146 geometry_info.xi=100.0;
9147 if (attribute_flag[0] != 0)
9148 (void)ParseGeometry(argument_list[0].string_reference,
9149 &geometry_info);
9150 if (attribute_flag[1] != 0)
9151 geometry_info.xi=argument_list[1].real_reference;
9152 if (attribute_flag[2] != 0)
9153 geometry_info.sigma=argument_list[2].real_reference;
9154 if (attribute_flag[3] != 0)
9155 {
9156 geometry_info.sigma=argument_list[3].real_reference;
9157 SetImageArtifact(image,"modulate:colorspace","HWB");
9158 }
9159 if (attribute_flag[4] != 0)
9160 {
9161 geometry_info.rho=argument_list[4].real_reference;
9162 SetImageArtifact(image,"modulate:colorspace","HSB");
9163 }
9164 if (attribute_flag[5] != 0)
9165 {
9166 geometry_info.sigma=argument_list[5].real_reference;
9167 SetImageArtifact(image,"modulate:colorspace","HSL");
9168 }
9169 if (attribute_flag[6] != 0)
9170 {
9171 geometry_info.rho=argument_list[6].real_reference;
9172 SetImageArtifact(image,"modulate:colorspace","HWB");
9173 }
cristy151b66d2015-04-15 10:50:31 +00009174 (void) FormatLocaleString(modulate,MagickPathExtent,"%.15g,%.15g,%.15g",
cristy4a3ce0a2013-08-03 20:06:59 +00009175 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
9176 (void) ModulateImage(image,modulate,exception);
9177 break;
9178 }
9179 case 44: /* Negate */
9180 {
9181 if (attribute_flag[0] == 0)
9182 argument_list[0].integer_reference=0;
9183 if (attribute_flag[1] != 0)
9184 channel=(ChannelType) argument_list[1].integer_reference;
9185 channel_mask=SetImageChannelMask(image,channel);
9186 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9187 MagickTrue : MagickFalse,exception);
9188 (void) SetImageChannelMask(image,channel_mask);
9189 break;
9190 }
9191 case 45: /* Normalize */
9192 {
9193 if (attribute_flag[0] != 0)
9194 channel=(ChannelType) argument_list[0].integer_reference;
9195 channel_mask=SetImageChannelMask(image,channel);
9196 NormalizeImage(image,exception);
9197 (void) SetImageChannelMask(image,channel_mask);
9198 break;
9199 }
9200 case 46: /* NumberColors */
9201 break;
9202 case 47: /* Opaque */
9203 {
9204 MagickBooleanType
9205 invert;
9206
9207 PixelInfo
9208 fill_color,
9209 target;
9210
9211 (void) QueryColorCompliance("none",AllCompliance,&target,
9212 exception);
9213 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9214 exception);
9215 if (attribute_flag[0] != 0)
9216 (void) QueryColorCompliance(argument_list[0].string_reference,
9217 AllCompliance,&target,exception);
9218 if (attribute_flag[1] != 0)
9219 (void) QueryColorCompliance(argument_list[1].string_reference,
9220 AllCompliance,&fill_color,exception);
9221 if (attribute_flag[2] != 0)
9222 image->fuzz=StringToDoubleInterval(
9223 argument_list[2].string_reference,(double) QuantumRange+1.0);
9224 if (attribute_flag[3] != 0)
9225 channel=(ChannelType) argument_list[3].integer_reference;
9226 invert=MagickFalse;
9227 if (attribute_flag[4] != 0)
9228 invert=(MagickBooleanType) argument_list[4].integer_reference;
9229 channel_mask=SetImageChannelMask(image,channel);
9230 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9231 (void) SetImageChannelMask(image,channel_mask);
9232 break;
9233 }
9234 case 48: /* Quantize */
9235 {
9236 QuantizeInfo
9237 *quantize_info;
9238
9239 quantize_info=AcquireQuantizeInfo(info->image_info);
9240 if (attribute_flag[0] != 0)
9241 quantize_info->number_colors=(size_t)
9242 argument_list[0].integer_reference;
9243 if (attribute_flag[1] != 0)
9244 quantize_info->tree_depth=(size_t)
9245 argument_list[1].integer_reference;
9246 if (attribute_flag[2] != 0)
9247 quantize_info->colorspace=(ColorspaceType)
9248 argument_list[2].integer_reference;
9249 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009250 quantize_info->dither_method=(DitherMethod)
9251 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009252 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009253 quantize_info->measure_error=
9254 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009255 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009256 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009257 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009258 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009259 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009260 argument_list[7].integer_reference;
9261 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009262 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009263 else
cristyf7563392014-03-25 13:54:04 +00009264 if ((image->storage_class == DirectClass) ||
9265 (image->colors > quantize_info->number_colors) ||
9266 (quantize_info->colorspace == GRAYColorspace))
9267 (void) QuantizeImage(quantize_info,image,exception);
9268 else
9269 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009270 quantize_info=DestroyQuantizeInfo(quantize_info);
9271 break;
9272 }
9273 case 49: /* Raise */
9274 {
9275 if (attribute_flag[0] != 0)
9276 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9277 &geometry,exception);
9278 if (attribute_flag[1] != 0)
9279 geometry.width=argument_list[1].integer_reference;
9280 if (attribute_flag[2] != 0)
9281 geometry.height=argument_list[2].integer_reference;
9282 if (attribute_flag[3] == 0)
9283 argument_list[3].integer_reference=1;
9284 (void) RaiseImage(image,&geometry,
9285 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9286 exception);
9287 break;
9288 }
9289 case 50: /* Segment */
9290 {
9291 ColorspaceType
9292 colorspace;
9293
9294 double
9295 cluster_threshold,
9296 smoothing_threshold;
9297
9298 MagickBooleanType
9299 verbose;
9300
9301 cluster_threshold=1.0;
9302 smoothing_threshold=1.5;
9303 colorspace=sRGBColorspace;
9304 verbose=MagickFalse;
9305 if (attribute_flag[0] != 0)
9306 {
9307 flags=ParseGeometry(argument_list[0].string_reference,
9308 &geometry_info);
9309 cluster_threshold=geometry_info.rho;
9310 if (flags & SigmaValue)
9311 smoothing_threshold=geometry_info.sigma;
9312 }
9313 if (attribute_flag[1] != 0)
9314 cluster_threshold=argument_list[1].real_reference;
9315 if (attribute_flag[2] != 0)
9316 smoothing_threshold=argument_list[2].real_reference;
9317 if (attribute_flag[3] != 0)
9318 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9319 if (attribute_flag[4] != 0)
9320 verbose=argument_list[4].integer_reference != 0 ?
9321 MagickTrue : MagickFalse;
9322 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9323 smoothing_threshold,exception);
9324 break;
9325 }
9326 case 51: /* Signature */
9327 {
9328 (void) SignatureImage(image,exception);
9329 break;
9330 }
9331 case 52: /* Solarize */
9332 {
9333 geometry_info.rho=QuantumRange/2.0;
9334 if (attribute_flag[0] != 0)
9335 flags=ParseGeometry(argument_list[0].string_reference,
9336 &geometry_info);
9337 if (attribute_flag[1] != 0)
9338 geometry_info.rho=StringToDoubleInterval(
9339 argument_list[1].string_reference,(double) QuantumRange+1.0);
9340 (void) SolarizeImage(image,geometry_info.rho,exception);
9341 break;
9342 }
9343 case 53: /* Sync */
9344 {
9345 (void) SyncImage(image,exception);
9346 break;
9347 }
9348 case 54: /* Texture */
9349 {
9350 if (attribute_flag[0] == 0)
9351 break;
9352 TextureImage(image,argument_list[0].image_reference,exception);
9353 break;
9354 }
9355 case 55: /* Evalute */
9356 {
9357 MagickEvaluateOperator
9358 op;
9359
9360 op=SetEvaluateOperator;
9361 if (attribute_flag[0] == MagickFalse)
9362 argument_list[0].real_reference=0.0;
9363 if (attribute_flag[1] != MagickFalse)
9364 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9365 if (attribute_flag[2] != MagickFalse)
9366 channel=(ChannelType) argument_list[2].integer_reference;
9367 channel_mask=SetImageChannelMask(image,channel);
9368 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9369 exception);
9370 (void) SetImageChannelMask(image,channel_mask);
9371 break;
9372 }
9373 case 56: /* Transparent */
9374 {
9375 double
9376 opacity;
9377
9378 MagickBooleanType
9379 invert;
9380
9381 PixelInfo
9382 target;
9383
9384 (void) QueryColorCompliance("none",AllCompliance,&target,
9385 exception);
9386 if (attribute_flag[0] != 0)
9387 (void) QueryColorCompliance(argument_list[0].string_reference,
9388 AllCompliance,&target,exception);
9389 opacity=TransparentAlpha;
9390 if (attribute_flag[1] != 0)
9391 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9392 (double) QuantumRange+1.0);
9393 if (attribute_flag[2] != 0)
9394 image->fuzz=StringToDoubleInterval(
9395 argument_list[2].string_reference,(double) QuantumRange+1.0);
9396 if (attribute_flag[3] == 0)
9397 argument_list[3].integer_reference=0;
9398 invert=MagickFalse;
9399 if (attribute_flag[3] != 0)
9400 invert=(MagickBooleanType) argument_list[3].integer_reference;
9401 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9402 invert,exception);
9403 break;
9404 }
9405 case 57: /* Threshold */
9406 {
9407 double
9408 threshold;
9409
9410 if (attribute_flag[0] == 0)
9411 argument_list[0].string_reference="50%";
9412 if (attribute_flag[1] != 0)
9413 channel=(ChannelType) argument_list[1].integer_reference;
9414 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9415 (double) QuantumRange+1.0);
9416 channel_mask=SetImageChannelMask(image,channel);
9417 (void) BilevelImage(image,threshold,exception);
9418 (void) SetImageChannelMask(image,channel_mask);
9419 break;
9420 }
9421 case 58: /* Charcoal */
9422 {
9423 if (attribute_flag[0] != 0)
9424 {
9425 flags=ParseGeometry(argument_list[0].string_reference,
9426 &geometry_info);
9427 if ((flags & SigmaValue) == 0)
9428 geometry_info.sigma=1.0;
9429 }
9430 if (attribute_flag[1] != 0)
9431 geometry_info.rho=argument_list[1].real_reference;
9432 if (attribute_flag[2] != 0)
9433 geometry_info.sigma=argument_list[2].real_reference;
9434 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9435 exception);
9436 break;
9437 }
9438 case 59: /* Trim */
9439 {
9440 if (attribute_flag[0] != 0)
9441 image->fuzz=StringToDoubleInterval(
9442 argument_list[0].string_reference,(double) QuantumRange+1.0);
9443 image=TrimImage(image,exception);
9444 break;
9445 }
9446 case 60: /* Wave */
9447 {
9448 PixelInterpolateMethod
9449 method;
9450
9451 if (attribute_flag[0] != 0)
9452 {
9453 flags=ParseGeometry(argument_list[0].string_reference,
9454 &geometry_info);
9455 if ((flags & SigmaValue) == 0)
9456 geometry_info.sigma=1.0;
9457 }
9458 if (attribute_flag[1] != 0)
9459 geometry_info.rho=argument_list[1].real_reference;
9460 if (attribute_flag[2] != 0)
9461 geometry_info.sigma=argument_list[2].real_reference;
9462 method=UndefinedInterpolatePixel;
9463 if (attribute_flag[3] != 0)
9464 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9465 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9466 method,exception);
9467 break;
9468 }
9469 case 61: /* Separate */
9470 {
9471 if (attribute_flag[0] != 0)
9472 channel=(ChannelType) argument_list[0].integer_reference;
9473 image=SeparateImage(image,channel,exception);
9474 break;
9475 }
9476 case 63: /* Stereo */
9477 {
9478 if (attribute_flag[0] == 0)
9479 {
9480 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9481 PackageName);
9482 goto PerlException;
9483 }
9484 if (attribute_flag[1] != 0)
9485 geometry.x=argument_list[1].integer_reference;
9486 if (attribute_flag[2] != 0)
9487 geometry.y=argument_list[2].integer_reference;
9488 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9489 geometry.x,geometry.y,exception);
9490 break;
9491 }
9492 case 64: /* Stegano */
9493 {
9494 if (attribute_flag[0] == 0)
9495 {
9496 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9497 PackageName);
9498 goto PerlException;
9499 }
9500 if (attribute_flag[1] == 0)
9501 argument_list[1].integer_reference=0;
9502 image->offset=argument_list[1].integer_reference;
9503 image=SteganoImage(image,argument_list[0].image_reference,exception);
9504 break;
9505 }
9506 case 65: /* Deconstruct */
9507 {
9508 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9509 break;
9510 }
9511 case 66: /* GaussianBlur */
9512 {
9513 if (attribute_flag[0] != 0)
9514 {
9515 flags=ParseGeometry(argument_list[0].string_reference,
9516 &geometry_info);
9517 if ((flags & SigmaValue) == 0)
9518 geometry_info.sigma=1.0;
9519 }
9520 if (attribute_flag[1] != 0)
9521 geometry_info.rho=argument_list[1].real_reference;
9522 if (attribute_flag[2] != 0)
9523 geometry_info.sigma=argument_list[2].real_reference;
9524 if (attribute_flag[3] != 0)
9525 channel=(ChannelType) argument_list[3].integer_reference;
9526 channel_mask=SetImageChannelMask(image,channel);
9527 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9528 exception);
9529 if (image != (Image *) NULL)
9530 (void) SetImageChannelMask(image,channel_mask);
9531 break;
9532 }
9533 case 67: /* Convolve */
9534 {
9535 KernelInfo
9536 *kernel;
9537
9538 kernel=(KernelInfo *) NULL;
9539 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9540 break;
9541 if (attribute_flag[0] != 0)
9542 {
9543 AV
9544 *av;
9545
9546 size_t
9547 order;
9548
cristy2c57b742014-10-31 00:40:34 +00009549 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009550 if (kernel == (KernelInfo *) NULL)
9551 break;
9552 av=(AV *) argument_list[0].array_reference;
9553 order=(size_t) sqrt(av_len(av)+1);
9554 kernel->width=order;
9555 kernel->height=order;
9556 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9557 order*sizeof(*kernel->values));
9558 if (kernel->values == (MagickRealType *) NULL)
9559 {
9560 kernel=DestroyKernelInfo(kernel);
9561 ThrowPerlException(exception,ResourceLimitFatalError,
9562 "MemoryAllocationFailed",PackageName);
9563 goto PerlException;
9564 }
9565 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9566 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9567 for ( ; j < (ssize_t) (order*order); j++)
9568 kernel->values[j]=0.0;
9569 }
9570 if (attribute_flag[1] != 0)
9571 channel=(ChannelType) argument_list[1].integer_reference;
9572 if (attribute_flag[2] != 0)
9573 SetImageArtifact(image,"filter:blur",
9574 argument_list[2].string_reference);
9575 if (attribute_flag[3] != 0)
9576 {
cristy2c57b742014-10-31 00:40:34 +00009577 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9578 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009579 if (kernel == (KernelInfo *) NULL)
9580 break;
9581 }
9582 channel_mask=SetImageChannelMask(image,channel);
9583 image=ConvolveImage(image,kernel,exception);
9584 if (image != (Image *) NULL)
9585 (void) SetImageChannelMask(image,channel_mask);
9586 kernel=DestroyKernelInfo(kernel);
9587 break;
9588 }
9589 case 68: /* Profile */
9590 {
9591 const char
9592 *name;
9593
9594 Image
9595 *profile_image;
9596
9597 ImageInfo
9598 *profile_info;
9599
9600 StringInfo
9601 *profile;
9602
9603 name="*";
9604 if (attribute_flag[0] != 0)
9605 name=argument_list[0].string_reference;
9606 if (attribute_flag[2] != 0)
9607 image->rendering_intent=(RenderingIntent)
9608 argument_list[2].integer_reference;
9609 if (attribute_flag[3] != 0)
9610 image->black_point_compensation=
9611 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9612 if (attribute_flag[1] != 0)
9613 {
9614 if (argument_list[1].length == 0)
9615 {
9616 /*
9617 Remove a profile from the image.
9618 */
9619 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9620 exception);
9621 break;
9622 }
9623 /*
9624 Associate user supplied profile with the image.
9625 */
9626 profile=AcquireStringInfo(argument_list[1].length);
9627 SetStringInfoDatum(profile,(const unsigned char *)
9628 argument_list[1].string_reference);
9629 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9630 (size_t) GetStringInfoLength(profile),exception);
9631 profile=DestroyStringInfo(profile);
9632 break;
9633 }
9634 /*
9635 Associate a profile with the image.
9636 */
9637 profile_info=CloneImageInfo(info ? info->image_info :
9638 (ImageInfo *) NULL);
9639 profile_image=ReadImages(profile_info,name,exception);
9640 if (profile_image == (Image *) NULL)
9641 break;
9642 ResetImageProfileIterator(profile_image);
9643 name=GetNextImageProfile(profile_image);
9644 while (name != (const char *) NULL)
9645 {
9646 const StringInfo
9647 *profile;
9648
9649 profile=GetImageProfile(profile_image,name);
9650 if (profile != (const StringInfo *) NULL)
9651 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9652 (size_t) GetStringInfoLength(profile),exception);
9653 name=GetNextImageProfile(profile_image);
9654 }
9655 profile_image=DestroyImage(profile_image);
9656 profile_info=DestroyImageInfo(profile_info);
9657 break;
9658 }
9659 case 69: /* UnsharpMask */
9660 {
9661 if (attribute_flag[0] != 0)
9662 {
9663 flags=ParseGeometry(argument_list[0].string_reference,
9664 &geometry_info);
9665 if ((flags & SigmaValue) == 0)
9666 geometry_info.sigma=1.0;
9667 if ((flags & XiValue) == 0)
9668 geometry_info.xi=1.0;
9669 if ((flags & PsiValue) == 0)
9670 geometry_info.psi=0.5;
9671 }
9672 if (attribute_flag[1] != 0)
9673 geometry_info.rho=argument_list[1].real_reference;
9674 if (attribute_flag[2] != 0)
9675 geometry_info.sigma=argument_list[2].real_reference;
9676 if (attribute_flag[3] != 0)
9677 geometry_info.xi=argument_list[3].real_reference;
9678 if (attribute_flag[4] != 0)
9679 geometry_info.psi=argument_list[4].real_reference;
9680 if (attribute_flag[5] != 0)
9681 channel=(ChannelType) argument_list[5].integer_reference;
9682 channel_mask=SetImageChannelMask(image,channel);
9683 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9684 geometry_info.xi,geometry_info.psi,exception);
9685 if (image != (Image *) NULL)
9686 (void) SetImageChannelMask(image,channel_mask);
9687 break;
9688 }
9689 case 70: /* MotionBlur */
9690 {
9691 if (attribute_flag[0] != 0)
9692 {
9693 flags=ParseGeometry(argument_list[0].string_reference,
9694 &geometry_info);
9695 if ((flags & SigmaValue) == 0)
9696 geometry_info.sigma=1.0;
9697 if ((flags & XiValue) == 0)
9698 geometry_info.xi=1.0;
9699 }
9700 if (attribute_flag[1] != 0)
9701 geometry_info.rho=argument_list[1].real_reference;
9702 if (attribute_flag[2] != 0)
9703 geometry_info.sigma=argument_list[2].real_reference;
9704 if (attribute_flag[3] != 0)
9705 geometry_info.xi=argument_list[3].real_reference;
9706 if (attribute_flag[4] != 0)
9707 channel=(ChannelType) argument_list[4].integer_reference;
9708 channel_mask=SetImageChannelMask(image,channel);
9709 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9710 geometry_info.xi,exception);
9711 if (image != (Image *) NULL)
9712 (void) SetImageChannelMask(image,channel_mask);
9713 break;
9714 }
9715 case 71: /* OrderedDither */
9716 {
9717 if (attribute_flag[0] == 0)
9718 argument_list[0].string_reference="o8x8";
9719 if (attribute_flag[1] != 0)
9720 channel=(ChannelType) argument_list[1].integer_reference;
9721 channel_mask=SetImageChannelMask(image,channel);
9722 (void) OrderedPosterizeImage(image,argument_list[0].string_reference,
9723 exception);
9724 (void) SetImageChannelMask(image,channel_mask);
9725 break;
9726 }
9727 case 72: /* Shave */
9728 {
9729 if (attribute_flag[0] != 0)
9730 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9731 &geometry,exception);
9732 if (attribute_flag[1] != 0)
9733 geometry.width=argument_list[1].integer_reference;
9734 if (attribute_flag[2] != 0)
9735 geometry.height=argument_list[2].integer_reference;
9736 image=ShaveImage(image,&geometry,exception);
9737 break;
9738 }
9739 case 73: /* Level */
9740 {
9741 double
9742 black_point,
9743 gamma,
9744 white_point;
9745
9746 black_point=0.0;
9747 white_point=(double) image->columns*image->rows;
9748 gamma=1.0;
9749 if (attribute_flag[0] != 0)
9750 {
9751 flags=ParseGeometry(argument_list[0].string_reference,
9752 &geometry_info);
9753 black_point=geometry_info.rho;
9754 if ((flags & SigmaValue) != 0)
9755 white_point=geometry_info.sigma;
9756 if ((flags & XiValue) != 0)
9757 gamma=geometry_info.xi;
9758 if ((flags & PercentValue) != 0)
9759 {
9760 black_point*=(double) (QuantumRange/100.0);
9761 white_point*=(double) (QuantumRange/100.0);
9762 }
9763 if ((flags & SigmaValue) == 0)
9764 white_point=(double) QuantumRange-black_point;
9765 }
9766 if (attribute_flag[1] != 0)
9767 black_point=argument_list[1].real_reference;
9768 if (attribute_flag[2] != 0)
9769 white_point=argument_list[2].real_reference;
9770 if (attribute_flag[3] != 0)
9771 gamma=argument_list[3].real_reference;
9772 if (attribute_flag[4] != 0)
9773 channel=(ChannelType) argument_list[4].integer_reference;
9774 if (attribute_flag[5] != 0)
9775 {
9776 argument_list[0].real_reference=argument_list[5].real_reference;
9777 attribute_flag[0]=attribute_flag[5];
9778 }
9779 channel_mask=SetImageChannelMask(image,channel);
9780 (void) LevelImage(image,black_point,white_point,gamma,exception);
9781 (void) SetImageChannelMask(image,channel_mask);
9782 break;
9783 }
9784 case 74: /* Clip */
9785 {
9786 if (attribute_flag[0] == 0)
9787 argument_list[0].string_reference="#1";
9788 if (attribute_flag[1] == 0)
9789 argument_list[1].integer_reference=MagickTrue;
9790 (void) ClipImagePath(image,argument_list[0].string_reference,
9791 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9792 exception);
9793 break;
9794 }
9795 case 75: /* AffineTransform */
9796 {
9797 DrawInfo
9798 *draw_info;
9799
9800 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9801 (DrawInfo *) NULL);
9802 if (attribute_flag[0] != 0)
9803 {
9804 AV
9805 *av;
9806
9807 av=(AV *) argument_list[0].array_reference;
9808 if ((av_len(av) != 3) && (av_len(av) != 5))
9809 {
9810 ThrowPerlException(exception,OptionError,
9811 "affine matrix must have 4 or 6 elements",PackageName);
9812 goto PerlException;
9813 }
9814 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9815 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9816 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9817 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9818 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9819 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9820 {
9821 ThrowPerlException(exception,OptionError,
9822 "affine matrix is singular",PackageName);
9823 goto PerlException;
9824 }
9825 if (av_len(av) == 5)
9826 {
9827 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9828 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9829 }
9830 }
9831 for (j=1; j < 6; j++)
9832 {
9833 if (attribute_flag[j] == 0)
9834 continue;
9835 value=argument_list[j].string_reference;
9836 angle=argument_list[j].real_reference;
9837 current=draw_info->affine;
9838 GetAffineMatrix(&affine);
9839 switch (j)
9840 {
9841 case 1:
9842 {
9843 /*
9844 Translate.
9845 */
9846 flags=ParseGeometry(value,&geometry_info);
9847 affine.tx=geometry_info.xi;
9848 affine.ty=geometry_info.psi;
9849 if ((flags & PsiValue) == 0)
9850 affine.ty=affine.tx;
9851 break;
9852 }
9853 case 2:
9854 {
9855 /*
9856 Scale.
9857 */
9858 flags=ParseGeometry(value,&geometry_info);
9859 affine.sx=geometry_info.rho;
9860 affine.sy=geometry_info.sigma;
9861 if ((flags & SigmaValue) == 0)
9862 affine.sy=affine.sx;
9863 break;
9864 }
9865 case 3:
9866 {
9867 /*
9868 Rotate.
9869 */
9870 if (angle == 0.0)
9871 break;
9872 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9873 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9874 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9875 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9876 break;
9877 }
9878 case 4:
9879 {
9880 /*
9881 SkewX.
9882 */
9883 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9884 break;
9885 }
9886 case 5:
9887 {
9888 /*
9889 SkewY.
9890 */
9891 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9892 break;
9893 }
9894 }
9895 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9896 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9897 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9898 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9899 draw_info->affine.tx=
9900 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9901 draw_info->affine.ty=
9902 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9903 }
9904 if (attribute_flag[6] != 0)
9905 image->interpolate=(PixelInterpolateMethod)
9906 argument_list[6].integer_reference;
9907 if (attribute_flag[7] != 0)
9908 QueryColorCompliance(argument_list[7].string_reference,
9909 AllCompliance,&image->background_color,exception);
9910 image=AffineTransformImage(image,&draw_info->affine,exception);
9911 draw_info=DestroyDrawInfo(draw_info);
9912 break;
9913 }
9914 case 76: /* Difference */
9915 {
9916 if (attribute_flag[0] == 0)
9917 {
9918 ThrowPerlException(exception,OptionError,
9919 "ReferenceImageRequired",PackageName);
9920 goto PerlException;
9921 }
9922 if (attribute_flag[1] != 0)
9923 image->fuzz=StringToDoubleInterval(
9924 argument_list[1].string_reference,(double) QuantumRange+1.0);
9925 (void) IsImagesEqual(image,argument_list[0].image_reference,
9926 exception);
9927 break;
9928 }
9929 case 77: /* AdaptiveThreshold */
9930 {
9931 if (attribute_flag[0] != 0)
9932 {
9933 flags=ParseGeometry(argument_list[0].string_reference,
9934 &geometry_info);
9935 if ((flags & PercentValue) != 0)
9936 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9937 }
9938 if (attribute_flag[1] != 0)
9939 geometry_info.rho=argument_list[1].integer_reference;
9940 if (attribute_flag[2] != 0)
9941 geometry_info.sigma=argument_list[2].integer_reference;
9942 if (attribute_flag[3] != 0)
9943 geometry_info.xi=argument_list[3].integer_reference;;
9944 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9945 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9946 break;
9947 }
9948 case 78: /* Resample */
9949 {
9950 size_t
9951 height,
9952 width;
9953
9954 if (attribute_flag[0] != 0)
9955 {
9956 flags=ParseGeometry(argument_list[0].string_reference,
9957 &geometry_info);
9958 if ((flags & SigmaValue) == 0)
9959 geometry_info.sigma=geometry_info.rho;
9960 }
9961 if (attribute_flag[1] != 0)
9962 geometry_info.rho=argument_list[1].real_reference;
9963 if (attribute_flag[2] != 0)
9964 geometry_info.sigma=argument_list[2].real_reference;
9965 if (attribute_flag[3] == 0)
9966 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
9967 if (attribute_flag[4] == 0)
9968 SetImageArtifact(image,"filter:support",
9969 argument_list[4].string_reference);
9970 width=(size_t) (geometry_info.rho*image->columns/
9971 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
9972 height=(size_t) (geometry_info.sigma*image->rows/
9973 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
9974 image=ResizeImage(image,width,height,(FilterTypes)
9975 argument_list[3].integer_reference,exception);
9976 if (image != (Image *) NULL)
9977 {
9978 image->resolution.x=geometry_info.rho;
9979 image->resolution.y=geometry_info.sigma;
9980 }
9981 break;
9982 }
9983 case 79: /* Describe */
9984 {
9985 if (attribute_flag[0] == 0)
9986 argument_list[0].file_reference=(FILE *) NULL;
9987 if (attribute_flag[1] != 0)
9988 (void) SetImageArtifact(image,"identify:features",
9989 argument_list[1].string_reference);
9990 (void) IdentifyImage(image,argument_list[0].file_reference,
9991 MagickTrue,exception);
9992 break;
9993 }
9994 case 80: /* BlackThreshold */
9995 {
9996 if (attribute_flag[0] == 0)
9997 argument_list[0].string_reference="50%";
9998 if (attribute_flag[2] != 0)
9999 channel=(ChannelType) argument_list[2].integer_reference;
10000 channel_mask=SetImageChannelMask(image,channel);
10001 BlackThresholdImage(image,argument_list[0].string_reference,
10002 exception);
10003 (void) SetImageChannelMask(image,channel_mask);
10004 break;
10005 }
10006 case 81: /* WhiteThreshold */
10007 {
10008 if (attribute_flag[0] == 0)
10009 argument_list[0].string_reference="50%";
10010 if (attribute_flag[2] != 0)
10011 channel=(ChannelType) argument_list[2].integer_reference;
10012 channel_mask=SetImageChannelMask(image,channel);
10013 WhiteThresholdImage(image,argument_list[0].string_reference,
10014 exception);
10015 (void) SetImageChannelMask(image,channel_mask);
10016 break;
10017 }
cristy60c73c02014-03-25 12:09:58 +000010018 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010019 {
10020 if (attribute_flag[0] != 0)
10021 {
10022 flags=ParseGeometry(argument_list[0].string_reference,
10023 &geometry_info);
10024 }
10025 if (attribute_flag[1] != 0)
10026 geometry_info.rho=argument_list[1].real_reference;
10027 if (attribute_flag[2] != 0)
10028 channel=(ChannelType) argument_list[2].integer_reference;
10029 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010030 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010031 if (image != (Image *) NULL)
10032 (void) SetImageChannelMask(image,channel_mask);
10033 break;
10034 }
10035 case 83: /* Thumbnail */
10036 {
10037 if (attribute_flag[0] != 0)
10038 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10039 &geometry,exception);
10040 if (attribute_flag[1] != 0)
10041 geometry.width=argument_list[1].integer_reference;
10042 if (attribute_flag[2] != 0)
10043 geometry.height=argument_list[2].integer_reference;
10044 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10045 break;
10046 }
10047 case 84: /* Strip */
10048 {
10049 (void) StripImage(image,exception);
10050 break;
10051 }
10052 case 85: /* Tint */
10053 {
10054 PixelInfo
10055 tint;
10056
10057 GetPixelInfo(image,&tint);
10058 if (attribute_flag[0] != 0)
10059 (void) QueryColorCompliance(argument_list[0].string_reference,
10060 AllCompliance,&tint,exception);
10061 if (attribute_flag[1] == 0)
10062 argument_list[1].string_reference="100";
10063 image=TintImage(image,argument_list[1].string_reference,&tint,
10064 exception);
10065 break;
10066 }
10067 case 86: /* Channel */
10068 {
10069 if (attribute_flag[0] != 0)
10070 channel=(ChannelType) argument_list[0].integer_reference;
10071 image=SeparateImage(image,channel,exception);
10072 break;
10073 }
10074 case 87: /* Splice */
10075 {
cristy260bd762014-08-15 12:46:34 +000010076 if (attribute_flag[7] != 0)
10077 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010078 if (attribute_flag[0] != 0)
10079 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10080 &geometry,exception);
10081 if (attribute_flag[1] != 0)
10082 geometry.width=argument_list[1].integer_reference;
10083 if (attribute_flag[2] != 0)
10084 geometry.height=argument_list[2].integer_reference;
10085 if (attribute_flag[3] != 0)
10086 geometry.x=argument_list[3].integer_reference;
10087 if (attribute_flag[4] != 0)
10088 geometry.y=argument_list[4].integer_reference;
10089 if (attribute_flag[5] != 0)
10090 image->fuzz=StringToDoubleInterval(
10091 argument_list[5].string_reference,(double) QuantumRange+1.0);
10092 if (attribute_flag[6] != 0)
10093 (void) QueryColorCompliance(argument_list[6].string_reference,
10094 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010095 image=SpliceImage(image,&geometry,exception);
10096 break;
10097 }
10098 case 88: /* Posterize */
10099 {
10100 if (attribute_flag[0] == 0)
10101 argument_list[0].integer_reference=3;
10102 if (attribute_flag[1] == 0)
10103 argument_list[1].integer_reference=0;
10104 (void) PosterizeImage(image,argument_list[0].integer_reference,
10105 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10106 NoDitherMethod,exception);
10107 break;
10108 }
10109 case 89: /* Shadow */
10110 {
10111 if (attribute_flag[0] != 0)
10112 {
10113 flags=ParseGeometry(argument_list[0].string_reference,
10114 &geometry_info);
10115 if ((flags & SigmaValue) == 0)
10116 geometry_info.sigma=1.0;
10117 if ((flags & XiValue) == 0)
10118 geometry_info.xi=4.0;
10119 if ((flags & PsiValue) == 0)
10120 geometry_info.psi=4.0;
10121 }
10122 if (attribute_flag[1] != 0)
10123 geometry_info.rho=argument_list[1].real_reference;
10124 if (attribute_flag[2] != 0)
10125 geometry_info.sigma=argument_list[2].real_reference;
10126 if (attribute_flag[3] != 0)
10127 geometry_info.xi=argument_list[3].integer_reference;
10128 if (attribute_flag[4] != 0)
10129 geometry_info.psi=argument_list[4].integer_reference;
10130 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10131 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10132 ceil(geometry_info.psi-0.5),exception);
10133 break;
10134 }
10135 case 90: /* Identify */
10136 {
10137 if (attribute_flag[0] == 0)
10138 argument_list[0].file_reference=(FILE *) NULL;
10139 if (attribute_flag[1] != 0)
10140 (void) SetImageArtifact(image,"identify:features",
10141 argument_list[1].string_reference);
10142 if ((attribute_flag[2] != 0) &&
10143 (argument_list[2].integer_reference != 0))
10144 (void) SetImageArtifact(image,"identify:unique","true");
10145 (void) IdentifyImage(image,argument_list[0].file_reference,
10146 MagickTrue,exception);
10147 break;
10148 }
10149 case 91: /* SepiaTone */
10150 {
10151 if (attribute_flag[0] == 0)
10152 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10153 image=SepiaToneImage(image,argument_list[0].real_reference,
10154 exception);
10155 break;
10156 }
10157 case 92: /* SigmoidalContrast */
10158 {
10159 MagickBooleanType
10160 sharpen;
10161
10162 if (attribute_flag[0] != 0)
10163 {
10164 flags=ParseGeometry(argument_list[0].string_reference,
10165 &geometry_info);
10166 if ((flags & SigmaValue) == 0)
10167 geometry_info.sigma=QuantumRange/2.0;
10168 if ((flags & PercentValue) != 0)
10169 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10170 }
10171 if (attribute_flag[1] != 0)
10172 geometry_info.rho=argument_list[1].real_reference;
10173 if (attribute_flag[2] != 0)
10174 geometry_info.sigma=argument_list[2].real_reference;
10175 if (attribute_flag[3] != 0)
10176 channel=(ChannelType) argument_list[3].integer_reference;
10177 sharpen=MagickTrue;
10178 if (attribute_flag[4] != 0)
10179 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10180 MagickFalse;
10181 channel_mask=SetImageChannelMask(image,channel);
10182 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10183 geometry_info.sigma,exception);
10184 (void) SetImageChannelMask(image,channel_mask);
10185 break;
10186 }
10187 case 93: /* Extent */
10188 {
10189 if (attribute_flag[7] != 0)
10190 image->gravity=(GravityType) argument_list[7].integer_reference;
10191 if (attribute_flag[0] != 0)
10192 {
10193 int
10194 flags;
10195
10196 flags=ParseGravityGeometry(image,
10197 argument_list[0].string_reference,&geometry,exception);
10198 (void) flags;
10199 if (geometry.width == 0)
10200 geometry.width=image->columns;
10201 if (geometry.height == 0)
10202 geometry.height=image->rows;
10203 }
10204 if (attribute_flag[1] != 0)
10205 geometry.width=argument_list[1].integer_reference;
10206 if (attribute_flag[2] != 0)
10207 geometry.height=argument_list[2].integer_reference;
10208 if (attribute_flag[3] != 0)
10209 geometry.x=argument_list[3].integer_reference;
10210 if (attribute_flag[4] != 0)
10211 geometry.y=argument_list[4].integer_reference;
10212 if (attribute_flag[5] != 0)
10213 image->fuzz=StringToDoubleInterval(
10214 argument_list[5].string_reference,(double) QuantumRange+1.0);
10215 if (attribute_flag[6] != 0)
10216 (void) QueryColorCompliance(argument_list[6].string_reference,
10217 AllCompliance,&image->background_color,exception);
10218 image=ExtentImage(image,&geometry,exception);
10219 break;
10220 }
10221 case 94: /* Vignette */
10222 {
10223 if (attribute_flag[0] != 0)
10224 {
10225 flags=ParseGeometry(argument_list[0].string_reference,
10226 &geometry_info);
10227 if ((flags & SigmaValue) == 0)
10228 geometry_info.sigma=1.0;
10229 if ((flags & XiValue) == 0)
10230 geometry_info.xi=0.1*image->columns;
10231 if ((flags & PsiValue) == 0)
10232 geometry_info.psi=0.1*image->rows;
10233 }
10234 if (attribute_flag[1] != 0)
10235 geometry_info.rho=argument_list[1].real_reference;
10236 if (attribute_flag[2] != 0)
10237 geometry_info.sigma=argument_list[2].real_reference;
10238 if (attribute_flag[3] != 0)
10239 geometry_info.xi=argument_list[3].integer_reference;
10240 if (attribute_flag[4] != 0)
10241 geometry_info.psi=argument_list[4].integer_reference;
10242 if (attribute_flag[5] != 0)
10243 (void) QueryColorCompliance(argument_list[5].string_reference,
10244 AllCompliance,&image->background_color,exception);
10245 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10246 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10247 ceil(geometry_info.psi-0.5),exception);
10248 break;
10249 }
10250 case 95: /* ContrastStretch */
10251 {
10252 double
10253 black_point,
10254 white_point;
10255
10256 black_point=0.0;
10257 white_point=(double) image->columns*image->rows;
10258 if (attribute_flag[0] != 0)
10259 {
10260 flags=ParseGeometry(argument_list[0].string_reference,
10261 &geometry_info);
10262 black_point=geometry_info.rho;
10263 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10264 black_point;
10265 if ((flags & PercentValue) != 0)
10266 {
10267 black_point*=(double) image->columns*image->rows/100.0;
10268 white_point*=(double) image->columns*image->rows/100.0;
10269 }
10270 white_point=(double) image->columns*image->rows-
10271 white_point;
10272 }
10273 if (attribute_flag[1] != 0)
10274 black_point=argument_list[1].real_reference;
10275 if (attribute_flag[2] != 0)
10276 white_point=argument_list[2].real_reference;
10277 if (attribute_flag[4] != 0)
10278 channel=(ChannelType) argument_list[4].integer_reference;
10279 channel_mask=SetImageChannelMask(image,channel);
10280 (void) ContrastStretchImage(image,black_point,white_point,exception);
10281 (void) SetImageChannelMask(image,channel_mask);
10282 break;
10283 }
10284 case 96: /* Sans0 */
10285 {
10286 break;
10287 }
10288 case 97: /* Sans1 */
10289 {
10290 break;
10291 }
10292 case 98: /* AdaptiveSharpen */
10293 {
10294 if (attribute_flag[0] != 0)
10295 {
10296 flags=ParseGeometry(argument_list[0].string_reference,
10297 &geometry_info);
10298 if ((flags & SigmaValue) == 0)
10299 geometry_info.sigma=1.0;
10300 if ((flags & XiValue) == 0)
10301 geometry_info.xi=0.0;
10302 }
10303 if (attribute_flag[1] != 0)
10304 geometry_info.rho=argument_list[1].real_reference;
10305 if (attribute_flag[2] != 0)
10306 geometry_info.sigma=argument_list[2].real_reference;
10307 if (attribute_flag[3] != 0)
10308 geometry_info.xi=argument_list[3].real_reference;
10309 if (attribute_flag[4] != 0)
10310 channel=(ChannelType) argument_list[4].integer_reference;
10311 channel_mask=SetImageChannelMask(image,channel);
10312 image=AdaptiveSharpenImage(image,geometry_info.rho,
10313 geometry_info.sigma,exception);
10314 if (image != (Image *) NULL)
10315 (void) SetImageChannelMask(image,channel_mask);
10316 break;
10317 }
10318 case 99: /* Transpose */
10319 {
10320 image=TransposeImage(image,exception);
10321 break;
10322 }
10323 case 100: /* Tranverse */
10324 {
10325 image=TransverseImage(image,exception);
10326 break;
10327 }
10328 case 101: /* AutoOrient */
10329 {
10330 image=AutoOrientImage(image,image->orientation,exception);
10331 break;
10332 }
10333 case 102: /* AdaptiveBlur */
10334 {
10335 if (attribute_flag[0] != 0)
10336 {
10337 flags=ParseGeometry(argument_list[0].string_reference,
10338 &geometry_info);
10339 if ((flags & SigmaValue) == 0)
10340 geometry_info.sigma=1.0;
10341 if ((flags & XiValue) == 0)
10342 geometry_info.xi=0.0;
10343 }
10344 if (attribute_flag[1] != 0)
10345 geometry_info.rho=argument_list[1].real_reference;
10346 if (attribute_flag[2] != 0)
10347 geometry_info.sigma=argument_list[2].real_reference;
10348 if (attribute_flag[3] != 0)
10349 channel=(ChannelType) argument_list[3].integer_reference;
10350 channel_mask=SetImageChannelMask(image,channel);
10351 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10352 exception);
10353 if (image != (Image *) NULL)
10354 (void) SetImageChannelMask(image,channel_mask);
10355 break;
10356 }
10357 case 103: /* Sketch */
10358 {
10359 if (attribute_flag[0] != 0)
10360 {
10361 flags=ParseGeometry(argument_list[0].string_reference,
10362 &geometry_info);
10363 if ((flags & SigmaValue) == 0)
10364 geometry_info.sigma=1.0;
10365 if ((flags & XiValue) == 0)
10366 geometry_info.xi=1.0;
10367 }
10368 if (attribute_flag[1] != 0)
10369 geometry_info.rho=argument_list[1].real_reference;
10370 if (attribute_flag[2] != 0)
10371 geometry_info.sigma=argument_list[2].real_reference;
10372 if (attribute_flag[3] != 0)
10373 geometry_info.xi=argument_list[3].real_reference;
10374 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10375 geometry_info.xi,exception);
10376 break;
10377 }
10378 case 104: /* UniqueColors */
10379 {
10380 image=UniqueImageColors(image,exception);
10381 break;
10382 }
10383 case 105: /* AdaptiveResize */
10384 {
10385 if (attribute_flag[0] != 0)
10386 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10387 &geometry,exception);
10388 if (attribute_flag[1] != 0)
10389 geometry.width=argument_list[1].integer_reference;
10390 if (attribute_flag[2] != 0)
10391 geometry.height=argument_list[2].integer_reference;
10392 if (attribute_flag[3] != 0)
10393 image->filter=(FilterTypes) argument_list[4].integer_reference;
10394 if (attribute_flag[4] != 0)
10395 SetImageArtifact(image,"filter:support",
10396 argument_list[4].string_reference);
10397 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10398 exception);
10399 break;
10400 }
10401 case 106: /* ClipMask */
10402 {
10403 Image
10404 *mask_image;
10405
10406 if (attribute_flag[0] == 0)
10407 {
10408 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10409 PackageName);
10410 goto PerlException;
10411 }
10412 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10413 exception);
10414 (void) SetImageMask(image,mask_image,exception);
10415 mask_image=DestroyImage(mask_image);
10416 break;
10417 }
10418 case 107: /* LinearStretch */
10419 {
10420 double
10421 black_point,
10422 white_point;
10423
10424 black_point=0.0;
10425 white_point=(double) image->columns*image->rows;
10426 if (attribute_flag[0] != 0)
10427 {
10428 flags=ParseGeometry(argument_list[0].string_reference,
10429 &geometry_info);
10430 if ((flags & SigmaValue) != 0)
10431 white_point=geometry_info.sigma;
10432 if ((flags & PercentValue) != 0)
10433 {
10434 black_point*=(double) image->columns*image->rows/100.0;
10435 white_point*=(double) image->columns*image->rows/100.0;
10436 }
10437 if ((flags & SigmaValue) == 0)
10438 white_point=(double) image->columns*image->rows-black_point;
10439 }
10440 if (attribute_flag[1] != 0)
10441 black_point=argument_list[1].real_reference;
10442 if (attribute_flag[2] != 0)
10443 white_point=argument_list[2].real_reference;
10444 (void) LinearStretchImage(image,black_point,white_point,exception);
10445 break;
10446 }
10447 case 108: /* ColorMatrix */
10448 {
10449 AV
10450 *av;
10451
10452 double
10453 *color_matrix;
10454
10455 KernelInfo
10456 *kernel_info;
10457
10458 size_t
10459 order;
10460
10461 if (attribute_flag[0] == 0)
10462 break;
10463 av=(AV *) argument_list[0].array_reference;
10464 order=(size_t) sqrt(av_len(av)+1);
10465 color_matrix=(double *) AcquireQuantumMemory(order,order*
10466 sizeof(*color_matrix));
10467 if (color_matrix == (double *) NULL)
10468 {
10469 ThrowPerlException(exception,ResourceLimitFatalError,
10470 "MemoryAllocationFailed",PackageName);
10471 goto PerlException;
10472 }
10473 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10474 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10475 for ( ; j < (ssize_t) (order*order); j++)
10476 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010477 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010478 if (kernel_info == (KernelInfo *) NULL)
10479 break;
10480 kernel_info->width=order;
10481 kernel_info->height=order;
10482 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10483 order*sizeof(*kernel_info->values));
10484 if (kernel_info->values != (MagickRealType *) NULL)
10485 {
10486 for (i=0; i < (ssize_t) (order*order); i++)
10487 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10488 image=ColorMatrixImage(image,kernel_info,exception);
10489 }
10490 kernel_info=DestroyKernelInfo(kernel_info);
10491 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10492 break;
10493 }
10494 case 109: /* Mask */
10495 {
10496 Image
10497 *mask_image;
10498
10499 if (attribute_flag[0] == 0)
10500 {
10501 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10502 PackageName);
10503 goto PerlException;
10504 }
10505 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10506 MagickTrue,exception);
10507 (void) SetImageMask(image,mask_image,exception);
10508 mask_image=DestroyImage(mask_image);
10509 break;
10510 }
10511 case 110: /* Polaroid */
10512 {
10513 char
10514 *caption;
10515
10516 DrawInfo
10517 *draw_info;
10518
10519 double
10520 angle;
10521
10522 PixelInterpolateMethod
10523 method;
10524
10525 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10526 (DrawInfo *) NULL);
10527 caption=(char *) NULL;
10528 if (attribute_flag[0] != 0)
10529 caption=InterpretImageProperties(info ? info->image_info :
10530 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10531 exception);
10532 angle=0.0;
10533 if (attribute_flag[1] != 0)
10534 angle=argument_list[1].real_reference;
10535 if (attribute_flag[2] != 0)
10536 (void) CloneString(&draw_info->font,
10537 argument_list[2].string_reference);
10538 if (attribute_flag[3] != 0)
10539 (void) QueryColorCompliance(argument_list[3].string_reference,
10540 AllCompliance,&draw_info->stroke,exception);
10541 if (attribute_flag[4] != 0)
10542 (void) QueryColorCompliance(argument_list[4].string_reference,
10543 AllCompliance,&draw_info->fill,exception);
10544 if (attribute_flag[5] != 0)
10545 draw_info->stroke_width=argument_list[5].real_reference;
10546 if (attribute_flag[6] != 0)
10547 draw_info->pointsize=argument_list[6].real_reference;
10548 if (attribute_flag[7] != 0)
10549 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10550 if (attribute_flag[8] != 0)
10551 (void) QueryColorCompliance(argument_list[8].string_reference,
10552 AllCompliance,&image->background_color,exception);
10553 method=UndefinedInterpolatePixel;
10554 if (attribute_flag[9] != 0)
10555 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10556 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10557 draw_info=DestroyDrawInfo(draw_info);
10558 if (caption != (char *) NULL)
10559 caption=DestroyString(caption);
10560 break;
10561 }
10562 case 111: /* FloodfillPaint */
10563 {
10564 DrawInfo
10565 *draw_info;
10566
10567 MagickBooleanType
10568 invert;
10569
10570 PixelInfo
10571 target;
10572
10573 draw_info=CloneDrawInfo(info ? info->image_info :
10574 (ImageInfo *) NULL,(DrawInfo *) NULL);
10575 if (attribute_flag[0] != 0)
10576 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10577 &geometry,exception);
10578 if (attribute_flag[1] != 0)
10579 geometry.x=argument_list[1].integer_reference;
10580 if (attribute_flag[2] != 0)
10581 geometry.y=argument_list[2].integer_reference;
10582 if (attribute_flag[3] != 0)
10583 (void) QueryColorCompliance(argument_list[3].string_reference,
10584 AllCompliance,&draw_info->fill,exception);
10585 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10586 geometry.x,geometry.y,&target,exception);
10587 if (attribute_flag[4] != 0)
10588 QueryColorCompliance(argument_list[4].string_reference,
10589 AllCompliance,&target,exception);
10590 if (attribute_flag[5] != 0)
10591 image->fuzz=StringToDoubleInterval(
10592 argument_list[5].string_reference,(double) QuantumRange+1.0);
10593 if (attribute_flag[6] != 0)
10594 channel=(ChannelType) argument_list[6].integer_reference;
10595 invert=MagickFalse;
10596 if (attribute_flag[7] != 0)
10597 invert=(MagickBooleanType) argument_list[7].integer_reference;
10598 channel_mask=SetImageChannelMask(image,channel);
10599 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10600 geometry.y,invert,exception);
10601 (void) SetImageChannelMask(image,channel_mask);
10602 draw_info=DestroyDrawInfo(draw_info);
10603 break;
10604 }
10605 case 112: /* Distort */
10606 {
10607 AV
10608 *av;
10609
10610 double
10611 *coordinates;
10612
10613 DistortImageMethod
10614 method;
10615
10616 size_t
10617 number_coordinates;
10618
10619 VirtualPixelMethod
10620 virtual_pixel;
10621
10622 if (attribute_flag[0] == 0)
10623 break;
10624 method=UndefinedDistortion;
10625 if (attribute_flag[1] != 0)
10626 method=(DistortImageMethod) argument_list[1].integer_reference;
10627 av=(AV *) argument_list[0].array_reference;
10628 number_coordinates=(size_t) av_len(av)+1;
10629 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10630 sizeof(*coordinates));
10631 if (coordinates == (double *) NULL)
10632 {
10633 ThrowPerlException(exception,ResourceLimitFatalError,
10634 "MemoryAllocationFailed",PackageName);
10635 goto PerlException;
10636 }
10637 for (j=0; j < (ssize_t) number_coordinates; j++)
10638 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10639 virtual_pixel=UndefinedVirtualPixelMethod;
10640 if (attribute_flag[2] != 0)
10641 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10642 argument_list[2].integer_reference,exception);
10643 image=DistortImage(image,method,number_coordinates,coordinates,
10644 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10645 exception);
10646 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10647 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10648 exception);
10649 coordinates=(double *) RelinquishMagickMemory(coordinates);
10650 break;
10651 }
10652 case 113: /* Clut */
10653 {
10654 PixelInterpolateMethod
10655 method;
10656
10657 if (attribute_flag[0] == 0)
10658 {
10659 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10660 PackageName);
10661 goto PerlException;
10662 }
10663 method=UndefinedInterpolatePixel;
10664 if (attribute_flag[1] != 0)
10665 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10666 if (attribute_flag[2] != 0)
10667 channel=(ChannelType) argument_list[2].integer_reference;
10668 channel_mask=SetImageChannelMask(image,channel);
10669 (void) ClutImage(image,argument_list[0].image_reference,method,
10670 exception);
10671 (void) SetImageChannelMask(image,channel_mask);
10672 break;
10673 }
10674 case 114: /* LiquidRescale */
10675 {
10676 if (attribute_flag[0] != 0)
10677 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10678 &geometry,exception);
10679 if (attribute_flag[1] != 0)
10680 geometry.width=argument_list[1].integer_reference;
10681 if (attribute_flag[2] != 0)
10682 geometry.height=argument_list[2].integer_reference;
10683 if (attribute_flag[3] == 0)
10684 argument_list[3].real_reference=1.0;
10685 if (attribute_flag[4] == 0)
10686 argument_list[4].real_reference=0.0;
10687 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10688 argument_list[3].real_reference,argument_list[4].real_reference,
10689 exception);
10690 break;
10691 }
10692 case 115: /* EncipherImage */
10693 {
10694 (void) EncipherImage(image,argument_list[0].string_reference,
10695 exception);
10696 break;
10697 }
10698 case 116: /* DecipherImage */
10699 {
10700 (void) DecipherImage(image,argument_list[0].string_reference,
10701 exception);
10702 break;
10703 }
10704 case 117: /* Deskew */
10705 {
10706 geometry_info.rho=QuantumRange/2.0;
10707 if (attribute_flag[0] != 0)
10708 flags=ParseGeometry(argument_list[0].string_reference,
10709 &geometry_info);
10710 if (attribute_flag[1] != 0)
10711 geometry_info.rho=StringToDoubleInterval(
10712 argument_list[1].string_reference,(double) QuantumRange+1.0);
10713 image=DeskewImage(image,geometry_info.rho,exception);
10714 break;
10715 }
10716 case 118: /* Remap */
10717 {
10718 QuantizeInfo
10719 *quantize_info;
10720
10721 if (attribute_flag[0] == 0)
10722 {
10723 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10724 PackageName);
10725 goto PerlException;
10726 }
10727 quantize_info=AcquireQuantizeInfo(info->image_info);
10728 if (attribute_flag[1] != 0)
10729 quantize_info->dither_method=(DitherMethod)
10730 argument_list[1].integer_reference;
10731 (void) RemapImages(quantize_info,image,
10732 argument_list[0].image_reference,exception);
10733 quantize_info=DestroyQuantizeInfo(quantize_info);
10734 break;
10735 }
10736 case 119: /* SparseColor */
10737 {
10738 AV
10739 *av;
10740
10741 double
10742 *coordinates;
10743
10744 SparseColorMethod
10745 method;
10746
10747 size_t
10748 number_coordinates;
10749
10750 VirtualPixelMethod
10751 virtual_pixel;
10752
10753 if (attribute_flag[0] == 0)
10754 break;
10755 method=UndefinedColorInterpolate;
10756 if (attribute_flag[1] != 0)
10757 method=(SparseColorMethod) argument_list[1].integer_reference;
10758 av=(AV *) argument_list[0].array_reference;
10759 number_coordinates=(size_t) av_len(av)+1;
10760 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10761 sizeof(*coordinates));
10762 if (coordinates == (double *) NULL)
10763 {
10764 ThrowPerlException(exception,ResourceLimitFatalError,
10765 "MemoryAllocationFailed",PackageName);
10766 goto PerlException;
10767 }
10768 for (j=0; j < (ssize_t) number_coordinates; j++)
10769 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10770 virtual_pixel=UndefinedVirtualPixelMethod;
10771 if (attribute_flag[2] != 0)
10772 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10773 argument_list[2].integer_reference,exception);
10774 if (attribute_flag[3] != 0)
10775 channel=(ChannelType) argument_list[3].integer_reference;
10776 channel_mask=SetImageChannelMask(image,channel);
10777 image=SparseColorImage(image,method,number_coordinates,coordinates,
10778 exception);
10779 if (image != (Image *) NULL)
10780 (void) SetImageChannelMask(image,channel_mask);
10781 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10782 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10783 exception);
10784 coordinates=(double *) RelinquishMagickMemory(coordinates);
10785 break;
10786 }
10787 case 120: /* Function */
10788 {
10789 AV
10790 *av;
10791
10792 double
10793 *parameters;
10794
10795 MagickFunction
10796 function;
10797
10798 size_t
10799 number_parameters;
10800
10801 VirtualPixelMethod
10802 virtual_pixel;
10803
10804 if (attribute_flag[0] == 0)
10805 break;
10806 function=UndefinedFunction;
10807 if (attribute_flag[1] != 0)
10808 function=(MagickFunction) argument_list[1].integer_reference;
10809 av=(AV *) argument_list[0].array_reference;
10810 number_parameters=(size_t) av_len(av)+1;
10811 parameters=(double *) AcquireQuantumMemory(number_parameters,
10812 sizeof(*parameters));
10813 if (parameters == (double *) NULL)
10814 {
10815 ThrowPerlException(exception,ResourceLimitFatalError,
10816 "MemoryAllocationFailed",PackageName);
10817 goto PerlException;
10818 }
10819 for (j=0; j < (ssize_t) number_parameters; j++)
10820 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10821 virtual_pixel=UndefinedVirtualPixelMethod;
10822 if (attribute_flag[2] != 0)
10823 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10824 argument_list[2].integer_reference,exception);
10825 (void) FunctionImage(image,function,number_parameters,parameters,
10826 exception);
10827 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10828 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10829 exception);
10830 parameters=(double *) RelinquishMagickMemory(parameters);
10831 break;
10832 }
10833 case 121: /* SelectiveBlur */
10834 {
10835 if (attribute_flag[0] != 0)
10836 {
10837 flags=ParseGeometry(argument_list[0].string_reference,
10838 &geometry_info);
10839 if ((flags & SigmaValue) == 0)
10840 geometry_info.sigma=1.0;
10841 if ((flags & PercentValue) != 0)
10842 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10843 }
10844 if (attribute_flag[1] != 0)
10845 geometry_info.rho=argument_list[1].real_reference;
10846 if (attribute_flag[2] != 0)
10847 geometry_info.sigma=argument_list[2].real_reference;
10848 if (attribute_flag[3] != 0)
10849 geometry_info.xi=argument_list[3].integer_reference;;
10850 if (attribute_flag[5] != 0)
10851 channel=(ChannelType) argument_list[5].integer_reference;
10852 channel_mask=SetImageChannelMask(image,channel);
10853 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10854 geometry_info.xi,exception);
10855 if (image != (Image *) NULL)
10856 (void) SetImageChannelMask(image,channel_mask);
10857 break;
10858 }
10859 case 122: /* HaldClut */
10860 {
10861 if (attribute_flag[0] == 0)
10862 {
10863 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10864 PackageName);
10865 goto PerlException;
10866 }
10867 if (attribute_flag[1] != 0)
10868 channel=(ChannelType) argument_list[1].integer_reference;
10869 channel_mask=SetImageChannelMask(image,channel);
10870 (void) HaldClutImage(image,argument_list[0].image_reference,
10871 exception);
10872 (void) SetImageChannelMask(image,channel_mask);
10873 break;
10874 }
10875 case 123: /* BlueShift */
10876 {
10877 if (attribute_flag[0] != 0)
10878 (void) ParseGeometry(argument_list[0].string_reference,
10879 &geometry_info);
10880 image=BlueShiftImage(image,geometry_info.rho,exception);
10881 break;
10882 }
10883 case 124: /* ForwardFourierTransformImage */
10884 {
10885 image=ForwardFourierTransformImage(image,
10886 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10887 exception);
10888 break;
10889 }
10890 case 125: /* InverseFourierTransformImage */
10891 {
10892 image=InverseFourierTransformImage(image,image->next,
10893 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10894 exception);
10895 break;
10896 }
10897 case 126: /* ColorDecisionList */
10898 {
10899 if (attribute_flag[0] == 0)
10900 argument_list[0].string_reference=(char *) NULL;
10901 (void) ColorDecisionListImage(image,
10902 argument_list[0].string_reference,exception);
10903 break;
10904 }
10905 case 127: /* AutoGamma */
10906 {
10907 if (attribute_flag[0] != 0)
10908 channel=(ChannelType) argument_list[0].integer_reference;
10909 channel_mask=SetImageChannelMask(image,channel);
10910 (void) AutoGammaImage(image,exception);
10911 (void) SetImageChannelMask(image,channel_mask);
10912 break;
10913 }
10914 case 128: /* AutoLevel */
10915 {
10916 if (attribute_flag[0] != 0)
10917 channel=(ChannelType) argument_list[0].integer_reference;
10918 channel_mask=SetImageChannelMask(image,channel);
10919 (void) AutoLevelImage(image,exception);
10920 (void) SetImageChannelMask(image,channel_mask);
10921 break;
10922 }
10923 case 129: /* LevelColors */
10924 {
10925 PixelInfo
10926 black_point,
10927 white_point;
10928
10929 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10930 exception);
10931 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10932 exception);
10933 if (attribute_flag[1] != 0)
10934 (void) QueryColorCompliance(
10935 argument_list[1].string_reference,AllCompliance,&black_point,
10936 exception);
10937 if (attribute_flag[2] != 0)
10938 (void) QueryColorCompliance(
10939 argument_list[2].string_reference,AllCompliance,&white_point,
10940 exception);
10941 if (attribute_flag[3] != 0)
10942 channel=(ChannelType) argument_list[3].integer_reference;
10943 channel_mask=SetImageChannelMask(image,channel);
10944 (void) LevelImageColors(image,&black_point,&white_point,
10945 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10946 exception);
10947 (void) SetImageChannelMask(image,channel_mask);
10948 break;
10949 }
10950 case 130: /* Clamp */
10951 {
10952 if (attribute_flag[0] != 0)
10953 channel=(ChannelType) argument_list[0].integer_reference;
10954 channel_mask=SetImageChannelMask(image,channel);
10955 (void) ClampImage(image,exception);
10956 (void) SetImageChannelMask(image,channel_mask);
10957 break;
10958 }
10959 case 131: /* BrightnessContrast */
10960 {
10961 double
10962 brightness,
10963 contrast;
10964
10965 brightness=0.0;
10966 contrast=0.0;
10967 if (attribute_flag[0] != 0)
10968 {
10969 flags=ParseGeometry(argument_list[0].string_reference,
10970 &geometry_info);
10971 brightness=geometry_info.rho;
10972 if ((flags & SigmaValue) == 0)
10973 contrast=geometry_info.sigma;
10974 }
10975 if (attribute_flag[1] != 0)
10976 brightness=argument_list[1].real_reference;
10977 if (attribute_flag[2] != 0)
10978 contrast=argument_list[2].real_reference;
10979 if (attribute_flag[4] != 0)
10980 channel=(ChannelType) argument_list[4].integer_reference;
10981 channel_mask=SetImageChannelMask(image,channel);
10982 (void) BrightnessContrastImage(image,brightness,contrast,exception);
10983 (void) SetImageChannelMask(image,channel_mask);
10984 break;
10985 }
10986 case 132: /* Morphology */
10987 {
10988 KernelInfo
10989 *kernel;
10990
10991 MorphologyMethod
10992 method;
10993
10994 ssize_t
10995 iterations;
10996
10997 if (attribute_flag[0] == 0)
10998 break;
cristy2c57b742014-10-31 00:40:34 +000010999 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011000 if (kernel == (KernelInfo *) NULL)
11001 break;
11002 if (attribute_flag[1] != 0)
11003 channel=(ChannelType) argument_list[1].integer_reference;
11004 method=UndefinedMorphology;
11005 if (attribute_flag[2] != 0)
11006 method=argument_list[2].integer_reference;
11007 iterations=1;
11008 if (attribute_flag[3] != 0)
11009 iterations=argument_list[3].integer_reference;
11010 channel_mask=SetImageChannelMask(image,channel);
11011 image=MorphologyImage(image,method,iterations,kernel,exception);
11012 if (image != (Image *) NULL)
11013 (void) SetImageChannelMask(image,channel_mask);
11014 kernel=DestroyKernelInfo(kernel);
11015 break;
11016 }
11017 case 133: /* Mode */
11018 {
11019 if (attribute_flag[0] != 0)
11020 {
11021 flags=ParseGeometry(argument_list[0].string_reference,
11022 &geometry_info);
11023 if ((flags & SigmaValue) == 0)
11024 geometry_info.sigma=1.0;
11025 }
11026 if (attribute_flag[1] != 0)
11027 geometry_info.rho=argument_list[1].real_reference;
11028 if (attribute_flag[2] != 0)
11029 geometry_info.sigma=argument_list[2].real_reference;
11030 if (attribute_flag[3] != 0)
11031 channel=(ChannelType) argument_list[3].integer_reference;
11032 channel_mask=SetImageChannelMask(image,channel);
11033 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11034 (size_t) geometry_info.sigma,exception);
11035 if (image != (Image *) NULL)
11036 (void) SetImageChannelMask(image,channel_mask);
11037 break;
11038 }
11039 case 134: /* Statistic */
11040 {
11041 StatisticType
11042 statistic;
11043
11044 statistic=UndefinedStatistic;
11045 if (attribute_flag[0] != 0)
11046 {
11047 flags=ParseGeometry(argument_list[0].string_reference,
11048 &geometry_info);
11049 if ((flags & SigmaValue) == 0)
11050 geometry_info.sigma=1.0;
11051 }
11052 if (attribute_flag[1] != 0)
11053 geometry_info.rho=argument_list[1].real_reference;
11054 if (attribute_flag[2] != 0)
11055 geometry_info.sigma=argument_list[2].real_reference;
11056 if (attribute_flag[3] != 0)
11057 channel=(ChannelType) argument_list[3].integer_reference;
11058 if (attribute_flag[4] != 0)
11059 statistic=(StatisticType) argument_list[4].integer_reference;
11060 channel_mask=SetImageChannelMask(image,channel);
11061 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11062 (size_t) geometry_info.sigma,exception);
11063 if (image != (Image *) NULL)
11064 (void) SetImageChannelMask(image,channel_mask);
11065 break;
11066 }
11067 case 135: /* Perceptible */
11068 {
11069 double
11070 epsilon;
11071
11072 epsilon=MagickEpsilon;
11073 if (attribute_flag[0] != 0)
11074 epsilon=argument_list[0].real_reference;
11075 if (attribute_flag[1] != 0)
11076 channel=(ChannelType) argument_list[1].integer_reference;
11077 channel_mask=SetImageChannelMask(image,channel);
11078 (void) PerceptibleImage(image,epsilon,exception);
11079 (void) SetImageChannelMask(image,channel_mask);
11080 break;
11081 }
11082 case 136: /* Poly */
11083 {
11084 AV
11085 *av;
11086
11087 double
11088 *terms;
11089
11090 size_t
11091 number_terms;
11092
11093 if (attribute_flag[0] == 0)
11094 break;
11095 if (attribute_flag[1] != 0)
11096 channel=(ChannelType) argument_list[1].integer_reference;
11097 av=(AV *) argument_list[0].array_reference;
11098 number_terms=(size_t) av_len(av);
11099 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11100 if (terms == (double *) NULL)
11101 {
11102 ThrowPerlException(exception,ResourceLimitFatalError,
11103 "MemoryAllocationFailed",PackageName);
11104 goto PerlException;
11105 }
11106 for (j=0; j < av_len(av); j++)
11107 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11108 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11109 terms=(double *) RelinquishMagickMemory(terms);
11110 break;
11111 }
11112 case 137: /* Grayscale */
11113 {
11114 PixelIntensityMethod
11115 method;
11116
11117 method=UndefinedPixelIntensityMethod;
11118 if (attribute_flag[0] != 0)
11119 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11120 (void) GrayscaleImage(image,method,exception);
11121 break;
11122 }
cristy4ceadb82014-03-29 15:30:43 +000011123 case 138: /* Canny */
11124 {
11125 if (attribute_flag[0] != 0)
11126 {
11127 flags=ParseGeometry(argument_list[0].string_reference,
11128 &geometry_info);
11129 if ((flags & SigmaValue) == 0)
11130 geometry_info.sigma=1.0;
11131 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011132 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011133 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011134 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011135 if ((flags & PercentValue) != 0)
11136 {
11137 geometry_info.xi/=100.0;
11138 geometry_info.psi/=100.0;
11139 }
cristy4ceadb82014-03-29 15:30:43 +000011140 }
11141 if (attribute_flag[1] != 0)
11142 geometry_info.rho=argument_list[1].real_reference;
11143 if (attribute_flag[2] != 0)
11144 geometry_info.sigma=argument_list[2].real_reference;
11145 if (attribute_flag[3] != 0)
11146 geometry_info.xi=argument_list[3].real_reference;
11147 if (attribute_flag[4] != 0)
11148 geometry_info.psi=argument_list[4].real_reference;
11149 if (attribute_flag[5] != 0)
11150 channel=(ChannelType) argument_list[5].integer_reference;
11151 channel_mask=SetImageChannelMask(image,channel);
11152 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11153 geometry_info.xi,geometry_info.psi,exception);
11154 if (image != (Image *) NULL)
11155 (void) SetImageChannelMask(image,channel_mask);
11156 break;
11157 }
cristy2fc10e52014-04-26 14:13:53 +000011158 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011159 {
11160 if (attribute_flag[0] != 0)
11161 {
11162 flags=ParseGeometry(argument_list[0].string_reference,
11163 &geometry_info);
11164 if ((flags & SigmaValue) == 0)
11165 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011166 if ((flags & XiValue) == 0)
11167 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011168 }
11169 if (attribute_flag[1] != 0)
11170 geometry_info.rho=(double) argument_list[1].integer_reference;
11171 if (attribute_flag[2] != 0)
11172 geometry_info.sigma=(double) argument_list[2].integer_reference;
11173 if (attribute_flag[3] != 0)
11174 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011175 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11176 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11177 break;
11178 }
11179 case 140: /* MeanShift */
11180 {
11181 if (attribute_flag[0] != 0)
11182 {
11183 flags=ParseGeometry(argument_list[0].string_reference,
11184 &geometry_info);
11185 if ((flags & SigmaValue) == 0)
11186 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011187 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011188 geometry_info.xi=0.10*QuantumRange;
11189 if ((flags & PercentValue) != 0)
11190 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011191 }
11192 if (attribute_flag[1] != 0)
11193 geometry_info.rho=(double) argument_list[1].integer_reference;
11194 if (attribute_flag[2] != 0)
11195 geometry_info.sigma=(double) argument_list[2].integer_reference;
11196 if (attribute_flag[3] != 0)
11197 geometry_info.xi=(double) argument_list[3].integer_reference;
11198 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011199 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011200 break;
11201 }
cristy3b207f82014-09-27 14:21:20 +000011202 case 141: /* Kuwahara */
11203 {
11204 if (attribute_flag[0] != 0)
11205 {
11206 flags=ParseGeometry(argument_list[0].string_reference,
11207 &geometry_info);
11208 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011209 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011210 }
11211 if (attribute_flag[1] != 0)
11212 geometry_info.rho=argument_list[1].real_reference;
11213 if (attribute_flag[2] != 0)
11214 geometry_info.sigma=argument_list[2].real_reference;
11215 if (attribute_flag[3] != 0)
11216 channel=(ChannelType) argument_list[3].integer_reference;
11217 channel_mask=SetImageChannelMask(image,channel);
11218 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11219 exception);
11220 if (image != (Image *) NULL)
11221 (void) SetImageChannelMask(image,channel_mask);
11222 break;
11223 }
cristy6e0b3bc2014-10-19 17:51:42 +000011224 case 142: /* ConnectedComponent */
11225 {
11226 size_t
11227 connectivity;
11228
11229 connectivity=4;
11230 if (attribute_flag[0] != 0)
11231 connectivity=argument_list[0].integer_reference;
11232 image=ConnectedComponentsImage(image,connectivity,exception);
11233 break;
11234 }
cristy4a3ce0a2013-08-03 20:06:59 +000011235 }
11236 if (next != (Image *) NULL)
11237 (void) CatchImageException(next);
11238 if (region_image != (Image *) NULL)
11239 {
11240 /*
11241 Composite region.
cristy83a28a02013-08-03 20:25:48 +000011242 */
cristy4a3ce0a2013-08-03 20:06:59 +000011243 status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11244 region_info.x,region_info.y,exception);
11245 (void) status;
11246 (void) CatchImageException(region_image);
11247 image=DestroyImage(image);
11248 image=region_image;
11249 }
11250 if (image != (Image *) NULL)
11251 {
11252 number_images++;
11253 if (next && (next != image))
11254 {
11255 image->next=next->next;
11256 if (image->next != (Image *) NULL)
11257 image->next->previous=image;
11258 DeleteImageFromRegistry(*pv,next);
11259 }
11260 sv_setiv(*pv,PTR2IV(image));
11261 next=image;
11262 }
11263 if (*pv)
11264 pv++;
11265 }
11266
11267 PerlException:
11268 if (reference_vector)
11269 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11270 InheritPerlException(exception,perl_exception);
11271 exception=DestroyExceptionInfo(exception);
11272 sv_setiv(perl_exception,(IV) number_images);
11273 SvPOK_on(perl_exception);
11274 ST(0)=sv_2mortal(perl_exception);
11275 XSRETURN(1);
11276 }
11277
11278#
11279###############################################################################
11280# #
11281# #
11282# #
11283# M o n t a g e #
11284# #
11285# #
11286# #
11287###############################################################################
11288#
11289#
11290void
11291Montage(ref,...)
11292 Image::Magick ref=NO_INIT
11293 ALIAS:
11294 MontageImage = 1
11295 montage = 2
11296 montageimage = 3
11297 PPCODE:
11298 {
11299 AV
11300 *av;
11301
11302 char
11303 *attribute;
11304
11305 ExceptionInfo
11306 *exception;
11307
11308 HV
11309 *hv;
11310
11311 Image
11312 *image,
11313 *next;
11314
11315 PixelInfo
11316 transparent_color;
11317
11318 MontageInfo
11319 *montage_info;
11320
11321 register ssize_t
11322 i;
11323
11324 ssize_t
11325 sp;
11326
11327 struct PackageInfo
11328 *info;
11329
11330 SV
11331 *av_reference,
11332 *perl_exception,
11333 *reference,
11334 *rv,
11335 *sv;
11336
11337 PERL_UNUSED_VAR(ref);
11338 PERL_UNUSED_VAR(ix);
11339 exception=AcquireExceptionInfo();
11340 perl_exception=newSVpv("",0);
11341 sv=NULL;
11342 attribute=NULL;
11343 if (sv_isobject(ST(0)) == 0)
11344 {
11345 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11346 PackageName);
11347 goto PerlException;
11348 }
11349 reference=SvRV(ST(0));
11350 hv=SvSTASH(reference);
11351 av=newAV();
11352 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11353 SvREFCNT_dec(av);
11354 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11355 if (image == (Image *) NULL)
11356 {
11357 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11358 PackageName);
11359 goto PerlException;
11360 }
11361 /*
11362 Get options.
11363 */
11364 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11365 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11366 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11367 exception);
11368 for (i=2; i < items; i+=2)
11369 {
11370 attribute=(char *) SvPV(ST(i-1),na);
11371 switch (*attribute)
11372 {
11373 case 'B':
11374 case 'b':
11375 {
11376 if (LocaleCompare(attribute,"background") == 0)
11377 {
11378 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11379 &montage_info->background_color,exception);
11380 for (next=image; next; next=next->next)
11381 next->background_color=montage_info->background_color;
11382 break;
11383 }
11384 if (LocaleCompare(attribute,"border") == 0)
11385 {
11386 montage_info->border_width=SvIV(ST(i));
11387 break;
11388 }
11389 if (LocaleCompare(attribute,"bordercolor") == 0)
11390 {
11391 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11392 &montage_info->border_color,exception);
11393 for (next=image; next; next=next->next)
11394 next->border_color=montage_info->border_color;
11395 break;
11396 }
11397 if (LocaleCompare(attribute,"borderwidth") == 0)
11398 {
11399 montage_info->border_width=SvIV(ST(i));
11400 break;
11401 }
11402 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11403 attribute);
11404 break;
11405 }
11406 case 'C':
11407 case 'c':
11408 {
11409 if (LocaleCompare(attribute,"compose") == 0)
11410 {
11411 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11412 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11413 if (sp < 0)
11414 {
11415 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11416 SvPV(ST(i),na));
11417 break;
11418 }
11419 for (next=image; next; next=next->next)
11420 next->compose=(CompositeOperator) sp;
11421 break;
11422 }
11423 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11424 attribute);
11425 break;
11426 }
11427 case 'F':
11428 case 'f':
11429 {
11430 if (LocaleCompare(attribute,"fill") == 0)
11431 {
11432 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11433 &montage_info->fill,exception);
11434 break;
11435 }
11436 if (LocaleCompare(attribute,"font") == 0)
11437 {
11438 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11439 break;
11440 }
11441 if (LocaleCompare(attribute,"frame") == 0)
11442 {
11443 char
11444 *p;
11445
11446 p=SvPV(ST(i),na);
11447 if (IsGeometry(p) == MagickFalse)
11448 {
11449 ThrowPerlException(exception,OptionError,"MissingGeometry",
11450 p);
11451 break;
11452 }
11453 (void) CloneString(&montage_info->frame,p);
11454 if (*p == '\0')
11455 montage_info->frame=(char *) NULL;
11456 break;
11457 }
11458 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11459 attribute);
11460 break;
11461 }
11462 case 'G':
11463 case 'g':
11464 {
11465 if (LocaleCompare(attribute,"geometry") == 0)
11466 {
11467 char
11468 *p;
11469
11470 p=SvPV(ST(i),na);
11471 if (IsGeometry(p) == MagickFalse)
11472 {
11473 ThrowPerlException(exception,OptionError,"MissingGeometry",
11474 p);
11475 break;
11476 }
11477 (void) CloneString(&montage_info->geometry,p);
11478 if (*p == '\0')
11479 montage_info->geometry=(char *) NULL;
11480 break;
11481 }
11482 if (LocaleCompare(attribute,"gravity") == 0)
11483 {
11484 ssize_t
11485 in;
11486
11487 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11488 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11489 if (in < 0)
11490 {
11491 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11492 SvPV(ST(i),na));
11493 return;
11494 }
11495 montage_info->gravity=(GravityType) in;
11496 for (next=image; next; next=next->next)
11497 next->gravity=(GravityType) in;
11498 break;
11499 }
11500 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11501 attribute);
11502 break;
11503 }
11504 case 'L':
11505 case 'l':
11506 {
11507 if (LocaleCompare(attribute,"label") == 0)
11508 {
11509 for (next=image; next; next=next->next)
11510 (void) SetImageProperty(next,"label",InterpretImageProperties(
11511 info ? info->image_info : (ImageInfo *) NULL,next,
11512 SvPV(ST(i),na),exception),exception);
11513 break;
11514 }
11515 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11516 attribute);
11517 break;
11518 }
11519 case 'M':
11520 case 'm':
11521 {
11522 if (LocaleCompare(attribute,"mattecolor") == 0)
11523 {
11524 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11525 &montage_info->matte_color,exception);
11526 for (next=image; next; next=next->next)
11527 next->matte_color=montage_info->matte_color;
11528 break;
11529 }
11530 if (LocaleCompare(attribute,"mode") == 0)
11531 {
11532 ssize_t
11533 in;
11534
11535 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11536 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11537 switch (in)
11538 {
11539 default:
11540 {
11541 ThrowPerlException(exception,OptionError,
11542 "UnrecognizedModeType",SvPV(ST(i),na));
11543 break;
11544 }
11545 case FrameMode:
11546 {
11547 (void) CloneString(&montage_info->frame,"15x15+3+3");
11548 montage_info->shadow=MagickTrue;
11549 break;
11550 }
11551 case UnframeMode:
11552 {
11553 montage_info->frame=(char *) NULL;
11554 montage_info->shadow=MagickFalse;
11555 montage_info->border_width=0;
11556 break;
11557 }
11558 case ConcatenateMode:
11559 {
11560 montage_info->frame=(char *) NULL;
11561 montage_info->shadow=MagickFalse;
11562 (void) CloneString(&montage_info->geometry,"+0+0");
11563 montage_info->border_width=0;
11564 }
11565 }
11566 break;
11567 }
11568 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11569 attribute);
11570 break;
11571 }
11572 case 'P':
11573 case 'p':
11574 {
11575 if (LocaleCompare(attribute,"pointsize") == 0)
11576 {
11577 montage_info->pointsize=SvIV(ST(i));
11578 break;
11579 }
11580 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11581 attribute);
11582 break;
11583 }
11584 case 'S':
11585 case 's':
11586 {
11587 if (LocaleCompare(attribute,"shadow") == 0)
11588 {
11589 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11590 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11591 if (sp < 0)
11592 {
11593 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11594 SvPV(ST(i),na));
11595 break;
11596 }
11597 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11598 break;
11599 }
11600 if (LocaleCompare(attribute,"stroke") == 0)
11601 {
11602 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11603 &montage_info->stroke,exception);
11604 break;
11605 }
11606 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11607 attribute);
11608 break;
11609 }
11610 case 'T':
11611 case 't':
11612 {
11613 if (LocaleCompare(attribute,"texture") == 0)
11614 {
11615 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11616 break;
11617 }
11618 if (LocaleCompare(attribute,"tile") == 0)
11619 {
11620 char *p=SvPV(ST(i),na);
11621 if (IsGeometry(p) == MagickFalse)
11622 {
11623 ThrowPerlException(exception,OptionError,"MissingGeometry",
11624 p);
11625 break;
11626 }
11627 (void) CloneString(&montage_info->tile,p);
11628 if (*p == '\0')
11629 montage_info->tile=(char *) NULL;
11630 break;
11631 }
11632 if (LocaleCompare(attribute,"title") == 0)
11633 {
11634 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11635 break;
11636 }
11637 if (LocaleCompare(attribute,"transparent") == 0)
11638 {
11639 PixelInfo
11640 transparent_color;
11641
11642 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11643 &transparent_color,exception);
11644 for (next=image; next; next=next->next)
11645 (void) TransparentPaintImage(next,&transparent_color,
11646 TransparentAlpha,MagickFalse,exception);
11647 break;
11648 }
11649 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11650 attribute);
11651 break;
11652 }
11653 default:
11654 {
11655 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11656 attribute);
11657 break;
11658 }
11659 }
11660 }
11661 image=MontageImageList(info->image_info,montage_info,image,exception);
11662 montage_info=DestroyMontageInfo(montage_info);
11663 if (image == (Image *) NULL)
11664 goto PerlException;
11665 if (transparent_color.alpha != TransparentAlpha)
11666 for (next=image; next; next=next->next)
11667 (void) TransparentPaintImage(next,&transparent_color,
11668 TransparentAlpha,MagickFalse,exception);
11669 for ( ; image; image=image->next)
11670 {
11671 AddImageToRegistry(sv,image);
11672 rv=newRV(sv);
11673 av_push(av,sv_bless(rv,hv));
11674 SvREFCNT_dec(sv);
11675 }
11676 exception=DestroyExceptionInfo(exception);
11677 ST(0)=av_reference;
11678 SvREFCNT_dec(perl_exception);
11679 XSRETURN(1);
11680
11681 PerlException:
11682 InheritPerlException(exception,perl_exception);
11683 exception=DestroyExceptionInfo(exception);
11684 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11685 SvPOK_on(perl_exception);
11686 ST(0)=sv_2mortal(perl_exception);
11687 XSRETURN(1);
11688 }
11689
11690#
11691###############################################################################
11692# #
11693# #
11694# #
11695# M o r p h #
11696# #
11697# #
11698# #
11699###############################################################################
11700#
11701#
11702void
11703Morph(ref,...)
11704 Image::Magick ref=NO_INIT
11705 ALIAS:
11706 MorphImage = 1
11707 morph = 2
11708 morphimage = 3
11709 PPCODE:
11710 {
11711 AV
11712 *av;
11713
11714 char
11715 *attribute;
11716
11717 ExceptionInfo
11718 *exception;
11719
11720 HV
11721 *hv;
11722
11723 Image
11724 *image;
11725
11726 register ssize_t
11727 i;
11728
11729 ssize_t
11730 number_frames;
11731
11732 struct PackageInfo
11733 *info;
11734
11735 SV
11736 *av_reference,
11737 *perl_exception,
11738 *reference,
11739 *rv,
11740 *sv;
11741
11742 PERL_UNUSED_VAR(ref);
11743 PERL_UNUSED_VAR(ix);
11744 exception=AcquireExceptionInfo();
11745 perl_exception=newSVpv("",0);
11746 sv=NULL;
11747 av=NULL;
11748 attribute=NULL;
11749 if (sv_isobject(ST(0)) == 0)
11750 {
11751 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11752 PackageName);
11753 goto PerlException;
11754 }
11755 reference=SvRV(ST(0));
11756 hv=SvSTASH(reference);
11757 av=newAV();
11758 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11759 SvREFCNT_dec(av);
11760 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11761 if (image == (Image *) NULL)
11762 {
11763 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11764 PackageName);
11765 goto PerlException;
11766 }
11767 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11768 /*
11769 Get attribute.
11770 */
11771 number_frames=30;
11772 for (i=2; i < items; i+=2)
11773 {
11774 attribute=(char *) SvPV(ST(i-1),na);
11775 switch (*attribute)
11776 {
11777 case 'F':
11778 case 'f':
11779 {
11780 if (LocaleCompare(attribute,"frames") == 0)
11781 {
11782 number_frames=SvIV(ST(i));
11783 break;
11784 }
11785 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11786 attribute);
11787 break;
11788 }
11789 default:
11790 {
11791 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11792 attribute);
11793 break;
11794 }
11795 }
11796 }
11797 image=MorphImages(image,number_frames,exception);
11798 if (image == (Image *) NULL)
11799 goto PerlException;
11800 for ( ; image; image=image->next)
11801 {
11802 AddImageToRegistry(sv,image);
11803 rv=newRV(sv);
11804 av_push(av,sv_bless(rv,hv));
11805 SvREFCNT_dec(sv);
11806 }
11807 exception=DestroyExceptionInfo(exception);
11808 ST(0)=av_reference;
11809 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11810 XSRETURN(1);
11811
11812 PerlException:
11813 InheritPerlException(exception,perl_exception);
11814 exception=DestroyExceptionInfo(exception);
11815 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11816 SvPOK_on(perl_exception);
11817 ST(0)=sv_2mortal(perl_exception);
11818 XSRETURN(1);
11819 }
11820
11821#
11822###############################################################################
11823# #
11824# #
11825# #
11826# M o s a i c #
11827# #
11828# #
11829# #
11830###############################################################################
11831#
11832#
11833void
11834Mosaic(ref)
11835 Image::Magick ref=NO_INIT
11836 ALIAS:
11837 MosaicImage = 1
11838 mosaic = 2
11839 mosaicimage = 3
11840 PPCODE:
11841 {
11842 AV
11843 *av;
11844
11845 ExceptionInfo
11846 *exception;
11847
11848 HV
11849 *hv;
11850
11851 Image
11852 *image;
11853
11854 struct PackageInfo
11855 *info;
11856
11857 SV
11858 *perl_exception,
11859 *reference,
11860 *rv,
11861 *sv;
11862
11863 PERL_UNUSED_VAR(ref);
11864 PERL_UNUSED_VAR(ix);
11865 exception=AcquireExceptionInfo();
11866 perl_exception=newSVpv("",0);
11867 sv=NULL;
11868 if (sv_isobject(ST(0)) == 0)
11869 {
11870 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11871 PackageName);
11872 goto PerlException;
11873 }
11874 reference=SvRV(ST(0));
11875 hv=SvSTASH(reference);
11876 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11877 if (image == (Image *) NULL)
11878 {
11879 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11880 PackageName);
11881 goto PerlException;
11882 }
11883 image=MergeImageLayers(image,MosaicLayer,exception);
11884 /*
11885 Create blessed Perl array for the returned image.
11886 */
11887 av=newAV();
11888 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11889 SvREFCNT_dec(av);
11890 AddImageToRegistry(sv,image);
11891 rv=newRV(sv);
11892 av_push(av,sv_bless(rv,hv));
11893 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000011894 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000011895 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000011896 SetImageInfo(info->image_info,0,exception);
11897 exception=DestroyExceptionInfo(exception);
11898 SvREFCNT_dec(perl_exception);
11899 XSRETURN(1);
11900
11901 PerlException:
11902 InheritPerlException(exception,perl_exception);
11903 exception=DestroyExceptionInfo(exception);
11904 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11905 SvPOK_on(perl_exception); /* return messages in string context */
11906 ST(0)=sv_2mortal(perl_exception);
11907 XSRETURN(1);
11908 }
11909
11910#
11911###############################################################################
11912# #
11913# #
11914# #
11915# P i n g #
11916# #
11917# #
11918# #
11919###############################################################################
11920#
11921#
11922void
11923Ping(ref,...)
11924 Image::Magick ref=NO_INIT
11925 ALIAS:
11926 PingImage = 1
11927 ping = 2
11928 pingimage = 3
11929 PPCODE:
11930 {
11931 AV
11932 *av;
11933
11934 char
11935 **keep,
11936 **list;
11937
11938 ExceptionInfo
11939 *exception;
11940
11941 Image
11942 *image,
11943 *next;
11944
11945 int
11946 n;
11947
11948 MagickBooleanType
11949 status;
11950
11951 register char
11952 **p;
11953
11954 register ssize_t
11955 i;
11956
11957 ssize_t
11958 ac;
11959
11960 STRLEN
11961 *length;
11962
11963 struct PackageInfo
11964 *info,
11965 *package_info;
11966
11967 SV
11968 *perl_exception,
11969 *reference;
11970
11971 size_t
11972 count;
11973
11974 PERL_UNUSED_VAR(ref);
11975 PERL_UNUSED_VAR(ix);
11976 exception=AcquireExceptionInfo();
11977 perl_exception=newSVpv("",0);
11978 package_info=(struct PackageInfo *) NULL;
11979 ac=(items < 2) ? 1 : items-1;
11980 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
11981 keep=list;
11982 length=(STRLEN *) NULL;
11983 if (list == (char **) NULL)
11984 {
11985 ThrowPerlException(exception,ResourceLimitError,
11986 "MemoryAllocationFailed",PackageName);
11987 goto PerlException;
11988 }
11989 keep=list;
11990 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
11991 if (length == (STRLEN *) NULL)
11992 {
11993 ThrowPerlException(exception,ResourceLimitError,
11994 "MemoryAllocationFailed",PackageName);
11995 goto PerlException;
11996 }
11997 if (sv_isobject(ST(0)) == 0)
11998 {
11999 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12000 PackageName);
12001 goto PerlException;
12002 }
12003 reference=SvRV(ST(0));
12004 if (SvTYPE(reference) != SVt_PVAV)
12005 {
12006 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12007 PackageName);
12008 goto PerlException;
12009 }
12010 av=(AV *) reference;
12011 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12012 exception);
12013 package_info=ClonePackageInfo(info,exception);
12014 n=1;
12015 if (items <= 1)
12016 *list=(char *) (*package_info->image_info->filename ?
12017 package_info->image_info->filename : "XC:black");
12018 else
12019 for (n=0, i=0; i < ac; i++)
12020 {
12021 list[n]=(char *) SvPV(ST(i+1),length[n]);
12022 if ((items >= 3) && strEQcase(list[n],"blob"))
12023 {
12024 void
12025 *blob;
12026
12027 i++;
12028 blob=(void *) (SvPV(ST(i+1),length[n]));
12029 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12030 }
12031 if ((items >= 3) && strEQcase(list[n],"filename"))
12032 continue;
12033 if ((items >= 3) && strEQcase(list[n],"file"))
12034 {
12035 FILE
12036 *file;
12037
12038 PerlIO
12039 *io_info;
12040
12041 i++;
12042 io_info=IoIFP(sv_2io(ST(i+1)));
12043 if (io_info == (PerlIO *) NULL)
12044 {
12045 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12046 PackageName);
12047 continue;
12048 }
12049 file=PerlIO_findFILE(io_info);
12050 if (file == (FILE *) NULL)
12051 {
12052 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12053 PackageName);
12054 continue;
12055 }
12056 SetImageInfoFile(package_info->image_info,file);
12057 }
12058 if ((items >= 3) && strEQcase(list[n],"magick"))
12059 continue;
12060 n++;
12061 }
12062 list[n]=(char *) NULL;
12063 keep=list;
12064 status=ExpandFilenames(&n,&list);
12065 if (status == MagickFalse)
12066 {
12067 ThrowPerlException(exception,ResourceLimitError,
12068 "MemoryAllocationFailed",PackageName);
12069 goto PerlException;
12070 }
12071 count=0;
12072 for (i=0; i < n; i++)
12073 {
12074 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012075 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012076 image=PingImage(package_info->image_info,exception);
12077 if (image == (Image *) NULL)
12078 break;
12079 if ((package_info->image_info->file != (FILE *) NULL) ||
12080 (package_info->image_info->blob != (void *) NULL))
12081 DisassociateImageStream(image);
12082 count+=GetImageListLength(image);
12083 EXTEND(sp,4*count);
12084 for (next=image; next; next=next->next)
12085 {
12086 PUSHs(sv_2mortal(newSViv(next->columns)));
12087 PUSHs(sv_2mortal(newSViv(next->rows)));
12088 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12089 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12090 }
12091 image=DestroyImageList(image);
12092 }
12093 /*
12094 Free resources.
12095 */
12096 for (i=0; i < n; i++)
12097 if (list[i] != (char *) NULL)
12098 for (p=keep; list[i] != *p++; )
12099 if (*p == NULL)
12100 {
12101 list[i]=(char *) RelinquishMagickMemory(list[i]);
12102 break;
12103 }
12104
12105 PerlException:
12106 if (package_info != (struct PackageInfo *) NULL)
12107 DestroyPackageInfo(package_info);
12108 if (list && (list != keep))
12109 list=(char **) RelinquishMagickMemory(list);
12110 if (keep)
12111 keep=(char **) RelinquishMagickMemory(keep);
12112 if (length)
12113 length=(STRLEN *) RelinquishMagickMemory(length);
12114 InheritPerlException(exception,perl_exception);
12115 exception=DestroyExceptionInfo(exception);
12116 SvREFCNT_dec(perl_exception); /* throw away all errors */
12117 }
12118
12119#
12120###############################################################################
12121# #
12122# #
12123# #
12124# P r e v i e w #
12125# #
12126# #
12127# #
12128###############################################################################
12129#
12130#
12131void
12132Preview(ref,...)
12133 Image::Magick ref=NO_INIT
12134 ALIAS:
12135 PreviewImage = 1
12136 preview = 2
12137 previewimage = 3
12138 PPCODE:
12139 {
12140 AV
12141 *av;
12142
12143 ExceptionInfo
12144 *exception;
12145
12146 HV
12147 *hv;
12148
12149 Image
12150 *image,
12151 *preview_image;
12152
12153 PreviewType
12154 preview_type;
12155
12156 struct PackageInfo
12157 *info;
12158
12159 SV
12160 *av_reference,
12161 *perl_exception,
12162 *reference,
12163 *rv,
12164 *sv;
12165
12166 PERL_UNUSED_VAR(ref);
12167 PERL_UNUSED_VAR(ix);
12168 exception=AcquireExceptionInfo();
12169 perl_exception=newSVpv("",0);
12170 sv=NULL;
12171 av=NULL;
12172 if (sv_isobject(ST(0)) == 0)
12173 {
12174 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12175 PackageName);
12176 goto PerlException;
12177 }
12178 reference=SvRV(ST(0));
12179 hv=SvSTASH(reference);
12180 av=newAV();
12181 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12182 SvREFCNT_dec(av);
12183 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12184 if (image == (Image *) NULL)
12185 {
12186 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12187 PackageName);
12188 goto PerlException;
12189 }
12190 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12191 preview_type=GammaPreview;
12192 if (items > 1)
12193 preview_type=(PreviewType)
12194 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12195 for ( ; image; image=image->next)
12196 {
12197 preview_image=PreviewImage(image,preview_type,exception);
12198 if (preview_image == (Image *) NULL)
12199 goto PerlException;
12200 AddImageToRegistry(sv,preview_image);
12201 rv=newRV(sv);
12202 av_push(av,sv_bless(rv,hv));
12203 SvREFCNT_dec(sv);
12204 }
12205 exception=DestroyExceptionInfo(exception);
12206 ST(0)=av_reference;
12207 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12208 XSRETURN(1);
12209
12210 PerlException:
12211 InheritPerlException(exception,perl_exception);
12212 exception=DestroyExceptionInfo(exception);
12213 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12214 SvPOK_on(perl_exception);
12215 ST(0)=sv_2mortal(perl_exception);
12216 XSRETURN(1);
12217 }
12218
12219#
12220###############################################################################
12221# #
12222# #
12223# #
12224# Q u e r y C o l o r #
12225# #
12226# #
12227# #
12228###############################################################################
12229#
12230#
12231void
12232QueryColor(ref,...)
12233 Image::Magick ref=NO_INIT
12234 ALIAS:
12235 querycolor = 1
12236 PPCODE:
12237 {
12238 char
12239 *name;
12240
12241 ExceptionInfo
12242 *exception;
12243
12244 PixelInfo
12245 color;
12246
12247 register ssize_t
12248 i;
12249
12250 SV
12251 *perl_exception;
12252
12253 PERL_UNUSED_VAR(ref);
12254 PERL_UNUSED_VAR(ix);
12255 exception=AcquireExceptionInfo();
12256 perl_exception=newSVpv("",0);
12257 if (items == 1)
12258 {
12259 const ColorInfo
12260 **colorlist;
12261
12262 size_t
12263 colors;
12264
12265 colorlist=GetColorInfoList("*",&colors,exception);
12266 EXTEND(sp,colors);
12267 for (i=0; i < (ssize_t) colors; i++)
12268 {
12269 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12270 }
12271 colorlist=(const ColorInfo **)
12272 RelinquishMagickMemory((ColorInfo **) colorlist);
12273 goto PerlException;
12274 }
12275 EXTEND(sp,5*items);
12276 for (i=1; i < items; i++)
12277 {
12278 name=(char *) SvPV(ST(i),na);
12279 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12280 {
12281 PUSHs(&sv_undef);
12282 continue;
12283 }
12284 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12285 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12286 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12287 if (color.colorspace == CMYKColorspace)
12288 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012289 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012290 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12291 }
12292
12293 PerlException:
12294 InheritPerlException(exception,perl_exception);
12295 exception=DestroyExceptionInfo(exception);
12296 SvREFCNT_dec(perl_exception);
12297 }
12298
12299#
12300###############################################################################
12301# #
12302# #
12303# #
12304# Q u e r y C o l o r N a m e #
12305# #
12306# #
12307# #
12308###############################################################################
12309#
12310#
12311void
12312QueryColorname(ref,...)
12313 Image::Magick ref=NO_INIT
12314 ALIAS:
12315 querycolorname = 1
12316 PPCODE:
12317 {
12318 AV
12319 *av;
12320
12321 char
cristy151b66d2015-04-15 10:50:31 +000012322 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012323
12324 ExceptionInfo
12325 *exception;
12326
12327 Image
12328 *image;
12329
12330 PixelInfo
12331 target_color;
12332
12333 register ssize_t
12334 i;
12335
12336 struct PackageInfo
12337 *info;
12338
12339 SV
12340 *perl_exception,
12341 *reference; /* reference is the SV* of ref=SvIV(reference) */
12342
12343 PERL_UNUSED_VAR(ref);
12344 PERL_UNUSED_VAR(ix);
12345 exception=AcquireExceptionInfo();
12346 perl_exception=newSVpv("",0);
12347 reference=SvRV(ST(0));
12348 av=(AV *) reference;
12349 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12350 exception);
12351 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12352 if (image == (Image *) NULL)
12353 {
12354 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12355 PackageName);
12356 goto PerlException;
12357 }
12358 EXTEND(sp,items);
12359 for (i=1; i < items; i++)
12360 {
12361 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12362 exception);
12363 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12364 exception);
12365 PUSHs(sv_2mortal(newSVpv(message,0)));
12366 }
12367
12368 PerlException:
12369 InheritPerlException(exception,perl_exception);
12370 exception=DestroyExceptionInfo(exception);
12371 SvREFCNT_dec(perl_exception);
12372 }
12373
12374#
12375###############################################################################
12376# #
12377# #
12378# #
12379# Q u e r y F o n t #
12380# #
12381# #
12382# #
12383###############################################################################
12384#
12385#
12386void
12387QueryFont(ref,...)
12388 Image::Magick ref=NO_INIT
12389 ALIAS:
12390 queryfont = 1
12391 PPCODE:
12392 {
12393 char
12394 *name,
cristy151b66d2015-04-15 10:50:31 +000012395 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012396
12397 ExceptionInfo
12398 *exception;
12399
12400 register ssize_t
12401 i;
12402
12403 SV
12404 *perl_exception;
12405
12406 volatile const TypeInfo
12407 *type_info;
12408
12409 PERL_UNUSED_VAR(ref);
12410 PERL_UNUSED_VAR(ix);
12411 exception=AcquireExceptionInfo();
12412 perl_exception=newSVpv("",0);
12413 if (items == 1)
12414 {
12415 const TypeInfo
12416 **typelist;
12417
12418 size_t
12419 types;
12420
12421 typelist=GetTypeInfoList("*",&types,exception);
12422 EXTEND(sp,types);
12423 for (i=0; i < (ssize_t) types; i++)
12424 {
12425 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12426 }
12427 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12428 typelist);
12429 goto PerlException;
12430 }
12431 EXTEND(sp,10*items);
12432 for (i=1; i < items; i++)
12433 {
12434 name=(char *) SvPV(ST(i),na);
12435 type_info=GetTypeInfo(name,exception);
12436 if (type_info == (TypeInfo *) NULL)
12437 {
12438 PUSHs(&sv_undef);
12439 continue;
12440 }
12441 if (type_info->name == (char *) NULL)
12442 PUSHs(&sv_undef);
12443 else
12444 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12445 if (type_info->description == (char *) NULL)
12446 PUSHs(&sv_undef);
12447 else
12448 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12449 if (type_info->family == (char *) NULL)
12450 PUSHs(&sv_undef);
12451 else
12452 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12453 if (type_info->style == UndefinedStyle)
12454 PUSHs(&sv_undef);
12455 else
12456 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12457 type_info->style),0)));
12458 if (type_info->stretch == UndefinedStretch)
12459 PUSHs(&sv_undef);
12460 else
12461 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12462 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012463 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012464 type_info->weight);
12465 PUSHs(sv_2mortal(newSVpv(message,0)));
12466 if (type_info->encoding == (char *) NULL)
12467 PUSHs(&sv_undef);
12468 else
12469 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12470 if (type_info->foundry == (char *) NULL)
12471 PUSHs(&sv_undef);
12472 else
12473 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12474 if (type_info->format == (char *) NULL)
12475 PUSHs(&sv_undef);
12476 else
12477 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12478 if (type_info->metrics == (char *) NULL)
12479 PUSHs(&sv_undef);
12480 else
12481 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12482 if (type_info->glyphs == (char *) NULL)
12483 PUSHs(&sv_undef);
12484 else
12485 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12486 }
12487
12488 PerlException:
12489 InheritPerlException(exception,perl_exception);
12490 exception=DestroyExceptionInfo(exception);
12491 SvREFCNT_dec(perl_exception);
12492 }
12493
12494#
12495###############################################################################
12496# #
12497# #
12498# #
12499# Q u e r y F o n t M e t r i c s #
12500# #
12501# #
12502# #
12503###############################################################################
12504#
12505#
12506void
12507QueryFontMetrics(ref,...)
12508 Image::Magick ref=NO_INIT
12509 ALIAS:
12510 queryfontmetrics = 1
12511 PPCODE:
12512 {
12513 AffineMatrix
12514 affine,
12515 current;
12516
12517 AV
12518 *av;
12519
12520 char
12521 *attribute;
12522
12523 double
12524 x,
12525 y;
12526
12527 DrawInfo
12528 *draw_info;
12529
12530 ExceptionInfo
12531 *exception;
12532
12533 GeometryInfo
12534 geometry_info;
12535
12536 Image
12537 *image;
12538
12539 MagickBooleanType
12540 status;
12541
12542 MagickStatusType
12543 flags;
12544
12545 register ssize_t
12546 i;
12547
12548 ssize_t
12549 type;
12550
12551 struct PackageInfo
12552 *info,
12553 *package_info;
12554
12555 SV
12556 *perl_exception,
12557 *reference; /* reference is the SV* of ref=SvIV(reference) */
12558
12559 TypeMetric
12560 metrics;
12561
12562 PERL_UNUSED_VAR(ref);
12563 PERL_UNUSED_VAR(ix);
12564 exception=AcquireExceptionInfo();
12565 package_info=(struct PackageInfo *) NULL;
12566 perl_exception=newSVpv("",0);
12567 reference=SvRV(ST(0));
12568 av=(AV *) reference;
12569 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12570 exception);
12571 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12572 if (image == (Image *) NULL)
12573 {
12574 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12575 PackageName);
12576 goto PerlException;
12577 }
12578 package_info=ClonePackageInfo(info,exception);
12579 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12580 CloneString(&draw_info->text,"");
12581 current=draw_info->affine;
12582 GetAffineMatrix(&affine);
12583 x=0.0;
12584 y=0.0;
12585 EXTEND(sp,7*items);
12586 for (i=2; i < items; i+=2)
12587 {
12588 attribute=(char *) SvPV(ST(i-1),na);
12589 switch (*attribute)
12590 {
12591 case 'A':
12592 case 'a':
12593 {
12594 if (LocaleCompare(attribute,"antialias") == 0)
12595 {
12596 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12597 SvPV(ST(i),na));
12598 if (type < 0)
12599 {
12600 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12601 SvPV(ST(i),na));
12602 break;
12603 }
12604 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12605 break;
12606 }
12607 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12608 attribute);
12609 break;
12610 }
12611 case 'd':
12612 case 'D':
12613 {
12614 if (LocaleCompare(attribute,"density") == 0)
12615 {
12616 CloneString(&draw_info->density,SvPV(ST(i),na));
12617 break;
12618 }
12619 if (LocaleCompare(attribute,"direction") == 0)
12620 {
12621 draw_info->direction=(DirectionType) ParseCommandOption(
12622 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12623 break;
12624 }
12625 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12626 attribute);
12627 break;
12628 }
12629 case 'e':
12630 case 'E':
12631 {
12632 if (LocaleCompare(attribute,"encoding") == 0)
12633 {
12634 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12635 break;
12636 }
12637 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12638 attribute);
12639 break;
12640 }
12641 case 'f':
12642 case 'F':
12643 {
12644 if (LocaleCompare(attribute,"family") == 0)
12645 {
12646 CloneString(&draw_info->family,SvPV(ST(i),na));
12647 break;
12648 }
12649 if (LocaleCompare(attribute,"fill") == 0)
12650 {
12651 if (info)
12652 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12653 &draw_info->fill,exception);
12654 break;
12655 }
12656 if (LocaleCompare(attribute,"font") == 0)
12657 {
12658 CloneString(&draw_info->font,SvPV(ST(i),na));
12659 break;
12660 }
12661 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12662 attribute);
12663 break;
12664 }
12665 case 'g':
12666 case 'G':
12667 {
12668 if (LocaleCompare(attribute,"geometry") == 0)
12669 {
12670 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12671 break;
12672 }
12673 if (LocaleCompare(attribute,"gravity") == 0)
12674 {
12675 draw_info->gravity=(GravityType) ParseCommandOption(
12676 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12677 break;
12678 }
12679 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12680 attribute);
12681 break;
12682 }
12683 case 'i':
12684 case 'I':
12685 {
12686 if (LocaleCompare(attribute,"interline-spacing") == 0)
12687 {
12688 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12689 draw_info->interline_spacing=geometry_info.rho;
12690 break;
12691 }
12692 if (LocaleCompare(attribute,"interword-spacing") == 0)
12693 {
12694 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12695 draw_info->interword_spacing=geometry_info.rho;
12696 break;
12697 }
12698 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12699 attribute);
12700 break;
12701 }
12702 case 'k':
12703 case 'K':
12704 {
12705 if (LocaleCompare(attribute,"kerning") == 0)
12706 {
12707 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12708 draw_info->kerning=geometry_info.rho;
12709 break;
12710 }
12711 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12712 attribute);
12713 break;
12714 }
12715 case 'p':
12716 case 'P':
12717 {
12718 if (LocaleCompare(attribute,"pointsize") == 0)
12719 {
12720 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12721 draw_info->pointsize=geometry_info.rho;
12722 break;
12723 }
12724 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12725 attribute);
12726 break;
12727 }
12728 case 'r':
12729 case 'R':
12730 {
12731 if (LocaleCompare(attribute,"rotate") == 0)
12732 {
12733 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12734 affine.rx=geometry_info.rho;
12735 affine.ry=geometry_info.sigma;
12736 if ((flags & SigmaValue) == 0)
12737 affine.ry=affine.rx;
12738 break;
12739 }
12740 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12741 attribute);
12742 break;
12743 }
12744 case 's':
12745 case 'S':
12746 {
12747 if (LocaleCompare(attribute,"scale") == 0)
12748 {
12749 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12750 affine.sx=geometry_info.rho;
12751 affine.sy=geometry_info.sigma;
12752 if ((flags & SigmaValue) == 0)
12753 affine.sy=affine.sx;
12754 break;
12755 }
12756 if (LocaleCompare(attribute,"skew") == 0)
12757 {
12758 double
12759 x_angle,
12760 y_angle;
12761
12762 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12763 x_angle=geometry_info.rho;
12764 y_angle=geometry_info.sigma;
12765 if ((flags & SigmaValue) == 0)
12766 y_angle=x_angle;
12767 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12768 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12769 break;
12770 }
12771 if (LocaleCompare(attribute,"stroke") == 0)
12772 {
12773 if (info)
12774 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12775 &draw_info->stroke,exception);
12776 break;
12777 }
12778 if (LocaleCompare(attribute,"style") == 0)
12779 {
12780 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12781 SvPV(ST(i),na));
12782 if (type < 0)
12783 {
12784 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12785 SvPV(ST(i),na));
12786 break;
12787 }
12788 draw_info->style=(StyleType) type;
12789 break;
12790 }
12791 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12792 attribute);
12793 break;
12794 }
12795 case 't':
12796 case 'T':
12797 {
12798 if (LocaleCompare(attribute,"text") == 0)
12799 {
12800 CloneString(&draw_info->text,SvPV(ST(i),na));
12801 break;
12802 }
12803 if (LocaleCompare(attribute,"translate") == 0)
12804 {
12805 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12806 affine.tx=geometry_info.rho;
12807 affine.ty=geometry_info.sigma;
12808 if ((flags & SigmaValue) == 0)
12809 affine.ty=affine.tx;
12810 break;
12811 }
12812 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12813 attribute);
12814 break;
12815 }
12816 case 'w':
12817 case 'W':
12818 {
12819 if (LocaleCompare(attribute,"weight") == 0)
12820 {
12821 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12822 draw_info->weight=(size_t) geometry_info.rho;
12823 break;
12824 }
12825 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12826 attribute);
12827 break;
12828 }
12829 case 'x':
12830 case 'X':
12831 {
12832 if (LocaleCompare(attribute,"x") == 0)
12833 {
12834 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12835 x=geometry_info.rho;
12836 break;
12837 }
12838 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12839 attribute);
12840 break;
12841 }
12842 case 'y':
12843 case 'Y':
12844 {
12845 if (LocaleCompare(attribute,"y") == 0)
12846 {
12847 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12848 y=geometry_info.rho;
12849 break;
12850 }
12851 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12852 attribute);
12853 break;
12854 }
12855 default:
12856 {
12857 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12858 attribute);
12859 break;
12860 }
12861 }
12862 }
12863 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12864 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12865 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12866 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12867 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12868 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12869 if (draw_info->geometry == (char *) NULL)
12870 {
12871 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000012872 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000012873 "%.15g,%.15g",x,y);
12874 }
12875 status=GetTypeMetrics(image,draw_info,&metrics,exception);
12876 (void) CatchImageException(image);
12877 if (status == MagickFalse)
12878 PUSHs(&sv_undef);
12879 else
12880 {
12881 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12882 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12883 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12884 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12885 PUSHs(sv_2mortal(newSVnv(metrics.width)));
12886 PUSHs(sv_2mortal(newSVnv(metrics.height)));
12887 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12888 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
12889 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
12890 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
12891 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
12892 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
12893 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
12894 }
12895 draw_info=DestroyDrawInfo(draw_info);
12896
12897 PerlException:
12898 if (package_info != (struct PackageInfo *) NULL)
12899 DestroyPackageInfo(package_info);
12900 InheritPerlException(exception,perl_exception);
12901 exception=DestroyExceptionInfo(exception);
12902 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12903 }
12904
12905#
12906###############################################################################
12907# #
12908# #
12909# #
12910# 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 #
12911# #
12912# #
12913# #
12914###############################################################################
12915#
12916#
12917void
12918QueryMultilineFontMetrics(ref,...)
12919 Image::Magick ref=NO_INIT
12920 ALIAS:
12921 querymultilinefontmetrics = 1
12922 PPCODE:
12923 {
12924 AffineMatrix
12925 affine,
12926 current;
12927
12928 AV
12929 *av;
12930
12931 char
12932 *attribute;
12933
12934 double
12935 x,
12936 y;
12937
12938 DrawInfo
12939 *draw_info;
12940
12941 ExceptionInfo
12942 *exception;
12943
12944 GeometryInfo
12945 geometry_info;
12946
12947 Image
12948 *image;
12949
12950 MagickBooleanType
12951 status;
12952
12953 MagickStatusType
12954 flags;
12955
12956 register ssize_t
12957 i;
12958
12959 ssize_t
12960 type;
12961
12962 struct PackageInfo
12963 *info,
12964 *package_info;
12965
12966 SV
12967 *perl_exception,
12968 *reference; /* reference is the SV* of ref=SvIV(reference) */
12969
12970 TypeMetric
12971 metrics;
12972
12973 PERL_UNUSED_VAR(ref);
12974 PERL_UNUSED_VAR(ix);
12975 exception=AcquireExceptionInfo();
12976 package_info=(struct PackageInfo *) NULL;
12977 perl_exception=newSVpv("",0);
12978 reference=SvRV(ST(0));
12979 av=(AV *) reference;
12980 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12981 exception);
12982 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12983 if (image == (Image *) NULL)
12984 {
12985 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12986 PackageName);
12987 goto PerlException;
12988 }
12989 package_info=ClonePackageInfo(info,exception);
12990 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12991 CloneString(&draw_info->text,"");
12992 current=draw_info->affine;
12993 GetAffineMatrix(&affine);
12994 x=0.0;
12995 y=0.0;
12996 EXTEND(sp,7*items);
12997 for (i=2; i < items; i+=2)
12998 {
12999 attribute=(char *) SvPV(ST(i-1),na);
13000 switch (*attribute)
13001 {
13002 case 'A':
13003 case 'a':
13004 {
13005 if (LocaleCompare(attribute,"antialias") == 0)
13006 {
13007 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13008 SvPV(ST(i),na));
13009 if (type < 0)
13010 {
13011 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13012 SvPV(ST(i),na));
13013 break;
13014 }
13015 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13016 break;
13017 }
13018 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13019 attribute);
13020 break;
13021 }
13022 case 'd':
13023 case 'D':
13024 {
13025 if (LocaleCompare(attribute,"density") == 0)
13026 {
13027 CloneString(&draw_info->density,SvPV(ST(i),na));
13028 break;
13029 }
13030 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13031 attribute);
13032 break;
13033 }
13034 case 'e':
13035 case 'E':
13036 {
13037 if (LocaleCompare(attribute,"encoding") == 0)
13038 {
13039 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13040 break;
13041 }
13042 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13043 attribute);
13044 break;
13045 }
13046 case 'f':
13047 case 'F':
13048 {
13049 if (LocaleCompare(attribute,"family") == 0)
13050 {
13051 CloneString(&draw_info->family,SvPV(ST(i),na));
13052 break;
13053 }
13054 if (LocaleCompare(attribute,"fill") == 0)
13055 {
13056 if (info)
13057 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13058 &draw_info->fill,exception);
13059 break;
13060 }
13061 if (LocaleCompare(attribute,"font") == 0)
13062 {
13063 CloneString(&draw_info->font,SvPV(ST(i),na));
13064 break;
13065 }
13066 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13067 attribute);
13068 break;
13069 }
13070 case 'g':
13071 case 'G':
13072 {
13073 if (LocaleCompare(attribute,"geometry") == 0)
13074 {
13075 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13076 break;
13077 }
13078 if (LocaleCompare(attribute,"gravity") == 0)
13079 {
13080 draw_info->gravity=(GravityType) ParseCommandOption(
13081 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13082 break;
13083 }
13084 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13085 attribute);
13086 break;
13087 }
13088 case 'p':
13089 case 'P':
13090 {
13091 if (LocaleCompare(attribute,"pointsize") == 0)
13092 {
13093 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13094 draw_info->pointsize=geometry_info.rho;
13095 break;
13096 }
13097 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13098 attribute);
13099 break;
13100 }
13101 case 'r':
13102 case 'R':
13103 {
13104 if (LocaleCompare(attribute,"rotate") == 0)
13105 {
13106 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13107 affine.rx=geometry_info.rho;
13108 affine.ry=geometry_info.sigma;
13109 if ((flags & SigmaValue) == 0)
13110 affine.ry=affine.rx;
13111 break;
13112 }
13113 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13114 attribute);
13115 break;
13116 }
13117 case 's':
13118 case 'S':
13119 {
13120 if (LocaleCompare(attribute,"scale") == 0)
13121 {
13122 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13123 affine.sx=geometry_info.rho;
13124 affine.sy=geometry_info.sigma;
13125 if ((flags & SigmaValue) == 0)
13126 affine.sy=affine.sx;
13127 break;
13128 }
13129 if (LocaleCompare(attribute,"skew") == 0)
13130 {
13131 double
13132 x_angle,
13133 y_angle;
13134
13135 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13136 x_angle=geometry_info.rho;
13137 y_angle=geometry_info.sigma;
13138 if ((flags & SigmaValue) == 0)
13139 y_angle=x_angle;
13140 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13141 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13142 break;
13143 }
13144 if (LocaleCompare(attribute,"stroke") == 0)
13145 {
13146 if (info)
13147 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13148 &draw_info->stroke,exception);
13149 break;
13150 }
13151 if (LocaleCompare(attribute,"style") == 0)
13152 {
13153 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13154 SvPV(ST(i),na));
13155 if (type < 0)
13156 {
13157 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13158 SvPV(ST(i),na));
13159 break;
13160 }
13161 draw_info->style=(StyleType) type;
13162 break;
13163 }
13164 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13165 attribute);
13166 break;
13167 }
13168 case 't':
13169 case 'T':
13170 {
13171 if (LocaleCompare(attribute,"text") == 0)
13172 {
13173 CloneString(&draw_info->text,SvPV(ST(i),na));
13174 break;
13175 }
13176 if (LocaleCompare(attribute,"translate") == 0)
13177 {
13178 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13179 affine.tx=geometry_info.rho;
13180 affine.ty=geometry_info.sigma;
13181 if ((flags & SigmaValue) == 0)
13182 affine.ty=affine.tx;
13183 break;
13184 }
13185 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13186 attribute);
13187 break;
13188 }
13189 case 'w':
13190 case 'W':
13191 {
13192 if (LocaleCompare(attribute,"weight") == 0)
13193 {
13194 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13195 draw_info->weight=(size_t) geometry_info.rho;
13196 break;
13197 }
13198 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13199 attribute);
13200 break;
13201 }
13202 case 'x':
13203 case 'X':
13204 {
13205 if (LocaleCompare(attribute,"x") == 0)
13206 {
13207 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13208 x=geometry_info.rho;
13209 break;
13210 }
13211 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13212 attribute);
13213 break;
13214 }
13215 case 'y':
13216 case 'Y':
13217 {
13218 if (LocaleCompare(attribute,"y") == 0)
13219 {
13220 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13221 y=geometry_info.rho;
13222 break;
13223 }
13224 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13225 attribute);
13226 break;
13227 }
13228 default:
13229 {
13230 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13231 attribute);
13232 break;
13233 }
13234 }
13235 }
13236 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13237 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13238 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13239 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13240 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13241 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13242 if (draw_info->geometry == (char *) NULL)
13243 {
13244 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013245 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013246 "%.15g,%.15g",x,y);
13247 }
13248 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13249 (void) CatchException(exception);
13250 if (status == MagickFalse)
13251 PUSHs(&sv_undef);
13252 else
13253 {
13254 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13255 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13256 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13257 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13258 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13259 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13260 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13261 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13262 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13263 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13264 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13265 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13266 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13267 }
13268 draw_info=DestroyDrawInfo(draw_info);
13269
13270 PerlException:
13271 if (package_info != (struct PackageInfo *) NULL)
13272 DestroyPackageInfo(package_info);
13273 InheritPerlException(exception,perl_exception);
13274 exception=DestroyExceptionInfo(exception);
13275 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13276 }
13277
13278#
13279###############################################################################
13280# #
13281# #
13282# #
13283# Q u e r y F o r m a t #
13284# #
13285# #
13286# #
13287###############################################################################
13288#
13289#
13290void
13291QueryFormat(ref,...)
13292 Image::Magick ref=NO_INIT
13293 ALIAS:
13294 queryformat = 1
13295 PPCODE:
13296 {
13297 char
13298 *name;
13299
13300 ExceptionInfo
13301 *exception;
13302
13303 register ssize_t
13304 i;
13305
13306 SV
13307 *perl_exception;
13308
13309 volatile const MagickInfo
13310 *magick_info;
13311
13312 PERL_UNUSED_VAR(ref);
13313 PERL_UNUSED_VAR(ix);
13314 exception=AcquireExceptionInfo();
13315 perl_exception=newSVpv("",0);
13316 if (items == 1)
13317 {
13318 char
cristy151b66d2015-04-15 10:50:31 +000013319 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013320
13321 const MagickInfo
13322 **format_list;
13323
13324 size_t
13325 types;
13326
13327 format_list=GetMagickInfoList("*",&types,exception);
13328 EXTEND(sp,types);
13329 for (i=0; i < (ssize_t) types; i++)
13330 {
cristy151b66d2015-04-15 10:50:31 +000013331 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013332 LocaleLower(format);
13333 PUSHs(sv_2mortal(newSVpv(format,0)));
13334 }
13335 format_list=(const MagickInfo **)
13336 RelinquishMagickMemory((MagickInfo *) format_list);
13337 goto PerlException;
13338 }
13339 EXTEND(sp,8*items);
13340 for (i=1; i < items; i++)
13341 {
13342 name=(char *) SvPV(ST(i),na);
13343 magick_info=GetMagickInfo(name,exception);
13344 if (magick_info == (const MagickInfo *) NULL)
13345 {
13346 PUSHs(&sv_undef);
13347 continue;
13348 }
cristy4a3ce0a2013-08-03 20:06:59 +000013349 if (magick_info->description == (char *) NULL)
13350 PUSHs(&sv_undef);
13351 else
13352 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13353 if (magick_info->module == (char *) NULL)
13354 PUSHs(&sv_undef);
13355 else
13356 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13357 }
13358
13359 PerlException:
13360 InheritPerlException(exception,perl_exception);
13361 exception=DestroyExceptionInfo(exception);
13362 SvREFCNT_dec(perl_exception);
13363 }
13364
13365#
13366###############################################################################
13367# #
13368# #
13369# #
13370# Q u e r y O p t i o n #
13371# #
13372# #
13373# #
13374###############################################################################
13375#
13376#
13377void
13378QueryOption(ref,...)
13379 Image::Magick ref=NO_INIT
13380 ALIAS:
13381 queryoption = 1
13382 PPCODE:
13383 {
13384 char
13385 **options;
13386
13387 ExceptionInfo
13388 *exception;
13389
13390 register ssize_t
13391 i;
13392
13393 ssize_t
13394 j,
13395 option;
13396
13397 SV
13398 *perl_exception;
13399
13400 PERL_UNUSED_VAR(ref);
13401 PERL_UNUSED_VAR(ix);
13402 exception=AcquireExceptionInfo();
13403 perl_exception=newSVpv("",0);
13404 EXTEND(sp,8*items);
13405 for (i=1; i < items; i++)
13406 {
13407 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13408 SvPV(ST(i),na));
13409 options=GetCommandOptions((CommandOption) option);
13410 if (options == (char **) NULL)
13411 PUSHs(&sv_undef);
13412 else
13413 {
13414 for (j=0; options[j] != (char *) NULL; j++)
13415 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13416 options=DestroyStringList(options);
13417 }
13418 }
13419
13420 InheritPerlException(exception,perl_exception);
13421 exception=DestroyExceptionInfo(exception);
13422 SvREFCNT_dec(perl_exception);
13423 }
13424
13425#
13426###############################################################################
13427# #
13428# #
13429# #
13430# R e a d #
13431# #
13432# #
13433# #
13434###############################################################################
13435#
13436#
13437void
13438Read(ref,...)
13439 Image::Magick ref=NO_INIT
13440 ALIAS:
13441 ReadImage = 1
13442 read = 2
13443 readimage = 3
13444 PPCODE:
13445 {
13446 AV
13447 *av;
13448
13449 char
13450 **keep,
13451 **list;
13452
13453 ExceptionInfo
13454 *exception;
13455
13456 HV
13457 *hv;
13458
13459 Image
13460 *image;
13461
13462 int
13463 n;
13464
13465 MagickBooleanType
13466 status;
13467
13468 register char
13469 **p;
13470
13471 register ssize_t
13472 i;
13473
13474 ssize_t
13475 ac,
13476 number_images;
13477
13478 STRLEN
13479 *length;
13480
13481 struct PackageInfo
13482 *info,
13483 *package_info;
13484
13485 SV
13486 *perl_exception, /* Perl variable for storing messages */
13487 *reference,
13488 *rv,
13489 *sv;
13490
13491 PERL_UNUSED_VAR(ref);
13492 PERL_UNUSED_VAR(ix);
13493 exception=AcquireExceptionInfo();
13494 perl_exception=newSVpv("",0);
13495 sv=NULL;
13496 package_info=(struct PackageInfo *) NULL;
13497 number_images=0;
13498 ac=(items < 2) ? 1 : items-1;
13499 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13500 keep=list;
13501 length=(STRLEN *) NULL;
13502 if (list == (char **) NULL)
13503 {
13504 ThrowPerlException(exception,ResourceLimitError,
13505 "MemoryAllocationFailed",PackageName);
13506 goto PerlException;
13507 }
13508 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13509 if (length == (STRLEN *) NULL)
13510 {
13511 ThrowPerlException(exception,ResourceLimitError,
13512 "MemoryAllocationFailed",PackageName);
13513 goto PerlException;
13514 }
13515 if (sv_isobject(ST(0)) == 0)
13516 {
13517 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13518 PackageName);
13519 goto PerlException;
13520 }
13521 reference=SvRV(ST(0));
13522 hv=SvSTASH(reference);
13523 if (SvTYPE(reference) != SVt_PVAV)
13524 {
13525 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13526 PackageName);
13527 goto PerlException;
13528 }
13529 av=(AV *) reference;
13530 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13531 exception);
13532 package_info=ClonePackageInfo(info,exception);
13533 n=1;
13534 if (items <= 1)
13535 *list=(char *) (*package_info->image_info->filename ?
13536 package_info->image_info->filename : "XC:black");
13537 else
13538 for (n=0, i=0; i < ac; i++)
13539 {
13540 list[n]=(char *) SvPV(ST(i+1),length[n]);
13541 if ((items >= 3) && strEQcase(list[n],"blob"))
13542 {
13543 void
13544 *blob;
13545
13546 i++;
13547 blob=(void *) (SvPV(ST(i+1),length[n]));
13548 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13549 }
13550 if ((items >= 3) && strEQcase(list[n],"filename"))
13551 continue;
13552 if ((items >= 3) && strEQcase(list[n],"file"))
13553 {
13554 FILE
13555 *file;
13556
13557 PerlIO
13558 *io_info;
13559
13560 i++;
13561 io_info=IoIFP(sv_2io(ST(i+1)));
13562 if (io_info == (PerlIO *) NULL)
13563 {
13564 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13565 PackageName);
13566 continue;
13567 }
13568 file=PerlIO_findFILE(io_info);
13569 if (file == (FILE *) NULL)
13570 {
13571 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13572 PackageName);
13573 continue;
13574 }
13575 SetImageInfoFile(package_info->image_info,file);
13576 }
13577 if ((items >= 3) && strEQcase(list[n],"magick"))
13578 continue;
13579 n++;
13580 }
13581 list[n]=(char *) NULL;
13582 keep=list;
13583 status=ExpandFilenames(&n,&list);
13584 if (status == MagickFalse)
13585 {
13586 ThrowPerlException(exception,ResourceLimitError,
13587 "MemoryAllocationFailed",PackageName);
13588 goto PerlException;
13589 }
13590 number_images=0;
13591 for (i=0; i < n; i++)
13592 {
13593 if ((package_info->image_info->file == (FILE *) NULL) &&
13594 (package_info->image_info->blob == (void *) NULL))
13595 image=ReadImages(package_info->image_info,list[i],exception);
13596 else
13597 {
13598 image=ReadImages(package_info->image_info,
13599 package_info->image_info->filename,exception);
13600 if (image != (Image *) NULL)
13601 DisassociateImageStream(image);
13602 }
13603 if (image == (Image *) NULL)
13604 break;
13605 for ( ; image; image=image->next)
13606 {
13607 AddImageToRegistry(sv,image);
13608 rv=newRV(sv);
13609 av_push(av,sv_bless(rv,hv));
13610 SvREFCNT_dec(sv);
13611 number_images++;
13612 }
13613 }
13614 /*
13615 Free resources.
13616 */
13617 for (i=0; i < n; i++)
13618 if (list[i] != (char *) NULL)
13619 for (p=keep; list[i] != *p++; )
13620 if (*p == (char *) NULL)
13621 {
13622 list[i]=(char *) RelinquishMagickMemory(list[i]);
13623 break;
13624 }
13625
13626 PerlException:
13627 if (package_info != (struct PackageInfo *) NULL)
13628 DestroyPackageInfo(package_info);
13629 if (list && (list != keep))
13630 list=(char **) RelinquishMagickMemory(list);
13631 if (keep)
13632 keep=(char **) RelinquishMagickMemory(keep);
13633 if (length)
13634 length=(STRLEN *) RelinquishMagickMemory(length);
13635 InheritPerlException(exception,perl_exception);
13636 exception=DestroyExceptionInfo(exception);
13637 sv_setiv(perl_exception,(IV) number_images);
13638 SvPOK_on(perl_exception);
13639 ST(0)=sv_2mortal(perl_exception);
13640 XSRETURN(1);
13641 }
13642
13643#
13644###############################################################################
13645# #
13646# #
13647# #
13648# R e m o t e #
13649# #
13650# #
13651# #
13652###############################################################################
13653#
13654#
13655void
13656Remote(ref,...)
13657 Image::Magick ref=NO_INIT
13658 ALIAS:
13659 RemoteCommand = 1
13660 remote = 2
13661 remoteCommand = 3
13662 PPCODE:
13663 {
13664 AV
13665 *av;
13666
13667 ExceptionInfo
13668 *exception;
13669
13670 register ssize_t
13671 i;
13672
13673 SV
13674 *perl_exception,
13675 *reference;
13676
13677 struct PackageInfo
13678 *info;
13679
13680 PERL_UNUSED_VAR(ref);
13681 PERL_UNUSED_VAR(ix);
13682 exception=AcquireExceptionInfo();
13683 perl_exception=newSVpv("",0);
13684 reference=SvRV(ST(0));
13685 av=(AV *) reference;
13686 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13687 exception);
13688 for (i=1; i < items; i++)
13689 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13690 SvPV(ST(i),na),exception);
13691 InheritPerlException(exception,perl_exception);
13692 exception=DestroyExceptionInfo(exception);
13693 SvREFCNT_dec(perl_exception); /* throw away all errors */
13694 }
13695
13696#
13697###############################################################################
13698# #
13699# #
13700# #
13701# S e t #
13702# #
13703# #
13704# #
13705###############################################################################
13706#
13707#
13708void
13709Set(ref,...)
13710 Image::Magick ref=NO_INIT
13711 ALIAS:
13712 SetAttributes = 1
13713 SetAttribute = 2
13714 set = 3
13715 setattributes = 4
13716 setattribute = 5
13717 PPCODE:
13718 {
13719 ExceptionInfo
13720 *exception;
13721
13722 Image
13723 *image;
13724
13725 register ssize_t
13726 i;
13727
13728 struct PackageInfo
13729 *info;
13730
13731 SV
13732 *perl_exception,
13733 *reference; /* reference is the SV* of ref=SvIV(reference) */
13734
13735 PERL_UNUSED_VAR(ref);
13736 PERL_UNUSED_VAR(ix);
13737 exception=AcquireExceptionInfo();
13738 perl_exception=newSVpv("",0);
13739 if (sv_isobject(ST(0)) == 0)
13740 {
13741 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13742 PackageName);
13743 goto PerlException;
13744 }
13745 reference=SvRV(ST(0));
13746 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13747 if (items == 2)
13748 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13749 else
13750 for (i=2; i < items; i+=2)
13751 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13752
13753 PerlException:
13754 InheritPerlException(exception,perl_exception);
13755 exception=DestroyExceptionInfo(exception);
13756 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13757 SvPOK_on(perl_exception);
13758 ST(0)=sv_2mortal(perl_exception);
13759 XSRETURN(1);
13760 }
13761
13762#
13763###############################################################################
13764# #
13765# #
13766# #
13767# S e t P i x e l #
13768# #
13769# #
13770# #
13771###############################################################################
13772#
13773#
13774void
13775SetPixel(ref,...)
13776 Image::Magick ref=NO_INIT
13777 ALIAS:
13778 setpixel = 1
13779 setPixel = 2
13780 PPCODE:
13781 {
13782 AV
13783 *av;
13784
13785 char
13786 *attribute;
13787
13788 ChannelType
13789 channel,
13790 channel_mask;
13791
13792 ExceptionInfo
13793 *exception;
13794
13795 Image
13796 *image;
13797
13798 MagickBooleanType
13799 normalize;
13800
13801 RectangleInfo
13802 region;
13803
13804 register ssize_t
13805 i;
13806
13807 register Quantum
13808 *q;
13809
13810 ssize_t
13811 option;
13812
13813 struct PackageInfo
13814 *info;
13815
13816 SV
13817 *perl_exception,
13818 *reference; /* reference is the SV* of ref=SvIV(reference) */
13819
13820 PERL_UNUSED_VAR(ref);
13821 PERL_UNUSED_VAR(ix);
13822 exception=AcquireExceptionInfo();
13823 perl_exception=newSVpv("",0);
13824 reference=SvRV(ST(0));
13825 av=(AV *) reference;
13826 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13827 exception);
13828 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13829 if (image == (Image *) NULL)
13830 {
13831 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13832 PackageName);
13833 goto PerlException;
13834 }
13835 av=(AV *) NULL;
13836 normalize=MagickTrue;
13837 region.x=0;
13838 region.y=0;
13839 region.width=image->columns;
13840 region.height=1;
13841 if (items == 1)
13842 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
13843 channel=DefaultChannels;
13844 for (i=2; i < items; i+=2)
13845 {
13846 attribute=(char *) SvPV(ST(i-1),na);
13847 switch (*attribute)
13848 {
13849 case 'C':
13850 case 'c':
13851 {
13852 if (LocaleCompare(attribute,"channel") == 0)
13853 {
13854 ssize_t
13855 option;
13856
13857 option=ParseChannelOption(SvPV(ST(i),na));
13858 if (option < 0)
13859 {
13860 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13861 SvPV(ST(i),na));
13862 return;
13863 }
13864 channel=(ChannelType) option;
13865 break;
13866 }
13867 if (LocaleCompare(attribute,"color") == 0)
13868 {
13869 if (SvTYPE(ST(i)) != SVt_RV)
13870 {
13871 char
cristy151b66d2015-04-15 10:50:31 +000013872 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013873
cristy151b66d2015-04-15 10:50:31 +000013874 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000013875 "invalid %.60s value",attribute);
13876 ThrowPerlException(exception,OptionError,message,
13877 SvPV(ST(i),na));
13878 }
13879 av=(AV *) SvRV(ST(i));
13880 break;
13881 }
13882 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13883 attribute);
13884 break;
13885 }
13886 case 'g':
13887 case 'G':
13888 {
13889 if (LocaleCompare(attribute,"geometry") == 0)
13890 {
13891 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
13892 break;
13893 }
13894 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13895 attribute);
13896 break;
13897 }
13898 case 'N':
13899 case 'n':
13900 {
13901 if (LocaleCompare(attribute,"normalize") == 0)
13902 {
13903 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13904 SvPV(ST(i),na));
13905 if (option < 0)
13906 {
13907 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13908 SvPV(ST(i),na));
13909 break;
13910 }
13911 normalize=option != 0 ? MagickTrue : MagickFalse;
13912 break;
13913 }
13914 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13915 attribute);
13916 break;
13917 }
13918 case 'x':
13919 case 'X':
13920 {
13921 if (LocaleCompare(attribute,"x") == 0)
13922 {
13923 region.x=SvIV(ST(i));
13924 break;
13925 }
13926 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13927 attribute);
13928 break;
13929 }
13930 case 'y':
13931 case 'Y':
13932 {
13933 if (LocaleCompare(attribute,"y") == 0)
13934 {
13935 region.y=SvIV(ST(i));
13936 break;
13937 }
13938 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13939 attribute);
13940 break;
13941 }
13942 default:
13943 {
13944 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13945 attribute);
13946 break;
13947 }
13948 }
13949 }
13950 (void) SetImageStorageClass(image,DirectClass,exception);
13951 channel_mask=SetImageChannelMask(image,channel);
13952 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
13953 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
13954 (SvTYPE(av) != SVt_PVAV))
13955 PUSHs(&sv_undef);
13956 else
13957 {
13958 double
13959 scale;
13960
13961 register ssize_t
13962 i;
13963
13964 i=0;
13965 scale=1.0;
13966 if (normalize != MagickFalse)
13967 scale=QuantumRange;
13968 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
13969 (i <= av_len(av)))
13970 {
13971 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
13972 av_fetch(av,i,0)))),q);
13973 i++;
13974 }
13975 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
13976 (i <= av_len(av)))
13977 {
13978 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
13979 av_fetch(av,i,0)))),q);
13980 i++;
13981 }
13982 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
13983 (i <= av_len(av)))
13984 {
13985 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
13986 av_fetch(av,i,0)))),q);
13987 i++;
13988 }
13989 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
13990 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
13991 {
13992 SetPixelBlack(image,ClampToQuantum(scale*
13993 SvNV(*(av_fetch(av,i,0)))),q);
13994 i++;
13995 }
13996 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
13997 (i <= av_len(av)))
13998 {
13999 SetPixelAlpha(image,ClampToQuantum(scale*
14000 SvNV(*(av_fetch(av,i,0)))),q);
14001 i++;
14002 }
14003 (void) SyncAuthenticPixels(image,exception);
14004 }
14005 (void) SetImageChannelMask(image,channel_mask);
14006
14007 PerlException:
14008 InheritPerlException(exception,perl_exception);
14009 exception=DestroyExceptionInfo(exception);
14010 SvREFCNT_dec(perl_exception);
14011 }
14012
14013#
14014###############################################################################
14015# #
14016# #
14017# #
14018# S m u s h #
14019# #
14020# #
14021# #
14022###############################################################################
14023#
14024#
14025void
14026Smush(ref,...)
14027 Image::Magick ref=NO_INIT
14028 ALIAS:
14029 SmushImage = 1
14030 smush = 2
14031 smushimage = 3
14032 PPCODE:
14033 {
14034 AV
14035 *av;
14036
14037 char
14038 *attribute;
14039
14040 ExceptionInfo
14041 *exception;
14042
14043 HV
14044 *hv;
14045
14046 Image
14047 *image;
14048
14049 register ssize_t
14050 i;
14051
14052 ssize_t
14053 offset,
14054 stack;
14055
14056 struct PackageInfo
14057 *info;
14058
14059 SV
14060 *av_reference,
14061 *perl_exception,
14062 *reference,
14063 *rv,
14064 *sv;
14065
14066 PERL_UNUSED_VAR(ref);
14067 PERL_UNUSED_VAR(ix);
14068 exception=AcquireExceptionInfo();
14069 perl_exception=newSVpv("",0);
14070 sv=NULL;
14071 attribute=NULL;
14072 av=NULL;
14073 if (sv_isobject(ST(0)) == 0)
14074 {
14075 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14076 PackageName);
14077 goto PerlException;
14078 }
14079 reference=SvRV(ST(0));
14080 hv=SvSTASH(reference);
14081 av=newAV();
14082 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14083 SvREFCNT_dec(av);
14084 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14085 if (image == (Image *) NULL)
14086 {
14087 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14088 PackageName);
14089 goto PerlException;
14090 }
14091 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14092 /*
14093 Get options.
14094 */
14095 offset=0;
14096 stack=MagickTrue;
14097 for (i=2; i < items; i+=2)
14098 {
14099 attribute=(char *) SvPV(ST(i-1),na);
14100 switch (*attribute)
14101 {
14102 case 'O':
14103 case 'o':
14104 {
14105 if (LocaleCompare(attribute,"offset") == 0)
14106 {
14107 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14108 break;
14109 }
14110 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14111 attribute);
14112 break;
14113 }
14114 case 'S':
14115 case 's':
14116 {
14117 if (LocaleCompare(attribute,"stack") == 0)
14118 {
14119 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14120 SvPV(ST(i),na));
14121 if (stack < 0)
14122 {
14123 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14124 SvPV(ST(i),na));
14125 return;
14126 }
14127 break;
14128 }
14129 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14130 attribute);
14131 break;
14132 }
14133 default:
14134 {
14135 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14136 attribute);
14137 break;
14138 }
14139 }
14140 }
14141 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14142 exception);
14143 if (image == (Image *) NULL)
14144 goto PerlException;
14145 for ( ; image; image=image->next)
14146 {
14147 AddImageToRegistry(sv,image);
14148 rv=newRV(sv);
14149 av_push(av,sv_bless(rv,hv));
14150 SvREFCNT_dec(sv);
14151 }
14152 exception=DestroyExceptionInfo(exception);
14153 ST(0)=av_reference;
14154 SvREFCNT_dec(perl_exception);
14155 XSRETURN(1);
14156
14157 PerlException:
14158 InheritPerlException(exception,perl_exception);
14159 exception=DestroyExceptionInfo(exception);
14160 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14161 SvPOK_on(perl_exception);
14162 ST(0)=sv_2mortal(perl_exception);
14163 XSRETURN(1);
14164 }
14165
14166#
14167###############################################################################
14168# #
14169# #
14170# #
14171# S t a t i s t i c s #
14172# #
14173# #
14174# #
14175###############################################################################
14176#
14177#
14178void
14179Statistics(ref,...)
14180 Image::Magick ref=NO_INIT
14181 ALIAS:
14182 StatisticsImage = 1
14183 statistics = 2
14184 statisticsimage = 3
14185 PPCODE:
14186 {
14187#define ChannelStatistics(channel) \
14188{ \
cristy151b66d2015-04-15 10:50:31 +000014189 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014190 (double) channel_statistics[channel].depth); \
14191 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014192 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014193 channel_statistics[channel].minima/scale); \
14194 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014195 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014196 channel_statistics[channel].maxima/scale); \
14197 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014198 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014199 channel_statistics[channel].mean/scale); \
14200 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014201 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014202 channel_statistics[channel].standard_deviation/scale); \
14203 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014204 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014205 channel_statistics[channel].kurtosis); \
14206 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014207 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014208 channel_statistics[channel].skewness); \
14209 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy151b66d2015-04-15 10:50:31 +000014210 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
cristy275bdd92014-11-08 23:45:03 +000014211 channel_statistics[channel].entropy); \
14212 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014213}
14214
14215 AV
14216 *av;
14217
14218 char
cristy151b66d2015-04-15 10:50:31 +000014219 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014220
14221 ChannelStatistics
14222 *channel_statistics;
14223
14224 double
14225 scale;
14226
14227 ExceptionInfo
14228 *exception;
14229
14230 Image
14231 *image;
14232
14233 ssize_t
14234 count;
14235
14236 struct PackageInfo
14237 *info;
14238
14239 SV
14240 *perl_exception,
14241 *reference;
14242
14243 PERL_UNUSED_VAR(ref);
14244 PERL_UNUSED_VAR(ix);
14245 exception=AcquireExceptionInfo();
14246 perl_exception=newSVpv("",0);
14247 av=NULL;
14248 if (sv_isobject(ST(0)) == 0)
14249 {
14250 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14251 PackageName);
14252 goto PerlException;
14253 }
14254 reference=SvRV(ST(0));
14255 av=newAV();
14256 SvREFCNT_dec(av);
14257 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14258 if (image == (Image *) NULL)
14259 {
14260 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14261 PackageName);
14262 goto PerlException;
14263 }
cristy4a3ce0a2013-08-03 20:06:59 +000014264 count=0;
14265 for ( ; image; image=image->next)
14266 {
14267 channel_statistics=GetImageStatistics(image,exception);
14268 if (channel_statistics == (ChannelStatistics *) NULL)
14269 continue;
14270 count++;
14271 EXTEND(sp,35*count);
14272 scale=(double) QuantumRange;
14273 ChannelStatistics(RedChannel);
14274 ChannelStatistics(GreenChannel);
14275 ChannelStatistics(BlueChannel);
14276 if (image->colorspace == CMYKColorspace)
14277 ChannelStatistics(BlackChannel);
cristy17f11b02014-12-20 19:37:04 +000014278 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000014279 ChannelStatistics(AlphaChannel);
14280 channel_statistics=(ChannelStatistics *)
14281 RelinquishMagickMemory(channel_statistics);
14282 }
14283
14284 PerlException:
14285 InheritPerlException(exception,perl_exception);
14286 exception=DestroyExceptionInfo(exception);
14287 SvREFCNT_dec(perl_exception);
14288 }
14289
14290#
14291###############################################################################
14292# #
14293# #
14294# #
14295# S y n c A u t h e n t i c P i x e l s #
14296# #
14297# #
14298# #
14299###############################################################################
14300#
14301#
14302void
14303SyncAuthenticPixels(ref,...)
14304 Image::Magick ref = NO_INIT
14305 ALIAS:
14306 Syncauthenticpixels = 1
14307 SyncImagePixels = 2
14308 syncimagepixels = 3
14309 CODE:
14310 {
14311 ExceptionInfo
14312 *exception;
14313
14314 Image
14315 *image;
14316
14317 MagickBooleanType
14318 status;
14319
14320 struct PackageInfo
14321 *info;
14322
14323 SV
14324 *perl_exception,
14325 *reference;
14326
14327 PERL_UNUSED_VAR(ref);
14328 PERL_UNUSED_VAR(ix);
14329 exception=AcquireExceptionInfo();
14330 perl_exception=newSVpv("",0);
14331 if (sv_isobject(ST(0)) == 0)
14332 {
14333 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14334 PackageName);
14335 goto PerlException;
14336 }
14337
14338 reference=SvRV(ST(0));
14339 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14340 if (image == (Image *) NULL)
14341 {
14342 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14343 PackageName);
14344 goto PerlException;
14345 }
14346
14347 status=SyncAuthenticPixels(image,exception);
14348 if (status != MagickFalse)
14349 return;
14350
14351 PerlException:
14352 InheritPerlException(exception,perl_exception);
14353 exception=DestroyExceptionInfo(exception);
14354 SvREFCNT_dec(perl_exception); /* throw away all errors */
14355 }
14356
14357#
14358###############################################################################
14359# #
14360# #
14361# #
14362# T r a n s f o r m #
14363# #
14364# #
14365# #
14366###############################################################################
14367#
14368#
14369void
14370Transform(ref,...)
14371 Image::Magick ref=NO_INIT
14372 ALIAS:
14373 TransformImage = 1
14374 transform = 2
14375 transformimage = 3
14376 PPCODE:
14377 {
14378 AV
14379 *av;
14380
14381 char
14382 *attribute,
14383 *crop_geometry,
14384 *geometry;
14385
14386 ExceptionInfo
14387 *exception;
14388
14389 HV
14390 *hv;
14391
14392 Image
14393 *clone,
14394 *image;
14395
14396 register ssize_t
14397 i;
14398
14399 struct PackageInfo
14400 *info;
14401
14402 SV
14403 *av_reference,
14404 *perl_exception,
14405 *reference,
14406 *rv,
14407 *sv;
14408
14409 PERL_UNUSED_VAR(ref);
14410 PERL_UNUSED_VAR(ix);
14411 exception=AcquireExceptionInfo();
14412 perl_exception=newSVpv("",0);
14413 sv=NULL;
14414 av=NULL;
14415 attribute=NULL;
14416 if (sv_isobject(ST(0)) == 0)
14417 {
14418 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14419 PackageName);
14420 goto PerlException;
14421 }
14422 reference=SvRV(ST(0));
14423 hv=SvSTASH(reference);
14424 av=newAV();
14425 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14426 SvREFCNT_dec(av);
14427 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14428 if (image == (Image *) NULL)
14429 {
14430 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14431 PackageName);
14432 goto PerlException;
14433 }
14434 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14435 /*
14436 Get attribute.
14437 */
14438 crop_geometry=(char *) NULL;
14439 geometry=(char *) NULL;
14440 for (i=2; i < items; i+=2)
14441 {
14442 attribute=(char *) SvPV(ST(i-1),na);
14443 switch (*attribute)
14444 {
14445 case 'c':
14446 case 'C':
14447 {
14448 if (LocaleCompare(attribute,"crop") == 0)
14449 {
14450 crop_geometry=SvPV(ST(i),na);
14451 break;
14452 }
14453 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14454 attribute);
14455 break;
14456 }
14457 case 'g':
14458 case 'G':
14459 {
14460 if (LocaleCompare(attribute,"geometry") == 0)
14461 {
14462 geometry=SvPV(ST(i),na);
14463 break;
14464 }
14465 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14466 attribute);
14467 break;
14468 }
14469 default:
14470 {
14471 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14472 attribute);
14473 break;
14474 }
14475 }
14476 }
14477 for ( ; image; image=image->next)
14478 {
14479 clone=CloneImage(image,0,0,MagickTrue,exception);
14480 if (clone == (Image *) NULL)
14481 goto PerlException;
14482 TransformImage(&clone,crop_geometry,geometry,exception);
14483 for ( ; clone; clone=clone->next)
14484 {
14485 AddImageToRegistry(sv,clone);
14486 rv=newRV(sv);
14487 av_push(av,sv_bless(rv,hv));
14488 SvREFCNT_dec(sv);
14489 }
14490 }
14491 exception=DestroyExceptionInfo(exception);
14492 ST(0)=av_reference;
14493 SvREFCNT_dec(perl_exception); /* can't return warning messages */
14494 XSRETURN(1);
14495
14496 PerlException:
14497 InheritPerlException(exception,perl_exception);
14498 exception=DestroyExceptionInfo(exception);
14499 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14500 SvPOK_on(perl_exception);
14501 ST(0)=sv_2mortal(perl_exception);
14502 XSRETURN(1);
14503 }
14504
14505#
14506###############################################################################
14507# #
14508# #
14509# #
14510# W r i t e #
14511# #
14512# #
14513# #
14514###############################################################################
14515#
14516#
14517void
14518Write(ref,...)
14519 Image::Magick ref=NO_INIT
14520 ALIAS:
14521 WriteImage = 1
14522 write = 2
14523 writeimage = 3
14524 PPCODE:
14525 {
14526 char
cristy151b66d2015-04-15 10:50:31 +000014527 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014528
14529 ExceptionInfo
14530 *exception;
14531
14532 Image
14533 *image,
14534 *next;
14535
14536 register ssize_t
14537 i;
14538
14539 ssize_t
14540 number_images,
14541 scene;
14542
14543 struct PackageInfo
14544 *info,
14545 *package_info;
14546
14547 SV
14548 *perl_exception,
14549 *reference;
14550
14551 PERL_UNUSED_VAR(ref);
14552 PERL_UNUSED_VAR(ix);
14553 exception=AcquireExceptionInfo();
14554 perl_exception=newSVpv("",0);
14555 number_images=0;
14556 package_info=(struct PackageInfo *) NULL;
14557 if (sv_isobject(ST(0)) == 0)
14558 {
14559 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14560 PackageName);
14561 goto PerlException;
14562 }
14563 reference=SvRV(ST(0));
14564 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14565 if (image == (Image *) NULL)
14566 {
14567 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14568 PackageName);
14569 goto PerlException;
14570 }
14571 package_info=ClonePackageInfo(info,exception);
14572 if (items == 2)
14573 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14574 else
14575 if (items > 2)
14576 for (i=2; i < items; i+=2)
14577 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14578 exception);
14579 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014580 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014581 scene=0;
14582 for (next=image; next; next=next->next)
14583 {
cristy151b66d2015-04-15 10:50:31 +000014584 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014585 next->scene=scene++;
14586 }
cristy68bd79a2015-02-25 12:23:36 +000014587 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014588 SetImageInfo(package_info->image_info,(unsigned int)
14589 GetImageListLength(image),exception);
14590 for (next=image; next; next=next->next)
14591 {
14592 (void) WriteImage(package_info->image_info,next,exception);
14593 number_images++;
14594 if (package_info->image_info->adjoin)
14595 break;
14596 }
14597
14598 PerlException:
14599 if (package_info != (struct PackageInfo *) NULL)
14600 DestroyPackageInfo(package_info);
14601 InheritPerlException(exception,perl_exception);
14602 exception=DestroyExceptionInfo(exception);
14603 sv_setiv(perl_exception,(IV) number_images);
14604 SvPOK_on(perl_exception);
14605 ST(0)=sv_2mortal(perl_exception);
14606 XSRETURN(1);
14607 }