blob: e4eb6df61d1358c02072b3cb1f40b5a686d1c684 [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% %
cristyfe676ee2013-11-18 13:03:38 +000026% Copyright 1999-2014 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 \
116 message[MaxTextExtent]; \
117 \
118 if ((exception)->severity != UndefinedException) \
119 { \
120 (void) FormatLocaleString(message,MaxTextExtent,"Exception %d: %s%s%s%s",\
121 (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},
221 {"y", IntegerReference} } },
222 { "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} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000550 };
551
552static SplayTreeInfo
553 *magick_registry = (SplayTreeInfo *) NULL;
554
555/*
556 Forward declarations.
557*/
558static Image
559 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
560
561static ssize_t
562 strEQcase(const char *,const char *);
563
564/*
565%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
566% %
567% %
568% %
569% C l o n e P a c k a g e I n f o %
570% %
571% %
572% %
573%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
574%
575% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
576% a new one.
577%
578% The format of the ClonePackageInfo routine is:
579%
580% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
581% exception)
582%
583% A description of each parameter follows:
584%
585% o info: a structure of type info.
586%
587% o exception: Return any errors or warnings in this structure.
588%
589*/
590static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
591 ExceptionInfo *exception)
592{
593 struct PackageInfo
594 *clone_info;
595
596 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
597 if (clone_info == (struct PackageInfo *) NULL)
598 {
599 ThrowPerlException(exception,ResourceLimitError,
600 "UnableToClonePackageInfo",PackageName);
601 return((struct PackageInfo *) NULL);
602 }
603 if (info == (struct PackageInfo *) NULL)
604 {
605 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
606 return(clone_info);
607 }
608 *clone_info=(*info);
609 clone_info->image_info=CloneImageInfo(info->image_info);
610 return(clone_info);
611}
612
613/*
614%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
615% %
616% %
617% %
618% c o n s t a n t %
619% %
620% %
621% %
622%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
623%
624% constant() returns a double value for the specified name.
625%
626% The format of the constant routine is:
627%
628% double constant(char *name,ssize_t sans)
629%
630% A description of each parameter follows:
631%
632% o value: Method constant returns a double value for the specified name.
633%
634% o name: The name of the constant.
635%
636% o sans: This integer value is not used.
637%
638*/
639static double constant(char *name,ssize_t sans)
640{
641 (void) sans;
642 errno=0;
643 switch (*name)
644 {
645 case 'B':
646 {
647 if (strEQ(name,"BlobError"))
648 return(BlobError);
649 if (strEQ(name,"BlobWarning"))
650 return(BlobWarning);
651 break;
652 }
653 case 'C':
654 {
655 if (strEQ(name,"CacheError"))
656 return(CacheError);
657 if (strEQ(name,"CacheWarning"))
658 return(CacheWarning);
659 if (strEQ(name,"CoderError"))
660 return(CoderError);
661 if (strEQ(name,"CoderWarning"))
662 return(CoderWarning);
663 if (strEQ(name,"ConfigureError"))
664 return(ConfigureError);
665 if (strEQ(name,"ConfigureWarning"))
666 return(ConfigureWarning);
667 if (strEQ(name,"CorruptImageError"))
668 return(CorruptImageError);
669 if (strEQ(name,"CorruptImageWarning"))
670 return(CorruptImageWarning);
671 break;
672 }
673 case 'D':
674 {
675 if (strEQ(name,"DelegateError"))
676 return(DelegateError);
677 if (strEQ(name,"DelegateWarning"))
678 return(DelegateWarning);
679 if (strEQ(name,"DrawError"))
680 return(DrawError);
681 if (strEQ(name,"DrawWarning"))
682 return(DrawWarning);
683 break;
684 }
685 case 'E':
686 {
687 if (strEQ(name,"ErrorException"))
688 return(ErrorException);
689 if (strEQ(name,"ExceptionError"))
690 return(CoderError);
691 if (strEQ(name,"ExceptionWarning"))
692 return(CoderWarning);
693 break;
694 }
695 case 'F':
696 {
697 if (strEQ(name,"FatalErrorException"))
698 return(FatalErrorException);
699 if (strEQ(name,"FileOpenError"))
700 return(FileOpenError);
701 if (strEQ(name,"FileOpenWarning"))
702 return(FileOpenWarning);
703 break;
704 }
705 case 'I':
706 {
707 if (strEQ(name,"ImageError"))
708 return(ImageError);
709 if (strEQ(name,"ImageWarning"))
710 return(ImageWarning);
711 break;
712 }
713 case 'M':
714 {
715 if (strEQ(name,"MaxRGB"))
716 return(QuantumRange);
717 if (strEQ(name,"MissingDelegateError"))
718 return(MissingDelegateError);
719 if (strEQ(name,"MissingDelegateWarning"))
720 return(MissingDelegateWarning);
721 if (strEQ(name,"ModuleError"))
722 return(ModuleError);
723 if (strEQ(name,"ModuleWarning"))
724 return(ModuleWarning);
725 break;
726 }
727 case 'O':
728 {
729 if (strEQ(name,"Opaque"))
730 return(OpaqueAlpha);
731 if (strEQ(name,"OptionError"))
732 return(OptionError);
733 if (strEQ(name,"OptionWarning"))
734 return(OptionWarning);
735 break;
736 }
737 case 'Q':
738 {
739 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
740 return(MAGICKCORE_QUANTUM_DEPTH);
741 if (strEQ(name,"QuantumDepth"))
742 return(MAGICKCORE_QUANTUM_DEPTH);
743 if (strEQ(name,"QuantumRange"))
744 return(QuantumRange);
745 break;
746 }
747 case 'R':
748 {
749 if (strEQ(name,"ResourceLimitError"))
750 return(ResourceLimitError);
751 if (strEQ(name,"ResourceLimitWarning"))
752 return(ResourceLimitWarning);
753 if (strEQ(name,"RegistryError"))
754 return(RegistryError);
755 if (strEQ(name,"RegistryWarning"))
756 return(RegistryWarning);
757 break;
758 }
759 case 'S':
760 {
761 if (strEQ(name,"StreamError"))
762 return(StreamError);
763 if (strEQ(name,"StreamWarning"))
764 return(StreamWarning);
765 if (strEQ(name,"Success"))
766 return(0);
767 break;
768 }
769 case 'T':
770 {
771 if (strEQ(name,"Transparent"))
772 return(TransparentAlpha);
773 if (strEQ(name,"TypeError"))
774 return(TypeError);
775 if (strEQ(name,"TypeWarning"))
776 return(TypeWarning);
777 break;
778 }
779 case 'W':
780 {
781 if (strEQ(name,"WarningException"))
782 return(WarningException);
783 break;
784 }
785 case 'X':
786 {
787 if (strEQ(name,"XServerError"))
788 return(XServerError);
789 if (strEQ(name,"XServerWarning"))
790 return(XServerWarning);
791 break;
792 }
793 }
794 errno=EINVAL;
795 return(0);
796}
797
798/*
799%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
800% %
801% %
802% %
803% D e s t r o y P a c k a g e I n f o %
804% %
805% %
806% %
807%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
808%
809% Method DestroyPackageInfo frees a previously created info structure.
810%
811% The format of the DestroyPackageInfo routine is:
812%
813% DestroyPackageInfo(struct PackageInfo *info)
814%
815% A description of each parameter follows:
816%
817% o info: a structure of type info.
818%
819*/
820static void DestroyPackageInfo(struct PackageInfo *info)
821{
822 info->image_info=DestroyImageInfo(info->image_info);
823 info=(struct PackageInfo *) RelinquishMagickMemory(info);
824}
825
826/*
827%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
828% %
829% %
830% %
831% G e t L i s t %
832% %
833% %
834% %
835%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
836%
837% Method GetList is recursively called by SetupList to traverse the
838% Image__Magick reference. If building an reference_vector (see SetupList),
839% *current is the current position in *reference_vector and *last is the final
840% entry in *reference_vector.
841%
842% The format of the GetList routine is:
843%
844% GetList(info)
845%
846% A description of each parameter follows:
847%
848% o info: a structure of type info.
849%
850*/
851static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
852 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
853{
854 Image
855 *image;
856
857 if (reference == (SV *) NULL)
858 return(NULL);
859 switch (SvTYPE(reference))
860 {
861 case SVt_PVAV:
862 {
863 AV
864 *av;
865
866 Image
867 *head,
868 *previous;
869
870 register ssize_t
871 i;
872
873 ssize_t
874 n;
875
876 /*
877 Array of images.
878 */
879 previous=(Image *) NULL;
880 head=(Image *) NULL;
881 av=(AV *) reference;
882 n=av_len(av);
883 for (i=0; i <= n; i++)
884 {
885 SV
886 **rv;
887
888 rv=av_fetch(av,i,0);
889 if (rv && *rv && sv_isobject(*rv))
890 {
891 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
892 exception);
893 if (image == (Image *) NULL)
894 continue;
895 if (image == previous)
896 {
897 image=CloneImage(image,0,0,MagickTrue,exception);
898 if (image == (Image *) NULL)
899 return(NULL);
900 }
901 image->previous=previous;
902 *(previous ? &previous->next : &head)=image;
903 for (previous=image; previous->next; previous=previous->next) ;
904 }
905 }
906 return(head);
907 }
908 case SVt_PVMG:
909 {
910 /*
911 Blessed scalar, one image.
912 */
913 image=INT2PTR(Image *,SvIV(reference));
914 if (image == (Image *) NULL)
915 return(NULL);
916 image->previous=(Image *) NULL;
917 image->next=(Image *) NULL;
918 if (reference_vector)
919 {
920 if (*current == *last)
921 {
922 *last+=256;
923 if (*reference_vector == (SV **) NULL)
924 *reference_vector=(SV **) AcquireQuantumMemory(*last,
925 sizeof(*reference_vector));
926 else
927 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
928 *last,sizeof(*reference_vector));
929 }
930 if (*reference_vector == (SV **) NULL)
931 {
932 ThrowPerlException(exception,ResourceLimitError,
933 "MemoryAllocationFailed",PackageName);
934 return((Image *) NULL);
935 }
936 (*reference_vector)[*current]=reference;
937 (*reference_vector)[++(*current)]=NULL;
938 }
939 return(image);
940 }
941 default:
942 break;
943 }
944 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
945 (double) SvTYPE(reference));
946 return((Image *) NULL);
947}
948
949/*
950%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
951% %
952% %
953% %
954% G e t P a c k a g e I n f o %
955% %
956% %
957% %
958%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
959%
960% Method GetPackageInfo looks up or creates an info structure for the given
961% Image__Magick reference. If it does create a new one, the information in
962% package_info is used to initialize it.
963%
964% The format of the GetPackageInfo routine is:
965%
966% struct PackageInfo *GetPackageInfo(void *reference,
967% struct PackageInfo *package_info,ExceptionInfo *exception)
968%
969% A description of each parameter follows:
970%
971% o info: a structure of type info.
972%
973% o exception: Return any errors or warnings in this structure.
974%
975*/
976static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
977 struct PackageInfo *package_info,ExceptionInfo *exception)
978{
979 char
980 message[MaxTextExtent];
981
982 struct PackageInfo
983 *clone_info;
984
985 SV
986 *sv;
987
988 (void) FormatLocaleString(message,MaxTextExtent,"%s::package%s%p",
989 PackageName,XS_VERSION,reference);
990 sv=perl_get_sv(message,(TRUE | 0x02));
991 if (sv == (SV *) NULL)
992 {
993 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
994 message);
995 return(package_info);
996 }
997 if (SvREFCNT(sv) == 0)
998 (void) SvREFCNT_inc(sv);
999 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1000 return(clone_info);
1001 clone_info=ClonePackageInfo(package_info,exception);
1002 sv_setiv(sv,PTR2IV(clone_info));
1003 return(clone_info);
1004}
1005
1006/*
1007%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1008% %
1009% %
1010% %
1011% S e t A t t r i b u t e %
1012% %
1013% %
1014% %
1015%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1016%
1017% SetAttribute() sets the attribute to the value in sval. This can change
1018% either or both of image or info.
1019%
1020% The format of the SetAttribute routine is:
1021%
1022% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1023% SV *sval,ExceptionInfo *exception)
1024%
1025% A description of each parameter follows:
1026%
1027% o list: a list of strings.
1028%
1029% o string: a character string.
1030%
1031*/
1032
1033static double SiPrefixToDoubleInterval(const char *string,const double interval)
1034{
1035 char
1036 *q;
1037
1038 double
1039 value;
1040
1041 value=InterpretSiPrefixValue(string,&q);
1042 if (*q == '%')
1043 value*=interval/100.0;
1044 return(value);
1045}
1046
1047static inline double StringToDouble(const char *string,char **sentinal)
1048{
1049 return(InterpretLocaleValue(string,sentinal));
1050}
1051
1052static double StringToDoubleInterval(const char *string,const double interval)
1053{
1054 char
1055 *q;
1056
1057 double
1058 value;
1059
1060 value=InterpretLocaleValue(string,&q);
1061 if (*q == '%')
1062 value*=interval/100.0;
1063 return(value);
1064}
1065
1066static inline ssize_t StringToLong(const char *value)
1067{
1068 return(strtol(value,(char **) NULL,10));
1069}
1070
1071static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1072 const char *attribute,SV *sval,ExceptionInfo *exception)
1073{
1074 GeometryInfo
1075 geometry_info;
1076
1077 long
1078 x,
1079 y;
1080
1081 PixelInfo
1082 pixel;
1083
1084 MagickStatusType
1085 flags;
1086
1087 PixelInfo
1088 *color,
1089 target_color;
1090
1091 ssize_t
1092 sp;
1093
1094 switch (*attribute)
1095 {
1096 case 'A':
1097 case 'a':
1098 {
1099 if (LocaleCompare(attribute,"adjoin") == 0)
1100 {
1101 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1102 SvPV(sval,na)) : SvIV(sval);
1103 if (sp < 0)
1104 {
1105 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1106 SvPV(sval,na));
1107 break;
1108 }
1109 if (info)
1110 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1111 break;
1112 }
1113 if (LocaleCompare(attribute,"alpha") == 0)
1114 {
1115 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1116 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1117 if (sp < 0)
1118 {
1119 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1120 SvPV(sval,na));
1121 break;
1122 }
1123 for ( ; image; image=image->next)
1124 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1125 exception);
1126 break;
1127 }
1128 if (LocaleCompare(attribute,"antialias") == 0)
1129 {
1130 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1131 SvPV(sval,na)) : SvIV(sval);
1132 if (sp < 0)
1133 {
1134 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1135 SvPV(sval,na));
1136 break;
1137 }
1138 if (info)
1139 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1140 break;
1141 }
1142 if (LocaleCompare(attribute,"area-limit") == 0)
1143 {
1144 MagickSizeType
1145 limit;
1146
1147 limit=MagickResourceInfinity;
1148 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1149 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1150 100.0);
1151 (void) SetMagickResourceLimit(AreaResource,limit);
1152 break;
1153 }
1154 if (LocaleCompare(attribute,"attenuate") == 0)
1155 {
1156 if (info)
1157 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1158 break;
1159 }
1160 if (LocaleCompare(attribute,"authenticate") == 0)
1161 {
1162 if (info)
1163 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1164 break;
1165 }
1166 if (info)
1167 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1168 for ( ; image; image=image->next)
1169 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1170 break;
1171 }
1172 case 'B':
1173 case 'b':
1174 {
1175 if (LocaleCompare(attribute,"background") == 0)
1176 {
1177 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1178 exception);
1179 if (info)
1180 info->image_info->background_color=target_color;
1181 for ( ; image; image=image->next)
1182 image->background_color=target_color;
1183 break;
1184 }
1185 if (LocaleCompare(attribute,"blue-primary") == 0)
1186 {
1187 for ( ; image; image=image->next)
1188 {
1189 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1190 image->chromaticity.blue_primary.x=geometry_info.rho;
1191 image->chromaticity.blue_primary.y=geometry_info.sigma;
1192 if ((flags & SigmaValue) == 0)
1193 image->chromaticity.blue_primary.y=
1194 image->chromaticity.blue_primary.x;
1195 }
1196 break;
1197 }
1198 if (LocaleCompare(attribute,"bordercolor") == 0)
1199 {
1200 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1201 exception);
1202 if (info)
1203 info->image_info->border_color=target_color;
1204 for ( ; image; image=image->next)
1205 image->border_color=target_color;
1206 break;
1207 }
1208 if (info)
1209 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1210 for ( ; image; image=image->next)
1211 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1212 break;
1213 }
1214 case 'C':
1215 case 'c':
1216 {
1217 if (LocaleCompare(attribute,"cache-threshold") == 0)
1218 {
1219 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1220 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1221 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1222 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1223 break;
1224 }
1225 if (LocaleCompare(attribute,"clip-mask") == 0)
1226 {
1227 Image
1228 *clip_mask;
1229
1230 clip_mask=(Image *) NULL;
1231 if (SvPOK(sval))
1232 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1233 for ( ; image; image=image->next)
1234 SetImageMask(image,clip_mask,exception);
1235 break;
1236 }
1237 if (LocaleNCompare(attribute,"colormap",8) == 0)
1238 {
1239 for ( ; image; image=image->next)
1240 {
1241 int
1242 items;
1243
1244 long
1245 i;
1246
1247 if (image->storage_class == DirectClass)
1248 continue;
1249 i=0;
1250 items=sscanf(attribute,"%*[^[][%ld",&i);
1251 (void) items;
1252 if (i > (ssize_t) image->colors)
1253 i%=image->colors;
1254 if ((strchr(SvPV(sval,na),',') == 0) ||
1255 (strchr(SvPV(sval,na),')') != 0))
1256 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1257 image->colormap+i,exception);
1258 else
1259 {
1260 color=image->colormap+i;
1261 pixel.red=color->red;
1262 pixel.green=color->green;
1263 pixel.blue=color->blue;
1264 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1265 pixel.red=geometry_info.rho;
1266 pixel.green=geometry_info.sigma;
1267 pixel.blue=geometry_info.xi;
1268 color->red=ClampToQuantum(pixel.red);
1269 color->green=ClampToQuantum(pixel.green);
1270 color->blue=ClampToQuantum(pixel.blue);
1271 }
1272 }
1273 break;
1274 }
1275 if (LocaleCompare(attribute,"colorspace") == 0)
1276 {
1277 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1278 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1279 if (sp < 0)
1280 {
1281 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1282 SvPV(sval,na));
1283 break;
1284 }
1285 for ( ; image; image=image->next)
1286 (void) TransformImageColorspace(image,(ColorspaceType) sp,
1287 exception);
1288 break;
1289 }
1290 if (LocaleCompare(attribute,"comment") == 0)
1291 {
1292 for ( ; image; image=image->next)
1293 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1294 info ? info->image_info : (ImageInfo *) NULL,image,
1295 SvPV(sval,na),exception),exception);
1296 break;
1297 }
1298 if (LocaleCompare(attribute,"compression") == 0)
1299 {
1300 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1301 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1302 if (sp < 0)
1303 {
1304 ThrowPerlException(exception,OptionError,
1305 "UnrecognizedImageCompression",SvPV(sval,na));
1306 break;
1307 }
1308 if (info)
1309 info->image_info->compression=(CompressionType) sp;
1310 for ( ; image; image=image->next)
1311 image->compression=(CompressionType) sp;
1312 break;
1313 }
1314 if (info)
1315 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1316 for ( ; image; image=image->next)
1317 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1318 break;
1319 }
1320 case 'D':
1321 case 'd':
1322 {
1323 if (LocaleCompare(attribute,"debug") == 0)
1324 {
1325 SetLogEventMask(SvPV(sval,na));
1326 break;
1327 }
1328 if (LocaleCompare(attribute,"delay") == 0)
1329 {
1330 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1331 for ( ; image; image=image->next)
1332 {
1333 image->delay=(size_t) floor(geometry_info.rho+0.5);
1334 if ((flags & SigmaValue) != 0)
1335 image->ticks_per_second=(ssize_t)
1336 floor(geometry_info.sigma+0.5);
1337 }
1338 break;
1339 }
1340 if (LocaleCompare(attribute,"disk-limit") == 0)
1341 {
1342 MagickSizeType
1343 limit;
1344
1345 limit=MagickResourceInfinity;
1346 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1347 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1348 100.0);
1349 (void) SetMagickResourceLimit(DiskResource,limit);
1350 break;
1351 }
1352 if (LocaleCompare(attribute,"density") == 0)
1353 {
1354 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1355 {
1356 ThrowPerlException(exception,OptionError,"MissingGeometry",
1357 SvPV(sval,na));
1358 break;
1359 }
1360 if (info)
1361 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1362 for ( ; image; image=image->next)
1363 {
1364 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1365 image->resolution.x=geometry_info.rho;
1366 image->resolution.y=geometry_info.sigma;
1367 if ((flags & SigmaValue) == 0)
1368 image->resolution.y=image->resolution.x;
1369 }
1370 break;
1371 }
1372 if (LocaleCompare(attribute,"depth") == 0)
1373 {
1374 if (info)
1375 info->image_info->depth=SvIV(sval);
1376 for ( ; image; image=image->next)
1377 (void) SetImageDepth(image,SvIV(sval),exception);
1378 break;
1379 }
1380 if (LocaleCompare(attribute,"dispose") == 0)
1381 {
1382 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1383 SvPV(sval,na)) : SvIV(sval);
1384 if (sp < 0)
1385 {
1386 ThrowPerlException(exception,OptionError,
1387 "UnrecognizedDisposeMethod",SvPV(sval,na));
1388 break;
1389 }
1390 for ( ; image; image=image->next)
1391 image->dispose=(DisposeType) sp;
1392 break;
1393 }
1394 if (LocaleCompare(attribute,"dither") == 0)
1395 {
1396 if (info)
1397 {
1398 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1399 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1400 if (sp < 0)
1401 {
1402 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1403 SvPV(sval,na));
1404 break;
1405 }
1406 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1407 }
1408 break;
1409 }
1410 if (LocaleCompare(attribute,"display") == 0)
1411 {
1412 display:
1413 if (info)
1414 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1415 break;
1416 }
1417 if (info)
1418 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1419 for ( ; image; image=image->next)
1420 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1421 break;
1422 }
1423 case 'E':
1424 case 'e':
1425 {
1426 if (LocaleCompare(attribute,"endian") == 0)
1427 {
1428 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1429 SvPV(sval,na)) : SvIV(sval);
1430 if (sp < 0)
1431 {
1432 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1433 SvPV(sval,na));
1434 break;
1435 }
1436 if (info)
1437 info->image_info->endian=(EndianType) sp;
1438 for ( ; image; image=image->next)
1439 image->endian=(EndianType) sp;
1440 break;
1441 }
1442 if (LocaleCompare(attribute,"extract") == 0)
1443 {
1444 /*
1445 Set image extract geometry.
1446 */
1447 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1448 break;
1449 }
1450 if (info)
1451 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1452 for ( ; image; image=image->next)
1453 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1454 break;
1455 }
1456 case 'F':
1457 case 'f':
1458 {
1459 if (LocaleCompare(attribute,"filename") == 0)
1460 {
1461 if (info)
1462 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
1463 MaxTextExtent);
1464 for ( ; image; image=image->next)
1465 (void) CopyMagickString(image->filename,SvPV(sval,na),
1466 MaxTextExtent);
1467 break;
1468 }
1469 if (LocaleCompare(attribute,"file") == 0)
1470 {
1471 FILE
1472 *file;
1473
1474 PerlIO
1475 *io_info;
1476
1477 if (info == (struct PackageInfo *) NULL)
1478 break;
1479 io_info=IoIFP(sv_2io(sval));
1480 if (io_info == (PerlIO *) NULL)
1481 {
1482 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1483 PackageName);
1484 break;
1485 }
1486 file=PerlIO_findFILE(io_info);
1487 if (file == (FILE *) NULL)
1488 {
1489 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1490 PackageName);
1491 break;
1492 }
1493 SetImageInfoFile(info->image_info,file);
1494 break;
1495 }
1496 if (LocaleCompare(attribute,"fill") == 0)
1497 {
1498 if (info)
1499 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1500 break;
1501 }
1502 if (LocaleCompare(attribute,"font") == 0)
1503 {
1504 if (info)
1505 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1506 break;
1507 }
1508 if (LocaleCompare(attribute,"foreground") == 0)
1509 break;
1510 if (LocaleCompare(attribute,"fuzz") == 0)
1511 {
1512 if (info)
1513 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1514 QuantumRange+1.0);
1515 for ( ; image; image=image->next)
1516 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1517 QuantumRange+1.0);
1518 break;
1519 }
1520 if (info)
1521 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1522 for ( ; image; image=image->next)
1523 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1524 break;
1525 }
1526 case 'G':
1527 case 'g':
1528 {
1529 if (LocaleCompare(attribute,"gamma") == 0)
1530 {
1531 for ( ; image; image=image->next)
1532 image->gamma=SvNV(sval);
1533 break;
1534 }
1535 if (LocaleCompare(attribute,"gravity") == 0)
1536 {
1537 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1538 SvPV(sval,na)) : SvIV(sval);
1539 if (sp < 0)
1540 {
1541 ThrowPerlException(exception,OptionError,
1542 "UnrecognizedGravityType",SvPV(sval,na));
1543 break;
1544 }
1545 if (info)
1546 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1547 for ( ; image; image=image->next)
1548 image->gravity=(GravityType) sp;
1549 break;
1550 }
1551 if (LocaleCompare(attribute,"green-primary") == 0)
1552 {
1553 for ( ; image; image=image->next)
1554 {
1555 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1556 image->chromaticity.green_primary.x=geometry_info.rho;
1557 image->chromaticity.green_primary.y=geometry_info.sigma;
1558 if ((flags & SigmaValue) == 0)
1559 image->chromaticity.green_primary.y=
1560 image->chromaticity.green_primary.x;
1561 }
1562 break;
1563 }
1564 if (info)
1565 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1566 for ( ; image; image=image->next)
1567 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1568 break;
1569 }
1570 case 'I':
1571 case 'i':
1572 {
1573 if (LocaleNCompare(attribute,"index",5) == 0)
1574 {
1575 int
1576 items;
1577
1578 long
1579 index;
1580
1581 register Quantum
1582 *q;
1583
1584 CacheView
1585 *image_view;
1586
1587 for ( ; image; image=image->next)
1588 {
1589 if (image->storage_class != PseudoClass)
1590 continue;
1591 x=0;
1592 y=0;
1593 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1594 (void) items;
1595 image_view=AcquireAuthenticCacheView(image,exception);
1596 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1597 if (q != (Quantum *) NULL)
1598 {
1599 items=sscanf(SvPV(sval,na),"%ld",&index);
1600 if ((index >= 0) && (index < (ssize_t) image->colors))
1601 SetPixelIndex(image,index,q);
1602 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1603 }
1604 image_view=DestroyCacheView(image_view);
1605 }
1606 break;
1607 }
1608 if (LocaleCompare(attribute,"iterations") == 0)
1609 {
1610 iterations:
1611 for ( ; image; image=image->next)
1612 image->iterations=SvIV(sval);
1613 break;
1614 }
1615 if (LocaleCompare(attribute,"interlace") == 0)
1616 {
1617 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1618 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1619 if (sp < 0)
1620 {
1621 ThrowPerlException(exception,OptionError,
1622 "UnrecognizedInterlaceType",SvPV(sval,na));
1623 break;
1624 }
1625 if (info)
1626 info->image_info->interlace=(InterlaceType) sp;
1627 for ( ; image; image=image->next)
1628 image->interlace=(InterlaceType) sp;
1629 break;
1630 }
1631 if (info)
1632 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1633 for ( ; image; image=image->next)
1634 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1635 break;
1636 }
1637 case 'L':
1638 case 'l':
1639 {
1640 if (LocaleCompare(attribute,"label") == 0)
1641 {
1642 for ( ; image; image=image->next)
1643 (void) SetImageProperty(image,"label",InterpretImageProperties(
1644 info ? info->image_info : (ImageInfo *) NULL,image,
1645 SvPV(sval,na),exception),exception);
1646 break;
1647 }
1648 if (LocaleCompare(attribute,"loop") == 0)
1649 goto iterations;
1650 if (info)
1651 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1652 for ( ; image; image=image->next)
1653 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1654 break;
1655 }
1656 case 'M':
1657 case 'm':
1658 {
1659 if (LocaleCompare(attribute,"magick") == 0)
1660 {
1661 if (info)
1662 (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
1663 "%s:",SvPV(sval,na));
1664 for ( ; image; image=image->next)
1665 (void) CopyMagickString(image->magick,SvPV(sval,na),MaxTextExtent);
1666 break;
1667 }
1668 if (LocaleCompare(attribute,"map-limit") == 0)
1669 {
1670 MagickSizeType
1671 limit;
1672
1673 limit=MagickResourceInfinity;
1674 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1675 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1676 100.0);
1677 (void) SetMagickResourceLimit(MapResource,limit);
1678 break;
1679 }
1680 if (LocaleCompare(attribute,"mask") == 0)
1681 {
1682 Image
1683 *mask;
1684
1685 mask=(Image *) NULL;
1686 if (SvPOK(sval))
1687 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1688 for ( ; image; image=image->next)
1689 SetImageMask(image,mask,exception);
1690 break;
1691 }
1692 if (LocaleCompare(attribute,"mattecolor") == 0)
1693 {
1694 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1695 exception);
1696 if (info)
1697 info->image_info->matte_color=target_color;
1698 for ( ; image; image=image->next)
1699 image->matte_color=target_color;
1700 break;
1701 }
1702 if (LocaleCompare(attribute,"matte") == 0)
1703 {
1704 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1705 SvPV(sval,na)) : SvIV(sval);
1706 if (sp < 0)
1707 {
1708 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1709 SvPV(sval,na));
1710 break;
1711 }
1712 for ( ; image; image=image->next)
1713 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1714 break;
1715 }
1716 if (LocaleCompare(attribute,"memory-limit") == 0)
1717 {
1718 MagickSizeType
1719 limit;
1720
1721 limit=MagickResourceInfinity;
1722 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1723 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1724 100.0);
1725 (void) SetMagickResourceLimit(MemoryResource,limit);
1726 break;
1727 }
1728 if (LocaleCompare(attribute,"monochrome") == 0)
1729 {
1730 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1731 SvPV(sval,na)) : SvIV(sval);
1732 if (sp < 0)
1733 {
1734 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1735 SvPV(sval,na));
1736 break;
1737 }
1738 if (info)
1739 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1740 for ( ; image; image=image->next)
1741 (void) SetImageType(image,BilevelType,exception);
1742 break;
1743 }
1744 if (info)
1745 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1746 for ( ; image; image=image->next)
1747 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1748 break;
1749 }
1750 case 'O':
1751 case 'o':
1752 {
1753 if (LocaleCompare(attribute,"option") == 0)
1754 {
1755 if (info)
1756 DefineImageOption(info->image_info,SvPV(sval,na));
1757 break;
1758 }
1759 if (LocaleCompare(attribute,"orientation") == 0)
1760 {
1761 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1762 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1763 if (sp < 0)
1764 {
1765 ThrowPerlException(exception,OptionError,
1766 "UnrecognizedOrientationType",SvPV(sval,na));
1767 break;
1768 }
1769 if (info)
1770 info->image_info->orientation=(OrientationType) sp;
1771 for ( ; image; image=image->next)
1772 image->orientation=(OrientationType) sp;
1773 break;
1774 }
1775 if (info)
1776 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1777 for ( ; image; image=image->next)
1778 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1779 break;
1780 }
1781 case 'P':
1782 case 'p':
1783 {
1784 if (LocaleCompare(attribute,"page") == 0)
1785 {
1786 char
1787 *geometry;
1788
1789 geometry=GetPageGeometry(SvPV(sval,na));
1790 if (info)
1791 (void) CloneString(&info->image_info->page,geometry);
1792 for ( ; image; image=image->next)
1793 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1794 geometry=(char *) RelinquishMagickMemory(geometry);
1795 break;
1796 }
1797 if (LocaleNCompare(attribute,"pixel",5) == 0)
1798 {
1799 int
1800 items;
1801
1802 PixelInfo
1803 pixel;
1804
1805 register Quantum
1806 *q;
1807
1808 CacheView
1809 *image_view;
1810
1811 for ( ; image; image=image->next)
1812 {
1813 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1814 break;
1815 x=0;
1816 y=0;
1817 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1818 (void) items;
1819 image_view=AcquireVirtualCacheView(image,exception);
1820 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1821 if (q != (Quantum *) NULL)
1822 {
1823 if ((strchr(SvPV(sval,na),',') == 0) ||
1824 (strchr(SvPV(sval,na),')') != 0))
1825 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1826 &pixel,exception);
1827 else
1828 {
1829 GetPixelInfo(image,&pixel);
1830 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1831 pixel.red=geometry_info.rho;
1832 if ((flags & SigmaValue) != 0)
1833 pixel.green=geometry_info.sigma;
1834 if ((flags & XiValue) != 0)
1835 pixel.blue=geometry_info.xi;
1836 if ((flags & PsiValue) != 0)
1837 pixel.alpha=geometry_info.psi;
1838 if ((flags & ChiValue) != 0)
1839 pixel.black=geometry_info.chi;
1840 }
1841 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1842 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1843 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1844 if (image->colorspace == CMYKColorspace)
1845 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1846 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1847 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1848 }
1849 image_view=DestroyCacheView(image_view);
1850 }
1851 break;
1852 }
1853 if (LocaleCompare(attribute,"pointsize") == 0)
1854 {
1855 if (info)
1856 {
1857 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1858 info->image_info->pointsize=geometry_info.rho;
1859 }
1860 break;
1861 }
1862 if (LocaleCompare(attribute,"preview") == 0)
1863 {
1864 sp=SvPOK(sval) ? ParseCommandOption(MagickPreviewOptions,MagickFalse,
1865 SvPV(sval,na)) : SvIV(sval);
1866 if (sp < 0)
1867 {
1868 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1869 SvPV(sval,na));
1870 break;
1871 }
1872 if (info)
1873 info->image_info->preview_type=(PreviewType) sp;
1874 break;
1875 }
1876 if (info)
1877 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1878 for ( ; image; image=image->next)
1879 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1880 break;
1881 }
1882 case 'Q':
1883 case 'q':
1884 {
1885 if (LocaleCompare(attribute,"quality") == 0)
1886 {
1887 if (info)
1888 info->image_info->quality=SvIV(sval);
1889 for ( ; image; image=image->next)
1890 image->quality=SvIV(sval);
1891 break;
1892 }
1893 if (info)
1894 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1895 for ( ; image; image=image->next)
1896 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1897 break;
1898 }
1899 case 'R':
1900 case 'r':
1901 {
1902 if (LocaleCompare(attribute,"red-primary") == 0)
1903 {
1904 for ( ; image; image=image->next)
1905 {
1906 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1907 image->chromaticity.red_primary.x=geometry_info.rho;
1908 image->chromaticity.red_primary.y=geometry_info.sigma;
1909 if ((flags & SigmaValue) == 0)
1910 image->chromaticity.red_primary.y=
1911 image->chromaticity.red_primary.x;
1912 }
1913 break;
1914 }
1915 if (LocaleCompare(attribute,"render") == 0)
1916 {
1917 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1918 SvPV(sval,na)) : SvIV(sval);
1919 if (sp < 0)
1920 {
1921 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1922 SvPV(sval,na));
1923 break;
1924 }
1925 for ( ; image; image=image->next)
1926 image->rendering_intent=(RenderingIntent) sp;
1927 break;
1928 }
1929 if (LocaleCompare(attribute,"repage") == 0)
1930 {
1931 RectangleInfo
1932 geometry;
1933
1934 for ( ; image; image=image->next)
1935 {
1936 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1937 if ((flags & WidthValue) != 0)
1938 {
1939 if ((flags & HeightValue) == 0)
1940 geometry.height=geometry.width;
1941 image->page.width=geometry.width;
1942 image->page.height=geometry.height;
1943 }
1944 if ((flags & AspectValue) != 0)
1945 {
1946 if ((flags & XValue) != 0)
1947 image->page.x+=geometry.x;
1948 if ((flags & YValue) != 0)
1949 image->page.y+=geometry.y;
1950 }
1951 else
1952 {
1953 if ((flags & XValue) != 0)
1954 {
1955 image->page.x=geometry.x;
1956 if (((flags & WidthValue) != 0) && (geometry.x > 0))
1957 image->page.width=image->columns+geometry.x;
1958 }
1959 if ((flags & YValue) != 0)
1960 {
1961 image->page.y=geometry.y;
1962 if (((flags & HeightValue) != 0) && (geometry.y > 0))
1963 image->page.height=image->rows+geometry.y;
1964 }
1965 }
1966 }
1967 break;
1968 }
1969 if (info)
1970 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1971 for ( ; image; image=image->next)
1972 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1973 break;
1974 }
1975 case 'S':
1976 case 's':
1977 {
1978 if (LocaleCompare(attribute,"sampling-factor") == 0)
1979 {
1980 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1981 {
1982 ThrowPerlException(exception,OptionError,"MissingGeometry",
1983 SvPV(sval,na));
1984 break;
1985 }
1986 if (info)
1987 (void) CloneString(&info->image_info->sampling_factor,
1988 SvPV(sval,na));
1989 break;
1990 }
1991 if (LocaleCompare(attribute,"scene") == 0)
1992 {
1993 for ( ; image; image=image->next)
1994 image->scene=SvIV(sval);
1995 break;
1996 }
1997 if (LocaleCompare(attribute,"server") == 0)
1998 goto display;
1999 if (LocaleCompare(attribute,"size") == 0)
2000 {
2001 if (info)
2002 {
2003 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2004 {
2005 ThrowPerlException(exception,OptionError,"MissingGeometry",
2006 SvPV(sval,na));
2007 break;
2008 }
2009 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2010 }
2011 break;
2012 }
2013 if (LocaleCompare(attribute,"stroke") == 0)
2014 {
2015 if (info)
2016 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2017 break;
2018 }
2019 if (info)
2020 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2021 for ( ; image; image=image->next)
2022 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2023 break;
2024 }
2025 case 'T':
2026 case 't':
2027 {
2028 if (LocaleCompare(attribute,"texture") == 0)
2029 {
2030 if (info)
2031 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2032 break;
2033 }
2034 if (LocaleCompare(attribute,"thread-limit") == 0)
2035 {
2036 MagickSizeType
2037 limit;
2038
2039 limit=MagickResourceInfinity;
2040 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2041 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2042 100.0);
2043 (void) SetMagickResourceLimit(ThreadResource,limit);
2044 break;
2045 }
2046 if (LocaleCompare(attribute,"tile-offset") == 0)
2047 {
2048 char
2049 *geometry;
2050
2051 geometry=GetPageGeometry(SvPV(sval,na));
2052 if (info)
2053 (void) CloneString(&info->image_info->page,geometry);
2054 for ( ; image; image=image->next)
2055 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2056 exception);
2057 geometry=(char *) RelinquishMagickMemory(geometry);
2058 break;
2059 }
2060 if (LocaleCompare(attribute,"time-limit") == 0)
2061 {
2062 MagickSizeType
2063 limit;
2064
2065 limit=MagickResourceInfinity;
2066 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2067 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2068 100.0);
2069 (void) SetMagickResourceLimit(TimeResource,limit);
2070 break;
2071 }
2072 if (LocaleCompare(attribute,"transparent-color") == 0)
2073 {
2074 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2075 exception);
2076 if (info)
2077 info->image_info->transparent_color=target_color;
2078 for ( ; image; image=image->next)
2079 image->transparent_color=target_color;
2080 break;
2081 }
2082 if (LocaleCompare(attribute,"type") == 0)
2083 {
2084 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2085 SvPV(sval,na)) : SvIV(sval);
2086 if (sp < 0)
2087 {
2088 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2089 SvPV(sval,na));
2090 break;
2091 }
2092 if (info)
2093 info->image_info->type=(ImageType) sp;
2094 for ( ; image; image=image->next)
2095 SetImageType(image,(ImageType) sp,exception);
2096 break;
2097 }
2098 if (info)
2099 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2100 for ( ; image; image=image->next)
2101 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2102 break;
2103 }
2104 case 'U':
2105 case 'u':
2106 {
2107 if (LocaleCompare(attribute,"units") == 0)
2108 {
2109 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2110 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2111 if (sp < 0)
2112 {
2113 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2114 SvPV(sval,na));
2115 break;
2116 }
2117 if (info)
2118 info->image_info->units=(ResolutionType) sp;
2119 for ( ; image; image=image->next)
2120 {
2121 ResolutionType
2122 units;
2123
2124 units=(ResolutionType) sp;
2125 if (image->units != units)
2126 switch (image->units)
2127 {
2128 case UndefinedResolution:
2129 case PixelsPerInchResolution:
2130 {
2131 if (units == PixelsPerCentimeterResolution)
2132 {
2133 image->resolution.x*=2.54;
2134 image->resolution.y*=2.54;
2135 }
2136 break;
2137 }
2138 case PixelsPerCentimeterResolution:
2139 {
2140 if (units == PixelsPerInchResolution)
2141 {
2142 image->resolution.x/=2.54;
2143 image->resolution.y/=2.54;
2144 }
2145 break;
2146 }
2147 }
2148 image->units=units;
2149 }
2150 break;
2151 }
2152 if (info)
2153 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2154 for ( ; image; image=image->next)
2155 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2156 break;
2157 }
2158 case 'V':
2159 case 'v':
2160 {
2161 if (LocaleCompare(attribute,"verbose") == 0)
2162 {
2163 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2164 SvPV(sval,na)) : SvIV(sval);
2165 if (sp < 0)
2166 {
2167 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2168 SvPV(sval,na));
2169 break;
2170 }
2171 if (info)
2172 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2173 break;
2174 }
2175 if (LocaleCompare(attribute,"view") == 0)
2176 {
2177 if (info)
2178 (void) CloneString(&info->image_info->view,SvPV(sval,na));
2179 break;
2180 }
2181 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2182 {
2183 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2184 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2185 if (sp < 0)
2186 {
2187 ThrowPerlException(exception,OptionError,
2188 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2189 break;
2190 }
2191 for ( ; image; image=image->next)
2192 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2193 break;
2194 }
2195 if (info)
2196 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2197 for ( ; image; image=image->next)
2198 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2199 break;
2200 }
2201 case 'W':
2202 case 'w':
2203 {
2204 if (LocaleCompare(attribute,"white-point") == 0)
2205 {
2206 for ( ; image; image=image->next)
2207 {
2208 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2209 image->chromaticity.white_point.x=geometry_info.rho;
2210 image->chromaticity.white_point.y=geometry_info.sigma;
2211 if ((flags & SigmaValue) == 0)
2212 image->chromaticity.white_point.y=
2213 image->chromaticity.white_point.x;
2214 }
2215 break;
2216 }
2217 if (info)
2218 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2219 for ( ; image; image=image->next)
2220 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2221 break;
2222 }
2223 default:
2224 {
2225 if (info)
2226 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2227 for ( ; image; image=image->next)
2228 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2229 break;
2230 }
2231 }
2232}
2233
2234/*
2235%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2236% %
2237% %
2238% %
2239% S e t u p L i s t %
2240% %
2241% %
2242% %
2243%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2244%
2245% Method SetupList returns the list of all the images linked by their
2246% image->next and image->previous link lists for use with ImageMagick. If
2247% info is non-NULL, an info structure is returned in *info. If
2248% reference_vector is non-NULL,an array of SV* are returned in
2249% *reference_vector. Reference_vector is used when the images are going to be
2250% replaced with new Image*'s.
2251%
2252% The format of the SetupList routine is:
2253%
2254% Image *SetupList(SV *reference,struct PackageInfo **info,
2255% SV ***reference_vector,ExceptionInfo *exception)
2256%
2257% A description of each parameter follows:
2258%
2259% o list: a list of strings.
2260%
2261% o string: a character string.
2262%
2263% o exception: Return any errors or warnings in this structure.
2264%
2265*/
2266static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2267 SV ***reference_vector,ExceptionInfo *exception)
2268{
2269 Image
2270 *image;
2271
2272 ssize_t
2273 current,
2274 last;
2275
2276 if (reference_vector)
2277 *reference_vector=NULL;
2278 if (info)
2279 *info=NULL;
2280 current=0;
2281 last=0;
2282 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2283 if (info && (SvTYPE(reference) == SVt_PVAV))
2284 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2285 exception);
2286 return(image);
2287}
2288
2289/*
2290%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2291% %
2292% %
2293% %
2294% s t r E Q c a s e %
2295% %
2296% %
2297% %
2298%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2299%
2300% strEQcase() compares two strings and returns 0 if they are the
2301% same or if the second string runs out first. The comparison is case
2302% insensitive.
2303%
2304% The format of the strEQcase routine is:
2305%
2306% ssize_t strEQcase(const char *p,const char *q)
2307%
2308% A description of each parameter follows:
2309%
2310% o p: a character string.
2311%
2312% o q: a character string.
2313%
2314%
2315*/
2316static ssize_t strEQcase(const char *p,const char *q)
2317{
2318 char
2319 c;
2320
2321 register ssize_t
2322 i;
2323
2324 for (i=0 ; (c=(*q)) != 0; i++)
2325 {
2326 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2327 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2328 return(0);
2329 p++;
2330 q++;
2331 }
2332 return(((*q == 0) && (*p == 0)) ? i : 0);
2333}
2334
2335/*
2336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2337% %
2338% %
2339% %
2340% I m a g e : : M a g i c k %
2341% %
2342% %
2343% %
2344%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2345%
2346%
2347*/
2348MODULE = Image::Magick PACKAGE = Image::Magick
2349
2350PROTOTYPES: ENABLE
2351
2352BOOT:
2353 MagickCoreGenesis("PerlMagick",MagickFalse);
2354 SetWarningHandler(NULL);
2355 SetErrorHandler(NULL);
2356 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2357 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2358
2359void
2360UNLOAD()
2361 PPCODE:
2362 {
2363 if (magick_registry != (SplayTreeInfo *) NULL)
2364 magick_registry=DestroySplayTree(magick_registry);
2365 MagickCoreTerminus();
2366 }
2367
2368double
2369constant(name,argument)
2370 char *name
2371 ssize_t argument
2372
2373#
2374###############################################################################
2375# #
2376# #
2377# #
2378# A n i m a t e #
2379# #
2380# #
2381# #
2382###############################################################################
2383#
2384#
2385void
2386Animate(ref,...)
2387 Image::Magick ref=NO_INIT
2388 ALIAS:
2389 AnimateImage = 1
2390 animate = 2
2391 animateimage = 3
2392 PPCODE:
2393 {
2394 ExceptionInfo
2395 *exception;
2396
2397 Image
2398 *image;
2399
2400 register ssize_t
2401 i;
2402
2403 struct PackageInfo
2404 *info,
2405 *package_info;
2406
2407 SV
2408 *perl_exception,
2409 *reference;
2410
2411 PERL_UNUSED_VAR(ref);
2412 PERL_UNUSED_VAR(ix);
2413 exception=AcquireExceptionInfo();
2414 perl_exception=newSVpv("",0);
2415 package_info=(struct PackageInfo *) NULL;
2416 if (sv_isobject(ST(0)) == 0)
2417 {
2418 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2419 PackageName);
2420 goto PerlException;
2421 }
2422 reference=SvRV(ST(0));
2423 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2424 if (image == (Image *) NULL)
2425 {
2426 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2427 PackageName);
2428 goto PerlException;
2429 }
2430 package_info=ClonePackageInfo(info,exception);
2431 if (items == 2)
2432 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2433 else
2434 if (items > 2)
2435 for (i=2; i < items; i+=2)
2436 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2437 exception);
2438 (void) AnimateImages(package_info->image_info,image,exception);
2439 (void) CatchImageException(image);
2440
2441 PerlException:
2442 if (package_info != (struct PackageInfo *) NULL)
2443 DestroyPackageInfo(package_info);
2444 InheritPerlException(exception,perl_exception);
2445 exception=DestroyExceptionInfo(exception);
2446 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2447 SvPOK_on(perl_exception);
2448 ST(0)=sv_2mortal(perl_exception);
2449 XSRETURN(1);
2450 }
2451
2452#
2453###############################################################################
2454# #
2455# #
2456# #
2457# A p p e n d #
2458# #
2459# #
2460# #
2461###############################################################################
2462#
2463#
2464void
2465Append(ref,...)
2466 Image::Magick ref=NO_INIT
2467 ALIAS:
2468 AppendImage = 1
2469 append = 2
2470 appendimage = 3
2471 PPCODE:
2472 {
2473 AV
2474 *av;
2475
2476 char
2477 *attribute;
2478
2479 ExceptionInfo
2480 *exception;
2481
2482 HV
2483 *hv;
2484
2485 Image
2486 *image;
2487
2488 register ssize_t
2489 i;
2490
2491 ssize_t
2492 stack;
2493
2494 struct PackageInfo
2495 *info;
2496
2497 SV
2498 *av_reference,
2499 *perl_exception,
2500 *reference,
2501 *rv,
2502 *sv;
2503
2504 PERL_UNUSED_VAR(ref);
2505 PERL_UNUSED_VAR(ix);
2506 exception=AcquireExceptionInfo();
2507 perl_exception=newSVpv("",0);
2508 sv=NULL;
2509 attribute=NULL;
2510 av=NULL;
2511 if (sv_isobject(ST(0)) == 0)
2512 {
2513 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2514 PackageName);
2515 goto PerlException;
2516 }
2517 reference=SvRV(ST(0));
2518 hv=SvSTASH(reference);
2519 av=newAV();
2520 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2521 SvREFCNT_dec(av);
2522 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2523 if (image == (Image *) NULL)
2524 {
2525 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2526 PackageName);
2527 goto PerlException;
2528 }
2529 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2530 /*
2531 Get options.
2532 */
2533 stack=MagickTrue;
2534 for (i=2; i < items; i+=2)
2535 {
2536 attribute=(char *) SvPV(ST(i-1),na);
2537 switch (*attribute)
2538 {
2539 case 'S':
2540 case 's':
2541 {
2542 if (LocaleCompare(attribute,"stack") == 0)
2543 {
2544 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2545 SvPV(ST(i),na));
2546 if (stack < 0)
2547 {
2548 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2549 SvPV(ST(i),na));
2550 return;
2551 }
2552 break;
2553 }
2554 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2555 attribute);
2556 break;
2557 }
2558 default:
2559 {
2560 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2561 attribute);
2562 break;
2563 }
2564 }
2565 }
2566 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2567 if (image == (Image *) NULL)
2568 goto PerlException;
2569 for ( ; image; image=image->next)
2570 {
2571 AddImageToRegistry(sv,image);
2572 rv=newRV(sv);
2573 av_push(av,sv_bless(rv,hv));
2574 SvREFCNT_dec(sv);
2575 }
2576 exception=DestroyExceptionInfo(exception);
2577 ST(0)=av_reference;
2578 SvREFCNT_dec(perl_exception);
2579 XSRETURN(1);
2580
2581 PerlException:
2582 InheritPerlException(exception,perl_exception);
2583 exception=DestroyExceptionInfo(exception);
2584 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2585 SvPOK_on(perl_exception);
2586 ST(0)=sv_2mortal(perl_exception);
2587 XSRETURN(1);
2588 }
2589
2590#
2591###############################################################################
2592# #
2593# #
2594# #
2595# A v e r a g e #
2596# #
2597# #
2598# #
2599###############################################################################
2600#
2601#
2602void
2603Average(ref)
2604 Image::Magick ref=NO_INIT
2605 ALIAS:
2606 AverageImage = 1
2607 average = 2
2608 averageimage = 3
2609 PPCODE:
2610 {
2611 AV
2612 *av;
2613
2614 char
2615 *p;
2616
2617 ExceptionInfo
2618 *exception;
2619
2620 HV
2621 *hv;
2622
2623 Image
2624 *image;
2625
2626 struct PackageInfo
2627 *info;
2628
2629 SV
2630 *perl_exception,
2631 *reference,
2632 *rv,
2633 *sv;
2634
2635 PERL_UNUSED_VAR(ref);
2636 PERL_UNUSED_VAR(ix);
2637 exception=AcquireExceptionInfo();
2638 perl_exception=newSVpv("",0);
2639 sv=NULL;
2640 if (sv_isobject(ST(0)) == 0)
2641 {
2642 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2643 PackageName);
2644 goto PerlException;
2645 }
2646 reference=SvRV(ST(0));
2647 hv=SvSTASH(reference);
2648 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2649 if (image == (Image *) NULL)
2650 {
2651 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2652 PackageName);
2653 goto PerlException;
2654 }
2655 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2656 if (image == (Image *) NULL)
2657 goto PerlException;
2658 /*
2659 Create blessed Perl array for the returned image.
2660 */
2661 av=newAV();
2662 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2663 SvREFCNT_dec(av);
2664 AddImageToRegistry(sv,image);
2665 rv=newRV(sv);
2666 av_push(av,sv_bless(rv,hv));
2667 SvREFCNT_dec(sv);
2668 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2669 (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
2670 "average-%.*s",(int) (MaxTextExtent-9),
2671 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2672 (void) CopyMagickString(image->filename,info->image_info->filename,
2673 MaxTextExtent);
2674 SetImageInfo(info->image_info,0,exception);
2675 exception=DestroyExceptionInfo(exception);
2676 SvREFCNT_dec(perl_exception);
2677 XSRETURN(1);
2678
2679 PerlException:
2680 InheritPerlException(exception,perl_exception);
2681 exception=DestroyExceptionInfo(exception);
2682 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2683 SvPOK_on(perl_exception);
2684 ST(0)=sv_2mortal(perl_exception);
2685 XSRETURN(1);
2686 }
2687
2688#
2689###############################################################################
2690# #
2691# #
2692# #
2693# B l o b T o I m a g e #
2694# #
2695# #
2696# #
2697###############################################################################
2698#
2699#
2700void
2701BlobToImage(ref,...)
2702 Image::Magick ref=NO_INIT
2703 ALIAS:
2704 BlobToImage = 1
2705 blobtoimage = 2
2706 blobto = 3
2707 PPCODE:
2708 {
2709 AV
2710 *av;
2711
2712 char
2713 **keep,
2714 **list;
2715
2716 ExceptionInfo
2717 *exception;
2718
2719 HV
2720 *hv;
2721
2722 Image
2723 *image;
2724
2725 register char
2726 **p;
2727
2728 register ssize_t
2729 i;
2730
2731 ssize_t
2732 ac,
2733 n,
2734 number_images;
2735
2736 STRLEN
2737 *length;
2738
2739 struct PackageInfo
2740 *info;
2741
2742 SV
2743 *perl_exception,
2744 *reference,
2745 *rv,
2746 *sv;
2747
2748 PERL_UNUSED_VAR(ref);
2749 PERL_UNUSED_VAR(ix);
2750 exception=AcquireExceptionInfo();
2751 perl_exception=newSVpv("",0);
2752 sv=NULL;
2753 number_images=0;
2754 ac=(items < 2) ? 1 : items-1;
2755 length=(STRLEN *) NULL;
2756 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2757 if (list == (char **) NULL)
2758 {
2759 ThrowPerlException(exception,ResourceLimitError,
2760 "MemoryAllocationFailed",PackageName);
2761 goto PerlException;
2762 }
2763 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2764 if (length == (STRLEN *) NULL)
2765 {
2766 ThrowPerlException(exception,ResourceLimitError,
2767 "MemoryAllocationFailed",PackageName);
2768 goto PerlException;
2769 }
2770 if (sv_isobject(ST(0)) == 0)
2771 {
2772 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2773 PackageName);
2774 goto PerlException;
2775 }
2776 reference=SvRV(ST(0));
2777 hv=SvSTASH(reference);
2778 if (SvTYPE(reference) != SVt_PVAV)
2779 {
2780 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2781 PackageName);
2782 goto PerlException;
2783 }
2784 av=(AV *) reference;
2785 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2786 exception);
2787 n=1;
2788 if (items <= 1)
2789 {
2790 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2791 goto PerlException;
2792 }
2793 for (n=0, i=0; i < ac; i++)
2794 {
2795 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2796 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2797 {
2798 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2799 continue;
2800 }
2801 n++;
2802 }
2803 list[n]=(char *) NULL;
2804 keep=list;
2805 for (i=number_images=0; i < n; i++)
2806 {
2807 image=BlobToImage(info->image_info,list[i],length[i],exception);
2808 if (image == (Image *) NULL)
2809 break;
2810 for ( ; image; image=image->next)
2811 {
2812 AddImageToRegistry(sv,image);
2813 rv=newRV(sv);
2814 av_push(av,sv_bless(rv,hv));
2815 SvREFCNT_dec(sv);
2816 number_images++;
2817 }
2818 }
2819 /*
2820 Free resources.
2821 */
2822 for (i=0; i < n; i++)
2823 if (list[i] != (char *) NULL)
2824 for (p=keep; list[i] != *p++; )
2825 if (*p == (char *) NULL)
2826 {
2827 list[i]=(char *) RelinquishMagickMemory(list[i]);
2828 break;
2829 }
2830
2831 PerlException:
2832 if (list)
2833 list=(char **) RelinquishMagickMemory(list);
2834 if (length)
2835 length=(STRLEN *) RelinquishMagickMemory(length);
2836 InheritPerlException(exception,perl_exception);
2837 exception=DestroyExceptionInfo(exception);
2838 sv_setiv(perl_exception,(IV) number_images);
2839 SvPOK_on(perl_exception);
2840 ST(0)=sv_2mortal(perl_exception);
2841 XSRETURN(1);
2842 }
2843
2844#
2845###############################################################################
2846# #
2847# #
2848# #
2849# C h a n n e l F x #
2850# #
2851# #
2852# #
2853###############################################################################
2854#
2855#
2856void
2857ChannelFx(ref,...)
2858 Image::Magick ref=NO_INIT
2859 ALIAS:
2860 ChannelFxImage = 1
2861 channelfx = 2
2862 channelfximage = 3
2863 PPCODE:
2864 {
2865 AV
2866 *av;
2867
2868 char
2869 *attribute,
2870 expression[MaxTextExtent];
2871
2872 ChannelType
2873 channel,
2874 channel_mask;
2875
2876 ExceptionInfo
2877 *exception;
2878
2879 HV
2880 *hv;
2881
2882 Image
2883 *image;
2884
2885 register ssize_t
2886 i;
2887
2888 struct PackageInfo
2889 *info;
2890
2891 SV
2892 *av_reference,
2893 *perl_exception,
2894 *reference,
2895 *rv,
2896 *sv;
2897
2898 PERL_UNUSED_VAR(ref);
2899 PERL_UNUSED_VAR(ix);
2900 exception=AcquireExceptionInfo();
2901 perl_exception=newSVpv("",0);
2902 sv=NULL;
2903 attribute=NULL;
2904 av=NULL;
2905 if (sv_isobject(ST(0)) == 0)
2906 {
2907 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2908 PackageName);
2909 goto PerlException;
2910 }
2911 reference=SvRV(ST(0));
2912 hv=SvSTASH(reference);
2913 av=newAV();
2914 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2915 SvREFCNT_dec(av);
2916 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2917 if (image == (Image *) NULL)
2918 {
2919 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2920 PackageName);
2921 goto PerlException;
2922 }
2923 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2924 /*
2925 Get options.
2926 */
2927 channel=DefaultChannels;
2928 (void) CopyMagickString(expression,"u",MaxTextExtent);
2929 if (items == 2)
2930 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MaxTextExtent);
2931 else
2932 for (i=2; i < items; i+=2)
2933 {
2934 attribute=(char *) SvPV(ST(i-1),na);
2935 switch (*attribute)
2936 {
2937 case 'C':
2938 case 'c':
2939 {
2940 if (LocaleCompare(attribute,"channel") == 0)
2941 {
2942 ssize_t
2943 option;
2944
2945 option=ParseChannelOption(SvPV(ST(i),na));
2946 if (option < 0)
2947 {
2948 ThrowPerlException(exception,OptionError,
2949 "UnrecognizedType",SvPV(ST(i),na));
2950 return;
2951 }
2952 channel=(ChannelType) option;
2953 break;
2954 }
2955 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2956 attribute);
2957 break;
2958 }
2959 case 'E':
2960 case 'e':
2961 {
2962 if (LocaleCompare(attribute,"expression") == 0)
2963 {
2964 (void) CopyMagickString(expression,SvPV(ST(i),na),
2965 MaxTextExtent);
2966 break;
2967 }
2968 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2969 attribute);
2970 break;
2971 }
2972 default:
2973 {
2974 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2975 attribute);
2976 break;
2977 }
2978 }
2979 }
2980 channel_mask=SetImageChannelMask(image,channel);
2981 image=ChannelFxImage(image,expression,exception);
2982 if (image != (Image *) NULL)
2983 (void) SetImageChannelMask(image,channel_mask);
2984 if (image == (Image *) NULL)
2985 goto PerlException;
2986 for ( ; image; image=image->next)
2987 {
2988 AddImageToRegistry(sv,image);
2989 rv=newRV(sv);
2990 av_push(av,sv_bless(rv,hv));
2991 SvREFCNT_dec(sv);
2992 }
2993 exception=DestroyExceptionInfo(exception);
2994 ST(0)=av_reference;
2995 SvREFCNT_dec(perl_exception); /* can't return warning messages */
2996 XSRETURN(1);
2997
2998 PerlException:
2999 InheritPerlException(exception,perl_exception);
3000 exception=DestroyExceptionInfo(exception);
3001 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3002 SvPOK_on(perl_exception);
3003 ST(0)=sv_2mortal(perl_exception);
3004 XSRETURN(1);
3005 }
3006
3007#
3008###############################################################################
3009# #
3010# #
3011# #
3012# C l o n e #
3013# #
3014# #
3015# #
3016###############################################################################
3017#
3018#
3019void
3020Clone(ref)
3021 Image::Magick ref=NO_INIT
3022 ALIAS:
3023 CopyImage = 1
3024 copy = 2
3025 copyimage = 3
3026 CloneImage = 4
3027 clone = 5
3028 cloneimage = 6
3029 Clone = 7
3030 PPCODE:
3031 {
3032 AV
3033 *av;
3034
3035 ExceptionInfo
3036 *exception;
3037
3038 HV
3039 *hv;
3040
3041 Image
3042 *clone,
3043 *image;
3044
3045 struct PackageInfo
3046 *info;
3047
3048 SV
3049 *perl_exception,
3050 *reference,
3051 *rv,
3052 *sv;
3053
3054 PERL_UNUSED_VAR(ref);
3055 PERL_UNUSED_VAR(ix);
3056 exception=AcquireExceptionInfo();
3057 perl_exception=newSVpv("",0);
3058 sv=NULL;
3059 if (sv_isobject(ST(0)) == 0)
3060 {
3061 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3062 PackageName);
3063 goto PerlException;
3064 }
3065 reference=SvRV(ST(0));
3066 hv=SvSTASH(reference);
3067 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3068 if (image == (Image *) NULL)
3069 {
3070 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3071 PackageName);
3072 goto PerlException;
3073 }
3074 /*
3075 Create blessed Perl array for the returned image.
3076 */
3077 av=newAV();
3078 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3079 SvREFCNT_dec(av);
3080 for ( ; image; image=image->next)
3081 {
3082 clone=CloneImage(image,0,0,MagickTrue,exception);
3083 if (clone == (Image *) NULL)
3084 break;
3085 AddImageToRegistry(sv,clone);
3086 rv=newRV(sv);
3087 av_push(av,sv_bless(rv,hv));
3088 SvREFCNT_dec(sv);
3089 }
3090 exception=DestroyExceptionInfo(exception);
3091 SvREFCNT_dec(perl_exception);
3092 XSRETURN(1);
3093
3094 PerlException:
3095 InheritPerlException(exception,perl_exception);
3096 exception=DestroyExceptionInfo(exception);
3097 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3098 SvPOK_on(perl_exception);
3099 ST(0)=sv_2mortal(perl_exception);
3100 XSRETURN(1);
3101 }
3102
3103#
3104###############################################################################
3105# #
3106# #
3107# #
3108# C L O N E #
3109# #
3110# #
3111# #
3112###############################################################################
3113#
3114#
3115void
3116CLONE(ref,...)
3117 SV *ref;
3118 CODE:
3119 {
3120 PERL_UNUSED_VAR(ref);
3121 if (magick_registry != (SplayTreeInfo *) NULL)
3122 {
3123 register Image
3124 *p;
3125
3126 ResetSplayTreeIterator(magick_registry);
3127 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3128 while (p != (Image *) NULL)
3129 {
3130 ReferenceImage(p);
3131 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3132 }
3133 }
3134 }
3135
3136#
3137###############################################################################
3138# #
3139# #
3140# #
3141# C o a l e s c e #
3142# #
3143# #
3144# #
3145###############################################################################
3146#
3147#
3148void
3149Coalesce(ref)
3150 Image::Magick ref=NO_INIT
3151 ALIAS:
3152 CoalesceImage = 1
3153 coalesce = 2
3154 coalesceimage = 3
3155 PPCODE:
3156 {
3157 AV
3158 *av;
3159
3160 ExceptionInfo
3161 *exception;
3162
3163 HV
3164 *hv;
3165
3166 Image
3167 *image;
3168
3169 struct PackageInfo
3170 *info;
3171
3172 SV
3173 *av_reference,
3174 *perl_exception,
3175 *reference,
3176 *rv,
3177 *sv;
3178
3179 PERL_UNUSED_VAR(ref);
3180 PERL_UNUSED_VAR(ix);
3181 exception=AcquireExceptionInfo();
3182 perl_exception=newSVpv("",0);
3183 sv=NULL;
3184 if (sv_isobject(ST(0)) == 0)
3185 {
3186 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3187 PackageName);
3188 goto PerlException;
3189 }
3190 reference=SvRV(ST(0));
3191 hv=SvSTASH(reference);
3192 av=newAV();
3193 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3194 SvREFCNT_dec(av);
3195 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3196 if (image == (Image *) NULL)
3197 {
3198 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3199 PackageName);
3200 goto PerlException;
3201 }
3202 image=CoalesceImages(image,exception);
3203 if (image == (Image *) NULL)
3204 goto PerlException;
3205 for ( ; image; image=image->next)
3206 {
3207 AddImageToRegistry(sv,image);
3208 rv=newRV(sv);
3209 av_push(av,sv_bless(rv,hv));
3210 SvREFCNT_dec(sv);
3211 }
3212 exception=DestroyExceptionInfo(exception);
3213 ST(0)=av_reference;
3214 SvREFCNT_dec(perl_exception);
3215 XSRETURN(1);
3216
3217 PerlException:
3218 InheritPerlException(exception,perl_exception);
3219 exception=DestroyExceptionInfo(exception);
3220 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3221 SvPOK_on(perl_exception);
3222 ST(0)=sv_2mortal(perl_exception);
3223 XSRETURN(1);
3224 }
3225
3226#
3227###############################################################################
3228# #
3229# #
3230# #
3231# C o m p a r e #
3232# #
3233# #
3234# #
3235###############################################################################
3236#
3237#
3238void
3239Compare(ref,...)
3240 Image::Magick ref=NO_INIT
3241 ALIAS:
3242 CompareImages = 1
3243 compare = 2
3244 compareimage = 3
3245 PPCODE:
3246 {
3247 AV
3248 *av;
3249
3250 char
3251 *attribute;
3252
3253 double
3254 distortion;
3255
3256 ExceptionInfo
3257 *exception;
3258
3259 HV
3260 *hv;
3261
3262 Image
3263 *difference_image,
3264 *image,
3265 *reconstruct_image;
3266
3267 MetricType
3268 metric;
3269
3270 register ssize_t
3271 i;
3272
3273 ssize_t
3274 option;
3275
3276 struct PackageInfo
3277 *info;
3278
3279 SV
3280 *av_reference,
3281 *perl_exception,
3282 *reference,
3283 *rv,
3284 *sv;
3285
3286 PERL_UNUSED_VAR(ref);
3287 PERL_UNUSED_VAR(ix);
3288 exception=AcquireExceptionInfo();
3289 perl_exception=newSVpv("",0);
3290 sv=NULL;
3291 av=NULL;
3292 attribute=NULL;
3293 if (sv_isobject(ST(0)) == 0)
3294 {
3295 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3296 PackageName);
3297 goto PerlException;
3298 }
3299 reference=SvRV(ST(0));
3300 hv=SvSTASH(reference);
3301 av=newAV();
3302 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3303 SvREFCNT_dec(av);
3304 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3305 if (image == (Image *) NULL)
3306 {
3307 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3308 PackageName);
3309 goto PerlException;
3310 }
3311 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3312 /*
3313 Get attribute.
3314 */
3315 reconstruct_image=image;
3316 metric=RootMeanSquaredErrorMetric;
3317 for (i=2; i < items; i+=2)
3318 {
3319 attribute=(char *) SvPV(ST(i-1),na);
3320 switch (*attribute)
3321 {
3322 case 'C':
3323 case 'c':
3324 {
3325 if (LocaleCompare(attribute,"channel") == 0)
3326 {
3327 ssize_t
3328 option;
3329
3330 option=ParseChannelOption(SvPV(ST(i),na));
3331 if (option < 0)
3332 {
3333 ThrowPerlException(exception,OptionError,
3334 "UnrecognizedType",SvPV(ST(i),na));
3335 return;
3336 }
3337 SetPixelChannelMask(image,(ChannelType) option);
3338 break;
3339 }
3340 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3341 attribute);
3342 break;
3343 }
3344 case 'F':
3345 case 'f':
3346 {
3347 if (LocaleCompare(attribute,"fuzz") == 0)
3348 {
3349 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3350 break;
3351 }
3352 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3353 attribute);
3354 break;
3355 }
3356 case 'I':
3357 case 'i':
3358 {
3359 if (LocaleCompare(attribute,"image") == 0)
3360 {
3361 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3362 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3363 break;
3364 }
3365 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3366 attribute);
3367 break;
3368 }
3369 case 'M':
3370 case 'm':
3371 {
3372 if (LocaleCompare(attribute,"metric") == 0)
3373 {
3374 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3375 SvPV(ST(i),na));
3376 if (option < 0)
3377 {
3378 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3379 SvPV(ST(i),na));
3380 break;
3381 }
3382 metric=(MetricType) option;
3383 break;
3384 }
3385 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3386 attribute);
3387 break;
3388 }
3389 default:
3390 {
3391 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3392 attribute);
3393 break;
3394 }
3395 }
3396 }
3397 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3398 exception);
3399 if (difference_image != (Image *) NULL)
3400 {
3401 difference_image->error.mean_error_per_pixel=distortion;
3402 AddImageToRegistry(sv,difference_image);
3403 rv=newRV(sv);
3404 av_push(av,sv_bless(rv,hv));
3405 SvREFCNT_dec(sv);
3406 }
3407 exception=DestroyExceptionInfo(exception);
3408 ST(0)=av_reference;
3409 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3410 XSRETURN(1);
3411
3412 PerlException:
3413 InheritPerlException(exception,perl_exception);
3414 exception=DestroyExceptionInfo(exception);
3415 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3416 SvPOK_on(perl_exception);
3417 ST(0)=sv_2mortal(perl_exception);
3418 XSRETURN(1);
3419 }
3420
3421#
3422###############################################################################
3423# #
3424# #
3425# #
cristy15655332013-10-06 00:27:33 +00003426# C o m p l e x I m a g e s #
3427# #
3428# #
3429# #
3430###############################################################################
3431#
3432#
3433void
3434ComplexImages(ref)
3435 Image::Magick ref=NO_INIT
3436 ALIAS:
3437 ComplexImages = 1
3438 compleximages = 2
3439 PPCODE:
3440 {
3441 AV
3442 *av;
3443
3444 char
3445 *attribute,
3446 *p;
3447
cristyfa21e9e2013-10-07 10:37:38 +00003448 ComplexOperator
3449 op;
3450
cristy15655332013-10-06 00:27:33 +00003451 ExceptionInfo
3452 *exception;
3453
3454 HV
3455 *hv;
3456
3457 Image
3458 *image;
3459
cristy15655332013-10-06 00:27:33 +00003460 register ssize_t
3461 i;
3462
3463 struct PackageInfo
3464 *info;
3465
3466 SV
3467 *perl_exception,
3468 *reference,
3469 *rv,
3470 *sv;
3471
3472 PERL_UNUSED_VAR(ref);
3473 PERL_UNUSED_VAR(ix);
3474 exception=AcquireExceptionInfo();
3475 perl_exception=newSVpv("",0);
3476 sv=NULL;
3477 if (sv_isobject(ST(0)) == 0)
3478 {
3479 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3480 PackageName);
3481 goto PerlException;
3482 }
3483 reference=SvRV(ST(0));
3484 hv=SvSTASH(reference);
3485 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3486 if (image == (Image *) NULL)
3487 {
3488 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3489 PackageName);
3490 goto PerlException;
3491 }
cristyfd168722013-10-07 15:59:31 +00003492 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003493 if (items == 2)
3494 {
3495 ssize_t
3496 in;
3497
3498 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3499 SvPV(ST(1),na));
3500 if (in < 0)
3501 {
3502 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3503 SvPV(ST(1),na));
3504 return;
3505 }
cristyfa21e9e2013-10-07 10:37:38 +00003506 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003507 }
3508 else
3509 for (i=2; i < items; i+=2)
3510 {
3511 attribute=(char *) SvPV(ST(i-1),na);
3512 switch (*attribute)
3513 {
3514 case 'O':
3515 case 'o':
3516 {
3517 if (LocaleCompare(attribute,"operator") == 0)
3518 {
3519 ssize_t
3520 in;
3521
3522 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3523 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3524 if (in < 0)
3525 {
3526 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3527 SvPV(ST(i),na));
3528 return;
3529 }
cristyfa21e9e2013-10-07 10:37:38 +00003530 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003531 break;
3532 }
3533 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3534 attribute);
3535 break;
3536 }
3537 default:
3538 {
3539 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3540 attribute);
3541 break;
3542 }
3543 }
3544 }
3545 image=ComplexImages(image,op,exception);
3546 if (image == (Image *) NULL)
3547 goto PerlException;
3548 /*
3549 Create blessed Perl array for the returned image.
3550 */
3551 av=newAV();
3552 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3553 SvREFCNT_dec(av);
3554 AddImageToRegistry(sv,image);
3555 rv=newRV(sv);
3556 av_push(av,sv_bless(rv,hv));
3557 SvREFCNT_dec(sv);
3558 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3559 (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
3560 "complex-%.*s",(int) (MaxTextExtent-9),
3561 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3562 (void) CopyMagickString(image->filename,info->image_info->filename,
3563 MaxTextExtent);
3564 SetImageInfo(info->image_info,0,exception);
3565 exception=DestroyExceptionInfo(exception);
3566 SvREFCNT_dec(perl_exception);
3567 XSRETURN(1);
3568
3569 PerlException:
3570 InheritPerlException(exception,perl_exception);
3571 exception=DestroyExceptionInfo(exception);
3572 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3573 SvPOK_on(perl_exception);
3574 ST(0)=sv_2mortal(perl_exception);
3575 XSRETURN(1);
3576 }
3577
3578#
3579###############################################################################
3580# #
3581# #
3582# #
cristy4a3ce0a2013-08-03 20:06:59 +00003583# C o m p a r e L a y e r s #
3584# #
3585# #
3586# #
3587###############################################################################
3588#
3589#
3590void
3591CompareLayers(ref)
3592 Image::Magick ref=NO_INIT
3593 ALIAS:
3594 CompareImagesLayers = 1
3595 comparelayers = 2
3596 compareimagelayers = 3
3597 PPCODE:
3598 {
3599 AV
3600 *av;
3601
3602 char
3603 *attribute;
3604
3605 ExceptionInfo
3606 *exception;
3607
3608 HV
3609 *hv;
3610
3611 Image
3612 *image;
3613
3614 LayerMethod
3615 method;
3616
3617 register ssize_t
3618 i;
3619
3620 ssize_t
3621 option;
3622
3623 struct PackageInfo
3624 *info;
3625
3626 SV
3627 *av_reference,
3628 *perl_exception,
3629 *reference,
3630 *rv,
3631 *sv;
3632
3633 PERL_UNUSED_VAR(ref);
3634 PERL_UNUSED_VAR(ix);
3635 exception=AcquireExceptionInfo();
3636 perl_exception=newSVpv("",0);
3637 sv=NULL;
3638 if (sv_isobject(ST(0)) == 0)
3639 {
3640 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3641 PackageName);
3642 goto PerlException;
3643 }
3644 reference=SvRV(ST(0));
3645 hv=SvSTASH(reference);
3646 av=newAV();
3647 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3648 SvREFCNT_dec(av);
3649 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3650 if (image == (Image *) NULL)
3651 {
3652 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3653 PackageName);
3654 goto PerlException;
3655 }
3656 method=CompareAnyLayer;
3657 for (i=2; i < items; i+=2)
3658 {
3659 attribute=(char *) SvPV(ST(i-1),na);
3660 switch (*attribute)
3661 {
3662 case 'M':
3663 case 'm':
3664 {
3665 if (LocaleCompare(attribute,"method") == 0)
3666 {
3667 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3668 SvPV(ST(i),na));
3669 if (option < 0)
3670 {
3671 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3672 SvPV(ST(i),na));
3673 break;
3674 }
3675 method=(LayerMethod) option;
3676 break;
3677 }
3678 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3679 attribute);
3680 break;
3681 }
3682 default:
3683 {
3684 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3685 attribute);
3686 break;
3687 }
3688 }
3689 }
3690 image=CompareImagesLayers(image,method,exception);
3691 if (image == (Image *) NULL)
3692 goto PerlException;
3693 for ( ; image; image=image->next)
3694 {
3695 AddImageToRegistry(sv,image);
3696 rv=newRV(sv);
3697 av_push(av,sv_bless(rv,hv));
3698 SvREFCNT_dec(sv);
3699 }
3700 exception=DestroyExceptionInfo(exception);
3701 ST(0)=av_reference;
3702 SvREFCNT_dec(perl_exception);
3703 XSRETURN(1);
3704
3705 PerlException:
3706 InheritPerlException(exception,perl_exception);
3707 exception=DestroyExceptionInfo(exception);
3708 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3709 SvPOK_on(perl_exception);
3710 ST(0)=sv_2mortal(perl_exception);
3711 XSRETURN(1);
3712 }
3713
3714#
3715###############################################################################
3716# #
3717# #
3718# #
3719# D e s t r o y #
3720# #
3721# #
3722# #
3723###############################################################################
3724#
3725#
3726void
3727DESTROY(ref)
3728 Image::Magick ref=NO_INIT
3729 PPCODE:
3730 {
3731 SV
3732 *reference;
3733
3734 PERL_UNUSED_VAR(ref);
3735 if (sv_isobject(ST(0)) == 0)
3736 croak("ReferenceIsNotMyType");
3737 reference=SvRV(ST(0));
3738 switch (SvTYPE(reference))
3739 {
3740 case SVt_PVAV:
3741 {
3742 char
3743 message[MaxTextExtent];
3744
3745 const SV
3746 *key;
3747
3748 HV
3749 *hv;
3750
3751 GV
3752 **gvp;
3753
3754 struct PackageInfo
3755 *info;
3756
3757 SV
3758 *sv;
3759
3760 /*
3761 Array (AV *) reference
3762 */
3763 (void) FormatLocaleString(message,MaxTextExtent,"package%s%p",
3764 XS_VERSION,reference);
3765 hv=gv_stashpv(PackageName, FALSE);
3766 if (!hv)
3767 break;
3768 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3769 if (!gvp)
3770 break;
3771 sv=GvSV(*gvp);
3772 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3773 {
3774 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3775 DestroyPackageInfo(info);
3776 }
3777 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3778 (void) key;
3779 break;
3780 }
3781 case SVt_PVMG:
3782 {
3783 Image
3784 *image;
3785
3786 /*
3787 Blessed scalar = (Image *) SvIV(reference)
3788 */
3789 image=INT2PTR(Image *,SvIV(reference));
3790 if (image != (Image *) NULL)
3791 DeleteImageFromRegistry(reference,image);
3792 break;
3793 }
3794 default:
3795 break;
3796 }
3797 }
3798
3799#
3800###############################################################################
3801# #
3802# #
3803# #
3804# D i s p l a y #
3805# #
3806# #
3807# #
3808###############################################################################
3809#
3810#
3811void
3812Display(ref,...)
3813 Image::Magick ref=NO_INIT
3814 ALIAS:
3815 DisplayImage = 1
3816 display = 2
3817 displayimage = 3
3818 PPCODE:
3819 {
3820 ExceptionInfo
3821 *exception;
3822
3823 Image
3824 *image;
3825
3826 register ssize_t
3827 i;
3828
3829 struct PackageInfo
3830 *info,
3831 *package_info;
3832
3833 SV
3834 *perl_exception,
3835 *reference;
3836
3837 PERL_UNUSED_VAR(ref);
3838 PERL_UNUSED_VAR(ix);
3839 exception=AcquireExceptionInfo();
3840 perl_exception=newSVpv("",0);
3841 package_info=(struct PackageInfo *) NULL;
3842 if (sv_isobject(ST(0)) == 0)
3843 {
3844 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3845 PackageName);
3846 goto PerlException;
3847 }
3848 reference=SvRV(ST(0));
3849 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3850 if (image == (Image *) NULL)
3851 {
3852 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3853 PackageName);
3854 goto PerlException;
3855 }
3856 package_info=ClonePackageInfo(info,exception);
3857 if (items == 2)
3858 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3859 else
3860 if (items > 2)
3861 for (i=2; i < items; i+=2)
3862 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3863 exception);
3864 (void) DisplayImages(package_info->image_info,image,exception);
3865 (void) CatchImageException(image);
3866
3867 PerlException:
3868 if (package_info != (struct PackageInfo *) NULL)
3869 DestroyPackageInfo(package_info);
3870 InheritPerlException(exception,perl_exception);
3871 exception=DestroyExceptionInfo(exception);
3872 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3873 SvPOK_on(perl_exception);
3874 ST(0)=sv_2mortal(perl_exception);
3875 XSRETURN(1);
3876 }
3877
3878#
3879###############################################################################
3880# #
3881# #
3882# #
3883# E v a l u a t e I m a g e s #
3884# #
3885# #
3886# #
3887###############################################################################
3888#
3889#
3890void
3891EvaluateImages(ref)
3892 Image::Magick ref=NO_INIT
3893 ALIAS:
3894 EvaluateImages = 1
3895 evaluateimages = 2
3896 PPCODE:
3897 {
3898 AV
3899 *av;
3900
3901 char
3902 *attribute,
3903 *p;
3904
3905 ExceptionInfo
3906 *exception;
3907
3908 HV
3909 *hv;
3910
3911 Image
3912 *image;
3913
3914 MagickEvaluateOperator
3915 op;
3916
3917 register ssize_t
3918 i;
3919
3920 struct PackageInfo
3921 *info;
3922
3923 SV
3924 *perl_exception,
3925 *reference,
3926 *rv,
3927 *sv;
3928
3929 PERL_UNUSED_VAR(ref);
3930 PERL_UNUSED_VAR(ix);
3931 exception=AcquireExceptionInfo();
3932 perl_exception=newSVpv("",0);
3933 sv=NULL;
3934 if (sv_isobject(ST(0)) == 0)
3935 {
3936 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3937 PackageName);
3938 goto PerlException;
3939 }
3940 reference=SvRV(ST(0));
3941 hv=SvSTASH(reference);
3942 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3943 if (image == (Image *) NULL)
3944 {
3945 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3946 PackageName);
3947 goto PerlException;
3948 }
3949 op=MeanEvaluateOperator;
3950 if (items == 2)
3951 {
3952 ssize_t
3953 in;
3954
3955 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
3956 SvPV(ST(1),na));
3957 if (in < 0)
3958 {
3959 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3960 SvPV(ST(1),na));
3961 return;
3962 }
3963 op=(MagickEvaluateOperator) in;
3964 }
3965 else
3966 for (i=2; i < items; i+=2)
3967 {
3968 attribute=(char *) SvPV(ST(i-1),na);
3969 switch (*attribute)
3970 {
3971 case 'O':
3972 case 'o':
3973 {
3974 if (LocaleCompare(attribute,"operator") == 0)
3975 {
3976 ssize_t
3977 in;
3978
3979 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3980 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
3981 if (in < 0)
3982 {
3983 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3984 SvPV(ST(i),na));
3985 return;
3986 }
3987 op=(MagickEvaluateOperator) in;
3988 break;
3989 }
3990 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3991 attribute);
3992 break;
3993 }
3994 default:
3995 {
3996 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3997 attribute);
3998 break;
3999 }
4000 }
4001 }
4002 image=EvaluateImages(image,op,exception);
4003 if (image == (Image *) NULL)
4004 goto PerlException;
4005 /*
4006 Create blessed Perl array for the returned image.
4007 */
4008 av=newAV();
4009 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4010 SvREFCNT_dec(av);
4011 AddImageToRegistry(sv,image);
4012 rv=newRV(sv);
4013 av_push(av,sv_bless(rv,hv));
4014 SvREFCNT_dec(sv);
4015 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4016 (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
4017 "evaluate-%.*s",(int) (MaxTextExtent-9),
4018 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4019 (void) CopyMagickString(image->filename,info->image_info->filename,
4020 MaxTextExtent);
4021 SetImageInfo(info->image_info,0,exception);
4022 exception=DestroyExceptionInfo(exception);
4023 SvREFCNT_dec(perl_exception);
4024 XSRETURN(1);
4025
4026 PerlException:
4027 InheritPerlException(exception,perl_exception);
4028 exception=DestroyExceptionInfo(exception);
4029 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4030 SvPOK_on(perl_exception);
4031 ST(0)=sv_2mortal(perl_exception);
4032 XSRETURN(1);
4033 }
4034
4035#
4036###############################################################################
4037# #
4038# #
4039# #
4040# F e a t u r e s #
4041# #
4042# #
4043# #
4044###############################################################################
4045#
4046#
4047void
4048Features(ref,...)
4049 Image::Magick ref=NO_INIT
4050 ALIAS:
4051 FeaturesImage = 1
4052 features = 2
4053 featuresimage = 3
4054 PPCODE:
4055 {
4056#define ChannelFeatures(channel,direction) \
4057{ \
4058 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
4059 channel_features[channel].angular_second_moment[direction]); \
4060 PUSHs(sv_2mortal(newSVpv(message,0))); \
4061 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
4062 channel_features[channel].contrast[direction]); \
4063 PUSHs(sv_2mortal(newSVpv(message,0))); \
4064 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
4065 channel_features[channel].contrast[direction]); \
4066 PUSHs(sv_2mortal(newSVpv(message,0))); \
4067 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
4068 channel_features[channel].variance_sum_of_squares[direction]); \
4069 PUSHs(sv_2mortal(newSVpv(message,0))); \
4070 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
4071 channel_features[channel].inverse_difference_moment[direction]); \
4072 PUSHs(sv_2mortal(newSVpv(message,0))); \
4073 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
4074 channel_features[channel].sum_average[direction]); \
4075 PUSHs(sv_2mortal(newSVpv(message,0))); \
4076 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
4077 channel_features[channel].sum_variance[direction]); \
4078 PUSHs(sv_2mortal(newSVpv(message,0))); \
4079 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
4080 channel_features[channel].sum_entropy[direction]); \
4081 PUSHs(sv_2mortal(newSVpv(message,0))); \
4082 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
4083 channel_features[channel].entropy[direction]); \
4084 PUSHs(sv_2mortal(newSVpv(message,0))); \
4085 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
4086 channel_features[channel].difference_variance[direction]); \
4087 PUSHs(sv_2mortal(newSVpv(message,0))); \
4088 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
4089 channel_features[channel].difference_entropy[direction]); \
4090 PUSHs(sv_2mortal(newSVpv(message,0))); \
4091 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
4092 channel_features[channel].measure_of_correlation_1[direction]); \
4093 PUSHs(sv_2mortal(newSVpv(message,0))); \
4094 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
4095 channel_features[channel].measure_of_correlation_2[direction]); \
4096 PUSHs(sv_2mortal(newSVpv(message,0))); \
4097 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
4098 channel_features[channel].maximum_correlation_coefficient[direction]); \
4099 PUSHs(sv_2mortal(newSVpv(message,0))); \
4100}
4101
4102 AV
4103 *av;
4104
4105 char
4106 *attribute,
4107 message[MaxTextExtent];
4108
4109 ChannelFeatures
4110 *channel_features;
4111
4112 double
4113 distance;
4114
4115 ExceptionInfo
4116 *exception;
4117
4118 Image
4119 *image;
4120
4121 register ssize_t
4122 i;
4123
4124 ssize_t
4125 count;
4126
4127 struct PackageInfo
4128 *info;
4129
4130 SV
4131 *perl_exception,
4132 *reference;
4133
4134 PERL_UNUSED_VAR(ref);
4135 PERL_UNUSED_VAR(ix);
4136 exception=AcquireExceptionInfo();
4137 perl_exception=newSVpv("",0);
4138 av=NULL;
4139 if (sv_isobject(ST(0)) == 0)
4140 {
4141 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4142 PackageName);
4143 goto PerlException;
4144 }
4145 reference=SvRV(ST(0));
4146 av=newAV();
4147 SvREFCNT_dec(av);
4148 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4149 if (image == (Image *) NULL)
4150 {
4151 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4152 PackageName);
4153 goto PerlException;
4154 }
4155 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4156 distance=1;
4157 for (i=2; i < items; i+=2)
4158 {
4159 attribute=(char *) SvPV(ST(i-1),na);
4160 switch (*attribute)
4161 {
4162 case 'D':
4163 case 'd':
4164 {
4165 if (LocaleCompare(attribute,"distance") == 0)
4166 {
4167 distance=StringToLong((char *) SvPV(ST(1),na));
4168 break;
4169 }
4170 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4171 attribute);
4172 break;
4173 }
4174 default:
4175 {
4176 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4177 attribute);
4178 break;
4179 }
4180 }
4181 }
4182 count=0;
4183 for ( ; image; image=image->next)
4184 {
4185 channel_features=GetImageFeatures(image,distance,exception);
4186 if (channel_features == (ChannelFeatures *) NULL)
4187 continue;
4188 count++;
4189 EXTEND(sp,75*count);
4190 for (i=0; i < 4; i++)
4191 {
4192 ChannelFeatures(RedChannel,i);
4193 ChannelFeatures(GreenChannel,i);
4194 ChannelFeatures(BlueChannel,i);
4195 if (image->colorspace == CMYKColorspace)
4196 ChannelFeatures(BlackChannel,i);
4197 if (image->alpha_trait == BlendPixelTrait)
4198 ChannelFeatures(AlphaChannel,i);
4199 }
4200 channel_features=(ChannelFeatures *)
4201 RelinquishMagickMemory(channel_features);
4202 }
4203
4204 PerlException:
4205 InheritPerlException(exception,perl_exception);
4206 exception=DestroyExceptionInfo(exception);
4207 SvREFCNT_dec(perl_exception);
4208 }
4209
4210#
4211###############################################################################
4212# #
4213# #
4214# #
4215# F l a t t e n #
4216# #
4217# #
4218# #
4219###############################################################################
4220#
4221#
4222void
4223Flatten(ref)
4224 Image::Magick ref=NO_INIT
4225 ALIAS:
4226 FlattenImage = 1
4227 flatten = 2
4228 flattenimage = 3
4229 PPCODE:
4230 {
4231 AV
4232 *av;
4233
4234 char
4235 *attribute,
4236 *p;
4237
4238 ExceptionInfo
4239 *exception;
4240
4241 HV
4242 *hv;
4243
4244 Image
4245 *image;
4246
4247 PixelInfo
4248 background_color;
4249
4250 register ssize_t
4251 i;
4252
4253 struct PackageInfo
4254 *info;
4255
4256 SV
4257 *perl_exception,
4258 *reference,
4259 *rv,
4260 *sv;
4261
4262 PERL_UNUSED_VAR(ref);
4263 PERL_UNUSED_VAR(ix);
4264 exception=AcquireExceptionInfo();
4265 perl_exception=newSVpv("",0);
4266 sv=NULL;
4267 if (sv_isobject(ST(0)) == 0)
4268 {
4269 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4270 PackageName);
4271 goto PerlException;
4272 }
4273 reference=SvRV(ST(0));
4274 hv=SvSTASH(reference);
4275 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4276 if (image == (Image *) NULL)
4277 {
4278 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4279 PackageName);
4280 goto PerlException;
4281 }
4282 background_color=image->background_color;
4283 if (items == 2)
4284 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4285 &background_color,exception);
4286 else
4287 for (i=2; i < items; i+=2)
4288 {
4289 attribute=(char *) SvPV(ST(i-1),na);
4290 switch (*attribute)
4291 {
4292 case 'B':
4293 case 'b':
4294 {
4295 if (LocaleCompare(attribute,"background") == 0)
4296 {
4297 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4298 AllCompliance,&background_color,exception);
4299 break;
4300 }
4301 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4302 attribute);
4303 break;
4304 }
4305 default:
4306 {
4307 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4308 attribute);
4309 break;
4310 }
4311 }
4312 }
4313 image->background_color=background_color;
4314 image=MergeImageLayers(image,FlattenLayer,exception);
4315 if (image == (Image *) NULL)
4316 goto PerlException;
4317 /*
4318 Create blessed Perl array for the returned image.
4319 */
4320 av=newAV();
4321 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4322 SvREFCNT_dec(av);
4323 AddImageToRegistry(sv,image);
4324 rv=newRV(sv);
4325 av_push(av,sv_bless(rv,hv));
4326 SvREFCNT_dec(sv);
4327 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4328 (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
4329 "flatten-%.*s",(int) (MaxTextExtent-9),
4330 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4331 (void) CopyMagickString(image->filename,info->image_info->filename,
4332 MaxTextExtent);
4333 SetImageInfo(info->image_info,0,exception);
4334 exception=DestroyExceptionInfo(exception);
4335 SvREFCNT_dec(perl_exception);
4336 XSRETURN(1);
4337
4338 PerlException:
4339 InheritPerlException(exception,perl_exception);
4340 exception=DestroyExceptionInfo(exception);
4341 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4342 SvPOK_on(perl_exception); /* return messages in string context */
4343 ST(0)=sv_2mortal(perl_exception);
4344 XSRETURN(1);
4345 }
4346
4347#
4348###############################################################################
4349# #
4350# #
4351# #
4352# F x #
4353# #
4354# #
4355# #
4356###############################################################################
4357#
4358#
4359void
4360Fx(ref,...)
4361 Image::Magick ref=NO_INIT
4362 ALIAS:
4363 FxImage = 1
4364 fx = 2
4365 fximage = 3
4366 PPCODE:
4367 {
4368 AV
4369 *av;
4370
4371 char
4372 *attribute,
4373 expression[MaxTextExtent];
4374
4375 ChannelType
4376 channel,
4377 channel_mask;
4378
4379 ExceptionInfo
4380 *exception;
4381
4382 HV
4383 *hv;
4384
4385 Image
4386 *image;
4387
4388 register ssize_t
4389 i;
4390
4391 struct PackageInfo
4392 *info;
4393
4394 SV
4395 *av_reference,
4396 *perl_exception,
4397 *reference,
4398 *rv,
4399 *sv;
4400
4401 PERL_UNUSED_VAR(ref);
4402 PERL_UNUSED_VAR(ix);
4403 exception=AcquireExceptionInfo();
4404 perl_exception=newSVpv("",0);
4405 sv=NULL;
4406 attribute=NULL;
4407 av=NULL;
4408 if (sv_isobject(ST(0)) == 0)
4409 {
4410 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4411 PackageName);
4412 goto PerlException;
4413 }
4414 reference=SvRV(ST(0));
4415 hv=SvSTASH(reference);
4416 av=newAV();
4417 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4418 SvREFCNT_dec(av);
4419 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4420 if (image == (Image *) NULL)
4421 {
4422 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4423 PackageName);
4424 goto PerlException;
4425 }
4426 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4427 /*
4428 Get options.
4429 */
4430 channel=DefaultChannels;
4431 (void) CopyMagickString(expression,"u",MaxTextExtent);
4432 if (items == 2)
4433 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MaxTextExtent);
4434 else
4435 for (i=2; i < items; i+=2)
4436 {
4437 attribute=(char *) SvPV(ST(i-1),na);
4438 switch (*attribute)
4439 {
4440 case 'C':
4441 case 'c':
4442 {
4443 if (LocaleCompare(attribute,"channel") == 0)
4444 {
4445 ssize_t
4446 option;
4447
4448 option=ParseChannelOption(SvPV(ST(i),na));
4449 if (option < 0)
4450 {
4451 ThrowPerlException(exception,OptionError,
4452 "UnrecognizedType",SvPV(ST(i),na));
4453 return;
4454 }
4455 channel=(ChannelType) option;
4456 break;
4457 }
4458 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4459 attribute);
4460 break;
4461 }
4462 case 'E':
4463 case 'e':
4464 {
4465 if (LocaleCompare(attribute,"expression") == 0)
4466 {
4467 (void) CopyMagickString(expression,SvPV(ST(i),na),
4468 MaxTextExtent);
4469 break;
4470 }
4471 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4472 attribute);
4473 break;
4474 }
4475 default:
4476 {
4477 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4478 attribute);
4479 break;
4480 }
4481 }
4482 }
4483 channel_mask=SetImageChannelMask(image,channel);
4484 image=FxImage(image,expression,exception);
4485 if (image != (Image *) NULL)
4486 (void) SetImageChannelMask(image,channel_mask);
4487 if (image == (Image *) NULL)
4488 goto PerlException;
4489 for ( ; image; image=image->next)
4490 {
4491 AddImageToRegistry(sv,image);
4492 rv=newRV(sv);
4493 av_push(av,sv_bless(rv,hv));
4494 SvREFCNT_dec(sv);
4495 }
4496 exception=DestroyExceptionInfo(exception);
4497 ST(0)=av_reference;
4498 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4499 XSRETURN(1);
4500
4501 PerlException:
4502 InheritPerlException(exception,perl_exception);
4503 exception=DestroyExceptionInfo(exception);
4504 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4505 SvPOK_on(perl_exception);
4506 ST(0)=sv_2mortal(perl_exception);
4507 XSRETURN(1);
4508 }
4509
4510#
4511###############################################################################
4512# #
4513# #
4514# #
4515# G e t #
4516# #
4517# #
4518# #
4519###############################################################################
4520#
4521#
4522void
4523Get(ref,...)
4524 Image::Magick ref=NO_INIT
4525 ALIAS:
4526 GetAttributes = 1
4527 GetAttribute = 2
4528 get = 3
4529 getattributes = 4
4530 getattribute = 5
4531 PPCODE:
4532 {
4533 char
4534 *attribute,
4535 color[MaxTextExtent];
4536
4537 const char
4538 *value;
4539
4540 ExceptionInfo
4541 *exception;
4542
4543 Image
4544 *image;
4545
4546 long
4547 j;
4548
4549 register ssize_t
4550 i;
4551
4552 struct PackageInfo
4553 *info;
4554
4555 SV
4556 *perl_exception,
4557 *reference,
4558 *s;
4559
4560 PERL_UNUSED_VAR(ref);
4561 PERL_UNUSED_VAR(ix);
4562 exception=AcquireExceptionInfo();
4563 perl_exception=newSVpv("",0);
4564 if (sv_isobject(ST(0)) == 0)
4565 {
4566 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4567 PackageName);
4568 XSRETURN_EMPTY;
4569 }
4570 reference=SvRV(ST(0));
4571 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4572 if (image == (Image *) NULL && !info)
4573 XSRETURN_EMPTY;
4574 EXTEND(sp,items);
4575 for (i=1; i < items; i++)
4576 {
4577 attribute=(char *) SvPV(ST(i),na);
4578 s=NULL;
4579 switch (*attribute)
4580 {
4581 case 'A':
4582 case 'a':
4583 {
4584 if (LocaleCompare(attribute,"adjoin") == 0)
4585 {
4586 if (info)
4587 s=newSViv((ssize_t) info->image_info->adjoin);
4588 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4589 continue;
4590 }
4591 if (LocaleCompare(attribute,"antialias") == 0)
4592 {
4593 if (info)
4594 s=newSViv((ssize_t) info->image_info->antialias);
4595 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4596 continue;
4597 }
4598 if (LocaleCompare(attribute,"area") == 0)
4599 {
4600 s=newSViv(GetMagickResource(AreaResource));
4601 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4602 continue;
4603 }
4604 if (LocaleCompare(attribute,"attenuate") == 0)
4605 {
4606 const char
4607 *value;
4608
4609 value=GetImageProperty(image,attribute,exception);
4610 if (value != (const char *) NULL)
4611 s=newSVpv(value,0);
4612 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4613 continue;
4614 }
4615 if (LocaleCompare(attribute,"authenticate") == 0)
4616 {
4617 if (info)
4618 {
4619 const char
4620 *option;
4621
4622 option=GetImageOption(info->image_info,attribute);
4623 if (option != (const char *) NULL)
4624 s=newSVpv(option,0);
4625 }
4626 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4627 continue;
4628 }
4629 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4630 attribute);
4631 break;
4632 }
4633 case 'B':
4634 case 'b':
4635 {
4636 if (LocaleCompare(attribute,"background") == 0)
4637 {
4638 if (image == (Image *) NULL)
4639 break;
4640 (void) FormatLocaleString(color,MaxTextExtent,
4641 "%.20g,%.20g,%.20g,%.20g",image->background_color.red,
4642 image->background_color.green,image->background_color.blue,
4643 image->background_color.alpha);
4644 s=newSVpv(color,0);
4645 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4646 continue;
4647 }
4648 if (LocaleCompare(attribute,"base-columns") == 0)
4649 {
4650 if (image != (Image *) NULL)
4651 s=newSViv((ssize_t) image->magick_columns);
4652 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4653 continue;
4654 }
4655 if (LocaleCompare(attribute,"base-filename") == 0)
4656 {
4657 if (image != (Image *) NULL)
4658 s=newSVpv(image->magick_filename,0);
4659 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4660 continue;
4661 }
4662 if (LocaleCompare(attribute,"base-height") == 0)
4663 {
4664 if (image != (Image *) NULL)
4665 s=newSViv((ssize_t) image->magick_rows);
4666 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4667 continue;
4668 }
4669 if (LocaleCompare(attribute,"base-rows") == 0)
4670 {
4671 if (image != (Image *) NULL)
4672 s=newSViv((ssize_t) image->magick_rows);
4673 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4674 continue;
4675 }
4676 if (LocaleCompare(attribute,"base-width") == 0)
4677 {
4678 if (image != (Image *) NULL)
4679 s=newSViv((ssize_t) image->magick_columns);
4680 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4681 continue;
4682 }
4683 if (LocaleCompare(attribute,"blue-primary") == 0)
4684 {
4685 if (image == (Image *) NULL)
4686 break;
4687 (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
4688 image->chromaticity.blue_primary.x,
4689 image->chromaticity.blue_primary.y);
4690 s=newSVpv(color,0);
4691 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4692 continue;
4693 }
4694 if (LocaleCompare(attribute,"bordercolor") == 0)
4695 {
4696 if (image == (Image *) NULL)
4697 break;
4698 (void) FormatLocaleString(color,MaxTextExtent,
4699 "%.20g,%.20g,%.20g,%.20g",image->border_color.red,
4700 image->border_color.green,image->border_color.blue,
4701 image->border_color.alpha);
4702 s=newSVpv(color,0);
4703 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4704 continue;
4705 }
4706 if (LocaleCompare(attribute,"bounding-box") == 0)
4707 {
4708 char
4709 geometry[MaxTextExtent];
4710
4711 RectangleInfo
4712 page;
4713
4714 if (image == (Image *) NULL)
4715 break;
4716 page=GetImageBoundingBox(image,exception);
4717 (void) FormatLocaleString(geometry,MaxTextExtent,
4718 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4719 page.height,(double) page.x,(double) page.y);
4720 s=newSVpv(geometry,0);
4721 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4722 continue;
4723 }
4724 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4725 attribute);
4726 break;
4727 }
4728 case 'C':
4729 case 'c':
4730 {
4731 if (LocaleCompare(attribute,"class") == 0)
4732 {
4733 if (image == (Image *) NULL)
4734 break;
4735 s=newSViv(image->storage_class);
4736 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4737 image->storage_class));
4738 SvIOK_on(s);
4739 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4740 continue;
4741 }
4742 if (LocaleCompare(attribute,"clip-mask") == 0)
4743 {
4744 if (image != (Image *) NULL)
4745 {
4746 Image
4747 *mask_image;
4748
4749 SV
4750 *sv;
4751
4752 sv=NULL;
4753 if (image->read_mask == MagickFalse)
4754 ClipImage(image,exception);
4755 mask_image=GetImageMask(image,exception);
4756 if (mask_image != (Image *) NULL)
4757 {
4758 AddImageToRegistry(sv,mask_image);
4759 s=sv_bless(newRV(sv),SvSTASH(reference));
4760 }
4761 }
4762 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4763 continue;
4764 }
4765 if (LocaleCompare(attribute,"clip-path") == 0)
4766 {
4767 if (image != (Image *) NULL)
4768 {
4769 Image
4770 *mask_image;
4771
4772 SV
4773 *sv;
4774
4775 sv=NULL;
4776 if (image->read_mask != MagickFalse)
4777 ClipImage(image,exception);
4778 mask_image=GetImageMask(image,exception);
4779 if (mask_image != (Image *) NULL)
4780 {
4781 AddImageToRegistry(sv,mask_image);
4782 s=sv_bless(newRV(sv),SvSTASH(reference));
4783 }
4784 }
4785 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4786 continue;
4787 }
4788 if (LocaleCompare(attribute,"compression") == 0)
4789 {
4790 j=info ? info->image_info->compression : image ?
4791 image->compression : UndefinedCompression;
4792 if (info)
4793 if (info->image_info->compression == UndefinedCompression)
4794 j=image->compression;
4795 s=newSViv(j);
4796 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4797 j));
4798 SvIOK_on(s);
4799 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4800 continue;
4801 }
4802 if (LocaleCompare(attribute,"colorspace") == 0)
4803 {
4804 j=image ? image->colorspace : RGBColorspace;
4805 s=newSViv(j);
4806 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4807 j));
4808 SvIOK_on(s);
4809 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4810 continue;
4811 }
4812 if (LocaleCompare(attribute,"colors") == 0)
4813 {
4814 if (image != (Image *) NULL)
4815 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4816 exception));
4817 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4818 continue;
4819 }
4820 if (LocaleNCompare(attribute,"colormap",8) == 0)
4821 {
4822 int
4823 items;
4824
4825 if (image == (Image *) NULL || !image->colormap)
4826 break;
4827 j=0;
4828 items=sscanf(attribute,"%*[^[][%ld",&j);
4829 (void) items;
4830 if (j > (ssize_t) image->colors)
4831 j%=image->colors;
4832 (void) FormatLocaleString(color,MaxTextExtent,
4833 "%.20g,%.20g,%.20g,%.20g",image->colormap[j].red,
4834 image->colormap[j].green,image->colormap[j].blue,
4835 image->colormap[j].alpha);
4836 s=newSVpv(color,0);
4837 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4838 continue;
4839 }
4840 if (LocaleCompare(attribute,"columns") == 0)
4841 {
4842 if (image != (Image *) NULL)
4843 s=newSViv((ssize_t) image->columns);
4844 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4845 continue;
4846 }
4847 if (LocaleCompare(attribute,"comment") == 0)
4848 {
4849 const char
4850 *value;
4851
4852 value=GetImageProperty(image,attribute,exception);
4853 if (value != (const char *) NULL)
4854 s=newSVpv(value,0);
4855 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4856 continue;
4857 }
4858 if (LocaleCompare(attribute,"copyright") == 0)
4859 {
4860 s=newSVpv(GetMagickCopyright(),0);
4861 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4862 continue;
4863 }
4864 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4865 attribute);
4866 break;
4867 }
4868 case 'D':
4869 case 'd':
4870 {
4871 if (LocaleCompare(attribute,"density") == 0)
4872 {
4873 char
4874 geometry[MaxTextExtent];
4875
4876 if (image == (Image *) NULL)
4877 break;
4878 (void) FormatLocaleString(geometry,MaxTextExtent,"%.15gx%.15g",
4879 image->resolution.x,image->resolution.y);
4880 s=newSVpv(geometry,0);
4881 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4882 continue;
4883 }
4884 if (LocaleCompare(attribute,"delay") == 0)
4885 {
4886 if (image != (Image *) NULL)
4887 s=newSViv((ssize_t) image->delay);
4888 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4889 continue;
4890 }
4891 if (LocaleCompare(attribute,"depth") == 0)
4892 {
4893 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4894 if (image != (Image *) NULL)
4895 s=newSViv((ssize_t) GetImageDepth(image,exception));
4896 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4897 continue;
4898 }
4899 if (LocaleCompare(attribute,"directory") == 0)
4900 {
4901 if (image && image->directory)
4902 s=newSVpv(image->directory,0);
4903 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4904 continue;
4905 }
4906 if (LocaleCompare(attribute,"dispose") == 0)
4907 {
4908 if (image == (Image *) NULL)
4909 break;
4910
4911 s=newSViv(image->dispose);
4912 (void) sv_setpv(s,
4913 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
4914 SvIOK_on(s);
4915 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4916 continue;
4917 }
4918 if (LocaleCompare(attribute,"disk") == 0)
4919 {
4920 s=newSViv(GetMagickResource(DiskResource));
4921 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4922 continue;
4923 }
4924 if (LocaleCompare(attribute,"dither") == 0)
4925 {
4926 if (info)
4927 s=newSViv((ssize_t) info->image_info->dither);
4928 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4929 continue;
4930 }
4931 if (LocaleCompare(attribute,"display") == 0) /* same as server */
4932 {
4933 if (info && info->image_info->server_name)
4934 s=newSVpv(info->image_info->server_name,0);
4935 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4936 continue;
4937 }
4938 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4939 attribute);
4940 break;
4941 }
4942 case 'E':
4943 case 'e':
4944 {
4945 if (LocaleCompare(attribute,"elapsed-time") == 0)
4946 {
4947 if (image != (Image *) NULL)
4948 s=newSVnv(GetElapsedTime(&image->timer));
4949 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4950 continue;
4951 }
4952 if (LocaleCompare(attribute,"endian") == 0)
4953 {
4954 j=info ? info->image_info->endian : image ? image->endian :
4955 UndefinedEndian;
4956 s=newSViv(j);
4957 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
4958 SvIOK_on(s);
4959 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4960 continue;
4961 }
4962 if (LocaleCompare(attribute,"error") == 0)
4963 {
4964 if (image != (Image *) NULL)
4965 s=newSVnv(image->error.mean_error_per_pixel);
4966 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4967 continue;
4968 }
4969 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4970 attribute);
4971 break;
4972 }
4973 case 'F':
4974 case 'f':
4975 {
4976 if (LocaleCompare(attribute,"filesize") == 0)
4977 {
4978 if (image != (Image *) NULL)
4979 s=newSViv((ssize_t) GetBlobSize(image));
4980 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4981 continue;
4982 }
4983 if (LocaleCompare(attribute,"filename") == 0)
4984 {
4985 if (info && info->image_info->filename &&
4986 *info->image_info->filename)
4987 s=newSVpv(info->image_info->filename,0);
4988 if (image != (Image *) NULL)
4989 s=newSVpv(image->filename,0);
4990 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4991 continue;
4992 }
4993 if (LocaleCompare(attribute,"filter") == 0)
4994 {
4995 s=image ? newSViv(image->filter) : newSViv(0);
4996 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
4997 image->filter));
4998 SvIOK_on(s);
4999 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5000 continue;
5001 }
5002 if (LocaleCompare(attribute,"font") == 0)
5003 {
5004 if (info && info->image_info->font)
5005 s=newSVpv(info->image_info->font,0);
5006 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5007 continue;
5008 }
5009 if (LocaleCompare(attribute,"foreground") == 0)
5010 continue;
5011 if (LocaleCompare(attribute,"format") == 0)
5012 {
5013 const MagickInfo
5014 *magick_info;
5015
5016 magick_info=(const MagickInfo *) NULL;
5017 if (info && (*info->image_info->magick != '\0'))
5018 magick_info=GetMagickInfo(info->image_info->magick,exception);
5019 if (image != (Image *) NULL)
5020 magick_info=GetMagickInfo(image->magick,exception);
5021 if ((magick_info != (const MagickInfo *) NULL) &&
5022 (*magick_info->description != '\0'))
5023 s=newSVpv((char *) magick_info->description,0);
5024 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5025 continue;
5026 }
5027 if (LocaleCompare(attribute,"fuzz") == 0)
5028 {
5029 if (info)
5030 s=newSVnv(info->image_info->fuzz);
5031 if (image != (Image *) NULL)
5032 s=newSVnv(image->fuzz);
5033 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5034 continue;
5035 }
5036 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5037 attribute);
5038 break;
5039 }
5040 case 'G':
5041 case 'g':
5042 {
5043 if (LocaleCompare(attribute,"gamma") == 0)
5044 {
5045 if (image != (Image *) NULL)
5046 s=newSVnv(image->gamma);
5047 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5048 continue;
5049 }
5050 if (LocaleCompare(attribute,"geometry") == 0)
5051 {
5052 if (image && image->geometry)
5053 s=newSVpv(image->geometry,0);
5054 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5055 continue;
5056 }
5057 if (LocaleCompare(attribute,"gravity") == 0)
5058 {
5059 s=image ? newSViv(image->gravity) : newSViv(0);
5060 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5061 image->gravity));
5062 SvIOK_on(s);
5063 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5064 continue;
5065 }
5066 if (LocaleCompare(attribute,"green-primary") == 0)
5067 {
5068 if (image == (Image *) NULL)
5069 break;
5070 (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
5071 image->chromaticity.green_primary.x,
5072 image->chromaticity.green_primary.y);
5073 s=newSVpv(color,0);
5074 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5075 continue;
5076 }
5077 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5078 attribute);
5079 break;
5080 }
5081 case 'H':
5082 case 'h':
5083 {
5084 if (LocaleCompare(attribute,"height") == 0)
5085 {
5086 if (image != (Image *) NULL)
5087 s=newSViv((ssize_t) image->rows);
5088 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5089 continue;
5090 }
5091 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5092 attribute);
5093 break;
5094 }
5095 case 'I':
5096 case 'i':
5097 {
5098 if (LocaleCompare(attribute,"icc") == 0)
5099 {
5100 if (image != (Image *) NULL)
5101 {
5102 const StringInfo
5103 *profile;
5104
5105 profile=GetImageProfile(image,"icc");
5106 if (profile != (StringInfo *) NULL)
5107 s=newSVpv((const char *) GetStringInfoDatum(profile),
5108 GetStringInfoLength(profile));
5109 }
5110 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5111 continue;
5112 }
5113 if (LocaleCompare(attribute,"icm") == 0)
5114 {
5115 if (image != (Image *) NULL)
5116 {
5117 const StringInfo
5118 *profile;
5119
5120 profile=GetImageProfile(image,"icm");
5121 if (profile != (const StringInfo *) NULL)
5122 s=newSVpv((const char *) GetStringInfoDatum(profile),
5123 GetStringInfoLength(profile));
5124 }
5125 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5126 continue;
5127 }
5128 if (LocaleCompare(attribute,"id") == 0)
5129 {
5130 if (image != (Image *) NULL)
5131 {
5132 char
5133 key[MaxTextExtent];
5134
5135 MagickBooleanType
5136 status;
5137
5138 static ssize_t
5139 id = 0;
5140
5141 (void) FormatLocaleString(key,MaxTextExtent,"%.20g\n",(double)
5142 id);
5143 status=SetImageRegistry(ImageRegistryType,key,image,
5144 exception);
5145 (void) status;
5146 s=newSViv(id++);
5147 }
5148 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5149 continue;
5150 }
5151 if (LocaleNCompare(attribute,"index",5) == 0)
5152 {
5153 char
5154 name[MaxTextExtent];
5155
5156 int
5157 items;
5158
5159 long
5160 x,
5161 y;
5162
5163 register const Quantum
5164 *p;
5165
5166 CacheView
5167 *image_view;
5168
5169 if (image == (Image *) NULL)
5170 break;
5171 if (image->storage_class != PseudoClass)
5172 break;
5173 x=0;
5174 y=0;
5175 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5176 (void) items;
5177 image_view=AcquireVirtualCacheView(image,exception);
5178 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5179 if (p != (const Quantum *) NULL)
5180 {
5181 (void) FormatLocaleString(name,MaxTextExtent,QuantumFormat,
5182 GetPixelIndex(image,p));
5183 s=newSVpv(name,0);
5184 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5185 }
5186 image_view=DestroyCacheView(image_view);
5187 continue;
5188 }
5189 if (LocaleCompare(attribute,"iptc") == 0)
5190 {
5191 if (image != (Image *) NULL)
5192 {
5193 const StringInfo
5194 *profile;
5195
5196 profile=GetImageProfile(image,"iptc");
5197 if (profile != (const StringInfo *) NULL)
5198 s=newSVpv((const char *) GetStringInfoDatum(profile),
5199 GetStringInfoLength(profile));
5200 }
5201 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5202 continue;
5203 }
5204 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5205 {
5206 if (image != (Image *) NULL)
5207 s=newSViv((ssize_t) image->iterations);
5208 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5209 continue;
5210 }
5211 if (LocaleCompare(attribute,"interlace") == 0)
5212 {
5213 j=info ? info->image_info->interlace : image ? image->interlace :
5214 UndefinedInterlace;
5215 s=newSViv(j);
5216 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5217 j));
5218 SvIOK_on(s);
5219 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5220 continue;
5221 }
5222 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5223 attribute);
5224 break;
5225 }
5226 case 'L':
5227 case 'l':
5228 {
5229 if (LocaleCompare(attribute,"label") == 0)
5230 {
5231 const char
5232 *value;
5233
5234 if (image == (Image *) NULL)
5235 break;
5236 value=GetImageProperty(image,"Label",exception);
5237 if (value != (const char *) NULL)
5238 s=newSVpv(value,0);
5239 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5240 continue;
5241 }
5242 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5243 {
5244 if (image != (Image *) NULL)
5245 s=newSViv((ssize_t) image->iterations);
5246 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5247 continue;
5248 }
5249 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5250 attribute);
5251 break;
5252 }
5253 case 'M':
5254 case 'm':
5255 {
5256 if (LocaleCompare(attribute,"magick") == 0)
5257 {
5258 if (info && *info->image_info->magick)
5259 s=newSVpv(info->image_info->magick,0);
5260 if (image != (Image *) NULL)
5261 s=newSVpv(image->magick,0);
5262 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5263 continue;
5264 }
5265 if (LocaleCompare(attribute,"map") == 0)
5266 {
5267 s=newSViv(GetMagickResource(MapResource));
5268 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5269 continue;
5270 }
5271 if (LocaleCompare(attribute,"maximum-error") == 0)
5272 {
5273 if (image != (Image *) NULL)
5274 s=newSVnv(image->error.normalized_maximum_error);
5275 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5276 continue;
5277 }
5278 if (LocaleCompare(attribute,"memory") == 0)
5279 {
5280 s=newSViv(GetMagickResource(MemoryResource));
5281 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5282 continue;
5283 }
5284 if (LocaleCompare(attribute,"mean-error") == 0)
5285 {
5286 if (image != (Image *) NULL)
5287 s=newSVnv(image->error.normalized_mean_error);
5288 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5289 continue;
5290 }
5291 if (LocaleCompare(attribute,"mime") == 0)
5292 {
5293 if (info && *info->image_info->magick)
5294 s=newSVpv(MagickToMime(info->image_info->magick),0);
5295 if (image != (Image *) NULL)
5296 s=newSVpv(MagickToMime(image->magick),0);
5297 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5298 continue;
5299 }
5300 if (LocaleCompare(attribute,"mattecolor") == 0)
5301 {
5302 if (image == (Image *) NULL)
5303 break;
5304 (void) FormatLocaleString(color,MaxTextExtent,
5305 "%.20g,%.20g,%.20g,%.20g",image->matte_color.red,
5306 image->matte_color.green,image->matte_color.blue,
5307 image->matte_color.alpha);
5308 s=newSVpv(color,0);
5309 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5310 continue;
5311 }
5312 if (LocaleCompare(attribute,"matte") == 0)
5313 {
5314 if (image != (Image *) NULL)
5315 s=newSViv((ssize_t) image->alpha_trait == BlendPixelTrait ?
5316 1 : 0);
5317 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5318 continue;
5319 }
5320 if (LocaleCompare(attribute,"mime") == 0)
5321 {
5322 const char
5323 *magick;
5324
5325 magick=NULL;
5326 if (info && *info->image_info->magick)
5327 magick=info->image_info->magick;
5328 if (image != (Image *) NULL)
5329 magick=image->magick;
5330 if (magick)
5331 {
5332 char
5333 *mime;
5334
5335 mime=MagickToMime(magick);
5336 s=newSVpv(mime,0);
5337 mime=(char *) RelinquishMagickMemory(mime);
5338 }
5339 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5340 continue;
5341 }
5342 if (LocaleCompare(attribute,"monochrome") == 0)
5343 {
5344 if (image == (Image *) NULL)
5345 continue;
5346 j=info ? info->image_info->monochrome :
5347 IsImageMonochrome(image,exception);
5348 s=newSViv(j);
5349 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5350 continue;
5351 }
5352 if (LocaleCompare(attribute,"montage") == 0)
5353 {
5354 if (image && image->montage)
5355 s=newSVpv(image->montage,0);
5356 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5357 continue;
5358 }
5359 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5360 attribute);
5361 break;
5362 }
5363 case 'O':
5364 case 'o':
5365 {
5366 if (LocaleCompare(attribute,"orientation") == 0)
5367 {
5368 j=info ? info->image_info->orientation : image ?
5369 image->orientation : UndefinedOrientation;
5370 s=newSViv(j);
5371 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5372 j));
5373 SvIOK_on(s);
5374 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5375 continue;
5376 }
5377 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5378 attribute);
5379 break;
5380 }
5381 case 'P':
5382 case 'p':
5383 {
5384 if (LocaleCompare(attribute,"page") == 0)
5385 {
5386 if (info && info->image_info->page)
5387 s=newSVpv(info->image_info->page,0);
5388 if (image != (Image *) NULL)
5389 {
5390 char
5391 geometry[MaxTextExtent];
5392
5393 (void) FormatLocaleString(geometry,MaxTextExtent,
5394 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5395 (double) image->page.height,(double) image->page.x,(double)
5396 image->page.y);
5397 s=newSVpv(geometry,0);
5398 }
5399 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5400 continue;
5401 }
5402 if (LocaleCompare(attribute,"page.x") == 0)
5403 {
5404 if (image != (Image *) NULL)
5405 s=newSViv((ssize_t) image->page.x);
5406 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5407 continue;
5408 }
5409 if (LocaleCompare(attribute,"page.y") == 0)
5410 {
5411 if (image != (Image *) NULL)
5412 s=newSViv((ssize_t) image->page.y);
5413 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5414 continue;
5415 }
5416 if (LocaleNCompare(attribute,"pixel",5) == 0)
5417 {
5418 char
5419 tuple[MaxTextExtent];
5420
5421 int
5422 items;
5423
5424 long
5425 x,
5426 y;
5427
5428 register const Quantum
5429 *p;
5430
5431 if (image == (Image *) NULL)
5432 break;
5433 x=0;
5434 y=0;
5435 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5436 (void) items;
5437 p=GetVirtualPixels(image,x,y,1,1,exception);
5438 if (image->colorspace != CMYKColorspace)
5439 (void) FormatLocaleString(tuple,MaxTextExtent,QuantumFormat ","
5440 QuantumFormat "," QuantumFormat "," QuantumFormat,
5441 GetPixelRed(image,p),GetPixelGreen(image,p),
5442 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5443 else
5444 (void) FormatLocaleString(tuple,MaxTextExtent,QuantumFormat ","
5445 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5446 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5447 GetPixelBlue(image,p),GetPixelBlack(image,p),
5448 GetPixelAlpha(image,p));
5449 s=newSVpv(tuple,0);
5450 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5451 continue;
5452 }
5453 if (LocaleCompare(attribute,"pointsize") == 0)
5454 {
5455 if (info)
5456 s=newSViv((ssize_t) info->image_info->pointsize);
5457 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5458 continue;
5459 }
5460 if (LocaleCompare(attribute,"preview") == 0)
5461 {
5462 s=newSViv(info->image_info->preview_type);
5463 (void) sv_setpv(s,CommandOptionToMnemonic(MagickPreviewOptions,
5464 info->image_info->preview_type));
5465 SvIOK_on(s);
5466 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5467 continue;
5468 }
5469 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5470 attribute);
5471 break;
5472 }
5473 case 'Q':
5474 case 'q':
5475 {
5476 if (LocaleCompare(attribute,"quality") == 0)
5477 {
5478 if (info)
5479 s=newSViv((ssize_t) info->image_info->quality);
5480 if (image != (Image *) NULL)
5481 s=newSViv((ssize_t) image->quality);
5482 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5483 continue;
5484 }
5485 if (LocaleCompare(attribute,"quantum") == 0)
5486 {
5487 if (info)
5488 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5489 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5490 continue;
5491 }
5492 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5493 attribute);
5494 break;
5495 }
5496 case 'R':
5497 case 'r':
5498 {
5499 if (LocaleCompare(attribute,"rendering-intent") == 0)
5500 {
5501 s=newSViv(image->rendering_intent);
5502 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5503 image->rendering_intent));
5504 SvIOK_on(s);
5505 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5506 continue;
5507 }
5508 if (LocaleCompare(attribute,"red-primary") == 0)
5509 {
5510 if (image == (Image *) NULL)
5511 break;
5512 (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
5513 image->chromaticity.red_primary.x,
5514 image->chromaticity.red_primary.y);
5515 s=newSVpv(color,0);
5516 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5517 continue;
5518 }
5519 if (LocaleCompare(attribute,"rows") == 0)
5520 {
5521 if (image != (Image *) NULL)
5522 s=newSViv((ssize_t) image->rows);
5523 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5524 continue;
5525 }
5526 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5527 attribute);
5528 break;
5529 }
5530 case 'S':
5531 case 's':
5532 {
5533 if (LocaleCompare(attribute,"sampling-factor") == 0)
5534 {
5535 if (info && info->image_info->sampling_factor)
5536 s=newSVpv(info->image_info->sampling_factor,0);
5537 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5538 continue;
5539 }
5540 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5541 {
5542 if (info && info->image_info->server_name)
5543 s=newSVpv(info->image_info->server_name,0);
5544 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5545 continue;
5546 }
5547 if (LocaleCompare(attribute,"size") == 0)
5548 {
5549 if (info && info->image_info->size)
5550 s=newSVpv(info->image_info->size,0);
5551 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5552 continue;
5553 }
5554 if (LocaleCompare(attribute,"scene") == 0)
5555 {
5556 if (image != (Image *) NULL)
5557 s=newSViv((ssize_t) image->scene);
5558 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5559 continue;
5560 }
5561 if (LocaleCompare(attribute,"scenes") == 0)
5562 {
5563 if (image != (Image *) NULL)
5564 s=newSViv((ssize_t) info->image_info->number_scenes);
5565 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5566 continue;
5567 }
5568 if (LocaleCompare(attribute,"signature") == 0)
5569 {
5570 const char
5571 *value;
5572
5573 if (image == (Image *) NULL)
5574 break;
5575 (void) SignatureImage(image,exception);
5576 value=GetImageProperty(image,"Signature",exception);
5577 if (value != (const char *) NULL)
5578 s=newSVpv(value,0);
5579 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5580 continue;
5581 }
5582 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5583 attribute);
5584 break;
5585 }
5586 case 'T':
5587 case 't':
5588 {
5589 if (LocaleCompare(attribute,"taint") == 0)
5590 {
5591 if (image != (Image *) NULL)
5592 s=newSViv((ssize_t) IsTaintImage(image));
5593 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5594 continue;
5595 }
5596 if (LocaleCompare(attribute,"texture") == 0)
5597 {
5598 if (info && info->image_info->texture)
5599 s=newSVpv(info->image_info->texture,0);
5600 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5601 continue;
5602 }
5603 if (LocaleCompare(attribute,"total-ink-density") == 0)
5604 {
5605 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5606 if (image != (Image *) NULL)
5607 s=newSVnv(GetImageTotalInkDensity(image,exception));
5608 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5609 continue;
5610 }
5611 if (LocaleCompare(attribute,"transparent-color") == 0)
5612 {
5613 if (image == (Image *) NULL)
5614 break;
5615 (void) FormatLocaleString(color,MaxTextExtent,
5616 "%.20g,%.20g,%.20g,%.20g",image->transparent_color.red,
5617 image->transparent_color.green,image->transparent_color.blue,
5618 image->transparent_color.alpha);
5619 s=newSVpv(color,0);
5620 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5621 continue;
5622 }
5623 if (LocaleCompare(attribute,"type") == 0)
5624 {
5625 if (image == (Image *) NULL)
5626 break;
5627 j=(ssize_t) GetImageType(image,exception);
5628 s=newSViv(j);
5629 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5630 SvIOK_on(s);
5631 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5632 continue;
5633 }
5634 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5635 attribute);
5636 break;
5637 }
5638 case 'U':
5639 case 'u':
5640 {
5641 if (LocaleCompare(attribute,"units") == 0)
5642 {
5643 j=info ? info->image_info->units : image ? image->units :
5644 UndefinedResolution;
5645 if (info && (info->image_info->units == UndefinedResolution))
5646 if (image)
5647 j=image->units;
5648 if (j == UndefinedResolution)
5649 s=newSVpv("undefined units",0);
5650 else
5651 if (j == PixelsPerInchResolution)
5652 s=newSVpv("pixels / inch",0);
5653 else
5654 s=newSVpv("pixels / centimeter",0);
5655 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5656 continue;
5657 }
5658 if (LocaleCompare(attribute,"user-time") == 0)
5659 {
5660 if (image != (Image *) NULL)
5661 s=newSVnv(GetUserTime(&image->timer));
5662 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5663 continue;
5664 }
5665 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5666 attribute);
5667 break;
5668 }
5669 case 'V':
5670 case 'v':
5671 {
5672 if (LocaleCompare(attribute,"verbose") == 0)
5673 {
5674 if (info)
5675 s=newSViv((ssize_t) info->image_info->verbose);
5676 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5677 continue;
5678 }
5679 if (LocaleCompare(attribute,"version") == 0)
5680 {
5681 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5682 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5683 continue;
5684 }
5685 if (LocaleCompare(attribute,"view") == 0)
5686 {
5687 if (info && info->image_info->view)
5688 s=newSVpv(info->image_info->view,0);
5689 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5690 continue;
5691 }
5692 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5693 {
5694 if (image == (Image *) NULL)
5695 break;
5696 j=(ssize_t) GetImageVirtualPixelMethod(image);
5697 s=newSViv(j);
5698 (void) sv_setpv(s,CommandOptionToMnemonic(
5699 MagickVirtualPixelOptions,j));
5700 SvIOK_on(s);
5701 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5702 continue;
5703 }
5704 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5705 attribute);
5706 break;
5707 }
5708 case 'W':
5709 case 'w':
5710 {
5711 if (LocaleCompare(attribute,"white-point") == 0)
5712 {
5713 if (image == (Image *) NULL)
5714 break;
5715 (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
5716 image->chromaticity.white_point.x,
5717 image->chromaticity.white_point.y);
5718 s=newSVpv(color,0);
5719 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5720 continue;
5721 }
5722 if (LocaleCompare(attribute,"width") == 0)
5723 {
5724 if (image != (Image *) NULL)
5725 s=newSViv((ssize_t) image->columns);
5726 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5727 continue;
5728 }
5729 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5730 attribute);
5731 break;
5732 }
5733 case 'X':
5734 case 'x':
5735 {
5736 if (LocaleCompare(attribute,"x-resolution") == 0)
5737 {
5738 if (image != (Image *) NULL)
5739 s=newSVnv(image->resolution.x);
5740 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5741 continue;
5742 }
5743 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5744 attribute);
5745 break;
5746 }
5747 case 'Y':
5748 case 'y':
5749 {
5750 if (LocaleCompare(attribute,"y-resolution") == 0)
5751 {
5752 if (image != (Image *) NULL)
5753 s=newSVnv(image->resolution.y);
5754 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5755 continue;
5756 }
5757 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5758 attribute);
5759 break;
5760 }
5761 default:
5762 break;
5763 }
5764 if (image == (Image *) NULL)
5765 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5766 attribute)
5767 else
5768 {
5769 value=GetImageProperty(image,attribute,exception);
5770 if (value != (const char *) NULL)
5771 {
5772 s=newSVpv(value,0);
5773 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5774 }
5775 else
5776 if (*attribute != '%')
5777 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5778 attribute)
5779 else
5780 {
5781 char
5782 *meta;
5783
5784 meta=InterpretImageProperties(info ? info->image_info :
5785 (ImageInfo *) NULL,image,attribute,exception);
5786 s=newSVpv(meta,0);
5787 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5788 meta=(char *) RelinquishMagickMemory(meta);
5789 }
5790 }
5791 }
5792 exception=DestroyExceptionInfo(exception);
5793 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5794 }
5795
5796#
5797###############################################################################
5798# #
5799# #
5800# #
5801# G e t A u t h e n t i c P i x e l s #
5802# #
5803# #
5804# #
5805###############################################################################
5806#
5807#
5808void *
5809GetAuthenticPixels(ref,...)
5810 Image::Magick ref = NO_INIT
5811 ALIAS:
5812 getauthenticpixels = 1
5813 GetImagePixels = 2
5814 getimagepixels = 3
5815 CODE:
5816 {
5817 char
5818 *attribute;
5819
5820 ExceptionInfo
5821 *exception;
5822
5823 Image
5824 *image;
5825
5826 RectangleInfo
5827 region;
5828
5829 ssize_t
5830 i;
5831
5832 struct PackageInfo
5833 *info;
5834
5835 SV
5836 *perl_exception,
5837 *reference;
5838
5839 void
5840 *blob = NULL;
5841
5842 PERL_UNUSED_VAR(ref);
5843 PERL_UNUSED_VAR(ix);
5844 exception=AcquireExceptionInfo();
5845 perl_exception=newSVpv("",0);
5846 if (sv_isobject(ST(0)) == 0)
5847 {
5848 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5849 PackageName);
5850 goto PerlException;
5851 }
5852 reference=SvRV(ST(0));
5853
5854 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5855 if (image == (Image *) NULL)
5856 {
5857 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5858 PackageName);
5859 goto PerlException;
5860 }
5861
5862 region.x=0;
5863 region.y=0;
5864 region.width=image->columns;
5865 region.height=1;
5866 if (items == 1)
5867 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5868 for (i=2; i < items; i+=2)
5869 {
5870 attribute=(char *) SvPV(ST(i-1),na);
5871 switch (*attribute)
5872 {
5873 case 'g':
5874 case 'G':
5875 {
5876 if (LocaleCompare(attribute,"geometry") == 0)
5877 {
5878 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5879 break;
5880 }
5881 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5882 attribute);
5883 break;
5884 }
5885 case 'H':
5886 case 'h':
5887 {
5888 if (LocaleCompare(attribute,"height") == 0)
5889 {
5890 region.height=SvIV(ST(i));
5891 continue;
5892 }
5893 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5894 attribute);
5895 break;
5896 }
5897 case 'X':
5898 case 'x':
5899 {
5900 if (LocaleCompare(attribute,"x") == 0)
5901 {
5902 region.x=SvIV(ST(i));
5903 continue;
5904 }
5905 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5906 attribute);
5907 break;
5908 }
5909 case 'Y':
5910 case 'y':
5911 {
5912 if (LocaleCompare(attribute,"y") == 0)
5913 {
5914 region.y=SvIV(ST(i));
5915 continue;
5916 }
5917 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5918 attribute);
5919 break;
5920 }
5921 case 'W':
5922 case 'w':
5923 {
5924 if (LocaleCompare(attribute,"width") == 0)
5925 {
5926 region.width=SvIV(ST(i));
5927 continue;
5928 }
5929 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5930 attribute);
5931 break;
5932 }
5933 }
5934 }
5935 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5936 region.height,exception);
5937 if (blob != (void *) NULL)
5938 goto PerlEnd;
5939
5940 PerlException:
5941 InheritPerlException(exception,perl_exception);
5942 exception=DestroyExceptionInfo(exception);
5943 SvREFCNT_dec(perl_exception); /* throw away all errors */
5944
5945 PerlEnd:
5946 RETVAL = blob;
5947 }
5948 OUTPUT:
5949 RETVAL
5950
5951#
5952###############################################################################
5953# #
5954# #
5955# #
5956# G e t V i r t u a l P i x e l s #
5957# #
5958# #
5959# #
5960###############################################################################
5961#
5962#
5963void *
5964GetVirtualPixels(ref,...)
5965 Image::Magick ref = NO_INIT
5966 ALIAS:
5967 getvirtualpixels = 1
5968 AcquireImagePixels = 2
5969 acquireimagepixels = 3
5970 CODE:
5971 {
5972 char
5973 *attribute;
5974
5975 const void
5976 *blob = NULL;
5977
5978 ExceptionInfo
5979 *exception;
5980
5981 Image
5982 *image;
5983
5984 RectangleInfo
5985 region;
5986
5987 ssize_t
5988 i;
5989
5990 struct PackageInfo
5991 *info;
5992
5993 SV
5994 *perl_exception,
5995 *reference;
5996
5997 PERL_UNUSED_VAR(ref);
5998 PERL_UNUSED_VAR(ix);
5999 exception=AcquireExceptionInfo();
6000 perl_exception=newSVpv("",0);
6001 if (sv_isobject(ST(0)) == 0)
6002 {
6003 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6004 PackageName);
6005 goto PerlException;
6006 }
6007 reference=SvRV(ST(0));
6008
6009 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6010 if (image == (Image *) NULL)
6011 {
6012 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6013 PackageName);
6014 goto PerlException;
6015 }
6016
6017 region.x=0;
6018 region.y=0;
6019 region.width=image->columns;
6020 region.height=1;
6021 if (items == 1)
6022 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6023 for (i=2; i < items; i+=2)
6024 {
6025 attribute=(char *) SvPV(ST(i-1),na);
6026 switch (*attribute)
6027 {
6028 case 'g':
6029 case 'G':
6030 {
6031 if (LocaleCompare(attribute,"geometry") == 0)
6032 {
6033 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6034 break;
6035 }
6036 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6037 attribute);
6038 break;
6039 }
6040 case 'H':
6041 case 'h':
6042 {
6043 if (LocaleCompare(attribute,"height") == 0)
6044 {
6045 region.height=SvIV(ST(i));
6046 continue;
6047 }
6048 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6049 attribute);
6050 break;
6051 }
6052 case 'X':
6053 case 'x':
6054 {
6055 if (LocaleCompare(attribute,"x") == 0)
6056 {
6057 region.x=SvIV(ST(i));
6058 continue;
6059 }
6060 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6061 attribute);
6062 break;
6063 }
6064 case 'Y':
6065 case 'y':
6066 {
6067 if (LocaleCompare(attribute,"y") == 0)
6068 {
6069 region.y=SvIV(ST(i));
6070 continue;
6071 }
6072 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6073 attribute);
6074 break;
6075 }
6076 case 'W':
6077 case 'w':
6078 {
6079 if (LocaleCompare(attribute,"width") == 0)
6080 {
6081 region.width=SvIV(ST(i));
6082 continue;
6083 }
6084 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6085 attribute);
6086 break;
6087 }
6088 }
6089 }
6090 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6091 region.height,exception);
6092 if (blob != (void *) NULL)
6093 goto PerlEnd;
6094
6095 PerlException:
6096 InheritPerlException(exception,perl_exception);
6097 exception=DestroyExceptionInfo(exception);
6098 SvREFCNT_dec(perl_exception); /* throw away all errors */
6099
6100 PerlEnd:
6101 RETVAL = (void *) blob;
6102 }
6103 OUTPUT:
6104 RETVAL
6105
6106#
6107###############################################################################
6108# #
6109# #
6110# #
6111# G e t A u t h e n t i c M e t a c o n t e n t #
6112# #
6113# #
6114# #
6115###############################################################################
6116#
6117#
6118void *
6119GetAuthenticMetacontent(ref,...)
6120 Image::Magick ref = NO_INIT
6121 ALIAS:
6122 getauthenticmetacontent = 1
6123 GetMetacontent = 2
6124 getmetacontent = 3
6125 CODE:
6126 {
6127 ExceptionInfo
6128 *exception;
6129
6130 Image
6131 *image;
6132
6133 struct PackageInfo
6134 *info;
6135
6136 SV
6137 *perl_exception,
6138 *reference;
6139
6140 void
6141 *blob = NULL;
6142
6143 PERL_UNUSED_VAR(ref);
6144 PERL_UNUSED_VAR(ix);
6145 exception=AcquireExceptionInfo();
6146 perl_exception=newSVpv("",0);
6147 if (sv_isobject(ST(0)) == 0)
6148 {
6149 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6150 PackageName);
6151 goto PerlException;
6152 }
6153 reference=SvRV(ST(0));
6154
6155 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6156 if (image == (Image *) NULL)
6157 {
6158 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6159 PackageName);
6160 goto PerlException;
6161 }
6162
6163 blob=(void *) GetAuthenticMetacontent(image);
6164 if (blob != (void *) NULL)
6165 goto PerlEnd;
6166
6167 PerlException:
6168 InheritPerlException(exception,perl_exception);
6169 exception=DestroyExceptionInfo(exception);
6170 SvREFCNT_dec(perl_exception); /* throw away all errors */
6171
6172 PerlEnd:
6173 RETVAL = blob;
6174 }
6175 OUTPUT:
6176 RETVAL
6177
6178#
6179###############################################################################
6180# #
6181# #
6182# #
6183# G e t V i r t u a l M e t a c o n t e n t #
6184# #
6185# #
6186# #
6187###############################################################################
6188#
6189#
6190void *
6191GetVirtualMetacontent(ref,...)
6192 Image::Magick ref = NO_INIT
6193 ALIAS:
6194 getvirtualmetacontent = 1
6195 CODE:
6196 {
6197 ExceptionInfo
6198 *exception;
6199
6200 Image
6201 *image;
6202
6203 struct PackageInfo
6204 *info;
6205
6206 SV
6207 *perl_exception,
6208 *reference;
6209
6210 void
6211 *blob = NULL;
6212
6213 PERL_UNUSED_VAR(ref);
6214 PERL_UNUSED_VAR(ix);
6215 exception=AcquireExceptionInfo();
6216 perl_exception=newSVpv("",0);
6217 if (sv_isobject(ST(0)) == 0)
6218 {
6219 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6220 PackageName);
6221 goto PerlException;
6222 }
6223 reference=SvRV(ST(0));
6224
6225 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6226 if (image == (Image *) NULL)
6227 {
6228 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6229 PackageName);
6230 goto PerlException;
6231 }
6232
6233 blob=(void *) GetVirtualMetacontent(image);
6234 if (blob != (void *) NULL)
6235 goto PerlEnd;
6236
6237 PerlException:
6238 InheritPerlException(exception,perl_exception);
6239 exception=DestroyExceptionInfo(exception);
6240 SvREFCNT_dec(perl_exception); /* throw away all errors */
6241
6242 PerlEnd:
6243 RETVAL = blob;
6244 }
6245 OUTPUT:
6246 RETVAL
6247
6248#
6249###############################################################################
6250# #
6251# #
6252# #
6253# H i s t o g r a m #
6254# #
6255# #
6256# #
6257###############################################################################
6258#
6259#
6260void
6261Histogram(ref,...)
6262 Image::Magick ref=NO_INIT
6263 ALIAS:
6264 HistogramImage = 1
6265 histogram = 2
6266 histogramimage = 3
6267 PPCODE:
6268 {
6269 AV
6270 *av;
6271
6272 char
6273 message[MaxTextExtent];
6274
6275 PixelInfo
6276 *histogram;
6277
6278 ExceptionInfo
6279 *exception;
6280
6281 Image
6282 *image;
6283
6284 register ssize_t
6285 i;
6286
6287 ssize_t
6288 count;
6289
6290 struct PackageInfo
6291 *info;
6292
6293 SV
6294 *perl_exception,
6295 *reference;
6296
6297 size_t
6298 number_colors;
6299
6300 PERL_UNUSED_VAR(ref);
6301 PERL_UNUSED_VAR(ix);
6302 exception=AcquireExceptionInfo();
6303 perl_exception=newSVpv("",0);
6304 av=NULL;
6305 if (sv_isobject(ST(0)) == 0)
6306 {
6307 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6308 PackageName);
6309 goto PerlException;
6310 }
6311 reference=SvRV(ST(0));
6312 av=newAV();
6313 SvREFCNT_dec(av);
6314 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6315 if (image == (Image *) NULL)
6316 {
6317 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6318 PackageName);
6319 goto PerlException;
6320 }
6321 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
6322 count=0;
6323 for ( ; image; image=image->next)
6324 {
6325 histogram=GetImageHistogram(image,&number_colors,exception);
6326 if (histogram == (PixelInfo *) NULL)
6327 continue;
6328 count+=(ssize_t) number_colors;
6329 EXTEND(sp,6*count);
6330 for (i=0; i < (ssize_t) number_colors; i++)
6331 {
6332 (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
6333 histogram[i].red);
6334 PUSHs(sv_2mortal(newSVpv(message,0)));
6335 (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
6336 histogram[i].green);
6337 PUSHs(sv_2mortal(newSVpv(message,0)));
6338 (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
6339 histogram[i].blue);
6340 PUSHs(sv_2mortal(newSVpv(message,0)));
6341 if (image->colorspace == CMYKColorspace)
6342 {
6343 (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
6344 histogram[i].black);
6345 PUSHs(sv_2mortal(newSVpv(message,0)));
6346 }
6347 (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
6348 histogram[i].alpha);
6349 PUSHs(sv_2mortal(newSVpv(message,0)));
6350 (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double)
6351 histogram[i].count);
6352 PUSHs(sv_2mortal(newSVpv(message,0)));
6353 }
6354 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6355 }
6356
6357 PerlException:
6358 InheritPerlException(exception,perl_exception);
6359 exception=DestroyExceptionInfo(exception);
6360 SvREFCNT_dec(perl_exception);
6361 }
6362
6363#
6364###############################################################################
6365# #
6366# #
6367# #
6368# G e t P i x e l #
6369# #
6370# #
6371# #
6372###############################################################################
6373#
6374#
6375void
6376GetPixel(ref,...)
6377 Image::Magick ref=NO_INIT
6378 ALIAS:
6379 getpixel = 1
6380 getPixel = 2
6381 PPCODE:
6382 {
6383 AV
6384 *av;
6385
6386 char
6387 *attribute;
6388
6389 ExceptionInfo
6390 *exception;
6391
6392 Image
6393 *image;
6394
6395 MagickBooleanType
6396 normalize;
6397
6398 RectangleInfo
6399 region;
6400
6401 register const Quantum
6402 *p;
6403
6404 register ssize_t
6405 i;
6406
6407 ssize_t
6408 option;
6409
6410 struct PackageInfo
6411 *info;
6412
6413 SV
6414 *perl_exception,
6415 *reference; /* reference is the SV* of ref=SvIV(reference) */
6416
6417 PERL_UNUSED_VAR(ref);
6418 PERL_UNUSED_VAR(ix);
6419 exception=AcquireExceptionInfo();
6420 perl_exception=newSVpv("",0);
6421 reference=SvRV(ST(0));
6422 av=(AV *) reference;
6423 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6424 exception);
6425 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6426 if (image == (Image *) NULL)
6427 {
6428 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6429 PackageName);
6430 goto PerlException;
6431 }
6432 normalize=MagickTrue;
6433 region.x=0;
6434 region.y=0;
6435 region.width=image->columns;
6436 region.height=1;
6437 if (items == 1)
6438 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6439 for (i=2; i < items; i+=2)
6440 {
6441 attribute=(char *) SvPV(ST(i-1),na);
6442 switch (*attribute)
6443 {
6444 case 'C':
6445 case 'c':
6446 {
6447 if (LocaleCompare(attribute,"channel") == 0)
6448 {
6449 ssize_t
6450 option;
6451
6452 option=ParseChannelOption(SvPV(ST(i),na));
6453 if (option < 0)
6454 {
6455 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6456 SvPV(ST(i),na));
6457 return;
6458 }
6459 SetPixelChannelMask(image,(ChannelType) option);
6460 break;
6461 }
6462 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6463 attribute);
6464 break;
6465 }
6466 case 'g':
6467 case 'G':
6468 {
6469 if (LocaleCompare(attribute,"geometry") == 0)
6470 {
6471 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6472 break;
6473 }
6474 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6475 attribute);
6476 break;
6477 }
6478 case 'N':
6479 case 'n':
6480 {
6481 if (LocaleCompare(attribute,"normalize") == 0)
6482 {
6483 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6484 SvPV(ST(i),na));
6485 if (option < 0)
6486 {
6487 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6488 SvPV(ST(i),na));
6489 break;
6490 }
6491 normalize=option != 0 ? MagickTrue : MagickFalse;
6492 break;
6493 }
6494 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6495 attribute);
6496 break;
6497 }
6498 case 'x':
6499 case 'X':
6500 {
6501 if (LocaleCompare(attribute,"x") == 0)
6502 {
6503 region.x=SvIV(ST(i));
6504 break;
6505 }
6506 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6507 attribute);
6508 break;
6509 }
6510 case 'y':
6511 case 'Y':
6512 {
6513 if (LocaleCompare(attribute,"y") == 0)
6514 {
6515 region.y=SvIV(ST(i));
6516 break;
6517 }
6518 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6519 attribute);
6520 break;
6521 }
6522 default:
6523 {
6524 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6525 attribute);
6526 break;
6527 }
6528 }
6529 }
6530 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6531 if (p == (const Quantum *) NULL)
6532 PUSHs(&sv_undef);
6533 else
6534 {
6535 double
6536 scale;
6537
6538 scale=1.0;
6539 if (normalize != MagickFalse)
6540 scale=1.0/QuantumRange;
6541 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6542 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6543 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6544 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6545 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6546 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6547 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6548 (image->colorspace == CMYKColorspace))
6549 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6550 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6551 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6552 }
6553
6554 PerlException:
6555 InheritPerlException(exception,perl_exception);
6556 exception=DestroyExceptionInfo(exception);
6557 SvREFCNT_dec(perl_exception);
6558 }
6559
6560#
6561###############################################################################
6562# #
6563# #
6564# #
6565# G e t P i x e l s #
6566# #
6567# #
6568# #
6569###############################################################################
6570#
6571#
6572void
6573GetPixels(ref,...)
6574 Image::Magick ref=NO_INIT
6575 ALIAS:
6576 getpixels = 1
6577 getPixels = 2
6578 PPCODE:
6579 {
6580 AV
6581 *av;
6582
6583 char
6584 *attribute;
6585
6586 const char
6587 *map;
6588
6589 ExceptionInfo
6590 *exception;
6591
6592 Image
6593 *image;
6594
6595 MagickBooleanType
6596 normalize,
6597 status;
6598
6599 RectangleInfo
6600 region;
6601
6602 register ssize_t
6603 i;
6604
6605 ssize_t
6606 option;
6607
6608 struct PackageInfo
6609 *info;
6610
6611 SV
6612 *perl_exception,
6613 *reference; /* reference is the SV* of ref=SvIV(reference) */
6614
6615 PERL_UNUSED_VAR(ref);
6616 PERL_UNUSED_VAR(ix);
6617 exception=AcquireExceptionInfo();
6618 perl_exception=newSVpv("",0);
6619 reference=SvRV(ST(0));
6620 av=(AV *) reference;
6621 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6622 exception);
6623 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6624 if (image == (Image *) NULL)
6625 {
6626 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6627 PackageName);
6628 goto PerlException;
6629 }
6630 map="RGB";
6631 if (image->alpha_trait == BlendPixelTrait)
6632 map="RGBA";
6633 if (image->colorspace == CMYKColorspace)
6634 {
6635 map="CMYK";
6636 if (image->alpha_trait == BlendPixelTrait)
6637 map="CMYKA";
6638 }
6639 normalize=MagickFalse;
6640 region.x=0;
6641 region.y=0;
6642 region.width=image->columns;
6643 region.height=1;
6644 if (items == 1)
6645 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6646 for (i=2; i < items; i+=2)
6647 {
6648 attribute=(char *) SvPV(ST(i-1),na);
6649 switch (*attribute)
6650 {
6651 case 'g':
6652 case 'G':
6653 {
6654 if (LocaleCompare(attribute,"geometry") == 0)
6655 {
6656 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6657 break;
6658 }
6659 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6660 attribute);
6661 break;
6662 }
6663 case 'H':
6664 case 'h':
6665 {
6666 if (LocaleCompare(attribute,"height") == 0)
6667 {
6668 region.height=SvIV(ST(i));
6669 break;
6670 }
6671 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6672 attribute);
6673 break;
6674 }
6675 case 'M':
6676 case 'm':
6677 {
6678 if (LocaleCompare(attribute,"map") == 0)
6679 {
6680 map=SvPV(ST(i),na);
6681 break;
6682 }
6683 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6684 attribute);
6685 break;
6686 }
6687 case 'N':
6688 case 'n':
6689 {
6690 if (LocaleCompare(attribute,"normalize") == 0)
6691 {
6692 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6693 SvPV(ST(i),na));
6694 if (option < 0)
6695 {
6696 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6697 SvPV(ST(i),na));
6698 break;
6699 }
6700 normalize=option != 0 ? MagickTrue : MagickFalse;
6701 break;
6702 }
6703 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6704 attribute);
6705 break;
6706 }
6707 case 'W':
6708 case 'w':
6709 {
6710 if (LocaleCompare(attribute,"width") == 0)
6711 {
6712 region.width=SvIV(ST(i));
6713 break;
6714 }
6715 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6716 attribute);
6717 break;
6718 }
6719 case 'x':
6720 case 'X':
6721 {
6722 if (LocaleCompare(attribute,"x") == 0)
6723 {
6724 region.x=SvIV(ST(i));
6725 break;
6726 }
6727 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6728 attribute);
6729 break;
6730 }
6731 case 'y':
6732 case 'Y':
6733 {
6734 if (LocaleCompare(attribute,"y") == 0)
6735 {
6736 region.y=SvIV(ST(i));
6737 break;
6738 }
6739 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6740 attribute);
6741 break;
6742 }
6743 default:
6744 {
6745 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6746 attribute);
6747 break;
6748 }
6749 }
6750 }
6751 if (normalize != MagickFalse)
6752 {
6753 float
6754 *pixels;
6755
6756 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6757 region.height*sizeof(*pixels));
6758 if (pixels == (float *) NULL)
6759 {
6760 ThrowPerlException(exception,ResourceLimitError,
6761 "MemoryAllocationFailed",PackageName);
6762 goto PerlException;
6763 }
6764 status=ExportImagePixels(image,region.x,region.y,region.width,
6765 region.height,map,FloatPixel,pixels,exception);
6766 if (status == MagickFalse)
6767 PUSHs(&sv_undef);
6768 else
6769 {
6770 EXTEND(sp,strlen(map)*region.width*region.height);
6771 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6772 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6773 }
6774 pixels=(float *) RelinquishMagickMemory(pixels);
6775 }
6776 else
6777 {
6778 Quantum
6779 *pixels;
6780
6781 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6782 region.height*sizeof(*pixels));
6783 if (pixels == (Quantum *) NULL)
6784 {
6785 ThrowPerlException(exception,ResourceLimitError,
6786 "MemoryAllocationFailed",PackageName);
6787 goto PerlException;
6788 }
6789 status=ExportImagePixels(image,region.x,region.y,region.width,
6790 region.height,map,QuantumPixel,pixels,exception);
6791 if (status == MagickFalse)
6792 PUSHs(&sv_undef);
6793 else
6794 {
6795 EXTEND(sp,strlen(map)*region.width*region.height);
6796 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6797 PUSHs(sv_2mortal(newSViv(pixels[i])));
6798 }
6799 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6800 }
6801
6802 PerlException:
6803 InheritPerlException(exception,perl_exception);
6804 exception=DestroyExceptionInfo(exception);
6805 SvREFCNT_dec(perl_exception);
6806 }
6807
6808#
6809###############################################################################
6810# #
6811# #
6812# #
6813# I m a g e T o B l o b #
6814# #
6815# #
6816# #
6817###############################################################################
6818#
6819#
6820void
6821ImageToBlob(ref,...)
6822 Image::Magick ref=NO_INIT
6823 ALIAS:
6824 ImageToBlob = 1
6825 imagetoblob = 2
6826 toblob = 3
6827 blob = 4
6828 PPCODE:
6829 {
6830 char
6831 filename[MaxTextExtent];
6832
6833 ExceptionInfo
6834 *exception;
6835
6836 Image
6837 *image,
6838 *next;
6839
6840 register ssize_t
6841 i;
6842
6843 struct PackageInfo
6844 *info,
6845 *package_info;
6846
6847 size_t
6848 length;
6849
6850 ssize_t
6851 scene;
6852
6853 SV
6854 *perl_exception,
6855 *reference;
6856
6857 void
6858 *blob;
6859
6860 PERL_UNUSED_VAR(ref);
6861 PERL_UNUSED_VAR(ix);
6862 exception=AcquireExceptionInfo();
6863 perl_exception=newSVpv("",0);
6864 package_info=(struct PackageInfo *) NULL;
6865 if (sv_isobject(ST(0)) == 0)
6866 {
6867 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6868 PackageName);
6869 goto PerlException;
6870 }
6871 reference=SvRV(ST(0));
6872 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6873 if (image == (Image *) NULL)
6874 {
6875 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6876 PackageName);
6877 goto PerlException;
6878 }
6879 package_info=ClonePackageInfo(info,exception);
6880 for (i=2; i < items; i+=2)
6881 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6882 (void) CopyMagickString(filename,package_info->image_info->filename,
6883 MaxTextExtent);
6884 scene=0;
6885 for (next=image; next; next=next->next)
6886 {
6887 (void) CopyMagickString(next->filename,filename,MaxTextExtent);
6888 next->scene=scene++;
6889 }
6890 SetImageInfo(package_info->image_info,(unsigned int)
6891 GetImageListLength(image),exception);
6892 EXTEND(sp,(ssize_t) GetImageListLength(image));
6893 for ( ; image; image=image->next)
6894 {
6895 length=0;
6896 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6897 if (blob != (char *) NULL)
6898 {
6899 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6900 blob=(unsigned char *) RelinquishMagickMemory(blob);
6901 }
6902 if (package_info->image_info->adjoin)
6903 break;
6904 }
6905
6906 PerlException:
6907 if (package_info != (struct PackageInfo *) NULL)
6908 DestroyPackageInfo(package_info);
6909 InheritPerlException(exception,perl_exception);
6910 exception=DestroyExceptionInfo(exception);
6911 SvREFCNT_dec(perl_exception); /* throw away all errors */
6912 }
6913
6914#
6915###############################################################################
6916# #
6917# #
6918# #
6919# L a y e r s #
6920# #
6921# #
6922# #
6923###############################################################################
6924#
6925#
6926void
6927Layers(ref,...)
6928 Image::Magick ref=NO_INIT
6929 ALIAS:
6930 Layers = 1
6931 layers = 2
6932 OptimizeImageLayers = 3
6933 optimizelayers = 4
6934 optimizeimagelayers = 5
6935 PPCODE:
6936 {
6937 AV
6938 *av;
6939
6940 char
6941 *attribute;
6942
6943 CompositeOperator
6944 compose;
6945
6946 ExceptionInfo
6947 *exception;
6948
6949 HV
6950 *hv;
6951
6952 Image
6953 *image,
6954 *layers;
6955
6956 LayerMethod
6957 method;
6958
6959 register ssize_t
6960 i;
6961
6962 ssize_t
6963 option,
6964 sp;
6965
6966 struct PackageInfo
6967 *info;
6968
6969 SV
6970 *av_reference,
6971 *perl_exception,
6972 *reference,
6973 *rv,
6974 *sv;
6975
6976 PERL_UNUSED_VAR(ref);
6977 PERL_UNUSED_VAR(ix);
6978 exception=AcquireExceptionInfo();
6979 perl_exception=newSVpv("",0);
6980 sv=NULL;
6981 if (sv_isobject(ST(0)) == 0)
6982 {
6983 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6984 PackageName);
6985 goto PerlException;
6986 }
6987 reference=SvRV(ST(0));
6988 hv=SvSTASH(reference);
6989 av=newAV();
6990 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
6991 SvREFCNT_dec(av);
6992 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6993 if (image == (Image *) NULL)
6994 {
6995 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6996 PackageName);
6997 goto PerlException;
6998 }
6999 compose=image->compose;
7000 method=OptimizeLayer;
7001 for (i=2; i < items; i+=2)
7002 {
7003 attribute=(char *) SvPV(ST(i-1),na);
7004 switch (*attribute)
7005 {
7006 case 'C':
7007 case 'c':
7008 {
7009 if (LocaleCompare(attribute,"compose") == 0)
7010 {
7011 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7012 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7013 if (sp < 0)
7014 {
7015 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7016 SvPV(ST(i),na));
7017 break;
7018 }
7019 compose=(CompositeOperator) sp;
7020 break;
7021 }
7022 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7023 attribute);
7024 break;
7025 }
7026 case 'M':
7027 case 'm':
7028 {
7029 if (LocaleCompare(attribute,"method") == 0)
7030 {
7031 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7032 SvPV(ST(i),na));
7033 if (option < 0)
7034 {
7035 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7036 SvPV(ST(i),na));
7037 break;
7038 }
7039 method=(LayerMethod) option;
7040 break;
7041 }
7042 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7043 attribute);
7044 break;
7045 }
7046 default:
7047 {
7048 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7049 attribute);
7050 break;
7051 }
7052 }
7053 }
7054 layers=(Image *) NULL;
7055 switch (method)
7056 {
7057 case CompareAnyLayer:
7058 case CompareClearLayer:
7059 case CompareOverlayLayer:
7060 default:
7061 {
7062 layers=CompareImagesLayers(image,method,exception);
7063 break;
7064 }
7065 case MergeLayer:
7066 case FlattenLayer:
7067 case MosaicLayer:
7068 {
7069 layers=MergeImageLayers(image,method,exception);
7070 break;
7071 }
7072 case DisposeLayer:
7073 {
7074 layers=DisposeImages(image,exception);
7075 break;
7076 }
7077 case OptimizeImageLayer:
7078 {
7079 layers=OptimizeImageLayers(image,exception);
7080 break;
7081 }
7082 case OptimizePlusLayer:
7083 {
7084 layers=OptimizePlusImageLayers(image,exception);
7085 break;
7086 }
7087 case OptimizeTransLayer:
7088 {
7089 OptimizeImageTransparency(image,exception);
7090 break;
7091 }
7092 case RemoveDupsLayer:
7093 {
7094 RemoveDuplicateLayers(&image,exception);
7095 break;
7096 }
7097 case RemoveZeroLayer:
7098 {
7099 RemoveZeroDelayLayers(&image,exception);
7100 break;
7101 }
7102 case OptimizeLayer:
7103 {
7104 QuantizeInfo
7105 *quantize_info;
7106
7107 /*
7108 General Purpose, GIF Animation Optimizer.
7109 */
7110 layers=CoalesceImages(image,exception);
7111 if (layers == (Image *) NULL)
7112 break;
7113 image=layers;
7114 layers=OptimizeImageLayers(image,exception);
7115 if (layers == (Image *) NULL)
7116 break;
7117 image=DestroyImageList(image);
7118 image=layers;
7119 layers=(Image *) NULL;
7120 OptimizeImageTransparency(image,exception);
7121 quantize_info=AcquireQuantizeInfo(info->image_info);
7122 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7123 quantize_info=DestroyQuantizeInfo(quantize_info);
7124 break;
7125 }
7126 case CompositeLayer:
7127 {
7128 Image
7129 *source;
7130
7131 RectangleInfo
7132 geometry;
7133
7134 /*
7135 Split image sequence at the first 'NULL:' image.
7136 */
7137 source=image;
7138 while (source != (Image *) NULL)
7139 {
7140 source=GetNextImageInList(source);
7141 if ((source != (Image *) NULL) &&
7142 (LocaleCompare(source->magick,"NULL") == 0))
7143 break;
7144 }
7145 if (source != (Image *) NULL)
7146 {
7147 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7148 (GetNextImageInList(source) == (Image *) NULL))
7149 source=(Image *) NULL;
7150 else
7151 {
7152 /*
7153 Separate the two lists, junk the null: image.
7154 */
7155 source=SplitImageList(source->previous);
7156 DeleteImageFromList(&source);
7157 }
7158 }
7159 if (source == (Image *) NULL)
7160 {
7161 (void) ThrowMagickException(exception,GetMagickModule(),
7162 OptionError,"MissingNullSeparator","layers Composite");
7163 break;
7164 }
7165 /*
7166 Adjust offset with gravity and virtual canvas.
7167 */
7168 SetGeometry(image,&geometry);
7169 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7170 geometry.width=source->page.width != 0 ? source->page.width :
7171 source->columns;
7172 geometry.height=source->page.height != 0 ? source->page.height :
7173 source->rows;
7174 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7175 image->columns,image->page.height != 0 ? image->page.height :
7176 image->rows,image->gravity,&geometry);
7177 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7178 source=DestroyImageList(source);
7179 break;
7180 }
7181 }
7182 if (layers != (Image *) NULL)
7183 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007184 else
7185 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007186 if (image == (Image *) NULL)
7187 goto PerlException;
7188 for ( ; image; image=image->next)
7189 {
7190 AddImageToRegistry(sv,image);
7191 rv=newRV(sv);
7192 av_push(av,sv_bless(rv,hv));
7193 SvREFCNT_dec(sv);
7194 }
7195 exception=DestroyExceptionInfo(exception);
7196 ST(0)=av_reference;
7197 SvREFCNT_dec(perl_exception);
7198 XSRETURN(1);
7199
7200 PerlException:
7201 InheritPerlException(exception,perl_exception);
7202 exception=DestroyExceptionInfo(exception);
7203 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7204 SvPOK_on(perl_exception);
7205 ST(0)=sv_2mortal(perl_exception);
7206 XSRETURN(1);
7207 }
7208
7209#
7210###############################################################################
7211# #
7212# #
7213# #
7214# M a g i c k T o M i m e #
7215# #
7216# #
7217# #
7218###############################################################################
7219#
7220#
7221SV *
7222MagickToMime(ref,name)
7223 Image::Magick ref=NO_INIT
7224 char *name
7225 ALIAS:
7226 magicktomime = 1
7227 CODE:
7228 {
7229 char
7230 *mime;
7231
7232 PERL_UNUSED_VAR(ref);
7233 PERL_UNUSED_VAR(ix);
7234 mime=MagickToMime(name);
7235 RETVAL=newSVpv(mime,0);
7236 mime=(char *) RelinquishMagickMemory(mime);
7237 }
7238 OUTPUT:
7239 RETVAL
7240
7241#
7242###############################################################################
7243# #
7244# #
7245# #
7246# M o g r i f y #
7247# #
7248# #
7249# #
7250###############################################################################
7251#
7252#
7253void
7254Mogrify(ref,...)
7255 Image::Magick ref=NO_INIT
7256 ALIAS:
7257 Comment = 1
7258 CommentImage = 2
7259 Label = 3
7260 LabelImage = 4
7261 AddNoise = 5
7262 AddNoiseImage = 6
7263 Colorize = 7
7264 ColorizeImage = 8
7265 Border = 9
7266 BorderImage = 10
7267 Blur = 11
7268 BlurImage = 12
7269 Chop = 13
7270 ChopImage = 14
7271 Crop = 15
7272 CropImage = 16
7273 Despeckle = 17
7274 DespeckleImage = 18
7275 Edge = 19
7276 EdgeImage = 20
7277 Emboss = 21
7278 EmbossImage = 22
7279 Enhance = 23
7280 EnhanceImage = 24
7281 Flip = 25
7282 FlipImage = 26
7283 Flop = 27
7284 FlopImage = 28
7285 Frame = 29
7286 FrameImage = 30
7287 Implode = 31
7288 ImplodeImage = 32
7289 Magnify = 33
7290 MagnifyImage = 34
7291 MedianFilter = 35
7292 MedianConvolveImage = 36
7293 Minify = 37
7294 MinifyImage = 38
7295 OilPaint = 39
7296 OilPaintImage = 40
7297 ReduceNoise = 41
7298 ReduceNoiseImage = 42
7299 Roll = 43
7300 RollImage = 44
7301 Rotate = 45
7302 RotateImage = 46
7303 Sample = 47
7304 SampleImage = 48
7305 Scale = 49
7306 ScaleImage = 50
7307 Shade = 51
7308 ShadeImage = 52
7309 Sharpen = 53
7310 SharpenImage = 54
7311 Shear = 55
7312 ShearImage = 56
7313 Spread = 57
7314 SpreadImage = 58
7315 Swirl = 59
7316 SwirlImage = 60
7317 Resize = 61
7318 ResizeImage = 62
7319 Zoom = 63
7320 ZoomImage = 64
7321 Annotate = 65
7322 AnnotateImage = 66
7323 ColorFloodfill = 67
7324 ColorFloodfillImage= 68
7325 Composite = 69
7326 CompositeImage = 70
7327 Contrast = 71
7328 ContrastImage = 72
7329 CycleColormap = 73
7330 CycleColormapImage = 74
7331 Draw = 75
7332 DrawImage = 76
7333 Equalize = 77
7334 EqualizeImage = 78
7335 Gamma = 79
7336 GammaImage = 80
7337 Map = 81
7338 MapImage = 82
7339 MatteFloodfill = 83
7340 MatteFloodfillImage= 84
7341 Modulate = 85
7342 ModulateImage = 86
7343 Negate = 87
7344 NegateImage = 88
7345 Normalize = 89
7346 NormalizeImage = 90
7347 NumberColors = 91
7348 NumberColorsImage = 92
7349 Opaque = 93
7350 OpaqueImage = 94
7351 Quantize = 95
7352 QuantizeImage = 96
7353 Raise = 97
7354 RaiseImage = 98
7355 Segment = 99
7356 SegmentImage = 100
7357 Signature = 101
7358 SignatureImage = 102
7359 Solarize = 103
7360 SolarizeImage = 104
7361 Sync = 105
7362 SyncImage = 106
7363 Texture = 107
7364 TextureImage = 108
7365 Evaluate = 109
7366 EvaluateImage = 110
7367 Transparent = 111
7368 TransparentImage = 112
7369 Threshold = 113
7370 ThresholdImage = 114
7371 Charcoal = 115
7372 CharcoalImage = 116
7373 Trim = 117
7374 TrimImage = 118
7375 Wave = 119
7376 WaveImage = 120
7377 Separate = 121
7378 SeparateImage = 122
7379 Stereo = 125
7380 StereoImage = 126
7381 Stegano = 127
7382 SteganoImage = 128
7383 Deconstruct = 129
7384 DeconstructImage = 130
7385 GaussianBlur = 131
7386 GaussianBlurImage = 132
7387 Convolve = 133
7388 ConvolveImage = 134
7389 Profile = 135
7390 ProfileImage = 136
7391 UnsharpMask = 137
7392 UnsharpMaskImage = 138
7393 MotionBlur = 139
7394 MotionBlurImage = 140
7395 OrderedDither = 141
7396 OrderedDitherImage = 142
7397 Shave = 143
7398 ShaveImage = 144
7399 Level = 145
7400 LevelImage = 146
7401 Clip = 147
7402 ClipImage = 148
7403 AffineTransform = 149
7404 AffineTransformImage = 150
7405 Difference = 151
7406 DifferenceImage = 152
7407 AdaptiveThreshold = 153
7408 AdaptiveThresholdImage = 154
7409 Resample = 155
7410 ResampleImage = 156
7411 Describe = 157
7412 DescribeImage = 158
7413 BlackThreshold = 159
7414 BlackThresholdImage= 160
7415 WhiteThreshold = 161
7416 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007417 RotationalBlur = 163
7418 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007419 Thumbnail = 165
7420 ThumbnailImage = 166
7421 Strip = 167
7422 StripImage = 168
7423 Tint = 169
7424 TintImage = 170
7425 Channel = 171
7426 ChannelImage = 172
7427 Splice = 173
7428 SpliceImage = 174
7429 Posterize = 175
7430 PosterizeImage = 176
7431 Shadow = 177
7432 ShadowImage = 178
7433 Identify = 179
7434 IdentifyImage = 180
7435 SepiaTone = 181
7436 SepiaToneImage = 182
7437 SigmoidalContrast = 183
7438 SigmoidalContrastImage = 184
7439 Extent = 185
7440 ExtentImage = 186
7441 Vignette = 187
7442 VignetteImage = 188
7443 ContrastStretch = 189
7444 ContrastStretchImage = 190
7445 Sans0 = 191
7446 Sans0Image = 192
7447 Sans1 = 193
7448 Sans1Image = 194
7449 AdaptiveSharpen = 195
7450 AdaptiveSharpenImage = 196
7451 Transpose = 197
7452 TransposeImage = 198
7453 Transverse = 199
7454 TransverseImage = 200
7455 AutoOrient = 201
7456 AutoOrientImage = 202
7457 AdaptiveBlur = 203
7458 AdaptiveBlurImage = 204
7459 Sketch = 205
7460 SketchImage = 206
7461 UniqueColors = 207
7462 UniqueColorsImage = 208
7463 AdaptiveResize = 209
7464 AdaptiveResizeImage= 210
7465 ClipMask = 211
7466 ClipMaskImage = 212
7467 LinearStretch = 213
7468 LinearStretchImage = 214
7469 ColorMatrix = 215
7470 ColorMatrixImage = 216
7471 Mask = 217
7472 MaskImage = 218
7473 Polaroid = 219
7474 PolaroidImage = 220
7475 FloodfillPaint = 221
7476 FloodfillPaintImage= 222
7477 Distort = 223
7478 DistortImage = 224
7479 Clut = 225
7480 ClutImage = 226
7481 LiquidRescale = 227
7482 LiquidRescaleImage = 228
7483 Encipher = 229
7484 EncipherImage = 230
7485 Decipher = 231
7486 DecipherImage = 232
7487 Deskew = 233
7488 DeskewImage = 234
7489 Remap = 235
7490 RemapImage = 236
7491 SparseColor = 237
7492 SparseColorImage = 238
7493 Function = 239
7494 FunctionImage = 240
7495 SelectiveBlur = 241
7496 SelectiveBlurImage = 242
7497 HaldClut = 243
7498 HaldClutImage = 244
7499 BlueShift = 245
7500 BlueShiftImage = 246
7501 ForwardFourierTransform = 247
7502 ForwardFourierTransformImage = 248
7503 InverseFourierTransform = 249
7504 InverseFourierTransformImage = 250
7505 ColorDecisionList = 251
7506 ColorDecisionListImage = 252
7507 AutoGamma = 253
7508 AutoGammaImage = 254
7509 AutoLevel = 255
7510 AutoLevelImage = 256
7511 LevelColors = 257
7512 LevelImageColors = 258
7513 Clamp = 259
7514 ClampImage = 260
7515 BrightnessContrast = 261
7516 BrightnessContrastImage = 262
7517 Morphology = 263
7518 MorphologyImage = 264
7519 Color = 265
7520 ColorImage = 266
7521 Mode = 267
7522 ModeImage = 268
7523 Statistic = 269
7524 StatisticImage = 270
7525 Perceptible = 271
7526 PerceptibleImage = 272
7527 Poly = 273
7528 PolyImage = 274
7529 Grayscale = 275
7530 GrayscaleImage = 276
cristy4ceadb82014-03-29 15:30:43 +00007531 CannyEdge = 278
7532 CannyEdgeImage = 279
cristy4a3ce0a2013-08-03 20:06:59 +00007533 MogrifyRegion = 666
7534 PPCODE:
7535 {
7536 AffineMatrix
7537 affine,
7538 current;
7539
7540 char
7541 attribute_flag[MaxArguments],
7542 message[MaxTextExtent];
7543
7544 ChannelType
7545 channel,
7546 channel_mask;
7547
7548 CompositeOperator
7549 compose;
7550
7551 const char
7552 *attribute,
7553 *value;
7554
7555 double
7556 angle;
7557
7558 ExceptionInfo
7559 *exception;
7560
7561 GeometryInfo
7562 geometry_info;
7563
7564 Image
7565 *image,
7566 *next,
7567 *region_image;
7568
7569 MagickBooleanType
7570 status;
7571
7572 MagickStatusType
7573 flags;
7574
7575 PixelInfo
7576 fill_color;
7577
7578 RectangleInfo
7579 geometry,
7580 region_info;
7581
7582 register ssize_t
7583 i;
7584
7585 ssize_t
7586 base,
7587 j,
7588 number_images;
7589
7590 struct Methods
7591 *rp;
7592
7593 struct PackageInfo
7594 *info;
7595
7596 SV
7597 *perl_exception,
7598 **pv,
7599 *reference,
7600 **reference_vector;
7601
7602 struct ArgumentList
7603 argument_list[MaxArguments];
7604
7605 PERL_UNUSED_VAR(ref);
7606 PERL_UNUSED_VAR(ix);
7607 exception=AcquireExceptionInfo();
7608 perl_exception=newSVpv("",0);
7609 reference_vector=NULL;
7610 region_image=NULL;
7611 number_images=0;
7612 base=2;
7613 if (sv_isobject(ST(0)) == 0)
7614 {
7615 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7616 PackageName);
7617 goto PerlException;
7618 }
7619 reference=SvRV(ST(0));
7620 region_info.width=0;
7621 region_info.height=0;
7622 region_info.x=0;
7623 region_info.y=0;
7624 region_image=(Image *) NULL;
7625 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7626 if (ix && (ix != 666))
7627 {
7628 /*
7629 Called as Method(...)
7630 */
7631 ix=(ix+1)/2;
7632 rp=(&Methods[ix-1]);
7633 attribute=rp->name;
7634 }
7635 else
7636 {
7637 /*
7638 Called as Mogrify("Method",...)
7639 */
7640 attribute=(char *) SvPV(ST(1),na);
7641 if (ix)
7642 {
7643 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7644 attribute=(char *) SvPV(ST(2),na);
7645 base++;
7646 }
7647 for (rp=Methods; ; rp++)
7648 {
7649 if (rp >= EndOf(Methods))
7650 {
7651 ThrowPerlException(exception,OptionError,
7652 "UnrecognizedPerlMagickMethod",attribute);
7653 goto PerlException;
7654 }
7655 if (strEQcase(attribute,rp->name))
7656 break;
7657 }
7658 ix=rp-Methods+1;
7659 base++;
7660 }
7661 if (image == (Image *) NULL)
7662 {
7663 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7664 goto PerlException;
7665 }
7666 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7667 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7668 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7669 {
7670 Arguments
7671 *pp,
7672 *qq;
7673
7674 ssize_t
7675 ssize_test;
7676
7677 struct ArgumentList
7678 *al;
7679
7680 SV
7681 *sv;
7682
7683 sv=NULL;
7684 ssize_test=0;
7685 pp=(Arguments *) NULL;
7686 qq=rp->arguments;
7687 if (i == items)
7688 {
7689 pp=rp->arguments,
7690 sv=ST(i-1);
7691 }
7692 else
7693 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7694 {
7695 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7696 break;
7697 if (strEQcase(attribute,qq->method) > ssize_test)
7698 {
7699 pp=qq;
7700 ssize_test=strEQcase(attribute,qq->method);
7701 }
7702 }
7703 if (pp == (Arguments *) NULL)
7704 {
7705 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7706 attribute);
7707 goto continue_outer_loop;
7708 }
7709 al=(&argument_list[pp-rp->arguments]);
7710 switch (pp->type)
7711 {
7712 case ArrayReference:
7713 {
7714 if (SvTYPE(sv) != SVt_RV)
7715 {
7716 (void) FormatLocaleString(message,MaxTextExtent,
7717 "invalid %.60s value",pp->method);
7718 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7719 goto continue_outer_loop;
7720 }
7721 al->array_reference=SvRV(sv);
7722 break;
7723 }
7724 case RealReference:
7725 {
7726 al->real_reference=SvNV(sv);
7727 break;
7728 }
7729 case FileReference:
7730 {
7731 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7732 break;
7733 }
7734 case ImageReference:
7735 {
7736 if (!sv_isobject(sv) ||
7737 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7738 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7739 {
7740 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7741 PackageName);
7742 goto PerlException;
7743 }
7744 break;
7745 }
7746 case IntegerReference:
7747 {
7748 al->integer_reference=SvIV(sv);
7749 break;
7750 }
7751 case StringReference:
7752 {
7753 al->string_reference=(char *) SvPV(sv,al->length);
7754 if (sv_isobject(sv))
7755 al->image_reference=SetupList(aTHX_ SvRV(sv),
7756 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7757 break;
7758 }
7759 default:
7760 {
7761 /*
7762 Is a string; look up name.
7763 */
7764 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7765 {
7766 al->string_reference=(char *) SvPV(sv,al->length);
7767 al->integer_reference=(-1);
7768 break;
7769 }
7770 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7771 MagickFalse,SvPV(sv,na));
7772 if (pp->type == MagickChannelOptions)
7773 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7774 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7775 {
7776 (void) FormatLocaleString(message,MaxTextExtent,
7777 "invalid %.60s value",pp->method);
7778 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7779 goto continue_outer_loop;
7780 }
7781 break;
7782 }
7783 }
7784 attribute_flag[pp-rp->arguments]++;
7785 continue_outer_loop: ;
7786 }
7787 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7788 pv=reference_vector;
7789 SetGeometryInfo(&geometry_info);
7790 channel=DefaultChannels;
7791 for (next=image; next; next=next->next)
7792 {
7793 image=next;
7794 SetGeometry(image,&geometry);
7795 if ((region_info.width*region_info.height) != 0)
7796 {
7797 region_image=image;
7798 image=CropImage(image,&region_info,exception);
7799 }
7800 switch (ix)
7801 {
7802 default:
7803 {
7804 (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double) ix);
7805 ThrowPerlException(exception,OptionError,
7806 "UnrecognizedPerlMagickMethod",message);
7807 goto PerlException;
7808 }
7809 case 1: /* Comment */
7810 {
7811 if (attribute_flag[0] == 0)
7812 argument_list[0].string_reference=(char *) NULL;
7813 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7814 info ? info->image_info : (ImageInfo *) NULL,image,
7815 argument_list[0].string_reference,exception),exception);
7816 break;
7817 }
7818 case 2: /* Label */
7819 {
7820 if (attribute_flag[0] == 0)
7821 argument_list[0].string_reference=(char *) NULL;
7822 (void) SetImageProperty(image,"label",InterpretImageProperties(
7823 info ? info->image_info : (ImageInfo *) NULL,image,
7824 argument_list[0].string_reference,exception),exception);
7825 break;
7826 }
7827 case 3: /* AddNoise */
7828 {
7829 double
7830 attenuate;
7831
7832 if (attribute_flag[0] == 0)
7833 argument_list[0].integer_reference=UniformNoise;
7834 attenuate=1.0;
7835 if (attribute_flag[1] != 0)
7836 attenuate=argument_list[1].real_reference;
7837 if (attribute_flag[2] != 0)
7838 channel=(ChannelType) argument_list[2].integer_reference;
7839 channel_mask=SetImageChannelMask(image,channel);
7840 image=AddNoiseImage(image,(NoiseType)
7841 argument_list[0].integer_reference,attenuate,exception);
7842 if (image != (Image *) NULL)
7843 (void) SetImageChannelMask(image,channel_mask);
7844 break;
7845 }
7846 case 4: /* Colorize */
7847 {
7848 PixelInfo
7849 target;
7850
7851 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7852 0,0,&target,exception);
7853 if (attribute_flag[0] != 0)
7854 (void) QueryColorCompliance(argument_list[0].string_reference,
7855 AllCompliance,&target,exception);
7856 if (attribute_flag[1] == 0)
7857 argument_list[1].string_reference="100%";
7858 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7859 exception);
7860 break;
7861 }
7862 case 5: /* Border */
7863 {
7864 CompositeOperator
7865 compose;
7866
7867 geometry.width=0;
7868 geometry.height=0;
7869 if (attribute_flag[0] != 0)
7870 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7871 &geometry,exception);
7872 if (attribute_flag[1] != 0)
7873 geometry.width=argument_list[1].integer_reference;
7874 if (attribute_flag[2] != 0)
7875 geometry.height=argument_list[2].integer_reference;
7876 if (attribute_flag[3] != 0)
7877 QueryColorCompliance(argument_list[3].string_reference,
7878 AllCompliance,&image->border_color,exception);
7879 if (attribute_flag[4] != 0)
7880 QueryColorCompliance(argument_list[4].string_reference,
7881 AllCompliance,&image->border_color,exception);
7882 if (attribute_flag[5] != 0)
7883 QueryColorCompliance(argument_list[5].string_reference,
7884 AllCompliance,&image->border_color,exception);
7885 compose=image->compose;
7886 if (attribute_flag[6] != 0)
7887 compose=(CompositeOperator) argument_list[6].integer_reference;
7888 image=BorderImage(image,&geometry,compose,exception);
7889 break;
7890 }
7891 case 6: /* Blur */
7892 {
7893 if (attribute_flag[0] != 0)
7894 {
7895 flags=ParseGeometry(argument_list[0].string_reference,
7896 &geometry_info);
7897 if ((flags & SigmaValue) == 0)
7898 geometry_info.sigma=1.0;
7899 }
7900 if (attribute_flag[1] != 0)
7901 geometry_info.rho=argument_list[1].real_reference;
7902 if (attribute_flag[2] != 0)
7903 geometry_info.sigma=argument_list[2].real_reference;
7904 if (attribute_flag[3] != 0)
7905 channel=(ChannelType) argument_list[3].integer_reference;
7906 channel_mask=SetImageChannelMask(image,channel);
7907 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
7908 exception);
7909 if (image != (Image *) NULL)
7910 (void) SetImageChannelMask(image,channel_mask);
7911 break;
7912 }
7913 case 7: /* Chop */
7914 {
7915 if (attribute_flag[0] != 0)
7916 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7917 &geometry,exception);
7918 if (attribute_flag[1] != 0)
7919 geometry.width=argument_list[1].integer_reference;
7920 if (attribute_flag[2] != 0)
7921 geometry.height=argument_list[2].integer_reference;
7922 if (attribute_flag[3] != 0)
7923 geometry.x=argument_list[3].integer_reference;
7924 if (attribute_flag[4] != 0)
7925 geometry.y=argument_list[4].integer_reference;
7926 image=ChopImage(image,&geometry,exception);
7927 break;
7928 }
7929 case 8: /* Crop */
7930 {
7931 if (attribute_flag[6] != 0)
7932 image->gravity=(GravityType) argument_list[6].integer_reference;
7933 if (attribute_flag[0] != 0)
7934 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7935 &geometry,exception);
7936 if (attribute_flag[1] != 0)
7937 geometry.width=argument_list[1].integer_reference;
7938 if (attribute_flag[2] != 0)
7939 geometry.height=argument_list[2].integer_reference;
7940 if (attribute_flag[3] != 0)
7941 geometry.x=argument_list[3].integer_reference;
7942 if (attribute_flag[4] != 0)
7943 geometry.y=argument_list[4].integer_reference;
7944 if (attribute_flag[5] != 0)
7945 image->fuzz=StringToDoubleInterval(
7946 argument_list[5].string_reference,(double) QuantumRange+1.0);
7947 image=CropImage(image,&geometry,exception);
7948 break;
7949 }
7950 case 9: /* Despeckle */
7951 {
7952 image=DespeckleImage(image,exception);
7953 break;
7954 }
7955 case 10: /* Edge */
7956 {
7957 if (attribute_flag[0] != 0)
7958 geometry_info.rho=argument_list[0].real_reference;
7959 image=EdgeImage(image,geometry_info.rho,exception);
7960 break;
7961 }
7962 case 11: /* Emboss */
7963 {
7964 if (attribute_flag[0] != 0)
7965 {
7966 flags=ParseGeometry(argument_list[0].string_reference,
7967 &geometry_info);
7968 if ((flags & SigmaValue) == 0)
7969 geometry_info.sigma=1.0;
7970 }
7971 if (attribute_flag[1] != 0)
7972 geometry_info.rho=argument_list[1].real_reference;
7973 if (attribute_flag[2] != 0)
7974 geometry_info.sigma=argument_list[2].real_reference;
7975 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
7976 exception);
7977 break;
7978 }
7979 case 12: /* Enhance */
7980 {
7981 image=EnhanceImage(image,exception);
7982 break;
7983 }
7984 case 13: /* Flip */
7985 {
7986 image=FlipImage(image,exception);
7987 break;
7988 }
7989 case 14: /* Flop */
7990 {
7991 image=FlopImage(image,exception);
7992 break;
7993 }
7994 case 15: /* Frame */
7995 {
7996 CompositeOperator
7997 compose;
7998
7999 FrameInfo
8000 frame_info;
8001
8002 if (attribute_flag[0] != 0)
8003 {
8004 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8005 &geometry,exception);
8006 frame_info.width=geometry.width;
8007 frame_info.height=geometry.height;
8008 frame_info.outer_bevel=geometry.x;
8009 frame_info.inner_bevel=geometry.y;
8010 }
8011 if (attribute_flag[1] != 0)
8012 frame_info.width=argument_list[1].integer_reference;
8013 if (attribute_flag[2] != 0)
8014 frame_info.height=argument_list[2].integer_reference;
8015 if (attribute_flag[3] != 0)
8016 frame_info.inner_bevel=argument_list[3].integer_reference;
8017 if (attribute_flag[4] != 0)
8018 frame_info.outer_bevel=argument_list[4].integer_reference;
8019 if (attribute_flag[5] != 0)
8020 QueryColorCompliance(argument_list[5].string_reference,
8021 AllCompliance,&fill_color,exception);
8022 if (attribute_flag[6] != 0)
8023 QueryColorCompliance(argument_list[6].string_reference,
8024 AllCompliance,&fill_color,exception);
8025 frame_info.x=(ssize_t) frame_info.width;
8026 frame_info.y=(ssize_t) frame_info.height;
8027 frame_info.width=image->columns+2*frame_info.x;
8028 frame_info.height=image->rows+2*frame_info.y;
8029 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
8030 image->matte_color=fill_color;
8031 compose=image->compose;
8032 if (attribute_flag[7] != 0)
8033 compose=(CompositeOperator) argument_list[7].integer_reference;
8034 image=FrameImage(image,&frame_info,compose,exception);
8035 break;
8036 }
8037 case 16: /* Implode */
8038 {
8039 PixelInterpolateMethod
8040 method;
8041
8042 if (attribute_flag[0] == 0)
8043 argument_list[0].real_reference=0.5;
8044 method=UndefinedInterpolatePixel;
8045 if (attribute_flag[1] != 0)
8046 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8047 image=ImplodeImage(image,argument_list[0].real_reference,
8048 method,exception);
8049 break;
8050 }
8051 case 17: /* Magnify */
8052 {
8053 image=MagnifyImage(image,exception);
8054 break;
8055 }
8056 case 18: /* MedianFilter */
8057 {
8058 if (attribute_flag[0] != 0)
8059 {
8060 flags=ParseGeometry(argument_list[0].string_reference,
8061 &geometry_info);
8062 if ((flags & SigmaValue) == 0)
8063 geometry_info.sigma=geometry_info.rho;
8064 }
8065 if (attribute_flag[1] != 0)
8066 geometry_info.rho=argument_list[1].real_reference;
8067 if (attribute_flag[2] != 0)
8068 geometry_info.sigma=argument_list[2].real_reference;
8069 if (attribute_flag[3] != 0)
8070 channel=(ChannelType) argument_list[3].integer_reference;
8071 channel_mask=SetImageChannelMask(image,channel);
8072 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8073 (size_t) geometry_info.sigma,exception);
8074 if (image != (Image *) NULL)
8075 (void) SetImageChannelMask(image,channel_mask);
8076 break;
8077 }
8078 case 19: /* Minify */
8079 {
8080 image=MinifyImage(image,exception);
8081 break;
8082 }
8083 case 20: /* OilPaint */
8084 {
8085 if (attribute_flag[0] == 0)
8086 argument_list[0].real_reference=0.0;
8087 if (attribute_flag[1] == 0)
8088 argument_list[1].real_reference=1.0;
8089 image=OilPaintImage(image,argument_list[0].real_reference,
8090 argument_list[1].real_reference,exception);
8091 break;
8092 }
8093 case 21: /* ReduceNoise */
8094 {
8095 if (attribute_flag[0] != 0)
8096 {
8097 flags=ParseGeometry(argument_list[0].string_reference,
8098 &geometry_info);
8099 if ((flags & SigmaValue) == 0)
8100 geometry_info.sigma=1.0;
8101 }
8102 if (attribute_flag[1] != 0)
8103 geometry_info.rho=argument_list[1].real_reference;
8104 if (attribute_flag[2] != 0)
8105 geometry_info.sigma=argument_list[2].real_reference;
8106 if (attribute_flag[3] != 0)
8107 channel=(ChannelType) argument_list[3].integer_reference;
8108 channel_mask=SetImageChannelMask(image,channel);
8109 image=StatisticImage(image,NonpeakStatistic,(size_t)
8110 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8111 if (image != (Image *) NULL)
8112 (void) SetImageChannelMask(image,channel_mask);
8113 break;
8114 }
8115 case 22: /* Roll */
8116 {
8117 if (attribute_flag[0] != 0)
8118 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8119 &geometry,exception);
8120 if (attribute_flag[1] != 0)
8121 geometry.x=argument_list[1].integer_reference;
8122 if (attribute_flag[2] != 0)
8123 geometry.y=argument_list[2].integer_reference;
8124 image=RollImage(image,geometry.x,geometry.y,exception);
8125 break;
8126 }
8127 case 23: /* Rotate */
8128 {
8129 if (attribute_flag[0] == 0)
8130 argument_list[0].real_reference=90.0;
8131 if (attribute_flag[1] != 0)
8132 {
8133 QueryColorCompliance(argument_list[1].string_reference,
8134 AllCompliance,&image->background_color,exception);
8135 if ((image->background_color.alpha_trait == BlendPixelTrait) &&
8136 (image->alpha_trait != BlendPixelTrait))
8137 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8138 }
8139 image=RotateImage(image,argument_list[0].real_reference,exception);
8140 break;
8141 }
8142 case 24: /* Sample */
8143 {
8144 if (attribute_flag[0] != 0)
8145 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8146 &geometry,exception);
8147 if (attribute_flag[1] != 0)
8148 geometry.width=argument_list[1].integer_reference;
8149 if (attribute_flag[2] != 0)
8150 geometry.height=argument_list[2].integer_reference;
8151 image=SampleImage(image,geometry.width,geometry.height,exception);
8152 break;
8153 }
8154 case 25: /* Scale */
8155 {
8156 if (attribute_flag[0] != 0)
8157 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8158 &geometry,exception);
8159 if (attribute_flag[1] != 0)
8160 geometry.width=argument_list[1].integer_reference;
8161 if (attribute_flag[2] != 0)
8162 geometry.height=argument_list[2].integer_reference;
8163 image=ScaleImage(image,geometry.width,geometry.height,exception);
8164 break;
8165 }
8166 case 26: /* Shade */
8167 {
8168 if (attribute_flag[0] != 0)
8169 {
8170 flags=ParseGeometry(argument_list[0].string_reference,
8171 &geometry_info);
8172 if ((flags & SigmaValue) == 0)
8173 geometry_info.sigma=0.0;
8174 }
8175 if (attribute_flag[1] != 0)
8176 geometry_info.rho=argument_list[1].real_reference;
8177 if (attribute_flag[2] != 0)
8178 geometry_info.sigma=argument_list[2].real_reference;
8179 image=ShadeImage(image,
8180 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8181 geometry_info.rho,geometry_info.sigma,exception);
8182 break;
8183 }
8184 case 27: /* Sharpen */
8185 {
8186 if (attribute_flag[0] != 0)
8187 {
8188 flags=ParseGeometry(argument_list[0].string_reference,
8189 &geometry_info);
8190 if ((flags & SigmaValue) == 0)
8191 geometry_info.sigma=1.0;
8192 }
8193 if (attribute_flag[1] != 0)
8194 geometry_info.rho=argument_list[1].real_reference;
8195 if (attribute_flag[2] != 0)
8196 geometry_info.sigma=argument_list[2].real_reference;
8197 if (attribute_flag[3] != 0)
8198 channel=(ChannelType) argument_list[3].integer_reference;
8199 channel_mask=SetImageChannelMask(image,channel);
8200 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8201 exception);
8202 if (image != (Image *) NULL)
8203 (void) SetImageChannelMask(image,channel_mask);
8204 break;
8205 }
8206 case 28: /* Shear */
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=geometry_info.rho;
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 QueryColorCompliance(argument_list[3].string_reference,
8221 AllCompliance,&image->background_color,exception);
8222 if (attribute_flag[4] != 0)
8223 QueryColorCompliance(argument_list[4].string_reference,
8224 AllCompliance,&image->background_color,exception);
8225 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8226 exception);
8227 break;
8228 }
8229 case 29: /* Spread */
8230 {
8231 PixelInterpolateMethod
8232 method;
8233
8234 if (attribute_flag[0] == 0)
8235 argument_list[0].real_reference=1.0;
8236 method=UndefinedInterpolatePixel;
8237 if (attribute_flag[1] != 0)
8238 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8239 image=SpreadImage(image,argument_list[0].real_reference,method,
8240 exception);
8241 break;
8242 }
8243 case 30: /* Swirl */
8244 {
8245 PixelInterpolateMethod
8246 method;
8247
8248 if (attribute_flag[0] == 0)
8249 argument_list[0].real_reference=50.0;
8250 method=UndefinedInterpolatePixel;
8251 if (attribute_flag[1] != 0)
8252 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8253 image=SwirlImage(image,argument_list[0].real_reference,
8254 method,exception);
8255 break;
8256 }
8257 case 31: /* Resize */
8258 case 32: /* Zoom */
8259 {
8260 if (attribute_flag[0] != 0)
8261 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8262 &geometry,exception);
8263 if (attribute_flag[1] != 0)
8264 geometry.width=argument_list[1].integer_reference;
8265 if (attribute_flag[2] != 0)
8266 geometry.height=argument_list[2].integer_reference;
8267 if (attribute_flag[3] == 0)
8268 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8269 if (attribute_flag[4] != 0)
8270 SetImageArtifact(image,"filter:support",
8271 argument_list[4].string_reference);
8272 image=ResizeImage(image,geometry.width,geometry.height,
8273 (FilterTypes) argument_list[3].integer_reference,
8274 exception);
8275 break;
8276 }
8277 case 33: /* Annotate */
8278 {
8279 DrawInfo
8280 *draw_info;
8281
8282 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8283 (DrawInfo *) NULL);
8284 if (attribute_flag[0] != 0)
8285 {
8286 char
8287 *text;
8288
8289 text=InterpretImageProperties(info ? info->image_info :
8290 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8291 exception);
8292 (void) CloneString(&draw_info->text,text);
8293 text=DestroyString(text);
8294 }
8295 if (attribute_flag[1] != 0)
8296 (void) CloneString(&draw_info->font,
8297 argument_list[1].string_reference);
8298 if (attribute_flag[2] != 0)
8299 draw_info->pointsize=argument_list[2].real_reference;
8300 if (attribute_flag[3] != 0)
8301 (void) CloneString(&draw_info->density,
8302 argument_list[3].string_reference);
8303 if (attribute_flag[4] != 0)
8304 (void) QueryColorCompliance(argument_list[4].string_reference,
8305 AllCompliance,&draw_info->undercolor,exception);
8306 if (attribute_flag[5] != 0)
8307 {
8308 (void) QueryColorCompliance(argument_list[5].string_reference,
8309 AllCompliance,&draw_info->stroke,exception);
8310 if (argument_list[5].image_reference != (Image *) NULL)
8311 draw_info->stroke_pattern=CloneImage(
8312 argument_list[5].image_reference,0,0,MagickTrue,exception);
8313 }
8314 if (attribute_flag[6] != 0)
8315 {
8316 (void) QueryColorCompliance(argument_list[6].string_reference,
8317 AllCompliance,&draw_info->fill,exception);
8318 if (argument_list[6].image_reference != (Image *) NULL)
8319 draw_info->fill_pattern=CloneImage(
8320 argument_list[6].image_reference,0,0,MagickTrue,exception);
8321 }
8322 if (attribute_flag[7] != 0)
8323 {
8324 (void) CloneString(&draw_info->geometry,
8325 argument_list[7].string_reference);
8326 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8327 &geometry,exception);
8328 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8329 geometry_info.sigma=geometry_info.xi;
8330 }
8331 if (attribute_flag[8] != 0)
8332 (void) QueryColorCompliance(argument_list[8].string_reference,
8333 AllCompliance,&draw_info->fill,exception);
8334 if (attribute_flag[11] != 0)
8335 draw_info->gravity=(GravityType)
8336 argument_list[11].integer_reference;
8337 if (attribute_flag[25] != 0)
8338 {
8339 AV
8340 *av;
8341
8342 av=(AV *) argument_list[25].array_reference;
8343 if ((av_len(av) != 3) && (av_len(av) != 5))
8344 {
8345 ThrowPerlException(exception,OptionError,
8346 "affine matrix must have 4 or 6 elements",PackageName);
8347 goto PerlException;
8348 }
8349 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8350 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8351 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8352 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8353 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8354 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8355 {
8356 ThrowPerlException(exception,OptionError,
8357 "affine matrix is singular",PackageName);
8358 goto PerlException;
8359 }
8360 if (av_len(av) == 5)
8361 {
8362 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8363 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8364 }
8365 }
8366 for (j=12; j < 17; j++)
8367 {
8368 if (attribute_flag[j] == 0)
8369 continue;
8370 value=argument_list[j].string_reference;
8371 angle=argument_list[j].real_reference;
8372 current=draw_info->affine;
8373 GetAffineMatrix(&affine);
8374 switch (j)
8375 {
8376 case 12:
8377 {
8378 /*
8379 Translate.
8380 */
8381 flags=ParseGeometry(value,&geometry_info);
8382 affine.tx=geometry_info.xi;
8383 affine.ty=geometry_info.psi;
8384 if ((flags & PsiValue) == 0)
8385 affine.ty=affine.tx;
8386 break;
8387 }
8388 case 13:
8389 {
8390 /*
8391 Scale.
8392 */
8393 flags=ParseGeometry(value,&geometry_info);
8394 affine.sx=geometry_info.rho;
8395 affine.sy=geometry_info.sigma;
8396 if ((flags & SigmaValue) == 0)
8397 affine.sy=affine.sx;
8398 break;
8399 }
8400 case 14:
8401 {
8402 /*
8403 Rotate.
8404 */
8405 if (angle == 0.0)
8406 break;
8407 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8408 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8409 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8410 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8411 break;
8412 }
8413 case 15:
8414 {
8415 /*
8416 SkewX.
8417 */
8418 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8419 break;
8420 }
8421 case 16:
8422 {
8423 /*
8424 SkewY.
8425 */
8426 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8427 break;
8428 }
8429 }
8430 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8431 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8432 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8433 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8434 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8435 current.tx;
8436 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8437 current.ty;
8438 }
8439 if (attribute_flag[9] == 0)
8440 argument_list[9].real_reference=0.0;
8441 if (attribute_flag[10] == 0)
8442 argument_list[10].real_reference=0.0;
8443 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8444 {
8445 char
8446 geometry[MaxTextExtent];
8447
8448 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
8449 (double) argument_list[9].real_reference+draw_info->affine.tx,
8450 (double) argument_list[10].real_reference+draw_info->affine.ty);
8451 (void) CloneString(&draw_info->geometry,geometry);
8452 }
8453 if (attribute_flag[17] != 0)
8454 draw_info->stroke_width=argument_list[17].real_reference;
8455 if (attribute_flag[18] != 0)
8456 {
8457 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8458 MagickTrue : MagickFalse;
8459 draw_info->stroke_antialias=draw_info->text_antialias;
8460 }
8461 if (attribute_flag[19] != 0)
8462 (void) CloneString(&draw_info->family,
8463 argument_list[19].string_reference);
8464 if (attribute_flag[20] != 0)
8465 draw_info->style=(StyleType) argument_list[20].integer_reference;
8466 if (attribute_flag[21] != 0)
8467 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8468 if (attribute_flag[22] != 0)
8469 draw_info->weight=argument_list[22].integer_reference;
8470 if (attribute_flag[23] != 0)
8471 draw_info->align=(AlignType) argument_list[23].integer_reference;
8472 if (attribute_flag[24] != 0)
8473 (void) CloneString(&draw_info->encoding,
8474 argument_list[24].string_reference);
8475 if (attribute_flag[25] != 0)
8476 draw_info->fill_pattern=CloneImage(
8477 argument_list[25].image_reference,0,0,MagickTrue,exception);
8478 if (attribute_flag[26] != 0)
8479 draw_info->fill_pattern=CloneImage(
8480 argument_list[26].image_reference,0,0,MagickTrue,exception);
8481 if (attribute_flag[27] != 0)
8482 draw_info->stroke_pattern=CloneImage(
8483 argument_list[27].image_reference,0,0,MagickTrue,exception);
8484 if (attribute_flag[29] != 0)
8485 draw_info->kerning=argument_list[29].real_reference;
8486 if (attribute_flag[30] != 0)
8487 draw_info->interline_spacing=argument_list[30].real_reference;
8488 if (attribute_flag[31] != 0)
8489 draw_info->interword_spacing=argument_list[31].real_reference;
8490 if (attribute_flag[32] != 0)
8491 draw_info->direction=(DirectionType)
8492 argument_list[32].integer_reference;
8493 (void) AnnotateImage(image,draw_info,exception);
8494 draw_info=DestroyDrawInfo(draw_info);
8495 break;
8496 }
8497 case 34: /* ColorFloodfill */
8498 {
8499 DrawInfo
8500 *draw_info;
8501
8502 MagickBooleanType
8503 invert;
8504
8505 PixelInfo
8506 target;
8507
8508 draw_info=CloneDrawInfo(info ? info->image_info :
8509 (ImageInfo *) NULL,(DrawInfo *) NULL);
8510 if (attribute_flag[0] != 0)
8511 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8512 &geometry,exception);
8513 if (attribute_flag[1] != 0)
8514 geometry.x=argument_list[1].integer_reference;
8515 if (attribute_flag[2] != 0)
8516 geometry.y=argument_list[2].integer_reference;
8517 if (attribute_flag[3] != 0)
8518 (void) QueryColorCompliance(argument_list[3].string_reference,
8519 AllCompliance,&draw_info->fill,exception);
8520 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8521 geometry.x,geometry.y,&target,exception);
8522 invert=MagickFalse;
8523 if (attribute_flag[4] != 0)
8524 {
8525 QueryColorCompliance(argument_list[4].string_reference,
8526 AllCompliance,&target,exception);
8527 invert=MagickTrue;
8528 }
8529 if (attribute_flag[5] != 0)
8530 image->fuzz=StringToDoubleInterval(
8531 argument_list[5].string_reference,(double) QuantumRange+1.0);
8532 if (attribute_flag[6] != 0)
8533 invert=(MagickBooleanType) argument_list[6].integer_reference;
8534 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8535 geometry.y,invert,exception);
8536 draw_info=DestroyDrawInfo(draw_info);
8537 break;
8538 }
8539 case 35: /* Composite */
8540 {
8541 char
8542 composite_geometry[MaxTextExtent];
8543
8544 Image
8545 *composite_image,
8546 *rotate_image;
8547
8548 MagickBooleanType
8549 clip_to_self;
8550
8551 compose=OverCompositeOp;
8552 if (attribute_flag[0] != 0)
8553 composite_image=argument_list[0].image_reference;
8554 else
8555 {
8556 ThrowPerlException(exception,OptionError,
8557 "CompositeImageRequired",PackageName);
8558 goto PerlException;
8559 }
8560 /*
8561 Parameter Handling used for BOTH normal and tiled composition.
8562 */
8563 if (attribute_flag[1] != 0) /* compose */
8564 compose=(CompositeOperator) argument_list[1].integer_reference;
8565 if (attribute_flag[6] != 0) /* opacity */
8566 {
8567 if (compose != DissolveCompositeOp)
8568 (void) SetImageAlpha(composite_image,(Quantum)
8569 StringToDoubleInterval(argument_list[6].string_reference,
8570 (double) QuantumRange+1.0),exception);
8571 else
8572 {
8573 CacheView
8574 *composite_view;
8575
8576 double
8577 opacity;
8578
8579 MagickBooleanType
8580 sync;
8581
8582 register ssize_t
8583 x;
8584
8585 register Quantum
8586 *q;
8587
8588 ssize_t
8589 y;
8590
8591 /*
8592 Handle dissolve composite operator (patch by
8593 Kevin A. McGrail).
8594 */
8595 (void) CloneString(&image->geometry,
8596 argument_list[6].string_reference);
8597 opacity=(Quantum) StringToDoubleInterval(
8598 argument_list[6].string_reference,(double) QuantumRange+
8599 1.0);
8600 if (composite_image->alpha_trait == BlendPixelTrait)
8601 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8602 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8603 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8604 {
8605 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8606 composite_image->columns,1,exception);
8607 for (x=0; x < (ssize_t) composite_image->columns; x++)
8608 {
8609 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8610 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8611 q);
8612 q+=GetPixelChannels(composite_image);
8613 }
8614 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8615 if (sync == MagickFalse)
8616 break;
8617 }
8618 composite_view=DestroyCacheView(composite_view);
8619 }
8620 }
8621 if (attribute_flag[9] != 0) /* "color=>" */
8622 QueryColorCompliance(argument_list[9].string_reference,
8623 AllCompliance,&composite_image->background_color,exception);
8624 if (attribute_flag[12] != 0) /* "interpolate=>" */
8625 image->interpolate=(PixelInterpolateMethod)
8626 argument_list[12].integer_reference;
8627 if (attribute_flag[13] != 0) /* "args=>" */
8628 (void) SetImageArtifact(composite_image,"compose:args",
8629 argument_list[13].string_reference);
8630 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8631 (void) SetImageArtifact(composite_image,"compose:args",
8632 argument_list[14].string_reference);
8633 clip_to_self=MagickTrue;
8634 if (attribute_flag[15] != 0)
8635 clip_to_self=(MagickBooleanType)
8636 argument_list[15].integer_reference;
8637 /*
8638 Tiling Composition (with orthogonal rotate).
8639 */
8640 rotate_image=(Image *) NULL;
8641 if (attribute_flag[8] != 0) /* "rotate=>" */
8642 {
8643 /*
8644 Rotate image.
8645 */
8646 rotate_image=RotateImage(composite_image,
8647 argument_list[8].real_reference,exception);
8648 if (rotate_image == (Image *) NULL)
8649 break;
8650 }
8651 if ((attribute_flag[7] != 0) &&
8652 (argument_list[7].integer_reference != 0)) /* tile */
8653 {
8654 ssize_t
8655 x,
8656 y;
8657
8658 /*
8659 Tile the composite image.
8660 */
8661 if (attribute_flag[8] != 0) /* "tile=>" */
8662 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8663 "false");
8664 else
8665 (void) SetImageArtifact(composite_image,
8666 "compose:outside-overlay","false");
8667 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8668 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8669 {
8670 if (attribute_flag[8] != 0) /* rotate */
8671 (void) CompositeImage(image,rotate_image,compose,
8672 MagickTrue,x,y,exception);
8673 else
8674 (void) CompositeImage(image,composite_image,compose,
8675 MagickTrue,x,y,exception);
8676 }
8677 if (attribute_flag[8] != 0) /* rotate */
8678 rotate_image=DestroyImage(rotate_image);
8679 break;
8680 }
8681 /*
8682 Parameter Handling used used ONLY for normal composition.
8683 */
8684 if (attribute_flag[5] != 0) /* gravity */
8685 image->gravity=(GravityType) argument_list[5].integer_reference;
8686 if (attribute_flag[2] != 0) /* geometry offset */
8687 {
8688 SetGeometry(image,&geometry);
8689 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8690 &geometry);
8691 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8692 &geometry);
8693 }
8694 if (attribute_flag[3] != 0) /* x offset */
8695 geometry.x=argument_list[3].integer_reference;
8696 if (attribute_flag[4] != 0) /* y offset */
8697 geometry.y=argument_list[4].integer_reference;
8698 if (attribute_flag[10] != 0) /* mask */
8699 {
8700 if ((image->compose == DisplaceCompositeOp) ||
8701 (image->compose == DistortCompositeOp))
8702 {
8703 /*
8704 Merge Y displacement into X displacement image.
8705 */
8706 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8707 exception);
8708 (void) CompositeImage(composite_image,
8709 argument_list[10].image_reference,CopyGreenCompositeOp,
8710 MagickTrue,0,0,exception);
8711 }
8712 else
8713 {
8714 Image
8715 *mask_image;
8716
8717 /*
8718 Set a blending mask for the composition.
8719 */
8720 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8721 MagickTrue,exception);
8722 (void) SetImageMask(composite_image,mask_image,exception);
8723 mask_image=DestroyImage(mask_image);
8724 }
8725 }
8726 if (attribute_flag[11] != 0) /* channel */
8727 channel=(ChannelType) argument_list[11].integer_reference;
8728 /*
8729 Composite two images (normal composition).
8730 */
8731 (void) FormatLocaleString(composite_geometry,MaxTextExtent,
8732 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8733 (double) composite_image->rows,(double) geometry.x,(double)
8734 geometry.y);
8735 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8736 exception);
8737 channel_mask=SetImageChannelMask(image,channel);
8738 if (attribute_flag[8] == 0) /* no rotate */
8739 CompositeImage(image,composite_image,compose,clip_to_self,
8740 geometry.x,geometry.y,exception);
8741 else
8742 {
8743 /*
8744 Position adjust rotated image then composite.
8745 */
8746 geometry.x-=(ssize_t) (rotate_image->columns-
8747 composite_image->columns)/2;
8748 geometry.y-=(ssize_t) (rotate_image->rows-
8749 composite_image->rows)/2;
8750 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8751 geometry.y,exception);
8752 rotate_image=DestroyImage(rotate_image);
8753 }
8754 if (attribute_flag[10] != 0) /* mask */
8755 {
8756 if ((image->compose == DisplaceCompositeOp) ||
8757 (image->compose == DistortCompositeOp))
8758 composite_image=DestroyImage(composite_image);
8759 else
8760 (void) SetImageMask(image,(Image *) NULL,exception);
8761 }
8762 (void) SetImageChannelMask(image,channel_mask);
8763 break;
8764 }
8765 case 36: /* Contrast */
8766 {
8767 if (attribute_flag[0] == 0)
8768 argument_list[0].integer_reference=0;
8769 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8770 MagickTrue : MagickFalse,exception);
8771 break;
8772 }
8773 case 37: /* CycleColormap */
8774 {
8775 if (attribute_flag[0] == 0)
8776 argument_list[0].integer_reference=6;
8777 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8778 exception);
8779 break;
8780 }
8781 case 38: /* Draw */
8782 {
8783 DrawInfo
8784 *draw_info;
8785
8786 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8787 (DrawInfo *) NULL);
8788 (void) CloneString(&draw_info->primitive,"point");
8789 if (attribute_flag[0] != 0)
8790 {
8791 if (argument_list[0].integer_reference < 0)
8792 (void) CloneString(&draw_info->primitive,
8793 argument_list[0].string_reference);
8794 else
8795 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8796 MagickPrimitiveOptions,argument_list[0].integer_reference));
8797 }
8798 if (attribute_flag[1] != 0)
8799 {
8800 if (LocaleCompare(draw_info->primitive,"path") == 0)
8801 {
8802 (void) ConcatenateString(&draw_info->primitive," '");
8803 ConcatenateString(&draw_info->primitive,
8804 argument_list[1].string_reference);
8805 (void) ConcatenateString(&draw_info->primitive,"'");
8806 }
8807 else
8808 {
8809 (void) ConcatenateString(&draw_info->primitive," ");
8810 ConcatenateString(&draw_info->primitive,
8811 argument_list[1].string_reference);
8812 }
8813 }
8814 if (attribute_flag[2] != 0)
8815 {
8816 (void) ConcatenateString(&draw_info->primitive," ");
8817 (void) ConcatenateString(&draw_info->primitive,
8818 CommandOptionToMnemonic(MagickMethodOptions,
8819 argument_list[2].integer_reference));
8820 }
8821 if (attribute_flag[3] != 0)
8822 {
8823 (void) QueryColorCompliance(argument_list[3].string_reference,
8824 AllCompliance,&draw_info->stroke,exception);
8825 if (argument_list[3].image_reference != (Image *) NULL)
8826 draw_info->stroke_pattern=CloneImage(
8827 argument_list[3].image_reference,0,0,MagickTrue,exception);
8828 }
8829 if (attribute_flag[4] != 0)
8830 {
8831 (void) QueryColorCompliance(argument_list[4].string_reference,
8832 AllCompliance,&draw_info->fill,exception);
8833 if (argument_list[4].image_reference != (Image *) NULL)
8834 draw_info->fill_pattern=CloneImage(
8835 argument_list[4].image_reference,0,0,MagickTrue,exception);
8836 }
8837 if (attribute_flag[5] != 0)
8838 draw_info->stroke_width=argument_list[5].real_reference;
8839 if (attribute_flag[6] != 0)
8840 (void) CloneString(&draw_info->font,
8841 argument_list[6].string_reference);
8842 if (attribute_flag[7] != 0)
8843 (void) QueryColorCompliance(argument_list[7].string_reference,
8844 AllCompliance,&draw_info->border_color,exception);
8845 if (attribute_flag[8] != 0)
8846 draw_info->affine.tx=argument_list[8].real_reference;
8847 if (attribute_flag[9] != 0)
8848 draw_info->affine.ty=argument_list[9].real_reference;
8849 if (attribute_flag[20] != 0)
8850 {
8851 AV
8852 *av;
8853
8854 av=(AV *) argument_list[20].array_reference;
8855 if ((av_len(av) != 3) && (av_len(av) != 5))
8856 {
8857 ThrowPerlException(exception,OptionError,
8858 "affine matrix must have 4 or 6 elements",PackageName);
8859 goto PerlException;
8860 }
8861 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8862 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8863 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8864 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8865 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8866 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8867 {
8868 ThrowPerlException(exception,OptionError,
8869 "affine matrix is singular",PackageName);
8870 goto PerlException;
8871 }
8872 if (av_len(av) == 5)
8873 {
8874 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8875 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8876 }
8877 }
8878 for (j=10; j < 15; j++)
8879 {
8880 if (attribute_flag[j] == 0)
8881 continue;
8882 value=argument_list[j].string_reference;
8883 angle=argument_list[j].real_reference;
8884 current=draw_info->affine;
8885 GetAffineMatrix(&affine);
8886 switch (j)
8887 {
8888 case 10:
8889 {
8890 /*
8891 Translate.
8892 */
8893 flags=ParseGeometry(value,&geometry_info);
8894 affine.tx=geometry_info.xi;
8895 affine.ty=geometry_info.psi;
8896 if ((flags & PsiValue) == 0)
8897 affine.ty=affine.tx;
8898 break;
8899 }
8900 case 11:
8901 {
8902 /*
8903 Scale.
8904 */
8905 flags=ParseGeometry(value,&geometry_info);
8906 affine.sx=geometry_info.rho;
8907 affine.sy=geometry_info.sigma;
8908 if ((flags & SigmaValue) == 0)
8909 affine.sy=affine.sx;
8910 break;
8911 }
8912 case 12:
8913 {
8914 /*
8915 Rotate.
8916 */
8917 if (angle == 0.0)
8918 break;
8919 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8920 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8921 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8922 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8923 break;
8924 }
8925 case 13:
8926 {
8927 /*
8928 SkewX.
8929 */
8930 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8931 break;
8932 }
8933 case 14:
8934 {
8935 /*
8936 SkewY.
8937 */
8938 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8939 break;
8940 }
8941 }
8942 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8943 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8944 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8945 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8946 draw_info->affine.tx=
8947 current.sx*affine.tx+current.ry*affine.ty+current.tx;
8948 draw_info->affine.ty=
8949 current.rx*affine.tx+current.sy*affine.ty+current.ty;
8950 }
8951 if (attribute_flag[15] != 0)
8952 draw_info->fill_pattern=CloneImage(
8953 argument_list[15].image_reference,0,0,MagickTrue,exception);
8954 if (attribute_flag[16] != 0)
8955 draw_info->pointsize=argument_list[16].real_reference;
8956 if (attribute_flag[17] != 0)
8957 {
8958 draw_info->stroke_antialias=argument_list[17].integer_reference != 0
8959 ? MagickTrue : MagickFalse;
8960 draw_info->text_antialias=draw_info->stroke_antialias;
8961 }
8962 if (attribute_flag[18] != 0)
8963 (void) CloneString(&draw_info->density,
8964 argument_list[18].string_reference);
8965 if (attribute_flag[19] != 0)
8966 draw_info->stroke_width=argument_list[19].real_reference;
8967 if (attribute_flag[21] != 0)
8968 draw_info->dash_offset=argument_list[21].real_reference;
8969 if (attribute_flag[22] != 0)
8970 {
8971 AV
8972 *av;
8973
8974 av=(AV *) argument_list[22].array_reference;
8975 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
8976 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
8977 if (draw_info->dash_pattern != (double *) NULL)
8978 {
8979 for (i=0; i <= av_len(av); i++)
8980 draw_info->dash_pattern[i]=(double)
8981 SvNV(*(av_fetch(av,i,0)));
8982 draw_info->dash_pattern[i]=0.0;
8983 }
8984 }
8985 if (attribute_flag[23] != 0)
8986 image->interpolate=(PixelInterpolateMethod)
8987 argument_list[23].integer_reference;
8988 if ((attribute_flag[24] != 0) &&
8989 (draw_info->fill_pattern != (Image *) NULL))
8990 flags=ParsePageGeometry(draw_info->fill_pattern,
8991 argument_list[24].string_reference,
8992 &draw_info->fill_pattern->tile_offset,exception);
8993 if (attribute_flag[25] != 0)
8994 {
8995 (void) ConcatenateString(&draw_info->primitive," '");
8996 (void) ConcatenateString(&draw_info->primitive,
8997 argument_list[25].string_reference);
8998 (void) ConcatenateString(&draw_info->primitive,"'");
8999 }
9000 if (attribute_flag[26] != 0)
9001 draw_info->fill_pattern=CloneImage(
9002 argument_list[26].image_reference,0,0,MagickTrue,exception);
9003 if (attribute_flag[27] != 0)
9004 draw_info->stroke_pattern=CloneImage(
9005 argument_list[27].image_reference,0,0,MagickTrue,exception);
9006 if (attribute_flag[28] != 0)
9007 (void) CloneString(&draw_info->primitive,
9008 argument_list[28].string_reference);
9009 if (attribute_flag[29] != 0)
9010 draw_info->kerning=argument_list[29].real_reference;
9011 if (attribute_flag[30] != 0)
9012 draw_info->interline_spacing=argument_list[30].real_reference;
9013 if (attribute_flag[31] != 0)
9014 draw_info->interword_spacing=argument_list[31].real_reference;
9015 if (attribute_flag[32] != 0)
9016 draw_info->direction=(DirectionType)
9017 argument_list[32].integer_reference;
9018 DrawImage(image,draw_info,exception);
9019 draw_info=DestroyDrawInfo(draw_info);
9020 break;
9021 }
9022 case 39: /* Equalize */
9023 {
9024 if (attribute_flag[0] != 0)
9025 channel=(ChannelType) argument_list[0].integer_reference;
9026 channel_mask=SetImageChannelMask(image,channel);
9027 EqualizeImage(image,exception);
9028 (void) SetImageChannelMask(image,channel_mask);
9029 break;
9030 }
9031 case 40: /* Gamma */
9032 {
9033 if (attribute_flag[1] != 0)
9034 channel=(ChannelType) argument_list[1].integer_reference;
9035 if (attribute_flag[2] == 0)
9036 argument_list[2].real_reference=1.0;
9037 if (attribute_flag[3] == 0)
9038 argument_list[3].real_reference=1.0;
9039 if (attribute_flag[4] == 0)
9040 argument_list[4].real_reference=1.0;
9041 if (attribute_flag[0] == 0)
9042 {
9043 (void) FormatLocaleString(message,MaxTextExtent,
9044 "%.15g,%.15g,%.15g",(double) argument_list[2].real_reference,
9045 (double) argument_list[3].real_reference,
9046 (double) argument_list[4].real_reference);
9047 argument_list[0].string_reference=message;
9048 }
9049 (void) GammaImage(image,StringToDouble(
9050 argument_list[0].string_reference,(char **) NULL),exception);
9051 break;
9052 }
9053 case 41: /* Map */
9054 {
9055 QuantizeInfo
9056 *quantize_info;
9057
9058 if (attribute_flag[0] == 0)
9059 {
9060 ThrowPerlException(exception,OptionError,"MapImageRequired",
9061 PackageName);
9062 goto PerlException;
9063 }
9064 quantize_info=AcquireQuantizeInfo(info->image_info);
9065 if (attribute_flag[1] != 0)
9066 quantize_info->dither_method=(DitherMethod)
9067 argument_list[1].integer_reference;
9068 (void) RemapImages(quantize_info,image,
9069 argument_list[0].image_reference,exception);
9070 quantize_info=DestroyQuantizeInfo(quantize_info);
9071 break;
9072 }
9073 case 42: /* MatteFloodfill */
9074 {
9075 DrawInfo
9076 *draw_info;
9077
9078 MagickBooleanType
9079 invert;
9080
9081 PixelInfo
9082 target;
9083
9084 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9085 (DrawInfo *) NULL);
9086 if (attribute_flag[0] != 0)
9087 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9088 &geometry,exception);
9089 if (attribute_flag[1] != 0)
9090 geometry.x=argument_list[1].integer_reference;
9091 if (attribute_flag[2] != 0)
9092 geometry.y=argument_list[2].integer_reference;
9093 if (image->alpha_trait != BlendPixelTrait)
9094 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9095 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9096 geometry.x,geometry.y,&target,exception);
9097 if (attribute_flag[4] != 0)
9098 QueryColorCompliance(argument_list[4].string_reference,
9099 AllCompliance,&target,exception);
9100 if (attribute_flag[3] != 0)
9101 target.alpha=StringToDoubleInterval(
9102 argument_list[3].string_reference,(double) (double) QuantumRange+
9103 1.0);
9104 if (attribute_flag[5] != 0)
9105 image->fuzz=StringToDoubleInterval(
9106 argument_list[5].string_reference,(double) QuantumRange+1.0);
9107 invert=MagickFalse;
9108 if (attribute_flag[6] != 0)
9109 invert=(MagickBooleanType) argument_list[6].integer_reference;
9110 channel_mask=SetImageChannelMask(image,AlphaChannel);
9111 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9112 geometry.y,invert,exception);
9113 (void) SetImageChannelMask(image,channel_mask);
9114 draw_info=DestroyDrawInfo(draw_info);
9115 break;
9116 }
9117 case 43: /* Modulate */
9118 {
9119 char
9120 modulate[MaxTextExtent];
9121
9122 geometry_info.rho=100.0;
9123 geometry_info.sigma=100.0;
9124 geometry_info.xi=100.0;
9125 if (attribute_flag[0] != 0)
9126 (void)ParseGeometry(argument_list[0].string_reference,
9127 &geometry_info);
9128 if (attribute_flag[1] != 0)
9129 geometry_info.xi=argument_list[1].real_reference;
9130 if (attribute_flag[2] != 0)
9131 geometry_info.sigma=argument_list[2].real_reference;
9132 if (attribute_flag[3] != 0)
9133 {
9134 geometry_info.sigma=argument_list[3].real_reference;
9135 SetImageArtifact(image,"modulate:colorspace","HWB");
9136 }
9137 if (attribute_flag[4] != 0)
9138 {
9139 geometry_info.rho=argument_list[4].real_reference;
9140 SetImageArtifact(image,"modulate:colorspace","HSB");
9141 }
9142 if (attribute_flag[5] != 0)
9143 {
9144 geometry_info.sigma=argument_list[5].real_reference;
9145 SetImageArtifact(image,"modulate:colorspace","HSL");
9146 }
9147 if (attribute_flag[6] != 0)
9148 {
9149 geometry_info.rho=argument_list[6].real_reference;
9150 SetImageArtifact(image,"modulate:colorspace","HWB");
9151 }
9152 (void) FormatLocaleString(modulate,MaxTextExtent,"%.15g,%.15g,%.15g",
9153 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
9154 (void) ModulateImage(image,modulate,exception);
9155 break;
9156 }
9157 case 44: /* Negate */
9158 {
9159 if (attribute_flag[0] == 0)
9160 argument_list[0].integer_reference=0;
9161 if (attribute_flag[1] != 0)
9162 channel=(ChannelType) argument_list[1].integer_reference;
9163 channel_mask=SetImageChannelMask(image,channel);
9164 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9165 MagickTrue : MagickFalse,exception);
9166 (void) SetImageChannelMask(image,channel_mask);
9167 break;
9168 }
9169 case 45: /* Normalize */
9170 {
9171 if (attribute_flag[0] != 0)
9172 channel=(ChannelType) argument_list[0].integer_reference;
9173 channel_mask=SetImageChannelMask(image,channel);
9174 NormalizeImage(image,exception);
9175 (void) SetImageChannelMask(image,channel_mask);
9176 break;
9177 }
9178 case 46: /* NumberColors */
9179 break;
9180 case 47: /* Opaque */
9181 {
9182 MagickBooleanType
9183 invert;
9184
9185 PixelInfo
9186 fill_color,
9187 target;
9188
9189 (void) QueryColorCompliance("none",AllCompliance,&target,
9190 exception);
9191 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9192 exception);
9193 if (attribute_flag[0] != 0)
9194 (void) QueryColorCompliance(argument_list[0].string_reference,
9195 AllCompliance,&target,exception);
9196 if (attribute_flag[1] != 0)
9197 (void) QueryColorCompliance(argument_list[1].string_reference,
9198 AllCompliance,&fill_color,exception);
9199 if (attribute_flag[2] != 0)
9200 image->fuzz=StringToDoubleInterval(
9201 argument_list[2].string_reference,(double) QuantumRange+1.0);
9202 if (attribute_flag[3] != 0)
9203 channel=(ChannelType) argument_list[3].integer_reference;
9204 invert=MagickFalse;
9205 if (attribute_flag[4] != 0)
9206 invert=(MagickBooleanType) argument_list[4].integer_reference;
9207 channel_mask=SetImageChannelMask(image,channel);
9208 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9209 (void) SetImageChannelMask(image,channel_mask);
9210 break;
9211 }
9212 case 48: /* Quantize */
9213 {
9214 QuantizeInfo
9215 *quantize_info;
9216
9217 quantize_info=AcquireQuantizeInfo(info->image_info);
9218 if (attribute_flag[0] != 0)
9219 quantize_info->number_colors=(size_t)
9220 argument_list[0].integer_reference;
9221 if (attribute_flag[1] != 0)
9222 quantize_info->tree_depth=(size_t)
9223 argument_list[1].integer_reference;
9224 if (attribute_flag[2] != 0)
9225 quantize_info->colorspace=(ColorspaceType)
9226 argument_list[2].integer_reference;
9227 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009228 quantize_info->dither_method=(DitherMethod)
9229 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009230 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009231 quantize_info->measure_error=
9232 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009233 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009234 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009235 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009236 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009237 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009238 argument_list[7].integer_reference;
9239 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009240 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009241 else
cristyf7563392014-03-25 13:54:04 +00009242 if ((image->storage_class == DirectClass) ||
9243 (image->colors > quantize_info->number_colors) ||
9244 (quantize_info->colorspace == GRAYColorspace))
9245 (void) QuantizeImage(quantize_info,image,exception);
9246 else
9247 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009248 quantize_info=DestroyQuantizeInfo(quantize_info);
9249 break;
9250 }
9251 case 49: /* Raise */
9252 {
9253 if (attribute_flag[0] != 0)
9254 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9255 &geometry,exception);
9256 if (attribute_flag[1] != 0)
9257 geometry.width=argument_list[1].integer_reference;
9258 if (attribute_flag[2] != 0)
9259 geometry.height=argument_list[2].integer_reference;
9260 if (attribute_flag[3] == 0)
9261 argument_list[3].integer_reference=1;
9262 (void) RaiseImage(image,&geometry,
9263 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9264 exception);
9265 break;
9266 }
9267 case 50: /* Segment */
9268 {
9269 ColorspaceType
9270 colorspace;
9271
9272 double
9273 cluster_threshold,
9274 smoothing_threshold;
9275
9276 MagickBooleanType
9277 verbose;
9278
9279 cluster_threshold=1.0;
9280 smoothing_threshold=1.5;
9281 colorspace=sRGBColorspace;
9282 verbose=MagickFalse;
9283 if (attribute_flag[0] != 0)
9284 {
9285 flags=ParseGeometry(argument_list[0].string_reference,
9286 &geometry_info);
9287 cluster_threshold=geometry_info.rho;
9288 if (flags & SigmaValue)
9289 smoothing_threshold=geometry_info.sigma;
9290 }
9291 if (attribute_flag[1] != 0)
9292 cluster_threshold=argument_list[1].real_reference;
9293 if (attribute_flag[2] != 0)
9294 smoothing_threshold=argument_list[2].real_reference;
9295 if (attribute_flag[3] != 0)
9296 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9297 if (attribute_flag[4] != 0)
9298 verbose=argument_list[4].integer_reference != 0 ?
9299 MagickTrue : MagickFalse;
9300 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9301 smoothing_threshold,exception);
9302 break;
9303 }
9304 case 51: /* Signature */
9305 {
9306 (void) SignatureImage(image,exception);
9307 break;
9308 }
9309 case 52: /* Solarize */
9310 {
9311 geometry_info.rho=QuantumRange/2.0;
9312 if (attribute_flag[0] != 0)
9313 flags=ParseGeometry(argument_list[0].string_reference,
9314 &geometry_info);
9315 if (attribute_flag[1] != 0)
9316 geometry_info.rho=StringToDoubleInterval(
9317 argument_list[1].string_reference,(double) QuantumRange+1.0);
9318 (void) SolarizeImage(image,geometry_info.rho,exception);
9319 break;
9320 }
9321 case 53: /* Sync */
9322 {
9323 (void) SyncImage(image,exception);
9324 break;
9325 }
9326 case 54: /* Texture */
9327 {
9328 if (attribute_flag[0] == 0)
9329 break;
9330 TextureImage(image,argument_list[0].image_reference,exception);
9331 break;
9332 }
9333 case 55: /* Evalute */
9334 {
9335 MagickEvaluateOperator
9336 op;
9337
9338 op=SetEvaluateOperator;
9339 if (attribute_flag[0] == MagickFalse)
9340 argument_list[0].real_reference=0.0;
9341 if (attribute_flag[1] != MagickFalse)
9342 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9343 if (attribute_flag[2] != MagickFalse)
9344 channel=(ChannelType) argument_list[2].integer_reference;
9345 channel_mask=SetImageChannelMask(image,channel);
9346 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9347 exception);
9348 (void) SetImageChannelMask(image,channel_mask);
9349 break;
9350 }
9351 case 56: /* Transparent */
9352 {
9353 double
9354 opacity;
9355
9356 MagickBooleanType
9357 invert;
9358
9359 PixelInfo
9360 target;
9361
9362 (void) QueryColorCompliance("none",AllCompliance,&target,
9363 exception);
9364 if (attribute_flag[0] != 0)
9365 (void) QueryColorCompliance(argument_list[0].string_reference,
9366 AllCompliance,&target,exception);
9367 opacity=TransparentAlpha;
9368 if (attribute_flag[1] != 0)
9369 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9370 (double) QuantumRange+1.0);
9371 if (attribute_flag[2] != 0)
9372 image->fuzz=StringToDoubleInterval(
9373 argument_list[2].string_reference,(double) QuantumRange+1.0);
9374 if (attribute_flag[3] == 0)
9375 argument_list[3].integer_reference=0;
9376 invert=MagickFalse;
9377 if (attribute_flag[3] != 0)
9378 invert=(MagickBooleanType) argument_list[3].integer_reference;
9379 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9380 invert,exception);
9381 break;
9382 }
9383 case 57: /* Threshold */
9384 {
9385 double
9386 threshold;
9387
9388 if (attribute_flag[0] == 0)
9389 argument_list[0].string_reference="50%";
9390 if (attribute_flag[1] != 0)
9391 channel=(ChannelType) argument_list[1].integer_reference;
9392 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9393 (double) QuantumRange+1.0);
9394 channel_mask=SetImageChannelMask(image,channel);
9395 (void) BilevelImage(image,threshold,exception);
9396 (void) SetImageChannelMask(image,channel_mask);
9397 break;
9398 }
9399 case 58: /* Charcoal */
9400 {
9401 if (attribute_flag[0] != 0)
9402 {
9403 flags=ParseGeometry(argument_list[0].string_reference,
9404 &geometry_info);
9405 if ((flags & SigmaValue) == 0)
9406 geometry_info.sigma=1.0;
9407 }
9408 if (attribute_flag[1] != 0)
9409 geometry_info.rho=argument_list[1].real_reference;
9410 if (attribute_flag[2] != 0)
9411 geometry_info.sigma=argument_list[2].real_reference;
9412 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9413 exception);
9414 break;
9415 }
9416 case 59: /* Trim */
9417 {
9418 if (attribute_flag[0] != 0)
9419 image->fuzz=StringToDoubleInterval(
9420 argument_list[0].string_reference,(double) QuantumRange+1.0);
9421 image=TrimImage(image,exception);
9422 break;
9423 }
9424 case 60: /* Wave */
9425 {
9426 PixelInterpolateMethod
9427 method;
9428
9429 if (attribute_flag[0] != 0)
9430 {
9431 flags=ParseGeometry(argument_list[0].string_reference,
9432 &geometry_info);
9433 if ((flags & SigmaValue) == 0)
9434 geometry_info.sigma=1.0;
9435 }
9436 if (attribute_flag[1] != 0)
9437 geometry_info.rho=argument_list[1].real_reference;
9438 if (attribute_flag[2] != 0)
9439 geometry_info.sigma=argument_list[2].real_reference;
9440 method=UndefinedInterpolatePixel;
9441 if (attribute_flag[3] != 0)
9442 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9443 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9444 method,exception);
9445 break;
9446 }
9447 case 61: /* Separate */
9448 {
9449 if (attribute_flag[0] != 0)
9450 channel=(ChannelType) argument_list[0].integer_reference;
9451 image=SeparateImage(image,channel,exception);
9452 break;
9453 }
9454 case 63: /* Stereo */
9455 {
9456 if (attribute_flag[0] == 0)
9457 {
9458 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9459 PackageName);
9460 goto PerlException;
9461 }
9462 if (attribute_flag[1] != 0)
9463 geometry.x=argument_list[1].integer_reference;
9464 if (attribute_flag[2] != 0)
9465 geometry.y=argument_list[2].integer_reference;
9466 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9467 geometry.x,geometry.y,exception);
9468 break;
9469 }
9470 case 64: /* Stegano */
9471 {
9472 if (attribute_flag[0] == 0)
9473 {
9474 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9475 PackageName);
9476 goto PerlException;
9477 }
9478 if (attribute_flag[1] == 0)
9479 argument_list[1].integer_reference=0;
9480 image->offset=argument_list[1].integer_reference;
9481 image=SteganoImage(image,argument_list[0].image_reference,exception);
9482 break;
9483 }
9484 case 65: /* Deconstruct */
9485 {
9486 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9487 break;
9488 }
9489 case 66: /* GaussianBlur */
9490 {
9491 if (attribute_flag[0] != 0)
9492 {
9493 flags=ParseGeometry(argument_list[0].string_reference,
9494 &geometry_info);
9495 if ((flags & SigmaValue) == 0)
9496 geometry_info.sigma=1.0;
9497 }
9498 if (attribute_flag[1] != 0)
9499 geometry_info.rho=argument_list[1].real_reference;
9500 if (attribute_flag[2] != 0)
9501 geometry_info.sigma=argument_list[2].real_reference;
9502 if (attribute_flag[3] != 0)
9503 channel=(ChannelType) argument_list[3].integer_reference;
9504 channel_mask=SetImageChannelMask(image,channel);
9505 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9506 exception);
9507 if (image != (Image *) NULL)
9508 (void) SetImageChannelMask(image,channel_mask);
9509 break;
9510 }
9511 case 67: /* Convolve */
9512 {
9513 KernelInfo
9514 *kernel;
9515
9516 kernel=(KernelInfo *) NULL;
9517 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9518 break;
9519 if (attribute_flag[0] != 0)
9520 {
9521 AV
9522 *av;
9523
9524 size_t
9525 order;
9526
9527 kernel=AcquireKernelInfo((const char *) NULL);
9528 if (kernel == (KernelInfo *) NULL)
9529 break;
9530 av=(AV *) argument_list[0].array_reference;
9531 order=(size_t) sqrt(av_len(av)+1);
9532 kernel->width=order;
9533 kernel->height=order;
9534 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9535 order*sizeof(*kernel->values));
9536 if (kernel->values == (MagickRealType *) NULL)
9537 {
9538 kernel=DestroyKernelInfo(kernel);
9539 ThrowPerlException(exception,ResourceLimitFatalError,
9540 "MemoryAllocationFailed",PackageName);
9541 goto PerlException;
9542 }
9543 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9544 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9545 for ( ; j < (ssize_t) (order*order); j++)
9546 kernel->values[j]=0.0;
9547 }
9548 if (attribute_flag[1] != 0)
9549 channel=(ChannelType) argument_list[1].integer_reference;
9550 if (attribute_flag[2] != 0)
9551 SetImageArtifact(image,"filter:blur",
9552 argument_list[2].string_reference);
9553 if (attribute_flag[3] != 0)
9554 {
9555 kernel=AcquireKernelInfo(argument_list[3].string_reference);
9556 if (kernel == (KernelInfo *) NULL)
9557 break;
9558 }
9559 channel_mask=SetImageChannelMask(image,channel);
9560 image=ConvolveImage(image,kernel,exception);
9561 if (image != (Image *) NULL)
9562 (void) SetImageChannelMask(image,channel_mask);
9563 kernel=DestroyKernelInfo(kernel);
9564 break;
9565 }
9566 case 68: /* Profile */
9567 {
9568 const char
9569 *name;
9570
9571 Image
9572 *profile_image;
9573
9574 ImageInfo
9575 *profile_info;
9576
9577 StringInfo
9578 *profile;
9579
9580 name="*";
9581 if (attribute_flag[0] != 0)
9582 name=argument_list[0].string_reference;
9583 if (attribute_flag[2] != 0)
9584 image->rendering_intent=(RenderingIntent)
9585 argument_list[2].integer_reference;
9586 if (attribute_flag[3] != 0)
9587 image->black_point_compensation=
9588 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9589 if (attribute_flag[1] != 0)
9590 {
9591 if (argument_list[1].length == 0)
9592 {
9593 /*
9594 Remove a profile from the image.
9595 */
9596 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9597 exception);
9598 break;
9599 }
9600 /*
9601 Associate user supplied profile with the image.
9602 */
9603 profile=AcquireStringInfo(argument_list[1].length);
9604 SetStringInfoDatum(profile,(const unsigned char *)
9605 argument_list[1].string_reference);
9606 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9607 (size_t) GetStringInfoLength(profile),exception);
9608 profile=DestroyStringInfo(profile);
9609 break;
9610 }
9611 /*
9612 Associate a profile with the image.
9613 */
9614 profile_info=CloneImageInfo(info ? info->image_info :
9615 (ImageInfo *) NULL);
9616 profile_image=ReadImages(profile_info,name,exception);
9617 if (profile_image == (Image *) NULL)
9618 break;
9619 ResetImageProfileIterator(profile_image);
9620 name=GetNextImageProfile(profile_image);
9621 while (name != (const char *) NULL)
9622 {
9623 const StringInfo
9624 *profile;
9625
9626 profile=GetImageProfile(profile_image,name);
9627 if (profile != (const StringInfo *) NULL)
9628 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9629 (size_t) GetStringInfoLength(profile),exception);
9630 name=GetNextImageProfile(profile_image);
9631 }
9632 profile_image=DestroyImage(profile_image);
9633 profile_info=DestroyImageInfo(profile_info);
9634 break;
9635 }
9636 case 69: /* UnsharpMask */
9637 {
9638 if (attribute_flag[0] != 0)
9639 {
9640 flags=ParseGeometry(argument_list[0].string_reference,
9641 &geometry_info);
9642 if ((flags & SigmaValue) == 0)
9643 geometry_info.sigma=1.0;
9644 if ((flags & XiValue) == 0)
9645 geometry_info.xi=1.0;
9646 if ((flags & PsiValue) == 0)
9647 geometry_info.psi=0.5;
9648 }
9649 if (attribute_flag[1] != 0)
9650 geometry_info.rho=argument_list[1].real_reference;
9651 if (attribute_flag[2] != 0)
9652 geometry_info.sigma=argument_list[2].real_reference;
9653 if (attribute_flag[3] != 0)
9654 geometry_info.xi=argument_list[3].real_reference;
9655 if (attribute_flag[4] != 0)
9656 geometry_info.psi=argument_list[4].real_reference;
9657 if (attribute_flag[5] != 0)
9658 channel=(ChannelType) argument_list[5].integer_reference;
9659 channel_mask=SetImageChannelMask(image,channel);
9660 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9661 geometry_info.xi,geometry_info.psi,exception);
9662 if (image != (Image *) NULL)
9663 (void) SetImageChannelMask(image,channel_mask);
9664 break;
9665 }
9666 case 70: /* MotionBlur */
9667 {
9668 if (attribute_flag[0] != 0)
9669 {
9670 flags=ParseGeometry(argument_list[0].string_reference,
9671 &geometry_info);
9672 if ((flags & SigmaValue) == 0)
9673 geometry_info.sigma=1.0;
9674 if ((flags & XiValue) == 0)
9675 geometry_info.xi=1.0;
9676 }
9677 if (attribute_flag[1] != 0)
9678 geometry_info.rho=argument_list[1].real_reference;
9679 if (attribute_flag[2] != 0)
9680 geometry_info.sigma=argument_list[2].real_reference;
9681 if (attribute_flag[3] != 0)
9682 geometry_info.xi=argument_list[3].real_reference;
9683 if (attribute_flag[4] != 0)
9684 channel=(ChannelType) argument_list[4].integer_reference;
9685 channel_mask=SetImageChannelMask(image,channel);
9686 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9687 geometry_info.xi,exception);
9688 if (image != (Image *) NULL)
9689 (void) SetImageChannelMask(image,channel_mask);
9690 break;
9691 }
9692 case 71: /* OrderedDither */
9693 {
9694 if (attribute_flag[0] == 0)
9695 argument_list[0].string_reference="o8x8";
9696 if (attribute_flag[1] != 0)
9697 channel=(ChannelType) argument_list[1].integer_reference;
9698 channel_mask=SetImageChannelMask(image,channel);
9699 (void) OrderedPosterizeImage(image,argument_list[0].string_reference,
9700 exception);
9701 (void) SetImageChannelMask(image,channel_mask);
9702 break;
9703 }
9704 case 72: /* Shave */
9705 {
9706 if (attribute_flag[0] != 0)
9707 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9708 &geometry,exception);
9709 if (attribute_flag[1] != 0)
9710 geometry.width=argument_list[1].integer_reference;
9711 if (attribute_flag[2] != 0)
9712 geometry.height=argument_list[2].integer_reference;
9713 image=ShaveImage(image,&geometry,exception);
9714 break;
9715 }
9716 case 73: /* Level */
9717 {
9718 double
9719 black_point,
9720 gamma,
9721 white_point;
9722
9723 black_point=0.0;
9724 white_point=(double) image->columns*image->rows;
9725 gamma=1.0;
9726 if (attribute_flag[0] != 0)
9727 {
9728 flags=ParseGeometry(argument_list[0].string_reference,
9729 &geometry_info);
9730 black_point=geometry_info.rho;
9731 if ((flags & SigmaValue) != 0)
9732 white_point=geometry_info.sigma;
9733 if ((flags & XiValue) != 0)
9734 gamma=geometry_info.xi;
9735 if ((flags & PercentValue) != 0)
9736 {
9737 black_point*=(double) (QuantumRange/100.0);
9738 white_point*=(double) (QuantumRange/100.0);
9739 }
9740 if ((flags & SigmaValue) == 0)
9741 white_point=(double) QuantumRange-black_point;
9742 }
9743 if (attribute_flag[1] != 0)
9744 black_point=argument_list[1].real_reference;
9745 if (attribute_flag[2] != 0)
9746 white_point=argument_list[2].real_reference;
9747 if (attribute_flag[3] != 0)
9748 gamma=argument_list[3].real_reference;
9749 if (attribute_flag[4] != 0)
9750 channel=(ChannelType) argument_list[4].integer_reference;
9751 if (attribute_flag[5] != 0)
9752 {
9753 argument_list[0].real_reference=argument_list[5].real_reference;
9754 attribute_flag[0]=attribute_flag[5];
9755 }
9756 channel_mask=SetImageChannelMask(image,channel);
9757 (void) LevelImage(image,black_point,white_point,gamma,exception);
9758 (void) SetImageChannelMask(image,channel_mask);
9759 break;
9760 }
9761 case 74: /* Clip */
9762 {
9763 if (attribute_flag[0] == 0)
9764 argument_list[0].string_reference="#1";
9765 if (attribute_flag[1] == 0)
9766 argument_list[1].integer_reference=MagickTrue;
9767 (void) ClipImagePath(image,argument_list[0].string_reference,
9768 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9769 exception);
9770 break;
9771 }
9772 case 75: /* AffineTransform */
9773 {
9774 DrawInfo
9775 *draw_info;
9776
9777 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9778 (DrawInfo *) NULL);
9779 if (attribute_flag[0] != 0)
9780 {
9781 AV
9782 *av;
9783
9784 av=(AV *) argument_list[0].array_reference;
9785 if ((av_len(av) != 3) && (av_len(av) != 5))
9786 {
9787 ThrowPerlException(exception,OptionError,
9788 "affine matrix must have 4 or 6 elements",PackageName);
9789 goto PerlException;
9790 }
9791 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9792 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9793 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9794 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9795 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9796 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9797 {
9798 ThrowPerlException(exception,OptionError,
9799 "affine matrix is singular",PackageName);
9800 goto PerlException;
9801 }
9802 if (av_len(av) == 5)
9803 {
9804 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9805 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9806 }
9807 }
9808 for (j=1; j < 6; j++)
9809 {
9810 if (attribute_flag[j] == 0)
9811 continue;
9812 value=argument_list[j].string_reference;
9813 angle=argument_list[j].real_reference;
9814 current=draw_info->affine;
9815 GetAffineMatrix(&affine);
9816 switch (j)
9817 {
9818 case 1:
9819 {
9820 /*
9821 Translate.
9822 */
9823 flags=ParseGeometry(value,&geometry_info);
9824 affine.tx=geometry_info.xi;
9825 affine.ty=geometry_info.psi;
9826 if ((flags & PsiValue) == 0)
9827 affine.ty=affine.tx;
9828 break;
9829 }
9830 case 2:
9831 {
9832 /*
9833 Scale.
9834 */
9835 flags=ParseGeometry(value,&geometry_info);
9836 affine.sx=geometry_info.rho;
9837 affine.sy=geometry_info.sigma;
9838 if ((flags & SigmaValue) == 0)
9839 affine.sy=affine.sx;
9840 break;
9841 }
9842 case 3:
9843 {
9844 /*
9845 Rotate.
9846 */
9847 if (angle == 0.0)
9848 break;
9849 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9850 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9851 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9852 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9853 break;
9854 }
9855 case 4:
9856 {
9857 /*
9858 SkewX.
9859 */
9860 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9861 break;
9862 }
9863 case 5:
9864 {
9865 /*
9866 SkewY.
9867 */
9868 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9869 break;
9870 }
9871 }
9872 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9873 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9874 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9875 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9876 draw_info->affine.tx=
9877 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9878 draw_info->affine.ty=
9879 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9880 }
9881 if (attribute_flag[6] != 0)
9882 image->interpolate=(PixelInterpolateMethod)
9883 argument_list[6].integer_reference;
9884 if (attribute_flag[7] != 0)
9885 QueryColorCompliance(argument_list[7].string_reference,
9886 AllCompliance,&image->background_color,exception);
9887 image=AffineTransformImage(image,&draw_info->affine,exception);
9888 draw_info=DestroyDrawInfo(draw_info);
9889 break;
9890 }
9891 case 76: /* Difference */
9892 {
9893 if (attribute_flag[0] == 0)
9894 {
9895 ThrowPerlException(exception,OptionError,
9896 "ReferenceImageRequired",PackageName);
9897 goto PerlException;
9898 }
9899 if (attribute_flag[1] != 0)
9900 image->fuzz=StringToDoubleInterval(
9901 argument_list[1].string_reference,(double) QuantumRange+1.0);
9902 (void) IsImagesEqual(image,argument_list[0].image_reference,
9903 exception);
9904 break;
9905 }
9906 case 77: /* AdaptiveThreshold */
9907 {
9908 if (attribute_flag[0] != 0)
9909 {
9910 flags=ParseGeometry(argument_list[0].string_reference,
9911 &geometry_info);
9912 if ((flags & PercentValue) != 0)
9913 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9914 }
9915 if (attribute_flag[1] != 0)
9916 geometry_info.rho=argument_list[1].integer_reference;
9917 if (attribute_flag[2] != 0)
9918 geometry_info.sigma=argument_list[2].integer_reference;
9919 if (attribute_flag[3] != 0)
9920 geometry_info.xi=argument_list[3].integer_reference;;
9921 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9922 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9923 break;
9924 }
9925 case 78: /* Resample */
9926 {
9927 size_t
9928 height,
9929 width;
9930
9931 if (attribute_flag[0] != 0)
9932 {
9933 flags=ParseGeometry(argument_list[0].string_reference,
9934 &geometry_info);
9935 if ((flags & SigmaValue) == 0)
9936 geometry_info.sigma=geometry_info.rho;
9937 }
9938 if (attribute_flag[1] != 0)
9939 geometry_info.rho=argument_list[1].real_reference;
9940 if (attribute_flag[2] != 0)
9941 geometry_info.sigma=argument_list[2].real_reference;
9942 if (attribute_flag[3] == 0)
9943 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
9944 if (attribute_flag[4] == 0)
9945 SetImageArtifact(image,"filter:support",
9946 argument_list[4].string_reference);
9947 width=(size_t) (geometry_info.rho*image->columns/
9948 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
9949 height=(size_t) (geometry_info.sigma*image->rows/
9950 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
9951 image=ResizeImage(image,width,height,(FilterTypes)
9952 argument_list[3].integer_reference,exception);
9953 if (image != (Image *) NULL)
9954 {
9955 image->resolution.x=geometry_info.rho;
9956 image->resolution.y=geometry_info.sigma;
9957 }
9958 break;
9959 }
9960 case 79: /* Describe */
9961 {
9962 if (attribute_flag[0] == 0)
9963 argument_list[0].file_reference=(FILE *) NULL;
9964 if (attribute_flag[1] != 0)
9965 (void) SetImageArtifact(image,"identify:features",
9966 argument_list[1].string_reference);
9967 (void) IdentifyImage(image,argument_list[0].file_reference,
9968 MagickTrue,exception);
9969 break;
9970 }
9971 case 80: /* BlackThreshold */
9972 {
9973 if (attribute_flag[0] == 0)
9974 argument_list[0].string_reference="50%";
9975 if (attribute_flag[2] != 0)
9976 channel=(ChannelType) argument_list[2].integer_reference;
9977 channel_mask=SetImageChannelMask(image,channel);
9978 BlackThresholdImage(image,argument_list[0].string_reference,
9979 exception);
9980 (void) SetImageChannelMask(image,channel_mask);
9981 break;
9982 }
9983 case 81: /* WhiteThreshold */
9984 {
9985 if (attribute_flag[0] == 0)
9986 argument_list[0].string_reference="50%";
9987 if (attribute_flag[2] != 0)
9988 channel=(ChannelType) argument_list[2].integer_reference;
9989 channel_mask=SetImageChannelMask(image,channel);
9990 WhiteThresholdImage(image,argument_list[0].string_reference,
9991 exception);
9992 (void) SetImageChannelMask(image,channel_mask);
9993 break;
9994 }
cristy60c73c02014-03-25 12:09:58 +00009995 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +00009996 {
9997 if (attribute_flag[0] != 0)
9998 {
9999 flags=ParseGeometry(argument_list[0].string_reference,
10000 &geometry_info);
10001 }
10002 if (attribute_flag[1] != 0)
10003 geometry_info.rho=argument_list[1].real_reference;
10004 if (attribute_flag[2] != 0)
10005 channel=(ChannelType) argument_list[2].integer_reference;
10006 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010007 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010008 if (image != (Image *) NULL)
10009 (void) SetImageChannelMask(image,channel_mask);
10010 break;
10011 }
10012 case 83: /* Thumbnail */
10013 {
10014 if (attribute_flag[0] != 0)
10015 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10016 &geometry,exception);
10017 if (attribute_flag[1] != 0)
10018 geometry.width=argument_list[1].integer_reference;
10019 if (attribute_flag[2] != 0)
10020 geometry.height=argument_list[2].integer_reference;
10021 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10022 break;
10023 }
10024 case 84: /* Strip */
10025 {
10026 (void) StripImage(image,exception);
10027 break;
10028 }
10029 case 85: /* Tint */
10030 {
10031 PixelInfo
10032 tint;
10033
10034 GetPixelInfo(image,&tint);
10035 if (attribute_flag[0] != 0)
10036 (void) QueryColorCompliance(argument_list[0].string_reference,
10037 AllCompliance,&tint,exception);
10038 if (attribute_flag[1] == 0)
10039 argument_list[1].string_reference="100";
10040 image=TintImage(image,argument_list[1].string_reference,&tint,
10041 exception);
10042 break;
10043 }
10044 case 86: /* Channel */
10045 {
10046 if (attribute_flag[0] != 0)
10047 channel=(ChannelType) argument_list[0].integer_reference;
10048 image=SeparateImage(image,channel,exception);
10049 break;
10050 }
10051 case 87: /* Splice */
10052 {
10053 if (attribute_flag[0] != 0)
10054 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10055 &geometry,exception);
10056 if (attribute_flag[1] != 0)
10057 geometry.width=argument_list[1].integer_reference;
10058 if (attribute_flag[2] != 0)
10059 geometry.height=argument_list[2].integer_reference;
10060 if (attribute_flag[3] != 0)
10061 geometry.x=argument_list[3].integer_reference;
10062 if (attribute_flag[4] != 0)
10063 geometry.y=argument_list[4].integer_reference;
10064 if (attribute_flag[5] != 0)
10065 image->fuzz=StringToDoubleInterval(
10066 argument_list[5].string_reference,(double) QuantumRange+1.0);
10067 if (attribute_flag[6] != 0)
10068 (void) QueryColorCompliance(argument_list[6].string_reference,
10069 AllCompliance,&image->background_color,exception);
10070 if (attribute_flag[7] != 0)
10071 image->gravity=(GravityType) argument_list[7].integer_reference;
10072 image=SpliceImage(image,&geometry,exception);
10073 break;
10074 }
10075 case 88: /* Posterize */
10076 {
10077 if (attribute_flag[0] == 0)
10078 argument_list[0].integer_reference=3;
10079 if (attribute_flag[1] == 0)
10080 argument_list[1].integer_reference=0;
10081 (void) PosterizeImage(image,argument_list[0].integer_reference,
10082 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10083 NoDitherMethod,exception);
10084 break;
10085 }
10086 case 89: /* Shadow */
10087 {
10088 if (attribute_flag[0] != 0)
10089 {
10090 flags=ParseGeometry(argument_list[0].string_reference,
10091 &geometry_info);
10092 if ((flags & SigmaValue) == 0)
10093 geometry_info.sigma=1.0;
10094 if ((flags & XiValue) == 0)
10095 geometry_info.xi=4.0;
10096 if ((flags & PsiValue) == 0)
10097 geometry_info.psi=4.0;
10098 }
10099 if (attribute_flag[1] != 0)
10100 geometry_info.rho=argument_list[1].real_reference;
10101 if (attribute_flag[2] != 0)
10102 geometry_info.sigma=argument_list[2].real_reference;
10103 if (attribute_flag[3] != 0)
10104 geometry_info.xi=argument_list[3].integer_reference;
10105 if (attribute_flag[4] != 0)
10106 geometry_info.psi=argument_list[4].integer_reference;
10107 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10108 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10109 ceil(geometry_info.psi-0.5),exception);
10110 break;
10111 }
10112 case 90: /* Identify */
10113 {
10114 if (attribute_flag[0] == 0)
10115 argument_list[0].file_reference=(FILE *) NULL;
10116 if (attribute_flag[1] != 0)
10117 (void) SetImageArtifact(image,"identify:features",
10118 argument_list[1].string_reference);
10119 if ((attribute_flag[2] != 0) &&
10120 (argument_list[2].integer_reference != 0))
10121 (void) SetImageArtifact(image,"identify:unique","true");
10122 (void) IdentifyImage(image,argument_list[0].file_reference,
10123 MagickTrue,exception);
10124 break;
10125 }
10126 case 91: /* SepiaTone */
10127 {
10128 if (attribute_flag[0] == 0)
10129 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10130 image=SepiaToneImage(image,argument_list[0].real_reference,
10131 exception);
10132 break;
10133 }
10134 case 92: /* SigmoidalContrast */
10135 {
10136 MagickBooleanType
10137 sharpen;
10138
10139 if (attribute_flag[0] != 0)
10140 {
10141 flags=ParseGeometry(argument_list[0].string_reference,
10142 &geometry_info);
10143 if ((flags & SigmaValue) == 0)
10144 geometry_info.sigma=QuantumRange/2.0;
10145 if ((flags & PercentValue) != 0)
10146 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10147 }
10148 if (attribute_flag[1] != 0)
10149 geometry_info.rho=argument_list[1].real_reference;
10150 if (attribute_flag[2] != 0)
10151 geometry_info.sigma=argument_list[2].real_reference;
10152 if (attribute_flag[3] != 0)
10153 channel=(ChannelType) argument_list[3].integer_reference;
10154 sharpen=MagickTrue;
10155 if (attribute_flag[4] != 0)
10156 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10157 MagickFalse;
10158 channel_mask=SetImageChannelMask(image,channel);
10159 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10160 geometry_info.sigma,exception);
10161 (void) SetImageChannelMask(image,channel_mask);
10162 break;
10163 }
10164 case 93: /* Extent */
10165 {
10166 if (attribute_flag[7] != 0)
10167 image->gravity=(GravityType) argument_list[7].integer_reference;
10168 if (attribute_flag[0] != 0)
10169 {
10170 int
10171 flags;
10172
10173 flags=ParseGravityGeometry(image,
10174 argument_list[0].string_reference,&geometry,exception);
10175 (void) flags;
10176 if (geometry.width == 0)
10177 geometry.width=image->columns;
10178 if (geometry.height == 0)
10179 geometry.height=image->rows;
10180 }
10181 if (attribute_flag[1] != 0)
10182 geometry.width=argument_list[1].integer_reference;
10183 if (attribute_flag[2] != 0)
10184 geometry.height=argument_list[2].integer_reference;
10185 if (attribute_flag[3] != 0)
10186 geometry.x=argument_list[3].integer_reference;
10187 if (attribute_flag[4] != 0)
10188 geometry.y=argument_list[4].integer_reference;
10189 if (attribute_flag[5] != 0)
10190 image->fuzz=StringToDoubleInterval(
10191 argument_list[5].string_reference,(double) QuantumRange+1.0);
10192 if (attribute_flag[6] != 0)
10193 (void) QueryColorCompliance(argument_list[6].string_reference,
10194 AllCompliance,&image->background_color,exception);
10195 image=ExtentImage(image,&geometry,exception);
10196 break;
10197 }
10198 case 94: /* Vignette */
10199 {
10200 if (attribute_flag[0] != 0)
10201 {
10202 flags=ParseGeometry(argument_list[0].string_reference,
10203 &geometry_info);
10204 if ((flags & SigmaValue) == 0)
10205 geometry_info.sigma=1.0;
10206 if ((flags & XiValue) == 0)
10207 geometry_info.xi=0.1*image->columns;
10208 if ((flags & PsiValue) == 0)
10209 geometry_info.psi=0.1*image->rows;
10210 }
10211 if (attribute_flag[1] != 0)
10212 geometry_info.rho=argument_list[1].real_reference;
10213 if (attribute_flag[2] != 0)
10214 geometry_info.sigma=argument_list[2].real_reference;
10215 if (attribute_flag[3] != 0)
10216 geometry_info.xi=argument_list[3].integer_reference;
10217 if (attribute_flag[4] != 0)
10218 geometry_info.psi=argument_list[4].integer_reference;
10219 if (attribute_flag[5] != 0)
10220 (void) QueryColorCompliance(argument_list[5].string_reference,
10221 AllCompliance,&image->background_color,exception);
10222 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10223 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10224 ceil(geometry_info.psi-0.5),exception);
10225 break;
10226 }
10227 case 95: /* ContrastStretch */
10228 {
10229 double
10230 black_point,
10231 white_point;
10232
10233 black_point=0.0;
10234 white_point=(double) image->columns*image->rows;
10235 if (attribute_flag[0] != 0)
10236 {
10237 flags=ParseGeometry(argument_list[0].string_reference,
10238 &geometry_info);
10239 black_point=geometry_info.rho;
10240 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10241 black_point;
10242 if ((flags & PercentValue) != 0)
10243 {
10244 black_point*=(double) image->columns*image->rows/100.0;
10245 white_point*=(double) image->columns*image->rows/100.0;
10246 }
10247 white_point=(double) image->columns*image->rows-
10248 white_point;
10249 }
10250 if (attribute_flag[1] != 0)
10251 black_point=argument_list[1].real_reference;
10252 if (attribute_flag[2] != 0)
10253 white_point=argument_list[2].real_reference;
10254 if (attribute_flag[4] != 0)
10255 channel=(ChannelType) argument_list[4].integer_reference;
10256 channel_mask=SetImageChannelMask(image,channel);
10257 (void) ContrastStretchImage(image,black_point,white_point,exception);
10258 (void) SetImageChannelMask(image,channel_mask);
10259 break;
10260 }
10261 case 96: /* Sans0 */
10262 {
10263 break;
10264 }
10265 case 97: /* Sans1 */
10266 {
10267 break;
10268 }
10269 case 98: /* AdaptiveSharpen */
10270 {
10271 if (attribute_flag[0] != 0)
10272 {
10273 flags=ParseGeometry(argument_list[0].string_reference,
10274 &geometry_info);
10275 if ((flags & SigmaValue) == 0)
10276 geometry_info.sigma=1.0;
10277 if ((flags & XiValue) == 0)
10278 geometry_info.xi=0.0;
10279 }
10280 if (attribute_flag[1] != 0)
10281 geometry_info.rho=argument_list[1].real_reference;
10282 if (attribute_flag[2] != 0)
10283 geometry_info.sigma=argument_list[2].real_reference;
10284 if (attribute_flag[3] != 0)
10285 geometry_info.xi=argument_list[3].real_reference;
10286 if (attribute_flag[4] != 0)
10287 channel=(ChannelType) argument_list[4].integer_reference;
10288 channel_mask=SetImageChannelMask(image,channel);
10289 image=AdaptiveSharpenImage(image,geometry_info.rho,
10290 geometry_info.sigma,exception);
10291 if (image != (Image *) NULL)
10292 (void) SetImageChannelMask(image,channel_mask);
10293 break;
10294 }
10295 case 99: /* Transpose */
10296 {
10297 image=TransposeImage(image,exception);
10298 break;
10299 }
10300 case 100: /* Tranverse */
10301 {
10302 image=TransverseImage(image,exception);
10303 break;
10304 }
10305 case 101: /* AutoOrient */
10306 {
10307 image=AutoOrientImage(image,image->orientation,exception);
10308 break;
10309 }
10310 case 102: /* AdaptiveBlur */
10311 {
10312 if (attribute_flag[0] != 0)
10313 {
10314 flags=ParseGeometry(argument_list[0].string_reference,
10315 &geometry_info);
10316 if ((flags & SigmaValue) == 0)
10317 geometry_info.sigma=1.0;
10318 if ((flags & XiValue) == 0)
10319 geometry_info.xi=0.0;
10320 }
10321 if (attribute_flag[1] != 0)
10322 geometry_info.rho=argument_list[1].real_reference;
10323 if (attribute_flag[2] != 0)
10324 geometry_info.sigma=argument_list[2].real_reference;
10325 if (attribute_flag[3] != 0)
10326 channel=(ChannelType) argument_list[3].integer_reference;
10327 channel_mask=SetImageChannelMask(image,channel);
10328 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10329 exception);
10330 if (image != (Image *) NULL)
10331 (void) SetImageChannelMask(image,channel_mask);
10332 break;
10333 }
10334 case 103: /* Sketch */
10335 {
10336 if (attribute_flag[0] != 0)
10337 {
10338 flags=ParseGeometry(argument_list[0].string_reference,
10339 &geometry_info);
10340 if ((flags & SigmaValue) == 0)
10341 geometry_info.sigma=1.0;
10342 if ((flags & XiValue) == 0)
10343 geometry_info.xi=1.0;
10344 }
10345 if (attribute_flag[1] != 0)
10346 geometry_info.rho=argument_list[1].real_reference;
10347 if (attribute_flag[2] != 0)
10348 geometry_info.sigma=argument_list[2].real_reference;
10349 if (attribute_flag[3] != 0)
10350 geometry_info.xi=argument_list[3].real_reference;
10351 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10352 geometry_info.xi,exception);
10353 break;
10354 }
10355 case 104: /* UniqueColors */
10356 {
10357 image=UniqueImageColors(image,exception);
10358 break;
10359 }
10360 case 105: /* AdaptiveResize */
10361 {
10362 if (attribute_flag[0] != 0)
10363 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10364 &geometry,exception);
10365 if (attribute_flag[1] != 0)
10366 geometry.width=argument_list[1].integer_reference;
10367 if (attribute_flag[2] != 0)
10368 geometry.height=argument_list[2].integer_reference;
10369 if (attribute_flag[3] != 0)
10370 image->filter=(FilterTypes) argument_list[4].integer_reference;
10371 if (attribute_flag[4] != 0)
10372 SetImageArtifact(image,"filter:support",
10373 argument_list[4].string_reference);
10374 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10375 exception);
10376 break;
10377 }
10378 case 106: /* ClipMask */
10379 {
10380 Image
10381 *mask_image;
10382
10383 if (attribute_flag[0] == 0)
10384 {
10385 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10386 PackageName);
10387 goto PerlException;
10388 }
10389 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10390 exception);
10391 (void) SetImageMask(image,mask_image,exception);
10392 mask_image=DestroyImage(mask_image);
10393 break;
10394 }
10395 case 107: /* LinearStretch */
10396 {
10397 double
10398 black_point,
10399 white_point;
10400
10401 black_point=0.0;
10402 white_point=(double) image->columns*image->rows;
10403 if (attribute_flag[0] != 0)
10404 {
10405 flags=ParseGeometry(argument_list[0].string_reference,
10406 &geometry_info);
10407 if ((flags & SigmaValue) != 0)
10408 white_point=geometry_info.sigma;
10409 if ((flags & PercentValue) != 0)
10410 {
10411 black_point*=(double) image->columns*image->rows/100.0;
10412 white_point*=(double) image->columns*image->rows/100.0;
10413 }
10414 if ((flags & SigmaValue) == 0)
10415 white_point=(double) image->columns*image->rows-black_point;
10416 }
10417 if (attribute_flag[1] != 0)
10418 black_point=argument_list[1].real_reference;
10419 if (attribute_flag[2] != 0)
10420 white_point=argument_list[2].real_reference;
10421 (void) LinearStretchImage(image,black_point,white_point,exception);
10422 break;
10423 }
10424 case 108: /* ColorMatrix */
10425 {
10426 AV
10427 *av;
10428
10429 double
10430 *color_matrix;
10431
10432 KernelInfo
10433 *kernel_info;
10434
10435 size_t
10436 order;
10437
10438 if (attribute_flag[0] == 0)
10439 break;
10440 av=(AV *) argument_list[0].array_reference;
10441 order=(size_t) sqrt(av_len(av)+1);
10442 color_matrix=(double *) AcquireQuantumMemory(order,order*
10443 sizeof(*color_matrix));
10444 if (color_matrix == (double *) NULL)
10445 {
10446 ThrowPerlException(exception,ResourceLimitFatalError,
10447 "MemoryAllocationFailed",PackageName);
10448 goto PerlException;
10449 }
10450 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10451 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10452 for ( ; j < (ssize_t) (order*order); j++)
10453 color_matrix[j]=0.0;
10454 kernel_info=AcquireKernelInfo((const char *) NULL);
10455 if (kernel_info == (KernelInfo *) NULL)
10456 break;
10457 kernel_info->width=order;
10458 kernel_info->height=order;
10459 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10460 order*sizeof(*kernel_info->values));
10461 if (kernel_info->values != (MagickRealType *) NULL)
10462 {
10463 for (i=0; i < (ssize_t) (order*order); i++)
10464 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10465 image=ColorMatrixImage(image,kernel_info,exception);
10466 }
10467 kernel_info=DestroyKernelInfo(kernel_info);
10468 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10469 break;
10470 }
10471 case 109: /* Mask */
10472 {
10473 Image
10474 *mask_image;
10475
10476 if (attribute_flag[0] == 0)
10477 {
10478 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10479 PackageName);
10480 goto PerlException;
10481 }
10482 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10483 MagickTrue,exception);
10484 (void) SetImageMask(image,mask_image,exception);
10485 mask_image=DestroyImage(mask_image);
10486 break;
10487 }
10488 case 110: /* Polaroid */
10489 {
10490 char
10491 *caption;
10492
10493 DrawInfo
10494 *draw_info;
10495
10496 double
10497 angle;
10498
10499 PixelInterpolateMethod
10500 method;
10501
10502 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10503 (DrawInfo *) NULL);
10504 caption=(char *) NULL;
10505 if (attribute_flag[0] != 0)
10506 caption=InterpretImageProperties(info ? info->image_info :
10507 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10508 exception);
10509 angle=0.0;
10510 if (attribute_flag[1] != 0)
10511 angle=argument_list[1].real_reference;
10512 if (attribute_flag[2] != 0)
10513 (void) CloneString(&draw_info->font,
10514 argument_list[2].string_reference);
10515 if (attribute_flag[3] != 0)
10516 (void) QueryColorCompliance(argument_list[3].string_reference,
10517 AllCompliance,&draw_info->stroke,exception);
10518 if (attribute_flag[4] != 0)
10519 (void) QueryColorCompliance(argument_list[4].string_reference,
10520 AllCompliance,&draw_info->fill,exception);
10521 if (attribute_flag[5] != 0)
10522 draw_info->stroke_width=argument_list[5].real_reference;
10523 if (attribute_flag[6] != 0)
10524 draw_info->pointsize=argument_list[6].real_reference;
10525 if (attribute_flag[7] != 0)
10526 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10527 if (attribute_flag[8] != 0)
10528 (void) QueryColorCompliance(argument_list[8].string_reference,
10529 AllCompliance,&image->background_color,exception);
10530 method=UndefinedInterpolatePixel;
10531 if (attribute_flag[9] != 0)
10532 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10533 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10534 draw_info=DestroyDrawInfo(draw_info);
10535 if (caption != (char *) NULL)
10536 caption=DestroyString(caption);
10537 break;
10538 }
10539 case 111: /* FloodfillPaint */
10540 {
10541 DrawInfo
10542 *draw_info;
10543
10544 MagickBooleanType
10545 invert;
10546
10547 PixelInfo
10548 target;
10549
10550 draw_info=CloneDrawInfo(info ? info->image_info :
10551 (ImageInfo *) NULL,(DrawInfo *) NULL);
10552 if (attribute_flag[0] != 0)
10553 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10554 &geometry,exception);
10555 if (attribute_flag[1] != 0)
10556 geometry.x=argument_list[1].integer_reference;
10557 if (attribute_flag[2] != 0)
10558 geometry.y=argument_list[2].integer_reference;
10559 if (attribute_flag[3] != 0)
10560 (void) QueryColorCompliance(argument_list[3].string_reference,
10561 AllCompliance,&draw_info->fill,exception);
10562 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10563 geometry.x,geometry.y,&target,exception);
10564 if (attribute_flag[4] != 0)
10565 QueryColorCompliance(argument_list[4].string_reference,
10566 AllCompliance,&target,exception);
10567 if (attribute_flag[5] != 0)
10568 image->fuzz=StringToDoubleInterval(
10569 argument_list[5].string_reference,(double) QuantumRange+1.0);
10570 if (attribute_flag[6] != 0)
10571 channel=(ChannelType) argument_list[6].integer_reference;
10572 invert=MagickFalse;
10573 if (attribute_flag[7] != 0)
10574 invert=(MagickBooleanType) argument_list[7].integer_reference;
10575 channel_mask=SetImageChannelMask(image,channel);
10576 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10577 geometry.y,invert,exception);
10578 (void) SetImageChannelMask(image,channel_mask);
10579 draw_info=DestroyDrawInfo(draw_info);
10580 break;
10581 }
10582 case 112: /* Distort */
10583 {
10584 AV
10585 *av;
10586
10587 double
10588 *coordinates;
10589
10590 DistortImageMethod
10591 method;
10592
10593 size_t
10594 number_coordinates;
10595
10596 VirtualPixelMethod
10597 virtual_pixel;
10598
10599 if (attribute_flag[0] == 0)
10600 break;
10601 method=UndefinedDistortion;
10602 if (attribute_flag[1] != 0)
10603 method=(DistortImageMethod) argument_list[1].integer_reference;
10604 av=(AV *) argument_list[0].array_reference;
10605 number_coordinates=(size_t) av_len(av)+1;
10606 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10607 sizeof(*coordinates));
10608 if (coordinates == (double *) NULL)
10609 {
10610 ThrowPerlException(exception,ResourceLimitFatalError,
10611 "MemoryAllocationFailed",PackageName);
10612 goto PerlException;
10613 }
10614 for (j=0; j < (ssize_t) number_coordinates; j++)
10615 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10616 virtual_pixel=UndefinedVirtualPixelMethod;
10617 if (attribute_flag[2] != 0)
10618 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10619 argument_list[2].integer_reference,exception);
10620 image=DistortImage(image,method,number_coordinates,coordinates,
10621 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10622 exception);
10623 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10624 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10625 exception);
10626 coordinates=(double *) RelinquishMagickMemory(coordinates);
10627 break;
10628 }
10629 case 113: /* Clut */
10630 {
10631 PixelInterpolateMethod
10632 method;
10633
10634 if (attribute_flag[0] == 0)
10635 {
10636 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10637 PackageName);
10638 goto PerlException;
10639 }
10640 method=UndefinedInterpolatePixel;
10641 if (attribute_flag[1] != 0)
10642 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10643 if (attribute_flag[2] != 0)
10644 channel=(ChannelType) argument_list[2].integer_reference;
10645 channel_mask=SetImageChannelMask(image,channel);
10646 (void) ClutImage(image,argument_list[0].image_reference,method,
10647 exception);
10648 (void) SetImageChannelMask(image,channel_mask);
10649 break;
10650 }
10651 case 114: /* LiquidRescale */
10652 {
10653 if (attribute_flag[0] != 0)
10654 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10655 &geometry,exception);
10656 if (attribute_flag[1] != 0)
10657 geometry.width=argument_list[1].integer_reference;
10658 if (attribute_flag[2] != 0)
10659 geometry.height=argument_list[2].integer_reference;
10660 if (attribute_flag[3] == 0)
10661 argument_list[3].real_reference=1.0;
10662 if (attribute_flag[4] == 0)
10663 argument_list[4].real_reference=0.0;
10664 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10665 argument_list[3].real_reference,argument_list[4].real_reference,
10666 exception);
10667 break;
10668 }
10669 case 115: /* EncipherImage */
10670 {
10671 (void) EncipherImage(image,argument_list[0].string_reference,
10672 exception);
10673 break;
10674 }
10675 case 116: /* DecipherImage */
10676 {
10677 (void) DecipherImage(image,argument_list[0].string_reference,
10678 exception);
10679 break;
10680 }
10681 case 117: /* Deskew */
10682 {
10683 geometry_info.rho=QuantumRange/2.0;
10684 if (attribute_flag[0] != 0)
10685 flags=ParseGeometry(argument_list[0].string_reference,
10686 &geometry_info);
10687 if (attribute_flag[1] != 0)
10688 geometry_info.rho=StringToDoubleInterval(
10689 argument_list[1].string_reference,(double) QuantumRange+1.0);
10690 image=DeskewImage(image,geometry_info.rho,exception);
10691 break;
10692 }
10693 case 118: /* Remap */
10694 {
10695 QuantizeInfo
10696 *quantize_info;
10697
10698 if (attribute_flag[0] == 0)
10699 {
10700 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10701 PackageName);
10702 goto PerlException;
10703 }
10704 quantize_info=AcquireQuantizeInfo(info->image_info);
10705 if (attribute_flag[1] != 0)
10706 quantize_info->dither_method=(DitherMethod)
10707 argument_list[1].integer_reference;
10708 (void) RemapImages(quantize_info,image,
10709 argument_list[0].image_reference,exception);
10710 quantize_info=DestroyQuantizeInfo(quantize_info);
10711 break;
10712 }
10713 case 119: /* SparseColor */
10714 {
10715 AV
10716 *av;
10717
10718 double
10719 *coordinates;
10720
10721 SparseColorMethod
10722 method;
10723
10724 size_t
10725 number_coordinates;
10726
10727 VirtualPixelMethod
10728 virtual_pixel;
10729
10730 if (attribute_flag[0] == 0)
10731 break;
10732 method=UndefinedColorInterpolate;
10733 if (attribute_flag[1] != 0)
10734 method=(SparseColorMethod) argument_list[1].integer_reference;
10735 av=(AV *) argument_list[0].array_reference;
10736 number_coordinates=(size_t) av_len(av)+1;
10737 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10738 sizeof(*coordinates));
10739 if (coordinates == (double *) NULL)
10740 {
10741 ThrowPerlException(exception,ResourceLimitFatalError,
10742 "MemoryAllocationFailed",PackageName);
10743 goto PerlException;
10744 }
10745 for (j=0; j < (ssize_t) number_coordinates; j++)
10746 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10747 virtual_pixel=UndefinedVirtualPixelMethod;
10748 if (attribute_flag[2] != 0)
10749 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10750 argument_list[2].integer_reference,exception);
10751 if (attribute_flag[3] != 0)
10752 channel=(ChannelType) argument_list[3].integer_reference;
10753 channel_mask=SetImageChannelMask(image,channel);
10754 image=SparseColorImage(image,method,number_coordinates,coordinates,
10755 exception);
10756 if (image != (Image *) NULL)
10757 (void) SetImageChannelMask(image,channel_mask);
10758 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10759 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10760 exception);
10761 coordinates=(double *) RelinquishMagickMemory(coordinates);
10762 break;
10763 }
10764 case 120: /* Function */
10765 {
10766 AV
10767 *av;
10768
10769 double
10770 *parameters;
10771
10772 MagickFunction
10773 function;
10774
10775 size_t
10776 number_parameters;
10777
10778 VirtualPixelMethod
10779 virtual_pixel;
10780
10781 if (attribute_flag[0] == 0)
10782 break;
10783 function=UndefinedFunction;
10784 if (attribute_flag[1] != 0)
10785 function=(MagickFunction) argument_list[1].integer_reference;
10786 av=(AV *) argument_list[0].array_reference;
10787 number_parameters=(size_t) av_len(av)+1;
10788 parameters=(double *) AcquireQuantumMemory(number_parameters,
10789 sizeof(*parameters));
10790 if (parameters == (double *) NULL)
10791 {
10792 ThrowPerlException(exception,ResourceLimitFatalError,
10793 "MemoryAllocationFailed",PackageName);
10794 goto PerlException;
10795 }
10796 for (j=0; j < (ssize_t) number_parameters; j++)
10797 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10798 virtual_pixel=UndefinedVirtualPixelMethod;
10799 if (attribute_flag[2] != 0)
10800 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10801 argument_list[2].integer_reference,exception);
10802 (void) FunctionImage(image,function,number_parameters,parameters,
10803 exception);
10804 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10805 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10806 exception);
10807 parameters=(double *) RelinquishMagickMemory(parameters);
10808 break;
10809 }
10810 case 121: /* SelectiveBlur */
10811 {
10812 if (attribute_flag[0] != 0)
10813 {
10814 flags=ParseGeometry(argument_list[0].string_reference,
10815 &geometry_info);
10816 if ((flags & SigmaValue) == 0)
10817 geometry_info.sigma=1.0;
10818 if ((flags & PercentValue) != 0)
10819 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10820 }
10821 if (attribute_flag[1] != 0)
10822 geometry_info.rho=argument_list[1].real_reference;
10823 if (attribute_flag[2] != 0)
10824 geometry_info.sigma=argument_list[2].real_reference;
10825 if (attribute_flag[3] != 0)
10826 geometry_info.xi=argument_list[3].integer_reference;;
10827 if (attribute_flag[5] != 0)
10828 channel=(ChannelType) argument_list[5].integer_reference;
10829 channel_mask=SetImageChannelMask(image,channel);
10830 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10831 geometry_info.xi,exception);
10832 if (image != (Image *) NULL)
10833 (void) SetImageChannelMask(image,channel_mask);
10834 break;
10835 }
10836 case 122: /* HaldClut */
10837 {
10838 if (attribute_flag[0] == 0)
10839 {
10840 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10841 PackageName);
10842 goto PerlException;
10843 }
10844 if (attribute_flag[1] != 0)
10845 channel=(ChannelType) argument_list[1].integer_reference;
10846 channel_mask=SetImageChannelMask(image,channel);
10847 (void) HaldClutImage(image,argument_list[0].image_reference,
10848 exception);
10849 (void) SetImageChannelMask(image,channel_mask);
10850 break;
10851 }
10852 case 123: /* BlueShift */
10853 {
10854 if (attribute_flag[0] != 0)
10855 (void) ParseGeometry(argument_list[0].string_reference,
10856 &geometry_info);
10857 image=BlueShiftImage(image,geometry_info.rho,exception);
10858 break;
10859 }
10860 case 124: /* ForwardFourierTransformImage */
10861 {
10862 image=ForwardFourierTransformImage(image,
10863 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10864 exception);
10865 break;
10866 }
10867 case 125: /* InverseFourierTransformImage */
10868 {
10869 image=InverseFourierTransformImage(image,image->next,
10870 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10871 exception);
10872 break;
10873 }
10874 case 126: /* ColorDecisionList */
10875 {
10876 if (attribute_flag[0] == 0)
10877 argument_list[0].string_reference=(char *) NULL;
10878 (void) ColorDecisionListImage(image,
10879 argument_list[0].string_reference,exception);
10880 break;
10881 }
10882 case 127: /* AutoGamma */
10883 {
10884 if (attribute_flag[0] != 0)
10885 channel=(ChannelType) argument_list[0].integer_reference;
10886 channel_mask=SetImageChannelMask(image,channel);
10887 (void) AutoGammaImage(image,exception);
10888 (void) SetImageChannelMask(image,channel_mask);
10889 break;
10890 }
10891 case 128: /* AutoLevel */
10892 {
10893 if (attribute_flag[0] != 0)
10894 channel=(ChannelType) argument_list[0].integer_reference;
10895 channel_mask=SetImageChannelMask(image,channel);
10896 (void) AutoLevelImage(image,exception);
10897 (void) SetImageChannelMask(image,channel_mask);
10898 break;
10899 }
10900 case 129: /* LevelColors */
10901 {
10902 PixelInfo
10903 black_point,
10904 white_point;
10905
10906 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10907 exception);
10908 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10909 exception);
10910 if (attribute_flag[1] != 0)
10911 (void) QueryColorCompliance(
10912 argument_list[1].string_reference,AllCompliance,&black_point,
10913 exception);
10914 if (attribute_flag[2] != 0)
10915 (void) QueryColorCompliance(
10916 argument_list[2].string_reference,AllCompliance,&white_point,
10917 exception);
10918 if (attribute_flag[3] != 0)
10919 channel=(ChannelType) argument_list[3].integer_reference;
10920 channel_mask=SetImageChannelMask(image,channel);
10921 (void) LevelImageColors(image,&black_point,&white_point,
10922 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10923 exception);
10924 (void) SetImageChannelMask(image,channel_mask);
10925 break;
10926 }
10927 case 130: /* Clamp */
10928 {
10929 if (attribute_flag[0] != 0)
10930 channel=(ChannelType) argument_list[0].integer_reference;
10931 channel_mask=SetImageChannelMask(image,channel);
10932 (void) ClampImage(image,exception);
10933 (void) SetImageChannelMask(image,channel_mask);
10934 break;
10935 }
10936 case 131: /* BrightnessContrast */
10937 {
10938 double
10939 brightness,
10940 contrast;
10941
10942 brightness=0.0;
10943 contrast=0.0;
10944 if (attribute_flag[0] != 0)
10945 {
10946 flags=ParseGeometry(argument_list[0].string_reference,
10947 &geometry_info);
10948 brightness=geometry_info.rho;
10949 if ((flags & SigmaValue) == 0)
10950 contrast=geometry_info.sigma;
10951 }
10952 if (attribute_flag[1] != 0)
10953 brightness=argument_list[1].real_reference;
10954 if (attribute_flag[2] != 0)
10955 contrast=argument_list[2].real_reference;
10956 if (attribute_flag[4] != 0)
10957 channel=(ChannelType) argument_list[4].integer_reference;
10958 channel_mask=SetImageChannelMask(image,channel);
10959 (void) BrightnessContrastImage(image,brightness,contrast,exception);
10960 (void) SetImageChannelMask(image,channel_mask);
10961 break;
10962 }
10963 case 132: /* Morphology */
10964 {
10965 KernelInfo
10966 *kernel;
10967
10968 MorphologyMethod
10969 method;
10970
10971 ssize_t
10972 iterations;
10973
10974 if (attribute_flag[0] == 0)
10975 break;
10976 kernel=AcquireKernelInfo(argument_list[0].string_reference);
10977 if (kernel == (KernelInfo *) NULL)
10978 break;
10979 if (attribute_flag[1] != 0)
10980 channel=(ChannelType) argument_list[1].integer_reference;
10981 method=UndefinedMorphology;
10982 if (attribute_flag[2] != 0)
10983 method=argument_list[2].integer_reference;
10984 iterations=1;
10985 if (attribute_flag[3] != 0)
10986 iterations=argument_list[3].integer_reference;
10987 channel_mask=SetImageChannelMask(image,channel);
10988 image=MorphologyImage(image,method,iterations,kernel,exception);
10989 if (image != (Image *) NULL)
10990 (void) SetImageChannelMask(image,channel_mask);
10991 kernel=DestroyKernelInfo(kernel);
10992 break;
10993 }
10994 case 133: /* Mode */
10995 {
10996 if (attribute_flag[0] != 0)
10997 {
10998 flags=ParseGeometry(argument_list[0].string_reference,
10999 &geometry_info);
11000 if ((flags & SigmaValue) == 0)
11001 geometry_info.sigma=1.0;
11002 }
11003 if (attribute_flag[1] != 0)
11004 geometry_info.rho=argument_list[1].real_reference;
11005 if (attribute_flag[2] != 0)
11006 geometry_info.sigma=argument_list[2].real_reference;
11007 if (attribute_flag[3] != 0)
11008 channel=(ChannelType) argument_list[3].integer_reference;
11009 channel_mask=SetImageChannelMask(image,channel);
11010 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11011 (size_t) geometry_info.sigma,exception);
11012 if (image != (Image *) NULL)
11013 (void) SetImageChannelMask(image,channel_mask);
11014 break;
11015 }
11016 case 134: /* Statistic */
11017 {
11018 StatisticType
11019 statistic;
11020
11021 statistic=UndefinedStatistic;
11022 if (attribute_flag[0] != 0)
11023 {
11024 flags=ParseGeometry(argument_list[0].string_reference,
11025 &geometry_info);
11026 if ((flags & SigmaValue) == 0)
11027 geometry_info.sigma=1.0;
11028 }
11029 if (attribute_flag[1] != 0)
11030 geometry_info.rho=argument_list[1].real_reference;
11031 if (attribute_flag[2] != 0)
11032 geometry_info.sigma=argument_list[2].real_reference;
11033 if (attribute_flag[3] != 0)
11034 channel=(ChannelType) argument_list[3].integer_reference;
11035 if (attribute_flag[4] != 0)
11036 statistic=(StatisticType) argument_list[4].integer_reference;
11037 channel_mask=SetImageChannelMask(image,channel);
11038 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11039 (size_t) geometry_info.sigma,exception);
11040 if (image != (Image *) NULL)
11041 (void) SetImageChannelMask(image,channel_mask);
11042 break;
11043 }
11044 case 135: /* Perceptible */
11045 {
11046 double
11047 epsilon;
11048
11049 epsilon=MagickEpsilon;
11050 if (attribute_flag[0] != 0)
11051 epsilon=argument_list[0].real_reference;
11052 if (attribute_flag[1] != 0)
11053 channel=(ChannelType) argument_list[1].integer_reference;
11054 channel_mask=SetImageChannelMask(image,channel);
11055 (void) PerceptibleImage(image,epsilon,exception);
11056 (void) SetImageChannelMask(image,channel_mask);
11057 break;
11058 }
11059 case 136: /* Poly */
11060 {
11061 AV
11062 *av;
11063
11064 double
11065 *terms;
11066
11067 size_t
11068 number_terms;
11069
11070 if (attribute_flag[0] == 0)
11071 break;
11072 if (attribute_flag[1] != 0)
11073 channel=(ChannelType) argument_list[1].integer_reference;
11074 av=(AV *) argument_list[0].array_reference;
11075 number_terms=(size_t) av_len(av);
11076 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11077 if (terms == (double *) NULL)
11078 {
11079 ThrowPerlException(exception,ResourceLimitFatalError,
11080 "MemoryAllocationFailed",PackageName);
11081 goto PerlException;
11082 }
11083 for (j=0; j < av_len(av); j++)
11084 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11085 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11086 terms=(double *) RelinquishMagickMemory(terms);
11087 break;
11088 }
11089 case 137: /* Grayscale */
11090 {
11091 PixelIntensityMethod
11092 method;
11093
11094 method=UndefinedPixelIntensityMethod;
11095 if (attribute_flag[0] != 0)
11096 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11097 (void) GrayscaleImage(image,method,exception);
11098 break;
11099 }
cristy4ceadb82014-03-29 15:30:43 +000011100 case 138: /* Canny */
11101 {
11102 if (attribute_flag[0] != 0)
11103 {
11104 flags=ParseGeometry(argument_list[0].string_reference,
11105 &geometry_info);
11106 if ((flags & SigmaValue) == 0)
11107 geometry_info.sigma=1.0;
11108 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011109 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011110 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011111 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011112 if ((flags & PercentValue) != 0)
11113 {
11114 geometry_info.xi/=100.0;
11115 geometry_info.psi/=100.0;
11116 }
cristy4ceadb82014-03-29 15:30:43 +000011117 }
11118 if (attribute_flag[1] != 0)
11119 geometry_info.rho=argument_list[1].real_reference;
11120 if (attribute_flag[2] != 0)
11121 geometry_info.sigma=argument_list[2].real_reference;
11122 if (attribute_flag[3] != 0)
11123 geometry_info.xi=argument_list[3].real_reference;
11124 if (attribute_flag[4] != 0)
11125 geometry_info.psi=argument_list[4].real_reference;
11126 if (attribute_flag[5] != 0)
11127 channel=(ChannelType) argument_list[5].integer_reference;
11128 channel_mask=SetImageChannelMask(image,channel);
11129 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11130 geometry_info.xi,geometry_info.psi,exception);
11131 if (image != (Image *) NULL)
11132 (void) SetImageChannelMask(image,channel_mask);
11133 break;
11134 }
cristy4a3ce0a2013-08-03 20:06:59 +000011135 }
11136 if (next != (Image *) NULL)
11137 (void) CatchImageException(next);
11138 if (region_image != (Image *) NULL)
11139 {
11140 /*
11141 Composite region.
cristy83a28a02013-08-03 20:25:48 +000011142 */
cristy4a3ce0a2013-08-03 20:06:59 +000011143 status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11144 region_info.x,region_info.y,exception);
11145 (void) status;
11146 (void) CatchImageException(region_image);
11147 image=DestroyImage(image);
11148 image=region_image;
11149 }
11150 if (image != (Image *) NULL)
11151 {
11152 number_images++;
11153 if (next && (next != image))
11154 {
11155 image->next=next->next;
11156 if (image->next != (Image *) NULL)
11157 image->next->previous=image;
11158 DeleteImageFromRegistry(*pv,next);
11159 }
11160 sv_setiv(*pv,PTR2IV(image));
11161 next=image;
11162 }
11163 if (*pv)
11164 pv++;
11165 }
11166
11167 PerlException:
11168 if (reference_vector)
11169 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11170 InheritPerlException(exception,perl_exception);
11171 exception=DestroyExceptionInfo(exception);
11172 sv_setiv(perl_exception,(IV) number_images);
11173 SvPOK_on(perl_exception);
11174 ST(0)=sv_2mortal(perl_exception);
11175 XSRETURN(1);
11176 }
11177
11178#
11179###############################################################################
11180# #
11181# #
11182# #
11183# M o n t a g e #
11184# #
11185# #
11186# #
11187###############################################################################
11188#
11189#
11190void
11191Montage(ref,...)
11192 Image::Magick ref=NO_INIT
11193 ALIAS:
11194 MontageImage = 1
11195 montage = 2
11196 montageimage = 3
11197 PPCODE:
11198 {
11199 AV
11200 *av;
11201
11202 char
11203 *attribute;
11204
11205 ExceptionInfo
11206 *exception;
11207
11208 HV
11209 *hv;
11210
11211 Image
11212 *image,
11213 *next;
11214
11215 PixelInfo
11216 transparent_color;
11217
11218 MontageInfo
11219 *montage_info;
11220
11221 register ssize_t
11222 i;
11223
11224 ssize_t
11225 sp;
11226
11227 struct PackageInfo
11228 *info;
11229
11230 SV
11231 *av_reference,
11232 *perl_exception,
11233 *reference,
11234 *rv,
11235 *sv;
11236
11237 PERL_UNUSED_VAR(ref);
11238 PERL_UNUSED_VAR(ix);
11239 exception=AcquireExceptionInfo();
11240 perl_exception=newSVpv("",0);
11241 sv=NULL;
11242 attribute=NULL;
11243 if (sv_isobject(ST(0)) == 0)
11244 {
11245 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11246 PackageName);
11247 goto PerlException;
11248 }
11249 reference=SvRV(ST(0));
11250 hv=SvSTASH(reference);
11251 av=newAV();
11252 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11253 SvREFCNT_dec(av);
11254 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11255 if (image == (Image *) NULL)
11256 {
11257 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11258 PackageName);
11259 goto PerlException;
11260 }
11261 /*
11262 Get options.
11263 */
11264 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11265 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11266 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11267 exception);
11268 for (i=2; i < items; i+=2)
11269 {
11270 attribute=(char *) SvPV(ST(i-1),na);
11271 switch (*attribute)
11272 {
11273 case 'B':
11274 case 'b':
11275 {
11276 if (LocaleCompare(attribute,"background") == 0)
11277 {
11278 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11279 &montage_info->background_color,exception);
11280 for (next=image; next; next=next->next)
11281 next->background_color=montage_info->background_color;
11282 break;
11283 }
11284 if (LocaleCompare(attribute,"border") == 0)
11285 {
11286 montage_info->border_width=SvIV(ST(i));
11287 break;
11288 }
11289 if (LocaleCompare(attribute,"bordercolor") == 0)
11290 {
11291 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11292 &montage_info->border_color,exception);
11293 for (next=image; next; next=next->next)
11294 next->border_color=montage_info->border_color;
11295 break;
11296 }
11297 if (LocaleCompare(attribute,"borderwidth") == 0)
11298 {
11299 montage_info->border_width=SvIV(ST(i));
11300 break;
11301 }
11302 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11303 attribute);
11304 break;
11305 }
11306 case 'C':
11307 case 'c':
11308 {
11309 if (LocaleCompare(attribute,"compose") == 0)
11310 {
11311 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11312 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11313 if (sp < 0)
11314 {
11315 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11316 SvPV(ST(i),na));
11317 break;
11318 }
11319 for (next=image; next; next=next->next)
11320 next->compose=(CompositeOperator) sp;
11321 break;
11322 }
11323 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11324 attribute);
11325 break;
11326 }
11327 case 'F':
11328 case 'f':
11329 {
11330 if (LocaleCompare(attribute,"fill") == 0)
11331 {
11332 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11333 &montage_info->fill,exception);
11334 break;
11335 }
11336 if (LocaleCompare(attribute,"font") == 0)
11337 {
11338 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11339 break;
11340 }
11341 if (LocaleCompare(attribute,"frame") == 0)
11342 {
11343 char
11344 *p;
11345
11346 p=SvPV(ST(i),na);
11347 if (IsGeometry(p) == MagickFalse)
11348 {
11349 ThrowPerlException(exception,OptionError,"MissingGeometry",
11350 p);
11351 break;
11352 }
11353 (void) CloneString(&montage_info->frame,p);
11354 if (*p == '\0')
11355 montage_info->frame=(char *) NULL;
11356 break;
11357 }
11358 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11359 attribute);
11360 break;
11361 }
11362 case 'G':
11363 case 'g':
11364 {
11365 if (LocaleCompare(attribute,"geometry") == 0)
11366 {
11367 char
11368 *p;
11369
11370 p=SvPV(ST(i),na);
11371 if (IsGeometry(p) == MagickFalse)
11372 {
11373 ThrowPerlException(exception,OptionError,"MissingGeometry",
11374 p);
11375 break;
11376 }
11377 (void) CloneString(&montage_info->geometry,p);
11378 if (*p == '\0')
11379 montage_info->geometry=(char *) NULL;
11380 break;
11381 }
11382 if (LocaleCompare(attribute,"gravity") == 0)
11383 {
11384 ssize_t
11385 in;
11386
11387 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11388 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11389 if (in < 0)
11390 {
11391 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11392 SvPV(ST(i),na));
11393 return;
11394 }
11395 montage_info->gravity=(GravityType) in;
11396 for (next=image; next; next=next->next)
11397 next->gravity=(GravityType) in;
11398 break;
11399 }
11400 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11401 attribute);
11402 break;
11403 }
11404 case 'L':
11405 case 'l':
11406 {
11407 if (LocaleCompare(attribute,"label") == 0)
11408 {
11409 for (next=image; next; next=next->next)
11410 (void) SetImageProperty(next,"label",InterpretImageProperties(
11411 info ? info->image_info : (ImageInfo *) NULL,next,
11412 SvPV(ST(i),na),exception),exception);
11413 break;
11414 }
11415 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11416 attribute);
11417 break;
11418 }
11419 case 'M':
11420 case 'm':
11421 {
11422 if (LocaleCompare(attribute,"mattecolor") == 0)
11423 {
11424 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11425 &montage_info->matte_color,exception);
11426 for (next=image; next; next=next->next)
11427 next->matte_color=montage_info->matte_color;
11428 break;
11429 }
11430 if (LocaleCompare(attribute,"mode") == 0)
11431 {
11432 ssize_t
11433 in;
11434
11435 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11436 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11437 switch (in)
11438 {
11439 default:
11440 {
11441 ThrowPerlException(exception,OptionError,
11442 "UnrecognizedModeType",SvPV(ST(i),na));
11443 break;
11444 }
11445 case FrameMode:
11446 {
11447 (void) CloneString(&montage_info->frame,"15x15+3+3");
11448 montage_info->shadow=MagickTrue;
11449 break;
11450 }
11451 case UnframeMode:
11452 {
11453 montage_info->frame=(char *) NULL;
11454 montage_info->shadow=MagickFalse;
11455 montage_info->border_width=0;
11456 break;
11457 }
11458 case ConcatenateMode:
11459 {
11460 montage_info->frame=(char *) NULL;
11461 montage_info->shadow=MagickFalse;
11462 (void) CloneString(&montage_info->geometry,"+0+0");
11463 montage_info->border_width=0;
11464 }
11465 }
11466 break;
11467 }
11468 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11469 attribute);
11470 break;
11471 }
11472 case 'P':
11473 case 'p':
11474 {
11475 if (LocaleCompare(attribute,"pointsize") == 0)
11476 {
11477 montage_info->pointsize=SvIV(ST(i));
11478 break;
11479 }
11480 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11481 attribute);
11482 break;
11483 }
11484 case 'S':
11485 case 's':
11486 {
11487 if (LocaleCompare(attribute,"shadow") == 0)
11488 {
11489 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11490 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11491 if (sp < 0)
11492 {
11493 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11494 SvPV(ST(i),na));
11495 break;
11496 }
11497 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11498 break;
11499 }
11500 if (LocaleCompare(attribute,"stroke") == 0)
11501 {
11502 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11503 &montage_info->stroke,exception);
11504 break;
11505 }
11506 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11507 attribute);
11508 break;
11509 }
11510 case 'T':
11511 case 't':
11512 {
11513 if (LocaleCompare(attribute,"texture") == 0)
11514 {
11515 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11516 break;
11517 }
11518 if (LocaleCompare(attribute,"tile") == 0)
11519 {
11520 char *p=SvPV(ST(i),na);
11521 if (IsGeometry(p) == MagickFalse)
11522 {
11523 ThrowPerlException(exception,OptionError,"MissingGeometry",
11524 p);
11525 break;
11526 }
11527 (void) CloneString(&montage_info->tile,p);
11528 if (*p == '\0')
11529 montage_info->tile=(char *) NULL;
11530 break;
11531 }
11532 if (LocaleCompare(attribute,"title") == 0)
11533 {
11534 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11535 break;
11536 }
11537 if (LocaleCompare(attribute,"transparent") == 0)
11538 {
11539 PixelInfo
11540 transparent_color;
11541
11542 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11543 &transparent_color,exception);
11544 for (next=image; next; next=next->next)
11545 (void) TransparentPaintImage(next,&transparent_color,
11546 TransparentAlpha,MagickFalse,exception);
11547 break;
11548 }
11549 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11550 attribute);
11551 break;
11552 }
11553 default:
11554 {
11555 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11556 attribute);
11557 break;
11558 }
11559 }
11560 }
11561 image=MontageImageList(info->image_info,montage_info,image,exception);
11562 montage_info=DestroyMontageInfo(montage_info);
11563 if (image == (Image *) NULL)
11564 goto PerlException;
11565 if (transparent_color.alpha != TransparentAlpha)
11566 for (next=image; next; next=next->next)
11567 (void) TransparentPaintImage(next,&transparent_color,
11568 TransparentAlpha,MagickFalse,exception);
11569 for ( ; image; image=image->next)
11570 {
11571 AddImageToRegistry(sv,image);
11572 rv=newRV(sv);
11573 av_push(av,sv_bless(rv,hv));
11574 SvREFCNT_dec(sv);
11575 }
11576 exception=DestroyExceptionInfo(exception);
11577 ST(0)=av_reference;
11578 SvREFCNT_dec(perl_exception);
11579 XSRETURN(1);
11580
11581 PerlException:
11582 InheritPerlException(exception,perl_exception);
11583 exception=DestroyExceptionInfo(exception);
11584 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11585 SvPOK_on(perl_exception);
11586 ST(0)=sv_2mortal(perl_exception);
11587 XSRETURN(1);
11588 }
11589
11590#
11591###############################################################################
11592# #
11593# #
11594# #
11595# M o r p h #
11596# #
11597# #
11598# #
11599###############################################################################
11600#
11601#
11602void
11603Morph(ref,...)
11604 Image::Magick ref=NO_INIT
11605 ALIAS:
11606 MorphImage = 1
11607 morph = 2
11608 morphimage = 3
11609 PPCODE:
11610 {
11611 AV
11612 *av;
11613
11614 char
11615 *attribute;
11616
11617 ExceptionInfo
11618 *exception;
11619
11620 HV
11621 *hv;
11622
11623 Image
11624 *image;
11625
11626 register ssize_t
11627 i;
11628
11629 ssize_t
11630 number_frames;
11631
11632 struct PackageInfo
11633 *info;
11634
11635 SV
11636 *av_reference,
11637 *perl_exception,
11638 *reference,
11639 *rv,
11640 *sv;
11641
11642 PERL_UNUSED_VAR(ref);
11643 PERL_UNUSED_VAR(ix);
11644 exception=AcquireExceptionInfo();
11645 perl_exception=newSVpv("",0);
11646 sv=NULL;
11647 av=NULL;
11648 attribute=NULL;
11649 if (sv_isobject(ST(0)) == 0)
11650 {
11651 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11652 PackageName);
11653 goto PerlException;
11654 }
11655 reference=SvRV(ST(0));
11656 hv=SvSTASH(reference);
11657 av=newAV();
11658 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11659 SvREFCNT_dec(av);
11660 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11661 if (image == (Image *) NULL)
11662 {
11663 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11664 PackageName);
11665 goto PerlException;
11666 }
11667 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11668 /*
11669 Get attribute.
11670 */
11671 number_frames=30;
11672 for (i=2; i < items; i+=2)
11673 {
11674 attribute=(char *) SvPV(ST(i-1),na);
11675 switch (*attribute)
11676 {
11677 case 'F':
11678 case 'f':
11679 {
11680 if (LocaleCompare(attribute,"frames") == 0)
11681 {
11682 number_frames=SvIV(ST(i));
11683 break;
11684 }
11685 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11686 attribute);
11687 break;
11688 }
11689 default:
11690 {
11691 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11692 attribute);
11693 break;
11694 }
11695 }
11696 }
11697 image=MorphImages(image,number_frames,exception);
11698 if (image == (Image *) NULL)
11699 goto PerlException;
11700 for ( ; image; image=image->next)
11701 {
11702 AddImageToRegistry(sv,image);
11703 rv=newRV(sv);
11704 av_push(av,sv_bless(rv,hv));
11705 SvREFCNT_dec(sv);
11706 }
11707 exception=DestroyExceptionInfo(exception);
11708 ST(0)=av_reference;
11709 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11710 XSRETURN(1);
11711
11712 PerlException:
11713 InheritPerlException(exception,perl_exception);
11714 exception=DestroyExceptionInfo(exception);
11715 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11716 SvPOK_on(perl_exception);
11717 ST(0)=sv_2mortal(perl_exception);
11718 XSRETURN(1);
11719 }
11720
11721#
11722###############################################################################
11723# #
11724# #
11725# #
11726# M o s a i c #
11727# #
11728# #
11729# #
11730###############################################################################
11731#
11732#
11733void
11734Mosaic(ref)
11735 Image::Magick ref=NO_INIT
11736 ALIAS:
11737 MosaicImage = 1
11738 mosaic = 2
11739 mosaicimage = 3
11740 PPCODE:
11741 {
11742 AV
11743 *av;
11744
11745 ExceptionInfo
11746 *exception;
11747
11748 HV
11749 *hv;
11750
11751 Image
11752 *image;
11753
11754 struct PackageInfo
11755 *info;
11756
11757 SV
11758 *perl_exception,
11759 *reference,
11760 *rv,
11761 *sv;
11762
11763 PERL_UNUSED_VAR(ref);
11764 PERL_UNUSED_VAR(ix);
11765 exception=AcquireExceptionInfo();
11766 perl_exception=newSVpv("",0);
11767 sv=NULL;
11768 if (sv_isobject(ST(0)) == 0)
11769 {
11770 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11771 PackageName);
11772 goto PerlException;
11773 }
11774 reference=SvRV(ST(0));
11775 hv=SvSTASH(reference);
11776 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11777 if (image == (Image *) NULL)
11778 {
11779 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11780 PackageName);
11781 goto PerlException;
11782 }
11783 image=MergeImageLayers(image,MosaicLayer,exception);
11784 /*
11785 Create blessed Perl array for the returned image.
11786 */
11787 av=newAV();
11788 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11789 SvREFCNT_dec(av);
11790 AddImageToRegistry(sv,image);
11791 rv=newRV(sv);
11792 av_push(av,sv_bless(rv,hv));
11793 SvREFCNT_dec(sv);
11794 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11795 (void) CopyMagickString(info->image_info->filename,image->filename,
11796 MaxTextExtent);
11797 SetImageInfo(info->image_info,0,exception);
11798 exception=DestroyExceptionInfo(exception);
11799 SvREFCNT_dec(perl_exception);
11800 XSRETURN(1);
11801
11802 PerlException:
11803 InheritPerlException(exception,perl_exception);
11804 exception=DestroyExceptionInfo(exception);
11805 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11806 SvPOK_on(perl_exception); /* return messages in string context */
11807 ST(0)=sv_2mortal(perl_exception);
11808 XSRETURN(1);
11809 }
11810
11811#
11812###############################################################################
11813# #
11814# #
11815# #
11816# P i n g #
11817# #
11818# #
11819# #
11820###############################################################################
11821#
11822#
11823void
11824Ping(ref,...)
11825 Image::Magick ref=NO_INIT
11826 ALIAS:
11827 PingImage = 1
11828 ping = 2
11829 pingimage = 3
11830 PPCODE:
11831 {
11832 AV
11833 *av;
11834
11835 char
11836 **keep,
11837 **list;
11838
11839 ExceptionInfo
11840 *exception;
11841
11842 Image
11843 *image,
11844 *next;
11845
11846 int
11847 n;
11848
11849 MagickBooleanType
11850 status;
11851
11852 register char
11853 **p;
11854
11855 register ssize_t
11856 i;
11857
11858 ssize_t
11859 ac;
11860
11861 STRLEN
11862 *length;
11863
11864 struct PackageInfo
11865 *info,
11866 *package_info;
11867
11868 SV
11869 *perl_exception,
11870 *reference;
11871
11872 size_t
11873 count;
11874
11875 PERL_UNUSED_VAR(ref);
11876 PERL_UNUSED_VAR(ix);
11877 exception=AcquireExceptionInfo();
11878 perl_exception=newSVpv("",0);
11879 package_info=(struct PackageInfo *) NULL;
11880 ac=(items < 2) ? 1 : items-1;
11881 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
11882 keep=list;
11883 length=(STRLEN *) NULL;
11884 if (list == (char **) NULL)
11885 {
11886 ThrowPerlException(exception,ResourceLimitError,
11887 "MemoryAllocationFailed",PackageName);
11888 goto PerlException;
11889 }
11890 keep=list;
11891 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
11892 if (length == (STRLEN *) NULL)
11893 {
11894 ThrowPerlException(exception,ResourceLimitError,
11895 "MemoryAllocationFailed",PackageName);
11896 goto PerlException;
11897 }
11898 if (sv_isobject(ST(0)) == 0)
11899 {
11900 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11901 PackageName);
11902 goto PerlException;
11903 }
11904 reference=SvRV(ST(0));
11905 if (SvTYPE(reference) != SVt_PVAV)
11906 {
11907 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11908 PackageName);
11909 goto PerlException;
11910 }
11911 av=(AV *) reference;
11912 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11913 exception);
11914 package_info=ClonePackageInfo(info,exception);
11915 n=1;
11916 if (items <= 1)
11917 *list=(char *) (*package_info->image_info->filename ?
11918 package_info->image_info->filename : "XC:black");
11919 else
11920 for (n=0, i=0; i < ac; i++)
11921 {
11922 list[n]=(char *) SvPV(ST(i+1),length[n]);
11923 if ((items >= 3) && strEQcase(list[n],"blob"))
11924 {
11925 void
11926 *blob;
11927
11928 i++;
11929 blob=(void *) (SvPV(ST(i+1),length[n]));
11930 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
11931 }
11932 if ((items >= 3) && strEQcase(list[n],"filename"))
11933 continue;
11934 if ((items >= 3) && strEQcase(list[n],"file"))
11935 {
11936 FILE
11937 *file;
11938
11939 PerlIO
11940 *io_info;
11941
11942 i++;
11943 io_info=IoIFP(sv_2io(ST(i+1)));
11944 if (io_info == (PerlIO *) NULL)
11945 {
11946 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
11947 PackageName);
11948 continue;
11949 }
11950 file=PerlIO_findFILE(io_info);
11951 if (file == (FILE *) NULL)
11952 {
11953 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
11954 PackageName);
11955 continue;
11956 }
11957 SetImageInfoFile(package_info->image_info,file);
11958 }
11959 if ((items >= 3) && strEQcase(list[n],"magick"))
11960 continue;
11961 n++;
11962 }
11963 list[n]=(char *) NULL;
11964 keep=list;
11965 status=ExpandFilenames(&n,&list);
11966 if (status == MagickFalse)
11967 {
11968 ThrowPerlException(exception,ResourceLimitError,
11969 "MemoryAllocationFailed",PackageName);
11970 goto PerlException;
11971 }
11972 count=0;
11973 for (i=0; i < n; i++)
11974 {
11975 (void) CopyMagickString(package_info->image_info->filename,list[i],
11976 MaxTextExtent);
11977 image=PingImage(package_info->image_info,exception);
11978 if (image == (Image *) NULL)
11979 break;
11980 if ((package_info->image_info->file != (FILE *) NULL) ||
11981 (package_info->image_info->blob != (void *) NULL))
11982 DisassociateImageStream(image);
11983 count+=GetImageListLength(image);
11984 EXTEND(sp,4*count);
11985 for (next=image; next; next=next->next)
11986 {
11987 PUSHs(sv_2mortal(newSViv(next->columns)));
11988 PUSHs(sv_2mortal(newSViv(next->rows)));
11989 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
11990 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
11991 }
11992 image=DestroyImageList(image);
11993 }
11994 /*
11995 Free resources.
11996 */
11997 for (i=0; i < n; i++)
11998 if (list[i] != (char *) NULL)
11999 for (p=keep; list[i] != *p++; )
12000 if (*p == NULL)
12001 {
12002 list[i]=(char *) RelinquishMagickMemory(list[i]);
12003 break;
12004 }
12005
12006 PerlException:
12007 if (package_info != (struct PackageInfo *) NULL)
12008 DestroyPackageInfo(package_info);
12009 if (list && (list != keep))
12010 list=(char **) RelinquishMagickMemory(list);
12011 if (keep)
12012 keep=(char **) RelinquishMagickMemory(keep);
12013 if (length)
12014 length=(STRLEN *) RelinquishMagickMemory(length);
12015 InheritPerlException(exception,perl_exception);
12016 exception=DestroyExceptionInfo(exception);
12017 SvREFCNT_dec(perl_exception); /* throw away all errors */
12018 }
12019
12020#
12021###############################################################################
12022# #
12023# #
12024# #
12025# P r e v i e w #
12026# #
12027# #
12028# #
12029###############################################################################
12030#
12031#
12032void
12033Preview(ref,...)
12034 Image::Magick ref=NO_INIT
12035 ALIAS:
12036 PreviewImage = 1
12037 preview = 2
12038 previewimage = 3
12039 PPCODE:
12040 {
12041 AV
12042 *av;
12043
12044 ExceptionInfo
12045 *exception;
12046
12047 HV
12048 *hv;
12049
12050 Image
12051 *image,
12052 *preview_image;
12053
12054 PreviewType
12055 preview_type;
12056
12057 struct PackageInfo
12058 *info;
12059
12060 SV
12061 *av_reference,
12062 *perl_exception,
12063 *reference,
12064 *rv,
12065 *sv;
12066
12067 PERL_UNUSED_VAR(ref);
12068 PERL_UNUSED_VAR(ix);
12069 exception=AcquireExceptionInfo();
12070 perl_exception=newSVpv("",0);
12071 sv=NULL;
12072 av=NULL;
12073 if (sv_isobject(ST(0)) == 0)
12074 {
12075 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12076 PackageName);
12077 goto PerlException;
12078 }
12079 reference=SvRV(ST(0));
12080 hv=SvSTASH(reference);
12081 av=newAV();
12082 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12083 SvREFCNT_dec(av);
12084 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12085 if (image == (Image *) NULL)
12086 {
12087 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12088 PackageName);
12089 goto PerlException;
12090 }
12091 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12092 preview_type=GammaPreview;
12093 if (items > 1)
12094 preview_type=(PreviewType)
12095 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12096 for ( ; image; image=image->next)
12097 {
12098 preview_image=PreviewImage(image,preview_type,exception);
12099 if (preview_image == (Image *) NULL)
12100 goto PerlException;
12101 AddImageToRegistry(sv,preview_image);
12102 rv=newRV(sv);
12103 av_push(av,sv_bless(rv,hv));
12104 SvREFCNT_dec(sv);
12105 }
12106 exception=DestroyExceptionInfo(exception);
12107 ST(0)=av_reference;
12108 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12109 XSRETURN(1);
12110
12111 PerlException:
12112 InheritPerlException(exception,perl_exception);
12113 exception=DestroyExceptionInfo(exception);
12114 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12115 SvPOK_on(perl_exception);
12116 ST(0)=sv_2mortal(perl_exception);
12117 XSRETURN(1);
12118 }
12119
12120#
12121###############################################################################
12122# #
12123# #
12124# #
12125# Q u e r y C o l o r #
12126# #
12127# #
12128# #
12129###############################################################################
12130#
12131#
12132void
12133QueryColor(ref,...)
12134 Image::Magick ref=NO_INIT
12135 ALIAS:
12136 querycolor = 1
12137 PPCODE:
12138 {
12139 char
12140 *name;
12141
12142 ExceptionInfo
12143 *exception;
12144
12145 PixelInfo
12146 color;
12147
12148 register ssize_t
12149 i;
12150
12151 SV
12152 *perl_exception;
12153
12154 PERL_UNUSED_VAR(ref);
12155 PERL_UNUSED_VAR(ix);
12156 exception=AcquireExceptionInfo();
12157 perl_exception=newSVpv("",0);
12158 if (items == 1)
12159 {
12160 const ColorInfo
12161 **colorlist;
12162
12163 size_t
12164 colors;
12165
12166 colorlist=GetColorInfoList("*",&colors,exception);
12167 EXTEND(sp,colors);
12168 for (i=0; i < (ssize_t) colors; i++)
12169 {
12170 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12171 }
12172 colorlist=(const ColorInfo **)
12173 RelinquishMagickMemory((ColorInfo **) colorlist);
12174 goto PerlException;
12175 }
12176 EXTEND(sp,5*items);
12177 for (i=1; i < items; i++)
12178 {
12179 name=(char *) SvPV(ST(i),na);
12180 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12181 {
12182 PUSHs(&sv_undef);
12183 continue;
12184 }
12185 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12186 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12187 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12188 if (color.colorspace == CMYKColorspace)
12189 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
12190 if (color.alpha_trait == BlendPixelTrait)
12191 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12192 }
12193
12194 PerlException:
12195 InheritPerlException(exception,perl_exception);
12196 exception=DestroyExceptionInfo(exception);
12197 SvREFCNT_dec(perl_exception);
12198 }
12199
12200#
12201###############################################################################
12202# #
12203# #
12204# #
12205# Q u e r y C o l o r N a m e #
12206# #
12207# #
12208# #
12209###############################################################################
12210#
12211#
12212void
12213QueryColorname(ref,...)
12214 Image::Magick ref=NO_INIT
12215 ALIAS:
12216 querycolorname = 1
12217 PPCODE:
12218 {
12219 AV
12220 *av;
12221
12222 char
12223 message[MaxTextExtent];
12224
12225 ExceptionInfo
12226 *exception;
12227
12228 Image
12229 *image;
12230
12231 PixelInfo
12232 target_color;
12233
12234 register ssize_t
12235 i;
12236
12237 struct PackageInfo
12238 *info;
12239
12240 SV
12241 *perl_exception,
12242 *reference; /* reference is the SV* of ref=SvIV(reference) */
12243
12244 PERL_UNUSED_VAR(ref);
12245 PERL_UNUSED_VAR(ix);
12246 exception=AcquireExceptionInfo();
12247 perl_exception=newSVpv("",0);
12248 reference=SvRV(ST(0));
12249 av=(AV *) reference;
12250 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12251 exception);
12252 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12253 if (image == (Image *) NULL)
12254 {
12255 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12256 PackageName);
12257 goto PerlException;
12258 }
12259 EXTEND(sp,items);
12260 for (i=1; i < items; i++)
12261 {
12262 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12263 exception);
12264 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12265 exception);
12266 PUSHs(sv_2mortal(newSVpv(message,0)));
12267 }
12268
12269 PerlException:
12270 InheritPerlException(exception,perl_exception);
12271 exception=DestroyExceptionInfo(exception);
12272 SvREFCNT_dec(perl_exception);
12273 }
12274
12275#
12276###############################################################################
12277# #
12278# #
12279# #
12280# Q u e r y F o n t #
12281# #
12282# #
12283# #
12284###############################################################################
12285#
12286#
12287void
12288QueryFont(ref,...)
12289 Image::Magick ref=NO_INIT
12290 ALIAS:
12291 queryfont = 1
12292 PPCODE:
12293 {
12294 char
12295 *name,
12296 message[MaxTextExtent];
12297
12298 ExceptionInfo
12299 *exception;
12300
12301 register ssize_t
12302 i;
12303
12304 SV
12305 *perl_exception;
12306
12307 volatile const TypeInfo
12308 *type_info;
12309
12310 PERL_UNUSED_VAR(ref);
12311 PERL_UNUSED_VAR(ix);
12312 exception=AcquireExceptionInfo();
12313 perl_exception=newSVpv("",0);
12314 if (items == 1)
12315 {
12316 const TypeInfo
12317 **typelist;
12318
12319 size_t
12320 types;
12321
12322 typelist=GetTypeInfoList("*",&types,exception);
12323 EXTEND(sp,types);
12324 for (i=0; i < (ssize_t) types; i++)
12325 {
12326 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12327 }
12328 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12329 typelist);
12330 goto PerlException;
12331 }
12332 EXTEND(sp,10*items);
12333 for (i=1; i < items; i++)
12334 {
12335 name=(char *) SvPV(ST(i),na);
12336 type_info=GetTypeInfo(name,exception);
12337 if (type_info == (TypeInfo *) NULL)
12338 {
12339 PUSHs(&sv_undef);
12340 continue;
12341 }
12342 if (type_info->name == (char *) NULL)
12343 PUSHs(&sv_undef);
12344 else
12345 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12346 if (type_info->description == (char *) NULL)
12347 PUSHs(&sv_undef);
12348 else
12349 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12350 if (type_info->family == (char *) NULL)
12351 PUSHs(&sv_undef);
12352 else
12353 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12354 if (type_info->style == UndefinedStyle)
12355 PUSHs(&sv_undef);
12356 else
12357 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12358 type_info->style),0)));
12359 if (type_info->stretch == UndefinedStretch)
12360 PUSHs(&sv_undef);
12361 else
12362 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12363 type_info->stretch),0)));
12364 (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double)
12365 type_info->weight);
12366 PUSHs(sv_2mortal(newSVpv(message,0)));
12367 if (type_info->encoding == (char *) NULL)
12368 PUSHs(&sv_undef);
12369 else
12370 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12371 if (type_info->foundry == (char *) NULL)
12372 PUSHs(&sv_undef);
12373 else
12374 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12375 if (type_info->format == (char *) NULL)
12376 PUSHs(&sv_undef);
12377 else
12378 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12379 if (type_info->metrics == (char *) NULL)
12380 PUSHs(&sv_undef);
12381 else
12382 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12383 if (type_info->glyphs == (char *) NULL)
12384 PUSHs(&sv_undef);
12385 else
12386 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12387 }
12388
12389 PerlException:
12390 InheritPerlException(exception,perl_exception);
12391 exception=DestroyExceptionInfo(exception);
12392 SvREFCNT_dec(perl_exception);
12393 }
12394
12395#
12396###############################################################################
12397# #
12398# #
12399# #
12400# Q u e r y F o n t M e t r i c s #
12401# #
12402# #
12403# #
12404###############################################################################
12405#
12406#
12407void
12408QueryFontMetrics(ref,...)
12409 Image::Magick ref=NO_INIT
12410 ALIAS:
12411 queryfontmetrics = 1
12412 PPCODE:
12413 {
12414 AffineMatrix
12415 affine,
12416 current;
12417
12418 AV
12419 *av;
12420
12421 char
12422 *attribute;
12423
12424 double
12425 x,
12426 y;
12427
12428 DrawInfo
12429 *draw_info;
12430
12431 ExceptionInfo
12432 *exception;
12433
12434 GeometryInfo
12435 geometry_info;
12436
12437 Image
12438 *image;
12439
12440 MagickBooleanType
12441 status;
12442
12443 MagickStatusType
12444 flags;
12445
12446 register ssize_t
12447 i;
12448
12449 ssize_t
12450 type;
12451
12452 struct PackageInfo
12453 *info,
12454 *package_info;
12455
12456 SV
12457 *perl_exception,
12458 *reference; /* reference is the SV* of ref=SvIV(reference) */
12459
12460 TypeMetric
12461 metrics;
12462
12463 PERL_UNUSED_VAR(ref);
12464 PERL_UNUSED_VAR(ix);
12465 exception=AcquireExceptionInfo();
12466 package_info=(struct PackageInfo *) NULL;
12467 perl_exception=newSVpv("",0);
12468 reference=SvRV(ST(0));
12469 av=(AV *) reference;
12470 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12471 exception);
12472 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12473 if (image == (Image *) NULL)
12474 {
12475 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12476 PackageName);
12477 goto PerlException;
12478 }
12479 package_info=ClonePackageInfo(info,exception);
12480 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12481 CloneString(&draw_info->text,"");
12482 current=draw_info->affine;
12483 GetAffineMatrix(&affine);
12484 x=0.0;
12485 y=0.0;
12486 EXTEND(sp,7*items);
12487 for (i=2; i < items; i+=2)
12488 {
12489 attribute=(char *) SvPV(ST(i-1),na);
12490 switch (*attribute)
12491 {
12492 case 'A':
12493 case 'a':
12494 {
12495 if (LocaleCompare(attribute,"antialias") == 0)
12496 {
12497 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12498 SvPV(ST(i),na));
12499 if (type < 0)
12500 {
12501 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12502 SvPV(ST(i),na));
12503 break;
12504 }
12505 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12506 break;
12507 }
12508 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12509 attribute);
12510 break;
12511 }
12512 case 'd':
12513 case 'D':
12514 {
12515 if (LocaleCompare(attribute,"density") == 0)
12516 {
12517 CloneString(&draw_info->density,SvPV(ST(i),na));
12518 break;
12519 }
12520 if (LocaleCompare(attribute,"direction") == 0)
12521 {
12522 draw_info->direction=(DirectionType) ParseCommandOption(
12523 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12524 break;
12525 }
12526 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12527 attribute);
12528 break;
12529 }
12530 case 'e':
12531 case 'E':
12532 {
12533 if (LocaleCompare(attribute,"encoding") == 0)
12534 {
12535 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12536 break;
12537 }
12538 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12539 attribute);
12540 break;
12541 }
12542 case 'f':
12543 case 'F':
12544 {
12545 if (LocaleCompare(attribute,"family") == 0)
12546 {
12547 CloneString(&draw_info->family,SvPV(ST(i),na));
12548 break;
12549 }
12550 if (LocaleCompare(attribute,"fill") == 0)
12551 {
12552 if (info)
12553 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12554 &draw_info->fill,exception);
12555 break;
12556 }
12557 if (LocaleCompare(attribute,"font") == 0)
12558 {
12559 CloneString(&draw_info->font,SvPV(ST(i),na));
12560 break;
12561 }
12562 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12563 attribute);
12564 break;
12565 }
12566 case 'g':
12567 case 'G':
12568 {
12569 if (LocaleCompare(attribute,"geometry") == 0)
12570 {
12571 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12572 break;
12573 }
12574 if (LocaleCompare(attribute,"gravity") == 0)
12575 {
12576 draw_info->gravity=(GravityType) ParseCommandOption(
12577 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12578 break;
12579 }
12580 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12581 attribute);
12582 break;
12583 }
12584 case 'i':
12585 case 'I':
12586 {
12587 if (LocaleCompare(attribute,"interline-spacing") == 0)
12588 {
12589 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12590 draw_info->interline_spacing=geometry_info.rho;
12591 break;
12592 }
12593 if (LocaleCompare(attribute,"interword-spacing") == 0)
12594 {
12595 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12596 draw_info->interword_spacing=geometry_info.rho;
12597 break;
12598 }
12599 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12600 attribute);
12601 break;
12602 }
12603 case 'k':
12604 case 'K':
12605 {
12606 if (LocaleCompare(attribute,"kerning") == 0)
12607 {
12608 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12609 draw_info->kerning=geometry_info.rho;
12610 break;
12611 }
12612 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12613 attribute);
12614 break;
12615 }
12616 case 'p':
12617 case 'P':
12618 {
12619 if (LocaleCompare(attribute,"pointsize") == 0)
12620 {
12621 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12622 draw_info->pointsize=geometry_info.rho;
12623 break;
12624 }
12625 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12626 attribute);
12627 break;
12628 }
12629 case 'r':
12630 case 'R':
12631 {
12632 if (LocaleCompare(attribute,"rotate") == 0)
12633 {
12634 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12635 affine.rx=geometry_info.rho;
12636 affine.ry=geometry_info.sigma;
12637 if ((flags & SigmaValue) == 0)
12638 affine.ry=affine.rx;
12639 break;
12640 }
12641 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12642 attribute);
12643 break;
12644 }
12645 case 's':
12646 case 'S':
12647 {
12648 if (LocaleCompare(attribute,"scale") == 0)
12649 {
12650 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12651 affine.sx=geometry_info.rho;
12652 affine.sy=geometry_info.sigma;
12653 if ((flags & SigmaValue) == 0)
12654 affine.sy=affine.sx;
12655 break;
12656 }
12657 if (LocaleCompare(attribute,"skew") == 0)
12658 {
12659 double
12660 x_angle,
12661 y_angle;
12662
12663 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12664 x_angle=geometry_info.rho;
12665 y_angle=geometry_info.sigma;
12666 if ((flags & SigmaValue) == 0)
12667 y_angle=x_angle;
12668 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12669 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12670 break;
12671 }
12672 if (LocaleCompare(attribute,"stroke") == 0)
12673 {
12674 if (info)
12675 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12676 &draw_info->stroke,exception);
12677 break;
12678 }
12679 if (LocaleCompare(attribute,"style") == 0)
12680 {
12681 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12682 SvPV(ST(i),na));
12683 if (type < 0)
12684 {
12685 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12686 SvPV(ST(i),na));
12687 break;
12688 }
12689 draw_info->style=(StyleType) type;
12690 break;
12691 }
12692 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12693 attribute);
12694 break;
12695 }
12696 case 't':
12697 case 'T':
12698 {
12699 if (LocaleCompare(attribute,"text") == 0)
12700 {
12701 CloneString(&draw_info->text,SvPV(ST(i),na));
12702 break;
12703 }
12704 if (LocaleCompare(attribute,"translate") == 0)
12705 {
12706 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12707 affine.tx=geometry_info.rho;
12708 affine.ty=geometry_info.sigma;
12709 if ((flags & SigmaValue) == 0)
12710 affine.ty=affine.tx;
12711 break;
12712 }
12713 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12714 attribute);
12715 break;
12716 }
12717 case 'w':
12718 case 'W':
12719 {
12720 if (LocaleCompare(attribute,"weight") == 0)
12721 {
12722 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12723 draw_info->weight=(size_t) geometry_info.rho;
12724 break;
12725 }
12726 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12727 attribute);
12728 break;
12729 }
12730 case 'x':
12731 case 'X':
12732 {
12733 if (LocaleCompare(attribute,"x") == 0)
12734 {
12735 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12736 x=geometry_info.rho;
12737 break;
12738 }
12739 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12740 attribute);
12741 break;
12742 }
12743 case 'y':
12744 case 'Y':
12745 {
12746 if (LocaleCompare(attribute,"y") == 0)
12747 {
12748 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12749 y=geometry_info.rho;
12750 break;
12751 }
12752 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12753 attribute);
12754 break;
12755 }
12756 default:
12757 {
12758 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12759 attribute);
12760 break;
12761 }
12762 }
12763 }
12764 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12765 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12766 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12767 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12768 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12769 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12770 if (draw_info->geometry == (char *) NULL)
12771 {
12772 draw_info->geometry=AcquireString((char *) NULL);
12773 (void) FormatLocaleString(draw_info->geometry,MaxTextExtent,
12774 "%.15g,%.15g",x,y);
12775 }
12776 status=GetTypeMetrics(image,draw_info,&metrics,exception);
12777 (void) CatchImageException(image);
12778 if (status == MagickFalse)
12779 PUSHs(&sv_undef);
12780 else
12781 {
12782 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12783 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12784 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12785 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12786 PUSHs(sv_2mortal(newSVnv(metrics.width)));
12787 PUSHs(sv_2mortal(newSVnv(metrics.height)));
12788 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12789 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
12790 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
12791 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
12792 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
12793 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
12794 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
12795 }
12796 draw_info=DestroyDrawInfo(draw_info);
12797
12798 PerlException:
12799 if (package_info != (struct PackageInfo *) NULL)
12800 DestroyPackageInfo(package_info);
12801 InheritPerlException(exception,perl_exception);
12802 exception=DestroyExceptionInfo(exception);
12803 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12804 }
12805
12806#
12807###############################################################################
12808# #
12809# #
12810# #
12811# 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 #
12812# #
12813# #
12814# #
12815###############################################################################
12816#
12817#
12818void
12819QueryMultilineFontMetrics(ref,...)
12820 Image::Magick ref=NO_INIT
12821 ALIAS:
12822 querymultilinefontmetrics = 1
12823 PPCODE:
12824 {
12825 AffineMatrix
12826 affine,
12827 current;
12828
12829 AV
12830 *av;
12831
12832 char
12833 *attribute;
12834
12835 double
12836 x,
12837 y;
12838
12839 DrawInfo
12840 *draw_info;
12841
12842 ExceptionInfo
12843 *exception;
12844
12845 GeometryInfo
12846 geometry_info;
12847
12848 Image
12849 *image;
12850
12851 MagickBooleanType
12852 status;
12853
12854 MagickStatusType
12855 flags;
12856
12857 register ssize_t
12858 i;
12859
12860 ssize_t
12861 type;
12862
12863 struct PackageInfo
12864 *info,
12865 *package_info;
12866
12867 SV
12868 *perl_exception,
12869 *reference; /* reference is the SV* of ref=SvIV(reference) */
12870
12871 TypeMetric
12872 metrics;
12873
12874 PERL_UNUSED_VAR(ref);
12875 PERL_UNUSED_VAR(ix);
12876 exception=AcquireExceptionInfo();
12877 package_info=(struct PackageInfo *) NULL;
12878 perl_exception=newSVpv("",0);
12879 reference=SvRV(ST(0));
12880 av=(AV *) reference;
12881 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12882 exception);
12883 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12884 if (image == (Image *) NULL)
12885 {
12886 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12887 PackageName);
12888 goto PerlException;
12889 }
12890 package_info=ClonePackageInfo(info,exception);
12891 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12892 CloneString(&draw_info->text,"");
12893 current=draw_info->affine;
12894 GetAffineMatrix(&affine);
12895 x=0.0;
12896 y=0.0;
12897 EXTEND(sp,7*items);
12898 for (i=2; i < items; i+=2)
12899 {
12900 attribute=(char *) SvPV(ST(i-1),na);
12901 switch (*attribute)
12902 {
12903 case 'A':
12904 case 'a':
12905 {
12906 if (LocaleCompare(attribute,"antialias") == 0)
12907 {
12908 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12909 SvPV(ST(i),na));
12910 if (type < 0)
12911 {
12912 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12913 SvPV(ST(i),na));
12914 break;
12915 }
12916 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12917 break;
12918 }
12919 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12920 attribute);
12921 break;
12922 }
12923 case 'd':
12924 case 'D':
12925 {
12926 if (LocaleCompare(attribute,"density") == 0)
12927 {
12928 CloneString(&draw_info->density,SvPV(ST(i),na));
12929 break;
12930 }
12931 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12932 attribute);
12933 break;
12934 }
12935 case 'e':
12936 case 'E':
12937 {
12938 if (LocaleCompare(attribute,"encoding") == 0)
12939 {
12940 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12941 break;
12942 }
12943 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12944 attribute);
12945 break;
12946 }
12947 case 'f':
12948 case 'F':
12949 {
12950 if (LocaleCompare(attribute,"family") == 0)
12951 {
12952 CloneString(&draw_info->family,SvPV(ST(i),na));
12953 break;
12954 }
12955 if (LocaleCompare(attribute,"fill") == 0)
12956 {
12957 if (info)
12958 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12959 &draw_info->fill,exception);
12960 break;
12961 }
12962 if (LocaleCompare(attribute,"font") == 0)
12963 {
12964 CloneString(&draw_info->font,SvPV(ST(i),na));
12965 break;
12966 }
12967 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12968 attribute);
12969 break;
12970 }
12971 case 'g':
12972 case 'G':
12973 {
12974 if (LocaleCompare(attribute,"geometry") == 0)
12975 {
12976 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12977 break;
12978 }
12979 if (LocaleCompare(attribute,"gravity") == 0)
12980 {
12981 draw_info->gravity=(GravityType) ParseCommandOption(
12982 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12983 break;
12984 }
12985 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12986 attribute);
12987 break;
12988 }
12989 case 'p':
12990 case 'P':
12991 {
12992 if (LocaleCompare(attribute,"pointsize") == 0)
12993 {
12994 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12995 draw_info->pointsize=geometry_info.rho;
12996 break;
12997 }
12998 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12999 attribute);
13000 break;
13001 }
13002 case 'r':
13003 case 'R':
13004 {
13005 if (LocaleCompare(attribute,"rotate") == 0)
13006 {
13007 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13008 affine.rx=geometry_info.rho;
13009 affine.ry=geometry_info.sigma;
13010 if ((flags & SigmaValue) == 0)
13011 affine.ry=affine.rx;
13012 break;
13013 }
13014 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13015 attribute);
13016 break;
13017 }
13018 case 's':
13019 case 'S':
13020 {
13021 if (LocaleCompare(attribute,"scale") == 0)
13022 {
13023 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13024 affine.sx=geometry_info.rho;
13025 affine.sy=geometry_info.sigma;
13026 if ((flags & SigmaValue) == 0)
13027 affine.sy=affine.sx;
13028 break;
13029 }
13030 if (LocaleCompare(attribute,"skew") == 0)
13031 {
13032 double
13033 x_angle,
13034 y_angle;
13035
13036 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13037 x_angle=geometry_info.rho;
13038 y_angle=geometry_info.sigma;
13039 if ((flags & SigmaValue) == 0)
13040 y_angle=x_angle;
13041 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13042 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13043 break;
13044 }
13045 if (LocaleCompare(attribute,"stroke") == 0)
13046 {
13047 if (info)
13048 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13049 &draw_info->stroke,exception);
13050 break;
13051 }
13052 if (LocaleCompare(attribute,"style") == 0)
13053 {
13054 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13055 SvPV(ST(i),na));
13056 if (type < 0)
13057 {
13058 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13059 SvPV(ST(i),na));
13060 break;
13061 }
13062 draw_info->style=(StyleType) type;
13063 break;
13064 }
13065 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13066 attribute);
13067 break;
13068 }
13069 case 't':
13070 case 'T':
13071 {
13072 if (LocaleCompare(attribute,"text") == 0)
13073 {
13074 CloneString(&draw_info->text,SvPV(ST(i),na));
13075 break;
13076 }
13077 if (LocaleCompare(attribute,"translate") == 0)
13078 {
13079 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13080 affine.tx=geometry_info.rho;
13081 affine.ty=geometry_info.sigma;
13082 if ((flags & SigmaValue) == 0)
13083 affine.ty=affine.tx;
13084 break;
13085 }
13086 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13087 attribute);
13088 break;
13089 }
13090 case 'w':
13091 case 'W':
13092 {
13093 if (LocaleCompare(attribute,"weight") == 0)
13094 {
13095 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13096 draw_info->weight=(size_t) geometry_info.rho;
13097 break;
13098 }
13099 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13100 attribute);
13101 break;
13102 }
13103 case 'x':
13104 case 'X':
13105 {
13106 if (LocaleCompare(attribute,"x") == 0)
13107 {
13108 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13109 x=geometry_info.rho;
13110 break;
13111 }
13112 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13113 attribute);
13114 break;
13115 }
13116 case 'y':
13117 case 'Y':
13118 {
13119 if (LocaleCompare(attribute,"y") == 0)
13120 {
13121 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13122 y=geometry_info.rho;
13123 break;
13124 }
13125 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13126 attribute);
13127 break;
13128 }
13129 default:
13130 {
13131 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13132 attribute);
13133 break;
13134 }
13135 }
13136 }
13137 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13138 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13139 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13140 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13141 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13142 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13143 if (draw_info->geometry == (char *) NULL)
13144 {
13145 draw_info->geometry=AcquireString((char *) NULL);
13146 (void) FormatLocaleString(draw_info->geometry,MaxTextExtent,
13147 "%.15g,%.15g",x,y);
13148 }
13149 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13150 (void) CatchException(exception);
13151 if (status == MagickFalse)
13152 PUSHs(&sv_undef);
13153 else
13154 {
13155 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13156 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13157 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13158 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13159 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13160 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13161 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13162 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13163 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13164 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13165 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13166 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13167 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13168 }
13169 draw_info=DestroyDrawInfo(draw_info);
13170
13171 PerlException:
13172 if (package_info != (struct PackageInfo *) NULL)
13173 DestroyPackageInfo(package_info);
13174 InheritPerlException(exception,perl_exception);
13175 exception=DestroyExceptionInfo(exception);
13176 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13177 }
13178
13179#
13180###############################################################################
13181# #
13182# #
13183# #
13184# Q u e r y F o r m a t #
13185# #
13186# #
13187# #
13188###############################################################################
13189#
13190#
13191void
13192QueryFormat(ref,...)
13193 Image::Magick ref=NO_INIT
13194 ALIAS:
13195 queryformat = 1
13196 PPCODE:
13197 {
13198 char
13199 *name;
13200
13201 ExceptionInfo
13202 *exception;
13203
13204 register ssize_t
13205 i;
13206
13207 SV
13208 *perl_exception;
13209
13210 volatile const MagickInfo
13211 *magick_info;
13212
13213 PERL_UNUSED_VAR(ref);
13214 PERL_UNUSED_VAR(ix);
13215 exception=AcquireExceptionInfo();
13216 perl_exception=newSVpv("",0);
13217 if (items == 1)
13218 {
13219 char
13220 format[MaxTextExtent];
13221
13222 const MagickInfo
13223 **format_list;
13224
13225 size_t
13226 types;
13227
13228 format_list=GetMagickInfoList("*",&types,exception);
13229 EXTEND(sp,types);
13230 for (i=0; i < (ssize_t) types; i++)
13231 {
13232 (void) CopyMagickString(format,format_list[i]->name,MaxTextExtent);
13233 LocaleLower(format);
13234 PUSHs(sv_2mortal(newSVpv(format,0)));
13235 }
13236 format_list=(const MagickInfo **)
13237 RelinquishMagickMemory((MagickInfo *) format_list);
13238 goto PerlException;
13239 }
13240 EXTEND(sp,8*items);
13241 for (i=1; i < items; i++)
13242 {
13243 name=(char *) SvPV(ST(i),na);
13244 magick_info=GetMagickInfo(name,exception);
13245 if (magick_info == (const MagickInfo *) NULL)
13246 {
13247 PUSHs(&sv_undef);
13248 continue;
13249 }
13250 PUSHs(sv_2mortal(newSViv(magick_info->adjoin)));
13251 PUSHs(sv_2mortal(newSViv(magick_info->blob_support)));
13252 PUSHs(sv_2mortal(newSViv(magick_info->raw)));
13253 PUSHs(sv_2mortal(newSViv((long) magick_info->decoder)));
13254 PUSHs(sv_2mortal(newSViv((long) magick_info->encoder)));
13255 if (magick_info->description == (char *) NULL)
13256 PUSHs(&sv_undef);
13257 else
13258 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13259 if (magick_info->module == (char *) NULL)
13260 PUSHs(&sv_undef);
13261 else
13262 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13263 }
13264
13265 PerlException:
13266 InheritPerlException(exception,perl_exception);
13267 exception=DestroyExceptionInfo(exception);
13268 SvREFCNT_dec(perl_exception);
13269 }
13270
13271#
13272###############################################################################
13273# #
13274# #
13275# #
13276# Q u e r y O p t i o n #
13277# #
13278# #
13279# #
13280###############################################################################
13281#
13282#
13283void
13284QueryOption(ref,...)
13285 Image::Magick ref=NO_INIT
13286 ALIAS:
13287 queryoption = 1
13288 PPCODE:
13289 {
13290 char
13291 **options;
13292
13293 ExceptionInfo
13294 *exception;
13295
13296 register ssize_t
13297 i;
13298
13299 ssize_t
13300 j,
13301 option;
13302
13303 SV
13304 *perl_exception;
13305
13306 PERL_UNUSED_VAR(ref);
13307 PERL_UNUSED_VAR(ix);
13308 exception=AcquireExceptionInfo();
13309 perl_exception=newSVpv("",0);
13310 EXTEND(sp,8*items);
13311 for (i=1; i < items; i++)
13312 {
13313 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13314 SvPV(ST(i),na));
13315 options=GetCommandOptions((CommandOption) option);
13316 if (options == (char **) NULL)
13317 PUSHs(&sv_undef);
13318 else
13319 {
13320 for (j=0; options[j] != (char *) NULL; j++)
13321 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13322 options=DestroyStringList(options);
13323 }
13324 }
13325
13326 InheritPerlException(exception,perl_exception);
13327 exception=DestroyExceptionInfo(exception);
13328 SvREFCNT_dec(perl_exception);
13329 }
13330
13331#
13332###############################################################################
13333# #
13334# #
13335# #
13336# R e a d #
13337# #
13338# #
13339# #
13340###############################################################################
13341#
13342#
13343void
13344Read(ref,...)
13345 Image::Magick ref=NO_INIT
13346 ALIAS:
13347 ReadImage = 1
13348 read = 2
13349 readimage = 3
13350 PPCODE:
13351 {
13352 AV
13353 *av;
13354
13355 char
13356 **keep,
13357 **list;
13358
13359 ExceptionInfo
13360 *exception;
13361
13362 HV
13363 *hv;
13364
13365 Image
13366 *image;
13367
13368 int
13369 n;
13370
13371 MagickBooleanType
13372 status;
13373
13374 register char
13375 **p;
13376
13377 register ssize_t
13378 i;
13379
13380 ssize_t
13381 ac,
13382 number_images;
13383
13384 STRLEN
13385 *length;
13386
13387 struct PackageInfo
13388 *info,
13389 *package_info;
13390
13391 SV
13392 *perl_exception, /* Perl variable for storing messages */
13393 *reference,
13394 *rv,
13395 *sv;
13396
13397 PERL_UNUSED_VAR(ref);
13398 PERL_UNUSED_VAR(ix);
13399 exception=AcquireExceptionInfo();
13400 perl_exception=newSVpv("",0);
13401 sv=NULL;
13402 package_info=(struct PackageInfo *) NULL;
13403 number_images=0;
13404 ac=(items < 2) ? 1 : items-1;
13405 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13406 keep=list;
13407 length=(STRLEN *) NULL;
13408 if (list == (char **) NULL)
13409 {
13410 ThrowPerlException(exception,ResourceLimitError,
13411 "MemoryAllocationFailed",PackageName);
13412 goto PerlException;
13413 }
13414 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13415 if (length == (STRLEN *) NULL)
13416 {
13417 ThrowPerlException(exception,ResourceLimitError,
13418 "MemoryAllocationFailed",PackageName);
13419 goto PerlException;
13420 }
13421 if (sv_isobject(ST(0)) == 0)
13422 {
13423 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13424 PackageName);
13425 goto PerlException;
13426 }
13427 reference=SvRV(ST(0));
13428 hv=SvSTASH(reference);
13429 if (SvTYPE(reference) != SVt_PVAV)
13430 {
13431 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13432 PackageName);
13433 goto PerlException;
13434 }
13435 av=(AV *) reference;
13436 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13437 exception);
13438 package_info=ClonePackageInfo(info,exception);
13439 n=1;
13440 if (items <= 1)
13441 *list=(char *) (*package_info->image_info->filename ?
13442 package_info->image_info->filename : "XC:black");
13443 else
13444 for (n=0, i=0; i < ac; i++)
13445 {
13446 list[n]=(char *) SvPV(ST(i+1),length[n]);
13447 if ((items >= 3) && strEQcase(list[n],"blob"))
13448 {
13449 void
13450 *blob;
13451
13452 i++;
13453 blob=(void *) (SvPV(ST(i+1),length[n]));
13454 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13455 }
13456 if ((items >= 3) && strEQcase(list[n],"filename"))
13457 continue;
13458 if ((items >= 3) && strEQcase(list[n],"file"))
13459 {
13460 FILE
13461 *file;
13462
13463 PerlIO
13464 *io_info;
13465
13466 i++;
13467 io_info=IoIFP(sv_2io(ST(i+1)));
13468 if (io_info == (PerlIO *) NULL)
13469 {
13470 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13471 PackageName);
13472 continue;
13473 }
13474 file=PerlIO_findFILE(io_info);
13475 if (file == (FILE *) NULL)
13476 {
13477 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13478 PackageName);
13479 continue;
13480 }
13481 SetImageInfoFile(package_info->image_info,file);
13482 }
13483 if ((items >= 3) && strEQcase(list[n],"magick"))
13484 continue;
13485 n++;
13486 }
13487 list[n]=(char *) NULL;
13488 keep=list;
13489 status=ExpandFilenames(&n,&list);
13490 if (status == MagickFalse)
13491 {
13492 ThrowPerlException(exception,ResourceLimitError,
13493 "MemoryAllocationFailed",PackageName);
13494 goto PerlException;
13495 }
13496 number_images=0;
13497 for (i=0; i < n; i++)
13498 {
13499 if ((package_info->image_info->file == (FILE *) NULL) &&
13500 (package_info->image_info->blob == (void *) NULL))
13501 image=ReadImages(package_info->image_info,list[i],exception);
13502 else
13503 {
13504 image=ReadImages(package_info->image_info,
13505 package_info->image_info->filename,exception);
13506 if (image != (Image *) NULL)
13507 DisassociateImageStream(image);
13508 }
13509 if (image == (Image *) NULL)
13510 break;
13511 for ( ; image; image=image->next)
13512 {
13513 AddImageToRegistry(sv,image);
13514 rv=newRV(sv);
13515 av_push(av,sv_bless(rv,hv));
13516 SvREFCNT_dec(sv);
13517 number_images++;
13518 }
13519 }
13520 /*
13521 Free resources.
13522 */
13523 for (i=0; i < n; i++)
13524 if (list[i] != (char *) NULL)
13525 for (p=keep; list[i] != *p++; )
13526 if (*p == (char *) NULL)
13527 {
13528 list[i]=(char *) RelinquishMagickMemory(list[i]);
13529 break;
13530 }
13531
13532 PerlException:
13533 if (package_info != (struct PackageInfo *) NULL)
13534 DestroyPackageInfo(package_info);
13535 if (list && (list != keep))
13536 list=(char **) RelinquishMagickMemory(list);
13537 if (keep)
13538 keep=(char **) RelinquishMagickMemory(keep);
13539 if (length)
13540 length=(STRLEN *) RelinquishMagickMemory(length);
13541 InheritPerlException(exception,perl_exception);
13542 exception=DestroyExceptionInfo(exception);
13543 sv_setiv(perl_exception,(IV) number_images);
13544 SvPOK_on(perl_exception);
13545 ST(0)=sv_2mortal(perl_exception);
13546 XSRETURN(1);
13547 }
13548
13549#
13550###############################################################################
13551# #
13552# #
13553# #
13554# R e m o t e #
13555# #
13556# #
13557# #
13558###############################################################################
13559#
13560#
13561void
13562Remote(ref,...)
13563 Image::Magick ref=NO_INIT
13564 ALIAS:
13565 RemoteCommand = 1
13566 remote = 2
13567 remoteCommand = 3
13568 PPCODE:
13569 {
13570 AV
13571 *av;
13572
13573 ExceptionInfo
13574 *exception;
13575
13576 register ssize_t
13577 i;
13578
13579 SV
13580 *perl_exception,
13581 *reference;
13582
13583 struct PackageInfo
13584 *info;
13585
13586 PERL_UNUSED_VAR(ref);
13587 PERL_UNUSED_VAR(ix);
13588 exception=AcquireExceptionInfo();
13589 perl_exception=newSVpv("",0);
13590 reference=SvRV(ST(0));
13591 av=(AV *) reference;
13592 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13593 exception);
13594 for (i=1; i < items; i++)
13595 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13596 SvPV(ST(i),na),exception);
13597 InheritPerlException(exception,perl_exception);
13598 exception=DestroyExceptionInfo(exception);
13599 SvREFCNT_dec(perl_exception); /* throw away all errors */
13600 }
13601
13602#
13603###############################################################################
13604# #
13605# #
13606# #
13607# S e t #
13608# #
13609# #
13610# #
13611###############################################################################
13612#
13613#
13614void
13615Set(ref,...)
13616 Image::Magick ref=NO_INIT
13617 ALIAS:
13618 SetAttributes = 1
13619 SetAttribute = 2
13620 set = 3
13621 setattributes = 4
13622 setattribute = 5
13623 PPCODE:
13624 {
13625 ExceptionInfo
13626 *exception;
13627
13628 Image
13629 *image;
13630
13631 register ssize_t
13632 i;
13633
13634 struct PackageInfo
13635 *info;
13636
13637 SV
13638 *perl_exception,
13639 *reference; /* reference is the SV* of ref=SvIV(reference) */
13640
13641 PERL_UNUSED_VAR(ref);
13642 PERL_UNUSED_VAR(ix);
13643 exception=AcquireExceptionInfo();
13644 perl_exception=newSVpv("",0);
13645 if (sv_isobject(ST(0)) == 0)
13646 {
13647 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13648 PackageName);
13649 goto PerlException;
13650 }
13651 reference=SvRV(ST(0));
13652 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13653 if (items == 2)
13654 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13655 else
13656 for (i=2; i < items; i+=2)
13657 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13658
13659 PerlException:
13660 InheritPerlException(exception,perl_exception);
13661 exception=DestroyExceptionInfo(exception);
13662 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13663 SvPOK_on(perl_exception);
13664 ST(0)=sv_2mortal(perl_exception);
13665 XSRETURN(1);
13666 }
13667
13668#
13669###############################################################################
13670# #
13671# #
13672# #
13673# S e t P i x e l #
13674# #
13675# #
13676# #
13677###############################################################################
13678#
13679#
13680void
13681SetPixel(ref,...)
13682 Image::Magick ref=NO_INIT
13683 ALIAS:
13684 setpixel = 1
13685 setPixel = 2
13686 PPCODE:
13687 {
13688 AV
13689 *av;
13690
13691 char
13692 *attribute;
13693
13694 ChannelType
13695 channel,
13696 channel_mask;
13697
13698 ExceptionInfo
13699 *exception;
13700
13701 Image
13702 *image;
13703
13704 MagickBooleanType
13705 normalize;
13706
13707 RectangleInfo
13708 region;
13709
13710 register ssize_t
13711 i;
13712
13713 register Quantum
13714 *q;
13715
13716 ssize_t
13717 option;
13718
13719 struct PackageInfo
13720 *info;
13721
13722 SV
13723 *perl_exception,
13724 *reference; /* reference is the SV* of ref=SvIV(reference) */
13725
13726 PERL_UNUSED_VAR(ref);
13727 PERL_UNUSED_VAR(ix);
13728 exception=AcquireExceptionInfo();
13729 perl_exception=newSVpv("",0);
13730 reference=SvRV(ST(0));
13731 av=(AV *) reference;
13732 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13733 exception);
13734 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13735 if (image == (Image *) NULL)
13736 {
13737 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13738 PackageName);
13739 goto PerlException;
13740 }
13741 av=(AV *) NULL;
13742 normalize=MagickTrue;
13743 region.x=0;
13744 region.y=0;
13745 region.width=image->columns;
13746 region.height=1;
13747 if (items == 1)
13748 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
13749 channel=DefaultChannels;
13750 for (i=2; i < items; i+=2)
13751 {
13752 attribute=(char *) SvPV(ST(i-1),na);
13753 switch (*attribute)
13754 {
13755 case 'C':
13756 case 'c':
13757 {
13758 if (LocaleCompare(attribute,"channel") == 0)
13759 {
13760 ssize_t
13761 option;
13762
13763 option=ParseChannelOption(SvPV(ST(i),na));
13764 if (option < 0)
13765 {
13766 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13767 SvPV(ST(i),na));
13768 return;
13769 }
13770 channel=(ChannelType) option;
13771 break;
13772 }
13773 if (LocaleCompare(attribute,"color") == 0)
13774 {
13775 if (SvTYPE(ST(i)) != SVt_RV)
13776 {
13777 char
13778 message[MaxTextExtent];
13779
13780 (void) FormatLocaleString(message,MaxTextExtent,
13781 "invalid %.60s value",attribute);
13782 ThrowPerlException(exception,OptionError,message,
13783 SvPV(ST(i),na));
13784 }
13785 av=(AV *) SvRV(ST(i));
13786 break;
13787 }
13788 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13789 attribute);
13790 break;
13791 }
13792 case 'g':
13793 case 'G':
13794 {
13795 if (LocaleCompare(attribute,"geometry") == 0)
13796 {
13797 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
13798 break;
13799 }
13800 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13801 attribute);
13802 break;
13803 }
13804 case 'N':
13805 case 'n':
13806 {
13807 if (LocaleCompare(attribute,"normalize") == 0)
13808 {
13809 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13810 SvPV(ST(i),na));
13811 if (option < 0)
13812 {
13813 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13814 SvPV(ST(i),na));
13815 break;
13816 }
13817 normalize=option != 0 ? MagickTrue : MagickFalse;
13818 break;
13819 }
13820 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13821 attribute);
13822 break;
13823 }
13824 case 'x':
13825 case 'X':
13826 {
13827 if (LocaleCompare(attribute,"x") == 0)
13828 {
13829 region.x=SvIV(ST(i));
13830 break;
13831 }
13832 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13833 attribute);
13834 break;
13835 }
13836 case 'y':
13837 case 'Y':
13838 {
13839 if (LocaleCompare(attribute,"y") == 0)
13840 {
13841 region.y=SvIV(ST(i));
13842 break;
13843 }
13844 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13845 attribute);
13846 break;
13847 }
13848 default:
13849 {
13850 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13851 attribute);
13852 break;
13853 }
13854 }
13855 }
13856 (void) SetImageStorageClass(image,DirectClass,exception);
13857 channel_mask=SetImageChannelMask(image,channel);
13858 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
13859 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
13860 (SvTYPE(av) != SVt_PVAV))
13861 PUSHs(&sv_undef);
13862 else
13863 {
13864 double
13865 scale;
13866
13867 register ssize_t
13868 i;
13869
13870 i=0;
13871 scale=1.0;
13872 if (normalize != MagickFalse)
13873 scale=QuantumRange;
13874 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
13875 (i <= av_len(av)))
13876 {
13877 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
13878 av_fetch(av,i,0)))),q);
13879 i++;
13880 }
13881 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
13882 (i <= av_len(av)))
13883 {
13884 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
13885 av_fetch(av,i,0)))),q);
13886 i++;
13887 }
13888 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
13889 (i <= av_len(av)))
13890 {
13891 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
13892 av_fetch(av,i,0)))),q);
13893 i++;
13894 }
13895 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
13896 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
13897 {
13898 SetPixelBlack(image,ClampToQuantum(scale*
13899 SvNV(*(av_fetch(av,i,0)))),q);
13900 i++;
13901 }
13902 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
13903 (i <= av_len(av)))
13904 {
13905 SetPixelAlpha(image,ClampToQuantum(scale*
13906 SvNV(*(av_fetch(av,i,0)))),q);
13907 i++;
13908 }
13909 (void) SyncAuthenticPixels(image,exception);
13910 }
13911 (void) SetImageChannelMask(image,channel_mask);
13912
13913 PerlException:
13914 InheritPerlException(exception,perl_exception);
13915 exception=DestroyExceptionInfo(exception);
13916 SvREFCNT_dec(perl_exception);
13917 }
13918
13919#
13920###############################################################################
13921# #
13922# #
13923# #
13924# S m u s h #
13925# #
13926# #
13927# #
13928###############################################################################
13929#
13930#
13931void
13932Smush(ref,...)
13933 Image::Magick ref=NO_INIT
13934 ALIAS:
13935 SmushImage = 1
13936 smush = 2
13937 smushimage = 3
13938 PPCODE:
13939 {
13940 AV
13941 *av;
13942
13943 char
13944 *attribute;
13945
13946 ExceptionInfo
13947 *exception;
13948
13949 HV
13950 *hv;
13951
13952 Image
13953 *image;
13954
13955 register ssize_t
13956 i;
13957
13958 ssize_t
13959 offset,
13960 stack;
13961
13962 struct PackageInfo
13963 *info;
13964
13965 SV
13966 *av_reference,
13967 *perl_exception,
13968 *reference,
13969 *rv,
13970 *sv;
13971
13972 PERL_UNUSED_VAR(ref);
13973 PERL_UNUSED_VAR(ix);
13974 exception=AcquireExceptionInfo();
13975 perl_exception=newSVpv("",0);
13976 sv=NULL;
13977 attribute=NULL;
13978 av=NULL;
13979 if (sv_isobject(ST(0)) == 0)
13980 {
13981 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13982 PackageName);
13983 goto PerlException;
13984 }
13985 reference=SvRV(ST(0));
13986 hv=SvSTASH(reference);
13987 av=newAV();
13988 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
13989 SvREFCNT_dec(av);
13990 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13991 if (image == (Image *) NULL)
13992 {
13993 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13994 PackageName);
13995 goto PerlException;
13996 }
13997 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
13998 /*
13999 Get options.
14000 */
14001 offset=0;
14002 stack=MagickTrue;
14003 for (i=2; i < items; i+=2)
14004 {
14005 attribute=(char *) SvPV(ST(i-1),na);
14006 switch (*attribute)
14007 {
14008 case 'O':
14009 case 'o':
14010 {
14011 if (LocaleCompare(attribute,"offset") == 0)
14012 {
14013 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14014 break;
14015 }
14016 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14017 attribute);
14018 break;
14019 }
14020 case 'S':
14021 case 's':
14022 {
14023 if (LocaleCompare(attribute,"stack") == 0)
14024 {
14025 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14026 SvPV(ST(i),na));
14027 if (stack < 0)
14028 {
14029 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14030 SvPV(ST(i),na));
14031 return;
14032 }
14033 break;
14034 }
14035 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14036 attribute);
14037 break;
14038 }
14039 default:
14040 {
14041 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14042 attribute);
14043 break;
14044 }
14045 }
14046 }
14047 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14048 exception);
14049 if (image == (Image *) NULL)
14050 goto PerlException;
14051 for ( ; image; image=image->next)
14052 {
14053 AddImageToRegistry(sv,image);
14054 rv=newRV(sv);
14055 av_push(av,sv_bless(rv,hv));
14056 SvREFCNT_dec(sv);
14057 }
14058 exception=DestroyExceptionInfo(exception);
14059 ST(0)=av_reference;
14060 SvREFCNT_dec(perl_exception);
14061 XSRETURN(1);
14062
14063 PerlException:
14064 InheritPerlException(exception,perl_exception);
14065 exception=DestroyExceptionInfo(exception);
14066 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14067 SvPOK_on(perl_exception);
14068 ST(0)=sv_2mortal(perl_exception);
14069 XSRETURN(1);
14070 }
14071
14072#
14073###############################################################################
14074# #
14075# #
14076# #
14077# S t a t i s t i c s #
14078# #
14079# #
14080# #
14081###############################################################################
14082#
14083#
14084void
14085Statistics(ref,...)
14086 Image::Magick ref=NO_INIT
14087 ALIAS:
14088 StatisticsImage = 1
14089 statistics = 2
14090 statisticsimage = 3
14091 PPCODE:
14092 {
14093#define ChannelStatistics(channel) \
14094{ \
14095 (void) FormatLocaleString(message,MaxTextExtent,"%.20g", \
14096 (double) channel_statistics[channel].depth); \
14097 PUSHs(sv_2mortal(newSVpv(message,0))); \
14098 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
14099 channel_statistics[channel].minima/scale); \
14100 PUSHs(sv_2mortal(newSVpv(message,0))); \
14101 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
14102 channel_statistics[channel].maxima/scale); \
14103 PUSHs(sv_2mortal(newSVpv(message,0))); \
14104 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
14105 channel_statistics[channel].mean/scale); \
14106 PUSHs(sv_2mortal(newSVpv(message,0))); \
14107 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
14108 channel_statistics[channel].standard_deviation/scale); \
14109 PUSHs(sv_2mortal(newSVpv(message,0))); \
14110 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
14111 channel_statistics[channel].kurtosis); \
14112 PUSHs(sv_2mortal(newSVpv(message,0))); \
14113 (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
14114 channel_statistics[channel].skewness); \
14115 PUSHs(sv_2mortal(newSVpv(message,0))); \
14116}
14117
14118 AV
14119 *av;
14120
14121 char
14122 message[MaxTextExtent];
14123
14124 ChannelStatistics
14125 *channel_statistics;
14126
14127 double
14128 scale;
14129
14130 ExceptionInfo
14131 *exception;
14132
14133 Image
14134 *image;
14135
14136 ssize_t
14137 count;
14138
14139 struct PackageInfo
14140 *info;
14141
14142 SV
14143 *perl_exception,
14144 *reference;
14145
14146 PERL_UNUSED_VAR(ref);
14147 PERL_UNUSED_VAR(ix);
14148 exception=AcquireExceptionInfo();
14149 perl_exception=newSVpv("",0);
14150 av=NULL;
14151 if (sv_isobject(ST(0)) == 0)
14152 {
14153 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14154 PackageName);
14155 goto PerlException;
14156 }
14157 reference=SvRV(ST(0));
14158 av=newAV();
14159 SvREFCNT_dec(av);
14160 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14161 if (image == (Image *) NULL)
14162 {
14163 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14164 PackageName);
14165 goto PerlException;
14166 }
14167 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14168 count=0;
14169 for ( ; image; image=image->next)
14170 {
14171 channel_statistics=GetImageStatistics(image,exception);
14172 if (channel_statistics == (ChannelStatistics *) NULL)
14173 continue;
14174 count++;
14175 EXTEND(sp,35*count);
14176 scale=(double) QuantumRange;
14177 ChannelStatistics(RedChannel);
14178 ChannelStatistics(GreenChannel);
14179 ChannelStatistics(BlueChannel);
14180 if (image->colorspace == CMYKColorspace)
14181 ChannelStatistics(BlackChannel);
14182 if (image->alpha_trait == BlendPixelTrait)
14183 ChannelStatistics(AlphaChannel);
14184 channel_statistics=(ChannelStatistics *)
14185 RelinquishMagickMemory(channel_statistics);
14186 }
14187
14188 PerlException:
14189 InheritPerlException(exception,perl_exception);
14190 exception=DestroyExceptionInfo(exception);
14191 SvREFCNT_dec(perl_exception);
14192 }
14193
14194#
14195###############################################################################
14196# #
14197# #
14198# #
14199# S y n c A u t h e n t i c P i x e l s #
14200# #
14201# #
14202# #
14203###############################################################################
14204#
14205#
14206void
14207SyncAuthenticPixels(ref,...)
14208 Image::Magick ref = NO_INIT
14209 ALIAS:
14210 Syncauthenticpixels = 1
14211 SyncImagePixels = 2
14212 syncimagepixels = 3
14213 CODE:
14214 {
14215 ExceptionInfo
14216 *exception;
14217
14218 Image
14219 *image;
14220
14221 MagickBooleanType
14222 status;
14223
14224 struct PackageInfo
14225 *info;
14226
14227 SV
14228 *perl_exception,
14229 *reference;
14230
14231 PERL_UNUSED_VAR(ref);
14232 PERL_UNUSED_VAR(ix);
14233 exception=AcquireExceptionInfo();
14234 perl_exception=newSVpv("",0);
14235 if (sv_isobject(ST(0)) == 0)
14236 {
14237 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14238 PackageName);
14239 goto PerlException;
14240 }
14241
14242 reference=SvRV(ST(0));
14243 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14244 if (image == (Image *) NULL)
14245 {
14246 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14247 PackageName);
14248 goto PerlException;
14249 }
14250
14251 status=SyncAuthenticPixels(image,exception);
14252 if (status != MagickFalse)
14253 return;
14254
14255 PerlException:
14256 InheritPerlException(exception,perl_exception);
14257 exception=DestroyExceptionInfo(exception);
14258 SvREFCNT_dec(perl_exception); /* throw away all errors */
14259 }
14260
14261#
14262###############################################################################
14263# #
14264# #
14265# #
14266# T r a n s f o r m #
14267# #
14268# #
14269# #
14270###############################################################################
14271#
14272#
14273void
14274Transform(ref,...)
14275 Image::Magick ref=NO_INIT
14276 ALIAS:
14277 TransformImage = 1
14278 transform = 2
14279 transformimage = 3
14280 PPCODE:
14281 {
14282 AV
14283 *av;
14284
14285 char
14286 *attribute,
14287 *crop_geometry,
14288 *geometry;
14289
14290 ExceptionInfo
14291 *exception;
14292
14293 HV
14294 *hv;
14295
14296 Image
14297 *clone,
14298 *image;
14299
14300 register ssize_t
14301 i;
14302
14303 struct PackageInfo
14304 *info;
14305
14306 SV
14307 *av_reference,
14308 *perl_exception,
14309 *reference,
14310 *rv,
14311 *sv;
14312
14313 PERL_UNUSED_VAR(ref);
14314 PERL_UNUSED_VAR(ix);
14315 exception=AcquireExceptionInfo();
14316 perl_exception=newSVpv("",0);
14317 sv=NULL;
14318 av=NULL;
14319 attribute=NULL;
14320 if (sv_isobject(ST(0)) == 0)
14321 {
14322 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14323 PackageName);
14324 goto PerlException;
14325 }
14326 reference=SvRV(ST(0));
14327 hv=SvSTASH(reference);
14328 av=newAV();
14329 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14330 SvREFCNT_dec(av);
14331 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14332 if (image == (Image *) NULL)
14333 {
14334 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14335 PackageName);
14336 goto PerlException;
14337 }
14338 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14339 /*
14340 Get attribute.
14341 */
14342 crop_geometry=(char *) NULL;
14343 geometry=(char *) NULL;
14344 for (i=2; i < items; i+=2)
14345 {
14346 attribute=(char *) SvPV(ST(i-1),na);
14347 switch (*attribute)
14348 {
14349 case 'c':
14350 case 'C':
14351 {
14352 if (LocaleCompare(attribute,"crop") == 0)
14353 {
14354 crop_geometry=SvPV(ST(i),na);
14355 break;
14356 }
14357 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14358 attribute);
14359 break;
14360 }
14361 case 'g':
14362 case 'G':
14363 {
14364 if (LocaleCompare(attribute,"geometry") == 0)
14365 {
14366 geometry=SvPV(ST(i),na);
14367 break;
14368 }
14369 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14370 attribute);
14371 break;
14372 }
14373 default:
14374 {
14375 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14376 attribute);
14377 break;
14378 }
14379 }
14380 }
14381 for ( ; image; image=image->next)
14382 {
14383 clone=CloneImage(image,0,0,MagickTrue,exception);
14384 if (clone == (Image *) NULL)
14385 goto PerlException;
14386 TransformImage(&clone,crop_geometry,geometry,exception);
14387 for ( ; clone; clone=clone->next)
14388 {
14389 AddImageToRegistry(sv,clone);
14390 rv=newRV(sv);
14391 av_push(av,sv_bless(rv,hv));
14392 SvREFCNT_dec(sv);
14393 }
14394 }
14395 exception=DestroyExceptionInfo(exception);
14396 ST(0)=av_reference;
14397 SvREFCNT_dec(perl_exception); /* can't return warning messages */
14398 XSRETURN(1);
14399
14400 PerlException:
14401 InheritPerlException(exception,perl_exception);
14402 exception=DestroyExceptionInfo(exception);
14403 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14404 SvPOK_on(perl_exception);
14405 ST(0)=sv_2mortal(perl_exception);
14406 XSRETURN(1);
14407 }
14408
14409#
14410###############################################################################
14411# #
14412# #
14413# #
14414# W r i t e #
14415# #
14416# #
14417# #
14418###############################################################################
14419#
14420#
14421void
14422Write(ref,...)
14423 Image::Magick ref=NO_INIT
14424 ALIAS:
14425 WriteImage = 1
14426 write = 2
14427 writeimage = 3
14428 PPCODE:
14429 {
14430 char
14431 filename[MaxTextExtent];
14432
14433 ExceptionInfo
14434 *exception;
14435
14436 Image
14437 *image,
14438 *next;
14439
14440 register ssize_t
14441 i;
14442
14443 ssize_t
14444 number_images,
14445 scene;
14446
14447 struct PackageInfo
14448 *info,
14449 *package_info;
14450
14451 SV
14452 *perl_exception,
14453 *reference;
14454
14455 PERL_UNUSED_VAR(ref);
14456 PERL_UNUSED_VAR(ix);
14457 exception=AcquireExceptionInfo();
14458 perl_exception=newSVpv("",0);
14459 number_images=0;
14460 package_info=(struct PackageInfo *) NULL;
14461 if (sv_isobject(ST(0)) == 0)
14462 {
14463 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14464 PackageName);
14465 goto PerlException;
14466 }
14467 reference=SvRV(ST(0));
14468 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14469 if (image == (Image *) NULL)
14470 {
14471 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14472 PackageName);
14473 goto PerlException;
14474 }
14475 package_info=ClonePackageInfo(info,exception);
14476 if (items == 2)
14477 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14478 else
14479 if (items > 2)
14480 for (i=2; i < items; i+=2)
14481 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14482 exception);
14483 (void) CopyMagickString(filename,package_info->image_info->filename,
14484 MaxTextExtent);
14485 scene=0;
14486 for (next=image; next; next=next->next)
14487 {
14488 (void) CopyMagickString(next->filename,filename,MaxTextExtent);
14489 next->scene=scene++;
14490 }
14491 SetImageInfo(package_info->image_info,(unsigned int)
14492 GetImageListLength(image),exception);
14493 for (next=image; next; next=next->next)
14494 {
14495 (void) WriteImage(package_info->image_info,next,exception);
14496 number_images++;
14497 if (package_info->image_info->adjoin)
14498 break;
14499 }
14500
14501 PerlException:
14502 if (package_info != (struct PackageInfo *) NULL)
14503 DestroyPackageInfo(package_info);
14504 InheritPerlException(exception,perl_exception);
14505 exception=DestroyExceptionInfo(exception);
14506 sv_setiv(perl_exception,(IV) number_images);
14507 SvPOK_on(perl_exception);
14508 ST(0)=sv_2mortal(perl_exception);
14509 XSRETURN(1);
14510 }