blob: 67bfaa67ea748914c7f06f63d3c087380a37ac06 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +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 %
22% John Cristy %
23% February 1997 %
24% %
25% %
26% Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization %
27% 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(WIN32)
52#define MagickExport
53#endif
54
55#if defined(__cplusplus) || defined(c_plusplus)
56extern "C" {
57#endif
58
59#define PERL_NO_GET_CONTEXT
60#include "EXTERN.h"
61#include "perl.h"
62#include "XSUB.h"
63#include <math.h>
64#include <magick/MagickCore.h>
65#undef tainted
66
67#if defined(__cplusplus) || defined(c_plusplus)
68}
69#endif
70
71/*
72 Define declarations.
73*/
74#ifndef aTHX_
75#define aTHX_
76#define pTHX_
77#define dTHX
78#endif
79#define DegreesToRadians(x) (MagickPI*(x)/180.0)
80#define EndOf(array) (&array[NumberOf(array)])
81#define MagickPI 3.14159265358979323846264338327950288419716939937510
cristyd4160cf2009-09-07 21:51:25 +000082#define MaxArguments 32
cristy3ed852e2009-09-05 21:47:34 +000083#ifndef na
84#define na PL_na
85#endif
86#define NumberOf(array) (sizeof(array)/sizeof(*array))
87#define PackageName "Image::Magick"
88#if PERL_VERSION <= 6
89#define PerlIO FILE
90#define PerlIO_importFILE(f, fl) (f)
91#define PerlIO_findFILE(f) NULL
92#endif
93#define RoundToQuantum(value) ((Quantum) ((value) < 0.0 ? 0.0 : \
94 ((value) > (MagickRealType) QuantumRange) ? (MagickRealType) \
95 QuantumRange : (value)+0.5))
96#ifndef sv_undef
97#define sv_undef PL_sv_undef
98#endif
99
100#define AddImageToRegistry(image) \
101{ \
102 if (magick_registry != (SplayTreeInfo *) NULL) \
103 { \
104 (void) AddValueToSplayTree(magick_registry,image,image); \
105 sv=newSViv((IV) image); \
106 } \
107}
108
109#define DeleteImageFromRegistry(reference,image) \
110{ \
111 if (magick_registry != (SplayTreeInfo *) NULL) \
112 { \
113 if (GetImageReferenceCount(image) == 1) \
114 (void) DeleteNodeByValueFromSplayTree(magick_registry,image); \
115 image=DestroyImage(image); \
116 sv_setiv(reference,0); \
117 } \
118}
119
120#define InheritPerlException(exception,perl_exception) \
121{ \
122 char \
123 message[MaxTextExtent]; \
124 \
125 if ((exception)->severity != UndefinedException) \
126 { \
127 (void) FormatMagickString(message,MaxTextExtent,"Exception %d: %s%s%s%s",\
128 (exception)->severity, (exception)->reason ? \
129 GetLocaleExceptionMessage((exception)->severity,(exception)->reason) : \
130 "Unknown", (exception)->description ? " (" : "", \
131 (exception)->description ? GetLocaleExceptionMessage( \
132 (exception)->severity,(exception)->description) : "", \
133 (exception)->description ? ")" : ""); \
134 if ((perl_exception) != (SV *) NULL) \
135 { \
136 if (SvCUR(perl_exception)) \
137 sv_catpv(perl_exception,"\n"); \
138 sv_catpv(perl_exception,message); \
139 } \
140 } \
141}
142
143#define ThrowPerlException(exception,severity,tag,reason) \
144 (void) ThrowMagickException(exception,GetMagickModule(),severity, \
145 tag,"`%s'",reason); \
146
147/*
148 Typedef and structure declarations.
149*/
150typedef enum
151{
152 ArrayReference = (~0),
153 RealReference = (~0)-1,
154 FileReference = (~0)-2,
155 ImageReference = (~0)-3,
156 IntegerReference = (~0)-4,
157 StringReference = (~0)-5
158} MagickReference;
159
160typedef struct _Arguments
161{
162 const char
163 *method;
164
165 long
166 type;
167} Arguments;
168
169struct ArgumentList
170{
171 long
172 long_reference;
173
174 MagickRealType
175 real_reference;
176
177 const char
178 *string_reference;
179
180 Image
181 *image_reference;
182
183 SV
184 *array_reference;
185
186 FILE
187 *file_reference;
188
189 size_t
190 length;
191};
192
193struct PackageInfo
194{
195 ImageInfo
196 *image_info;
197};
198
199typedef void
200 *Image__Magick; /* data type for the Image::Magick package */
201
202/*
203 Static declarations.
204*/
205static struct
206 Methods
207 {
208 const char
209 *name;
210
211 Arguments
212 arguments[MaxArguments];
213 } Methods[] =
214 {
215 { "Comment", { {"comment", StringReference} } },
216 { "Label", { {"label", StringReference} } },
217 { "AddNoise", { {"noise", MagickNoiseOptions},
218 {"channel", MagickChannelOptions} } },
219 { "Colorize", { {"fill", StringReference}, {"opacity", StringReference} } },
220 { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
221 {"height", IntegerReference}, {"fill", StringReference},
222 {"bordercolor", StringReference}, {"color", StringReference},
223 {"compose", MagickComposeOptions} } },
224 { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
225 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
226 { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
227 {"height", IntegerReference}, {"x", IntegerReference},
228 {"y", IntegerReference} } },
229 { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
230 {"height", IntegerReference}, {"x", IntegerReference},
231 {"y", IntegerReference}, {"fuzz", StringReference} } },
232 { "Despeckle", },
233 { "Edge", { {"radius", RealReference} } },
234 { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
235 {"sigma", RealReference} } },
236 { "Enhance", },
237 { "Flip", },
238 { "Flop", },
239 { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
240 {"height", IntegerReference}, {"inner", IntegerReference},
241 {"outer", IntegerReference}, {"fill", StringReference},
242 {"color", StringReference}, {"compose", MagickComposeOptions} } },
243 { "Implode", { {"amount", RealReference},
244 {"interpolate", MagickInterpolateOptions} } },
245 { "Magnify", },
246 { "MedianFilter", { {"radius", RealReference} } },
247 { "Minify", },
248 { "OilPaint", { {"radius", RealReference} } },
249 { "ReduceNoise", { {"radius", RealReference} } },
250 { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
251 {"y", IntegerReference} } },
252 { "Rotate", { {"degrees", RealReference}, {"fill", StringReference},
253 {"color", StringReference}, {"background", StringReference} } },
254 { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
255 {"height", IntegerReference} } },
256 { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
257 {"height", IntegerReference} } },
258 { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
259 {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
260 { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
261 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
262 { "Shear", { {"geometry", StringReference}, {"x", RealReference},
263 {"y", RealReference}, { "fill", StringReference},
264 {"color", StringReference} } },
265 { "Spread", { {"radius", RealReference} } },
266 { "Swirl", { {"degrees", RealReference},
267 {"interpolate", MagickInterpolateOptions} } },
268 { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
269 {"height", IntegerReference}, {"filter", MagickFilterOptions},
270 {"support", StringReference }, {"blur", RealReference } } },
271 { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
272 {"height", IntegerReference}, {"filter", MagickFilterOptions},
273 {"support", RealReference }, {"blur", RealReference } } },
274 { "Annotate", { {"text", StringReference}, {"font", StringReference},
275 {"pointsize", RealReference}, {"density", StringReference},
276 {"undercolor", StringReference}, {"stroke", StringReference},
277 {"fill", StringReference}, {"geometry", StringReference},
278 {"pen", StringReference}, {"x", RealReference},
279 {"y", RealReference}, {"gravity", MagickGravityOptions},
280 {"translate", StringReference}, {"scale", StringReference},
281 {"rotate", RealReference}, {"skewX", RealReference},
282 {"skewY", RealReference}, {"strokewidth", RealReference},
283 {"antialias", MagickBooleanOptions}, {"family", StringReference},
284 {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
285 {"weight", IntegerReference}, {"align", MagickAlignOptions},
286 {"encoding", StringReference}, {"affine", ArrayReference},
287 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
288 {"tile", ImageReference}, {"kerning", RealReference},
cristyb32b90a2009-09-07 21:45:48 +0000289 {"interline-spacing", RealReference},
cristy3ed852e2009-09-05 21:47:34 +0000290 {"interword-spacing", RealReference} } },
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} } },
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},
cristyb32b90a2009-09-07 21:45:48 +0000323 {"interline-spacing", RealReference},
cristy3ed852e2009-09-05 21:47:34 +0000324 {"interword-spacing", RealReference} } },
325 { "Equalize", { {"channel", MagickChannelOptions} } },
326 { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
327 {"red", RealReference}, {"green", RealReference},
328 {"blue", RealReference} } },
329 { "Map", { {"image", ImageReference}, {"dither", MagickBooleanOptions} } },
330 { "MatteFloodfill", { {"geometry", StringReference},
331 {"x", IntegerReference}, {"y", IntegerReference},
332 {"opacity", StringReference}, {"bordercolor", StringReference},
333 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
334 { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
335 {"saturation", RealReference}, {"whiteness", RealReference},
336 {"brightness", RealReference}, {"luminosity", RealReference},
337 {"blackness", RealReference} } },
338 { "Negate", { {"gray", MagickBooleanOptions},
339 {"channel", MagickChannelOptions} } },
340 { "Normalize", { {"channel", MagickChannelOptions} } },
341 { "NumberColors", },
342 { "Opaque", { {"color", StringReference}, {"fill", StringReference},
343 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
344 {"invert", MagickBooleanOptions} } },
345 { "Quantize", { {"colors", IntegerReference},
346 {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
347 {"dither", MagickBooleanOptions}, {"measure", MagickBooleanOptions},
348 {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
349 {"dither-method", MagickDitherOptions} } },
350 { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
351 {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
352 { "Segment", { {"geometry", StringReference},
353 {"cluster-threshold", RealReference},
354 {"smoothing-threshold", RealReference},
355 {"colorspace", MagickColorspaceOptions},
356 {"verbose", MagickBooleanOptions} } },
357 { "Signature", },
358 { "Solarize", { {"geometry", StringReference},
359 {"threshold", StringReference} } },
360 { "Sync", },
361 { "Texture", { {"texture", ImageReference} } },
362 { "Evaluate", { {"value", RealReference},
363 {"operator", MagickEvaluateOptions},
364 {"channel", MagickChannelOptions} } },
365 { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
366 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
367 { "Threshold", { {"threshold", StringReference},
368 {"channel", MagickChannelOptions} } },
369 { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
370 {"sigma", RealReference} } },
371 { "Trim", { {"fuzz", StringReference} } },
372 { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
373 {"wavelength", RealReference},
374 {"interpolate", MagickInterpolateOptions} } },
375 { "Separate", { {"channel", MagickChannelOptions} } },
376 { "Condense", },
377 { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
378 {"y", IntegerReference} } },
379 { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
380 { "Deconstruct", },
381 { "GaussianBlur", { {"geometry", StringReference},
382 {"radius", RealReference}, {"sigma", RealReference},
383 {"channel", MagickChannelOptions} } },
384 { "Convolve", { {"coefficients", ArrayReference},
385 {"channel", MagickChannelOptions}, {"bias", StringReference} } },
386 { "Profile", { {"name", StringReference}, {"profile", StringReference},
387 { "rendering-intent", MagickIntentOptions},
388 { "black-point-compensation", MagickBooleanOptions} } },
389 { "UnsharpMask", { {"geometry", StringReference},
390 {"radius", RealReference}, {"sigma", RealReference},
391 {"amount", RealReference}, {"threshold", RealReference},
392 {"channel", MagickChannelOptions} } },
393 { "MotionBlur", { {"geometry", StringReference},
394 {"radius", RealReference}, {"sigma", RealReference},
395 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
396 { "OrderedDither", { {"threshold", StringReference},
397 {"channel", MagickChannelOptions} } },
398 { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
399 {"height", IntegerReference} } },
400 { "Level", { {"levels", StringReference}, {"black-point", RealReference},
401 {"white-point", RealReference}, {"gamma", RealReference},
402 {"channel", MagickChannelOptions}, {"level", StringReference} } },
403 { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
404 { "AffineTransform", { {"affine", ArrayReference},
405 {"translate", StringReference}, {"scale", StringReference},
406 {"rotate", RealReference}, {"skewX", RealReference},
407 {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
408 {"background", StringReference} } },
409 { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
410 { "AdaptiveThreshold", { {"geometry", StringReference},
411 {"width", IntegerReference}, {"height", IntegerReference},
412 {"offset", IntegerReference} } },
413 { "Resample", { {"density", StringReference}, {"x", RealReference},
414 {"y", RealReference}, {"filter", MagickFilterOptions},
415 {"support", RealReference }, {"blur", RealReference } } },
416 { "Describe", { {"file", FileReference} } },
417 { "BlackThreshold", { {"threshold", StringReference},
418 {"channel", MagickChannelOptions} } },
419 { "WhiteThreshold", { {"threshold", StringReference},
420 {"channel", MagickChannelOptions} } },
421 { "RadialBlur", { {"geometry", StringReference}, {"angle", RealReference},
422 {"channel", MagickChannelOptions} } },
423 { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
424 {"height", IntegerReference} } },
425 { "Strip", },
426 { "Tint", { {"fill", StringReference}, {"opacity", StringReference} } },
427 { "Channel", { {"channel", MagickChannelOptions} } },
428 { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
429 {"height", IntegerReference}, {"x", IntegerReference},
430 {"y", IntegerReference}, {"fuzz", StringReference},
431 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
432 { "Posterize", { {"levels", IntegerReference},
433 {"dither", MagickBooleanOptions} } },
434 { "Shadow", { {"geometry", StringReference}, {"opacity", RealReference},
435 {"sigma", RealReference}, {"x", IntegerReference},
436 {"y", IntegerReference} } },
437 { "Identify", { {"file", FileReference} } },
438 { "SepiaTone", { {"threshold", RealReference} } },
439 { "SigmoidalContrast", { {"geometry", StringReference},
440 {"contrast", RealReference}, {"mid-point", RealReference},
441 {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
442 { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
443 {"height", IntegerReference}, {"x", IntegerReference},
444 {"y", IntegerReference}, {"fuzz", StringReference},
445 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
446 { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
447 {"sigma", RealReference}, {"x", IntegerReference},
448 {"y", IntegerReference}, {"background", StringReference} } },
449 { "ContrastStretch", { {"levels", StringReference},
450 {"black-point", RealReference},{"white-point", RealReference},
451 {"channel", MagickChannelOptions} } },
452 { "Sans0", },
453 { "Sans1", },
454 { "AdaptiveSharpen", { {"geometry", StringReference},
455 {"radius", RealReference}, {"sigma", RealReference},
456 {"channel", MagickChannelOptions} } },
457 { "Transpose", },
458 { "Transverse", },
459 { "AutoOrient", },
460 { "AdaptiveBlur", { {"geometry", StringReference},
461 {"radius", RealReference}, {"sigma", RealReference},
462 {"channel", MagickChannelOptions} } },
463 { "Sketch", { {"geometry", StringReference},
464 {"radius", RealReference}, {"sigma", RealReference},
465 {"angle", RealReference} } },
466 { "UniqueColors", },
467 { "AdaptiveResize", { {"geometry", StringReference},
468 {"width", IntegerReference}, {"height", IntegerReference},
469 {"filter", MagickFilterOptions}, {"support", StringReference },
470 {"blur", RealReference } } },
471 { "ClipMask", { {"mask", ImageReference} } },
472 { "LinearStretch", { {"levels", StringReference},
473 {"black-point", RealReference},{"white-point", RealReference} } },
474 { "Recolor", { {"matrix", ArrayReference} } },
475 { "Mask", { {"mask", ImageReference} } },
476 { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
477 {"font", StringReference}, {"stroke", StringReference},
478 {"fill", StringReference}, {"strokewidth", RealReference},
479 {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
480 {"background", StringReference} } },
481 { "FloodfillPaint", { {"geometry", StringReference},
482 {"x", IntegerReference}, {"y", IntegerReference},
483 {"fill", StringReference}, {"bordercolor", StringReference},
484 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
485 {"invert", MagickBooleanOptions} } },
486 { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
487 {"virtual-pixel", MagickVirtualPixelOptions},
488 {"best-fit", MagickBooleanOptions} } },
489 { "Clut", { {"image", ImageReference},
490 {"channel", MagickChannelOptions} } },
491 { "LiquidRescale", { {"geometry", StringReference},
492 {"width", IntegerReference}, {"height", IntegerReference},
493 {"delta-x", RealReference}, {"rigidity", RealReference } } },
494 { "Encipher", { {"passphrase", StringReference} } },
495 { "Decipher", { {"passphrase", StringReference} } },
496 { "Deskew", { {"geometry", StringReference},
497 {"threshold", StringReference} } },
498 { "Remap", { {"image", ImageReference},
499 {"dither-method", MagickDitherOptions} } },
500 { "SparseColor", { {"points", ArrayReference},
501 {"method", MagickSparseColorOptions},
502 {"virtual-pixel", MagickVirtualPixelOptions},
503 {"channel", MagickChannelOptions} } },
504 { "Function", { {"parameters", ArrayReference},
505 {"function", MagickFunctionOptions},
506 {"virtual-pixel", MagickVirtualPixelOptions} } },
507 { "SelectiveBlur", { {"geometry", StringReference},
508 {"radius", RealReference}, {"sigma", RealReference},
509 {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
510 { "HaldClut", { {"image", ImageReference},
511 {"channel", MagickChannelOptions} } },
512 { "BlueShift", {"factor", StringReference} },
513 { "ForwardFourierTransform", {"magnitude", MagickBooleanOptions} },
514 { "InverseFourierTransform", {"magnitude", MagickBooleanOptions} },
515 { "ColorDecisionList", {
516 {"color-correction-collection", StringReference} } },
517 { "AutoGamma", { {"channel", MagickChannelOptions} } },
518 { "AutoLevel", { {"channel", MagickChannelOptions} } },
cristyee0f8d72009-09-19 00:58:29 +0000519 { "LevelColors", { {"invert", MagickBooleanOptions},
520 {"black-point", RealReference}, {"white-point", RealReference},
521 {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
cristy3ed852e2009-09-05 21:47:34 +0000522 };
523
524static SplayTreeInfo
525 *magick_registry = (SplayTreeInfo *) NULL;
526
527/*
528 Forward declarations.
529*/
530static Image
531 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
532
533static long
534 strEQcase(const char *,const char *);
535
536/*
537%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
538% %
539% %
540% %
541% C l o n e P a c k a g e I n f o %
542% %
543% %
544% %
545%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
546%
547% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
548% a new one.
549%
550% The format of the ClonePackageInfo routine is:
551%
552% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
553% exception)
554%
555% A description of each parameter follows:
556%
557% o info: a structure of type info.
558%
559% o exception: Return any errors or warnings in this structure.
560%
561*/
562static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
563 ExceptionInfo *exception)
564{
565 struct PackageInfo
566 *clone_info;
567
568 clone_info=(struct PackageInfo *) AcquireMagickMemory(sizeof(*clone_info));
569 if (clone_info == (struct PackageInfo *) NULL)
570 {
571 ThrowPerlException(exception,ResourceLimitError,
572 "UnableToClonePackageInfo",PackageName);
573 return((struct PackageInfo *) NULL);
574 }
575 if (info == (struct PackageInfo *) NULL)
576 {
577 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
578 return(clone_info);
579 }
580 *clone_info=(*info);
581 clone_info->image_info=CloneImageInfo(info->image_info);
582 return(clone_info);
583}
584
585/*
586%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
587% %
588% %
589% %
590% c o n s t a n t %
591% %
592% %
593% %
594%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
595%
596% constant() returns a double value for the specified name.
597%
598% The format of the constant routine is:
599%
600% double constant(char *name,long sans)
601%
602% A description of each parameter follows:
603%
604% o value: Method constant returns a double value for the specified name.
605%
606% o name: The name of the constant.
607%
608% o sans: This integer value is not used.
609%
610*/
611static double constant(char *name,long sans)
612{
613 (void) sans;
614 errno=0;
615 switch (*name)
616 {
617 case 'B':
618 {
619 if (strEQ(name,"BlobError"))
620 return(BlobError);
621 if (strEQ(name,"BlobWarning"))
622 return(BlobWarning);
623 break;
624 }
625 case 'C':
626 {
627 if (strEQ(name,"CacheError"))
628 return(CacheError);
629 if (strEQ(name,"CacheWarning"))
630 return(CacheWarning);
631 if (strEQ(name,"CoderError"))
632 return(CoderError);
633 if (strEQ(name,"CoderWarning"))
634 return(CoderWarning);
635 if (strEQ(name,"ConfigureError"))
636 return(ConfigureError);
637 if (strEQ(name,"ConfigureWarning"))
638 return(ConfigureWarning);
639 if (strEQ(name,"CorruptImageError"))
640 return(CorruptImageError);
641 if (strEQ(name,"CorruptImageWarning"))
642 return(CorruptImageWarning);
643 break;
644 }
645 case 'D':
646 {
647 if (strEQ(name,"DelegateError"))
648 return(DelegateError);
649 if (strEQ(name,"DelegateWarning"))
650 return(DelegateWarning);
651 if (strEQ(name,"DrawError"))
652 return(DrawError);
653 if (strEQ(name,"DrawWarning"))
654 return(DrawWarning);
655 break;
656 }
657 case 'E':
658 {
659 if (strEQ(name,"ErrorException"))
660 return(ErrorException);
661 if (strEQ(name,"ExceptionError"))
662 return(CoderError);
663 if (strEQ(name,"ExceptionWarning"))
664 return(CoderWarning);
665 break;
666 }
667 case 'F':
668 {
669 if (strEQ(name,"FatalErrorException"))
670 return(FatalErrorException);
671 if (strEQ(name,"FileOpenError"))
672 return(FileOpenError);
673 if (strEQ(name,"FileOpenWarning"))
674 return(FileOpenWarning);
675 break;
676 }
677 case 'I':
678 {
679 if (strEQ(name,"ImageError"))
680 return(ImageError);
681 if (strEQ(name,"ImageWarning"))
682 return(ImageWarning);
683 break;
684 }
685 case 'M':
686 {
687 if (strEQ(name,"MaxRGB"))
688 return(QuantumRange);
689 if (strEQ(name,"MissingDelegateError"))
690 return(MissingDelegateError);
691 if (strEQ(name,"MissingDelegateWarning"))
692 return(MissingDelegateWarning);
693 if (strEQ(name,"ModuleError"))
694 return(ModuleError);
695 if (strEQ(name,"ModuleWarning"))
696 return(ModuleWarning);
697 break;
698 }
699 case 'O':
700 {
701 if (strEQ(name,"Opaque"))
702 return(OpaqueOpacity);
703 if (strEQ(name,"OptionError"))
704 return(OptionError);
705 if (strEQ(name,"OptionWarning"))
706 return(OptionWarning);
707 break;
708 }
709 case 'Q':
710 {
711 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
712 return(MAGICKCORE_QUANTUM_DEPTH);
713 if (strEQ(name,"QuantumDepth"))
714 return(QuantumDepth);
715 if (strEQ(name,"QuantumRange"))
716 return(QuantumRange);
717 break;
718 }
719 case 'R':
720 {
721 if (strEQ(name,"ResourceLimitError"))
722 return(ResourceLimitError);
723 if (strEQ(name,"ResourceLimitWarning"))
724 return(ResourceLimitWarning);
725 if (strEQ(name,"RegistryError"))
726 return(RegistryError);
727 if (strEQ(name,"RegistryWarning"))
728 return(RegistryWarning);
729 break;
730 }
731 case 'S':
732 {
733 if (strEQ(name,"StreamError"))
734 return(StreamError);
735 if (strEQ(name,"StreamWarning"))
736 return(StreamWarning);
737 if (strEQ(name,"Success"))
738 return(0);
739 break;
740 }
741 case 'T':
742 {
743 if (strEQ(name,"Transparent"))
744 return(TransparentOpacity);
745 if (strEQ(name,"TypeError"))
746 return(TypeError);
747 if (strEQ(name,"TypeWarning"))
748 return(TypeWarning);
749 break;
750 }
751 case 'W':
752 {
753 if (strEQ(name,"WarningException"))
754 return(WarningException);
755 break;
756 }
757 case 'X':
758 {
759 if (strEQ(name,"XServerError"))
760 return(XServerError);
761 if (strEQ(name,"XServerWarning"))
762 return(XServerWarning);
763 break;
764 }
765 }
766 errno=EINVAL;
767 return(0);
768}
769
770/*
771%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
772% %
773% %
774% %
775% D e s t r o y P a c k a g e I n f o %
776% %
777% %
778% %
779%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
780%
781% Method DestroyPackageInfo frees a previously created info structure.
782%
783% The format of the DestroyPackageInfo routine is:
784%
785% DestroyPackageInfo(struct PackageInfo *info)
786%
787% A description of each parameter follows:
788%
789% o info: a structure of type info.
790%
791*/
792static void DestroyPackageInfo(struct PackageInfo *info)
793{
794 info->image_info=DestroyImageInfo(info->image_info);
795 info=(struct PackageInfo *) RelinquishMagickMemory(info);
796}
797
798/*
799%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
800% %
801% %
802% %
803% G e t L i s t %
804% %
805% %
806% %
807%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
808%
809% Method GetList is recursively called by SetupList to traverse the
810% Image__Magick reference. If building an reference_vector (see SetupList),
811% *current is the current position in *reference_vector and *last is the final
812% entry in *reference_vector.
813%
814% The format of the GetList routine is:
815%
816% GetList(info)
817%
818% A description of each parameter follows:
819%
820% o info: a structure of type info.
821%
822*/
823static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,long *current,
824 long *last,ExceptionInfo *exception)
825{
826 Image
827 *image;
828
829 if (reference == (SV *) NULL)
830 return(NULL);
831 switch (SvTYPE(reference))
832 {
833 case SVt_PVAV:
834 {
835 AV
836 *av;
837
838 Image
839 *head,
840 *previous;
841
842 long
843 n;
844
845 register long
846 i;
847
848 /*
849 Array of images.
850 */
851 previous=(Image *) NULL;
852 head=(Image *) NULL;
853 av=(AV *) reference;
854 n=av_len(av);
855 for (i=0; i <= n; i++)
856 {
857 SV
858 **rv;
859
860 rv=av_fetch(av,i,0);
861 if (rv && *rv && sv_isobject(*rv))
862 {
863 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
864 exception);
865 if (image == (Image *) NULL)
866 continue;
867 if (image == previous)
868 {
869 image=CloneImage(image,0,0,MagickTrue,exception);
870 if (image == (Image *) NULL)
871 return(NULL);
872 }
873 image->previous=previous;
874 *(previous ? &previous->next : &head)=image;
875 for (previous=image; previous->next; previous=previous->next) ;
876 }
877 }
878 return(head);
879 }
880 case SVt_PVMG:
881 {
882 /*
883 Blessed scalar, one image.
884 */
885 image=(Image *) SvIV(reference);
886 if (image == (Image *) NULL)
887 return(NULL);
888 image->previous=(Image *) NULL;
889 image->next=(Image *) NULL;
890 if (reference_vector)
891 {
892 if (*current == *last)
893 {
894 *last+=256;
895 if (*reference_vector == (SV **) NULL)
896 *reference_vector=(SV **) AcquireQuantumMemory(*last,
897 sizeof(*reference_vector));
898 else
899 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
900 *last,sizeof(*reference_vector));
901 }
902 if (*reference_vector == (SV **) NULL)
903 {
904 ThrowPerlException(exception,ResourceLimitError,
905 "MemoryAllocationFailed",PackageName);
906 return((Image *) NULL);
907 }
908 (*reference_vector)[*current]=reference;
909 (*reference_vector)[++(*current)]=NULL;
910 }
911 return(image);
912 }
913 default:
914 break;
915 }
916 (void) fprintf(stderr,"GetList: UnrecognizedType %ld\n",
917 (long) SvTYPE(reference));
918 return((Image *) NULL);
919}
920
921/*
922%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
923% %
924% %
925% %
926% G e t P a c k a g e I n f o %
927% %
928% %
929% %
930%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
931%
932% Method GetPackageInfo looks up or creates an info structure for the given
933% Image__Magick reference. If it does create a new one, the information in
934% package_info is used to initialize it.
935%
936% The format of the GetPackageInfo routine is:
937%
938% struct PackageInfo *GetPackageInfo(void *reference,
939% struct PackageInfo *package_info,ExceptionInfo *exception)
940%
941% A description of each parameter follows:
942%
943% o info: a structure of type info.
944%
945% o exception: Return any errors or warnings in this structure.
946%
947*/
948static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
949 struct PackageInfo *package_info,ExceptionInfo *exception)
950{
951 char
952 message[MaxTextExtent];
953
954 struct PackageInfo
955 *clone_info;
956
957 SV
958 *sv;
959
960 (void) FormatMagickString(message,MaxTextExtent,"%s::package%s%lx",
961 PackageName,XS_VERSION,(long) reference);
962 sv=perl_get_sv(message,(TRUE | 0x02));
963 if (sv == (SV *) NULL)
964 {
965 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
966 message);
967 return(package_info);
968 }
969 if (SvREFCNT(sv) == 0)
970 (void) SvREFCNT_inc(sv);
971 if (SvIOKp(sv) && (clone_info=(struct PackageInfo *) SvIV(sv)))
972 return(clone_info);
973 clone_info=ClonePackageInfo(package_info,exception);
974 sv_setiv(sv,(IV) clone_info);
975 return(clone_info);
976}
977
978/*
979%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
980% %
981% %
982% %
983% S e t A t t r i b u t e %
984% %
985% %
986% %
987%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
988%
989% SetAttribute() sets the attribute to the value in sval. This can change
990% either or both of image or info.
991%
992% The format of the SetAttribute routine is:
993%
994% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
995% SV *sval,ExceptionInfo *exception)
996%
997% A description of each parameter follows:
998%
999% o list: a list of strings.
1000%
1001% o string: a character string.
1002%
1003*/
1004static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1005 const char *attribute,SV *sval,ExceptionInfo *exception)
1006{
1007 GeometryInfo
1008 geometry_info;
1009
1010 long
1011 sp;
1012
1013 long
1014 x,
1015 y;
1016
1017 MagickPixelPacket
1018 pixel;
1019
1020 MagickStatusType
1021 flags;
1022
1023 PixelPacket
1024 *color,
1025 target_color;
1026
1027 switch (*attribute)
1028 {
1029 case 'A':
1030 case 'a':
1031 {
1032 if (LocaleCompare(attribute,"adjoin") == 0)
1033 {
1034 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1035 SvPV(sval,na)) : SvIV(sval);
1036 if (sp < 0)
1037 {
1038 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1039 SvPV(sval,na));
1040 break;
1041 }
1042 if (info)
1043 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1044 break;
1045 }
1046 if (LocaleCompare(attribute,"alpha") == 0)
1047 {
1048 sp=SvPOK(sval) ? ParseMagickOption(MagickAlphaOptions,MagickFalse,
1049 SvPV(sval,na)) : SvIV(sval);
1050 if (sp < 0)
1051 {
1052 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1053 SvPV(sval,na));
1054 break;
1055 }
1056 for ( ; image; image=image->next)
1057 (void) SetImageAlphaChannel(image,(AlphaChannelType) sp);
1058 break;
1059 }
1060 if (LocaleCompare(attribute,"antialias") == 0)
1061 {
1062 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1063 SvPV(sval,na)) : SvIV(sval);
1064 if (sp < 0)
1065 {
1066 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1067 SvPV(sval,na));
1068 break;
1069 }
1070 if (info)
1071 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1072 break;
1073 }
1074 if (LocaleCompare(attribute,"area-limit") == 0)
1075 {
1076 MagickSizeType
1077 limit;
1078
1079 limit=MagickResourceInfinity;
1080 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1081 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1082 (void) SetMagickResourceLimit(AreaResource,limit);
1083 break;
1084 }
1085 if (LocaleCompare(attribute,"attenuate") == 0)
1086 {
1087 if (info)
1088 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1089 break;
1090 }
1091 if (LocaleCompare(attribute,"authenticate") == 0)
1092 {
1093 if (info)
1094 (void) CloneString(&info->image_info->authenticate,SvPV(sval,na));
1095 break;
1096 }
1097 if (info)
1098 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1099 for ( ; image; image=image->next)
1100 SetImageProperty(image,attribute,SvPV(sval,na));
1101 break;
1102 }
1103 case 'B':
1104 case 'b':
1105 {
1106 if (LocaleCompare(attribute,"background") == 0)
1107 {
1108 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
1109 if (info)
1110 info->image_info->background_color=target_color;
1111 for ( ; image; image=image->next)
1112 image->background_color=target_color;
1113 break;
1114 }
1115 if (LocaleCompare(attribute,"bias") == 0)
1116 {
1117 for ( ; image; image=image->next)
1118 image->bias=StringToDouble(SvPV(sval,na),QuantumRange);
1119 break;
1120 }
1121 if (LocaleCompare(attribute,"blue-primary") == 0)
1122 {
1123 for ( ; image; image=image->next)
1124 {
1125 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1126 image->chromaticity.blue_primary.x=geometry_info.rho;
1127 image->chromaticity.blue_primary.y=geometry_info.sigma;
1128 if ((flags & SigmaValue) == 0)
1129 image->chromaticity.blue_primary.y=
1130 image->chromaticity.blue_primary.x;
1131 }
1132 break;
1133 }
1134 if (LocaleCompare(attribute,"bordercolor") == 0)
1135 {
1136 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
1137 if (info)
1138 info->image_info->border_color=target_color;
1139 for ( ; image; image=image->next)
1140 image->border_color=target_color;
1141 break;
1142 }
1143 if (info)
1144 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1145 for ( ; image; image=image->next)
1146 SetImageProperty(image,attribute,SvPV(sval,na));
1147 break;
1148 }
1149 case 'C':
1150 case 'c':
1151 {
1152 if (LocaleCompare(attribute,"cache-threshold") == 0)
1153 {
1154 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1155 StringToDouble(SvPV(sval,na),100.0));
1156 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1157 (2*StringToDouble(SvPV(sval,na),100.0)));
1158 break;
1159 }
1160 if (LocaleCompare(attribute,"clip-mask") == 0)
1161 {
1162 Image
1163 *clip_mask;
1164
1165 clip_mask=(Image *) NULL;
1166 if (SvPOK(sval))
1167 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1168 for ( ; image; image=image->next)
1169 SetImageClipMask(image,clip_mask);
1170 break;
1171 }
1172 if (LocaleNCompare(attribute,"colormap",8) == 0)
1173 {
1174 for ( ; image; image=image->next)
1175 {
1176 int
1177 items;
1178
1179 long
1180 i;
1181
1182 if (image->storage_class == DirectClass)
1183 continue;
1184 i=0;
1185 items=sscanf(attribute,"%*[^[][%ld",&i);
1186 if (i > (long) image->colors)
1187 i%=image->colors;
1188 if ((strchr(SvPV(sval,na),',') == 0) ||
1189 (strchr(SvPV(sval,na),')') != 0))
1190 QueryColorDatabase(SvPV(sval,na),image->colormap+i,exception);
1191 else
1192 {
1193 color=image->colormap+i;
1194 pixel.red=color->red;
1195 pixel.green=color->green;
1196 pixel.blue=color->blue;
1197 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1198 pixel.red=geometry_info.rho;
1199 pixel.green=geometry_info.sigma;
1200 pixel.blue=geometry_info.xi;
1201 color->red=RoundToQuantum(pixel.red);
1202 color->green=RoundToQuantum(pixel.green);
1203 color->blue=RoundToQuantum(pixel.blue);
1204 }
1205 }
1206 break;
1207 }
1208 if (LocaleCompare(attribute,"colorspace") == 0)
1209 {
1210 sp=SvPOK(sval) ? ParseMagickOption(MagickColorspaceOptions,
1211 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1212 if (sp < 0)
1213 {
1214 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1215 SvPV(sval,na));
1216 break;
1217 }
1218 for ( ; image; image=image->next)
1219 (void) TransformImageColorspace(image,(ColorspaceType) sp);
1220 break;
1221 }
1222 if (LocaleCompare(attribute,"comment") == 0)
1223 {
1224 for ( ; image; image=image->next)
1225 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1226 info ? info->image_info : (ImageInfo *) NULL,image,
1227 SvPV(sval,na)));
1228 break;
1229 }
1230 if (LocaleCompare(attribute,"compression") == 0)
1231 {
1232 sp=SvPOK(sval) ? ParseMagickOption(MagickCompressOptions,
1233 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1234 if (sp < 0)
1235 {
1236 ThrowPerlException(exception,OptionError,
1237 "UnrecognizedImageCompression",SvPV(sval,na));
1238 break;
1239 }
1240 if (info)
1241 info->image_info->compression=(CompressionType) sp;
1242 for ( ; image; image=image->next)
1243 image->compression=(CompressionType) sp;
1244 break;
1245 }
1246 if (info)
1247 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1248 for ( ; image; image=image->next)
1249 SetImageProperty(image,attribute,SvPV(sval,na));
1250 break;
1251 }
1252 case 'D':
1253 case 'd':
1254 {
1255 if (LocaleCompare(attribute,"debug") == 0)
1256 {
1257 SetLogEventMask(SvPV(sval,na));
1258 break;
1259 }
1260 if (LocaleCompare(attribute,"delay") == 0)
1261 {
1262 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1263 for ( ; image; image=image->next)
1264 {
1265 image->delay=(unsigned long) (geometry_info.rho+0.5);
1266 if ((flags & SigmaValue) != 0)
1267 image->ticks_per_second=(unsigned long) (geometry_info.sigma+0.5);
1268 }
1269 break;
1270 }
1271 if (LocaleCompare(attribute,"disk-limit") == 0)
1272 {
1273 MagickSizeType
1274 limit;
1275
1276 limit=MagickResourceInfinity;
1277 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1278 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1279 (void) SetMagickResourceLimit(DiskResource,limit);
1280 break;
1281 }
1282 if (LocaleCompare(attribute,"density") == 0)
1283 {
1284 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1285 {
1286 ThrowPerlException(exception,OptionError,"MissingGeometry",
1287 SvPV(sval,na));
1288 break;
1289 }
1290 if (info)
1291 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1292 for ( ; image; image=image->next)
1293 {
1294 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1295 image->x_resolution=geometry_info.rho;
1296 image->y_resolution=geometry_info.sigma;
1297 if ((flags & SigmaValue) == 0)
1298 image->y_resolution=image->x_resolution;
1299 }
1300 break;
1301 }
1302 if (LocaleCompare(attribute,"depth") == 0)
1303 {
1304 if (info)
1305 info->image_info->depth=SvIV(sval);
1306 for ( ; image; image=image->next)
1307 (void) SetImageDepth(image,SvIV(sval));
1308 break;
1309 }
1310 if (LocaleCompare(attribute,"dispose") == 0)
1311 {
1312 sp=SvPOK(sval) ? ParseMagickOption(MagickDisposeOptions,MagickFalse,
1313 SvPV(sval,na)) : SvIV(sval);
1314 if (sp < 0)
1315 {
1316 ThrowPerlException(exception,OptionError,
1317 "UnrecognizedDisposeMethod",SvPV(sval,na));
1318 break;
1319 }
1320 for ( ; image; image=image->next)
1321 image->dispose=(DisposeType) sp;
1322 break;
1323 }
1324 if (LocaleCompare(attribute,"dither") == 0)
1325 {
1326 if (info)
1327 {
1328 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,
1329 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1330 if (sp < 0)
1331 {
1332 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1333 SvPV(sval,na));
1334 break;
1335 }
1336 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1337 }
1338 break;
1339 }
1340 if (LocaleCompare(attribute,"display") == 0)
1341 {
1342 display:
1343 if (info)
1344 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1345 break;
1346 }
1347 if (info)
1348 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1349 for ( ; image; image=image->next)
1350 SetImageProperty(image,attribute,SvPV(sval,na));
1351 break;
1352 }
1353 case 'E':
1354 case 'e':
1355 {
1356 if (LocaleCompare(attribute,"endian") == 0)
1357 {
1358 sp=SvPOK(sval) ? ParseMagickOption(MagickEndianOptions,MagickFalse,
1359 SvPV(sval,na)) : SvIV(sval);
1360 if (sp < 0)
1361 {
1362 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1363 SvPV(sval,na));
1364 break;
1365 }
1366 if (info)
1367 info->image_info->endian=(EndianType) sp;
1368 for ( ; image; image=image->next)
1369 image->endian=(EndianType) sp;
1370 break;
1371 }
1372 if (LocaleCompare(attribute,"extract") == 0)
1373 {
1374 /*
1375 Set image extract geometry.
1376 */
1377 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1378 break;
1379 }
1380 if (info)
1381 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1382 for ( ; image; image=image->next)
1383 SetImageProperty(image,attribute,SvPV(sval,na));
1384 break;
1385 }
1386 case 'F':
1387 case 'f':
1388 {
1389 if (LocaleCompare(attribute,"filename") == 0)
1390 {
1391 if (info)
1392 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
1393 MaxTextExtent);
1394 for ( ; image; image=image->next)
1395 (void) CopyMagickString(image->filename,SvPV(sval,na),
1396 MaxTextExtent);
1397 break;
1398 }
1399 if (LocaleCompare(attribute,"file") == 0)
1400 {
1401 FILE
1402 *file;
1403
1404 PerlIO
1405 *io_info;
1406
1407 if (info == (struct PackageInfo *) NULL)
1408 break;
1409 io_info=IoIFP(sv_2io(sval));
1410 if (io_info == (PerlIO *) NULL)
1411 {
1412 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1413 PackageName);
1414 break;
1415 }
1416 file=PerlIO_findFILE(io_info);
1417 if (file == (FILE *) NULL)
1418 {
1419 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1420 PackageName);
1421 break;
1422 }
1423 SetImageInfoFile(info->image_info,file);
1424 break;
1425 }
1426 if (LocaleCompare(attribute,"fill") == 0)
1427 {
1428 if (info)
1429 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1430 break;
1431 }
1432 if (LocaleCompare(attribute,"font") == 0)
1433 {
1434 if (info)
1435 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1436 break;
1437 }
1438 if (LocaleCompare(attribute,"foreground") == 0)
1439 break;
1440 if (LocaleCompare(attribute,"fuzz") == 0)
1441 {
1442 if (info)
1443 info->image_info->fuzz=StringToDouble(SvPV(sval,na),QuantumRange);
1444 for ( ; image; image=image->next)
1445 image->fuzz=StringToDouble(SvPV(sval,na),QuantumRange);
1446 break;
1447 }
1448 if (info)
1449 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1450 for ( ; image; image=image->next)
1451 SetImageProperty(image,attribute,SvPV(sval,na));
1452 break;
1453 }
1454 case 'G':
1455 case 'g':
1456 {
1457 if (LocaleCompare(attribute,"gamma") == 0)
1458 {
1459 for ( ; image; image=image->next)
1460 image->gamma=SvNV(sval);
1461 break;
1462 }
1463 if (LocaleCompare(attribute,"gravity") == 0)
1464 {
1465 sp=SvPOK(sval) ? ParseMagickOption(MagickGravityOptions,MagickFalse,
1466 SvPV(sval,na)) : SvIV(sval);
1467 if (sp < 0)
1468 {
1469 ThrowPerlException(exception,OptionError,
1470 "UnrecognizedGravityType",SvPV(sval,na));
1471 break;
1472 }
1473 for ( ; image; image=image->next)
1474 image->gravity=(GravityType) sp;
1475 break;
1476 }
1477 if (LocaleCompare(attribute,"green-primary") == 0)
1478 {
1479 for ( ; image; image=image->next)
1480 {
1481 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1482 image->chromaticity.green_primary.x=geometry_info.rho;
1483 image->chromaticity.green_primary.y=geometry_info.sigma;
1484 if ((flags & SigmaValue) == 0)
1485 image->chromaticity.green_primary.y=
1486 image->chromaticity.green_primary.x;
1487 }
1488 break;
1489 }
1490 if (info)
1491 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1492 for ( ; image; image=image->next)
1493 SetImageProperty(image,attribute,SvPV(sval,na));
1494 break;
1495 }
1496 case 'I':
1497 case 'i':
1498 {
1499 if (LocaleNCompare(attribute,"index",5) == 0)
1500 {
1501 IndexPacket
1502 *indexes;
1503
1504 int
1505 items;
1506
1507 long
1508 index;
1509
1510 register PixelPacket
1511 *p;
1512
1513 CacheView
1514 *image_view;
1515
1516 for ( ; image; image=image->next)
1517 {
1518 if (image->storage_class != PseudoClass)
1519 continue;
1520 x=0;
1521 y=0;
1522 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1523 image_view=OpenCacheView(image);
1524 p=GetCacheViewPixels(image_view,x,y,1,1);
1525 if (p != (PixelPacket *) NULL)
1526 {
1527 indexes=GetCacheViewIndexes(image_view);
1528 items=sscanf(SvPV(sval,na),"%ld",&index);
1529 if ((index >= 0) && (index < (long) image->colors))
1530 *indexes=(IndexPacket) index;
1531 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1532 }
1533 image_view=CloseCacheView(image_view);
1534 }
1535 break;
1536 }
1537 if (LocaleCompare(attribute,"iterations") == 0)
1538 {
1539 iterations:
1540 for ( ; image; image=image->next)
1541 image->iterations=SvIV(sval);
1542 break;
1543 }
1544 if (LocaleCompare(attribute,"interlace") == 0)
1545 {
1546 sp=SvPOK(sval) ? ParseMagickOption(MagickInterlaceOptions,MagickFalse,
1547 SvPV(sval,na)) : SvIV(sval);
1548 if (sp < 0)
1549 {
1550 ThrowPerlException(exception,OptionError,
1551 "UnrecognizedInterlaceType",SvPV(sval,na));
1552 break;
1553 }
1554 if (info)
1555 info->image_info->interlace=(InterlaceType) sp;
1556 for ( ; image; image=image->next)
1557 image->interlace=(InterlaceType) sp;
1558 break;
1559 }
1560 if (info)
1561 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1562 for ( ; image; image=image->next)
1563 SetImageProperty(image,attribute,SvPV(sval,na));
1564 break;
1565 }
1566 case 'L':
1567 case 'l':
1568 {
1569 if (LocaleCompare(attribute,"label") == 0)
1570 {
1571 for ( ; image; image=image->next)
1572 (void) SetImageProperty(image,"label",InterpretImageProperties(
1573 info ? info->image_info : (ImageInfo *) NULL,image,
1574 SvPV(sval,na)));
1575 break;
1576 }
1577 if (LocaleCompare(attribute,"loop") == 0)
1578 goto iterations;
1579 if (info)
1580 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1581 for ( ; image; image=image->next)
1582 SetImageProperty(image,attribute,SvPV(sval,na));
1583 break;
1584 }
1585 case 'M':
1586 case 'm':
1587 {
1588 if (LocaleCompare(attribute,"magick") == 0)
1589 {
1590 if (info)
1591 (void) FormatMagickString(info->image_info->filename,MaxTextExtent,
1592 "%.1024s:",SvPV(sval,na));
1593 for ( ; image; image=image->next)
1594 (void) CopyMagickString(image->magick,SvPV(sval,na),MaxTextExtent);
1595 break;
1596 }
1597 if (LocaleCompare(attribute,"map-limit") == 0)
1598 {
1599 MagickSizeType
1600 limit;
1601
1602 limit=MagickResourceInfinity;
1603 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1604 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1605 (void) SetMagickResourceLimit(MapResource,limit);
1606 break;
1607 }
1608 if (LocaleCompare(attribute,"mask") == 0)
1609 {
1610 Image
1611 *mask;
1612
1613 mask=(Image *) NULL;
1614 if (SvPOK(sval))
1615 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1616 for ( ; image; image=image->next)
1617 SetImageMask(image,mask);
1618 break;
1619 }
1620 if (LocaleCompare(attribute,"mattecolor") == 0)
1621 {
1622 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
1623 if (info)
1624 info->image_info->matte_color=target_color;
1625 for ( ; image; image=image->next)
1626 image->matte_color=target_color;
1627 break;
1628 }
1629 if (LocaleCompare(attribute,"matte") == 0)
1630 {
1631 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1632 SvPV(sval,na)) : SvIV(sval);
1633 if (sp < 0)
1634 {
1635 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1636 SvPV(sval,na));
1637 break;
1638 }
1639 for ( ; image; image=image->next)
1640 image->matte=sp != 0 ? MagickTrue : MagickFalse;
1641 break;
1642 }
1643 if (LocaleCompare(attribute,"memory-limit") == 0)
1644 {
1645 MagickSizeType
1646 limit;
1647
1648 limit=MagickResourceInfinity;
1649 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1650 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1651 (void) SetMagickResourceLimit(MemoryResource,limit);
1652 break;
1653 }
1654 if (LocaleCompare(attribute,"monochrome") == 0)
1655 {
1656 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1657 SvPV(sval,na)) : SvIV(sval);
1658 if (sp < 0)
1659 {
1660 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1661 SvPV(sval,na));
1662 break;
1663 }
1664 if (info)
1665 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1666 for ( ; image; image=image->next)
1667 (void) SetImageType(image,BilevelType);
1668 break;
1669 }
1670 if (info)
1671 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1672 for ( ; image; image=image->next)
1673 SetImageProperty(image,attribute,SvPV(sval,na));
1674 break;
1675 }
1676 case 'O':
1677 case 'o':
1678 {
1679 if (LocaleCompare(attribute,"option") == 0)
1680 {
1681 if (info)
1682 DefineImageOption(info->image_info,SvPV(sval,na));
1683 break;
1684 }
1685 if (LocaleCompare(attribute,"orientation") == 0)
1686 {
1687 sp=SvPOK(sval) ? ParseMagickOption(MagickOrientationOptions,
1688 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1689 if (sp < 0)
1690 {
1691 ThrowPerlException(exception,OptionError,
1692 "UnrecognizedOrientationType",SvPV(sval,na));
1693 break;
1694 }
1695 if (info)
1696 info->image_info->orientation=(OrientationType) sp;
1697 for ( ; image; image=image->next)
1698 image->orientation=(OrientationType) sp;
1699 break;
1700 }
1701 if (info)
1702 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1703 for ( ; image; image=image->next)
1704 SetImageProperty(image,attribute,SvPV(sval,na));
1705 break;
1706 }
1707 case 'P':
1708 case 'p':
1709 {
1710 if (LocaleCompare(attribute,"page") == 0)
1711 {
1712 char
1713 *geometry;
1714
1715 geometry=GetPageGeometry(SvPV(sval,na));
1716 if (info)
1717 (void) CloneString(&info->image_info->page,geometry);
1718 for ( ; image; image=image->next)
1719 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1720 geometry=(char *) RelinquishMagickMemory(geometry);
1721 break;
1722 }
1723 if (LocaleCompare(attribute,"pen") == 0)
1724 {
1725 if (info)
1726 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1727 break;
1728 }
1729 if (LocaleNCompare(attribute,"pixel",5) == 0)
1730 {
1731 int
1732 items;
1733
1734 MagickPixelPacket
1735 pixel;
1736
1737 register IndexPacket
1738 *indexes;
1739
1740 register PixelPacket
1741 *p;
1742
1743 CacheView
1744 *image_view;
1745
1746 for ( ; image; image=image->next)
1747 {
1748 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1749 break;
1750 x=0;
1751 y=0;
1752 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1753 image_view=OpenCacheView(image);
1754 p=GetCacheViewPixels(image_view,x,y,1,1);
1755 indexes=GetCacheViewIndexes(image_view);
1756 if (p != (PixelPacket *) NULL)
1757 {
1758 if ((strchr(SvPV(sval,na),',') == 0) ||
1759 (strchr(SvPV(sval,na),')') != 0))
1760 QueryMagickColor(SvPV(sval,na),&pixel,exception);
1761 else
1762 {
1763 GetMagickPixelPacket(image,&pixel);
1764 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1765 pixel.red=geometry_info.rho;
1766 if ((flags & SigmaValue) != 0)
1767 pixel.green=geometry_info.sigma;
1768 if ((flags & XiValue) != 0)
1769 pixel.blue=geometry_info.xi;
1770 if ((flags & PsiValue) != 0)
1771 pixel.opacity=geometry_info.psi;
1772 if ((flags & ChiValue) != 0)
1773 pixel.index=geometry_info.chi;
1774 }
1775 p->red=RoundToQuantum(pixel.red);
1776 p->green=RoundToQuantum(pixel.green);
1777 p->blue=RoundToQuantum(pixel.blue);
1778 p->opacity=RoundToQuantum(pixel.opacity);
1779 if (((image->colorspace == CMYKColorspace) ||
1780 (image->storage_class == PseudoClass)) &&
1781 (indexes != (IndexPacket *) NULL))
1782 *indexes=RoundToQuantum(pixel.index);
1783 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1784 }
1785 image_view=CloseCacheView(image_view);
1786 }
1787 break;
1788 }
1789 if (LocaleCompare(attribute,"pointsize") == 0)
1790 {
1791 if (info)
1792 {
1793 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1794 info->image_info->pointsize=geometry_info.rho;
1795 }
1796 break;
1797 }
1798 if (LocaleCompare(attribute,"preview") == 0)
1799 {
1800 sp=SvPOK(sval) ? ParseMagickOption(MagickPreviewOptions,MagickFalse,
1801 SvPV(sval,na)) : SvIV(sval);
1802 if (sp < 0)
1803 {
1804 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1805 SvPV(sval,na));
1806 break;
1807 }
1808 if (info)
1809 info->image_info->preview_type=(PreviewType) sp;
1810 break;
1811 }
1812 if (info)
1813 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1814 for ( ; image; image=image->next)
1815 SetImageProperty(image,attribute,SvPV(sval,na));
1816 break;
1817 }
1818 case 'Q':
1819 case 'q':
1820 {
1821 if (LocaleCompare(attribute,"quality") == 0)
1822 {
1823 if (info)
1824 info->image_info->quality=SvIV(sval);
1825 for ( ; image; image=image->next)
1826 image->quality=SvIV(sval);
1827 break;
1828 }
1829 if (info)
1830 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1831 for ( ; image; image=image->next)
1832 SetImageProperty(image,attribute,SvPV(sval,na));
1833 break;
1834 }
1835 case 'R':
1836 case 'r':
1837 {
1838 if (LocaleCompare(attribute,"red-primary") == 0)
1839 {
1840 for ( ; image; image=image->next)
1841 {
1842 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1843 image->chromaticity.red_primary.x=geometry_info.rho;
1844 image->chromaticity.red_primary.y=geometry_info.sigma;
1845 if ((flags & SigmaValue) == 0)
1846 image->chromaticity.red_primary.y=
1847 image->chromaticity.red_primary.x;
1848 }
1849 break;
1850 }
1851 if (LocaleCompare(attribute,"render") == 0)
1852 {
1853 sp=SvPOK(sval) ? ParseMagickOption(MagickIntentOptions,MagickFalse,
1854 SvPV(sval,na)) : SvIV(sval);
1855 if (sp < 0)
1856 {
1857 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1858 SvPV(sval,na));
1859 break;
1860 }
1861 for ( ; image; image=image->next)
1862 image->rendering_intent=(RenderingIntent) sp;
1863 break;
1864 }
1865 if (LocaleCompare(attribute,"repage") == 0)
1866 {
1867 RectangleInfo
1868 geometry;
1869
1870 for ( ; image; image=image->next)
1871 {
1872 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1873 if ((flags & WidthValue) != 0)
1874 {
1875 if ((flags & HeightValue) == 0)
1876 geometry.height=geometry.width;
1877 image->page.width=geometry.width;
1878 image->page.height=geometry.height;
1879 }
1880 if ((flags & AspectValue) != 0)
1881 {
1882 if ((flags & XValue) != 0)
1883 image->page.x+=geometry.x;
1884 if ((flags & YValue) != 0)
1885 image->page.y+=geometry.y;
1886 }
1887 else
1888 {
1889 if ((flags & XValue) != 0)
1890 {
1891 image->page.x=geometry.x;
1892 if (((flags & WidthValue) != 0) && (geometry.x > 0))
1893 image->page.width=image->columns+geometry.x;
1894 }
1895 if ((flags & YValue) != 0)
1896 {
1897 image->page.y=geometry.y;
1898 if (((flags & HeightValue) != 0) && (geometry.y > 0))
1899 image->page.height=image->rows+geometry.y;
1900 }
1901 }
1902 }
1903 break;
1904 }
1905 if (info)
1906 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1907 for ( ; image; image=image->next)
1908 SetImageProperty(image,attribute,SvPV(sval,na));
1909 break;
1910 }
1911 case 'S':
1912 case 's':
1913 {
1914 if (LocaleCompare(attribute,"sampling-factor") == 0)
1915 {
1916 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1917 {
1918 ThrowPerlException(exception,OptionError,"MissingGeometry",
1919 SvPV(sval,na));
1920 break;
1921 }
1922 if (info)
1923 (void) CloneString(&info->image_info->sampling_factor,
1924 SvPV(sval,na));
1925 break;
1926 }
1927 if (LocaleCompare(attribute,"scene") == 0)
1928 {
1929 for ( ; image; image=image->next)
1930 image->scene=SvIV(sval);
1931 break;
1932 }
1933 if (LocaleCompare(attribute,"subimage") == 0)
1934 {
1935 if (info)
1936 info->image_info->subimage=SvIV(sval);
1937 break;
1938 }
1939 if (LocaleCompare(attribute,"subrange") == 0)
1940 {
1941 if (info)
1942 info->image_info->subrange=SvIV(sval);
1943 break;
1944 }
1945 if (LocaleCompare(attribute,"server") == 0)
1946 goto display;
1947 if (LocaleCompare(attribute,"size") == 0)
1948 {
1949 if (info)
1950 {
1951 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1952 {
1953 ThrowPerlException(exception,OptionError,"MissingGeometry",
1954 SvPV(sval,na));
1955 break;
1956 }
1957 (void) CloneString(&info->image_info->size,SvPV(sval,na));
1958 }
1959 break;
1960 }
1961 if (LocaleCompare(attribute,"stroke") == 0)
1962 {
1963 if (info)
1964 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
1965 break;
1966 }
1967 if (info)
1968 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1969 for ( ; image; image=image->next)
1970 SetImageProperty(image,attribute,SvPV(sval,na));
1971 break;
1972 }
1973 case 'T':
1974 case 't':
1975 {
1976 if (LocaleCompare(attribute,"tile") == 0)
1977 {
1978 if (info)
1979 (void) CloneString(&info->image_info->tile,SvPV(sval,na));
1980 break;
1981 }
1982 if (LocaleCompare(attribute,"texture") == 0)
1983 {
1984 if (info)
1985 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
1986 break;
1987 }
1988 if (LocaleCompare(attribute,"tile-offset") == 0)
1989 {
1990 char
1991 *geometry;
1992
1993 geometry=GetPageGeometry(SvPV(sval,na));
1994 if (info)
1995 (void) CloneString(&info->image_info->page,geometry);
1996 for ( ; image; image=image->next)
1997 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
1998 exception);
1999 geometry=(char *) RelinquishMagickMemory(geometry);
2000 break;
2001 }
2002 if (LocaleCompare(attribute,"time-limit") == 0)
2003 {
2004 MagickSizeType
2005 limit;
2006
2007 limit=MagickResourceInfinity;
2008 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2009 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
2010 (void) SetMagickResourceLimit(TimeResource,limit);
2011 break;
2012 }
2013 if (LocaleCompare(attribute,"transparent-color") == 0)
2014 {
2015 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
2016 if (info)
2017 info->image_info->transparent_color=target_color;
2018 for ( ; image; image=image->next)
2019 image->transparent_color=target_color;
2020 break;
2021 }
2022 if (LocaleCompare(attribute,"type") == 0)
2023 {
2024 sp=SvPOK(sval) ? ParseMagickOption(MagickTypeOptions,MagickFalse,
2025 SvPV(sval,na)) : SvIV(sval);
2026 if (sp < 0)
2027 {
2028 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2029 SvPV(sval,na));
2030 break;
2031 }
2032 if (info)
2033 info->image_info->type=(ImageType) sp;
2034 for ( ; image; image=image->next)
2035 SetImageType(image,(ImageType) sp);
2036 break;
2037 }
2038 if (info)
2039 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2040 for ( ; image; image=image->next)
2041 SetImageProperty(image,attribute,SvPV(sval,na));
2042 break;
2043 }
2044 case 'U':
2045 case 'u':
2046 {
2047 if (LocaleCompare(attribute,"units") == 0)
2048 {
2049 sp=SvPOK(sval) ? ParseMagickOption(MagickResolutionOptions,
2050 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2051 if (sp < 0)
2052 {
2053 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2054 SvPV(sval,na));
2055 break;
2056 }
2057 if (info)
2058 info->image_info->units=(ResolutionType) sp;
2059 for ( ; image; image=image->next)
2060 {
2061 ResolutionType
2062 units;
2063
2064 units=(ResolutionType) sp;
2065 if (image->units != units)
2066 switch (image->units)
2067 {
2068 case UndefinedResolution:
2069 case PixelsPerInchResolution:
2070 {
2071 if (units == PixelsPerCentimeterResolution)
2072 {
2073 image->x_resolution*=2.54;
2074 image->y_resolution*=2.54;
2075 }
2076 break;
2077 }
2078 case PixelsPerCentimeterResolution:
2079 {
2080 if (units == PixelsPerInchResolution)
2081 {
2082 image->x_resolution/=2.54;
2083 image->y_resolution/=2.54;
2084 }
2085 break;
2086 }
2087 }
2088 image->units=units;
2089 }
2090 break;
2091 }
2092 if (info)
2093 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2094 for ( ; image; image=image->next)
2095 SetImageProperty(image,attribute,SvPV(sval,na));
2096 break;
2097 }
2098 case 'V':
2099 case 'v':
2100 {
2101 if (LocaleCompare(attribute,"verbose") == 0)
2102 {
2103 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
2104 SvPV(sval,na)) : SvIV(sval);
2105 if (sp < 0)
2106 {
2107 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2108 SvPV(sval,na));
2109 break;
2110 }
2111 if (info)
2112 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2113 break;
2114 }
2115 if (LocaleCompare(attribute,"view") == 0)
2116 {
2117 if (info)
2118 (void) CloneString(&info->image_info->view,SvPV(sval,na));
2119 break;
2120 }
2121 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2122 {
2123 sp=SvPOK(sval) ? ParseMagickOption(MagickVirtualPixelOptions,
2124 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2125 if (sp < 0)
2126 {
2127 ThrowPerlException(exception,OptionError,
2128 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2129 break;
2130 }
2131 if (info)
2132 info->image_info->virtual_pixel_method=(VirtualPixelMethod) sp;
2133 for ( ; image; image=image->next)
2134 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp);
2135 break;
2136 }
2137 if (info)
2138 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2139 for ( ; image; image=image->next)
2140 SetImageProperty(image,attribute,SvPV(sval,na));
2141 break;
2142 }
2143 case 'W':
2144 case 'w':
2145 {
2146 if (LocaleCompare(attribute,"white-point") == 0)
2147 {
2148 for ( ; image; image=image->next)
2149 {
2150 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2151 image->chromaticity.white_point.x=geometry_info.rho;
2152 image->chromaticity.white_point.y=geometry_info.sigma;
2153 if ((flags & SigmaValue) == 0)
2154 image->chromaticity.white_point.y=
2155 image->chromaticity.white_point.x;
2156 }
2157 break;
2158 }
2159 if (info)
2160 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2161 for ( ; image; image=image->next)
2162 SetImageProperty(image,attribute,SvPV(sval,na));
2163 break;
2164 }
2165 default:
2166 {
2167 if (info)
2168 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2169 for ( ; image; image=image->next)
2170 SetImageProperty(image,attribute,SvPV(sval,na));
2171 break;
2172 }
2173 }
2174}
2175
2176/*
2177%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2178% %
2179% %
2180% %
2181% S e t u p L i s t %
2182% %
2183% %
2184% %
2185%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2186%
2187% Method SetupList returns the list of all the images linked by their
2188% image->next and image->previous link lists for use with ImageMagick. If
2189% info is non-NULL, an info structure is returned in *info. If
2190% reference_vector is non-NULL,an array of SV* are returned in
2191% *reference_vector. Reference_vector is used when the images are going to be
2192% replaced with new Image*'s.
2193%
2194% The format of the SetupList routine is:
2195%
2196% Image *SetupList(SV *reference,struct PackageInfo **info,
2197% SV ***reference_vector,ExceptionInfo *exception)
2198%
2199% A description of each parameter follows:
2200%
2201% o list: a list of strings.
2202%
2203% o string: a character string.
2204%
2205% o exception: Return any errors or warnings in this structure.
2206%
2207*/
2208static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2209 SV ***reference_vector,ExceptionInfo *exception)
2210{
2211 Image
2212 *image;
2213
2214 long
2215 current,
2216 last;
2217
2218 if (reference_vector)
2219 *reference_vector=NULL;
2220 if (info)
2221 *info=NULL;
2222 current=0;
2223 last=0;
2224 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2225 if (info && (SvTYPE(reference) == SVt_PVAV))
2226 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2227 exception);
2228 return(image);
2229}
2230
2231/*
2232%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2233% %
2234% %
2235% %
2236% s t r E Q c a s e %
2237% %
2238% %
2239% %
2240%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2241%
2242% strEQcase() compares two strings and returns 0 if they are the
2243% same or if the second string runs out first. The comparison is case
2244% insensitive.
2245%
2246% The format of the strEQcase routine is:
2247%
2248% long strEQcase(const char *p,const char *q)
2249%
2250% A description of each parameter follows:
2251%
2252% o p: a character string.
2253%
2254% o q: a character string.
2255%
2256%
2257*/
2258static long strEQcase(const char *p,const char *q)
2259{
2260 char
2261 c;
2262
2263 register long
2264 i;
2265
2266 for (i=0 ; (c=(*q)) != 0; i++)
2267 {
2268 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2269 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2270 return(0);
2271 p++;
2272 q++;
2273 }
2274 return(((*q == 0) && (*p == 0)) ? i : 0);
2275}
2276
2277/*
2278%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2279% %
2280% %
2281% %
2282% I m a g e : : M a g i c k %
2283% %
2284% %
2285% %
2286%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2287%
2288%
2289*/
2290MODULE = Image::Magick PACKAGE = Image::Magick
2291
2292PROTOTYPES: ENABLE
2293
2294BOOT:
2295 MagickCoreGenesis("PerlMagick",MagickFalse);
2296 SetWarningHandler(NULL);
2297 SetErrorHandler(NULL);
2298 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2299 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2300
2301void
2302UNLOAD()
2303 PPCODE:
2304 {
2305 if (magick_registry != (SplayTreeInfo *) NULL)
2306 magick_registry=DestroySplayTree(magick_registry);
2307 MagickCoreTerminus();
2308 }
2309
2310double
2311constant(name,argument)
2312 char *name
2313 long argument
2314
2315#
2316###############################################################################
2317# #
2318# #
2319# #
2320# A n i m a t e #
2321# #
2322# #
2323# #
2324###############################################################################
2325#
2326#
2327void
2328Animate(ref,...)
2329 Image::Magick ref=NO_INIT
2330 ALIAS:
2331 AnimateImage = 1
2332 animate = 2
2333 animateimage = 3
2334 PPCODE:
2335 {
2336 ExceptionInfo
2337 *exception;
2338
2339 Image
2340 *image;
2341
2342 register long
2343 i;
2344
2345 struct PackageInfo
2346 *info,
2347 *package_info;
2348
2349 SV
2350 *perl_exception,
2351 *reference;
2352
2353 exception=AcquireExceptionInfo();
2354 perl_exception=newSVpv("",0);
2355 package_info=(struct PackageInfo *) NULL;
2356 if (sv_isobject(ST(0)) == 0)
2357 {
2358 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2359 PackageName);
2360 goto PerlException;
2361 }
2362 reference=SvRV(ST(0));
2363 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2364 if (image == (Image *) NULL)
2365 {
2366 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2367 PackageName);
2368 goto PerlException;
2369 }
2370 package_info=ClonePackageInfo(info,exception);
2371 if (items == 2)
2372 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2373 else
2374 if (items > 2)
2375 for (i=2; i < items; i+=2)
2376 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2377 exception);
2378 (void) AnimateImages(package_info->image_info,image);
2379 (void) CatchImageException(image);
2380 InheritException(exception,&image->exception);
2381
2382 PerlException:
2383 if (package_info != (struct PackageInfo *) NULL)
2384 DestroyPackageInfo(package_info);
2385 InheritPerlException(exception,perl_exception);
2386 exception=DestroyExceptionInfo(exception);
2387 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2388 SvPOK_on(perl_exception);
2389 ST(0)=sv_2mortal(perl_exception);
2390 XSRETURN(1);
2391 }
2392
2393#
2394###############################################################################
2395# #
2396# #
2397# #
2398# A p p e n d #
2399# #
2400# #
2401# #
2402###############################################################################
2403#
2404#
2405void
2406Append(ref,...)
2407 Image::Magick ref=NO_INIT
2408 ALIAS:
2409 AppendImage = 1
2410 append = 2
2411 appendimage = 3
2412 PPCODE:
2413 {
2414 AV
2415 *av;
2416
2417 char
2418 *attribute;
2419
2420 ExceptionInfo
2421 *exception;
2422
2423 HV
2424 *hv;
2425
2426 Image
2427 *image;
2428
2429 long
2430 stack;
2431
2432 register long
2433 i;
2434
2435 struct PackageInfo
2436 *info;
2437
2438 SV
2439 *av_reference,
2440 *perl_exception,
2441 *reference,
2442 *rv,
2443 *sv;
2444
2445 exception=AcquireExceptionInfo();
2446 perl_exception=newSVpv("",0);
2447 attribute=NULL;
2448 av=NULL;
2449 if (sv_isobject(ST(0)) == 0)
2450 {
2451 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2452 PackageName);
2453 goto PerlException;
2454 }
2455 reference=SvRV(ST(0));
2456 hv=SvSTASH(reference);
2457 av=newAV();
2458 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2459 SvREFCNT_dec(av);
2460 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2461 if (image == (Image *) NULL)
2462 {
2463 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2464 PackageName);
2465 goto PerlException;
2466 }
2467 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2468 /*
2469 Get options.
2470 */
2471 stack=MagickTrue;
2472 for (i=2; i < items; i+=2)
2473 {
2474 attribute=(char *) SvPV(ST(i-1),na);
2475 switch (*attribute)
2476 {
2477 case 'S':
2478 case 's':
2479 {
2480 if (LocaleCompare(attribute,"stack") == 0)
2481 {
2482 stack=ParseMagickOption(MagickBooleanOptions,MagickFalse,
2483 SvPV(ST(i),na));
2484 if (stack < 0)
2485 {
2486 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2487 SvPV(ST(i),na));
2488 return;
2489 }
2490 break;
2491 }
2492 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2493 attribute);
2494 break;
2495 }
2496 default:
2497 {
2498 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2499 attribute);
2500 break;
2501 }
2502 }
2503 }
2504 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2505 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2506 goto PerlException;
2507 for ( ; image; image=image->next)
2508 {
2509 AddImageToRegistry(image);
2510 rv=newRV(sv);
2511 av_push(av,sv_bless(rv,hv));
2512 SvREFCNT_dec(sv);
2513 }
2514 exception=DestroyExceptionInfo(exception);
2515 ST(0)=av_reference;
2516 SvREFCNT_dec(perl_exception);
2517 XSRETURN(1);
2518
2519 PerlException:
2520 InheritPerlException(exception,perl_exception);
2521 exception=DestroyExceptionInfo(exception);
2522 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2523 SvPOK_on(perl_exception);
2524 ST(0)=sv_2mortal(perl_exception);
2525 XSRETURN(1);
2526 }
2527
2528#
2529###############################################################################
2530# #
2531# #
2532# #
2533# A v e r a g e #
2534# #
2535# #
2536# #
2537###############################################################################
2538#
2539#
2540void
2541Average(ref)
2542 Image::Magick ref=NO_INIT
2543 ALIAS:
2544 AverageImage = 1
2545 average = 2
2546 averageimage = 3
2547 PPCODE:
2548 {
2549 AV
2550 *av;
2551
2552 char
2553 *p;
2554
2555 ExceptionInfo
2556 *exception;
2557
2558 HV
2559 *hv;
2560
2561 Image
2562 *image;
2563
2564 struct PackageInfo
2565 *info;
2566
2567 SV
2568 *perl_exception,
2569 *reference,
2570 *rv,
2571 *sv;
2572
2573 exception=AcquireExceptionInfo();
2574 perl_exception=newSVpv("",0);
2575 if (sv_isobject(ST(0)) == 0)
2576 {
2577 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2578 PackageName);
2579 goto PerlException;
2580 }
2581 reference=SvRV(ST(0));
2582 hv=SvSTASH(reference);
2583 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2584 if (image == (Image *) NULL)
2585 {
2586 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2587 PackageName);
2588 goto PerlException;
2589 }
2590 image=AverageImages(image,exception);
2591 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2592 goto PerlException;
2593 /*
2594 Create blessed Perl array for the returned image.
2595 */
2596 av=newAV();
2597 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2598 SvREFCNT_dec(av);
2599 AddImageToRegistry(image);
2600 rv=newRV(sv);
2601 av_push(av,sv_bless(rv,hv));
2602 SvREFCNT_dec(sv);
2603 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2604 (void) FormatMagickString(info->image_info->filename,MaxTextExtent,
2605 "average-%.*s",(int) (MaxTextExtent-9),
2606 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2607 (void) CopyMagickString(image->filename,info->image_info->filename,
2608 MaxTextExtent);
2609 SetImageInfo(info->image_info,MagickFalse,exception);
2610 exception=DestroyExceptionInfo(exception);
2611 SvREFCNT_dec(perl_exception);
2612 XSRETURN(1);
2613
2614 PerlException:
2615 InheritPerlException(exception,perl_exception);
2616 exception=DestroyExceptionInfo(exception);
2617 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2618 SvPOK_on(perl_exception);
2619 ST(0)=sv_2mortal(perl_exception);
2620 XSRETURN(1);
2621 }
2622
2623#
2624###############################################################################
2625# #
2626# #
2627# #
2628# B l o b T o I m a g e #
2629# #
2630# #
2631# #
2632###############################################################################
2633#
2634#
2635void
2636BlobToImage(ref,...)
2637 Image::Magick ref=NO_INIT
2638 ALIAS:
2639 BlobToImage = 1
2640 blobtoimage = 2
2641 blobto = 3
2642 PPCODE:
2643 {
2644 AV
2645 *av;
2646
2647 char
2648 **keep,
2649 **list;
2650
2651 ExceptionInfo
2652 *exception;
2653
2654 HV
2655 *hv;
2656
2657 Image
2658 *image;
2659
2660 long
2661 ac,
2662 n,
2663 number_images;
2664
2665 register char
2666 **p;
2667
2668 register long
2669 i;
2670
2671 STRLEN
2672 *length;
2673
2674 struct PackageInfo
2675 *info;
2676
2677 SV
2678 *perl_exception,
2679 *reference,
2680 *rv,
2681 *sv;
2682
2683 exception=AcquireExceptionInfo();
2684 perl_exception=newSVpv("",0);
2685 number_images=0;
2686 ac=(items < 2) ? 1 : items-1;
2687 length=(STRLEN *) NULL;
2688 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2689 if (list == (char **) NULL)
2690 {
2691 ThrowPerlException(exception,ResourceLimitError,
2692 "MemoryAllocationFailed",PackageName);
2693 goto PerlException;
2694 }
2695 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2696 if (length == (STRLEN *) NULL)
2697 {
2698 ThrowPerlException(exception,ResourceLimitError,
2699 "MemoryAllocationFailed",PackageName);
2700 goto PerlException;
2701 }
2702 if (sv_isobject(ST(0)) == 0)
2703 {
2704 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2705 PackageName);
2706 goto PerlException;
2707 }
2708 reference=SvRV(ST(0));
2709 hv=SvSTASH(reference);
2710 if (SvTYPE(reference) != SVt_PVAV)
2711 {
2712 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2713 PackageName);
2714 goto PerlException;
2715 }
2716 av=(AV *) reference;
2717 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2718 exception);
2719 n=1;
2720 if (items <= 1)
2721 {
2722 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2723 goto PerlException;
2724 }
2725 for (n=0, i=0; i < ac; i++)
2726 {
2727 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2728 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2729 {
2730 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2731 continue;
2732 }
2733 n++;
2734 }
2735 list[n]=(char *) NULL;
2736 keep=list;
2737 for (i=number_images=0; i < n; i++)
2738 {
2739 image=BlobToImage(info->image_info,list[i],length[i],exception);
2740 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2741 break;
2742 for ( ; image; image=image->next)
2743 {
2744 AddImageToRegistry(image);
2745 rv=newRV(sv);
2746 av_push(av,sv_bless(rv,hv));
2747 SvREFCNT_dec(sv);
2748 number_images++;
2749 }
2750 }
2751 /*
2752 Free resources.
2753 */
2754 for (i=0; i < n; i++)
2755 if (list[i] != (char *) NULL)
2756 for (p=keep; list[i] != *p++; )
2757 if (*p == (char *) NULL)
2758 {
2759 list[i]=(char *) RelinquishMagickMemory(list[i]);
2760 break;
2761 }
2762
2763 PerlException:
2764 if (list)
2765 list=(char **) RelinquishMagickMemory(list);
2766 if (length)
2767 length=(STRLEN *) RelinquishMagickMemory(length);
2768 InheritPerlException(exception,perl_exception);
2769 exception=DestroyExceptionInfo(exception);
2770 sv_setiv(perl_exception,(IV) number_images);
2771 SvPOK_on(perl_exception);
2772 ST(0)=sv_2mortal(perl_exception);
2773 XSRETURN(1);
2774 }
2775
2776#
2777###############################################################################
2778# #
2779# #
2780# #
2781# C l o n e #
2782# #
2783# #
2784# #
2785###############################################################################
2786#
2787#
2788void
2789Clone(ref)
2790 Image::Magick ref=NO_INIT
2791 ALIAS:
2792 CopyImage = 1
2793 copy = 2
2794 copyimage = 3
2795 CloneImage = 4
2796 clone = 5
2797 cloneimage = 6
2798 Clone = 7
2799 PPCODE:
2800 {
2801 AV
2802 *av;
2803
2804 ExceptionInfo
2805 *exception;
2806
2807 HV
2808 *hv;
2809
2810 Image
2811 *clone,
2812 *image;
2813
2814 struct PackageInfo
2815 *info;
2816
2817 SV
2818 *perl_exception,
2819 *reference,
2820 *rv,
2821 *sv;
2822
2823 exception=AcquireExceptionInfo();
2824 perl_exception=newSVpv("",0);
2825 if (sv_isobject(ST(0)) == 0)
2826 {
2827 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2828 PackageName);
2829 goto PerlException;
2830 }
2831 reference=SvRV(ST(0));
2832 hv=SvSTASH(reference);
2833 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2834 if (image == (Image *) NULL)
2835 {
2836 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2837 PackageName);
2838 goto PerlException;
2839 }
2840 /*
2841 Create blessed Perl array for the returned image.
2842 */
2843 av=newAV();
2844 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2845 SvREFCNT_dec(av);
2846 for ( ; image; image=image->next)
2847 {
2848 clone=CloneImage(image,0,0,MagickTrue,exception);
2849 if ((clone == (Image *) NULL) || (exception->severity >= ErrorException))
2850 break;
2851 AddImageToRegistry(clone);
2852 rv=newRV(sv);
2853 av_push(av,sv_bless(rv,hv));
2854 SvREFCNT_dec(sv);
2855 }
2856 exception=DestroyExceptionInfo(exception);
2857 SvREFCNT_dec(perl_exception);
2858 XSRETURN(1);
2859
2860 PerlException:
2861 InheritPerlException(exception,perl_exception);
2862 exception=DestroyExceptionInfo(exception);
2863 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2864 SvPOK_on(perl_exception);
2865 ST(0)=sv_2mortal(perl_exception);
2866 XSRETURN(1);
2867 }
2868
2869#
2870###############################################################################
2871# #
2872# #
2873# #
2874# C L O N E #
2875# #
2876# #
2877# #
2878###############################################################################
2879#
2880#
2881void
2882CLONE(ref,...)
2883 SV *ref;
2884 CODE:
2885 {
2886 if (magick_registry != (SplayTreeInfo *) NULL)
2887 {
2888 register Image
2889 *p;
2890
2891 ResetSplayTreeIterator(magick_registry);
2892 p=(Image *) GetNextKeyInSplayTree(magick_registry);
2893 while (p != (Image *) NULL)
2894 {
2895 ReferenceImage(p);
2896 p=(Image *) GetNextKeyInSplayTree(magick_registry);
2897 }
2898 }
2899 }
2900
2901#
2902###############################################################################
2903# #
2904# #
2905# #
2906# C o a l e s c e #
2907# #
2908# #
2909# #
2910###############################################################################
2911#
2912#
2913void
2914Coalesce(ref)
2915 Image::Magick ref=NO_INIT
2916 ALIAS:
2917 CoalesceImage = 1
2918 coalesce = 2
2919 coalesceimage = 3
2920 PPCODE:
2921 {
2922 AV
2923 *av;
2924
2925 ExceptionInfo
2926 *exception;
2927
2928 HV
2929 *hv;
2930
2931 Image
2932 *image;
2933
2934 struct PackageInfo
2935 *info;
2936
2937 SV
2938 *av_reference,
2939 *perl_exception,
2940 *reference,
2941 *rv,
2942 *sv;
2943
2944 exception=AcquireExceptionInfo();
2945 perl_exception=newSVpv("",0);
2946 if (sv_isobject(ST(0)) == 0)
2947 {
2948 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2949 PackageName);
2950 goto PerlException;
2951 }
2952 reference=SvRV(ST(0));
2953 hv=SvSTASH(reference);
2954 av=newAV();
2955 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2956 SvREFCNT_dec(av);
2957 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2958 if (image == (Image *) NULL)
2959 {
2960 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2961 PackageName);
2962 goto PerlException;
2963 }
2964 image=CoalesceImages(image,exception);
2965 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2966 goto PerlException;
2967 for ( ; image; image=image->next)
2968 {
2969 AddImageToRegistry(image);
2970 rv=newRV(sv);
2971 av_push(av,sv_bless(rv,hv));
2972 SvREFCNT_dec(sv);
2973 }
2974 exception=DestroyExceptionInfo(exception);
2975 ST(0)=av_reference;
2976 SvREFCNT_dec(perl_exception);
2977 XSRETURN(1);
2978
2979 PerlException:
2980 InheritPerlException(exception,perl_exception);
2981 exception=DestroyExceptionInfo(exception);
2982 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2983 SvPOK_on(perl_exception);
2984 ST(0)=sv_2mortal(perl_exception);
2985 XSRETURN(1);
2986 }
2987
2988#
2989###############################################################################
2990# #
2991# #
2992# #
2993# C o m p a r e #
2994# #
2995# #
2996# #
2997###############################################################################
2998#
2999#
3000void
3001Compare(ref,...)
3002 Image::Magick ref=NO_INIT
3003 ALIAS:
3004 CompareImage = 1
3005 compare = 2
3006 compareimage = 3
3007 PPCODE:
3008 {
3009 AV
3010 *av;
3011
3012 char
3013 *attribute;
3014
3015 ChannelType
3016 channel;
3017
3018 double
3019 distortion;
3020
3021 ExceptionInfo
3022 *exception;
3023
3024 HV
3025 *hv;
3026
3027 Image
3028 *difference_image,
3029 *image,
3030 *reconstruct_image;
3031
3032 long
3033 option;
3034
3035 MetricType
3036 metric;
3037
3038 register long
3039 i;
3040
3041 struct PackageInfo
3042 *info;
3043
3044 SV
3045 *av_reference,
3046 *perl_exception,
3047 *reference,
3048 *rv,
3049 *sv;
3050
3051 exception=AcquireExceptionInfo();
3052 perl_exception=newSVpv("",0);
3053 av=NULL;
3054 attribute=NULL;
3055 if (sv_isobject(ST(0)) == 0)
3056 {
3057 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3058 PackageName);
3059 goto PerlException;
3060 }
3061 reference=SvRV(ST(0));
3062 hv=SvSTASH(reference);
3063 av=newAV();
3064 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3065 SvREFCNT_dec(av);
3066 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3067 if (image == (Image *) NULL)
3068 {
3069 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3070 PackageName);
3071 goto PerlException;
3072 }
3073 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3074 /*
3075 Get attribute.
3076 */
3077 channel=DefaultChannels;
3078 reconstruct_image=image;
3079 metric=RootMeanSquaredErrorMetric;
3080 for (i=2; i < items; i+=2)
3081 {
3082 attribute=(char *) SvPV(ST(i-1),na);
3083 switch (*attribute)
3084 {
3085 case 'C':
3086 case 'c':
3087 {
3088 if (LocaleCompare(attribute,"channel") == 0)
3089 {
3090 long
3091 option;
3092
3093 option=ParseChannelOption(SvPV(ST(i),na));
3094 if (option < 0)
3095 {
3096 ThrowPerlException(exception,OptionError,
3097 "UnrecognizedType",SvPV(ST(i),na));
3098 return;
3099 }
3100 channel=(ChannelType) option;
3101 break;
3102 }
3103 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3104 attribute);
3105 break;
3106 }
3107 case 'F':
3108 case 'f':
3109 {
3110 if (LocaleCompare(attribute,"fuzz") == 0)
3111 {
3112 image->fuzz=StringToDouble(SvPV(ST(i),na),100.0);
3113 break;
3114 }
3115 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3116 attribute);
3117 break;
3118 }
3119 case 'I':
3120 case 'i':
3121 {
3122 if (LocaleCompare(attribute,"image") == 0)
3123 {
3124 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3125 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3126 }
3127 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3128 attribute);
3129 break;
3130 }
3131 case 'M':
3132 case 'm':
3133 {
3134 if (LocaleCompare(attribute,"metric") == 0)
3135 {
3136 option=ParseMagickOption(MagickMetricOptions,MagickFalse,
3137 SvPV(ST(i),na));
3138 if (option < 0)
3139 {
3140 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3141 SvPV(ST(i),na));
3142 break;
3143 }
3144 metric=(MetricType) option;
3145 break;
3146 }
3147 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3148 attribute);
3149 break;
3150 }
3151 default:
3152 {
3153 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3154 attribute);
3155 break;
3156 }
3157 }
3158 }
3159 difference_image=CompareImageChannels(image,reconstruct_image,channel,
3160 metric,&distortion,exception);
3161 if (difference_image != (Image *) NULL)
3162 {
3163 difference_image->error.mean_error_per_pixel=distortion;
3164 AddImageToRegistry(difference_image);
3165 rv=newRV(sv);
3166 av_push(av,sv_bless(rv,hv));
3167 SvREFCNT_dec(sv);
3168 }
3169 exception=DestroyExceptionInfo(exception);
3170 ST(0)=av_reference;
3171 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3172 XSRETURN(1);
3173
3174 PerlException:
3175 InheritPerlException(exception,perl_exception);
3176 exception=DestroyExceptionInfo(exception);
3177 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3178 SvPOK_on(perl_exception);
3179 ST(0)=sv_2mortal(perl_exception);
3180 XSRETURN(1);
3181 }
3182
3183#
3184###############################################################################
3185# #
3186# #
3187# #
3188# C o m p a r e L a y e r s #
3189# #
3190# #
3191# #
3192###############################################################################
3193#
3194#
3195void
3196CompareLayers(ref)
3197 Image::Magick ref=NO_INIT
3198 ALIAS:
3199 CompareImageLayers = 1
3200 comparelayers = 2
3201 compareimagelayers = 3
3202 PPCODE:
3203 {
3204 AV
3205 *av;
3206
3207 char
3208 *attribute;
3209
3210 ExceptionInfo
3211 *exception;
3212
3213 HV
3214 *hv;
3215
3216 Image
3217 *image;
3218
3219 long
3220 option;
3221
3222 ImageLayerMethod
3223 method;
3224
3225 register long
3226 i;
3227
3228 struct PackageInfo
3229 *info;
3230
3231 SV
3232 *av_reference,
3233 *perl_exception,
3234 *reference,
3235 *rv,
3236 *sv;
3237
3238 exception=AcquireExceptionInfo();
3239 perl_exception=newSVpv("",0);
3240 if (sv_isobject(ST(0)) == 0)
3241 {
3242 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3243 PackageName);
3244 goto PerlException;
3245 }
3246 reference=SvRV(ST(0));
3247 hv=SvSTASH(reference);
3248 av=newAV();
3249 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3250 SvREFCNT_dec(av);
3251 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3252 if (image == (Image *) NULL)
3253 {
3254 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3255 PackageName);
3256 goto PerlException;
3257 }
3258 method=CompareAnyLayer;
3259 for (i=2; i < items; i+=2)
3260 {
3261 attribute=(char *) SvPV(ST(i-1),na);
3262 switch (*attribute)
3263 {
3264 case 'M':
3265 case 'm':
3266 {
3267 if (LocaleCompare(attribute,"method") == 0)
3268 {
3269 option=ParseMagickOption(MagickLayerOptions,MagickFalse,
3270 SvPV(ST(i),na));
3271 if (option < 0)
3272 {
3273 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3274 SvPV(ST(i),na));
3275 break;
3276 }
3277 method=(ImageLayerMethod) option;
3278 break;
3279 }
3280 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3281 attribute);
3282 break;
3283 }
3284 default:
3285 {
3286 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3287 attribute);
3288 break;
3289 }
3290 }
3291 }
3292 image=CompareImageLayers(image,method,exception);
3293 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
3294 goto PerlException;
3295 for ( ; image; image=image->next)
3296 {
3297 AddImageToRegistry(image);
3298 rv=newRV(sv);
3299 av_push(av,sv_bless(rv,hv));
3300 SvREFCNT_dec(sv);
3301 }
3302 exception=DestroyExceptionInfo(exception);
3303 ST(0)=av_reference;
3304 SvREFCNT_dec(perl_exception);
3305 XSRETURN(1);
3306
3307 PerlException:
3308 InheritPerlException(exception,perl_exception);
3309 exception=DestroyExceptionInfo(exception);
3310 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3311 SvPOK_on(perl_exception);
3312 ST(0)=sv_2mortal(perl_exception);
3313 XSRETURN(1);
3314 }
3315
3316#
3317###############################################################################
3318# #
3319# #
3320# #
3321# D e s t r o y #
3322# #
3323# #
3324# #
3325###############################################################################
3326#
3327#
3328void
3329DESTROY(ref)
3330 Image::Magick ref=NO_INIT
3331 PPCODE:
3332 {
3333 SV
3334 *reference;
3335
3336 if (sv_isobject(ST(0)) == 0)
3337 croak("ReferenceIsNotMyType");
3338 reference=SvRV(ST(0));
3339 switch (SvTYPE(reference))
3340 {
3341 case SVt_PVAV:
3342 {
3343 char
3344 message[MaxTextExtent];
3345
3346 struct PackageInfo
3347 *info;
3348
3349 HV
3350 *hv;
3351
3352 GV
3353 **gvp;
3354
3355 SV
3356 *sv;
3357
3358 /*
3359 Array (AV *) reference
3360 */
3361 (void) FormatMagickString(message,MaxTextExtent,"package%s%lx",
3362 XS_VERSION,(long) reference);
3363 hv=gv_stashpv(PackageName, FALSE);
3364 if (!hv)
3365 break;
3366 gvp=(GV **) hv_fetch(hv,message,strlen(message),FALSE);
3367 if (!gvp)
3368 break;
3369 sv=GvSV(*gvp);
3370 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3371 {
3372 info=(struct PackageInfo *) SvIV(sv);
3373 DestroyPackageInfo(info);
3374 }
3375 hv_delete(hv,message,strlen(message),G_DISCARD);
3376 break;
3377 }
3378 case SVt_PVMG:
3379 {
3380 Image
3381 *image;
3382
3383 /*
3384 Blessed scalar = (Image *) SvIV(reference)
3385 */
3386 image=(Image *) SvIV(reference);
3387 if (image != (Image *) NULL)
3388 DeleteImageFromRegistry(reference,image);
3389 break;
3390 }
3391 default:
3392 break;
3393 }
3394 }
3395
3396#
3397###############################################################################
3398# #
3399# #
3400# #
3401# D i s p l a y #
3402# #
3403# #
3404# #
3405###############################################################################
3406#
3407#
3408void
3409Display(ref,...)
3410 Image::Magick ref=NO_INIT
3411 ALIAS:
3412 DisplayImage = 1
3413 display = 2
3414 displayimage = 3
3415 PPCODE:
3416 {
3417 ExceptionInfo
3418 *exception;
3419
3420 Image
3421 *image;
3422
3423 register long
3424 i;
3425
3426 struct PackageInfo
3427 *info,
3428 *package_info;
3429
3430 SV
3431 *perl_exception,
3432 *reference;
3433
3434 exception=AcquireExceptionInfo();
3435 perl_exception=newSVpv("",0);
3436 package_info=(struct PackageInfo *) NULL;
3437 if (sv_isobject(ST(0)) == 0)
3438 {
3439 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3440 PackageName);
3441 goto PerlException;
3442 }
3443 reference=SvRV(ST(0));
3444 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3445 if (image == (Image *) NULL)
3446 {
3447 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3448 PackageName);
3449 goto PerlException;
3450 }
3451 package_info=ClonePackageInfo(info,exception);
3452 if (items == 2)
3453 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3454 else
3455 if (items > 2)
3456 for (i=2; i < items; i+=2)
3457 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3458 exception);
3459 (void) DisplayImages(package_info->image_info,image);
3460 (void) CatchImageException(image);
3461 InheritException(exception,&image->exception);
3462
3463 PerlException:
3464 if (package_info != (struct PackageInfo *) NULL)
3465 DestroyPackageInfo(package_info);
3466 InheritPerlException(exception,perl_exception);
3467 exception=DestroyExceptionInfo(exception);
3468 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3469 SvPOK_on(perl_exception);
3470 ST(0)=sv_2mortal(perl_exception);
3471 XSRETURN(1);
3472 }
3473
3474#
3475###############################################################################
3476# #
3477# #
3478# #
3479# F l a t t e n #
3480# #
3481# #
3482# #
3483###############################################################################
3484#
3485#
3486void
3487Flatten(ref)
3488 Image::Magick ref=NO_INIT
3489 ALIAS:
3490 FlattenImage = 1
3491 flatten = 2
3492 flattenimage = 3
3493 PPCODE:
3494 {
3495 AV
3496 *av;
3497
3498 char
3499 *attribute,
3500 *p;
3501
3502 ExceptionInfo
3503 *exception;
3504
3505 HV
3506 *hv;
3507
3508 Image
3509 *image;
3510
3511 PixelPacket
3512 background_color;
3513
3514 register long
3515 i;
3516
3517 struct PackageInfo
3518 *info;
3519
3520 SV
3521 *perl_exception,
3522 *reference,
3523 *rv,
3524 *sv;
3525
3526 exception=AcquireExceptionInfo();
3527 perl_exception=newSVpv("",0);
3528 if (sv_isobject(ST(0)) == 0)
3529 {
3530 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3531 PackageName);
3532 goto PerlException;
3533 }
3534 reference=SvRV(ST(0));
3535 hv=SvSTASH(reference);
3536 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3537 if (image == (Image *) NULL)
3538 {
3539 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3540 PackageName);
3541 goto PerlException;
3542 }
3543 background_color=image->background_color;
3544 if (items == 2)
3545 (void) QueryColorDatabase((char *) SvPV(ST(1),na),&background_color,
3546 exception);
3547 else
3548 for (i=2; i < items; i+=2)
3549 {
3550 attribute=(char *) SvPV(ST(i-1),na);
3551 switch (*attribute)
3552 {
3553 case 'B':
3554 case 'b':
3555 {
3556 if (LocaleCompare(attribute,"background") == 0)
3557 {
3558 (void) QueryColorDatabase((char *) SvPV(ST(1),na),
3559 &background_color,exception);
3560 break;
3561 }
3562 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3563 attribute);
3564 break;
3565 }
3566 default:
3567 {
3568 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3569 attribute);
3570 break;
3571 }
3572 }
3573 }
3574 image->background_color=background_color;
3575 image=MergeImageLayers(image,FlattenLayer,exception);
3576 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
3577 goto PerlException;
3578 /*
3579 Create blessed Perl array for the returned image.
3580 */
3581 av=newAV();
3582 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3583 SvREFCNT_dec(av);
3584 AddImageToRegistry(image);
3585 rv=newRV(sv);
3586 av_push(av,sv_bless(rv,hv));
3587 SvREFCNT_dec(sv);
3588 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3589 (void) FormatMagickString(info->image_info->filename,MaxTextExtent,
3590 "flatten-%.*s",(int) (MaxTextExtent-9),
3591 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3592 (void) CopyMagickString(image->filename,info->image_info->filename,
3593 MaxTextExtent);
3594 SetImageInfo(info->image_info,MagickFalse,exception);
3595 exception=DestroyExceptionInfo(exception);
3596 SvREFCNT_dec(perl_exception);
3597 XSRETURN(1);
3598
3599 PerlException:
3600 InheritPerlException(exception,perl_exception);
3601 exception=DestroyExceptionInfo(exception);
3602 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3603 SvPOK_on(perl_exception); /* return messages in string context */
3604 ST(0)=sv_2mortal(perl_exception);
3605 XSRETURN(1);
3606 }
3607
3608#
3609###############################################################################
3610# #
3611# #
3612# #
3613# F x #
3614# #
3615# #
3616# #
3617###############################################################################
3618#
3619#
3620void
3621Fx(ref,...)
3622 Image::Magick ref=NO_INIT
3623 ALIAS:
3624 FxImage = 1
3625 fx = 2
3626 fximage = 3
3627 PPCODE:
3628 {
3629 AV
3630 *av;
3631
3632 char
3633 *attribute,
3634 expression[MaxTextExtent];
3635
3636 ChannelType
3637 channel;
3638
3639 ExceptionInfo
3640 *exception;
3641
3642 HV
3643 *hv;
3644
3645 Image
3646 *image;
3647
3648 register long
3649 i;
3650
3651 struct PackageInfo
3652 *info;
3653
3654 SV
3655 *av_reference,
3656 *perl_exception,
3657 *reference,
3658 *rv,
3659 *sv;
3660
3661 exception=AcquireExceptionInfo();
3662 perl_exception=newSVpv("",0);
3663 attribute=NULL;
3664 av=NULL;
3665 if (sv_isobject(ST(0)) == 0)
3666 {
3667 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3668 PackageName);
3669 goto PerlException;
3670 }
3671 reference=SvRV(ST(0));
3672 hv=SvSTASH(reference);
3673 av=newAV();
3674 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3675 SvREFCNT_dec(av);
3676 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3677 if (image == (Image *) NULL)
3678 {
3679 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3680 PackageName);
3681 goto PerlException;
3682 }
3683 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3684 /*
3685 Get options.
3686 */
3687 channel=DefaultChannels;
3688 (void) CopyMagickString(expression,"u",MaxTextExtent);
3689 if (items == 2)
3690 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MaxTextExtent);
3691 else
3692 for (i=2; i < items; i+=2)
3693 {
3694 attribute=(char *) SvPV(ST(i-1),na);
3695 switch (*attribute)
3696 {
3697 case 'C':
3698 case 'c':
3699 {
3700 if (LocaleCompare(attribute,"channel") == 0)
3701 {
3702 long
3703 option;
3704
3705 option=ParseChannelOption(SvPV(ST(i),na));
3706 if (option < 0)
3707 {
3708 ThrowPerlException(exception,OptionError,
3709 "UnrecognizedType",SvPV(ST(i),na));
3710 return;
3711 }
3712 channel=(ChannelType) option;
3713 break;
3714 }
3715 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3716 attribute);
3717 break;
3718 }
3719 case 'E':
3720 case 'e':
3721 {
3722 if (LocaleCompare(attribute,"expression") == 0)
3723 {
3724 (void) CopyMagickString(expression,SvPV(ST(i),na),
3725 MaxTextExtent);
3726 break;
3727 }
3728 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3729 attribute);
3730 break;
3731 }
3732 default:
3733 {
3734 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3735 attribute);
3736 break;
3737 }
3738 }
3739 }
3740 image=FxImageChannel(image,channel,expression,exception);
3741 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
3742 goto PerlException;
3743 for ( ; image; image=image->next)
3744 {
3745 AddImageToRegistry(image);
3746 rv=newRV(sv);
3747 av_push(av,sv_bless(rv,hv));
3748 SvREFCNT_dec(sv);
3749 }
3750 exception=DestroyExceptionInfo(exception);
3751 ST(0)=av_reference;
3752 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3753 XSRETURN(1);
3754
3755 PerlException:
3756 InheritPerlException(exception,perl_exception);
3757 exception=DestroyExceptionInfo(exception);
3758 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3759 SvPOK_on(perl_exception);
3760 ST(0)=sv_2mortal(perl_exception);
3761 XSRETURN(1);
3762 }
3763
3764#
3765###############################################################################
3766# #
3767# #
3768# #
3769# G e t #
3770# #
3771# #
3772# #
3773###############################################################################
3774#
3775#
3776void
3777Get(ref,...)
3778 Image::Magick ref=NO_INIT
3779 ALIAS:
3780 GetAttributes = 1
3781 GetAttribute = 2
3782 get = 3
3783 getattributes = 4
3784 getattribute = 5
3785 PPCODE:
3786 {
3787 char
3788 *attribute,
3789 color[MaxTextExtent];
3790
3791 const char
3792 *value;
3793
3794 ExceptionInfo
3795 *exception;
3796
3797 Image
3798 *image;
3799
3800 long
3801 j;
3802
3803 register long
3804 i;
3805
3806 struct PackageInfo
3807 *info;
3808
3809 SV
3810 *perl_exception,
3811 *reference,
3812 *s;
3813
3814 exception=AcquireExceptionInfo();
3815 perl_exception=newSVpv("",0);
3816 if (sv_isobject(ST(0)) == 0)
3817 {
3818 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3819 PackageName);
3820 XSRETURN_EMPTY;
3821 }
3822 reference=SvRV(ST(0));
3823 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3824 if (image == (Image *) NULL && !info)
3825 XSRETURN_EMPTY;
3826 EXTEND(sp,items);
3827 for (i=1; i < items; i++)
3828 {
3829 attribute=(char *) SvPV(ST(i),na);
3830 s=NULL;
3831 switch (*attribute)
3832 {
3833 case 'A':
3834 case 'a':
3835 {
3836 if (LocaleCompare(attribute,"adjoin") == 0)
3837 {
3838 if (info)
3839 s=newSViv((long) info->image_info->adjoin);
3840 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3841 continue;
3842 }
3843 if (LocaleCompare(attribute,"antialias") == 0)
3844 {
3845 if (info)
3846 s=newSViv((long) info->image_info->antialias);
3847 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3848 continue;
3849 }
3850 if (LocaleCompare(attribute,"area") == 0)
3851 {
3852 s=newSViv(GetMagickResource(AreaResource));
3853 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3854 continue;
3855 }
3856 if (LocaleCompare(attribute,"attenuate") == 0)
3857 {
3858 const char
3859 *value;
3860
3861 value=GetImageProperty(image,attribute);
3862 if (value != (const char *) NULL)
3863 s=newSVpv(value,0);
3864 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3865 continue;
3866 }
3867 if (LocaleCompare(attribute,"authenticate") == 0)
3868 {
3869 if (info)
3870 s=newSVpv(info->image_info->authenticate,0);
3871 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3872 continue;
3873 }
3874 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3875 attribute);
3876 break;
3877 }
3878 case 'B':
3879 case 'b':
3880 {
3881 if (LocaleCompare(attribute,"background") == 0)
3882 {
3883 if (image == (Image *) NULL)
3884 break;
3885 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
3886 QuantumFormat "," QuantumFormat "," QuantumFormat,
3887 image->background_color.red,image->background_color.green,
3888 image->background_color.blue,image->background_color.opacity);
3889 s=newSVpv(color,0);
3890 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3891 continue;
3892 }
3893 if (LocaleCompare(attribute,"base-columns") == 0)
3894 {
3895 if (image != (Image *) NULL)
3896 s=newSViv((long) image->magick_columns);
3897 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3898 continue;
3899 }
3900 if (LocaleCompare(attribute,"base-filename") == 0)
3901 {
3902 if (image != (Image *) NULL)
3903 s=newSVpv(image->magick_filename,0);
3904 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3905 continue;
3906 }
3907 if (LocaleCompare(attribute,"base-height") == 0)
3908 {
3909 if (image != (Image *) NULL)
3910 s=newSViv((long) image->magick_rows);
3911 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3912 continue;
3913 }
3914 if (LocaleCompare(attribute,"base-rows") == 0)
3915 {
3916 if (image != (Image *) NULL)
3917 s=newSViv((long) image->magick_rows);
3918 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3919 continue;
3920 }
3921 if (LocaleCompare(attribute,"base-width") == 0)
3922 {
3923 if (image != (Image *) NULL)
3924 s=newSViv((long) image->magick_columns);
3925 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3926 continue;
3927 }
3928 if (LocaleCompare(attribute,"bias") == 0)
3929 {
3930 if (image != (Image *) NULL)
3931 s=newSVnv(image->bias);
3932 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3933 continue;
3934 }
3935 if (LocaleCompare(attribute,"blue-primary") == 0)
3936 {
3937 if (image == (Image *) NULL)
3938 break;
3939 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
3940 image->chromaticity.blue_primary.x,
3941 image->chromaticity.blue_primary.y);
3942 s=newSVpv(color,0);
3943 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3944 continue;
3945 }
3946 if (LocaleCompare(attribute,"bordercolor") == 0)
3947 {
3948 if (image == (Image *) NULL)
3949 break;
3950 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
3951 QuantumFormat "," QuantumFormat "," QuantumFormat,
3952 image->border_color.red,image->border_color.green,
3953 image->border_color.blue,image->border_color.opacity);
3954 s=newSVpv(color,0);
3955 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3956 continue;
3957 }
3958 if (LocaleCompare(attribute,"bounding-box") == 0)
3959 {
3960 char
3961 geometry[MaxTextExtent];
3962
3963 RectangleInfo
3964 page;
3965
3966 if (image == (Image *) NULL)
3967 break;
3968 page=GetImageBoundingBox(image,&image->exception);
3969 (void) FormatMagickString(geometry,MaxTextExtent,
3970 "%lux%lu%+ld%+ld",page.width,page.height,page.x,page.y);
3971 s=newSVpv(geometry,0);
3972 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3973 continue;
3974 }
3975 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3976 attribute);
3977 break;
3978 }
3979 case 'C':
3980 case 'c':
3981 {
3982 if (LocaleCompare(attribute,"class") == 0)
3983 {
3984 if (image == (Image *) NULL)
3985 break;
3986 s=newSViv(image->storage_class);
3987 (void) sv_setpv(s,MagickOptionToMnemonic(MagickClassOptions,
3988 image->storage_class));
3989 SvIOK_on(s);
3990 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3991 continue;
3992 }
3993 if (LocaleCompare(attribute,"clip-mask") == 0)
3994 {
3995 if (image != (Image *) NULL)
3996 {
3997 SV
3998 *sv;
3999
4000 if (image->mask == (Image *) NULL)
4001 ClipImage(image);
4002 if (image->mask != (Image *) NULL)
4003 {
4004 AddImageToRegistry(image->mask);
4005 s=sv_bless(newRV(sv),SvSTASH(reference));
4006 }
4007 }
4008 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4009 continue;
4010 }
4011 if (LocaleCompare(attribute,"clip-path") == 0)
4012 {
4013 if (image != (Image *) NULL)
4014 {
4015 SV
4016 *sv;
4017
4018 if (image->clip_mask == (Image *) NULL)
4019 ClipImage(image);
4020 if (image->clip_mask != (Image *) NULL)
4021 {
4022 AddImageToRegistry(image->clip_mask);
4023 s=sv_bless(newRV(sv),SvSTASH(reference));
4024 }
4025 }
4026 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4027 continue;
4028 }
4029 if (LocaleCompare(attribute,"compression") == 0)
4030 {
4031 j=info ? info->image_info->compression : image->compression;
4032 if (info)
4033 if (info->image_info->compression == UndefinedCompression)
4034 j=image->compression;
4035 s=newSViv(j);
4036 (void) sv_setpv(s,MagickOptionToMnemonic(MagickCompressOptions,
4037 j));
4038 SvIOK_on(s);
4039 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4040 continue;
4041 }
4042 if (LocaleCompare(attribute,"colorspace") == 0)
4043 {
4044 j=image ? image->colorspace : RGBColorspace;
4045 s=newSViv(j);
4046 (void) sv_setpv(s,MagickOptionToMnemonic(MagickColorspaceOptions,
4047 j));
4048 SvIOK_on(s);
4049 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4050 continue;
4051 }
4052 if (LocaleCompare(attribute,"colors") == 0)
4053 {
4054 if (image != (Image *) NULL)
4055 s=newSViv((long) GetNumberColors(image,(FILE *) NULL,
4056 &image->exception));
4057 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4058 continue;
4059 }
4060 if (LocaleNCompare(attribute,"colormap",8) == 0)
4061 {
4062 int
4063 items;
4064
4065 if (image == (Image *) NULL || !image->colormap)
4066 break;
4067 j=0;
4068 items=sscanf(attribute,"%*[^[][%ld",&j);
4069 if (j > (long) image->colors)
4070 j%=image->colors;
4071 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
4072 QuantumFormat "," QuantumFormat "," QuantumFormat,
4073 image->colormap[j].red,image->colormap[j].green,
4074 image->colormap[j].blue,image->colormap[j].opacity);
4075 s=newSVpv(color,0);
4076 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4077 continue;
4078 }
4079 if (LocaleCompare(attribute,"columns") == 0)
4080 {
4081 if (image != (Image *) NULL)
4082 s=newSViv((long) image->columns);
4083 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4084 continue;
4085 }
4086 if (LocaleCompare(attribute,"comment") == 0)
4087 {
4088 const char
4089 *value;
4090
4091 value=GetImageProperty(image,attribute);
4092 if (value != (const char *) NULL)
4093 s=newSVpv(value,0);
4094 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4095 continue;
4096 }
4097 if (LocaleCompare(attribute,"copyright") == 0)
4098 {
4099 s=newSVpv(GetMagickCopyright(),0);
4100 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4101 continue;
4102 }
4103 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4104 attribute);
4105 break;
4106 }
4107 case 'D':
4108 case 'd':
4109 {
4110 if (LocaleCompare(attribute,"density") == 0)
4111 {
4112 char
4113 geometry[MaxTextExtent];
4114
4115 if (image == (Image *) NULL)
4116 break;
4117 (void) FormatMagickString(geometry,MaxTextExtent,"%gx%g",
4118 image->x_resolution,image->y_resolution);
4119 s=newSVpv(geometry,0);
4120 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4121 continue;
4122 }
4123 if (LocaleCompare(attribute,"dispose") == 0)
4124 {
4125 if (image == (Image *) NULL)
4126 break;
4127
4128 s=newSViv(image->dispose);
4129 (void) sv_setpv(s,
4130 MagickOptionToMnemonic(MagickDisposeOptions,image->dispose));
4131 SvIOK_on(s);
4132 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4133 continue;
4134 }
4135 if (LocaleCompare(attribute,"delay") == 0)
4136 {
4137 if (image != (Image *) NULL)
4138 s=newSViv((long) image->delay);
4139 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4140 continue;
4141 }
4142 if (LocaleCompare(attribute,"depth") == 0)
4143 {
4144 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4145 if (image != (Image *) NULL)
4146 s=newSViv((long) GetImageDepth(image,&image->exception));
4147 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4148 continue;
4149 }
4150 if (LocaleCompare(attribute,"disk") == 0)
4151 {
4152 s=newSViv(GetMagickResource(DiskResource));
4153 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4154 continue;
4155 }
4156 if (LocaleCompare(attribute,"dither") == 0)
4157 {
4158 if (info)
4159 s=newSViv((long) info->image_info->dither);
4160 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4161 continue;
4162 }
4163 if (LocaleCompare(attribute,"display") == 0) /* same as server */
4164 {
4165 if (info && info->image_info->server_name)
4166 s=newSVpv(info->image_info->server_name,0);
4167 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4168 continue;
4169 }
4170 if (LocaleCompare(attribute,"directory") == 0)
4171 {
4172 if (image && image->directory)
4173 s=newSVpv(image->directory,0);
4174 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4175 continue;
4176 }
4177 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4178 attribute);
4179 break;
4180 }
4181 case 'E':
4182 case 'e':
4183 {
4184 if (LocaleCompare(attribute,"elapsed-time") == 0)
4185 {
4186 if (image != (Image *) NULL)
4187 s=newSVnv(GetElapsedTime(&image->timer));
4188 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4189 continue;
4190 }
4191 if (LocaleCompare(attribute,"endian") == 0)
4192 {
4193 j=info ? info->image_info->endian : image->endian;
4194 s=newSViv(j);
4195 (void) sv_setpv(s,MagickOptionToMnemonic(MagickEndianOptions,j));
4196 SvIOK_on(s);
4197 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4198 continue;
4199 }
4200 if (LocaleCompare(attribute,"error") == 0)
4201 {
4202 if (image != (Image *) NULL)
4203 s=newSVnv(image->error.mean_error_per_pixel);
4204 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4205 continue;
4206 }
4207 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4208 attribute);
4209 break;
4210 }
4211 case 'F':
4212 case 'f':
4213 {
4214 if (LocaleCompare(attribute,"filesize") == 0)
4215 {
4216 if (image != (Image *) NULL)
4217 s=newSViv((long) GetBlobSize(image));
4218 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4219 continue;
4220 }
4221 if (LocaleCompare(attribute,"filename") == 0)
4222 {
4223 if (info && info->image_info->filename &&
4224 *info->image_info->filename)
4225 s=newSVpv(info->image_info->filename,0);
4226 if (image != (Image *) NULL)
4227 s=newSVpv(image->filename,0);
4228 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4229 continue;
4230 }
4231 if (LocaleCompare(attribute,"filter") == 0)
4232 {
4233 s=newSViv(image->filter);
4234 (void) sv_setpv(s,MagickOptionToMnemonic(MagickFilterOptions,
4235 image->filter));
4236 SvIOK_on(s);
4237 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4238 continue;
4239 }
4240 if (LocaleCompare(attribute,"font") == 0)
4241 {
4242 if (info && info->image_info->font)
4243 s=newSVpv(info->image_info->font,0);
4244 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4245 continue;
4246 }
4247 if (LocaleCompare(attribute,"foreground") == 0)
4248 continue;
4249 if (LocaleCompare(attribute,"format") == 0)
4250 {
4251 const MagickInfo
4252 *magick_info;
4253
4254 magick_info=(const MagickInfo *) NULL;
4255 if (info && (*info->image_info->magick != '\0'))
4256 magick_info=GetMagickInfo(info->image_info->magick,exception);
4257 if (image != (Image *) NULL)
4258 magick_info=GetMagickInfo(image->magick,&image->exception);
4259 if ((magick_info != (const MagickInfo *) NULL) &&
4260 (*magick_info->description != '\0'))
4261 s=newSVpv((char *) magick_info->description,0);
4262 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4263 continue;
4264 }
4265 if (LocaleCompare(attribute,"fuzz") == 0)
4266 {
4267 if (info)
4268 s=newSVnv(info->image_info->fuzz);
4269 if (image != (Image *) NULL)
4270 s=newSVnv(image->fuzz);
4271 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4272 continue;
4273 }
4274 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4275 attribute);
4276 break;
4277 }
4278 case 'G':
4279 case 'g':
4280 {
4281 if (LocaleCompare(attribute,"gamma") == 0)
4282 {
4283 if (image != (Image *) NULL)
4284 s=newSVnv(image->gamma);
4285 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4286 continue;
4287 }
4288 if (LocaleCompare(attribute,"geometry") == 0)
4289 {
4290 if (image && image->geometry)
4291 s=newSVpv(image->geometry,0);
4292 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4293 continue;
4294 }
4295 if (LocaleCompare(attribute,"gravity") == 0)
4296 {
4297 s=newSViv(image->gravity);
4298 (void) sv_setpv(s,
4299 MagickOptionToMnemonic(MagickGravityOptions,image->gravity));
4300 SvIOK_on(s);
4301 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4302 continue;
4303 }
4304 if (LocaleCompare(attribute,"green-primary") == 0)
4305 {
4306 if (image == (Image *) NULL)
4307 break;
4308 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
4309 image->chromaticity.green_primary.x,
4310 image->chromaticity.green_primary.y);
4311 s=newSVpv(color,0);
4312 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4313 continue;
4314 }
4315 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4316 attribute);
4317 break;
4318 }
4319 case 'H':
4320 case 'h':
4321 {
4322 if (LocaleCompare(attribute,"height") == 0)
4323 {
4324 if (image != (Image *) NULL)
4325 s=newSViv((long) image->rows);
4326 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4327 continue;
4328 }
4329 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4330 attribute);
4331 break;
4332 }
4333 case 'I':
4334 case 'i':
4335 {
4336 if (LocaleCompare(attribute,"icc") == 0)
4337 {
4338 if (image != (Image *) NULL)
4339 {
4340 const StringInfo
4341 *profile;
4342
4343 profile=GetImageProfile(image,"icc");
4344 if (profile != (StringInfo *) NULL)
4345 s=newSVpv((const char *) GetStringInfoDatum(profile),
4346 GetStringInfoLength(profile));
4347 }
4348 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4349 continue;
4350 }
4351 if (LocaleCompare(attribute,"icm") == 0)
4352 {
4353 if (image != (Image *) NULL)
4354 {
4355 const StringInfo
4356 *profile;
4357
4358 profile=GetImageProfile(image,"icm");
4359 if (profile != (const StringInfo *) NULL)
4360 s=newSVpv((const char *) GetStringInfoDatum(profile),
4361 GetStringInfoLength(profile));
4362 }
4363 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4364 continue;
4365 }
4366 if (LocaleCompare(attribute,"id") == 0)
4367 {
4368 if (image != (Image *) NULL)
4369 s=newSViv(SetMagickRegistry(ImageRegistryType,image,0,
4370 &image->exception));
4371 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4372 continue;
4373 }
4374 if (LocaleNCompare(attribute,"index",5) == 0)
4375 {
4376 char
4377 name[MaxTextExtent];
4378
4379 int
4380 items;
4381
4382 long
4383 x,
4384 y;
4385
4386 register const IndexPacket
4387 *indexes;
4388
4389 register const PixelPacket
4390 *p;
4391
4392 CacheView
4393 *image_view;
4394
4395 if (image == (Image *) NULL)
4396 break;
4397 if (image->storage_class != PseudoClass)
4398 break;
4399 x=0;
4400 y=0;
4401 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
4402 image_view=OpenCacheView(image);
4403 p=AcquireCacheViewPixels(image_view,x,y,1,1,&image->exception);
4404 if (p != (const PixelPacket *) NULL)
4405 {
4406 indexes=AcquireCacheViewIndexes(image_view);
4407 (void) FormatMagickString(name,MaxTextExtent,QuantumFormat,
4408 *indexes);
4409 s=newSVpv(name,0);
4410 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4411 }
4412 image_view=CloseCacheView(image_view);
4413 continue;
4414 }
4415 if (LocaleCompare(attribute,"iptc") == 0)
4416 {
4417 if (image != (Image *) NULL)
4418 {
4419 const StringInfo
4420 *profile;
4421
4422 profile=GetImageProfile(image,"iptc");
4423 if (profile != (const StringInfo *) NULL)
4424 s=newSVpv((const char *) GetStringInfoDatum(profile),
4425 GetStringInfoLength(profile));
4426 }
4427 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4428 continue;
4429 }
4430 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
4431 {
4432 if (image != (Image *) NULL)
4433 s=newSViv((long) image->iterations);
4434 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4435 continue;
4436 }
4437 if (LocaleCompare(attribute,"interlace") == 0)
4438 {
4439 j=info ? info->image_info->interlace : image->interlace;
4440 s=newSViv(j);
4441 (void) sv_setpv(s,MagickOptionToMnemonic(MagickInterlaceOptions,
4442 j));
4443 SvIOK_on(s);
4444 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4445 continue;
4446 }
4447 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4448 attribute);
4449 break;
4450 }
4451 case 'L':
4452 case 'l':
4453 {
4454 if (LocaleCompare(attribute,"label") == 0)
4455 {
4456 const char
4457 *value;
4458
4459 if (image == (Image *) NULL)
4460 break;
4461 value=GetImageProperty(image,"Label");
4462 if (value != (const char *) NULL)
4463 s=newSVpv(value,0);
4464 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4465 continue;
4466 }
4467 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
4468 {
4469 if (image != (Image *) NULL)
4470 s=newSViv((long) image->iterations);
4471 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4472 continue;
4473 }
4474 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4475 attribute);
4476 break;
4477 }
4478 case 'M':
4479 case 'm':
4480 {
4481 if (LocaleCompare(attribute,"magick") == 0)
4482 {
4483 if (info && *info->image_info->magick)
4484 s=newSVpv(info->image_info->magick,0);
4485 if (image != (Image *) NULL)
4486 s=newSVpv(image->magick,0);
4487 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4488 continue;
4489 }
4490 if (LocaleCompare(attribute,"map") == 0)
4491 {
4492 s=newSViv(GetMagickResource(MapResource));
4493 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4494 continue;
4495 }
4496 if (LocaleCompare(attribute,"maximum-error") == 0)
4497 {
4498 if (image != (Image *) NULL)
4499 s=newSVnv(image->error.normalized_maximum_error);
4500 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4501 continue;
4502 }
4503 if (LocaleCompare(attribute,"memory") == 0)
4504 {
4505 s=newSViv(GetMagickResource(MemoryResource));
4506 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4507 continue;
4508 }
4509 if (LocaleCompare(attribute,"mean-error") == 0)
4510 {
4511 if (image != (Image *) NULL)
4512 s=newSVnv(image->error.normalized_mean_error);
4513 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4514 continue;
4515 }
4516 if (LocaleCompare(attribute,"mime") == 0)
4517 {
4518 if (info && *info->image_info->magick)
4519 s=newSVpv(MagickToMime(info->image_info->magick),0);
4520 if (image != (Image *) NULL)
4521 s=newSVpv(MagickToMime(image->magick),0);
4522 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4523 continue;
4524 }
4525 if (LocaleCompare(attribute,"monochrome") == 0)
4526 {
4527 if (image == (Image *) NULL)
4528 continue;
4529 j=info ? info->image_info->monochrome :
4530 IsMonochromeImage(image,&image->exception);
4531 s=newSViv(j);
4532 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4533 continue;
4534 }
4535 if (LocaleCompare(attribute,"mattecolor") == 0)
4536 {
4537 if (image == (Image *) NULL)
4538 break;
4539 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
4540 QuantumFormat "," QuantumFormat "," QuantumFormat,
4541 image->matte_color.red,image->matte_color.green,
4542 image->matte_color.blue,image->matte_color.opacity);
4543 s=newSVpv(color,0);
4544 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4545 continue;
4546 }
4547 if (LocaleCompare(attribute,"matte") == 0)
4548 {
4549 if (image != (Image *) NULL)
4550 s=newSViv((long) image->matte);
4551 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4552 continue;
4553 }
4554 if (LocaleCompare(attribute,"montage") == 0)
4555 {
4556 if (image && image->montage)
4557 s=newSVpv(image->montage,0);
4558 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4559 continue;
4560 }
4561 if (LocaleCompare(attribute,"mime") == 0)
4562 {
4563 const char
4564 *magick;
4565
4566 magick=NULL;
4567 if (info && *info->image_info->magick)
4568 magick=info->image_info->magick;
4569 if (image != (Image *) NULL)
4570 magick=image->magick;
4571 if (magick)
4572 {
4573 char
4574 *mime;
4575
4576 mime=MagickToMime(magick);
4577 s=newSVpv(mime,0);
4578 mime=(char *) RelinquishMagickMemory(mime);
4579 }
4580 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4581 continue;
4582 }
4583 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4584 attribute);
4585 break;
4586 }
4587 case 'O':
4588 case 'o':
4589 {
4590 if (LocaleCompare(attribute,"orientation") == 0)
4591 {
4592 j=info ? info->image_info->orientation : image->orientation;
4593 s=newSViv(j);
4594 (void) sv_setpv(s,MagickOptionToMnemonic(MagickOrientationOptions,
4595 j));
4596 SvIOK_on(s);
4597 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4598 continue;
4599 }
4600 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4601 attribute);
4602 break;
4603 }
4604 case 'P':
4605 case 'p':
4606 {
4607 if (LocaleCompare(attribute,"page") == 0)
4608 {
4609 if (info && info->image_info->page)
4610 s=newSVpv(info->image_info->page,0);
4611 if (image != (Image *) NULL)
4612 {
4613 char
4614 geometry[MaxTextExtent];
4615
4616 (void) FormatMagickString(geometry,MaxTextExtent,
4617 "%lux%lu%+ld%+ld",image->page.width,image->page.height,
4618 image->page.x,image->page.y);
4619 s=newSVpv(geometry,0);
4620 }
4621 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4622 continue;
4623 }
4624 if (LocaleCompare(attribute,"page.x") == 0)
4625 {
4626 if (image != (Image *) NULL)
4627 s=newSViv((long) image->page.x);
4628 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4629 continue;
4630 }
4631 if (LocaleCompare(attribute,"page.y") == 0)
4632 {
4633 if (image != (Image *) NULL)
4634 s=newSViv((long) image->page.y);
4635 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4636 continue;
4637 }
4638 if (LocaleNCompare(attribute,"pixel",5) == 0)
4639 {
4640 char
4641 tuple[MaxTextExtent];
4642
4643 int
4644 items;
4645
4646 long
4647 x,
4648 y;
4649
4650 register const PixelPacket
4651 *p;
4652
4653 register const IndexPacket
4654 *indexes;
4655
4656 if (image == (Image *) NULL)
4657 break;
4658 x=0;
4659 y=0;
4660 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
4661 p=GetVirtualPixels(image,x,y,1,1,exception);
4662 indexes=AcquireIndexes(image);
4663 if (image->colorspace != CMYKColorspace)
4664 (void) FormatMagickString(tuple,MaxTextExtent,QuantumFormat ","
4665 QuantumFormat "," QuantumFormat "," QuantumFormat,
4666 p->red,p->green,p->blue,p->opacity);
4667 else
4668 (void) FormatMagickString(tuple,MaxTextExtent,QuantumFormat ","
4669 QuantumFormat "," QuantumFormat "," QuantumFormat ","
4670 QuantumFormat,p->red,p->green,p->blue,*indexes,p->opacity);
4671 s=newSVpv(tuple,0);
4672 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4673 continue;
4674 }
4675 if (LocaleCompare(attribute,"pointsize") == 0)
4676 {
4677 if (info)
4678 s=newSViv((long) info->image_info->pointsize);
4679 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4680 continue;
4681 }
4682 if (LocaleCompare(attribute,"preview") == 0)
4683 {
4684 s=newSViv(info->image_info->preview_type);
4685 (void) sv_setpv(s,MagickOptionToMnemonic(MagickPreviewOptions,
4686 info->image_info->preview_type));
4687 SvIOK_on(s);
4688 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4689 continue;
4690 }
4691 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4692 attribute);
4693 break;
4694 }
4695 case 'Q':
4696 case 'q':
4697 {
4698 if (LocaleCompare(attribute,"quality") == 0)
4699 {
4700 if (info)
4701 s=newSViv((long) info->image_info->quality);
4702 if (image != (Image *) NULL)
4703 s=newSViv((long) image->quality);
4704 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4705 continue;
4706 }
4707 if (LocaleCompare(attribute,"quantum") == 0)
4708 {
4709 if (info)
4710 s=newSViv((long) MAGICKCORE_QUANTUM_DEPTH);
4711 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4712 continue;
4713 }
4714 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4715 attribute);
4716 break;
4717 }
4718 case 'R':
4719 case 'r':
4720 {
4721 if (LocaleCompare(attribute,"rendering-intent") == 0)
4722 {
4723 s=newSViv(image->rendering_intent);
4724 (void) sv_setpv(s,MagickOptionToMnemonic(MagickIntentOptions,
4725 image->rendering_intent));
4726 SvIOK_on(s);
4727 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4728 continue;
4729 }
4730 if (LocaleCompare(attribute,"red-primary") == 0)
4731 {
4732 if (image == (Image *) NULL)
4733 break;
4734 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
4735 image->chromaticity.red_primary.x,
4736 image->chromaticity.red_primary.y);
4737 s=newSVpv(color,0);
4738 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4739 continue;
4740 }
4741 if (LocaleCompare(attribute,"rows") == 0)
4742 {
4743 if (image != (Image *) NULL)
4744 s=newSViv((long) image->rows);
4745 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4746 continue;
4747 }
4748 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4749 attribute);
4750 break;
4751 }
4752 case 'S':
4753 case 's':
4754 {
4755 if (LocaleCompare(attribute,"sampling-factor") == 0)
4756 {
4757 if (info && info->image_info->sampling_factor)
4758 s=newSVpv(info->image_info->sampling_factor,0);
4759 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4760 continue;
4761 }
4762 if (LocaleCompare(attribute,"subimage") == 0)
4763 {
4764 if (info)
4765 s=newSViv((long) info->image_info->subimage);
4766 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4767 continue;
4768 }
4769 if (LocaleCompare(attribute,"subrange") == 0)
4770 {
4771 if (info)
4772 s=newSViv((long) info->image_info->subrange);
4773 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4774 continue;
4775 }
4776 if (LocaleCompare(attribute,"server") == 0) /* same as display */
4777 {
4778 if (info && info->image_info->server_name)
4779 s=newSVpv(info->image_info->server_name,0);
4780 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4781 continue;
4782 }
4783 if (LocaleCompare(attribute,"size") == 0)
4784 {
4785 if (info && info->image_info->size)
4786 s=newSVpv(info->image_info->size,0);
4787 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4788 continue;
4789 }
4790 if (LocaleCompare(attribute,"scene") == 0)
4791 {
4792 if (image != (Image *) NULL)
4793 s=newSViv((long) image->scene);
4794 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4795 continue;
4796 }
4797 if (LocaleCompare(attribute,"scenes") == 0)
4798 {
4799 if (image != (Image *) NULL)
4800 s=newSViv((long) info->image_info->number_scenes);
4801 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4802 continue;
4803 }
4804 if (LocaleCompare(attribute,"signature") == 0)
4805 {
4806 const char
4807 *value;
4808
4809 if (image == (Image *) NULL)
4810 break;
4811 (void) SignatureImage(image);
4812 value=GetImageProperty(image,"Signature");
4813 if (value != (const char *) NULL)
4814 s=newSVpv(value,0);
4815 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4816 continue;
4817 }
4818 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4819 attribute);
4820 break;
4821 }
4822 case 'T':
4823 case 't':
4824 {
4825 if (LocaleCompare(attribute,"taint") == 0)
4826 {
4827 if (image != (Image *) NULL)
4828 s=newSViv((long) IsTaintImage(image));
4829 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4830 continue;
4831 }
4832 if (LocaleCompare(attribute,"tile") == 0)
4833 {
4834 if (info && info->image_info->tile)
4835 s=newSVpv(info->image_info->tile,0);
4836 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4837 continue;
4838 }
4839 if (LocaleCompare(attribute,"texture") == 0)
4840 {
4841 if (info && info->image_info->texture)
4842 s=newSVpv(info->image_info->texture,0);
4843 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4844 continue;
4845 }
4846 if (LocaleCompare(attribute,"total-ink-density") == 0)
4847 {
4848 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4849 if (image != (Image *) NULL)
4850 s=newSVnv(GetImageTotalInkDensity(image));
4851 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4852 continue;
4853 }
4854 if (LocaleCompare(attribute,"type") == 0)
4855 {
4856 if (image == (Image *) NULL)
4857 break;
4858 j=(long) GetImageType(image,&image->exception);
4859 s=newSViv(j);
4860 (void) sv_setpv(s,MagickOptionToMnemonic(MagickTypeOptions,j));
4861 SvIOK_on(s);
4862 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4863 continue;
4864 }
4865 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4866 attribute);
4867 break;
4868 }
4869 case 'U':
4870 case 'u':
4871 {
4872 if (LocaleCompare(attribute,"units") == 0)
4873 {
4874 j=info ? info->image_info->units : image->units;
4875 if (info)
4876 if (info->image_info->units == UndefinedResolution)
4877 j=image->units;
4878 if (j == UndefinedResolution)
4879 s=newSVpv("undefined units",0);
4880 else
4881 if (j == PixelsPerInchResolution)
4882 s=newSVpv("pixels / inch",0);
4883 else
4884 s=newSVpv("pixels / centimeter",0);
4885 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4886 continue;
4887 }
4888 if (LocaleCompare(attribute,"user-time") == 0)
4889 {
4890 if (image != (Image *) NULL)
4891 s=newSVnv(GetUserTime(&image->timer));
4892 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4893 continue;
4894 }
4895 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4896 attribute);
4897 break;
4898 }
4899 case 'V':
4900 case 'v':
4901 {
4902 if (LocaleCompare(attribute,"verbose") == 0)
4903 {
4904 if (info)
4905 s=newSViv((long) info->image_info->verbose);
4906 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4907 continue;
4908 }
4909 if (LocaleCompare(attribute,"version") == 0)
4910 {
4911 s=newSVpv(GetMagickVersion((unsigned long *) NULL),0);
4912 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4913 continue;
4914 }
4915 if (LocaleCompare(attribute,"view") == 0)
4916 {
4917 if (info && info->image_info->view)
4918 s=newSVpv(info->image_info->view,0);
4919 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4920 continue;
4921 }
4922 if (LocaleCompare(attribute,"virtual-pixel") == 0)
4923 {
4924 if (image == (Image *) NULL)
4925 break;
4926 j=(long) GetImageVirtualPixelMethod(image);
4927 s=newSViv(j);
4928 (void) sv_setpv(s,MagickOptionToMnemonic(
4929 MagickVirtualPixelOptions,j));
4930 SvIOK_on(s);
4931 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4932 continue;
4933 }
4934 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4935 attribute);
4936 break;
4937 }
4938 case 'W':
4939 case 'w':
4940 {
4941 if (LocaleCompare(attribute,"white-point") == 0)
4942 {
4943 if (image == (Image *) NULL)
4944 break;
4945 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
4946 image->chromaticity.white_point.x,
4947 image->chromaticity.white_point.y);
4948 s=newSVpv(color,0);
4949 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4950 continue;
4951 }
4952 if (LocaleCompare(attribute,"width") == 0)
4953 {
4954 if (image != (Image *) NULL)
4955 s=newSViv((long) image->columns);
4956 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4957 continue;
4958 }
4959 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4960 attribute);
4961 break;
4962 }
4963 case 'X':
4964 case 'x':
4965 {
4966 if (LocaleCompare(attribute,"x-resolution") == 0)
4967 {
4968 if (image != (Image *) NULL)
4969 s=newSVnv(image->x_resolution);
4970 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4971 continue;
4972 }
4973 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4974 attribute);
4975 break;
4976 }
4977 case 'Y':
4978 case 'y':
4979 {
4980 if (LocaleCompare(attribute,"y-resolution") == 0)
4981 {
4982 if (image != (Image *) NULL)
4983 s=newSVnv(image->y_resolution);
4984 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4985 continue;
4986 }
4987 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4988 attribute);
4989 break;
4990 }
4991 default:
4992 break;
4993 }
4994 if (image == (Image *) NULL)
4995 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4996 attribute)
4997 else
4998 {
4999 value=GetImageProperty(image,attribute);
5000 if (value != (const char *) NULL)
5001 {
5002 s=newSVpv(value,0);
5003 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5004 }
5005 else
5006 if (*attribute != '%')
5007 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5008 attribute)
5009 else
5010 {
5011 char
5012 *meta;
5013
5014 meta=InterpretImageProperties(info ? info->image_info :
5015 (ImageInfo *) NULL,image,attribute);
5016 s=newSVpv(meta,0);
5017 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5018 meta=(char *) RelinquishMagickMemory(meta);
5019 }
5020 }
5021 }
5022 exception=DestroyExceptionInfo(exception);
5023 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5024 }
5025
5026#
5027###############################################################################
5028# #
5029# #
5030# #
5031# G e t A u t h e n t i c P i x e l s #
5032# #
5033# #
5034# #
5035###############################################################################
5036#
5037#
5038void *
5039GetAuthenticPixels(ref,...)
5040 Image::Magick ref = NO_INIT
5041 ALIAS:
5042 getauthenticpixels = 1
5043 GetImagePixels = 2
5044 getimagepixels = 3
5045 CODE:
5046 {
5047 char
5048 *attribute;
5049
5050 ExceptionInfo
5051 *exception;
5052
5053 Image
5054 *image;
5055
5056 long
5057 i;
5058
5059 RectangleInfo
5060 region;
5061
5062 struct PackageInfo
5063 *info;
5064
5065 SV
5066 *perl_exception,
5067 *reference;
5068
5069 void
5070 *blob = NULL;
5071
5072 exception=AcquireExceptionInfo();
5073 perl_exception=newSVpv("",0);
5074 if (sv_isobject(ST(0)) == 0)
5075 {
5076 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5077 PackageName);
5078 goto PerlException;
5079 }
5080 reference=SvRV(ST(0));
5081
5082 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5083 if (image == (Image *) NULL)
5084 {
5085 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5086 PackageName);
5087 goto PerlException;
5088 }
5089
5090 region.x=0;
5091 region.y=0;
5092 region.width=image->columns;
5093 region.height=1;
5094 if (items == 1)
5095 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5096 for (i=2; i < items; i+=2)
5097 {
5098 attribute=(char *) SvPV(ST(i-1),na);
5099 switch (*attribute)
5100 {
5101 case 'g':
5102 case 'G':
5103 {
5104 if (LocaleCompare(attribute,"geometry") == 0)
5105 {
5106 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5107 break;
5108 }
5109 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5110 attribute);
5111 break;
5112 }
5113 case 'H':
5114 case 'h':
5115 {
5116 if (LocaleCompare(attribute,"height") == 0)
5117 {
5118 region.height=SvIV(ST(i));
5119 continue;
5120 }
5121 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5122 attribute);
5123 break;
5124 }
5125 case 'X':
5126 case 'x':
5127 {
5128 if (LocaleCompare(attribute,"x") == 0)
5129 {
5130 region.x=SvIV(ST(i));
5131 continue;
5132 }
5133 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5134 attribute);
5135 break;
5136 }
5137 case 'Y':
5138 case 'y':
5139 {
5140 if (LocaleCompare(attribute,"y") == 0)
5141 {
5142 region.y=SvIV(ST(i));
5143 continue;
5144 }
5145 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5146 attribute);
5147 break;
5148 }
5149 case 'W':
5150 case 'w':
5151 {
5152 if (LocaleCompare(attribute,"width") == 0)
5153 {
5154 region.width=SvIV(ST(i));
5155 continue;
5156 }
5157 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5158 attribute);
5159 break;
5160 }
5161 }
5162 }
5163 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5164 region.height,exception);
5165 if (blob != (void *) NULL)
5166 goto PerlEnd;
5167
5168 PerlException:
5169 InheritPerlException(exception,perl_exception);
5170 exception=DestroyExceptionInfo(exception);
5171 SvREFCNT_dec(perl_exception); /* throw away all errors */
5172
5173 PerlEnd:
5174 RETVAL = blob;
5175 }
5176 OUTPUT:
5177 RETVAL
5178
5179#
5180###############################################################################
5181# #
5182# #
5183# #
5184# G e t V i r t u a l P i x e l s #
5185# #
5186# #
5187# #
5188###############################################################################
5189#
5190#
5191void *
5192GetVirtualPixels(ref,...)
5193 Image::Magick ref = NO_INIT
5194 ALIAS:
5195 getvirtualpixels = 1
5196 AcquireImagePixels = 2
5197 acquireimagepixels = 3
5198 CODE:
5199 {
5200 char
5201 *attribute;
5202
5203 const void
5204 *blob = NULL;
5205
5206 ExceptionInfo
5207 *exception;
5208
5209 Image
5210 *image;
5211
5212 long
5213 i;
5214
5215 RectangleInfo
5216 region;
5217
5218 struct PackageInfo
5219 *info;
5220
5221 SV
5222 *perl_exception,
5223 *reference;
5224
5225 exception=AcquireExceptionInfo();
5226 perl_exception=newSVpv("",0);
5227 if (sv_isobject(ST(0)) == 0)
5228 {
5229 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5230 PackageName);
5231 goto PerlException;
5232 }
5233 reference=SvRV(ST(0));
5234
5235 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5236 if (image == (Image *) NULL)
5237 {
5238 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5239 PackageName);
5240 goto PerlException;
5241 }
5242
5243 region.x=0;
5244 region.y=0;
5245 region.width=image->columns;
5246 region.height=1;
5247 if (items == 1)
5248 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5249 for (i=2; i < items; i+=2)
5250 {
5251 attribute=(char *) SvPV(ST(i-1),na);
5252 switch (*attribute)
5253 {
5254 case 'g':
5255 case 'G':
5256 {
5257 if (LocaleCompare(attribute,"geometry") == 0)
5258 {
5259 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5260 break;
5261 }
5262 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5263 attribute);
5264 break;
5265 }
5266 case 'H':
5267 case 'h':
5268 {
5269 if (LocaleCompare(attribute,"height") == 0)
5270 {
5271 region.height=SvIV(ST(i));
5272 continue;
5273 }
5274 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5275 attribute);
5276 break;
5277 }
5278 case 'X':
5279 case 'x':
5280 {
5281 if (LocaleCompare(attribute,"x") == 0)
5282 {
5283 region.x=SvIV(ST(i));
5284 continue;
5285 }
5286 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5287 attribute);
5288 break;
5289 }
5290 case 'Y':
5291 case 'y':
5292 {
5293 if (LocaleCompare(attribute,"y") == 0)
5294 {
5295 region.y=SvIV(ST(i));
5296 continue;
5297 }
5298 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5299 attribute);
5300 break;
5301 }
5302 case 'W':
5303 case 'w':
5304 {
5305 if (LocaleCompare(attribute,"width") == 0)
5306 {
5307 region.width=SvIV(ST(i));
5308 continue;
5309 }
5310 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5311 attribute);
5312 break;
5313 }
5314 }
5315 }
5316 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
5317 region.height,exception);
5318 if (blob != (void *) NULL)
5319 goto PerlEnd;
5320
5321 PerlException:
5322 InheritPerlException(exception,perl_exception);
5323 exception=DestroyExceptionInfo(exception);
5324 SvREFCNT_dec(perl_exception); /* throw away all errors */
5325
5326 PerlEnd:
5327 RETVAL = (void *) blob;
5328 }
5329 OUTPUT:
5330 RETVAL
5331
5332#
5333###############################################################################
5334# #
5335# #
5336# #
5337# G e t A u t h e n t i c I n d e x Q u e u e #
5338# #
5339# #
5340# #
5341###############################################################################
5342#
5343#
5344void *
5345GetAuthenticIndexQueue(ref,...)
5346 Image::Magick ref = NO_INIT
5347 ALIAS:
5348 getauthenticindexqueue = 1
5349 GetIndexes = 2
5350 getindexes = 3
5351 CODE:
5352 {
5353 ExceptionInfo
5354 *exception;
5355
5356 Image
5357 *image;
5358
5359 struct PackageInfo
5360 *info;
5361
5362 SV
5363 *perl_exception,
5364 *reference;
5365
5366 void
5367 *blob = NULL;
5368
5369 exception=AcquireExceptionInfo();
5370 perl_exception=newSVpv("",0);
5371 if (sv_isobject(ST(0)) == 0)
5372 {
5373 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5374 PackageName);
5375 goto PerlException;
5376 }
5377 reference=SvRV(ST(0));
5378
5379 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5380 if (image == (Image *) NULL)
5381 {
5382 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5383 PackageName);
5384 goto PerlException;
5385 }
5386
5387 blob=(void *) GetAuthenticIndexQueue(image);
5388 if (blob != (void *) NULL)
5389 goto PerlEnd;
5390
5391 PerlException:
5392 InheritPerlException(exception,perl_exception);
5393 exception=DestroyExceptionInfo(exception);
5394 SvREFCNT_dec(perl_exception); /* throw away all errors */
5395
5396 PerlEnd:
5397 RETVAL = blob;
5398 }
5399 OUTPUT:
5400 RETVAL
5401
5402#
5403###############################################################################
5404# #
5405# #
5406# #
5407# G e t V i r t u a l I n d e x Q u e u e #
5408# #
5409# #
5410# #
5411###############################################################################
5412#
5413#
5414void *
5415GetVirtualIndexQueue(ref,...)
5416 Image::Magick ref = NO_INIT
5417 ALIAS:
5418 getvirtualindexqueue = 1
5419 CODE:
5420 {
5421 ExceptionInfo
5422 *exception;
5423
5424 Image
5425 *image;
5426
5427 struct PackageInfo
5428 *info;
5429
5430 SV
5431 *perl_exception,
5432 *reference;
5433
5434 void
5435 *blob = NULL;
5436
5437 exception=AcquireExceptionInfo();
5438 perl_exception=newSVpv("",0);
5439 if (sv_isobject(ST(0)) == 0)
5440 {
5441 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5442 PackageName);
5443 goto PerlException;
5444 }
5445 reference=SvRV(ST(0));
5446
5447 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5448 if (image == (Image *) NULL)
5449 {
5450 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5451 PackageName);
5452 goto PerlException;
5453 }
5454
5455 blob=(void *) GetVirtualIndexQueue(image);
5456 if (blob != (void *) NULL)
5457 goto PerlEnd;
5458
5459 PerlException:
5460 InheritPerlException(exception,perl_exception);
5461 exception=DestroyExceptionInfo(exception);
5462 SvREFCNT_dec(perl_exception); /* throw away all errors */
5463
5464 PerlEnd:
5465 RETVAL = blob;
5466 }
5467 OUTPUT:
5468 RETVAL
5469
5470#
5471###############################################################################
5472# #
5473# #
5474# #
5475# H i s t o g r a m #
5476# #
5477# #
5478# #
5479###############################################################################
5480#
5481#
5482void
5483Histogram(ref,...)
5484 Image::Magick ref=NO_INIT
5485 ALIAS:
5486 HistogramImage = 1
5487 histogram = 2
5488 histogramimage = 3
5489 PPCODE:
5490 {
5491 AV
5492 *av;
5493
5494 char
5495 message[MaxTextExtent];
5496
5497 ColorPacket
5498 *histogram;
5499
5500 ExceptionInfo
5501 *exception;
5502
5503 HV
5504 *hv;
5505
5506 Image
5507 *image;
5508
5509 register long
5510 i;
5511
5512 ssize_t
5513 count;
5514
5515 struct PackageInfo
5516 *info;
5517
5518 SV
5519 *av_reference,
5520 *perl_exception,
5521 *reference;
5522
5523 unsigned long
5524 number_colors;
5525
5526 exception=AcquireExceptionInfo();
5527 perl_exception=newSVpv("",0);
5528 av=NULL;
5529 if (sv_isobject(ST(0)) == 0)
5530 {
5531 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5532 PackageName);
5533 goto PerlException;
5534 }
5535 reference=SvRV(ST(0));
5536 hv=SvSTASH(reference);
5537 av=newAV();
5538 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
5539 SvREFCNT_dec(av);
5540 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5541 if (image == (Image *) NULL)
5542 {
5543 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5544 PackageName);
5545 goto PerlException;
5546 }
5547 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
5548 count=0;
5549 for ( ; image; image=image->next)
5550 {
5551 histogram=GetImageHistogram(image,&number_colors,&image->exception);
5552 if (histogram == (ColorPacket *) NULL)
5553 continue;
5554 count+=number_colors;
5555 EXTEND(sp,6*count);
5556 for (i=0; i < (long) number_colors; i++)
5557 {
5558 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5559 histogram[i].pixel.red);
5560 PUSHs(sv_2mortal(newSVpv(message,0)));
5561 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5562 histogram[i].pixel.green);
5563 PUSHs(sv_2mortal(newSVpv(message,0)));
5564 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5565 histogram[i].pixel.blue);
5566 PUSHs(sv_2mortal(newSVpv(message,0)));
5567 if (image->colorspace == CMYKColorspace)
5568 {
5569 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5570 histogram[i].index);
5571 PUSHs(sv_2mortal(newSVpv(message,0)));
5572 }
5573 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5574 histogram[i].pixel.opacity);
5575 PUSHs(sv_2mortal(newSVpv(message,0)));
5576 (void) FormatMagickString(message,MaxTextExtent,"%lu",
5577 (unsigned long) histogram[i].count);
5578 PUSHs(sv_2mortal(newSVpv(message,0)));
5579 }
5580 histogram=(ColorPacket *) RelinquishMagickMemory(histogram);
5581 }
5582
5583 PerlException:
5584 InheritPerlException(exception,perl_exception);
5585 exception=DestroyExceptionInfo(exception);
5586 SvREFCNT_dec(perl_exception);
5587 }
5588
5589#
5590###############################################################################
5591# #
5592# #
5593# #
5594# G e t P i x e l #
5595# #
5596# #
5597# #
5598###############################################################################
5599#
5600#
5601void
5602GetPixel(ref,...)
5603 Image::Magick ref=NO_INIT
5604 ALIAS:
5605 getpixel = 1
5606 getPixel = 2
5607 PPCODE:
5608 {
5609 AV
5610 *av;
5611
5612 char
5613 *attribute;
5614
5615 ChannelType
5616 channel;
5617
5618 ExceptionInfo
5619 *exception;
5620
5621 Image
5622 *image;
5623
5624 long
5625 option;
5626
5627 MagickBooleanType
5628 normalize;
5629
5630 RectangleInfo
5631 region;
5632
5633 register const IndexPacket
5634 *indexes;
5635
5636 register const PixelPacket
5637 *p;
5638
5639 register long
5640 i;
5641
5642 struct PackageInfo
5643 *info;
5644
5645 SV
5646 *perl_exception,
5647 *reference; /* reference is the SV* of ref=SvIV(reference) */
5648
5649 exception=AcquireExceptionInfo();
5650 perl_exception=newSVpv("",0);
5651 reference=SvRV(ST(0));
5652 av=(AV *) reference;
5653 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
5654 exception);
5655 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5656 if (image == (Image *) NULL)
5657 {
5658 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5659 PackageName);
5660 goto PerlException;
5661 }
5662 channel=DefaultChannels;
5663 normalize=MagickTrue;
5664 region.x=0;
5665 region.y=0;
5666 region.width=image->columns;
5667 region.height=1;
5668 if (items == 1)
5669 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5670 for (i=2; i < items; i+=2)
5671 {
5672 attribute=(char *) SvPV(ST(i-1),na);
5673 switch (*attribute)
5674 {
5675 case 'C':
5676 case 'c':
5677 {
5678 if (LocaleCompare(attribute,"channel") == 0)
5679 {
5680 long
5681 option;
5682
5683 option=ParseChannelOption(SvPV(ST(i),na));
5684 if (option < 0)
5685 {
5686 ThrowPerlException(exception,OptionError,"UnrecognizedType",
5687 SvPV(ST(i),na));
5688 return;
5689 }
5690 channel=(ChannelType) option;
5691 break;
5692 }
5693 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5694 attribute);
5695 break;
5696 }
5697 case 'g':
5698 case 'G':
5699 {
5700 if (LocaleCompare(attribute,"geometry") == 0)
5701 {
5702 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5703 break;
5704 }
5705 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5706 attribute);
5707 break;
5708 }
5709 case 'N':
5710 case 'n':
5711 {
5712 if (LocaleCompare(attribute,"normalize") == 0)
5713 {
5714 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
5715 SvPV(ST(i),na));
5716 if (option < 0)
5717 {
5718 ThrowPerlException(exception,OptionError,"UnrecognizedType",
5719 SvPV(ST(i),na));
5720 break;
5721 }
5722 normalize=option != 0 ? MagickTrue : MagickFalse;
5723 break;
5724 }
5725 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5726 attribute);
5727 break;
5728 }
5729 case 'x':
5730 case 'X':
5731 {
5732 if (LocaleCompare(attribute,"x") == 0)
5733 {
5734 region.x=SvIV(ST(i));
5735 break;
5736 }
5737 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5738 attribute);
5739 break;
5740 }
5741 case 'y':
5742 case 'Y':
5743 {
5744 if (LocaleCompare(attribute,"y") == 0)
5745 {
5746 region.y=SvIV(ST(i));
5747 break;
5748 }
5749 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5750 attribute);
5751 break;
5752 }
5753 default:
5754 {
5755 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5756 attribute);
5757 break;
5758 }
5759 }
5760 }
5761 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
5762 if (p == (const PixelPacket *) NULL)
5763 PUSHs(&sv_undef);
5764 else
5765 {
5766 double
5767 scale;
5768
5769 indexes=AcquireIndexes(image);
5770 scale=1.0;
5771 if (normalize != MagickFalse)
5772 scale=1.0/QuantumRange;
5773 if ((channel & RedChannel) != 0)
5774 PUSHs(sv_2mortal(newSVnv(scale*p->red)));
5775 if ((channel & GreenChannel) != 0)
5776 PUSHs(sv_2mortal(newSVnv(scale*p->green)));
5777 if ((channel & BlueChannel) != 0)
5778 PUSHs(sv_2mortal(newSVnv(scale*p->blue)));
5779 if (((channel & IndexChannel) != 0) &&
5780 (image->colorspace == CMYKColorspace))
5781 PUSHs(sv_2mortal(newSVnv(scale*(*indexes))));
5782 if ((channel & OpacityChannel) != 0)
5783 PUSHs(sv_2mortal(newSVnv(scale*p->opacity)));
5784 }
5785
5786 PerlException:
5787 InheritPerlException(exception,perl_exception);
5788 exception=DestroyExceptionInfo(exception);
5789 SvREFCNT_dec(perl_exception);
5790 }
5791
5792#
5793###############################################################################
5794# #
5795# #
5796# #
5797# G e t P i x e l s #
5798# #
5799# #
5800# #
5801###############################################################################
5802#
5803#
5804void
5805GetPixels(ref,...)
5806 Image::Magick ref=NO_INIT
5807 ALIAS:
5808 getpixels = 1
5809 getPixels = 2
5810 PPCODE:
5811 {
5812 AV
5813 *av;
5814
5815 char
5816 *attribute;
5817
5818 const char
5819 *map;
5820
5821 ExceptionInfo
5822 *exception;
5823
5824 Image
5825 *image;
5826
5827 long
5828 option;
5829
5830 MagickBooleanType
5831 normalize,
5832 status;
5833
5834 RectangleInfo
5835 region;
5836
5837 register long
5838 i;
5839
5840 struct PackageInfo
5841 *info;
5842
5843 SV
5844 *perl_exception,
5845 *reference; /* reference is the SV* of ref=SvIV(reference) */
5846
5847 exception=AcquireExceptionInfo();
5848 perl_exception=newSVpv("",0);
5849 reference=SvRV(ST(0));
5850 av=(AV *) reference;
5851 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
5852 exception);
5853 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5854 if (image == (Image *) NULL)
5855 {
5856 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5857 PackageName);
5858 goto PerlException;
5859 }
5860 map="RGB";
5861 if (image->matte != MagickFalse)
5862 map="RGBA";
5863 if (image->colorspace == CMYKColorspace)
5864 {
5865 map="CMYK";
5866 if (image->matte != MagickFalse)
5867 map="CMYKA";
5868 }
5869 normalize=MagickFalse;
5870 region.x=0;
5871 region.y=0;
5872 region.width=image->columns;
5873 region.height=1;
5874 if (items == 1)
5875 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5876 for (i=2; i < items; i+=2)
5877 {
5878 attribute=(char *) SvPV(ST(i-1),na);
5879 switch (*attribute)
5880 {
5881 case 'g':
5882 case 'G':
5883 {
5884 if (LocaleCompare(attribute,"geometry") == 0)
5885 {
5886 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5887 break;
5888 }
5889 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5890 attribute);
5891 break;
5892 }
5893 case 'H':
5894 case 'h':
5895 {
5896 if (LocaleCompare(attribute,"height") == 0)
5897 {
5898 region.height=SvIV(ST(i));
5899 break;
5900 }
5901 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5902 attribute);
5903 break;
5904 }
5905 case 'M':
5906 case 'm':
5907 {
5908 if (LocaleCompare(attribute,"map") == 0)
5909 {
5910 map=SvPV(ST(i),na);
5911 break;
5912 }
5913 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5914 attribute);
5915 break;
5916 }
5917 case 'N':
5918 case 'n':
5919 {
5920 if (LocaleCompare(attribute,"normalize") == 0)
5921 {
5922 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
5923 SvPV(ST(i),na));
5924 if (option < 0)
5925 {
5926 ThrowPerlException(exception,OptionError,"UnrecognizedType",
5927 SvPV(ST(i),na));
5928 break;
5929 }
5930 normalize=option != 0 ? MagickTrue : MagickFalse;
5931 break;
5932 }
5933 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5934 attribute);
5935 break;
5936 }
5937 case 'W':
5938 case 'w':
5939 {
5940 if (LocaleCompare(attribute,"width") == 0)
5941 {
5942 region.width=SvIV(ST(i));
5943 break;
5944 }
5945 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5946 attribute);
5947 break;
5948 }
5949 case 'x':
5950 case 'X':
5951 {
5952 if (LocaleCompare(attribute,"x") == 0)
5953 {
5954 region.x=SvIV(ST(i));
5955 break;
5956 }
5957 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5958 attribute);
5959 break;
5960 }
5961 case 'y':
5962 case 'Y':
5963 {
5964 if (LocaleCompare(attribute,"y") == 0)
5965 {
5966 region.y=SvIV(ST(i));
5967 break;
5968 }
5969 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5970 attribute);
5971 break;
5972 }
5973 default:
5974 {
5975 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5976 attribute);
5977 break;
5978 }
5979 }
5980 }
5981 if (normalize != MagickFalse)
5982 {
5983 float
5984 *pixels;
5985
5986 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
5987 region.height*sizeof(*pixels));
5988 if (pixels == (float *) NULL)
5989 {
5990 ThrowPerlException(exception,ResourceLimitError,
5991 "MemoryAllocationFailed",PackageName);
5992 goto PerlException;
5993 }
5994 status=ExportImagePixels(image,region.x,region.y,region.width,
5995 region.height,map,FloatPixel,pixels,exception);
5996 if (status == MagickFalse)
5997 PUSHs(&sv_undef);
5998 else
5999 {
6000 EXTEND(sp,strlen(map)*region.width*region.height);
6001 for (i=0; i < (long) (strlen(map)*region.width*region.height); i++)
6002 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6003 }
6004 pixels=(float *) RelinquishMagickMemory(pixels);
6005 }
6006 else
6007 {
6008 Quantum
6009 *pixels;
6010
6011 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6012 region.height*sizeof(*pixels));
6013 if (pixels == (Quantum *) NULL)
6014 {
6015 ThrowPerlException(exception,ResourceLimitError,
6016 "MemoryAllocationFailed",PackageName);
6017 goto PerlException;
6018 }
6019 status=ExportImagePixels(image,region.x,region.y,region.width,
6020 region.height,map,QuantumPixel,pixels,exception);
6021 if (status == MagickFalse)
6022 PUSHs(&sv_undef);
6023 else
6024 {
6025 EXTEND(sp,strlen(map)*region.width*region.height);
6026 for (i=0; i < (long) (strlen(map)*region.width*region.height); i++)
6027 PUSHs(sv_2mortal(newSViv(pixels[i])));
6028 }
6029 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6030 }
6031
6032 PerlException:
6033 InheritPerlException(exception,perl_exception);
6034 exception=DestroyExceptionInfo(exception);
6035 SvREFCNT_dec(perl_exception);
6036 }
6037
6038#
6039###############################################################################
6040# #
6041# #
6042# #
6043# I m a g e T o B l o b #
6044# #
6045# #
6046# #
6047###############################################################################
6048#
6049#
6050void
6051ImageToBlob(ref,...)
6052 Image::Magick ref=NO_INIT
6053 ALIAS:
6054 ImageToBlob = 1
6055 imagetoblob = 2
6056 toblob = 3
6057 blob = 4
6058 PPCODE:
6059 {
6060 char
6061 filename[MaxTextExtent];
6062
6063 ExceptionInfo
6064 *exception;
6065
6066 Image
6067 *image,
6068 *next;
6069
6070 long
6071 scene;
6072
6073 register long
6074 i;
6075
6076 struct PackageInfo
6077 *info,
6078 *package_info;
6079
6080 size_t
6081 length;
6082
6083 SV
6084 *perl_exception,
6085 *reference;
6086
6087 void
6088 *blob;
6089
6090 exception=AcquireExceptionInfo();
6091 perl_exception=newSVpv("",0);
6092 package_info=(struct PackageInfo *) NULL;
6093 if (sv_isobject(ST(0)) == 0)
6094 {
6095 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6096 PackageName);
6097 goto PerlException;
6098 }
6099 reference=SvRV(ST(0));
6100 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6101 if (image == (Image *) NULL)
6102 {
6103 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6104 PackageName);
6105 goto PerlException;
6106 }
6107 package_info=ClonePackageInfo(info,exception);
6108 for (i=2; i < items; i+=2)
6109 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6110 (void) CopyMagickString(filename,package_info->image_info->filename,
6111 MaxTextExtent);
6112 scene=0;
6113 for (next=image; next; next=next->next)
6114 {
6115 (void) CopyMagickString(next->filename,filename,MaxTextExtent);
6116 next->scene=scene++;
6117 }
6118 SetImageInfo(package_info->image_info,MagickTrue,&image->exception);
6119 EXTEND(sp,(long) GetImageListLength(image));
6120 for ( ; image; image=image->next)
6121 {
6122 length=0;
6123 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6124 if (blob != (char *) NULL)
6125 {
6126 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6127 blob=(unsigned char *) RelinquishMagickMemory(blob);
6128 }
6129 if (package_info->image_info->adjoin)
6130 break;
6131 }
6132
6133 PerlException:
6134 if (package_info != (struct PackageInfo *) NULL)
6135 DestroyPackageInfo(package_info);
6136 InheritPerlException(exception,perl_exception);
6137 exception=DestroyExceptionInfo(exception);
6138 SvREFCNT_dec(perl_exception); /* throw away all errors */
6139 }
6140
6141#
6142###############################################################################
6143# #
6144# #
6145# #
6146# L a y e r s #
6147# #
6148# #
6149# #
6150###############################################################################
6151#
6152#
6153void
6154Layers(ref,...)
6155 Image::Magick ref=NO_INIT
6156 ALIAS:
6157 Layers = 1
6158 layers = 2
6159 OptimizeImageLayers = 3
6160 optimizelayers = 4
6161 optimizeimagelayers = 5
6162 PPCODE:
6163 {
6164 AV
6165 *av;
6166
6167 char
6168 *attribute;
6169
6170 CompositeOperator
6171 compose;
6172
6173 ExceptionInfo
6174 *exception;
6175
6176 HV
6177 *hv;
6178
6179 Image
6180 *image,
6181 *layers;
6182
6183 long
6184 option,
6185 sp;
6186
6187 MagickBooleanType
6188 dither;
6189
6190 ImageLayerMethod
6191 method;
6192
6193 register long
6194 i;
6195
6196 struct PackageInfo
6197 *info;
6198
6199 SV
6200 *av_reference,
6201 *perl_exception,
6202 *reference,
6203 *rv,
6204 *sv;
6205
6206 exception=AcquireExceptionInfo();
6207 perl_exception=newSVpv("",0);
6208 if (sv_isobject(ST(0)) == 0)
6209 {
6210 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6211 PackageName);
6212 goto PerlException;
6213 }
6214 reference=SvRV(ST(0));
6215 hv=SvSTASH(reference);
6216 av=newAV();
6217 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
6218 SvREFCNT_dec(av);
6219 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6220 if (image == (Image *) NULL)
6221 {
6222 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6223 PackageName);
6224 goto PerlException;
6225 }
6226 compose=image->compose;
6227 dither=MagickFalse;
6228 method=OptimizeLayer;
6229 for (i=2; i < items; i+=2)
6230 {
6231 attribute=(char *) SvPV(ST(i-1),na);
6232 switch (*attribute)
6233 {
6234 case 'C':
6235 case 'c':
6236 {
6237 if (LocaleCompare(attribute,"compose") == 0)
6238 {
6239 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
6240 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
6241 if (sp < 0)
6242 {
6243 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6244 SvPV(ST(i),na));
6245 break;
6246 }
6247 compose=(CompositeOperator) sp;
6248 break;
6249 }
6250 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6251 attribute);
6252 break;
6253 }
6254 case 'D':
6255 case 'd':
6256 {
6257 if (LocaleCompare(attribute,"dither") == 0)
6258 {
6259 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
6260 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
6261 if (sp < 0)
6262 {
6263 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6264 SvPV(ST(i),na));
6265 break;
6266 }
6267 dither=(MagickBooleanType) sp;
6268 break;
6269 }
6270 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6271 attribute);
6272 break;
6273 }
6274 case 'M':
6275 case 'm':
6276 {
6277 if (LocaleCompare(attribute,"method") == 0)
6278 {
6279 option=ParseMagickOption(MagickLayerOptions,MagickFalse,
6280 SvPV(ST(i),na));
6281 if (option < 0)
6282 {
6283 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6284 SvPV(ST(i),na));
6285 break;
6286 }
6287 method=(ImageLayerMethod) option;
6288 break;
6289 }
6290 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6291 attribute);
6292 break;
6293 }
6294 default:
6295 {
6296 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6297 attribute);
6298 break;
6299 }
6300 }
6301 }
6302 layers=(Image *) NULL;
6303 switch (method)
6304 {
6305 case CompareAnyLayer:
6306 case CompareClearLayer:
6307 case CompareOverlayLayer:
6308 default:
6309 {
6310 layers=CompareImageLayers(image,method,exception);
6311 break;
6312 }
6313 case MergeLayer:
6314 case FlattenLayer:
6315 case MosaicLayer:
6316 {
6317 layers=MergeImageLayers(image,method,exception);
6318 break;
6319 }
6320 case DisposeLayer:
6321 {
6322 layers=DisposeImages(image,exception);
6323 break;
6324 }
6325 case OptimizeImageLayer:
6326 {
6327 layers=OptimizeImageLayers(image,exception);
6328 break;
6329 }
6330 case OptimizePlusLayer:
6331 {
6332 layers=OptimizePlusImageLayers(image,exception);
6333 break;
6334 }
6335 case OptimizeTransLayer:
6336 {
6337 OptimizeImageTransparency(image,exception);
6338 InheritException(&(image->exception),exception);
6339 break;
6340 }
6341 case RemoveDupsLayer:
6342 {
6343 RemoveDuplicateLayers(&image,exception);
6344 InheritException(&(image->exception),exception);
6345 break;
6346 }
6347 case RemoveZeroLayer:
6348 {
6349 RemoveZeroDelayLayers(&image,exception);
6350 InheritException(&(image->exception),exception);
6351 break;
6352 }
6353 case OptimizeLayer:
6354 {
6355 QuantizeInfo
6356 *quantize_info;
6357
6358 /*
6359 General Purpose, GIF Animation Optimizer.
6360 */
6361 layers=CoalesceImages(image,exception);
6362 if (layers == (Image *) NULL)
6363 break;
6364 InheritException(&(layers->exception),exception);
6365 image=layers;
6366 layers=OptimizeImageLayers(image,exception);
6367 if (layers == (Image *) NULL)
6368 break;
6369 InheritException(&(layers->exception),exception);
6370 image=DestroyImageList(image);
6371 image=layers;
6372 layers=(Image *) NULL;
6373 OptimizeImageTransparency(image,exception);
6374 InheritException(&(image->exception),exception);
6375 quantize_info=AcquireQuantizeInfo(info->image_info);
6376 (void) RemapImages(quantize_info,image,(Image *) NULL);
6377 quantize_info=DestroyQuantizeInfo(quantize_info);
6378 break;
6379 }
6380 case CompositeLayer:
6381 {
6382 Image
6383 *source;
6384
6385 RectangleInfo
6386 geometry;
6387
6388 /*
6389 Split image sequence at the first 'NULL:' image.
6390 */
6391 source=image;
6392 while (source != (Image *) NULL)
6393 {
6394 source=GetNextImageInList(source);
6395 if ((source != (Image *) NULL) &&
6396 (LocaleCompare(source->magick,"NULL") == 0))
6397 break;
6398 }
6399 if (source != (Image *) NULL)
6400 {
6401 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
6402 (GetNextImageInList(source) == (Image *) NULL))
6403 source=(Image *) NULL;
6404 else
6405 {
6406 /*
6407 Separate the two lists, junk the null: image.
6408 */
6409 source=SplitImageList(source->previous);
6410 DeleteImageFromList(&source);
6411 }
6412 }
6413 if (source == (Image *) NULL)
6414 {
6415 (void) ThrowMagickException(exception,GetMagickModule(),
6416 OptionError,"MissingNullSeparator","layers Composite");
6417 break;
6418 }
6419 /*
6420 Adjust offset with gravity and virtual canvas.
6421 */
6422 SetGeometry(image,&geometry);
6423 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
6424 geometry.width=source->page.width != 0 ? source->page.width :
6425 source->columns;
6426 geometry.height=source->page.height != 0 ? source->page.height :
6427 source->rows;
6428 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
6429 image->columns,image->page.height != 0 ? image->page.height :
6430 image->rows,image->gravity,&geometry);
6431 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
6432 source=DestroyImageList(source);
6433 InheritException(&(image->exception),exception);
6434 break;
6435 }
6436 }
6437 if (layers != (Image *) NULL)
6438 {
6439 InheritException(&(layers->exception),exception);
6440 image=layers;
6441 }
6442 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
6443 goto PerlException;
6444 for ( ; image; image=image->next)
6445 {
6446 AddImageToRegistry(image);
6447 rv=newRV(sv);
6448 av_push(av,sv_bless(rv,hv));
6449 SvREFCNT_dec(sv);
6450 }
6451 exception=DestroyExceptionInfo(exception);
6452 ST(0)=av_reference;
6453 SvREFCNT_dec(perl_exception);
6454 XSRETURN(1);
6455
6456 PerlException:
6457 InheritPerlException(exception,perl_exception);
6458 exception=DestroyExceptionInfo(exception);
6459 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
6460 SvPOK_on(perl_exception);
6461 ST(0)=sv_2mortal(perl_exception);
6462 XSRETURN(1);
6463 }
6464
6465#
6466###############################################################################
6467# #
6468# #
6469# #
6470# M a g i c k T o M i m e #
6471# #
6472# #
6473# #
6474###############################################################################
6475#
6476#
6477SV *
6478MagickToMime(ref,name)
6479 Image::Magick ref=NO_INIT
6480 char *name
6481 ALIAS:
6482 magicktomime = 1
6483 CODE:
6484 {
6485 char
6486 *mime;
6487
6488 mime=MagickToMime(name);
6489 RETVAL=newSVpv(mime,0);
6490 mime=(char *) RelinquishMagickMemory(mime);
6491 }
6492 OUTPUT:
6493 RETVAL
6494
6495#
6496###############################################################################
6497# #
6498# #
6499# #
6500# M o g r i f y #
6501# #
6502# #
6503# #
6504###############################################################################
6505#
6506#
6507void
6508Mogrify(ref,...)
6509 Image::Magick ref=NO_INIT
6510 ALIAS:
6511 Comment = 1
6512 CommentImage = 2
6513 Label = 3
6514 LabelImage = 4
6515 AddNoise = 5
6516 AddNoiseImage = 6
6517 Colorize = 7
6518 ColorizeImage = 8
6519 Border = 9
6520 BorderImage = 10
6521 Blur = 11
6522 BlurImage = 12
6523 Chop = 13
6524 ChopImage = 14
6525 Crop = 15
6526 CropImage = 16
6527 Despeckle = 17
6528 DespeckleImage = 18
6529 Edge = 19
6530 EdgeImage = 20
6531 Emboss = 21
6532 EmbossImage = 22
6533 Enhance = 23
6534 EnhanceImage = 24
6535 Flip = 25
6536 FlipImage = 26
6537 Flop = 27
6538 FlopImage = 28
6539 Frame = 29
6540 FrameImage = 30
6541 Implode = 31
6542 ImplodeImage = 32
6543 Magnify = 33
6544 MagnifyImage = 34
6545 MedianFilter = 35
6546 MedianFilterImage = 36
6547 Minify = 37
6548 MinifyImage = 38
6549 OilPaint = 39
6550 OilPaintImage = 40
6551 ReduceNoise = 41
6552 ReduceNoiseImage = 42
6553 Roll = 43
6554 RollImage = 44
6555 Rotate = 45
6556 RotateImage = 46
6557 Sample = 47
6558 SampleImage = 48
6559 Scale = 49
6560 ScaleImage = 50
6561 Shade = 51
6562 ShadeImage = 52
6563 Sharpen = 53
6564 SharpenImage = 54
6565 Shear = 55
6566 ShearImage = 56
6567 Spread = 57
6568 SpreadImage = 58
6569 Swirl = 59
6570 SwirlImage = 60
6571 Resize = 61
6572 ResizeImage = 62
6573 Zoom = 63
6574 ZoomImage = 64
6575 Annotate = 65
6576 AnnotateImage = 66
6577 ColorFloodfill = 67
6578 ColorFloodfillImage= 68
6579 Composite = 69
6580 CompositeImage = 70
6581 Contrast = 71
6582 ContrastImage = 72
6583 CycleColormap = 73
6584 CycleColormapImage = 74
6585 Draw = 75
6586 DrawImage = 76
6587 Equalize = 77
6588 EqualizeImage = 78
6589 Gamma = 79
6590 GammaImage = 80
6591 Map = 81
6592 MapImage = 82
6593 MatteFloodfill = 83
6594 MatteFloodfillImage= 84
6595 Modulate = 85
6596 ModulateImage = 86
6597 Negate = 87
6598 NegateImage = 88
6599 Normalize = 89
6600 NormalizeImage = 90
6601 NumberColors = 91
6602 NumberColorsImage = 92
6603 Opaque = 93
6604 OpaqueImage = 94
6605 Quantize = 95
6606 QuantizeImage = 96
6607 Raise = 97
6608 RaiseImage = 98
6609 Segment = 99
6610 SegmentImage = 100
6611 Signature = 101
6612 SignatureImage = 102
6613 Solarize = 103
6614 SolarizeImage = 104
6615 Sync = 105
6616 SyncImage = 106
6617 Texture = 107
6618 TextureImage = 108
6619 Evaluate = 109
6620 EvaluateImage = 110
6621 Transparent = 111
6622 TransparentImage = 112
6623 Threshold = 113
6624 ThresholdImage = 114
6625 Charcoal = 115
6626 CharcoalImage = 116
6627 Trim = 117
6628 TrimImage = 118
6629 Wave = 119
6630 WaveImage = 120
6631 Separate = 121
6632 SeparateImage = 122
6633 Stereo = 125
6634 StereoImage = 126
6635 Stegano = 127
6636 SteganoImage = 128
6637 Deconstruct = 129
6638 DeconstructImage = 130
6639 GaussianBlur = 131
6640 GaussianBlurImage = 132
6641 Convolve = 133
6642 ConvolveImage = 134
6643 Profile = 135
6644 ProfileImage = 136
6645 UnsharpMask = 137
6646 UnsharpMaskImage = 138
6647 MotionBlur = 139
6648 MotionBlurImage = 140
6649 OrderedDither = 141
6650 OrderedDitherImage = 142
6651 Shave = 143
6652 ShaveImage = 144
6653 Level = 145
6654 LevelImage = 146
6655 Clip = 147
6656 ClipImage = 148
6657 AffineTransform = 149
6658 AffineTransformImage = 150
6659 Difference = 151
6660 DifferenceImage = 152
6661 AdaptiveThreshold = 153
6662 AdaptiveThresholdImage = 154
6663 Resample = 155
6664 ResampleImage = 156
6665 Describe = 157
6666 DescribeImage = 158
6667 BlackThreshold = 159
6668 BlackThresholdImage= 160
6669 WhiteThreshold = 161
6670 WhiteThresholdImage= 162
6671 RadialBlur = 163
6672 RadialBlurImage = 164
6673 Thumbnail = 165
6674 ThumbnailImage = 166
6675 Strip = 167
6676 StripImage = 168
6677 Tint = 169
6678 TintImage = 170
6679 Channel = 171
6680 ChannelImage = 172
6681 Splice = 173
6682 SpliceImage = 174
6683 Posterize = 175
6684 PosterizeImage = 176
6685 Shadow = 177
6686 ShadowImage = 178
6687 Identify = 179
6688 IdentifyImage = 180
6689 SepiaTone = 181
6690 SepiaToneImage = 182
6691 SigmoidalContrast = 183
6692 SigmoidalContrastImage = 184
6693 Extent = 185
6694 ExtentImage = 186
6695 Vignette = 187
6696 VignetteImage = 188
6697 ContrastStretch = 189
6698 ContrastStretchImage = 190
6699 Sans0 = 191
6700 Sans0Image = 192
6701 Sans1 = 193
6702 Sans1Image = 194
6703 AdaptiveSharpen = 195
6704 AdaptiveSharpenImage = 196
6705 Transpose = 197
6706 TransposeImage = 198
6707 Transverse = 199
6708 TransverseImage = 200
6709 AutoOrient = 201
6710 AutoOrientImage = 202
6711 AdaptiveBlur = 203
6712 AdaptiveBlurImage = 204
6713 Sketch = 205
6714 SketchImage = 206
6715 UniqueColors = 207
6716 UniqueColorsImage = 208
6717 AdaptiveResize = 209
6718 AdaptiveResizeImage= 210
6719 ClipMask = 211
6720 ClipMaskImage = 212
6721 LinearStretch = 213
6722 LinearStretchImage = 214
6723 RecolorImage = 215
6724 Recolor = 216
6725 Mask = 217
6726 MaskImage = 218
6727 Polaroid = 219
6728 PolaroidImage = 220
6729 FloodfillPaint = 221
6730 FloodfillPaintImage= 222
6731 Distort = 223
6732 DistortImage = 224
6733 Clut = 225
6734 ClutImage = 226
6735 LiquidRescale = 227
6736 LiquidRescaleImage = 228
6737 Encipher = 229
6738 EncipherImage = 230
6739 Decipher = 231
6740 DecipherImage = 232
6741 Deskew = 233
6742 DeskewImage = 234
6743 Remap = 235
6744 RemapImage = 236
6745 SparseColor = 237
6746 SparseColorImage = 238
6747 Function = 239
6748 FunctionImage = 240
6749 SelectiveBlur = 241
6750 SelectiveBlurImage = 242
6751 HaldClut = 243
6752 HaldClutImage = 244
6753 BlueShift = 245
6754 BlueShiftImage = 246
6755 ForwardFourierTransform = 247
6756 ForwardFourierTransformImage = 248
6757 InverseFourierTransform = 249
6758 InverseFourierTransformImage = 250
6759 ColorDecisionList = 251
6760 ColorDecisionListImage = 252
6761 AutoGamma = 253
6762 AutoGammaImage = 254
6763 AutoLevel = 255
6764 AutoLevelImage = 256
cristyee0f8d72009-09-19 00:58:29 +00006765 LevelColors = 257
6766 LevelColorsImage = 258
cristy3ed852e2009-09-05 21:47:34 +00006767 MogrifyRegion = 666
6768 PPCODE:
6769 {
6770 AffineMatrix
6771 affine,
6772 current;
6773
6774 char
6775 attribute_flag[MaxArguments],
6776 message[MaxTextExtent];
6777
6778 ChannelType
6779 channel;
6780
6781 CompositeOperator
6782 compose;
6783
6784 const char
6785 *attribute,
6786 *value;
6787
6788 double
6789 angle;
6790
6791 ExceptionInfo
6792 *exception;
6793
6794 GeometryInfo
6795 geometry_info;
6796
6797 Image
6798 *image,
6799 *next,
6800 *region_image;
6801
6802 long
6803 base,
6804 j,
6805 number_images;
6806
6807 MagickBooleanType
6808 status;
6809
6810 MagickStatusType
6811 flags;
6812
6813 PixelPacket
6814 fill_color;
6815
6816 RectangleInfo
6817 geometry,
6818 region_info;
6819
6820 register long
6821 i;
6822
6823 struct PackageInfo
6824 *info;
6825
6826 struct Methods
6827 *rp;
6828
6829 SV
6830 *perl_exception,
6831 **pv,
6832 *reference,
6833 **reference_vector;
6834
6835 struct ArgumentList
6836 argument_list[MaxArguments];
6837
6838 exception=AcquireExceptionInfo();
6839 perl_exception=newSVpv("",0);
6840 reference_vector=NULL;
6841 region_image=NULL;
6842 number_images=0;
6843 base=2;
6844 if (sv_isobject(ST(0)) == 0)
6845 {
6846 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6847 PackageName);
6848 goto PerlException;
6849 }
6850 reference=SvRV(ST(0));
6851 region_info.width=0;
6852 region_info.height=0;
6853 region_info.x=0;
6854 region_info.y=0;
6855 region_image=(Image *) NULL;
6856 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
6857 if (ix && (ix != 666))
6858 {
6859 /*
6860 Called as Method(...)
6861 */
6862 ix=(ix+1)/2;
6863 rp=(&Methods[ix-1]);
6864 attribute=rp->name;
6865 }
6866 else
6867 {
6868 /*
6869 Called as Mogrify("Method",...)
6870 */
6871 attribute=(char *) SvPV(ST(1),na);
6872 if (ix)
6873 {
6874 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
6875 attribute=(char *) SvPV(ST(2),na);
6876 base++;
6877 }
6878 for (rp=Methods; ; rp++)
6879 {
6880 if (rp >= EndOf(Methods))
6881 {
6882 ThrowPerlException(exception,OptionError,
6883 "UnrecognizedPerlMagickMethod",attribute);
6884 goto PerlException;
6885 }
6886 if (strEQcase(attribute,rp->name))
6887 break;
6888 }
6889 ix=rp-Methods+1;
6890 base++;
6891 }
6892 if (image == (Image *) NULL)
6893 {
6894 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
6895 goto PerlException;
6896 }
6897 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
6898 Zero(&attribute_flag,NumberOf(attribute_flag),char);
6899 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
6900 {
6901 long
6902 longest;
6903
6904 Arguments
6905 *pp,
6906 *qq;
6907
6908 struct ArgumentList
6909 *al;
6910
6911 SV
6912 *sv;
6913
6914 longest=0;
6915 pp=(Arguments *) NULL;
6916 qq=rp->arguments;
6917 if (i == items)
6918 {
6919 pp=rp->arguments,
6920 sv=ST(i-1);
6921 }
6922 else
6923 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
6924 {
6925 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
6926 break;
6927 if (strEQcase(attribute,qq->method) > longest)
6928 {
6929 pp=qq;
6930 longest=strEQcase(attribute,qq->method);
6931 }
6932 }
6933 if (pp == (Arguments *) NULL)
6934 {
6935 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6936 attribute);
6937 goto continue_outer_loop;
6938 }
6939 al=(&argument_list[pp-rp->arguments]);
6940 switch (pp->type)
6941 {
6942 case ArrayReference:
6943 {
6944 if (SvTYPE(sv) != SVt_RV)
6945 {
6946 (void) FormatMagickString(message,MaxTextExtent,
6947 "invalid %.60s value",pp->method);
6948 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
6949 goto continue_outer_loop;
6950 }
6951 al->array_reference=SvRV(sv);
6952 break;
6953 }
6954 case RealReference:
6955 {
6956 al->real_reference=SvNV(sv);
6957 break;
6958 }
6959 case FileReference:
6960 {
6961 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
6962 break;
6963 }
6964 case ImageReference:
6965 {
6966 if (!sv_isobject(sv) ||
6967 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
6968 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
6969 {
6970 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6971 PackageName);
6972 goto PerlException;
6973 }
6974 break;
6975 }
6976 case IntegerReference:
6977 {
6978 al->long_reference=SvIV(sv);
6979 break;
6980 }
6981 case StringReference:
6982 {
6983 al->string_reference=(char *) SvPV(sv,al->length);
6984 if (sv_isobject(sv))
6985 al->image_reference=SetupList(aTHX_ SvRV(sv),
6986 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
6987 break;
6988 }
6989 default:
6990 {
6991 /*
6992 Is a string; look up name.
6993 */
6994 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
6995 {
6996 al->string_reference=(char *) SvPV(sv,al->length);
6997 al->long_reference=(-1);
6998 break;
6999 }
7000 al->long_reference=ParseMagickOption((MagickOption) pp->type,
7001 MagickFalse,SvPV(sv,na));
7002 if (pp->type == MagickChannelOptions)
7003 al->long_reference=ParseChannelOption(SvPV(sv,na));
7004 if ((al->long_reference < 0) && ((al->long_reference=SvIV(sv)) <= 0))
7005 {
7006 (void) FormatMagickString(message,MaxTextExtent,
7007 "invalid %.60s value",pp->method);
7008 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7009 goto continue_outer_loop;
7010 }
7011 break;
7012 }
7013 }
7014 attribute_flag[pp-rp->arguments]++;
7015 continue_outer_loop: ;
7016 }
7017 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7018 pv=reference_vector;
7019 SetGeometryInfo(&geometry_info);
7020 channel=DefaultChannels;
7021 for (next=image; next; next=next->next)
7022 {
7023 image=next;
7024 SetGeometry(image,&geometry);
7025 if ((region_info.width*region_info.height) != 0)
7026 {
7027 region_image=image;
7028 image=CropImage(image,&region_info,exception);
7029 }
7030 switch (ix)
7031 {
7032 default:
7033 {
7034 (void) FormatMagickString(message,MaxTextExtent,"%ld",(long) ix);
7035 ThrowPerlException(exception,OptionError,
7036 "UnrecognizedPerlMagickMethod",message);
7037 goto PerlException;
7038 }
7039 case 1: /* Comment */
7040 {
7041 if (attribute_flag[0] == 0)
7042 argument_list[0].string_reference=(char *) NULL;
7043 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7044 info ? info->image_info : (ImageInfo *) NULL,image,
7045 argument_list[0].string_reference));
7046 break;
7047 }
7048 case 2: /* Label */
7049 {
7050 if (attribute_flag[0] == 0)
7051 argument_list[0].string_reference=(char *) NULL;
7052 (void) SetImageProperty(image,"label",InterpretImageProperties(
7053 info ? info->image_info : (ImageInfo *) NULL,image,
7054 argument_list[0].string_reference));
7055 break;
7056 }
7057 case 3: /* AddNoise */
7058 {
7059 if (attribute_flag[0] == 0)
7060 argument_list[0].long_reference=UniformNoise;
7061 if (attribute_flag[1] != 0)
7062 channel=(ChannelType) argument_list[1].long_reference;
7063 image=AddNoiseImageChannel(image,channel,(NoiseType)
7064 argument_list[0].long_reference,exception);
7065 break;
7066 }
7067 case 4: /* Colorize */
7068 {
7069 PixelPacket
7070 target;
7071
7072 (void) GetOneVirtualPixel(image,0,0,&target,exception);
7073 if (attribute_flag[0] != 0)
7074 (void) QueryColorDatabase(argument_list[0].string_reference,&target,
7075 exception);
7076 if (attribute_flag[1] == 0)
7077 argument_list[1].string_reference="100%";
7078 image=ColorizeImage(image,argument_list[1].string_reference,target,
7079 exception);
7080 break;
7081 }
7082 case 5: /* Border */
7083 {
7084 geometry.width=0;
7085 geometry.height=0;
7086 if (attribute_flag[0] != 0)
7087 {
7088 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7089 &geometry,exception);
7090 if ((flags & HeightValue) == 0)
7091 geometry.height=geometry.width;
7092 }
7093 if (attribute_flag[1] != 0)
7094 geometry.width=argument_list[1].long_reference;
7095 if (attribute_flag[2] != 0)
7096 geometry.height=argument_list[2].long_reference;
7097 if (attribute_flag[3] != 0)
7098 QueryColorDatabase(argument_list[3].string_reference,
7099 &image->border_color,exception);
7100 if (attribute_flag[4] != 0)
7101 QueryColorDatabase(argument_list[4].string_reference,
7102 &image->border_color,exception);
7103 if (attribute_flag[5] != 0)
7104 QueryColorDatabase(argument_list[5].string_reference,
7105 &image->border_color,exception);
7106 if (attribute_flag[6] != 0)
7107 image->compose=(CompositeOperator) argument_list[6].long_reference;
7108 image=BorderImage(image,&geometry,exception);
7109 break;
7110 }
7111 case 6: /* Blur */
7112 {
7113 if (attribute_flag[0] != 0)
7114 {
7115 flags=ParseGeometry(argument_list[0].string_reference,
7116 &geometry_info);
7117 if ((flags & SigmaValue) == 0)
7118 geometry_info.sigma=1.0;
7119 }
7120 if (attribute_flag[1] != 0)
7121 geometry_info.rho=argument_list[1].real_reference;
7122 if (attribute_flag[2] != 0)
7123 geometry_info.sigma=argument_list[2].real_reference;
7124 if (attribute_flag[3] != 0)
7125 channel=(ChannelType) argument_list[3].long_reference;
7126 image=BlurImageChannel(image,channel,geometry_info.rho,
7127 geometry_info.sigma,exception);
7128 break;
7129 }
7130 case 7: /* Chop */
7131 {
7132 if (attribute_flag[0] != 0)
7133 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7134 &geometry,exception);
7135 if (attribute_flag[1] != 0)
7136 geometry.width=argument_list[1].long_reference;
7137 if (attribute_flag[2] != 0)
7138 geometry.height=argument_list[2].long_reference;
7139 if (attribute_flag[3] != 0)
7140 geometry.x=argument_list[3].long_reference;
7141 if (attribute_flag[4] != 0)
7142 geometry.y=argument_list[4].long_reference;
7143 image=ChopImage(image,&geometry,exception);
7144 break;
7145 }
7146 case 8: /* Crop */
7147 {
7148 if (attribute_flag[0] != 0)
7149 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7150 &geometry,exception);
7151 if (attribute_flag[1] != 0)
7152 geometry.width=argument_list[1].long_reference;
7153 if (attribute_flag[2] != 0)
7154 geometry.height=argument_list[2].long_reference;
7155 if (attribute_flag[3] != 0)
7156 geometry.x=argument_list[3].long_reference;
7157 if (attribute_flag[4] != 0)
7158 geometry.y=argument_list[4].long_reference;
7159 if (attribute_flag[5] != 0)
7160 image->fuzz=
7161 StringToDouble(argument_list[5].string_reference,QuantumRange);
7162 image=CropImage(image,&geometry,exception);
7163 break;
7164 }
7165 case 9: /* Despeckle */
7166 {
7167 image=DespeckleImage(image,exception);
7168 break;
7169 }
7170 case 10: /* Edge */
7171 {
7172 if (attribute_flag[0] != 0)
7173 geometry_info.rho=argument_list[0].real_reference;
7174 image=EdgeImage(image,geometry_info.rho,exception);
7175 break;
7176 }
7177 case 11: /* Emboss */
7178 {
7179 if (attribute_flag[0] != 0)
7180 {
7181 flags=ParseGeometry(argument_list[0].string_reference,
7182 &geometry_info);
7183 if ((flags & SigmaValue) == 0)
7184 geometry_info.sigma=1.0;
7185 }
7186 if (attribute_flag[1] != 0)
7187 geometry_info.rho=argument_list[1].real_reference;
7188 if (attribute_flag[2] != 0)
7189 geometry_info.sigma=argument_list[2].real_reference;
7190 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
7191 exception);
7192 break;
7193 }
7194 case 12: /* Enhance */
7195 {
7196 image=EnhanceImage(image,exception);
7197 break;
7198 }
7199 case 13: /* Flip */
7200 {
7201 image=FlipImage(image,exception);
7202 break;
7203 }
7204 case 14: /* Flop */
7205 {
7206 image=FlopImage(image,exception);
7207 break;
7208 }
7209 case 15: /* Frame */
7210 {
7211 FrameInfo
7212 frame_info;
7213
7214 if (attribute_flag[0] != 0)
7215 {
7216 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7217 &geometry,exception);
7218 if ((flags & HeightValue) == 0)
7219 geometry.height=geometry.width;
7220 frame_info.width=geometry.width;
7221 frame_info.height=geometry.height;
7222 frame_info.outer_bevel=geometry.x;
7223 frame_info.inner_bevel=geometry.y;
7224 }
7225 if (attribute_flag[1] != 0)
7226 frame_info.width=argument_list[1].long_reference;
7227 if (attribute_flag[2] != 0)
7228 frame_info.height=argument_list[2].long_reference;
7229 if (attribute_flag[3] != 0)
7230 frame_info.inner_bevel=argument_list[3].long_reference;
7231 if (attribute_flag[4] != 0)
7232 frame_info.outer_bevel=argument_list[4].long_reference;
7233 if (attribute_flag[5] != 0)
7234 QueryColorDatabase(argument_list[5].string_reference,&fill_color,
7235 exception);
7236 if (attribute_flag[6] != 0)
7237 QueryColorDatabase(argument_list[6].string_reference,&fill_color,
7238 exception);
7239 frame_info.x=(long) frame_info.width;
7240 frame_info.y=(long) frame_info.height;
7241 frame_info.width=image->columns+2*frame_info.x;
7242 frame_info.height=image->rows+2*frame_info.y;
7243 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
7244 image->matte_color=fill_color;
7245 if (attribute_flag[7] != 0)
7246 image->compose=(CompositeOperator) argument_list[7].long_reference;
7247 image=FrameImage(image,&frame_info,exception);
7248 break;
7249 }
7250 case 16: /* Implode */
7251 {
7252 if (attribute_flag[0] == 0)
7253 argument_list[0].real_reference=0.5;
7254 if (attribute_flag[1] != 0)
7255 image->interpolate=(InterpolatePixelMethod)
7256 argument_list[1].long_reference;
7257 image=ImplodeImage(image,argument_list[0].real_reference,
7258 exception);
7259 break;
7260 }
7261 case 17: /* Magnify */
7262 {
7263 image=MagnifyImage(image,exception);
7264 break;
7265 }
7266 case 18: /* MedianFilter */
7267 {
7268 if (attribute_flag[0] == 0)
7269 argument_list[0].real_reference=0.0;
7270 image=MedianFilterImage(image,argument_list[0].real_reference,
7271 exception);
7272 break;
7273 }
7274 case 19: /* Minify */
7275 {
7276 image=MinifyImage(image,exception);
7277 break;
7278 }
7279 case 20: /* OilPaint */
7280 {
7281 if (attribute_flag[0] == 0)
7282 argument_list[0].real_reference=0.0;
7283 image=OilPaintImage(image,argument_list[0].real_reference,
7284 exception);
7285 break;
7286 }
7287 case 21: /* ReduceNoise */
7288 {
7289 if (attribute_flag[0] == 0)
7290 argument_list[0].real_reference=0.0;
7291 image=ReduceNoiseImage(image,argument_list[0].real_reference,
7292 exception);
7293 break;
7294 }
7295 case 22: /* Roll */
7296 {
7297 if (attribute_flag[0] != 0)
7298 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7299 &geometry,exception);
7300 if (attribute_flag[1] != 0)
7301 geometry.x=argument_list[1].long_reference;
7302 if (attribute_flag[2] != 0)
7303 geometry.y=argument_list[2].long_reference;
7304 image=RollImage(image,geometry.x,geometry.y,exception);
7305 break;
7306 }
7307 case 23: /* Rotate */
7308 {
7309 if (attribute_flag[0] == 0)
7310 argument_list[0].real_reference=90.0;
7311 if (attribute_flag[1] != 0)
7312 QueryColorDatabase(argument_list[1].string_reference,
7313 &image->background_color,exception);
7314 if (attribute_flag[2] != 0)
7315 QueryColorDatabase(argument_list[2].string_reference,
7316 &image->background_color,exception);
7317 if (attribute_flag[3] != 0)
7318 QueryColorDatabase(argument_list[3].string_reference,
7319 &image->background_color,exception);
7320 image=RotateImage(image,argument_list[0].real_reference,exception);
7321 break;
7322 }
7323 case 24: /* Sample */
7324 {
7325 if (attribute_flag[0] != 0)
7326 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7327 &geometry,exception);
7328 if (attribute_flag[1] != 0)
7329 geometry.width=argument_list[1].long_reference;
7330 if (attribute_flag[2] != 0)
7331 geometry.height=argument_list[2].long_reference;
7332 image=SampleImage(image,geometry.width,geometry.height,exception);
7333 break;
7334 }
7335 case 25: /* Scale */
7336 {
7337 if (attribute_flag[0] != 0)
7338 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7339 &geometry,exception);
7340 if (attribute_flag[1] != 0)
7341 geometry.width=argument_list[1].long_reference;
7342 if (attribute_flag[2] != 0)
7343 geometry.height=argument_list[2].long_reference;
7344 image=ScaleImage(image,geometry.width,geometry.height,exception);
7345 break;
7346 }
7347 case 26: /* Shade */
7348 {
7349 if (attribute_flag[0] != 0)
7350 {
7351 flags=ParseGeometry(argument_list[0].string_reference,
7352 &geometry_info);
7353 if ((flags & SigmaValue) == 0)
7354 geometry_info.sigma=0.0;
7355 }
7356 if (attribute_flag[1] != 0)
7357 geometry_info.rho=argument_list[1].real_reference;
7358 if (attribute_flag[2] != 0)
7359 geometry_info.sigma=argument_list[2].real_reference;
7360 image=ShadeImage(image,
7361 argument_list[3].long_reference != 0 ? MagickTrue : MagickFalse,
7362 geometry_info.rho,geometry_info.sigma,exception);
7363 break;
7364 }
7365 case 27: /* Sharpen */
7366 {
7367 if (attribute_flag[0] != 0)
7368 {
7369 flags=ParseGeometry(argument_list[0].string_reference,
7370 &geometry_info);
7371 if ((flags & SigmaValue) == 0)
7372 geometry_info.sigma=1.0;
7373 }
7374 if (attribute_flag[1] != 0)
7375 geometry_info.rho=argument_list[1].real_reference;
7376 if (attribute_flag[2] != 0)
7377 geometry_info.sigma=argument_list[2].real_reference;
7378 if (attribute_flag[3] != 0)
7379 channel=(ChannelType) argument_list[3].long_reference;
7380 image=SharpenImageChannel(image,channel,geometry_info.rho,
7381 geometry_info.sigma,exception);
7382 break;
7383 }
7384 case 28: /* Shear */
7385 {
7386 if (attribute_flag[0] != 0)
7387 {
7388 flags=ParseGeometry(argument_list[0].string_reference,
7389 &geometry_info);
7390 if ((flags & SigmaValue) == 0)
7391 geometry_info.sigma=geometry_info.rho;
7392 }
7393 if (attribute_flag[1] != 0)
7394 geometry_info.rho=argument_list[1].real_reference;
7395 if (attribute_flag[2] != 0)
7396 geometry_info.sigma=argument_list[2].real_reference;
7397 if (attribute_flag[3] != 0)
7398 QueryColorDatabase(argument_list[3].string_reference,
7399 &image->background_color,exception);
7400 if (attribute_flag[4] != 0)
7401 QueryColorDatabase(argument_list[4].string_reference,
7402 &image->background_color,exception);
7403 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
7404 exception);
7405 break;
7406 }
7407 case 29: /* Spread */
7408 {
7409 if (attribute_flag[0] == 0)
7410 argument_list[0].real_reference=1.0;
7411 image=SpreadImage(image,argument_list[0].real_reference,exception);
7412 break;
7413 }
7414 case 30: /* Swirl */
7415 {
7416 if (attribute_flag[0] == 0)
7417 argument_list[0].real_reference=50.0;
7418 if (attribute_flag[1] != 0)
7419 image->interpolate=(InterpolatePixelMethod)
7420 argument_list[1].long_reference;
7421 image=SwirlImage(image,argument_list[0].real_reference,exception);
7422 break;
7423 }
7424 case 31: /* Resize */
7425 case 32: /* Zoom */
7426 {
7427 if (attribute_flag[0] != 0)
7428 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7429 &geometry,exception);
7430 if (attribute_flag[1] != 0)
7431 geometry.width=argument_list[1].long_reference;
7432 if (attribute_flag[2] != 0)
7433 geometry.height=argument_list[2].long_reference;
7434 if (attribute_flag[3] == 0)
7435 argument_list[3].long_reference=(long) UndefinedFilter;
7436 if (attribute_flag[4] != 0)
7437 SetImageArtifact(image,"filter:support",
7438 argument_list[4].string_reference);
7439 if (attribute_flag[5] == 0)
7440 argument_list[5].real_reference=1.0;
7441 image=ResizeImage(image,geometry.width,geometry.height,
7442 (FilterTypes) argument_list[3].long_reference,
7443 argument_list[5].real_reference,exception);
7444 break;
7445 }
7446 case 33: /* Annotate */
7447 {
7448 DrawInfo
7449 *draw_info;
7450
7451 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
7452 (DrawInfo *) NULL);
7453 if (attribute_flag[0] != 0)
7454 {
7455 char
7456 *text;
7457
7458 text=InterpretImageProperties(info ? info->image_info :
7459 (ImageInfo *) NULL,image,argument_list[0].string_reference);
7460 (void) CloneString(&draw_info->text,text);
7461 text=DestroyString(text);
7462 }
7463 if (attribute_flag[1] != 0)
7464 (void) CloneString(&draw_info->font,
7465 argument_list[1].string_reference);
7466 if (attribute_flag[2] != 0)
7467 draw_info->pointsize=argument_list[2].real_reference;
7468 if (attribute_flag[3] != 0)
7469 (void) CloneString(&draw_info->density,
7470 argument_list[3].string_reference);
7471 if (attribute_flag[4] != 0)
7472 (void) QueryColorDatabase(argument_list[4].string_reference,
7473 &draw_info->undercolor,exception);
7474 if (attribute_flag[5] != 0)
7475 {
7476 (void) QueryColorDatabase(argument_list[5].string_reference,
7477 &draw_info->stroke,exception);
7478 if (argument_list[5].image_reference != (Image *) NULL)
7479 draw_info->stroke_pattern=CloneImage(
7480 argument_list[5].image_reference,0,0,MagickTrue,exception);
7481 }
7482 if (attribute_flag[6] != 0)
7483 {
7484 (void) QueryColorDatabase(argument_list[6].string_reference,
7485 &draw_info->fill,exception);
7486 if (argument_list[6].image_reference != (Image *) NULL)
7487 draw_info->fill_pattern=CloneImage(
7488 argument_list[6].image_reference,0,0,MagickTrue,exception);
7489 }
7490 if (attribute_flag[7] != 0)
7491 {
7492 (void) CloneString(&draw_info->geometry,
7493 argument_list[7].string_reference);
7494 flags=ParsePageGeometry(image,argument_list[7].string_reference,
7495 &geometry,exception);
7496 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
7497 geometry_info.sigma=geometry_info.xi;
7498 }
7499 if (attribute_flag[8] != 0)
7500 (void) QueryColorDatabase(argument_list[8].string_reference,
7501 &draw_info->fill,exception);
7502 if (attribute_flag[11] != 0)
7503 draw_info->gravity=(GravityType) argument_list[11].long_reference;
7504 if (attribute_flag[25] != 0)
7505 {
7506 AV
7507 *av;
7508
7509 av=(AV *) argument_list[25].array_reference;
7510 if ((av_len(av) != 3) && (av_len(av) != 5))
7511 {
7512 ThrowPerlException(exception,OptionError,
7513 "affine matrix must have 4 or 6 elements",PackageName);
7514 goto PerlException;
7515 }
7516 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
7517 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
7518 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
7519 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
7520 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
7521 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
7522 {
7523 ThrowPerlException(exception,OptionError,
7524 "affine matrix is singular",PackageName);
7525 goto PerlException;
7526 }
7527 if (av_len(av) == 5)
7528 {
7529 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
7530 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
7531 }
7532 }
7533 for (j=12; j < 17; j++)
7534 {
7535 if (attribute_flag[j] == 0)
7536 continue;
7537 value=argument_list[j].string_reference;
7538 angle=argument_list[j].real_reference;
7539 current=draw_info->affine;
7540 GetAffineMatrix(&affine);
7541 switch (j)
7542 {
7543 case 12:
7544 {
7545 /*
7546 Translate.
7547 */
7548 flags=ParseGeometry(value,&geometry_info);
7549 affine.tx=geometry_info.xi;
7550 affine.ty=geometry_info.psi;
7551 if ((flags & PsiValue) == 0)
7552 affine.ty=affine.tx;
7553 break;
7554 }
7555 case 13:
7556 {
7557 /*
7558 Scale.
7559 */
7560 flags=ParseGeometry(value,&geometry_info);
7561 affine.sx=geometry_info.rho;
7562 affine.sy=geometry_info.sigma;
7563 if ((flags & SigmaValue) == 0)
7564 affine.sy=affine.sx;
7565 break;
7566 }
7567 case 14:
7568 {
7569 /*
7570 Rotate.
7571 */
7572 if (angle == 0.0)
7573 break;
7574 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
7575 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
7576 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
7577 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
7578 break;
7579 }
7580 case 15:
7581 {
7582 /*
7583 SkewX.
7584 */
7585 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
7586 break;
7587 }
7588 case 16:
7589 {
7590 /*
7591 SkewY.
7592 */
7593 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
7594 break;
7595 }
7596 }
7597 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
7598 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
7599 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
7600 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
7601 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
7602 current.tx;
7603 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
7604 current.ty;
7605 }
7606 if (attribute_flag[9] == 0)
7607 argument_list[9].real_reference=0.0;
7608 if (attribute_flag[10] == 0)
7609 argument_list[10].real_reference=0.0;
7610 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
7611 {
7612 char
7613 geometry[MaxTextExtent];
7614
7615 (void) FormatMagickString(geometry,MaxTextExtent,"%+f%+f",
7616 (double) argument_list[9].real_reference+draw_info->affine.tx,
7617 (double) argument_list[10].real_reference+draw_info->affine.ty);
7618 (void) CloneString(&draw_info->geometry,geometry);
7619 }
7620 if (attribute_flag[17] != 0)
7621 draw_info->stroke_width=argument_list[17].real_reference;
7622 if (attribute_flag[18] != 0)
7623 {
7624 draw_info->text_antialias=argument_list[18].long_reference != 0 ?
7625 MagickTrue : MagickFalse;
7626 draw_info->stroke_antialias=draw_info->text_antialias;
7627 }
7628 if (attribute_flag[19] != 0)
7629 (void) CloneString(&draw_info->family,
7630 argument_list[19].string_reference);
7631 if (attribute_flag[20] != 0)
7632 draw_info->style=(StyleType) argument_list[20].long_reference;
7633 if (attribute_flag[21] != 0)
7634 draw_info->stretch=(StretchType) argument_list[21].long_reference;
7635 if (attribute_flag[22] != 0)
7636 draw_info->weight=argument_list[22].long_reference;
7637 if (attribute_flag[23] != 0)
7638 draw_info->align=(AlignType) argument_list[23].long_reference;
7639 if (attribute_flag[24] != 0)
7640 (void) CloneString(&draw_info->encoding,
7641 argument_list[24].string_reference);
7642 if (attribute_flag[25] != 0)
7643 draw_info->fill_pattern=CloneImage(
7644 argument_list[25].image_reference,0,0,MagickTrue,exception);
7645 if (attribute_flag[26] != 0)
7646 draw_info->fill_pattern=CloneImage(
7647 argument_list[26].image_reference,0,0,MagickTrue,exception);
7648 if (attribute_flag[27] != 0)
7649 draw_info->stroke_pattern=CloneImage(
7650 argument_list[27].image_reference,0,0,MagickTrue,exception);
7651 if (attribute_flag[29] != 0)
7652 draw_info->kerning=argument_list[29].real_reference;
7653 if (attribute_flag[30] != 0)
cristyb32b90a2009-09-07 21:45:48 +00007654 draw_info->interline_spacing=argument_list[30].real_reference;
7655 if (attribute_flag[31] != 0)
7656 draw_info->interword_spacing=argument_list[31].real_reference;
cristy3ed852e2009-09-05 21:47:34 +00007657 (void) AnnotateImage(image,draw_info);
7658 draw_info=DestroyDrawInfo(draw_info);
7659 break;
7660 }
7661 case 34: /* ColorFloodfill */
7662 {
7663 DrawInfo
7664 *draw_info;
7665
7666 MagickBooleanType
7667 invert;
7668
7669 MagickPixelPacket
7670 target;
7671
7672 draw_info=CloneDrawInfo(info ? info->image_info :
7673 (ImageInfo *) NULL,(DrawInfo *) NULL);
7674 if (attribute_flag[0] != 0)
7675 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7676 &geometry,exception);
7677 if (attribute_flag[1] != 0)
7678 geometry.x=argument_list[1].long_reference;
7679 if (attribute_flag[2] != 0)
7680 geometry.y=argument_list[2].long_reference;
7681 if (attribute_flag[3] != 0)
7682 (void) QueryColorDatabase(argument_list[3].string_reference,
7683 &draw_info->fill,exception);
7684 (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target,
7685 exception);
7686 invert=MagickFalse;
7687 if (attribute_flag[4] != 0)
7688 {
7689 QueryMagickColor(argument_list[4].string_reference,&target,
7690 exception);
7691 invert=MagickTrue;
7692 }
7693 if (attribute_flag[5] != 0)
7694 image->fuzz=StringToDouble(argument_list[5].string_reference,
7695 QuantumRange);
7696 if (attribute_flag[6] != 0)
7697 invert=(MagickBooleanType) argument_list[6].long_reference;
7698 (void) FloodfillPaintImage(image,DefaultChannels,draw_info,&target,
7699 geometry.x,geometry.y,invert);
7700 draw_info=DestroyDrawInfo(draw_info);
7701 break;
7702 }
7703 case 35: /* Composite */
7704 {
7705 char
7706 composite_geometry[MaxTextExtent];
7707
7708 Image
7709 *composite_image,
7710 *rotate_image;
7711
7712 compose=OverCompositeOp;
7713 if (attribute_flag[0] != 0)
7714 composite_image=argument_list[0].image_reference;
7715 else
7716 {
7717 ThrowPerlException(exception,OptionError,
7718 "CompositeImageRequired",PackageName);
7719 goto PerlException;
7720 }
7721 /*
7722 Parameter Handling used for BOTH normal and tiled composition.
7723 */
7724 if (attribute_flag[1] != 0) /* compose */
7725 compose=(CompositeOperator) argument_list[1].long_reference;
7726 if (attribute_flag[6] != 0) /* opacity */
7727 {
7728 if (compose != DissolveCompositeOp)
7729 (void) SetImageOpacity(composite_image,(Quantum) (QuantumRange-
7730 StringToDouble(argument_list[6].string_reference,
7731 QuantumRange)));
7732 else
7733 {
7734 double
7735 opacity;
7736
7737 long
7738 y;
7739
7740 MagickBooleanType
7741 sync;
7742
7743 register long
7744 x;
7745
7746 register PixelPacket
7747 *q;
7748
7749 CacheView
7750 *composite_view;
7751
7752 /*
7753 Handle dissolve composite operator (patch by
7754 Kevin A. McGrail).
7755 */
7756 (void) CloneString(&image->geometry,
7757 argument_list[6].string_reference);
7758 opacity=(Quantum) (QuantumRange-StringToDouble(
7759 argument_list[6].string_reference,QuantumRange));
7760 if (composite_image->matte != MagickTrue)
7761 (void) SetImageOpacity(composite_image,OpaqueOpacity);
7762 composite_view=OpenCacheView(composite_image);
7763 for (y=0; y < (long) composite_image->rows ; y++)
7764 {
7765 q=GetCacheViewPixels(composite_view,0,y,(long)
7766 composite_image->columns,1);
7767 for (x=0; x < (long) composite_image->columns; x++)
7768 {
7769 if (q->opacity == OpaqueOpacity)
7770 q->opacity=RoundToQuantum(opacity);
7771 q++;
7772 }
7773 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
7774 if (sync == MagickFalse)
7775 break;
7776 }
7777 composite_view=CloseCacheView(composite_view);
7778 }
7779 }
7780 if (attribute_flag[9] != 0) /* "color=>" */
7781 QueryColorDatabase(argument_list[9].string_reference,
7782 &composite_image->background_color,exception);
7783 if (attribute_flag[12] != 0) /* "interpolate=>" */
7784 image->interpolate=(InterpolatePixelMethod)
7785 argument_list[12].long_reference;
7786 if (attribute_flag[13] != 0) /* "args=>" */
7787 (void) SetImageArtifact(composite_image,"compose:args",
7788 argument_list[13].string_reference);
7789 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
7790 (void) SetImageArtifact(composite_image,"compose:args",
7791 argument_list[14].string_reference);
7792 /*
7793 Tiling Composition (with orthogonal rotate).
7794 */
7795 rotate_image=(Image *) NULL;
7796 if (attribute_flag[8] != 0) /* "rotate=>" */
7797 {
7798 /*
7799 Rotate image.
7800 */
7801 rotate_image=RotateImage(composite_image,
7802 argument_list[8].real_reference,exception);
7803 if (rotate_image == (Image *) NULL)
7804 break;
7805 }
7806 if (attribute_flag[7] && argument_list[7].long_reference) /* tile */
7807 {
7808 long
7809 x,
7810 y;
7811
7812 /*
7813 Tile the composite image.
7814 */
7815 if (attribute_flag[8] != 0) /* "tile=>" */
7816 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
7817 "false");
7818 else
7819 (void) SetImageArtifact(composite_image,
7820 "compose:outside-overlay","false");
7821 for (y=0; y < (long) image->rows; y+=composite_image->rows)
7822 for (x=0; x < (long) image->columns; x+=composite_image->columns)
7823 {
7824 if (attribute_flag[8] != 0) /* rotate */
7825 (void) CompositeImage(image,compose,rotate_image,x,y);
7826 else
7827 (void) CompositeImage(image,compose,composite_image,x,y);
7828 }
7829 if (attribute_flag[8] != 0) /* rotate */
7830 rotate_image=DestroyImage(rotate_image);
7831 break;
7832 }
7833 /*
7834 Parameter Handling used used ONLY for normal composition.
7835 */
7836 if (attribute_flag[5] != 0) /* gravity */
7837 image->gravity=(GravityType) argument_list[5].long_reference;
7838 if (attribute_flag[2] != 0) /* geometry offset */
7839 {
7840 SetGeometry(image,&geometry);
7841 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
7842 &geometry);
7843 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
7844 &geometry);
7845 }
7846 if (attribute_flag[3] != 0) /* x offset */
7847 geometry.x=argument_list[3].long_reference;
7848 if (attribute_flag[4] != 0) /* y offset */
7849 geometry.y=argument_list[4].long_reference;
7850 if (attribute_flag[10] != 0) /* mask */
7851 {
7852 if ((image->compose == DisplaceCompositeOp) ||
7853 (image->compose == DistortCompositeOp))
7854 {
7855 /*
7856 Merge Y displacement into X displacement image.
7857 */
7858 composite_image=CloneImage(composite_image,0,0,MagickTrue,
7859 &image->exception);
7860 (void) CompositeImage(composite_image,CopyGreenCompositeOp,
7861 argument_list[10].image_reference,0,0);
7862 }
7863 else
7864 {
7865 /*
7866 Set a blending mask for the composition.
7867 */
7868 image->mask=CloneImage(argument_list[10].image_reference,0,0,
7869 MagickTrue,&image->exception);
7870 (void) NegateImage(image->mask,MagickFalse);
7871 }
7872 }
7873 if (attribute_flag[11] != 0) /* channel */
7874 channel=(ChannelType) argument_list[11].long_reference;
7875 /*
7876 Composite two images (normal composition).
7877 */
7878 (void) FormatMagickString(composite_geometry,MaxTextExtent,
7879 "%lux%lu%+ld%+ld",composite_image->columns,composite_image->rows,
7880 geometry.x,geometry.y);
7881 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
7882 exception);
7883 if (attribute_flag[8] == 0) /* no rotate */
7884 CompositeImageChannel(image,channel,compose,composite_image,
7885 geometry.x,geometry.y);
7886 else
7887 {
7888 /*
7889 Position adjust rotated image then composite.
7890 */
7891 geometry.x-=(long) (rotate_image->columns-
7892 composite_image->columns)/2;
7893 geometry.y-=(long) (rotate_image->rows-composite_image->rows)/2;
7894 CompositeImageChannel(image,channel,compose,rotate_image,
7895 geometry.x,geometry.y);
7896 rotate_image=DestroyImage(rotate_image);
7897 }
7898 if (attribute_flag[10] != 0) /* mask */
7899 {
7900 if ((image->compose == DisplaceCompositeOp) ||
7901 (image->compose == DistortCompositeOp))
7902 composite_image=DestroyImage(composite_image);
7903 else
7904 image->mask=DestroyImage(image->mask);
7905 }
7906 break;
7907 }
7908 case 36: /* Contrast */
7909 {
7910 if (attribute_flag[0] == 0)
7911 argument_list[0].long_reference=0;
7912 (void) ContrastImage(image,argument_list[0].long_reference != 0 ?
7913 MagickTrue : MagickFalse);
7914 break;
7915 }
7916 case 37: /* CycleColormap */
7917 {
7918 if (attribute_flag[0] == 0)
7919 argument_list[0].long_reference=6;
7920 (void) CycleColormapImage(image,argument_list[0].long_reference);
7921 break;
7922 }
7923 case 38: /* Draw */
7924 {
7925 DrawInfo
7926 *draw_info;
7927
7928 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
7929 (DrawInfo *) NULL);
7930 (void) CloneString(&draw_info->primitive,"point");
7931 if (attribute_flag[0] != 0)
7932 {
7933 if (argument_list[0].long_reference < 0)
7934 (void) CloneString(&draw_info->primitive,
7935 argument_list[0].string_reference);
7936 else
7937 (void) CloneString(&draw_info->primitive,MagickOptionToMnemonic(
7938 MagickPrimitiveOptions,argument_list[0].long_reference));
7939 }
7940 if (attribute_flag[1] != 0)
7941 {
7942 if (LocaleCompare(draw_info->primitive,"path") == 0)
7943 {
7944 (void) ConcatenateString(&draw_info->primitive," '");
7945 ConcatenateString(&draw_info->primitive,
7946 argument_list[1].string_reference);
7947 (void) ConcatenateString(&draw_info->primitive,"'");
7948 }
7949 else
7950 {
7951 (void) ConcatenateString(&draw_info->primitive," ");
7952 ConcatenateString(&draw_info->primitive,
7953 argument_list[1].string_reference);
7954 }
7955 }
7956 if (attribute_flag[2] != 0)
7957 {
7958 (void) ConcatenateString(&draw_info->primitive," ");
7959 (void) ConcatenateString(&draw_info->primitive,
7960 MagickOptionToMnemonic(MagickMethodOptions,
7961 argument_list[2].long_reference));
7962 }
7963 if (attribute_flag[3] != 0)
7964 {
7965 (void) QueryColorDatabase(argument_list[3].string_reference,
7966 &draw_info->stroke,exception);
7967 if (argument_list[3].image_reference != (Image *) NULL)
7968 draw_info->stroke_pattern=CloneImage(
7969 argument_list[3].image_reference,0,0,MagickTrue,exception);
7970 }
7971 if (attribute_flag[4] != 0)
7972 {
7973 (void) QueryColorDatabase(argument_list[4].string_reference,
7974 &draw_info->fill,exception);
7975 if (argument_list[4].image_reference != (Image *) NULL)
7976 draw_info->fill_pattern=CloneImage(
7977 argument_list[4].image_reference,0,0,MagickTrue,exception);
7978 }
7979 if (attribute_flag[5] != 0)
7980 draw_info->stroke_width=argument_list[5].real_reference;
7981 if (attribute_flag[6] != 0)
7982 (void) CloneString(&draw_info->font,
7983 argument_list[6].string_reference);
7984 if (attribute_flag[7] != 0)
7985 (void) QueryColorDatabase(argument_list[7].string_reference,
7986 &draw_info->border_color,exception);
7987 if (attribute_flag[8] != 0)
7988 draw_info->affine.tx=argument_list[8].real_reference;
7989 if (attribute_flag[9] != 0)
7990 draw_info->affine.ty=argument_list[9].real_reference;
7991 if (attribute_flag[20] != 0)
7992 {
7993 AV
7994 *av;
7995
7996 av=(AV *) argument_list[20].array_reference;
7997 if ((av_len(av) != 3) && (av_len(av) != 5))
7998 {
7999 ThrowPerlException(exception,OptionError,
8000 "affine matrix must have 4 or 6 elements",PackageName);
8001 goto PerlException;
8002 }
8003 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8004 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8005 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8006 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8007 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8008 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8009 {
8010 ThrowPerlException(exception,OptionError,
8011 "affine matrix is singular",PackageName);
8012 goto PerlException;
8013 }
8014 if (av_len(av) == 5)
8015 {
8016 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8017 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8018 }
8019 }
8020 for (j=10; j < 15; j++)
8021 {
8022 if (attribute_flag[j] == 0)
8023 continue;
8024 value=argument_list[j].string_reference;
8025 angle=argument_list[j].real_reference;
8026 current=draw_info->affine;
8027 GetAffineMatrix(&affine);
8028 switch (j)
8029 {
8030 case 10:
8031 {
8032 /*
8033 Translate.
8034 */
8035 flags=ParseGeometry(value,&geometry_info);
8036 affine.tx=geometry_info.xi;
8037 affine.ty=geometry_info.psi;
8038 if ((flags & PsiValue) == 0)
8039 affine.ty=affine.tx;
8040 break;
8041 }
8042 case 11:
8043 {
8044 /*
8045 Scale.
8046 */
8047 flags=ParseGeometry(value,&geometry_info);
8048 affine.sx=geometry_info.rho;
8049 affine.sy=geometry_info.sigma;
8050 if ((flags & SigmaValue) == 0)
8051 affine.sy=affine.sx;
8052 break;
8053 }
8054 case 12:
8055 {
8056 /*
8057 Rotate.
8058 */
8059 if (angle == 0.0)
8060 break;
8061 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8062 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8063 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8064 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8065 break;
8066 }
8067 case 13:
8068 {
8069 /*
8070 SkewX.
8071 */
8072 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8073 break;
8074 }
8075 case 14:
8076 {
8077 /*
8078 SkewY.
8079 */
8080 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8081 break;
8082 }
8083 }
8084 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8085 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8086 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8087 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8088 draw_info->affine.tx=
8089 current.sx*affine.tx+current.ry*affine.ty+current.tx;
8090 draw_info->affine.ty=
8091 current.rx*affine.tx+current.sy*affine.ty+current.ty;
8092 }
8093 if (attribute_flag[15] != 0)
8094 draw_info->fill_pattern=CloneImage(
8095 argument_list[15].image_reference,0,0,MagickTrue,exception);
8096 if (attribute_flag[16] != 0)
8097 draw_info->pointsize=argument_list[16].real_reference;
8098 if (attribute_flag[17] != 0)
8099 {
8100 draw_info->stroke_antialias=argument_list[17].long_reference != 0
8101 ? MagickTrue : MagickFalse;
8102 draw_info->text_antialias=draw_info->stroke_antialias;
8103 }
8104 if (attribute_flag[18] != 0)
8105 (void) CloneString(&draw_info->density,
8106 argument_list[18].string_reference);
8107 if (attribute_flag[19] != 0)
8108 draw_info->stroke_width=argument_list[19].real_reference;
8109 if (attribute_flag[21] != 0)
8110 draw_info->dash_offset=argument_list[21].real_reference;
8111 if (attribute_flag[22] != 0)
8112 {
8113 AV
8114 *av;
8115
8116 av=(AV *) argument_list[22].array_reference;
8117 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
8118 av_len(av)+1UL,sizeof(draw_info->dash_pattern));
8119 if (draw_info->dash_pattern != (double *) NULL)
8120 {
8121 for (i=0; i <= av_len(av); i++)
8122 draw_info->dash_pattern[i]=(double)
8123 SvNV(*(av_fetch(av,i,0)));
8124 draw_info->dash_pattern[i]=0.0;
8125 }
8126 }
8127 if (attribute_flag[23] != 0)
8128 image->interpolate=(InterpolatePixelMethod)
8129 argument_list[23].long_reference;
8130 if ((attribute_flag[24] != 0) &&
8131 (draw_info->fill_pattern != (Image *) NULL))
8132 flags=ParsePageGeometry(draw_info->fill_pattern,
8133 argument_list[24].string_reference,
8134 &draw_info->fill_pattern->tile_offset,exception);
8135 if (attribute_flag[25] != 0)
8136 {
8137 (void) ConcatenateString(&draw_info->primitive," '");
8138 (void) ConcatenateString(&draw_info->primitive,
8139 argument_list[25].string_reference);
8140 (void) ConcatenateString(&draw_info->primitive,"'");
8141 }
8142 if (attribute_flag[26] != 0)
8143 draw_info->fill_pattern=CloneImage(
8144 argument_list[26].image_reference,0,0,MagickTrue,exception);
8145 if (attribute_flag[27] != 0)
8146 draw_info->stroke_pattern=CloneImage(
8147 argument_list[27].image_reference,0,0,MagickTrue,exception);
8148 if (attribute_flag[28] != 0)
8149 (void) CloneString(&draw_info->primitive,
8150 argument_list[28].string_reference);
8151 if (attribute_flag[29] != 0)
8152 draw_info->kerning=argument_list[29].real_reference;
8153 if (attribute_flag[30] != 0)
cristyb32b90a2009-09-07 21:45:48 +00008154 draw_info->interline_spacing=argument_list[30].real_reference;
8155 if (attribute_flag[31] != 0)
8156 draw_info->interword_spacing=argument_list[31].real_reference;
cristy3ed852e2009-09-05 21:47:34 +00008157 DrawImage(image,draw_info);
8158 draw_info=DestroyDrawInfo(draw_info);
8159 break;
8160 }
8161 case 39: /* Equalize */
8162 {
8163 if (attribute_flag[0] != 0)
8164 channel=(ChannelType) argument_list[0].long_reference;
8165 EqualizeImageChannel(image,channel);
8166 break;
8167 }
8168 case 40: /* Gamma */
8169 {
8170 if (attribute_flag[1] != 0)
8171 channel=(ChannelType) argument_list[1].long_reference;
8172 if (attribute_flag[2] == 0)
8173 argument_list[2].real_reference=1.0;
8174 if (attribute_flag[3] == 0)
8175 argument_list[3].real_reference=1.0;
8176 if (attribute_flag[4] == 0)
8177 argument_list[4].real_reference=1.0;
8178 if (attribute_flag[0] == 0)
8179 {
8180 (void) FormatMagickString(message,MaxTextExtent,"%g,%g,%g",
8181 (double) argument_list[2].real_reference,
8182 (double) argument_list[3].real_reference,
8183 (double) argument_list[4].real_reference);
8184 argument_list[0].string_reference=message;
8185 }
8186 if (strchr(argument_list[0].string_reference,',') != (char *) NULL)
8187 (void) GammaImage(image,argument_list[0].string_reference);
8188 else
8189 (void) GammaImageChannel(image,channel,
8190 atof(argument_list[0].string_reference));
8191 break;
8192 }
8193 case 41: /* Map */
8194 {
8195 QuantizeInfo
8196 *quantize_info;
8197
8198 if (attribute_flag[0] == 0)
8199 {
8200 ThrowPerlException(exception,OptionError,"MapImageRequired",
8201 PackageName);
8202 goto PerlException;
8203 }
8204 quantize_info=AcquireQuantizeInfo(info->image_info);
8205 if (attribute_flag[1] != 0)
8206 quantize_info->dither=(MagickBooleanType)
8207 argument_list[1].long_reference;
8208 (void) RemapImages(quantize_info,image,
8209 argument_list[0].image_reference);
8210 quantize_info=DestroyQuantizeInfo(quantize_info);
8211 break;
8212 }
8213 case 42: /* MatteFloodfill */
8214 {
8215 DrawInfo
8216 *draw_info;
8217
8218 MagickBooleanType
8219 invert;
8220
8221 MagickPixelPacket
8222 target;
8223
8224 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8225 (DrawInfo *) NULL);
8226 if (attribute_flag[0] != 0)
8227 if (attribute_flag[0] != 0)
8228 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8229 &geometry,exception);
8230 if (attribute_flag[1] != 0)
8231 geometry.x=argument_list[1].long_reference;
8232 if (attribute_flag[2] != 0)
8233 geometry.y=argument_list[2].long_reference;
8234 if (image->matte == MagickFalse)
8235 (void) SetImageOpacity(image,OpaqueOpacity);
8236 (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target,
8237 exception);
8238 if (attribute_flag[4] != 0)
8239 QueryMagickColor(argument_list[4].string_reference,&target,
8240 exception);
8241 if (attribute_flag[3] != 0)
8242 target.opacity=StringToDouble(argument_list[3].string_reference,
8243 QuantumRange);
8244 if (attribute_flag[5] != 0)
8245 image->fuzz=StringToDouble(argument_list[5].string_reference,
8246 QuantumRange);
8247 invert=MagickFalse;
8248 if (attribute_flag[6] != 0)
8249 invert=(MagickBooleanType) argument_list[6].long_reference;
8250 (void) FloodfillPaintImage(image,OpacityChannel,draw_info,&target,
8251 geometry.x,geometry.y,invert);
8252 draw_info=DestroyDrawInfo(draw_info);
8253 break;
8254 }
8255 case 43: /* Modulate */
8256 {
8257 char
8258 modulate[MaxTextExtent];
8259
8260 ColorspaceType
8261 colorspace;
8262
8263 colorspace=image->colorspace;
8264 geometry_info.rho=100.0;
8265 geometry_info.sigma=100.0;
8266 geometry_info.xi=100.0;
8267 if (attribute_flag[0] != 0)
8268 (void)ParseGeometry(argument_list[0].string_reference,
8269 &geometry_info);
8270 if (attribute_flag[1] != 0)
8271 geometry_info.xi=argument_list[1].real_reference;
8272 if (attribute_flag[2] != 0)
8273 geometry_info.sigma=argument_list[2].real_reference;
8274 if (attribute_flag[3] != 0)
8275 {
8276 (void) SetImageColorspace(image,HWBColorspace);
8277 geometry_info.sigma=argument_list[3].real_reference;
8278 }
8279 if (attribute_flag[4] != 0)
8280 geometry_info.rho=argument_list[4].real_reference;
8281 if (attribute_flag[5] != 0)
8282 {
8283 (void) SetImageColorspace(image,HSLColorspace);
8284 geometry_info.sigma=argument_list[5].real_reference;
8285 }
8286 if (attribute_flag[6] != 0)
8287 {
8288 (void) SetImageColorspace(image,HWBColorspace);
8289 geometry_info.rho=argument_list[6].real_reference;
8290 }
8291 (void) FormatMagickString(modulate,MaxTextExtent,"%g,%g,%g",
8292 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
8293 (void) ModulateImage(image,modulate);
8294 (void) SetImageColorspace(image,colorspace);
8295 break;
8296 }
8297 case 44: /* Negate */
8298 {
8299 if (attribute_flag[0] == 0)
8300 argument_list[0].long_reference=0;
8301 if (attribute_flag[1] != 0)
8302 channel=(ChannelType) argument_list[1].long_reference;
8303 (void) NegateImageChannel(image,channel,
8304 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse);
8305 break;
8306 }
8307 case 45: /* Normalize */
8308 {
8309 if (attribute_flag[0] != 0)
8310 channel=(ChannelType) argument_list[0].long_reference;
8311 NormalizeImageChannel(image,channel);
8312 break;
8313 }
8314 case 46: /* NumberColors */
8315 break;
8316 case 47: /* Opaque */
8317 {
8318 MagickBooleanType
8319 invert;
8320
8321 MagickPixelPacket
8322 fill_color,
8323 target;
8324
8325 (void) QueryMagickColor("none",&target,exception);
8326 (void) QueryMagickColor("none",&fill_color,exception);
8327 if (attribute_flag[0] != 0)
8328 (void) QueryMagickColor(argument_list[0].string_reference,
8329 &target,exception);
8330 if (attribute_flag[1] != 0)
8331 (void) QueryMagickColor(argument_list[1].string_reference,
8332 &fill_color,exception);
8333 if (attribute_flag[2] != 0)
8334 image->fuzz=StringToDouble(argument_list[2].string_reference,
8335 QuantumRange);
8336 if (attribute_flag[3] != 0)
8337 channel=(ChannelType) argument_list[3].long_reference;
8338 invert=MagickFalse;
8339 if (attribute_flag[4] != 0)
8340 invert=(MagickBooleanType) argument_list[4].long_reference;
8341 (void) OpaquePaintImageChannel(image,channel,&target,&fill_color,
8342 invert);
8343 break;
8344 }
8345 case 48: /* Quantize */
8346 {
8347 QuantizeInfo
8348 *quantize_info;
8349
8350 quantize_info=AcquireQuantizeInfo(info->image_info);
8351 if (attribute_flag[0] != 0)
8352 quantize_info->number_colors=(unsigned long)
8353 argument_list[0].long_reference;
8354 if (attribute_flag[1] != 0)
8355 quantize_info->tree_depth=(unsigned long)
8356 argument_list[1].long_reference;
8357 if (attribute_flag[2] != 0)
8358 quantize_info->colorspace=(ColorspaceType)
8359 argument_list[2].long_reference;
8360 if (attribute_flag[3] != 0)
8361 quantize_info->dither=argument_list[3].long_reference != 0 ?
8362 MagickTrue : MagickFalse;
8363 if (attribute_flag[4] != 0)
8364 quantize_info->measure_error=
8365 argument_list[4].long_reference != 0 ? MagickTrue : MagickFalse;
8366 if (attribute_flag[5] != 0)
8367 (void) QueryColorDatabase(argument_list[5].string_reference,
8368 &image->transparent_color,exception);
8369 if (attribute_flag[5] && argument_list[5].long_reference)
8370 {
8371 (void) QuantizeImages(quantize_info,image);
8372 goto PerlException;
8373 }
8374 if (attribute_flag[6] != 0)
8375 quantize_info->dither_method=(DitherMethod)
8376 argument_list[6].long_reference;
8377 if ((image->storage_class == DirectClass) ||
8378 (image->colors > quantize_info->number_colors) ||
8379 (quantize_info->colorspace == GRAYColorspace))
8380 (void) QuantizeImage(quantize_info,image);
8381 else
8382 CompressImageColormap(image);
8383 quantize_info=DestroyQuantizeInfo(quantize_info);
8384 break;
8385 }
8386 case 49: /* Raise */
8387 {
8388 if (attribute_flag[0] != 0)
8389 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8390 &geometry,exception);
8391 if (attribute_flag[1] != 0)
8392 geometry.width=argument_list[1].long_reference;
8393 if (attribute_flag[2] != 0)
8394 geometry.height=argument_list[2].long_reference;
8395 if (attribute_flag[3] == 0)
8396 argument_list[3].long_reference=1;
8397 (void) RaiseImage(image,&geometry,argument_list[3].long_reference !=
8398 0 ? MagickTrue : MagickFalse);
8399 break;
8400 }
8401 case 50: /* Segment */
8402 {
8403 ColorspaceType
8404 colorspace;
8405
8406 double
8407 cluster_threshold,
8408 smoothing_threshold;
8409
8410 MagickBooleanType
8411 verbose;
8412
8413 cluster_threshold=1.0;
8414 smoothing_threshold=1.5;
8415 colorspace=RGBColorspace;
8416 verbose=MagickFalse;
8417 if (attribute_flag[0] != 0)
8418 {
8419 flags=ParseGeometry(argument_list[0].string_reference,
8420 &geometry_info);
8421 cluster_threshold=geometry_info.rho;
8422 if (flags & SigmaValue)
8423 smoothing_threshold=geometry_info.sigma;
8424 }
8425 if (attribute_flag[1] != 0)
8426 cluster_threshold=argument_list[1].real_reference;
8427 if (attribute_flag[2] != 0)
8428 smoothing_threshold=argument_list[2].real_reference;
8429 if (attribute_flag[3] != 0)
8430 colorspace=(ColorspaceType) argument_list[3].long_reference;
8431 if (attribute_flag[4] != 0)
8432 verbose=argument_list[4].long_reference != 0 ?
8433 MagickTrue : MagickFalse;
8434 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
8435 smoothing_threshold);
8436 break;
8437 }
8438 case 51: /* Signature */
8439 {
8440 (void) SignatureImage(image);
8441 break;
8442 }
8443 case 52: /* Solarize */
8444 {
8445 geometry_info.rho=QuantumRange/2.0;
8446 if (attribute_flag[0] != 0)
8447 flags=ParseGeometry(argument_list[0].string_reference,
8448 &geometry_info);
8449 if (attribute_flag[1] != 0)
8450 geometry_info.rho=StringToDouble(argument_list[1].string_reference,
8451 QuantumRange);
8452 (void) SolarizeImage(image,geometry_info.rho);
8453 break;
8454 }
8455 case 53: /* Sync */
8456 {
8457 (void) SyncImage(image);
8458 break;
8459 }
8460 case 54: /* Texture */
8461 {
8462 if (attribute_flag[0] == 0)
8463 break;
8464 TextureImage(image,argument_list[0].image_reference);
8465 break;
8466 }
8467 case 55: /* Evalute */
8468 {
8469 MagickEvaluateOperator
8470 op;
8471
8472 op=SetEvaluateOperator;
8473 if (attribute_flag[0] == MagickFalse)
8474 argument_list[0].real_reference=0.0;
8475 if (attribute_flag[1] != MagickFalse)
8476 op=(MagickEvaluateOperator) argument_list[1].long_reference;
8477 if (attribute_flag[2] != MagickFalse)
8478 channel=(ChannelType) argument_list[2].long_reference;
8479 (void) EvaluateImageChannel(image,channel,op,
8480 argument_list[0].real_reference,exception);
8481 break;
8482 }
8483 case 56: /* Transparent */
8484 {
8485 double
8486 opacity;
8487
8488 MagickBooleanType
8489 invert;
8490
8491 MagickPixelPacket
8492 target;
8493
8494 (void) QueryMagickColor("none",&target,exception);
8495 if (attribute_flag[0] != 0)
8496 (void) QueryMagickColor(argument_list[0].string_reference,&target,
8497 exception);
8498 opacity=TransparentOpacity;
8499 if (attribute_flag[1] != 0)
8500 opacity=StringToDouble(argument_list[1].string_reference,
8501 QuantumRange);
8502 if (attribute_flag[2] != 0)
8503 image->fuzz=StringToDouble(argument_list[2].string_reference,
8504 QuantumRange);
8505 if (attribute_flag[3] == 0)
8506 argument_list[3].long_reference=0;
8507 invert=MagickFalse;
8508 if (attribute_flag[3] != 0)
8509 invert=(MagickBooleanType) argument_list[3].long_reference;
8510 (void) TransparentPaintImage(image,&target,RoundToQuantum(opacity),
8511 invert);
8512 break;
8513 }
8514 case 57: /* Threshold */
8515 {
8516 double
8517 threshold;
8518
8519 if (attribute_flag[0] == 0)
8520 argument_list[0].string_reference="50%";
8521 if (attribute_flag[1] != 0)
8522 channel=(ChannelType) argument_list[1].long_reference;
8523 threshold=StringToDouble(argument_list[0].string_reference,
8524 QuantumRange);
8525 (void) BilevelImageChannel(image,channel,threshold);
8526 break;
8527 }
8528 case 58: /* Charcoal */
8529 {
8530 if (attribute_flag[0] != 0)
8531 {
8532 flags=ParseGeometry(argument_list[0].string_reference,
8533 &geometry_info);
8534 if ((flags & SigmaValue) == 0)
8535 geometry_info.sigma=1.0;
8536 }
8537 if (attribute_flag[1] != 0)
8538 geometry_info.rho=argument_list[1].real_reference;
8539 if (attribute_flag[2] != 0)
8540 geometry_info.sigma=argument_list[2].real_reference;
8541 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
8542 exception);
8543 break;
8544 }
8545 case 59: /* Trim */
8546 {
8547 if (attribute_flag[0] != 0)
8548 image->fuzz=StringToDouble(argument_list[0].string_reference,
8549 QuantumRange);
8550 image=TrimImage(image,exception);
8551 break;
8552 }
8553 case 60: /* Wave */
8554 {
8555 if (attribute_flag[0] != 0)
8556 {
8557 flags=ParseGeometry(argument_list[0].string_reference,
8558 &geometry_info);
8559 if ((flags & SigmaValue) == 0)
8560 geometry_info.sigma=1.0;
8561 }
8562 if (attribute_flag[1] != 0)
8563 geometry_info.rho=argument_list[1].real_reference;
8564 if (attribute_flag[2] != 0)
8565 geometry_info.sigma=argument_list[2].real_reference;
8566 if (attribute_flag[3] != 0)
8567 image->interpolate=(InterpolatePixelMethod)
8568 argument_list[3].long_reference;
8569 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
8570 exception);
8571 break;
8572 }
8573 case 61: /* Separate */
8574 {
8575 if (attribute_flag[0] != 0)
8576 channel=(ChannelType) argument_list[0].long_reference;
8577 (void) SeparateImageChannel(image,channel);
8578 break;
8579 }
8580 case 63: /* Stereo */
8581 {
8582 if (attribute_flag[0] == 0)
8583 {
8584 ThrowPerlException(exception,OptionError,"StereoImageRequired",
8585 PackageName);
8586 goto PerlException;
8587 }
8588 if (attribute_flag[1] != 0)
8589 geometry.x=argument_list[1].long_reference;
8590 if (attribute_flag[2] != 0)
8591 geometry.y=argument_list[2].long_reference;
8592 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
8593 geometry.x,geometry.y,exception);
8594 break;
8595 }
8596 case 64: /* Stegano */
8597 {
8598 if (attribute_flag[0] == 0)
8599 {
8600 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
8601 PackageName);
8602 goto PerlException;
8603 }
8604 if (attribute_flag[1] == 0)
8605 argument_list[1].long_reference=0;
8606 image->offset=argument_list[1].long_reference;
8607 image=SteganoImage(image,argument_list[0].image_reference,exception);
8608 break;
8609 }
8610 case 65: /* Deconstruct */
8611 {
8612 image=DeconstructImages(image,exception);
8613 break;
8614 }
8615 case 66: /* GaussianBlur */
8616 {
8617 if (attribute_flag[0] != 0)
8618 {
8619 flags=ParseGeometry(argument_list[0].string_reference,
8620 &geometry_info);
8621 if ((flags & SigmaValue) == 0)
8622 geometry_info.sigma=1.0;
8623 }
8624 if (attribute_flag[1] != 0)
8625 geometry_info.rho=argument_list[1].real_reference;
8626 if (attribute_flag[2] != 0)
8627 geometry_info.sigma=argument_list[2].real_reference;
8628 if (attribute_flag[3] != 0)
8629 channel=(ChannelType) argument_list[3].long_reference;
8630 image=GaussianBlurImageChannel(image,channel,geometry_info.rho,
8631 geometry_info.sigma,exception);
8632 break;
8633 }
8634 case 67: /* Convolve */
8635 {
8636 AV
8637 *av;
8638
8639 double
8640 *kernel;
8641
8642 unsigned long
8643 order;
8644
8645 if (attribute_flag[0] == 0)
8646 break;
8647 if (attribute_flag[1] != 0)
8648 channel=(ChannelType) argument_list[1].long_reference;
8649 if (attribute_flag[2] != 0)
8650 image->bias=StringToDouble(argument_list[2].string_reference,
8651 QuantumRange);
8652 av=(AV *) argument_list[0].array_reference;
8653 order=(unsigned long) sqrt(av_len(av)+1);
8654 kernel=(double *) AcquireQuantumMemory(order,order*sizeof(*kernel));
8655 if (kernel == (double *) NULL)
8656 {
8657 ThrowPerlException(exception,ResourceLimitFatalError,
8658 "MemoryAllocationFailed",PackageName);
8659 goto PerlException;
8660 }
8661 for (j=0; (j < (long) (order*order)) && (j < (av_len(av)+1)); j++)
8662 kernel[j]=(double) SvNV(*(av_fetch(av,j,0)));
8663 for ( ; j < (long) (order*order); j++)
8664 kernel[j]=0.0;
8665 image=ConvolveImageChannel(image,channel,order,kernel,exception);
8666 kernel=(double *) RelinquishMagickMemory(kernel);
8667 break;
8668 }
8669 case 68: /* Profile */
8670 {
8671 const char
8672 *name;
8673
8674 Image
8675 *profile_image;
8676
8677 ImageInfo
8678 *profile_info;
8679
8680 StringInfo
8681 *profile;
8682
8683 name="*";
8684 if (attribute_flag[0] != 0)
8685 name=argument_list[0].string_reference;
8686 if (attribute_flag[2] != 0)
8687 image->rendering_intent=(RenderingIntent)
8688 argument_list[2].long_reference;
8689 if (attribute_flag[3] != 0)
8690 image->black_point_compensation=
8691 argument_list[3].long_reference != 0 ? MagickTrue : MagickFalse;
8692 if (attribute_flag[1] != 0)
8693 {
8694 if (argument_list[1].length == 0)
8695 {
8696 /*
8697 Remove a profile from the image.
8698 */
8699 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
8700 MagickTrue);
8701 break;
8702 }
8703 /*
8704 Associate user supplied profile with the image.
8705 */
8706 profile=AcquireStringInfo(argument_list[1].length);
8707 SetStringInfoDatum(profile,(const unsigned char *)
8708 argument_list[1].string_reference);
8709 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
8710 (unsigned long) GetStringInfoLength(profile),MagickFalse);
8711 profile=DestroyStringInfo(profile);
8712 break;
8713 }
8714 /*
8715 Associate a profile with the image.
8716 */
8717 profile_info=
8718 CloneImageInfo(info ? info->image_info : (ImageInfo *) NULL);
8719 (void) CopyMagickString(profile_info->filename,name,MaxTextExtent);
8720 profile_image=ReadImages(profile_info,&image->exception);
8721 if (profile_image == (Image *) NULL)
8722 break;
8723 ResetImageProfileIterator(profile_image);
8724 name=GetNextImageProfile(profile_image);
8725 while (name != (const char *) NULL)
8726 {
8727 const StringInfo
8728 *profile;
8729
8730 profile=GetImageProfile(profile_image,name);
8731 if (profile != (const StringInfo *) NULL)
8732 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
8733 (unsigned long) GetStringInfoLength(profile),MagickFalse);
8734 name=GetNextImageProfile(profile_image);
8735 }
8736 profile_image=DestroyImage(profile_image);
8737 profile_info=DestroyImageInfo(profile_info);
8738 break;
8739 }
8740 case 69: /* UnsharpMask */
8741 {
8742 if (attribute_flag[0] != 0)
8743 {
8744 flags=ParseGeometry(argument_list[0].string_reference,
8745 &geometry_info);
8746 if ((flags & SigmaValue) == 0)
8747 geometry_info.sigma=1.0;
8748 if ((flags & XiValue) == 0)
8749 geometry_info.xi=1.0;
8750 if ((flags & PsiValue) == 0)
8751 geometry_info.psi=0.5;
8752 }
8753 if (attribute_flag[1] != 0)
8754 geometry_info.rho=argument_list[1].real_reference;
8755 if (attribute_flag[2] != 0)
8756 geometry_info.sigma=argument_list[2].real_reference;
8757 if (attribute_flag[3] != 0)
8758 geometry_info.xi=argument_list[3].real_reference;
8759 if (attribute_flag[4] != 0)
8760 geometry_info.psi=argument_list[4].real_reference;
8761 if (attribute_flag[5] != 0)
8762 channel=(ChannelType) argument_list[5].long_reference;
8763 image=UnsharpMaskImageChannel(image,channel,geometry_info.rho,
8764 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
8765 break;
8766 }
8767 case 70: /* MotionBlur */
8768 {
8769 if (attribute_flag[0] != 0)
8770 {
8771 flags=ParseGeometry(argument_list[0].string_reference,
8772 &geometry_info);
8773 if ((flags & SigmaValue) == 0)
8774 geometry_info.sigma=1.0;
8775 if ((flags & XiValue) == 0)
8776 geometry_info.xi=1.0;
8777 }
8778 if (attribute_flag[1] != 0)
8779 geometry_info.rho=argument_list[1].real_reference;
8780 if (attribute_flag[2] != 0)
8781 geometry_info.sigma=argument_list[2].real_reference;
8782 if (attribute_flag[3] != 0)
8783 geometry_info.xi=argument_list[3].real_reference;
8784 if (attribute_flag[4] != 0)
8785 channel=(ChannelType) argument_list[4].long_reference;
8786 image=MotionBlurImageChannel(image,channel,geometry_info.rho,geometry_info.sigma,
8787 geometry_info.xi,exception);
8788 break;
8789 }
8790 case 71: /* OrderedDither */
8791 {
8792 if (attribute_flag[0] == 0)
8793 argument_list[0].string_reference="o8x8";
8794 if (attribute_flag[1] != 0)
8795 channel=(ChannelType) argument_list[1].long_reference;
8796 (void) OrderedPosterizeImageChannel(image,channel,
8797 argument_list[0].string_reference,exception);
8798 break;
8799 }
8800 case 72: /* Shave */
8801 {
8802 if (attribute_flag[0] != 0)
8803 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8804 &geometry,exception);
8805 if (attribute_flag[1] != 0)
8806 geometry.width=argument_list[1].long_reference;
8807 if (attribute_flag[2] != 0)
8808 geometry.height=argument_list[2].long_reference;
8809 image=ShaveImage(image,&geometry,exception);
8810 break;
8811 }
8812 case 73: /* Level */
8813 {
8814 double
8815 black_point,
8816 gamma,
8817 white_point;
8818
8819 black_point=0.0;
8820 white_point=(MagickRealType) image->columns*image->rows;
8821 gamma=1.0;
8822 if (attribute_flag[0] != 0)
8823 {
8824 flags=ParseGeometry(argument_list[0].string_reference,
8825 &geometry_info);
8826 black_point=geometry_info.rho;
8827 if ((flags & SigmaValue) != 0)
8828 white_point=geometry_info.sigma;
8829 if ((flags & XiValue) != 0)
8830 gamma=geometry_info.xi;
8831 if ((flags & PercentValue) != 0)
8832 {
8833 black_point*=(double) (QuantumRange/100.0);
8834 white_point*=(double) (QuantumRange/100.0);
8835 }
8836 if ((flags & SigmaValue) == 0)
8837 white_point=(double) QuantumRange-black_point;
8838 }
8839 if (attribute_flag[1] != 0)
8840 black_point=argument_list[1].real_reference;
8841 if (attribute_flag[2] != 0)
8842 white_point=argument_list[2].real_reference;
8843 if (attribute_flag[3] != 0)
8844 gamma=argument_list[3].real_reference;
8845 if (attribute_flag[4] != 0)
8846 channel=(ChannelType) argument_list[4].long_reference;
8847 if (attribute_flag[5] != 0)
8848 {
8849 argument_list[0].real_reference=argument_list[5].real_reference;
8850 attribute_flag[0]=attribute_flag[5];
8851 }
8852 (void) LevelImageChannel(image,channel,black_point,white_point,gamma);
8853 break;
8854 }
8855 case 74: /* Clip */
8856 {
8857 if (attribute_flag[0] == 0)
8858 argument_list[0].string_reference="#1";
8859 if (attribute_flag[1] == 0)
8860 argument_list[1].long_reference=MagickTrue;
8861 (void) ClipImagePath(image,argument_list[0].string_reference,
8862 argument_list[1].long_reference != 0 ? MagickTrue : MagickFalse);
8863 break;
8864 }
8865 case 75: /* AffineTransform */
8866 {
8867 DrawInfo
8868 *draw_info;
8869
8870 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8871 (DrawInfo *) NULL);
8872 if (attribute_flag[0] != 0)
8873 {
8874 AV
8875 *av;
8876
8877 av=(AV *) argument_list[0].array_reference;
8878 if ((av_len(av) != 3) && (av_len(av) != 5))
8879 {
8880 ThrowPerlException(exception,OptionError,
8881 "affine matrix must have 4 or 6 elements",PackageName);
8882 goto PerlException;
8883 }
8884 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8885 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8886 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8887 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8888 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8889 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8890 {
8891 ThrowPerlException(exception,OptionError,
8892 "affine matrix is singular",PackageName);
8893 goto PerlException;
8894 }
8895 if (av_len(av) == 5)
8896 {
8897 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8898 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8899 }
8900 }
8901 for (j=1; j < 6; j++)
8902 {
8903 if (attribute_flag[j] == 0)
8904 continue;
8905 value=argument_list[j].string_reference;
8906 angle=argument_list[j].real_reference;
8907 current=draw_info->affine;
8908 GetAffineMatrix(&affine);
8909 switch (j)
8910 {
8911 case 1:
8912 {
8913 /*
8914 Translate.
8915 */
8916 flags=ParseGeometry(value,&geometry_info);
8917 affine.tx=geometry_info.xi;
8918 affine.ty=geometry_info.psi;
8919 if ((flags & PsiValue) == 0)
8920 affine.ty=affine.tx;
8921 break;
8922 }
8923 case 2:
8924 {
8925 /*
8926 Scale.
8927 */
8928 flags=ParseGeometry(value,&geometry_info);
8929 affine.sx=geometry_info.rho;
8930 affine.sy=geometry_info.sigma;
8931 if ((flags & SigmaValue) == 0)
8932 affine.sy=affine.sx;
8933 break;
8934 }
8935 case 3:
8936 {
8937 /*
8938 Rotate.
8939 */
8940 if (angle == 0.0)
8941 break;
8942 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8943 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8944 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8945 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8946 break;
8947 }
8948 case 4:
8949 {
8950 /*
8951 SkewX.
8952 */
8953 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8954 break;
8955 }
8956 case 5:
8957 {
8958 /*
8959 SkewY.
8960 */
8961 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8962 break;
8963 }
8964 }
8965 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8966 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8967 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8968 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8969 draw_info->affine.tx=
8970 current.sx*affine.tx+current.ry*affine.ty+current.tx;
8971 draw_info->affine.ty=
8972 current.rx*affine.tx+current.sy*affine.ty+current.ty;
8973 }
8974 if (attribute_flag[6] != 0)
8975 image->interpolate=(InterpolatePixelMethod)
8976 argument_list[6].long_reference;
8977 if (attribute_flag[7] != 0)
8978 QueryColorDatabase(argument_list[7].string_reference,
8979 &image->background_color,exception);
8980 image=AffineTransformImage(image,&draw_info->affine,exception);
8981 draw_info=DestroyDrawInfo(draw_info);
8982 break;
8983 }
8984 case 76: /* Difference */
8985 {
8986 if (attribute_flag[0] == 0)
8987 {
8988 ThrowPerlException(exception,OptionError,
8989 "ReferenceImageRequired",PackageName);
8990 goto PerlException;
8991 }
8992 if (attribute_flag[1] != 0)
8993 image->fuzz=StringToDouble(argument_list[1].string_reference,
8994 QuantumRange);
8995 (void) IsImagesEqual(image,argument_list[0].image_reference);
8996 break;
8997 }
8998 case 77: /* AdaptiveThreshold */
8999 {
9000 if (attribute_flag[0] != 0)
9001 {
9002 flags=ParseGeometry(argument_list[0].string_reference,
9003 &geometry_info);
9004 if ((flags & PercentValue) != 0)
9005 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9006 }
9007 if (attribute_flag[1] != 0)
9008 geometry_info.rho=argument_list[1].long_reference;
9009 if (attribute_flag[2] != 0)
9010 geometry_info.sigma=argument_list[2].long_reference;
9011 if (attribute_flag[3] != 0)
9012 geometry_info.xi=argument_list[3].long_reference;;
9013 image=AdaptiveThresholdImage(image,(unsigned long) geometry_info.rho,
9014 (unsigned long) geometry_info.sigma,(long) geometry_info.xi,
9015 exception);
9016 break;
9017 }
9018 case 78: /* Resample */
9019 {
9020 unsigned long
9021 height,
9022 width;
9023
9024 if (attribute_flag[0] != 0)
9025 {
9026 flags=ParseGeometry(argument_list[0].string_reference,
9027 &geometry_info);
9028 if ((flags & SigmaValue) == 0)
9029 geometry_info.sigma=geometry_info.rho;
9030 }
9031 if (attribute_flag[1] != 0)
9032 geometry_info.rho=argument_list[1].real_reference;
9033 if (attribute_flag[2] != 0)
9034 geometry_info.sigma=argument_list[2].real_reference;
9035 if (attribute_flag[3] == 0)
9036 argument_list[3].long_reference=(long) UndefinedFilter;
9037 if (attribute_flag[4] == 0)
9038 SetImageArtifact(image,"filter:support",
9039 argument_list[4].string_reference);
9040 if (attribute_flag[5] != 0)
9041 argument_list[5].real_reference=1.0;
9042 width=(unsigned long) (geometry_info.rho*image->columns/
9043 (image->x_resolution == 0.0 ? 72.0 : image->x_resolution)+0.5);
9044 height=(unsigned long) (geometry_info.sigma*image->rows/
9045 (image->y_resolution == 0.0 ? 72.0 : image->y_resolution)+0.5);
9046 image=ResizeImage(image,width,height,(FilterTypes)
9047 argument_list[3].long_reference,argument_list[5].real_reference,
9048 exception);
9049 if (image != (Image *) NULL)
9050 {
9051 image->x_resolution=geometry_info.rho;
9052 image->y_resolution=geometry_info.sigma;
9053 }
9054 break;
9055 }
9056 case 79: /* Describe */
9057 {
9058 if (attribute_flag[0] == 0)
9059 argument_list[0].file_reference=(FILE *) NULL;
9060 (void) IdentifyImage(image,argument_list[0].file_reference,
9061 MagickTrue);
9062 break;
9063 }
9064 case 80: /* BlackThreshold */
9065 {
9066 if (attribute_flag[0] == 0)
9067 argument_list[0].string_reference="50%";
9068 if (attribute_flag[2] != 0)
9069 channel=(ChannelType) argument_list[2].long_reference;
9070 BlackThresholdImageChannel(image,channel,
9071 argument_list[0].string_reference,exception);
9072 break;
9073 }
9074 case 81: /* WhiteThreshold */
9075 {
9076 if (attribute_flag[0] == 0)
9077 argument_list[0].string_reference="50%";
9078 if (attribute_flag[2] != 0)
9079 channel=(ChannelType) argument_list[2].long_reference;
9080 WhiteThresholdImageChannel(image,channel,
9081 argument_list[0].string_reference,exception);
9082 break;
9083 }
9084 case 82: /* RadialBlur */
9085 {
9086 if (attribute_flag[0] != 0)
9087 {
9088 flags=ParseGeometry(argument_list[0].string_reference,
9089 &geometry_info);
9090 if ((flags & SigmaValue) == 0)
9091 geometry_info.sigma=1.0;
9092 }
9093 if (attribute_flag[1] != 0)
9094 geometry_info.rho=argument_list[1].real_reference;
9095 if (attribute_flag[2] != 0)
9096 channel=(ChannelType) argument_list[2].long_reference;
9097 image=RadialBlurImageChannel(image,channel,geometry_info.rho,
9098 exception);
9099 break;
9100 }
9101 case 83: /* Thumbnail */
9102 {
9103 if (attribute_flag[0] != 0)
9104 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9105 &geometry,exception);
9106 if (attribute_flag[1] != 0)
9107 geometry.width=argument_list[1].long_reference;
9108 if (attribute_flag[2] != 0)
9109 geometry.height=argument_list[2].long_reference;
9110 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
9111 break;
9112 }
9113 case 84: /* Strip */
9114 {
9115 (void) StripImage(image);
9116 break;
9117 }
9118 case 85: /* Tint */
9119 {
9120 PixelPacket
9121 target;
9122
9123 (void) GetOneVirtualPixel(image,0,0,&target,exception);
9124 if (attribute_flag[0] != 0)
9125 (void) QueryColorDatabase(argument_list[0].string_reference,&target,
9126 exception);
9127 if (attribute_flag[1] == 0)
9128 argument_list[1].string_reference="100";
9129 image=TintImage(image,argument_list[1].string_reference,target,
9130 exception);
9131 break;
9132 }
9133 case 86: /* Channel */
9134 {
9135 if (attribute_flag[0] != 0)
9136 channel=(ChannelType) argument_list[0].long_reference;
9137 (void) SeparateImageChannel(image,channel);
9138 break;
9139 }
9140 case 87: /* Splice */
9141 {
9142 if (attribute_flag[0] != 0)
9143 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
9144 &geometry,exception);
9145 if (attribute_flag[1] != 0)
9146 geometry.width=argument_list[1].long_reference;
9147 if (attribute_flag[2] != 0)
9148 geometry.height=argument_list[2].long_reference;
9149 if (attribute_flag[3] != 0)
9150 geometry.x=argument_list[3].long_reference;
9151 if (attribute_flag[4] != 0)
9152 geometry.y=argument_list[4].long_reference;
9153 if (attribute_flag[5] != 0)
9154 image->fuzz=StringToDouble(argument_list[5].string_reference,
9155 QuantumRange);
9156 if (attribute_flag[6] != 0)
9157 (void) QueryColorDatabase(argument_list[6].string_reference,
9158 &image->background_color,exception);
9159 if (attribute_flag[7] != 0)
9160 image->gravity=(GravityType) argument_list[7].long_reference;
9161 image=SpliceImage(image,&geometry,exception);
9162 break;
9163 }
9164 case 88: /* Posterize */
9165 {
9166 if (attribute_flag[0] == 0)
9167 argument_list[0].long_reference=3;
9168 if (attribute_flag[1] == 0)
9169 argument_list[1].long_reference=0;
9170 (void) PosterizeImage(image,argument_list[0].long_reference,
9171 argument_list[1].long_reference ? MagickTrue : MagickFalse);
9172 break;
9173 }
9174 case 89: /* Shadow */
9175 {
9176 if (attribute_flag[0] != 0)
9177 {
9178 flags=ParseGeometry(argument_list[0].string_reference,
9179 &geometry_info);
9180 if ((flags & SigmaValue) == 0)
9181 geometry_info.sigma=1.0;
9182 if ((flags & XiValue) == 0)
9183 geometry_info.xi=4.0;
9184 if ((flags & PsiValue) == 0)
9185 geometry_info.psi=4.0;
9186 }
9187 if (attribute_flag[1] != 0)
9188 geometry_info.rho=argument_list[1].real_reference;
9189 if (attribute_flag[2] != 0)
9190 geometry_info.sigma=argument_list[2].real_reference;
9191 if (attribute_flag[3] != 0)
9192 geometry_info.xi=argument_list[3].long_reference;
9193 if (attribute_flag[4] != 0)
9194 geometry_info.psi=argument_list[4].long_reference;
9195 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
9196 (long) (geometry_info.xi+0.5),(long) (geometry_info.psi+0.5),
9197 exception);
9198 break;
9199 }
9200 case 90: /* Identify */
9201 {
9202 if (attribute_flag[0] == 0)
9203 argument_list[0].file_reference=(FILE *) NULL;
9204 (void) IdentifyImage(image,argument_list[0].file_reference,
9205 MagickTrue);
9206 break;
9207 }
9208 case 91: /* SepiaTone */
9209 {
9210 if (attribute_flag[0] == 0)
9211 argument_list[0].real_reference=80.0*QuantumRange/100.0;
9212 image=SepiaToneImage(image,argument_list[0].real_reference,
9213 exception);
9214 break;
9215 }
9216 case 92: /* SigmoidalContrast */
9217 {
9218 MagickBooleanType
9219 sharpen;
9220
9221 if (attribute_flag[0] != 0)
9222 {
9223 flags=ParseGeometry(argument_list[0].string_reference,
9224 &geometry_info);
9225 if ((flags & SigmaValue) == 0)
9226 geometry_info.sigma=QuantumRange/2.0;
9227 if ((flags & PercentValue) != 0)
9228 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
9229 }
9230 if (attribute_flag[1] != 0)
9231 geometry_info.rho=argument_list[1].real_reference;
9232 if (attribute_flag[2] != 0)
9233 geometry_info.sigma=argument_list[2].real_reference;
9234 if (attribute_flag[3] != 0)
9235 channel=(ChannelType) argument_list[3].long_reference;
9236 sharpen=MagickTrue;
9237 if (attribute_flag[4] != 0)
9238 sharpen=argument_list[4].long_reference != 0 ? MagickTrue :
9239 MagickFalse;
9240 (void) SigmoidalContrastImageChannel(image,channel,sharpen,
9241 geometry_info.rho,geometry_info.sigma);
9242 break;
9243 }
9244 case 93: /* Extent */
9245 {
9246 GravityType
9247 gravity;
9248
9249 gravity=image->gravity;
9250 if (attribute_flag[7] != 0)
9251 gravity=(GravityType) argument_list[7].long_reference;
9252 if (attribute_flag[0] != 0)
9253 {
9254 SetGeometry(image,&geometry);
9255 (void) ParseAbsoluteGeometry(argument_list[0].string_reference,
9256 &geometry);
9257 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
9258 &geometry);
9259 }
9260 if (attribute_flag[1] != 0)
9261 geometry.width=argument_list[1].long_reference;
9262 if (attribute_flag[2] != 0)
9263 geometry.height=argument_list[2].long_reference;
9264 if (attribute_flag[3] != 0)
9265 geometry.x=argument_list[3].long_reference;
9266 if (attribute_flag[4] != 0)
9267 geometry.y=argument_list[4].long_reference;
9268 if (attribute_flag[5] != 0)
9269 image->fuzz=StringToDouble(argument_list[5].string_reference,
9270 QuantumRange);
9271 if (attribute_flag[6] != 0)
9272 (void) QueryColorDatabase(argument_list[6].string_reference,
9273 &image->background_color,exception);
9274 GravityAdjustGeometry(image->columns,image->rows,gravity,&geometry);
9275 image=ExtentImage(image,&geometry,exception);
9276 break;
9277 }
9278 case 94: /* Vignette */
9279 {
9280 if (attribute_flag[0] != 0)
9281 {
9282 flags=ParseGeometry(argument_list[0].string_reference,
9283 &geometry_info);
9284 if ((flags & SigmaValue) == 0)
9285 geometry_info.sigma=1.0;
9286 if ((flags & XiValue) == 0)
9287 geometry_info.xi=0.1*image->columns;
9288 if ((flags & PsiValue) == 0)
9289 geometry_info.psi=0.1*image->rows;
9290 }
9291 if (attribute_flag[1] != 0)
9292 geometry_info.rho=argument_list[1].real_reference;
9293 if (attribute_flag[2] != 0)
9294 geometry_info.sigma=argument_list[2].real_reference;
9295 if (attribute_flag[3] != 0)
9296 geometry_info.xi=argument_list[3].long_reference;
9297 if (attribute_flag[4] != 0)
9298 geometry_info.psi=argument_list[4].long_reference;
9299 if (attribute_flag[5] != 0)
9300 (void) QueryColorDatabase(argument_list[5].string_reference,
9301 &image->background_color,exception);
9302 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
9303 (long) (geometry_info.xi+0.5),(long) (geometry_info.psi+0.5),
9304 exception);
9305 break;
9306 }
9307 case 95: /* ContrastStretch */
9308 {
9309 double
9310 black_point,
9311 white_point;
9312
9313 black_point=0.0;
9314 white_point=(MagickRealType) image->columns*image->rows;
9315 if (attribute_flag[0] != 0)
9316 {
9317 flags=ParseGeometry(argument_list[0].string_reference,
9318 &geometry_info);
9319 black_point=geometry_info.rho;
9320 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
9321 black_point;
9322 if ((flags & PercentValue) != 0)
9323 {
9324 black_point*=(double) image->columns*image->rows/100.0;
9325 white_point*=(double) image->columns*image->rows/100.0;
9326 }
9327 white_point=(MagickRealType) image->columns*image->rows-
9328 white_point;
9329 }
9330 if (attribute_flag[1] != 0)
9331 black_point=argument_list[1].real_reference;
9332 if (attribute_flag[2] != 0)
9333 white_point=argument_list[2].real_reference;
9334 if (attribute_flag[4] != 0)
9335 channel=(ChannelType) argument_list[4].long_reference;
9336 (void) ContrastStretchImageChannel(image,channel,black_point,
9337 white_point);
9338 break;
9339 }
9340 case 96: /* Sans0 */
9341 {
9342 break;
9343 }
9344 case 97: /* Sans1 */
9345 {
9346 break;
9347 }
9348 case 98: /* AdaptiveSharpen */
9349 {
9350 if (attribute_flag[0] != 0)
9351 {
9352 flags=ParseGeometry(argument_list[0].string_reference,
9353 &geometry_info);
9354 if ((flags & SigmaValue) == 0)
9355 geometry_info.sigma=1.0;
9356 }
9357 if (attribute_flag[1] != 0)
9358 geometry_info.rho=argument_list[1].real_reference;
9359 if (attribute_flag[2] != 0)
9360 geometry_info.sigma=argument_list[2].real_reference;
9361 if (attribute_flag[3] != 0)
9362 channel=(ChannelType) argument_list[3].long_reference;
9363 image=AdaptiveSharpenImageChannel(image,channel,geometry_info.rho,
9364 geometry_info.sigma,exception);
9365 break;
9366 }
9367 case 99: /* Transpose */
9368 {
9369 image=TransposeImage(image,exception);
9370 break;
9371 }
9372 case 100: /* Tranverse */
9373 {
9374 image=TransverseImage(image,exception);
9375 break;
9376 }
9377 case 101: /* AutoOrient */
9378 {
9379 switch (image->orientation)
9380 {
9381 case TopRightOrientation:
9382 {
9383 image=FlopImage(image,exception);
9384 break;
9385 }
9386 case BottomRightOrientation:
9387 {
9388 image=RotateImage(image,180.0,exception);
9389 break;
9390 }
9391 case BottomLeftOrientation:
9392 {
9393 image=FlipImage(image,exception);
9394 break;
9395 }
9396 case LeftTopOrientation:
9397 {
9398 image=TransposeImage(image,exception);
9399 break;
9400 }
9401 case RightTopOrientation:
9402 {
9403 image=RotateImage(image,90.0,exception);
9404 break;
9405 }
9406 case RightBottomOrientation:
9407 {
9408 image=TransverseImage(image,exception);
9409 break;
9410 }
9411 case LeftBottomOrientation:
9412 {
9413 image=RotateImage(image,270.0,exception);
9414 break;
9415 }
9416 default:
9417 break;
9418 }
9419 break;
9420 }
9421 case 102: /* AdaptiveBlur */
9422 {
9423 if (attribute_flag[0] != 0)
9424 {
9425 flags=ParseGeometry(argument_list[0].string_reference,
9426 &geometry_info);
9427 if ((flags & SigmaValue) == 0)
9428 geometry_info.sigma=1.0;
9429 }
9430 if (attribute_flag[1] != 0)
9431 geometry_info.rho=argument_list[1].real_reference;
9432 if (attribute_flag[2] != 0)
9433 geometry_info.sigma=argument_list[2].real_reference;
9434 if (attribute_flag[3] != 0)
9435 channel=(ChannelType) argument_list[3].long_reference;
9436 image=AdaptiveBlurImageChannel(image,channel,geometry_info.rho,
9437 geometry_info.sigma,exception);
9438 break;
9439 }
9440 case 103: /* Sketch */
9441 {
9442 if (attribute_flag[0] != 0)
9443 {
9444 flags=ParseGeometry(argument_list[0].string_reference,
9445 &geometry_info);
9446 if ((flags & SigmaValue) == 0)
9447 geometry_info.sigma=1.0;
9448 if ((flags & XiValue) == 0)
9449 geometry_info.xi=1.0;
9450 }
9451 if (attribute_flag[1] != 0)
9452 geometry_info.rho=argument_list[1].real_reference;
9453 if (attribute_flag[2] != 0)
9454 geometry_info.sigma=argument_list[2].real_reference;
9455 if (attribute_flag[3] != 0)
9456 geometry_info.xi=argument_list[3].real_reference;
9457 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
9458 geometry_info.xi,exception);
9459 break;
9460 }
9461 case 104: /* UniqueColors */
9462 {
9463 image=UniqueImageColors(image,exception);
9464 break;
9465 }
9466 case 105: /* AdaptiveResize */
9467 {
9468 if (attribute_flag[0] != 0)
9469 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9470 &geometry,exception);
9471 if (attribute_flag[1] != 0)
9472 geometry.width=argument_list[1].long_reference;
9473 if (attribute_flag[2] != 0)
9474 geometry.height=argument_list[2].long_reference;
9475 if (attribute_flag[3] != 0)
9476 image->filter=(FilterTypes) argument_list[4].long_reference;
9477 if (attribute_flag[4] != 0)
9478 SetImageArtifact(image,"filter:support",
9479 argument_list[4].string_reference);
9480 if (attribute_flag[5] != 0)
9481 image->blur=argument_list[5].real_reference;
9482 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
9483 exception);
9484 break;
9485 }
9486 case 106: /* ClipMask */
9487 {
9488 if (attribute_flag[0] == 0)
9489 {
9490 ThrowPerlException(exception,OptionError,"MaskImageRequired",
9491 PackageName);
9492 goto PerlException;
9493 }
9494 image->clip_mask=CloneImage(argument_list[0].image_reference,0,0,
9495 MagickTrue,exception);
9496 (void) NegateImage(image->clip_mask,MagickFalse);
9497 break;
9498 }
9499 case 107: /* LinearStretch */
9500 {
9501 double
9502 black_point,
9503 white_point;
9504
9505 black_point=0.0;
9506 white_point=(MagickRealType) image->columns*image->rows;
9507 if (attribute_flag[0] != 0)
9508 {
9509 flags=ParseGeometry(argument_list[0].string_reference,
9510 &geometry_info);
9511 if ((flags & SigmaValue) != 0)
9512 white_point=geometry_info.sigma;
9513 if ((flags & PercentValue) != 0)
9514 {
9515 black_point*=(double) image->columns*image->rows/100.0;
9516 white_point*=(double) image->columns*image->rows/100.0;
9517 }
9518 if ((flags & SigmaValue) == 0)
9519 white_point=(double) image->columns*image->rows-black_point;
9520 }
9521 if (attribute_flag[1] != 0)
9522 black_point=argument_list[1].real_reference;
9523 if (attribute_flag[2] != 0)
9524 white_point=argument_list[2].real_reference;
9525 (void) LinearStretchImage(image,black_point,white_point);
9526 break;
9527 }
9528 case 108: /* Recolor */
9529 {
9530 AV
9531 *av;
9532
9533 double
9534 *color_matrix;
9535
9536 unsigned long
9537 order;
9538
9539 if (attribute_flag[0] == 0)
9540 break;
9541 av=(AV *) argument_list[0].array_reference;
9542 order=(unsigned long) sqrt(av_len(av)+1);
9543 color_matrix=(double *) AcquireQuantumMemory(order,order*
9544 sizeof(*color_matrix));
9545 if (color_matrix == (double *) NULL)
9546 {
9547 ThrowPerlException(exception,ResourceLimitFatalError,
9548 "MemoryAllocationFailed",PackageName);
9549 goto PerlException;
9550 }
9551 for (j=0; (j < (long) (order*order)) && (j < (av_len(av)+1)); j++)
9552 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
9553 for ( ; j < (long) (order*order); j++)
9554 color_matrix[j]=0.0;
9555 image=RecolorImage(image,order,color_matrix,exception);
9556 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
9557 break;
9558 }
9559 case 109: /* Mask */
9560 {
9561 if (attribute_flag[0] == 0)
9562 {
9563 ThrowPerlException(exception,OptionError,"MaskImageRequired",
9564 PackageName);
9565 goto PerlException;
9566 }
9567 image->mask=CloneImage(argument_list[0].image_reference,0,0,
9568 MagickTrue,exception);
9569 (void) NegateImage(image->mask,MagickFalse);
9570 break;
9571 }
9572 case 110: /* Polaroid */
9573 {
9574 DrawInfo
9575 *draw_info;
9576
9577 double
9578 angle;
9579
9580 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9581 (DrawInfo *) NULL);
9582 if (attribute_flag[0] != 0)
9583 (void) SetImageProperty(image,"caption",InterpretImageProperties(
9584 info ? info->image_info : (ImageInfo *) NULL,image,
9585 argument_list[0].string_reference));
9586 angle=0.0;
9587 if (attribute_flag[1] != 0)
9588 angle=argument_list[1].real_reference;
9589 if (attribute_flag[2] != 0)
9590 (void) CloneString(&draw_info->font,
9591 argument_list[2].string_reference);
9592 if (attribute_flag[3] != 0)
9593 (void) QueryColorDatabase(argument_list[3].string_reference,
9594 &draw_info->stroke,exception);
9595 if (attribute_flag[4] != 0)
9596 (void) QueryColorDatabase(argument_list[4].string_reference,
9597 &draw_info->fill,exception);
9598 if (attribute_flag[5] != 0)
9599 draw_info->stroke_width=argument_list[5].real_reference;
9600 if (attribute_flag[6] != 0)
9601 draw_info->pointsize=argument_list[6].real_reference;
9602 if (attribute_flag[7] != 0)
9603 draw_info->gravity=(GravityType) argument_list[7].long_reference;
9604 if (attribute_flag[8] != 0)
9605 (void) QueryColorDatabase(argument_list[8].string_reference,
9606 &image->background_color,exception);
9607 image=PolaroidImage(image,draw_info,angle,exception);
9608 draw_info=DestroyDrawInfo(draw_info);
9609 break;
9610 }
9611 case 111: /* FloodfillPaint */
9612 {
9613 DrawInfo
9614 *draw_info;
9615
9616 MagickBooleanType
9617 invert;
9618
9619 MagickPixelPacket
9620 target;
9621
9622 draw_info=CloneDrawInfo(info ? info->image_info :
9623 (ImageInfo *) NULL,(DrawInfo *) NULL);
9624 if (attribute_flag[0] != 0)
9625 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9626 &geometry,exception);
9627 if (attribute_flag[1] != 0)
9628 geometry.x=argument_list[1].long_reference;
9629 if (attribute_flag[2] != 0)
9630 geometry.y=argument_list[2].long_reference;
9631 if (attribute_flag[3] != 0)
9632 (void) QueryColorDatabase(argument_list[3].string_reference,
9633 &draw_info->fill,exception);
9634 (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target,
9635 exception);
9636 if (attribute_flag[4] != 0)
9637 QueryMagickColor(argument_list[4].string_reference,&target,
9638 exception);
9639 if (attribute_flag[5] != 0)
9640 image->fuzz=StringToDouble(argument_list[5].string_reference,
9641 QuantumRange);
9642 if (attribute_flag[6] != 0)
9643 channel=(ChannelType) argument_list[6].long_reference;
9644 invert=MagickFalse;
9645 if (attribute_flag[7] != 0)
9646 invert=(MagickBooleanType) argument_list[7].long_reference;
9647 (void) FloodfillPaintImage(image,channel,draw_info,&target,geometry.x,
9648 geometry.y,invert);
9649 draw_info=DestroyDrawInfo(draw_info);
9650 break;
9651 }
9652 case 112: /* Distort */
9653 {
9654 AV
9655 *av;
9656
9657 double
9658 *coordinates;
9659
9660 DistortImageMethod
9661 method;
9662
9663 unsigned long
9664 number_coordinates;
9665
9666 VirtualPixelMethod
9667 virtual_pixel;
9668
9669 if (attribute_flag[0] == 0)
9670 break;
9671 method=UndefinedDistortion;
9672 if (attribute_flag[1] != 0)
9673 method=(DistortImageMethod) argument_list[1].long_reference;
9674 av=(AV *) argument_list[0].array_reference;
9675 number_coordinates=(unsigned long) av_len(av)+1;
9676 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
9677 sizeof(*coordinates));
9678 if (coordinates == (double *) NULL)
9679 {
9680 ThrowPerlException(exception,ResourceLimitFatalError,
9681 "MemoryAllocationFailed",PackageName);
9682 goto PerlException;
9683 }
9684 for (j=0; j < (long) number_coordinates; j++)
9685 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
9686 virtual_pixel=UndefinedVirtualPixelMethod;
9687 if (attribute_flag[2] != 0)
9688 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
9689 argument_list[2].long_reference);
9690 image=DistortImage(image,method,number_coordinates,coordinates,
9691 argument_list[3].long_reference != 0 ? MagickTrue : MagickFalse,
9692 exception);
9693 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
9694 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel);
9695 coordinates=(double *) RelinquishMagickMemory(coordinates);
9696 break;
9697 }
9698 case 113: /* Clut */
9699 {
9700 if (attribute_flag[0] == 0)
9701 {
9702 ThrowPerlException(exception,OptionError,"ClutImageRequired",
9703 PackageName);
9704 goto PerlException;
9705 }
9706 if (attribute_flag[1] != 0)
9707 channel=(ChannelType) argument_list[1].long_reference;
9708 (void) ClutImageChannel(image,channel,
9709 argument_list[0].image_reference);
9710 break;
9711 }
9712 case 114: /* LiquidRescale */
9713 {
9714 if (attribute_flag[0] != 0)
9715 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9716 &geometry,exception);
9717 if (attribute_flag[1] != 0)
9718 geometry.width=argument_list[1].long_reference;
9719 if (attribute_flag[2] != 0)
9720 geometry.height=argument_list[2].long_reference;
9721 if (attribute_flag[3] == 0)
9722 argument_list[3].real_reference=1.0;
9723 if (attribute_flag[4] == 0)
9724 argument_list[4].real_reference=0.0;
9725 image=LiquidRescaleImage(image,geometry.width,geometry.height,
9726 argument_list[3].real_reference,argument_list[4].real_reference,
9727 exception);
9728 break;
9729 }
9730 case 115: /* EncipherImage */
9731 {
9732 (void) EncipherImage(image,argument_list[0].string_reference,
9733 exception);
9734 break;
9735 }
9736 case 116: /* DecipherImage */
9737 {
9738 (void) DecipherImage(image,argument_list[0].string_reference,
9739 exception);
9740 break;
9741 }
9742 case 117: /* Deskew */
9743 {
9744 geometry_info.rho=QuantumRange/2.0;
9745 if (attribute_flag[0] != 0)
9746 flags=ParseGeometry(argument_list[0].string_reference,
9747 &geometry_info);
9748 if (attribute_flag[1] != 0)
9749 geometry_info.rho=StringToDouble(argument_list[1].string_reference,
9750 QuantumRange);
9751 image=DeskewImage(image,geometry_info.rho,exception);
9752 break;
9753 }
9754 case 118: /* Remap */
9755 {
9756 QuantizeInfo
9757 *quantize_info;
9758
9759 if (attribute_flag[0] == 0)
9760 {
9761 ThrowPerlException(exception,OptionError,"RemapImageRequired",
9762 PackageName);
9763 goto PerlException;
9764 }
9765 quantize_info=AcquireQuantizeInfo(info->image_info);
9766 if (attribute_flag[1] == 0)
9767 quantize_info->dither_method=(DitherMethod)
9768 argument_list[1].long_reference;
9769 (void) RemapImages(quantize_info,image,
9770 argument_list[0].image_reference);
9771 quantize_info=DestroyQuantizeInfo(quantize_info);
9772 break;
9773 }
9774 case 119: /* SparseColor */
9775 {
9776 AV
9777 *av;
9778
9779 double
9780 *coordinates;
9781
9782 SparseColorMethod
9783 method;
9784
9785 unsigned long
9786 number_coordinates;
9787
9788 VirtualPixelMethod
9789 virtual_pixel;
9790
9791 if (attribute_flag[0] == 0)
9792 break;
9793 method=UndefinedColorInterpolate;
9794 if (attribute_flag[1] != 0)
9795 method=(SparseColorMethod) argument_list[1].long_reference;
9796 av=(AV *) argument_list[0].array_reference;
9797 number_coordinates=(unsigned long) av_len(av)+1;
9798 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
9799 sizeof(*coordinates));
9800 if (coordinates == (double *) NULL)
9801 {
9802 ThrowPerlException(exception,ResourceLimitFatalError,
9803 "MemoryAllocationFailed",PackageName);
9804 goto PerlException;
9805 }
9806 for (j=0; j < (long) number_coordinates; j++)
9807 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
9808 virtual_pixel=UndefinedVirtualPixelMethod;
9809 if (attribute_flag[2] != 0)
9810 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
9811 argument_list[2].long_reference);
9812 if (attribute_flag[3] != 0)
9813 channel=(ChannelType) argument_list[3].long_reference;
9814 image=SparseColorImage(image,channel,method,number_coordinates,
9815 coordinates,exception);
9816 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
9817 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel);
9818 coordinates=(double *) RelinquishMagickMemory(coordinates);
9819 break;
9820 }
9821 case 120: /* Function */
9822 {
9823 AV
9824 *av;
9825
9826 double
9827 *parameters;
9828
9829 MagickFunction
9830 function;
9831
9832 unsigned long
9833 number_parameters;
9834
9835 VirtualPixelMethod
9836 virtual_pixel;
9837
9838 if (attribute_flag[0] == 0)
9839 break;
9840 function=UndefinedFunction;
9841 if (attribute_flag[1] != 0)
9842 function=(MagickFunction) argument_list[1].long_reference;
9843 av=(AV *) argument_list[0].array_reference;
9844 number_parameters=(unsigned long) av_len(av)+1;
9845 parameters=(double *) AcquireQuantumMemory(number_parameters,
9846 sizeof(*parameters));
9847 if (parameters == (double *) NULL)
9848 {
9849 ThrowPerlException(exception,ResourceLimitFatalError,
9850 "MemoryAllocationFailed",PackageName);
9851 goto PerlException;
9852 }
9853 for (j=0; j < (long) number_parameters; j++)
9854 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
9855 virtual_pixel=UndefinedVirtualPixelMethod;
9856 if (attribute_flag[2] != 0)
9857 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
9858 argument_list[2].long_reference);
9859 (void) FunctionImage(image,function,number_parameters,parameters,
9860 exception);
9861 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
9862 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel);
9863 parameters=(double *) RelinquishMagickMemory(parameters);
9864 break;
9865 }
9866 case 121: /* SelectiveBlur */
9867 {
9868 if (attribute_flag[0] != 0)
9869 {
9870 flags=ParseGeometry(argument_list[0].string_reference,
9871 &geometry_info);
9872 if ((flags & SigmaValue) == 0)
9873 geometry_info.sigma=1.0;
9874 if ((flags & PercentValue) != 0)
9875 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9876 }
9877 if (attribute_flag[1] != 0)
9878 geometry_info.rho=argument_list[1].real_reference;
9879 if (attribute_flag[2] != 0)
9880 geometry_info.sigma=argument_list[2].real_reference;
9881 if (attribute_flag[3] != 0)
9882 geometry_info.xi=argument_list[3].long_reference;;
9883 if (attribute_flag[4] != 0)
9884 channel=(ChannelType) argument_list[4].long_reference;
9885 image=SelectiveBlurImageChannel(image,channel,geometry_info.rho,
9886 geometry_info.sigma,geometry_info.xi,exception);
9887 break;
9888 }
9889 case 122: /* HaldClut */
9890 {
9891 if (attribute_flag[0] == 0)
9892 {
9893 ThrowPerlException(exception,OptionError,"ClutImageRequired",
9894 PackageName);
9895 goto PerlException;
9896 }
9897 if (attribute_flag[1] != 0)
9898 channel=(ChannelType) argument_list[1].long_reference;
9899 (void) HaldClutImageChannel(image,channel,
9900 argument_list[0].image_reference);
9901 break;
9902 }
9903 case 123: /* BlueShift */
9904 {
9905 if (attribute_flag[0] != 0)
9906 (void) ParseGeometry(argument_list[0].string_reference,
9907 &geometry_info);
9908 image=BlueShiftImage(image,geometry_info.rho,exception);
9909 break;
9910 }
9911 case 124: /* ForwardFourierTransformImage */
9912 {
9913 image=ForwardFourierTransformImage(image,
9914 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse,
9915 exception);
9916 break;
9917 }
9918 case 125: /* InverseFourierTransformImage */
9919 {
9920 image=InverseFourierTransformImage(image,
9921 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse,
9922 exception);
9923 break;
9924 }
9925 case 126: /* ColorDecisionList */
9926 {
9927 if (attribute_flag[0] == 0)
9928 argument_list[0].string_reference=(char *) NULL;
9929 (void) ColorDecisionListImage(image,
9930 argument_list[0].string_reference);
9931 break;
9932 }
9933 case 127: /* AutoGamma */
9934 {
9935 if (attribute_flag[0] != 0)
9936 channel=(ChannelType) argument_list[0].long_reference;
9937 (void) AutoGammaImageChannel(image,channel);
9938 break;
9939 }
9940 case 128: /* AutoLevel */
9941 {
9942 if (attribute_flag[0] != 0)
9943 channel=(ChannelType) argument_list[0].long_reference;
9944 (void) AutoLevelImageChannel(image,channel);
9945 break;
9946 }
cristyee0f8d72009-09-19 00:58:29 +00009947 case 129: /* LevelColors */
9948 {
9949 MagickPixelPacket
9950 black_point,
9951 white_point;
9952
9953 (void) QueryMagickColor("#000000",&black_point,exception);
9954 (void) QueryMagickColor("#ffffff",&black_point,exception);
9955 if (attribute_flag[1] != 0)
9956 (void) QueryMagickColor(argument_list[1].string_reference,
9957 &black_point,exception);
9958 if (attribute_flag[2] != 0)
9959 (void) QueryMagickColor(argument_list[2].string_reference,
9960 &white_point,exception);
9961 if (attribute_flag[3] != 0)
9962 channel=(ChannelType) argument_list[3].long_reference;
cristy308b4e62009-09-21 14:40:44 +00009963 (void) LevelColorsImageChannel(image,channel,&black_point,&white_point,
cristyee0f8d72009-09-19 00:58:29 +00009964 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse);
9965 break;
9966 }
cristy3ed852e2009-09-05 21:47:34 +00009967 }
9968 if (next != (Image *) NULL)
9969 (void) CatchImageException(next);
9970 if (region_image != (Image *) NULL)
9971 {
9972 /*
9973 Composite region.
9974 */
9975 status=CompositeImage(region_image,CopyCompositeOp,image,
9976 region_info.x,region_info.y);
9977 (void) CatchImageException(region_image);
9978 image=DestroyImage(image);
9979 image=region_image;
9980 }
9981 if (image != (Image *) NULL)
9982 {
9983 number_images++;
9984 if (next && (next != image))
9985 {
9986 image->next=next->next;
9987 DeleteImageFromRegistry(*pv,next);
9988 }
9989 sv_setiv(*pv,(IV) image);
9990 next=image;
9991 }
9992 if (*pv)
9993 pv++;
9994 }
9995
9996 PerlException:
9997 if (reference_vector)
9998 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
9999 InheritPerlException(exception,perl_exception);
10000 exception=DestroyExceptionInfo(exception);
10001 sv_setiv(perl_exception,(IV) number_images);
10002 SvPOK_on(perl_exception);
10003 ST(0)=sv_2mortal(perl_exception);
10004 XSRETURN(1);
10005 }
10006
10007#
10008###############################################################################
10009# #
10010# #
10011# #
10012# M o n t a g e #
10013# #
10014# #
10015# #
10016###############################################################################
10017#
10018#
10019void
10020Montage(ref,...)
10021 Image::Magick ref=NO_INIT
10022 ALIAS:
10023 MontageImage = 1
10024 montage = 2
10025 montageimage = 3
10026 PPCODE:
10027 {
10028 AV
10029 *av;
10030
10031 char
10032 *attribute;
10033
10034 ExceptionInfo
10035 *exception;
10036
10037 HV
10038 *hv;
10039
10040 Image
10041 *image,
10042 *next;
10043
10044 long
10045 sp;
10046
10047 MagickPixelPacket
10048 transparent_color;
10049
10050 MontageInfo
10051 *montage_info;
10052
10053 register long
10054 i;
10055
10056 struct PackageInfo
10057 *info;
10058
10059 SV
10060 *av_reference,
10061 *perl_exception,
10062 *reference,
10063 *rv,
10064 *sv;
10065
10066 exception=AcquireExceptionInfo();
10067 perl_exception=newSVpv("",0);
10068 attribute=NULL;
10069 if (sv_isobject(ST(0)) == 0)
10070 {
10071 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10072 PackageName);
10073 goto PerlException;
10074 }
10075 reference=SvRV(ST(0));
10076 hv=SvSTASH(reference);
10077 av=newAV();
10078 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10079 SvREFCNT_dec(av);
10080 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10081 if (image == (Image *) NULL)
10082 {
10083 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10084 PackageName);
10085 goto PerlException;
10086 }
10087 /*
10088 Get options.
10089 */
10090 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10091 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
10092 (void) QueryMagickColor("none",&transparent_color,exception);
10093 for (i=2; i < items; i+=2)
10094 {
10095 attribute=(char *) SvPV(ST(i-1),na);
10096 switch (*attribute)
10097 {
10098 case 'B':
10099 case 'b':
10100 {
10101 if (LocaleCompare(attribute,"background") == 0)
10102 {
10103 (void) QueryColorDatabase(SvPV(ST(i),na),
10104 &montage_info->background_color,exception);
10105 for (next=image; next; next=next->next)
10106 next->background_color=montage_info->background_color;
10107 break;
10108 }
10109 if (LocaleCompare(attribute,"border") == 0)
10110 {
10111 montage_info->border_width=SvIV(ST(i));
10112 break;
10113 }
10114 if (LocaleCompare(attribute,"bordercolor") == 0)
10115 {
10116 (void) QueryColorDatabase(SvPV(ST(i),na),
10117 &montage_info->border_color,exception);
10118 for (next=image; next; next=next->next)
10119 next->border_color=montage_info->border_color;
10120 break;
10121 }
10122 if (LocaleCompare(attribute,"borderwidth") == 0)
10123 {
10124 montage_info->border_width=SvIV(ST(i));
10125 break;
10126 }
10127 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10128 attribute);
10129 break;
10130 }
10131 case 'C':
10132 case 'c':
10133 {
10134 if (LocaleCompare(attribute,"compose") == 0)
10135 {
10136 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
10137 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
10138 if (sp < 0)
10139 {
10140 ThrowPerlException(exception,OptionError,"UnrecognizedType",
10141 SvPV(ST(i),na));
10142 break;
10143 }
10144 for (next=image; next; next=next->next)
10145 next->compose=(CompositeOperator) sp;
10146 break;
10147 }
10148 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10149 attribute);
10150 break;
10151 }
10152 case 'F':
10153 case 'f':
10154 {
10155 if (LocaleCompare(attribute,"fill") == 0)
10156 {
10157 (void) QueryColorDatabase(SvPV(ST(i),na),&montage_info->fill,
10158 exception);
10159 break;
10160 }
10161 if (LocaleCompare(attribute,"font") == 0)
10162 {
10163 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
10164 break;
10165 }
10166 if (LocaleCompare(attribute,"frame") == 0)
10167 {
10168 char
10169 *p;
10170
10171 p=SvPV(ST(i),na);
10172 if (IsGeometry(p) == MagickFalse)
10173 {
10174 ThrowPerlException(exception,OptionError,"MissingGeometry",
10175 p);
10176 break;
10177 }
10178 (void) CloneString(&montage_info->frame,p);
10179 if (*p == '\0')
10180 montage_info->frame=(char *) NULL;
10181 break;
10182 }
10183 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10184 attribute);
10185 break;
10186 }
10187 case 'G':
10188 case 'g':
10189 {
10190 if (LocaleCompare(attribute,"geometry") == 0)
10191 {
10192 char
10193 *p;
10194
10195 p=SvPV(ST(i),na);
10196 if (IsGeometry(p) == MagickFalse)
10197 {
10198 ThrowPerlException(exception,OptionError,"MissingGeometry",
10199 p);
10200 break;
10201 }
10202 (void) CloneString(&montage_info->geometry,p);
10203 if (*p == '\0')
10204 montage_info->geometry=(char *) NULL;
10205 break;
10206 }
10207 if (LocaleCompare(attribute,"gravity") == 0)
10208 {
10209 long
10210 in;
10211
10212 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
10213 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
10214 if (in < 0)
10215 {
10216 ThrowPerlException(exception,OptionError,"UnrecognizedType",
10217 SvPV(ST(i),na));
10218 return;
10219 }
10220 montage_info->gravity=(GravityType) in;
10221 for (next=image; next; next=next->next)
10222 next->gravity=(GravityType) in;
10223 break;
10224 }
10225 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10226 attribute);
10227 break;
10228 }
10229 case 'L':
10230 case 'l':
10231 {
10232 if (LocaleCompare(attribute,"label") == 0)
10233 {
10234 for (next=image; next; next=next->next)
10235 (void) SetImageProperty(next,"label",InterpretImageProperties(
10236 info ? info->image_info : (ImageInfo *) NULL,next,
10237 SvPV(ST(i),na)));
10238 break;
10239 }
10240 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10241 attribute);
10242 break;
10243 }
10244 case 'M':
10245 case 'm':
10246 {
10247 if (LocaleCompare(attribute,"mattecolor") == 0)
10248 {
10249 (void) QueryColorDatabase(SvPV(ST(i),na),
10250 &montage_info->matte_color,exception);
10251 for (next=image; next; next=next->next)
10252 next->matte_color=montage_info->matte_color;
10253 break;
10254 }
10255 if (LocaleCompare(attribute,"mode") == 0)
10256 {
10257 long
10258 in;
10259
10260 in=!SvPOK(ST(i)) ? SvIV(ST(i)) :
10261 ParseMagickOption(MagickModeOptions,MagickFalse,SvPV(ST(i),na));
10262 switch (in)
10263 {
10264 default:
10265 {
10266 ThrowPerlException(exception,OptionError,
10267 "UnrecognizedModeType",SvPV(ST(i),na));
10268 break;
10269 }
10270 case FrameMode:
10271 {
10272 (void) CloneString(&montage_info->frame,"15x15+3+3");
10273 montage_info->shadow=MagickTrue;
10274 break;
10275 }
10276 case UnframeMode:
10277 {
10278 montage_info->frame=(char *) NULL;
10279 montage_info->shadow=MagickFalse;
10280 montage_info->border_width=0;
10281 break;
10282 }
10283 case ConcatenateMode:
10284 {
10285 montage_info->frame=(char *) NULL;
10286 montage_info->shadow=MagickFalse;
10287 (void) CloneString(&montage_info->geometry,"+0+0");
10288 montage_info->border_width=0;
10289 }
10290 }
10291 break;
10292 }
10293 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10294 attribute);
10295 break;
10296 }
10297 case 'P':
10298 case 'p':
10299 {
10300 if (LocaleCompare(attribute,"pointsize") == 0)
10301 {
10302 montage_info->pointsize=SvIV(ST(i));
10303 break;
10304 }
10305 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10306 attribute);
10307 break;
10308 }
10309 case 'S':
10310 case 's':
10311 {
10312 if (LocaleCompare(attribute,"shadow") == 0)
10313 {
10314 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
10315 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
10316 if (sp < 0)
10317 {
10318 ThrowPerlException(exception,OptionError,"UnrecognizedType",
10319 SvPV(ST(i),na));
10320 break;
10321 }
10322 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
10323 break;
10324 }
10325 if (LocaleCompare(attribute,"stroke") == 0)
10326 {
10327 (void) QueryColorDatabase(SvPV(ST(i),na),&montage_info->stroke,
10328 exception);
10329 break;
10330 }
10331 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10332 attribute);
10333 break;
10334 }
10335 case 'T':
10336 case 't':
10337 {
10338 if (LocaleCompare(attribute,"texture") == 0)
10339 {
10340 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
10341 break;
10342 }
10343 if (LocaleCompare(attribute,"tile") == 0)
10344 {
10345 char *p=SvPV(ST(i),na);
10346 if (IsGeometry(p) == MagickFalse)
10347 {
10348 ThrowPerlException(exception,OptionError,"MissingGeometry",
10349 p);
10350 break;
10351 }
10352 (void) CloneString(&montage_info->tile,p);
10353 if (*p == '\0')
10354 montage_info->tile=(char *) NULL;
10355 break;
10356 }
10357 if (LocaleCompare(attribute,"title") == 0)
10358 {
10359 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
10360 break;
10361 }
10362 if (LocaleCompare(attribute,"transparent") == 0)
10363 {
10364 MagickPixelPacket
10365 transparent_color;
10366
10367 QueryMagickColor(SvPV(ST(i),na),&transparent_color,exception);
10368 for (next=image; next; next=next->next)
10369 (void) TransparentPaintImage(next,&transparent_color,
10370 TransparentOpacity,MagickFalse);
10371 break;
10372 }
10373 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10374 attribute);
10375 break;
10376 }
10377 default:
10378 {
10379 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10380 attribute);
10381 break;
10382 }
10383 }
10384 }
10385 image=MontageImageList(info->image_info,montage_info,image,exception);
10386 montage_info=DestroyMontageInfo(montage_info);
10387 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
10388 goto PerlException;
10389 if (transparent_color.opacity != TransparentOpacity)
10390 for (next=image; next; next=next->next)
10391 (void) TransparentPaintImage(next,&transparent_color,
10392 TransparentOpacity,MagickFalse);
10393 for ( ; image; image=image->next)
10394 {
10395 AddImageToRegistry(image);
10396 rv=newRV(sv);
10397 av_push(av,sv_bless(rv,hv));
10398 SvREFCNT_dec(sv);
10399 }
10400 exception=DestroyExceptionInfo(exception);
10401 ST(0)=av_reference;
10402 SvREFCNT_dec(perl_exception);
10403 XSRETURN(1);
10404
10405 PerlException:
10406 InheritPerlException(exception,perl_exception);
10407 exception=DestroyExceptionInfo(exception);
10408 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10409 SvPOK_on(perl_exception);
10410 ST(0)=sv_2mortal(perl_exception);
10411 XSRETURN(1);
10412 }
10413
10414#
10415###############################################################################
10416# #
10417# #
10418# #
10419# M o r p h #
10420# #
10421# #
10422# #
10423###############################################################################
10424#
10425#
10426void
10427Morph(ref,...)
10428 Image::Magick ref=NO_INIT
10429 ALIAS:
10430 MorphImage = 1
10431 morph = 2
10432 morphimage = 3
10433 PPCODE:
10434 {
10435 AV
10436 *av;
10437
10438 char
10439 *attribute;
10440
10441 ExceptionInfo
10442 *exception;
10443
10444 HV
10445 *hv;
10446
10447 Image
10448 *image;
10449
10450 long
10451 number_frames;
10452
10453 register long
10454 i;
10455
10456 struct PackageInfo
10457 *info;
10458
10459 SV
10460 *av_reference,
10461 *perl_exception,
10462 *reference,
10463 *rv,
10464 *sv;
10465
10466 exception=AcquireExceptionInfo();
10467 perl_exception=newSVpv("",0);
10468 av=NULL;
10469 attribute=NULL;
10470 if (sv_isobject(ST(0)) == 0)
10471 {
10472 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10473 PackageName);
10474 goto PerlException;
10475 }
10476 reference=SvRV(ST(0));
10477 hv=SvSTASH(reference);
10478 av=newAV();
10479 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10480 SvREFCNT_dec(av);
10481 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10482 if (image == (Image *) NULL)
10483 {
10484 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10485 PackageName);
10486 goto PerlException;
10487 }
10488 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10489 /*
10490 Get attribute.
10491 */
10492 number_frames=30;
10493 for (i=2; i < items; i+=2)
10494 {
10495 attribute=(char *) SvPV(ST(i-1),na);
10496 switch (*attribute)
10497 {
10498 case 'F':
10499 case 'f':
10500 {
10501 if (LocaleCompare(attribute,"frames") == 0)
10502 {
10503 number_frames=SvIV(ST(i));
10504 break;
10505 }
10506 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10507 attribute);
10508 break;
10509 }
10510 default:
10511 {
10512 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10513 attribute);
10514 break;
10515 }
10516 }
10517 }
10518 image=MorphImages(image,number_frames,exception);
10519 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
10520 goto PerlException;
10521 for ( ; image; image=image->next)
10522 {
10523 AddImageToRegistry(image);
10524 rv=newRV(sv);
10525 av_push(av,sv_bless(rv,hv));
10526 SvREFCNT_dec(sv);
10527 }
10528 exception=DestroyExceptionInfo(exception);
10529 ST(0)=av_reference;
10530 SvREFCNT_dec(perl_exception); /* can't return warning messages */
10531 XSRETURN(1);
10532
10533 PerlException:
10534 InheritPerlException(exception,perl_exception);
10535 exception=DestroyExceptionInfo(exception);
10536 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10537 SvPOK_on(perl_exception);
10538 ST(0)=sv_2mortal(perl_exception);
10539 XSRETURN(1);
10540 }
10541
10542#
10543###############################################################################
10544# #
10545# #
10546# #
10547# M o s a i c #
10548# #
10549# #
10550# #
10551###############################################################################
10552#
10553#
10554void
10555Mosaic(ref)
10556 Image::Magick ref=NO_INIT
10557 ALIAS:
10558 MosaicImage = 1
10559 mosaic = 2
10560 mosaicimage = 3
10561 PPCODE:
10562 {
10563 AV
10564 *av;
10565
10566 ExceptionInfo
10567 *exception;
10568
10569 HV
10570 *hv;
10571
10572 Image
10573 *image;
10574
10575 struct PackageInfo
10576 *info;
10577
10578 SV
10579 *perl_exception,
10580 *reference,
10581 *rv,
10582 *sv;
10583
10584 exception=AcquireExceptionInfo();
10585 perl_exception=newSVpv("",0);
10586 if (sv_isobject(ST(0)) == 0)
10587 {
10588 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10589 PackageName);
10590 goto PerlException;
10591 }
10592 reference=SvRV(ST(0));
10593 hv=SvSTASH(reference);
10594 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10595 if (image == (Image *) NULL)
10596 {
10597 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10598 PackageName);
10599 goto PerlException;
10600 }
10601 image=MergeImageLayers(image,MosaicLayer,exception);
10602 /*
10603 Create blessed Perl array for the returned image.
10604 */
10605 av=newAV();
10606 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10607 SvREFCNT_dec(av);
10608 AddImageToRegistry(image);
10609 rv=newRV(sv);
10610 av_push(av,sv_bless(rv,hv));
10611 SvREFCNT_dec(sv);
10612 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10613 (void) CopyMagickString(image->filename,info->image_info->filename,
10614 MaxTextExtent);
10615 SetImageInfo(info->image_info,MagickFalse,&image->exception);
10616 exception=DestroyExceptionInfo(exception);
10617 SvREFCNT_dec(perl_exception);
10618 XSRETURN(1);
10619
10620 PerlException:
10621 InheritPerlException(exception,perl_exception);
10622 exception=DestroyExceptionInfo(exception);
10623 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10624 SvPOK_on(perl_exception); /* return messages in string context */
10625 ST(0)=sv_2mortal(perl_exception);
10626 XSRETURN(1);
10627 }
10628
10629#
10630###############################################################################
10631# #
10632# #
10633# #
10634# P i n g #
10635# #
10636# #
10637# #
10638###############################################################################
10639#
10640#
10641void
10642Ping(ref,...)
10643 Image::Magick ref=NO_INIT
10644 ALIAS:
10645 PingImage = 1
10646 ping = 2
10647 pingimage = 3
10648 PPCODE:
10649 {
10650 AV
10651 *av;
10652
10653 char
10654 **keep,
10655 **list;
10656
10657 ExceptionInfo
10658 *exception;
10659
10660 HV
10661 *hv;
10662
10663 Image
10664 *image,
10665 *next;
10666
10667 int
10668 n;
10669
10670 long
10671 ac;
10672
10673 MagickBooleanType
10674 status;
10675
10676 register char
10677 **p;
10678
10679 register long
10680 i;
10681
10682 STRLEN
10683 *length;
10684
10685 struct PackageInfo
10686 *info,
10687 *package_info;
10688
10689 SV
10690 *perl_exception,
10691 *reference;
10692
10693 unsigned long
10694 count;
10695
10696 exception=AcquireExceptionInfo();
10697 perl_exception=newSVpv("",0);
10698 package_info=(struct PackageInfo *) NULL;
10699 ac=(items < 2) ? 1 : items-1;
10700 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
10701 keep=list;
10702 length=(STRLEN *) NULL;
10703 if (list == (char **) NULL)
10704 {
10705 ThrowPerlException(exception,ResourceLimitError,
10706 "MemoryAllocationFailed",PackageName);
10707 goto PerlException;
10708 }
10709 keep=list;
10710 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
10711 if (length == (STRLEN *) NULL)
10712 {
10713 ThrowPerlException(exception,ResourceLimitError,
10714 "MemoryAllocationFailed",PackageName);
10715 goto PerlException;
10716 }
10717 if (sv_isobject(ST(0)) == 0)
10718 {
10719 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10720 PackageName);
10721 goto PerlException;
10722 }
10723 reference=SvRV(ST(0));
10724 hv=SvSTASH(reference);
10725 if (SvTYPE(reference) != SVt_PVAV)
10726 {
10727 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10728 PackageName);
10729 goto PerlException;
10730 }
10731 av=(AV *) reference;
10732 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
10733 exception);
10734 package_info=ClonePackageInfo(info,exception);
10735 n=1;
10736 if (items <= 1)
10737 *list=(char *) (*package_info->image_info->filename ?
10738 package_info->image_info->filename : "XC:black");
10739 else
10740 for (n=0, i=0; i < ac; i++)
10741 {
10742 list[n]=(char *) SvPV(ST(i+1),length[n]);
10743 if ((items >= 3) && strEQcase(list[n],"blob"))
10744 {
10745 void
10746 *blob;
10747
10748 i++;
10749 blob=(void *) (SvPV(ST(i+1),length[n]));
10750 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
10751 }
10752 if ((items >= 3) && strEQcase(list[n],"filename"))
10753 continue;
10754 if ((items >= 3) && strEQcase(list[n],"file"))
10755 {
10756 FILE
10757 *file;
10758
10759 PerlIO
10760 *io_info;
10761
10762 i++;
10763 io_info=IoIFP(sv_2io(ST(i+1)));
10764 if (io_info == (PerlIO *) NULL)
10765 {
10766 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
10767 PackageName);
10768 continue;
10769 }
10770 file=PerlIO_findFILE(io_info);
10771 if (file == (FILE *) NULL)
10772 {
10773 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
10774 PackageName);
10775 continue;
10776 }
10777 SetImageInfoFile(package_info->image_info,file);
10778 }
10779 if ((items >= 3) && strEQcase(list[n],"magick"))
10780 continue;
10781 n++;
10782 }
10783 list[n]=(char *) NULL;
10784 keep=list;
10785 status=ExpandFilenames(&n,&list);
10786 if (status == MagickFalse)
10787 {
10788 ThrowPerlException(exception,ResourceLimitError,
10789 "MemoryAllocationFailed",PackageName);
10790 goto PerlException;
10791 }
10792 count=0;
10793 for (i=0; i < n; i++)
10794 {
10795 (void) CopyMagickString(package_info->image_info->filename,list[i],
10796 MaxTextExtent);
10797 image=PingImage(package_info->image_info,exception);
10798 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
10799 break;
10800 if ((package_info->image_info->file != (FILE *) NULL) ||
10801 (package_info->image_info->blob != (void *) NULL))
10802 DisassociateImageStream(image);
10803 count+=GetImageListLength(image);
10804 EXTEND(sp,4*count);
10805 for (next=image; next; next=next->next)
10806 {
10807 PUSHs(sv_2mortal(newSViv(next->columns)));
10808 PUSHs(sv_2mortal(newSViv(next->rows)));
10809 PUSHs(sv_2mortal(newSViv((unsigned long) GetBlobSize(next))));
10810 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
10811 }
10812 image=DestroyImageList(image);
10813 }
10814 /*
10815 Free resources.
10816 */
10817 for (i=0; i < n; i++)
10818 if (list[i] != (char *) NULL)
10819 for (p=keep; list[i] != *p++; )
10820 if (*p == NULL)
10821 {
10822 list[i]=(char *) RelinquishMagickMemory(list[i]);
10823 break;
10824 }
10825
10826 PerlException:
10827 if (package_info != (struct PackageInfo *) NULL)
10828 DestroyPackageInfo(package_info);
10829 if (list && (list != keep))
10830 list=(char **) RelinquishMagickMemory(list);
10831 if (keep)
10832 keep=(char **) RelinquishMagickMemory(keep);
10833 if (length)
10834 length=(STRLEN *) RelinquishMagickMemory(length);
10835 InheritPerlException(exception,perl_exception);
10836 exception=DestroyExceptionInfo(exception);
10837 SvREFCNT_dec(perl_exception); /* throw away all errors */
10838 }
10839
10840#
10841###############################################################################
10842# #
10843# #
10844# #
10845# P r e v i e w #
10846# #
10847# #
10848# #
10849###############################################################################
10850#
10851#
10852void
10853Preview(ref,...)
10854 Image::Magick ref=NO_INIT
10855 ALIAS:
10856 PreviewImage = 1
10857 preview = 2
10858 previewimage = 3
10859 PPCODE:
10860 {
10861 AV
10862 *av;
10863
10864 ExceptionInfo
10865 *exception;
10866
10867 HV
10868 *hv;
10869
10870 Image
10871 *image,
10872 *preview_image;
10873
10874 PreviewType
10875 preview_type;
10876
10877 struct PackageInfo
10878 *info;
10879
10880 SV
10881 *av_reference,
10882 *perl_exception,
10883 *reference,
10884 *rv,
10885 *sv;
10886
10887 exception=AcquireExceptionInfo();
10888 perl_exception=newSVpv("",0);
10889 av=NULL;
10890 if (sv_isobject(ST(0)) == 0)
10891 {
10892 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10893 PackageName);
10894 goto PerlException;
10895 }
10896 reference=SvRV(ST(0));
10897 hv=SvSTASH(reference);
10898 av=newAV();
10899 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10900 SvREFCNT_dec(av);
10901 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10902 if (image == (Image *) NULL)
10903 {
10904 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10905 PackageName);
10906 goto PerlException;
10907 }
10908 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10909 preview_type=GammaPreview;
10910 if (items > 1)
10911 preview_type=(PreviewType)
10912 ParseMagickOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
10913 for ( ; image; image=image->next)
10914 {
10915 preview_image=PreviewImage(image,preview_type,exception);
10916 if (preview_image == (Image *) NULL)
10917 goto PerlException;
10918 AddImageToRegistry(preview_image);
10919 rv=newRV(sv);
10920 av_push(av,sv_bless(rv,hv));
10921 SvREFCNT_dec(sv);
10922 }
10923 exception=DestroyExceptionInfo(exception);
10924 ST(0)=av_reference;
10925 SvREFCNT_dec(perl_exception); /* can't return warning messages */
10926 XSRETURN(1);
10927
10928 PerlException:
10929 InheritPerlException(exception,perl_exception);
10930 exception=DestroyExceptionInfo(exception);
10931 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10932 SvPOK_on(perl_exception);
10933 ST(0)=sv_2mortal(perl_exception);
10934 XSRETURN(1);
10935 }
10936
10937#
10938###############################################################################
10939# #
10940# #
10941# #
10942# Q u e r y C o l o r #
10943# #
10944# #
10945# #
10946###############################################################################
10947#
10948#
10949void
10950QueryColor(ref,...)
10951 Image::Magick ref=NO_INIT
10952 ALIAS:
10953 querycolor = 1
10954 PPCODE:
10955 {
10956 char
10957 *name;
10958
10959 ExceptionInfo
10960 *exception;
10961
10962 MagickPixelPacket
10963 color;
10964
10965 register long
10966 i;
10967
10968 SV
10969 *perl_exception;
10970
10971 exception=AcquireExceptionInfo();
10972 perl_exception=newSVpv("",0);
10973 if (items == 1)
10974 {
10975 const ColorInfo
10976 **colorlist;
10977
10978 unsigned long
10979 colors;
10980
10981 colorlist=GetColorInfoList("*",&colors,exception);
10982 EXTEND(sp,colors);
10983 for (i=0; i < (long) colors; i++)
10984 {
10985 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
10986 }
10987 colorlist=(const ColorInfo **)
10988 RelinquishMagickMemory((ColorInfo **) colorlist);
10989 goto PerlException;
10990 }
10991 EXTEND(sp,5*items);
10992 for (i=1; i < items; i++)
10993 {
10994 name=(char *) SvPV(ST(i),na);
10995 if (QueryMagickColor(name,&color,exception) == MagickFalse)
10996 {
10997 PUSHs(&sv_undef);
10998 continue;
10999 }
11000 PUSHs(sv_2mortal(newSViv((unsigned long) (color.red+0.5))));
11001 PUSHs(sv_2mortal(newSViv((unsigned long) (color.green+0.5))));
11002 PUSHs(sv_2mortal(newSViv((unsigned long) (color.blue+0.5))));
11003 if (color.matte != MagickFalse)
11004 PUSHs(sv_2mortal(newSViv((unsigned long) (color.opacity+0.5))));
11005 if (color.colorspace == CMYKColorspace)
11006 PUSHs(sv_2mortal(newSViv((unsigned long) (color.index+0.5))));
11007 }
11008
11009 PerlException:
11010 InheritPerlException(exception,perl_exception);
11011 exception=DestroyExceptionInfo(exception);
11012 SvREFCNT_dec(perl_exception);
11013 }
11014
11015#
11016###############################################################################
11017# #
11018# #
11019# #
11020# Q u e r y C o l o r N a m e #
11021# #
11022# #
11023# #
11024###############################################################################
11025#
11026#
11027void
11028QueryColorname(ref,...)
11029 Image::Magick ref=NO_INIT
11030 ALIAS:
11031 querycolorname = 1
11032 PPCODE:
11033 {
11034 AV
11035 *av;
11036
11037 char
11038 message[MaxTextExtent];
11039
11040 ExceptionInfo
11041 *exception;
11042
11043 Image
11044 *image;
11045
11046 PixelPacket
11047 target_color;
11048
11049 register long
11050 i;
11051
11052 struct PackageInfo
11053 *info;
11054
11055 SV
11056 *perl_exception,
11057 *reference; /* reference is the SV* of ref=SvIV(reference) */
11058
11059 exception=AcquireExceptionInfo();
11060 perl_exception=newSVpv("",0);
11061 reference=SvRV(ST(0));
11062 av=(AV *) reference;
11063 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11064 exception);
11065 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11066 if (image == (Image *) NULL)
11067 {
11068 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11069 PackageName);
11070 goto PerlException;
11071 }
11072 EXTEND(sp,items);
11073 for (i=1; i < items; i++)
11074 {
11075 (void) QueryColorDatabase(SvPV(ST(i),na),&target_color,exception);
11076 (void) QueryColorname(image,&target_color,SVGCompliance,message,
11077 exception);
11078 PUSHs(sv_2mortal(newSVpv(message,0)));
11079 }
11080
11081 PerlException:
11082 InheritPerlException(exception,perl_exception);
11083 exception=DestroyExceptionInfo(exception);
11084 SvREFCNT_dec(perl_exception);
11085 }
11086
11087#
11088###############################################################################
11089# #
11090# #
11091# #
11092# Q u e r y F o n t #
11093# #
11094# #
11095# #
11096###############################################################################
11097#
11098#
11099void
11100QueryFont(ref,...)
11101 Image::Magick ref=NO_INIT
11102 ALIAS:
11103 queryfont = 1
11104 PPCODE:
11105 {
11106 char
11107 *name,
11108 message[MaxTextExtent];
11109
11110 ExceptionInfo
11111 *exception;
11112
11113 register long
11114 i;
11115
11116 SV
11117 *perl_exception;
11118
11119 volatile const TypeInfo
11120 *type_info;
11121
11122 exception=AcquireExceptionInfo();
11123 perl_exception=newSVpv("",0);
11124 if (items == 1)
11125 {
11126 const TypeInfo
11127 **typelist;
11128
11129 unsigned long
11130 types;
11131
11132 typelist=GetTypeInfoList("*",&types,exception);
11133 EXTEND(sp,types);
11134 for (i=0; i < (long) types; i++)
11135 {
11136 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
11137 }
11138 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
11139 typelist);
11140 goto PerlException;
11141 }
11142 EXTEND(sp,10*items);
11143 for (i=1; i < items; i++)
11144 {
11145 name=(char *) SvPV(ST(i),na);
11146 type_info=GetTypeInfo(name,exception);
11147 if (type_info == (TypeInfo *) NULL)
11148 {
11149 PUSHs(&sv_undef);
11150 continue;
11151 }
11152 if (type_info->name == (char *) NULL)
11153 PUSHs(&sv_undef);
11154 else
11155 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
11156 if (type_info->description == (char *) NULL)
11157 PUSHs(&sv_undef);
11158 else
11159 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
11160 if (type_info->family == (char *) NULL)
11161 PUSHs(&sv_undef);
11162 else
11163 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
11164 if (type_info->style == UndefinedStyle)
11165 PUSHs(&sv_undef);
11166 else
11167 PUSHs(sv_2mortal(newSVpv(MagickOptionToMnemonic(MagickStyleOptions,
11168 type_info->style),0)));
11169 if (type_info->stretch == UndefinedStretch)
11170 PUSHs(&sv_undef);
11171 else
11172 PUSHs(sv_2mortal(newSVpv(MagickOptionToMnemonic(MagickStretchOptions,
11173 type_info->stretch),0)));
11174 (void) FormatMagickString(message,MaxTextExtent,"%lu",type_info->weight);
11175 PUSHs(sv_2mortal(newSVpv(message,0)));
11176 if (type_info->encoding == (char *) NULL)
11177 PUSHs(&sv_undef);
11178 else
11179 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
11180 if (type_info->foundry == (char *) NULL)
11181 PUSHs(&sv_undef);
11182 else
11183 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
11184 if (type_info->format == (char *) NULL)
11185 PUSHs(&sv_undef);
11186 else
11187 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
11188 if (type_info->metrics == (char *) NULL)
11189 PUSHs(&sv_undef);
11190 else
11191 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
11192 if (type_info->glyphs == (char *) NULL)
11193 PUSHs(&sv_undef);
11194 else
11195 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
11196 }
11197
11198 PerlException:
11199 InheritPerlException(exception,perl_exception);
11200 exception=DestroyExceptionInfo(exception);
11201 SvREFCNT_dec(perl_exception);
11202 }
11203
11204#
11205###############################################################################
11206# #
11207# #
11208# #
11209# Q u e r y F o n t M e t r i c s #
11210# #
11211# #
11212# #
11213###############################################################################
11214#
11215#
11216void
11217QueryFontMetrics(ref,...)
11218 Image::Magick ref=NO_INIT
11219 ALIAS:
11220 queryfontmetrics = 1
11221 PPCODE:
11222 {
11223 AffineMatrix
11224 affine,
11225 current;
11226
11227 AV
11228 *av;
11229
11230 char
11231 *attribute;
11232
11233 double
11234 x,
11235 y;
11236
11237 DrawInfo
11238 *draw_info;
11239
11240 ExceptionInfo
11241 *exception;
11242
11243 GeometryInfo
11244 geometry_info;
11245
11246 Image
11247 *image;
11248
11249 long
11250 type;
11251
11252 MagickBooleanType
11253 status;
11254
11255 MagickStatusType
11256 flags;
11257
11258 register long
11259 i;
11260
11261 struct PackageInfo
11262 *info,
11263 *package_info;
11264
11265 SV
11266 *perl_exception,
11267 *reference; /* reference is the SV* of ref=SvIV(reference) */
11268
11269 TypeMetric
11270 metrics;
11271
11272 exception=AcquireExceptionInfo();
11273 package_info=(struct PackageInfo *) NULL;
11274 perl_exception=newSVpv("",0);
11275 reference=SvRV(ST(0));
11276 av=(AV *) reference;
11277 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11278 exception);
11279 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11280 if (image == (Image *) NULL)
11281 {
11282 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11283 PackageName);
11284 goto PerlException;
11285 }
11286 package_info=ClonePackageInfo(info,exception);
11287 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
11288 CloneString(&draw_info->text,"");
11289 current=draw_info->affine;
11290 GetAffineMatrix(&affine);
11291 x=0.0;
11292 y=0.0;
11293 EXTEND(sp,7*items);
11294 for (i=2; i < items; i+=2)
11295 {
11296 attribute=(char *) SvPV(ST(i-1),na);
11297 switch (*attribute)
11298 {
11299 case 'A':
11300 case 'a':
11301 {
11302 if (LocaleCompare(attribute,"antialias") == 0)
11303 {
11304 type=ParseMagickOption(MagickBooleanOptions,MagickFalse,
11305 SvPV(ST(i),na));
11306 if (type < 0)
11307 {
11308 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11309 SvPV(ST(i),na));
11310 break;
11311 }
11312 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
11313 break;
11314 }
11315 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11316 attribute);
11317 break;
11318 }
11319 case 'd':
11320 case 'D':
11321 {
11322 if (LocaleCompare(attribute,"density") == 0)
11323 {
11324 CloneString(&draw_info->density,SvPV(ST(i),na));
11325 break;
11326 }
11327 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11328 attribute);
11329 break;
11330 }
11331 case 'e':
11332 case 'E':
11333 {
11334 if (LocaleCompare(attribute,"encoding") == 0)
11335 {
11336 CloneString(&draw_info->encoding,SvPV(ST(i),na));
11337 break;
11338 }
11339 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11340 attribute);
11341 break;
11342 }
11343 case 'f':
11344 case 'F':
11345 {
11346 if (LocaleCompare(attribute,"family") == 0)
11347 {
11348 CloneString(&draw_info->family,SvPV(ST(i),na));
11349 break;
11350 }
11351 if (LocaleCompare(attribute,"fill") == 0)
11352 {
11353 if (info)
11354 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->fill,
11355 &image->exception);
11356 break;
11357 }
11358 if (LocaleCompare(attribute,"font") == 0)
11359 {
11360 CloneString(&draw_info->font,SvPV(ST(i),na));
11361 break;
11362 }
11363 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11364 attribute);
11365 break;
11366 }
11367 case 'g':
11368 case 'G':
11369 {
11370 if (LocaleCompare(attribute,"geometry") == 0)
11371 {
11372 CloneString(&draw_info->geometry,SvPV(ST(i),na));
11373 break;
11374 }
11375 if (LocaleCompare(attribute,"gravity") == 0)
11376 {
11377 draw_info->gravity=(GravityType) ParseMagickOption(
11378 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11379 break;
11380 }
11381 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11382 attribute);
11383 break;
11384 }
11385 case 'i':
11386 case 'I':
11387 {
cristyb32b90a2009-09-07 21:45:48 +000011388 if (LocaleCompare(attribute,"interline-spacing") == 0)
11389 {
11390 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11391 draw_info->interline_spacing=geometry_info.rho;
11392 break;
11393 }
cristy3ed852e2009-09-05 21:47:34 +000011394 if (LocaleCompare(attribute,"interword-spacing") == 0)
11395 {
11396 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11397 draw_info->interword_spacing=geometry_info.rho;
11398 break;
11399 }
11400 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11401 attribute);
11402 break;
11403 }
11404 case 'k':
11405 case 'K':
11406 {
11407 if (LocaleCompare(attribute,"kerning") == 0)
11408 {
11409 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11410 draw_info->kerning=geometry_info.rho;
11411 break;
11412 }
11413 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11414 attribute);
11415 break;
11416 }
11417 case 'p':
11418 case 'P':
11419 {
11420 if (LocaleCompare(attribute,"pointsize") == 0)
11421 {
11422 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11423 draw_info->pointsize=geometry_info.rho;
11424 break;
11425 }
11426 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11427 attribute);
11428 break;
11429 }
11430 case 'r':
11431 case 'R':
11432 {
11433 if (LocaleCompare(attribute,"rotate") == 0)
11434 {
11435 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11436 affine.rx=geometry_info.rho;
11437 affine.ry=geometry_info.sigma;
11438 if ((flags & SigmaValue) == 0)
11439 affine.ry=affine.rx;
11440 break;
11441 }
11442 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11443 attribute);
11444 break;
11445 }
11446 case 's':
11447 case 'S':
11448 {
11449 if (LocaleCompare(attribute,"scale") == 0)
11450 {
11451 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11452 affine.sx=geometry_info.rho;
11453 affine.sy=geometry_info.sigma;
11454 if ((flags & SigmaValue) == 0)
11455 affine.sy=affine.sx;
11456 break;
11457 }
11458 if (LocaleCompare(attribute,"skew") == 0)
11459 {
11460 double
11461 x_angle,
11462 y_angle;
11463
11464 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11465 x_angle=geometry_info.rho;
11466 y_angle=geometry_info.sigma;
11467 if ((flags & SigmaValue) == 0)
11468 y_angle=x_angle;
11469 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
11470 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
11471 break;
11472 }
11473 if (LocaleCompare(attribute,"stroke") == 0)
11474 {
11475 if (info)
11476 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->stroke,
11477 &image->exception);
11478 break;
11479 }
11480 if (LocaleCompare(attribute,"style") == 0)
11481 {
11482 type=ParseMagickOption(MagickStyleOptions,MagickFalse,
11483 SvPV(ST(i),na));
11484 if (type < 0)
11485 {
11486 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11487 SvPV(ST(i),na));
11488 break;
11489 }
11490 draw_info->style=(StyleType) type;
11491 break;
11492 }
11493 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11494 attribute);
11495 break;
11496 }
11497 case 't':
11498 case 'T':
11499 {
11500 if (LocaleCompare(attribute,"text") == 0)
11501 {
11502 CloneString(&draw_info->text,SvPV(ST(i),na));
11503 break;
11504 }
11505 if (LocaleCompare(attribute,"translate") == 0)
11506 {
11507 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11508 affine.tx=geometry_info.rho;
11509 affine.ty=geometry_info.sigma;
11510 if ((flags & SigmaValue) == 0)
11511 affine.ty=affine.tx;
11512 break;
11513 }
11514 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11515 attribute);
11516 break;
11517 }
11518 case 'w':
11519 case 'W':
11520 {
11521 if (LocaleCompare(attribute,"weight") == 0)
11522 {
11523 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11524 draw_info->weight=(unsigned long) geometry_info.rho;
11525 break;
11526 }
11527 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11528 attribute);
11529 break;
11530 }
11531 case 'x':
11532 case 'X':
11533 {
11534 if (LocaleCompare(attribute,"x") == 0)
11535 {
11536 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11537 x=geometry_info.rho;
11538 break;
11539 }
11540 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11541 attribute);
11542 break;
11543 }
11544 case 'y':
11545 case 'Y':
11546 {
11547 if (LocaleCompare(attribute,"y") == 0)
11548 {
11549 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11550 y=geometry_info.rho;
11551 break;
11552 }
11553 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11554 attribute);
11555 break;
11556 }
11557 default:
11558 {
11559 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11560 attribute);
11561 break;
11562 }
11563 }
11564 }
11565 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
11566 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
11567 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
11568 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
11569 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
11570 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
11571 if (draw_info->geometry == (char *) NULL)
11572 {
11573 draw_info->geometry=AcquireString((char *) NULL);
11574 (void) FormatMagickString(draw_info->geometry,MaxTextExtent,"%g,%g",
11575 x,y);
11576 }
11577 status=GetTypeMetrics(image,draw_info,&metrics);
11578 (void) CatchImageException(image);
11579 if (status == MagickFalse)
11580 PUSHs(&sv_undef);
11581 else
11582 {
11583 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
11584 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
11585 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
11586 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
11587 PUSHs(sv_2mortal(newSVnv(metrics.width)));
11588 PUSHs(sv_2mortal(newSVnv(metrics.height)));
11589 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
11590 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
11591 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
11592 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
11593 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
11594 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
11595 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
11596 }
11597 draw_info=DestroyDrawInfo(draw_info);
11598
11599 PerlException:
11600 if (package_info != (struct PackageInfo *) NULL)
11601 DestroyPackageInfo(package_info);
11602 InheritPerlException(exception,perl_exception);
11603 exception=DestroyExceptionInfo(exception);
11604 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11605 }
11606
11607#
11608###############################################################################
11609# #
11610# #
11611# #
11612# 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 #
11613# #
11614# #
11615# #
11616###############################################################################
11617#
11618#
11619void
11620QueryMultilineFontMetrics(ref,...)
11621 Image::Magick ref=NO_INIT
11622 ALIAS:
11623 querymultilinefontmetrics = 1
11624 PPCODE:
11625 {
11626 AffineMatrix
11627 affine,
11628 current;
11629
11630 AV
11631 *av;
11632
11633 char
11634 *attribute;
11635
11636 double
11637 x,
11638 y;
11639
11640 DrawInfo
11641 *draw_info;
11642
11643 ExceptionInfo
11644 *exception;
11645
11646 GeometryInfo
11647 geometry_info;
11648
11649 Image
11650 *image;
11651
11652 long
11653 type;
11654
11655 MagickBooleanType
11656 status;
11657
11658 MagickStatusType
11659 flags;
11660
11661 register long
11662 i;
11663
11664 struct PackageInfo
11665 *info,
11666 *package_info;
11667
11668 SV
11669 *perl_exception,
11670 *reference; /* reference is the SV* of ref=SvIV(reference) */
11671
11672 TypeMetric
11673 metrics;
11674
11675 exception=AcquireExceptionInfo();
11676 package_info=(struct PackageInfo *) NULL;
11677 perl_exception=newSVpv("",0);
11678 reference=SvRV(ST(0));
11679 av=(AV *) reference;
11680 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11681 exception);
11682 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11683 if (image == (Image *) NULL)
11684 {
11685 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11686 PackageName);
11687 goto PerlException;
11688 }
11689 package_info=ClonePackageInfo(info,exception);
11690 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
11691 CloneString(&draw_info->text,"");
11692 current=draw_info->affine;
11693 GetAffineMatrix(&affine);
11694 x=0.0;
11695 y=0.0;
11696 EXTEND(sp,7*items);
11697 for (i=2; i < items; i+=2)
11698 {
11699 attribute=(char *) SvPV(ST(i-1),na);
11700 switch (*attribute)
11701 {
11702 case 'A':
11703 case 'a':
11704 {
11705 if (LocaleCompare(attribute,"antialias") == 0)
11706 {
11707 type=ParseMagickOption(MagickBooleanOptions,MagickFalse,
11708 SvPV(ST(i),na));
11709 if (type < 0)
11710 {
11711 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11712 SvPV(ST(i),na));
11713 break;
11714 }
11715 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
11716 break;
11717 }
11718 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11719 attribute);
11720 break;
11721 }
11722 case 'd':
11723 case 'D':
11724 {
11725 if (LocaleCompare(attribute,"density") == 0)
11726 {
11727 CloneString(&draw_info->density,SvPV(ST(i),na));
11728 break;
11729 }
11730 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11731 attribute);
11732 break;
11733 }
11734 case 'e':
11735 case 'E':
11736 {
11737 if (LocaleCompare(attribute,"encoding") == 0)
11738 {
11739 CloneString(&draw_info->encoding,SvPV(ST(i),na));
11740 break;
11741 }
11742 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11743 attribute);
11744 break;
11745 }
11746 case 'f':
11747 case 'F':
11748 {
11749 if (LocaleCompare(attribute,"family") == 0)
11750 {
11751 CloneString(&draw_info->family,SvPV(ST(i),na));
11752 break;
11753 }
11754 if (LocaleCompare(attribute,"fill") == 0)
11755 {
11756 if (info)
11757 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->fill,
11758 &image->exception);
11759 break;
11760 }
11761 if (LocaleCompare(attribute,"font") == 0)
11762 {
11763 CloneString(&draw_info->font,SvPV(ST(i),na));
11764 break;
11765 }
11766 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11767 attribute);
11768 break;
11769 }
11770 case 'g':
11771 case 'G':
11772 {
11773 if (LocaleCompare(attribute,"geometry") == 0)
11774 {
11775 CloneString(&draw_info->geometry,SvPV(ST(i),na));
11776 break;
11777 }
11778 if (LocaleCompare(attribute,"gravity") == 0)
11779 {
11780 draw_info->gravity=(GravityType) ParseMagickOption(
11781 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11782 break;
11783 }
11784 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11785 attribute);
11786 break;
11787 }
11788 case 'p':
11789 case 'P':
11790 {
11791 if (LocaleCompare(attribute,"pointsize") == 0)
11792 {
11793 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11794 draw_info->pointsize=geometry_info.rho;
11795 break;
11796 }
11797 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11798 attribute);
11799 break;
11800 }
11801 case 'r':
11802 case 'R':
11803 {
11804 if (LocaleCompare(attribute,"rotate") == 0)
11805 {
11806 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11807 affine.rx=geometry_info.rho;
11808 affine.ry=geometry_info.sigma;
11809 if ((flags & SigmaValue) == 0)
11810 affine.ry=affine.rx;
11811 break;
11812 }
11813 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11814 attribute);
11815 break;
11816 }
11817 case 's':
11818 case 'S':
11819 {
11820 if (LocaleCompare(attribute,"scale") == 0)
11821 {
11822 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11823 affine.sx=geometry_info.rho;
11824 affine.sy=geometry_info.sigma;
11825 if ((flags & SigmaValue) == 0)
11826 affine.sy=affine.sx;
11827 break;
11828 }
11829 if (LocaleCompare(attribute,"skew") == 0)
11830 {
11831 double
11832 x_angle,
11833 y_angle;
11834
11835 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11836 x_angle=geometry_info.rho;
11837 y_angle=geometry_info.sigma;
11838 if ((flags & SigmaValue) == 0)
11839 y_angle=x_angle;
11840 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
11841 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
11842 break;
11843 }
11844 if (LocaleCompare(attribute,"stroke") == 0)
11845 {
11846 if (info)
11847 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->stroke,
11848 &image->exception);
11849 break;
11850 }
11851 if (LocaleCompare(attribute,"style") == 0)
11852 {
11853 type=ParseMagickOption(MagickStyleOptions,MagickFalse,
11854 SvPV(ST(i),na));
11855 if (type < 0)
11856 {
11857 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11858 SvPV(ST(i),na));
11859 break;
11860 }
11861 draw_info->style=(StyleType) type;
11862 break;
11863 }
11864 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11865 attribute);
11866 break;
11867 }
11868 case 't':
11869 case 'T':
11870 {
11871 if (LocaleCompare(attribute,"text") == 0)
11872 {
11873 CloneString(&draw_info->text,SvPV(ST(i),na));
11874 break;
11875 }
11876 if (LocaleCompare(attribute,"translate") == 0)
11877 {
11878 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11879 affine.tx=geometry_info.rho;
11880 affine.ty=geometry_info.sigma;
11881 if ((flags & SigmaValue) == 0)
11882 affine.ty=affine.tx;
11883 break;
11884 }
11885 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11886 attribute);
11887 break;
11888 }
11889 case 'w':
11890 case 'W':
11891 {
11892 if (LocaleCompare(attribute,"weight") == 0)
11893 {
11894 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11895 draw_info->weight=(unsigned long) geometry_info.rho;
11896 break;
11897 }
11898 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11899 attribute);
11900 break;
11901 }
11902 case 'x':
11903 case 'X':
11904 {
11905 if (LocaleCompare(attribute,"x") == 0)
11906 {
11907 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11908 x=geometry_info.rho;
11909 break;
11910 }
11911 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11912 attribute);
11913 break;
11914 }
11915 case 'y':
11916 case 'Y':
11917 {
11918 if (LocaleCompare(attribute,"y") == 0)
11919 {
11920 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11921 y=geometry_info.rho;
11922 break;
11923 }
11924 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11925 attribute);
11926 break;
11927 }
11928 default:
11929 {
11930 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11931 attribute);
11932 break;
11933 }
11934 }
11935 }
11936 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
11937 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
11938 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
11939 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
11940 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
11941 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
11942 if (draw_info->geometry == (char *) NULL)
11943 {
11944 draw_info->geometry=AcquireString((char *) NULL);
11945 (void) FormatMagickString(draw_info->geometry,MaxTextExtent,"%g,%g",
11946 x,y);
11947 }
11948 status=GetMultilineTypeMetrics(image,draw_info,&metrics);
11949 (void) CatchImageException(image);
11950 if (status == MagickFalse)
11951 PUSHs(&sv_undef);
11952 else
11953 {
11954 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
11955 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
11956 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
11957 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
11958 PUSHs(sv_2mortal(newSVnv(metrics.width)));
11959 PUSHs(sv_2mortal(newSVnv(metrics.height)));
11960 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
11961 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
11962 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
11963 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
11964 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
11965 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
11966 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
11967 }
11968 draw_info=DestroyDrawInfo(draw_info);
11969
11970 PerlException:
11971 if (package_info != (struct PackageInfo *) NULL)
11972 DestroyPackageInfo(package_info);
11973 InheritPerlException(exception,perl_exception);
11974 exception=DestroyExceptionInfo(exception);
11975 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11976 }
11977
11978#
11979###############################################################################
11980# #
11981# #
11982# #
11983# Q u e r y F o r m a t #
11984# #
11985# #
11986# #
11987###############################################################################
11988#
11989#
11990void
11991QueryFormat(ref,...)
11992 Image::Magick ref=NO_INIT
11993 ALIAS:
11994 queryformat = 1
11995 PPCODE:
11996 {
11997 char
11998 *name;
11999
12000 ExceptionInfo
12001 *exception;
12002
12003 register long
12004 i;
12005
12006 SV
12007 *perl_exception;
12008
12009 volatile const MagickInfo
12010 *magick_info;
12011
12012 exception=AcquireExceptionInfo();
12013 perl_exception=newSVpv("",0);
12014 if (items == 1)
12015 {
12016 char
12017 format[MaxTextExtent];
12018
12019 const MagickInfo
12020 **format_list;
12021
12022 unsigned long
12023 types;
12024
12025 format_list=GetMagickInfoList("*",&types,exception);
12026 EXTEND(sp,types);
12027 for (i=0; i < (long) types; i++)
12028 {
12029 (void) CopyMagickString(format,format_list[i]->name,MaxTextExtent);
12030 LocaleLower(format);
12031 PUSHs(sv_2mortal(newSVpv(format,0)));
12032 }
12033 format_list=(const MagickInfo **)
12034 RelinquishMagickMemory((MagickInfo *) format_list);
12035 goto PerlException;
12036 }
12037 EXTEND(sp,8*items);
12038 for (i=1; i < items; i++)
12039 {
12040 name=(char *) SvPV(ST(i),na);
12041 magick_info=GetMagickInfo(name,exception);
12042 if (magick_info == (const MagickInfo *) NULL)
12043 {
12044 PUSHs(&sv_undef);
12045 continue;
12046 }
12047 PUSHs(sv_2mortal(newSViv(magick_info->adjoin)));
12048 PUSHs(sv_2mortal(newSViv(magick_info->blob_support)));
12049 PUSHs(sv_2mortal(newSViv(magick_info->raw)));
12050 PUSHs(sv_2mortal(newSViv((long) magick_info->decoder)));
12051 PUSHs(sv_2mortal(newSViv((long) magick_info->encoder)));
12052 if (magick_info->description == (char *) NULL)
12053 PUSHs(&sv_undef);
12054 else
12055 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
12056 if (magick_info->module == (char *) NULL)
12057 PUSHs(&sv_undef);
12058 else
12059 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
12060 }
12061
12062 PerlException:
12063 InheritPerlException(exception,perl_exception);
12064 exception=DestroyExceptionInfo(exception);
12065 SvREFCNT_dec(perl_exception);
12066 }
12067
12068#
12069###############################################################################
12070# #
12071# #
12072# #
12073# Q u e r y O p t i o n #
12074# #
12075# #
12076# #
12077###############################################################################
12078#
12079#
12080void
12081QueryOption(ref,...)
12082 Image::Magick ref=NO_INIT
12083 ALIAS:
12084 queryoption = 1
12085 PPCODE:
12086 {
12087 char
12088 **options;
12089
12090 ExceptionInfo
12091 *exception;
12092
12093 long
12094 j,
12095 option;
12096
12097 register long
12098 i;
12099
12100 SV
12101 *perl_exception;
12102
12103 exception=AcquireExceptionInfo();
12104 perl_exception=newSVpv("",0);
12105 EXTEND(sp,8*items);
12106 for (i=1; i < items; i++)
12107 {
12108 option=ParseMagickOption(MagickListOptions,MagickFalse,(char *)
12109 SvPV(ST(i),na));
12110 options=GetMagickOptions((MagickOption) option);
12111 if (options == (char **) NULL)
12112 PUSHs(&sv_undef);
12113 else
12114 {
12115 for (j=0; options[j] != (char *) NULL; j++)
12116 PUSHs(sv_2mortal(newSVpv(options[j],0)));
12117 options=DestroyStringList(options);
12118 }
12119 }
12120
12121 PerlException:
12122 InheritPerlException(exception,perl_exception);
12123 exception=DestroyExceptionInfo(exception);
12124 SvREFCNT_dec(perl_exception);
12125 }
12126
12127#
12128###############################################################################
12129# #
12130# #
12131# #
12132# R e a d #
12133# #
12134# #
12135# #
12136###############################################################################
12137#
12138#
12139void
12140Read(ref,...)
12141 Image::Magick ref=NO_INIT
12142 ALIAS:
12143 ReadImage = 1
12144 read = 2
12145 readimage = 3
12146 PPCODE:
12147 {
12148 AV
12149 *av;
12150
12151 char
12152 **keep,
12153 **list;
12154
12155 ExceptionInfo
12156 *exception;
12157
12158 HV
12159 *hv;
12160
12161 Image
12162 *image;
12163
12164 int
12165 n;
12166
12167 long
12168 ac,
12169 number_images;
12170
12171 MagickBooleanType
12172 status;
12173
12174 register char
12175 **p;
12176
12177 register long
12178 i;
12179
12180 STRLEN
12181 *length;
12182
12183 struct PackageInfo
12184 *info,
12185 *package_info;
12186
12187 SV
12188 *perl_exception, /* Perl variable for storing messages */
12189 *reference,
12190 *rv,
12191 *sv;
12192
12193 exception=AcquireExceptionInfo();
12194 perl_exception=newSVpv("",0);
12195 package_info=(struct PackageInfo *) NULL;
12196 number_images=0;
12197 ac=(items < 2) ? 1 : items-1;
12198 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12199 keep=list;
12200 length=(STRLEN *) NULL;
12201 if (list == (char **) NULL)
12202 {
12203 ThrowPerlException(exception,ResourceLimitError,
12204 "MemoryAllocationFailed",PackageName);
12205 goto PerlException;
12206 }
12207 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12208 if (length == (STRLEN *) NULL)
12209 {
12210 ThrowPerlException(exception,ResourceLimitError,
12211 "MemoryAllocationFailed",PackageName);
12212 goto PerlException;
12213 }
12214 if (sv_isobject(ST(0)) == 0)
12215 {
12216 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12217 PackageName);
12218 goto PerlException;
12219 }
12220 reference=SvRV(ST(0));
12221 hv=SvSTASH(reference);
12222 if (SvTYPE(reference) != SVt_PVAV)
12223 {
12224 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12225 PackageName);
12226 goto PerlException;
12227 }
12228 av=(AV *) reference;
12229 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12230 exception);
12231 package_info=ClonePackageInfo(info,exception);
12232 n=1;
12233 if (items <= 1)
12234 *list=(char *) (*package_info->image_info->filename ?
12235 package_info->image_info->filename : "XC:black");
12236 else
12237 for (n=0, i=0; i < ac; i++)
12238 {
12239 list[n]=(char *) SvPV(ST(i+1),length[n]);
12240 if ((items >= 3) && strEQcase(list[n],"blob"))
12241 {
12242 void
12243 *blob;
12244
12245 i++;
12246 blob=(void *) (SvPV(ST(i+1),length[n]));
12247 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12248 }
12249 if ((items >= 3) && strEQcase(list[n],"filename"))
12250 continue;
12251 if ((items >= 3) && strEQcase(list[n],"file"))
12252 {
12253 FILE
12254 *file;
12255
12256 PerlIO
12257 *io_info;
12258
12259 i++;
12260 io_info=IoIFP(sv_2io(ST(i+1)));
12261 if (io_info == (PerlIO *) NULL)
12262 {
12263 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12264 PackageName);
12265 continue;
12266 }
12267 file=PerlIO_findFILE(io_info);
12268 if (file == (FILE *) NULL)
12269 {
12270 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12271 PackageName);
12272 continue;
12273 }
12274 SetImageInfoFile(package_info->image_info,file);
12275 }
12276 if ((items >= 3) && strEQcase(list[n],"magick"))
12277 continue;
12278 n++;
12279 }
12280 list[n]=(char *) NULL;
12281 keep=list;
12282 status=ExpandFilenames(&n,&list);
12283 if (status == MagickFalse)
12284 {
12285 ThrowPerlException(exception,ResourceLimitError,
12286 "MemoryAllocationFailed",PackageName);
12287 goto PerlException;
12288 }
12289 number_images=0;
12290 for (i=0; i < n; i++)
12291 {
12292 if ((package_info->image_info->file != (FILE *) NULL) ||
12293 (package_info->image_info->blob != (void *) NULL))
12294 {
12295 image=ReadImages(package_info->image_info,exception);
12296 if (image != (Image *) NULL)
12297 DisassociateImageStream(image);
12298 }
12299 else
12300 {
12301 (void) CopyMagickString(package_info->image_info->filename,list[i],
12302 MaxTextExtent);
12303 image=ReadImages(package_info->image_info,exception);
12304 }
12305 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
12306 break;
12307 for ( ; image; image=image->next)
12308 {
12309 AddImageToRegistry(image);
12310 rv=newRV(sv);
12311 av_push(av,sv_bless(rv,hv));
12312 SvREFCNT_dec(sv);
12313 number_images++;
12314 }
12315 }
12316 /*
12317 Free resources.
12318 */
12319 for (i=0; i < n; i++)
12320 if (list[i] != (char *) NULL)
12321 for (p=keep; list[i] != *p++; )
12322 if (*p == (char *) NULL)
12323 {
12324 list[i]=(char *) RelinquishMagickMemory(list[i]);
12325 break;
12326 }
12327
12328 PerlException:
12329 if (package_info != (struct PackageInfo *) NULL)
12330 DestroyPackageInfo(package_info);
12331 if (list && (list != keep))
12332 list=(char **) RelinquishMagickMemory(list);
12333 if (keep)
12334 keep=(char **) RelinquishMagickMemory(keep);
12335 if (length)
12336 length=(STRLEN *) RelinquishMagickMemory(length);
12337 InheritPerlException(exception,perl_exception);
12338 exception=DestroyExceptionInfo(exception);
12339 sv_setiv(perl_exception,(IV) number_images);
12340 SvPOK_on(perl_exception);
12341 ST(0)=sv_2mortal(perl_exception);
12342 XSRETURN(1);
12343 }
12344
12345#
12346###############################################################################
12347# #
12348# #
12349# #
12350# R e m o t e #
12351# #
12352# #
12353# #
12354###############################################################################
12355#
12356#
12357void
12358Remote(ref,...)
12359 Image::Magick ref=NO_INIT
12360 ALIAS:
12361 RemoteCommand = 1
12362 remote = 2
12363 remoteCommand = 3
12364 PPCODE:
12365 {
12366 AV
12367 *av;
12368
12369 ExceptionInfo
12370 *exception;
12371
12372 register long
12373 i;
12374
12375 SV
12376 *perl_exception,
12377 *reference;
12378
12379 struct PackageInfo
12380 *info;
12381
12382 exception=AcquireExceptionInfo();
12383 perl_exception=newSVpv("",0);
12384 reference=SvRV(ST(0));
12385 av=(AV *) reference;
12386 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12387 exception);
12388 for (i=1; i < items; i++)
12389 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
12390 SvPV(ST(i),na),exception);
12391 InheritPerlException(exception,perl_exception);
12392 exception=DestroyExceptionInfo(exception);
12393 SvREFCNT_dec(perl_exception); /* throw away all errors */
12394 }
12395
12396#
12397###############################################################################
12398# #
12399# #
12400# #
12401# S e t #
12402# #
12403# #
12404# #
12405###############################################################################
12406#
12407#
12408void
12409Set(ref,...)
12410 Image::Magick ref=NO_INIT
12411 ALIAS:
12412 SetAttributes = 1
12413 SetAttribute = 2
12414 set = 3
12415 setattributes = 4
12416 setattribute = 5
12417 PPCODE:
12418 {
12419 ExceptionInfo
12420 *exception;
12421
12422 Image
12423 *image;
12424
12425 register long
12426 i;
12427
12428 struct PackageInfo
12429 *info;
12430
12431 SV
12432 *perl_exception,
12433 *reference; /* reference is the SV* of ref=SvIV(reference) */
12434
12435 exception=AcquireExceptionInfo();
12436 perl_exception=newSVpv("",0);
12437 if (sv_isobject(ST(0)) == 0)
12438 {
12439 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12440 PackageName);
12441 goto PerlException;
12442 }
12443 reference=SvRV(ST(0));
12444 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12445 if (items == 2)
12446 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
12447 else
12448 for (i=2; i < items; i+=2)
12449 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
12450
12451 PerlException:
12452 InheritPerlException(exception,perl_exception);
12453 exception=DestroyExceptionInfo(exception);
12454 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
12455 SvPOK_on(perl_exception);
12456 ST(0)=sv_2mortal(perl_exception);
12457 XSRETURN(1);
12458 }
12459
12460#
12461###############################################################################
12462# #
12463# #
12464# #
12465# S e t P i x e l #
12466# #
12467# #
12468# #
12469###############################################################################
12470#
12471#
12472void
12473SetPixel(ref,...)
12474 Image::Magick ref=NO_INIT
12475 ALIAS:
12476 setpixel = 1
12477 setPixel = 2
12478 PPCODE:
12479 {
12480 AV
12481 *av;
12482
12483 char
12484 *attribute;
12485
12486 ChannelType
12487 channel;
12488
12489 ExceptionInfo
12490 *exception;
12491
12492 Image
12493 *image;
12494
12495 long
12496 option;
12497
12498 MagickBooleanType
12499 normalize;
12500
12501 RectangleInfo
12502 region;
12503
12504 register IndexPacket
12505 *indexes;
12506
12507 register long
12508 i;
12509
12510 register PixelPacket
12511 *q;
12512
12513 struct PackageInfo
12514 *info;
12515
12516 SV
12517 *perl_exception,
12518 *reference; /* reference is the SV* of ref=SvIV(reference) */
12519
12520 exception=AcquireExceptionInfo();
12521 perl_exception=newSVpv("",0);
12522 reference=SvRV(ST(0));
12523 av=(AV *) reference;
12524 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12525 exception);
12526 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12527 if (image == (Image *) NULL)
12528 {
12529 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12530 PackageName);
12531 goto PerlException;
12532 }
12533 av=(AV *) NULL;
12534 channel=DefaultChannels;
12535 normalize=MagickTrue;
12536 region.x=0;
12537 region.y=0;
12538 region.width=image->columns;
12539 region.height=1;
12540 if (items == 1)
12541 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
12542 for (i=2; i < items; i+=2)
12543 {
12544 attribute=(char *) SvPV(ST(i-1),na);
12545 switch (*attribute)
12546 {
12547 case 'C':
12548 case 'c':
12549 {
12550 if (LocaleCompare(attribute,"channel") == 0)
12551 {
12552 long
12553 option;
12554
12555 option=ParseChannelOption(SvPV(ST(i),na));
12556 if (option < 0)
12557 {
12558 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12559 SvPV(ST(i),na));
12560 return;
12561 }
12562 channel=(ChannelType) option;
12563 break;
12564 }
12565 if (LocaleCompare(attribute,"color") == 0)
12566 {
12567 if (SvTYPE(ST(i)) != SVt_RV)
12568 {
12569 char
12570 message[MaxTextExtent];
12571
12572 (void) FormatMagickString(message,MaxTextExtent,
12573 "invalid %.60s value",attribute);
12574 ThrowPerlException(exception,OptionError,message,
12575 SvPV(ST(i),na));
12576 }
12577 av=(AV *) SvRV(ST(i));
12578 break;
12579 }
12580 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12581 attribute);
12582 break;
12583 }
12584 case 'g':
12585 case 'G':
12586 {
12587 if (LocaleCompare(attribute,"geometry") == 0)
12588 {
12589 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
12590 break;
12591 }
12592 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12593 attribute);
12594 break;
12595 }
12596 case 'N':
12597 case 'n':
12598 {
12599 if (LocaleCompare(attribute,"normalize") == 0)
12600 {
12601 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
12602 SvPV(ST(i),na));
12603 if (option < 0)
12604 {
12605 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12606 SvPV(ST(i),na));
12607 break;
12608 }
12609 normalize=option != 0 ? MagickTrue : MagickFalse;
12610 break;
12611 }
12612 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12613 attribute);
12614 break;
12615 }
12616 case 'x':
12617 case 'X':
12618 {
12619 if (LocaleCompare(attribute,"x") == 0)
12620 {
12621 region.x=SvIV(ST(i));
12622 break;
12623 }
12624 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12625 attribute);
12626 break;
12627 }
12628 case 'y':
12629 case 'Y':
12630 {
12631 if (LocaleCompare(attribute,"y") == 0)
12632 {
12633 region.y=SvIV(ST(i));
12634 break;
12635 }
12636 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12637 attribute);
12638 break;
12639 }
12640 default:
12641 {
12642 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12643 attribute);
12644 break;
12645 }
12646 }
12647 }
12648 (void) SetImageStorageClass(image,DirectClass);
12649 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
12650 if ((q == (PixelPacket *) NULL) || (av == (AV *) NULL))
12651 PUSHs(&sv_undef);
12652 else
12653 {
12654 double
12655 scale;
12656
12657 register long
12658 i;
12659
12660 i=0;
12661 indexes=GetAuthenticIndexQueue(image);
12662 scale=1.0;
12663 if (normalize != MagickFalse)
12664 scale=QuantumRange;
12665 if (((channel & RedChannel) != 0) && (i <= av_len(av)))
12666 {
12667 q->red=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12668 i++;
12669 }
12670 if (((channel & GreenChannel) != 0) && (i <= av_len(av)))
12671 {
12672 q->green=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12673 i++;
12674 }
12675 if (((channel & BlueChannel) != 0) && (i <= av_len(av)))
12676 {
12677 q->blue=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12678 i++;
12679 }
12680 if ((((channel & IndexChannel) != 0) &&
12681 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
12682 {
12683 *indexes=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12684 i++;
12685 }
12686 if (((channel & OpacityChannel) != 0) && (i <= av_len(av)))
12687 {
12688 q->opacity=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12689 i++;
12690 }
12691 (void) SyncAuthenticPixels(image,exception);
12692 }
12693
12694 PerlException:
12695 InheritPerlException(exception,perl_exception);
12696 exception=DestroyExceptionInfo(exception);
12697 SvREFCNT_dec(perl_exception);
12698 }
12699
12700#
12701###############################################################################
12702# #
12703# #
12704# #
12705# S t a t i s t i c s #
12706# #
12707# #
12708# #
12709###############################################################################
12710#
12711#
12712void
12713Statistics(ref,...)
12714 Image::Magick ref=NO_INIT
12715 ALIAS:
12716 StatisticsImage = 1
12717 statistics = 2
12718 statisticsimage = 3
12719 PPCODE:
12720 {
12721 AV
12722 *av;
12723
12724 char
12725 message[MaxTextExtent];
12726
12727 ChannelStatistics
12728 *channel_statistics;
12729
12730 double
12731 scale;
12732
12733 ExceptionInfo
12734 *exception;
12735
12736 HV
12737 *hv;
12738
12739 Image
12740 *image;
12741
12742 ssize_t
12743 count;
12744
12745 struct PackageInfo
12746 *info;
12747
12748 SV
12749 *av_reference,
12750 *perl_exception,
12751 *reference;
12752
12753 exception=AcquireExceptionInfo();
12754 perl_exception=newSVpv("",0);
12755 av=NULL;
12756 if (sv_isobject(ST(0)) == 0)
12757 {
12758 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12759 PackageName);
12760 goto PerlException;
12761 }
12762 reference=SvRV(ST(0));
12763 hv=SvSTASH(reference);
12764 av=newAV();
12765 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12766 SvREFCNT_dec(av);
12767 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12768 if (image == (Image *) NULL)
12769 {
12770 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12771 PackageName);
12772 goto PerlException;
12773 }
12774 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12775 count=0;
12776 for ( ; image; image=image->next)
12777 {
12778 channel_statistics=GetImageChannelStatistics(image,&image->exception);
12779 if (channel_statistics == (ChannelStatistics *) NULL)
12780 continue;
12781 count++;
12782 EXTEND(sp,25*count);
12783 scale=(double) QuantumRange;
12784 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12785 channel_statistics[RedChannel].depth);
12786 PUSHs(sv_2mortal(newSVpv(message,0)));
12787 (void) FormatMagickString(message,MaxTextExtent,"%g",
12788 channel_statistics[RedChannel].minima/scale);
12789 PUSHs(sv_2mortal(newSVpv(message,0)));
12790 (void) FormatMagickString(message,MaxTextExtent,"%g",
12791 channel_statistics[RedChannel].maxima/scale);
12792 PUSHs(sv_2mortal(newSVpv(message,0)));
12793 (void) FormatMagickString(message,MaxTextExtent,"%g",
12794 channel_statistics[RedChannel].mean/scale);
12795 PUSHs(sv_2mortal(newSVpv(message,0)));
12796 (void) FormatMagickString(message,MaxTextExtent,"%g",
12797 channel_statistics[RedChannel].standard_deviation/scale);
12798 PUSHs(sv_2mortal(newSVpv(message,0)));
12799 (void) FormatMagickString(message,MaxTextExtent,"%g",
12800 channel_statistics[RedChannel].kurtosis);
12801 PUSHs(sv_2mortal(newSVpv(message,0)));
12802 (void) FormatMagickString(message,MaxTextExtent,"%g",
12803 channel_statistics[RedChannel].skewness);
12804 PUSHs(sv_2mortal(newSVpv(message,0)));
12805 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12806 channel_statistics[GreenChannel].depth);
12807 PUSHs(sv_2mortal(newSVpv(message,0)));
12808 (void) FormatMagickString(message,MaxTextExtent,"%g",
12809 channel_statistics[GreenChannel].minima/scale);
12810 PUSHs(sv_2mortal(newSVpv(message,0)));
12811 (void) FormatMagickString(message,MaxTextExtent,"%g",
12812 channel_statistics[GreenChannel].maxima/scale);
12813 PUSHs(sv_2mortal(newSVpv(message,0)));
12814 (void) FormatMagickString(message,MaxTextExtent,"%g",
12815 channel_statistics[GreenChannel].mean/scale);
12816 PUSHs(sv_2mortal(newSVpv(message,0)));
12817 (void) FormatMagickString(message,MaxTextExtent,"%g",
12818 channel_statistics[GreenChannel].standard_deviation/scale);
12819 PUSHs(sv_2mortal(newSVpv(message,0)));
12820 (void) FormatMagickString(message,MaxTextExtent,"%g",
12821 channel_statistics[GreenChannel].kurtosis);
12822 PUSHs(sv_2mortal(newSVpv(message,0)));
12823 (void) FormatMagickString(message,MaxTextExtent,"%g",
12824 channel_statistics[GreenChannel].skewness);
12825 PUSHs(sv_2mortal(newSVpv(message,0)));
12826 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12827 channel_statistics[BlueChannel].depth);
12828 PUSHs(sv_2mortal(newSVpv(message,0)));
12829 (void) FormatMagickString(message,MaxTextExtent,"%g",
12830 channel_statistics[BlueChannel].minima/scale);
12831 PUSHs(sv_2mortal(newSVpv(message,0)));
12832 (void) FormatMagickString(message,MaxTextExtent,"%g",
12833 channel_statistics[BlueChannel].maxima/scale);
12834 PUSHs(sv_2mortal(newSVpv(message,0)));
12835 (void) FormatMagickString(message,MaxTextExtent,"%g",
12836 channel_statistics[BlueChannel].mean/scale);
12837 PUSHs(sv_2mortal(newSVpv(message,0)));
12838 (void) FormatMagickString(message,MaxTextExtent,"%g",
12839 channel_statistics[BlueChannel].standard_deviation/scale);
12840 PUSHs(sv_2mortal(newSVpv(message,0)));
12841 (void) FormatMagickString(message,MaxTextExtent,"%g",
12842 channel_statistics[BlueChannel].kurtosis);
12843 PUSHs(sv_2mortal(newSVpv(message,0)));
12844 (void) FormatMagickString(message,MaxTextExtent,"%g",
12845 channel_statistics[BlueChannel].skewness);
12846 PUSHs(sv_2mortal(newSVpv(message,0)));
12847 if (image->colorspace == CMYKColorspace)
12848 {
12849 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12850 channel_statistics[BlackChannel].depth);
12851 PUSHs(sv_2mortal(newSVpv(message,0)));
12852 (void) FormatMagickString(message,MaxTextExtent,"%g",
12853 channel_statistics[BlackChannel].minima/scale);
12854 PUSHs(sv_2mortal(newSVpv(message,0)));
12855 (void) FormatMagickString(message,MaxTextExtent,"%g",
12856 channel_statistics[BlackChannel].maxima/scale);
12857 PUSHs(sv_2mortal(newSVpv(message,0)));
12858 (void) FormatMagickString(message,MaxTextExtent,"%g",
12859 channel_statistics[BlackChannel].mean/scale);
12860 PUSHs(sv_2mortal(newSVpv(message,0)));
12861 (void) FormatMagickString(message,MaxTextExtent,"%g",
12862 channel_statistics[BlackChannel].standard_deviation/scale);
12863 PUSHs(sv_2mortal(newSVpv(message,0)));
12864 (void) FormatMagickString(message,MaxTextExtent,"%g",
12865 channel_statistics[BlackChannel].kurtosis);
12866 PUSHs(sv_2mortal(newSVpv(message,0)));
12867 (void) FormatMagickString(message,MaxTextExtent,"%g",
12868 channel_statistics[BlackChannel].skewness);
12869 PUSHs(sv_2mortal(newSVpv(message,0)));
12870 }
12871 if (image->matte != MagickFalse)
12872 {
12873 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12874 channel_statistics[OpacityChannel].depth);
12875 PUSHs(sv_2mortal(newSVpv(message,0)));
12876 (void) FormatMagickString(message,MaxTextExtent,"%g",
12877 channel_statistics[OpacityChannel].minima/scale);
12878 PUSHs(sv_2mortal(newSVpv(message,0)));
12879 (void) FormatMagickString(message,MaxTextExtent,"%g",
12880 channel_statistics[OpacityChannel].maxima/scale);
12881 PUSHs(sv_2mortal(newSVpv(message,0)));
12882 (void) FormatMagickString(message,MaxTextExtent,"%g",
12883 channel_statistics[OpacityChannel].mean/scale);
12884 PUSHs(sv_2mortal(newSVpv(message,0)));
12885 (void) FormatMagickString(message,MaxTextExtent,"%g",
12886 channel_statistics[OpacityChannel].standard_deviation/scale);
12887 PUSHs(sv_2mortal(newSVpv(message,0)));
12888 (void) FormatMagickString(message,MaxTextExtent,"%g",
12889 channel_statistics[OpacityChannel].kurtosis);
12890 PUSHs(sv_2mortal(newSVpv(message,0)));
12891 (void) FormatMagickString(message,MaxTextExtent,"%g",
12892 channel_statistics[OpacityChannel].skewness);
12893 PUSHs(sv_2mortal(newSVpv(message,0)));
12894 }
12895 channel_statistics=(ChannelStatistics *)
12896 RelinquishMagickMemory(channel_statistics);
12897 }
12898
12899 PerlException:
12900 InheritPerlException(exception,perl_exception);
12901 exception=DestroyExceptionInfo(exception);
12902 SvREFCNT_dec(perl_exception);
12903 }
12904
12905#
12906###############################################################################
12907# #
12908# #
12909# #
12910# S y n c A u t h e n t i c P i x e l s #
12911# #
12912# #
12913# #
12914###############################################################################
12915#
12916#
12917void
12918SyncAuthenticPixels(ref,...)
12919 Image::Magick ref = NO_INIT
12920 ALIAS:
12921 Syncauthenticpixels = 1
12922 SyncImagePixels = 2
12923 syncimagepixels = 3
12924 CODE:
12925 {
12926 ExceptionInfo
12927 *exception;
12928
12929 Image
12930 *image;
12931
12932 MagickBooleanType
12933 status;
12934
12935 struct PackageInfo
12936 *info;
12937
12938 SV
12939 *perl_exception,
12940 *reference;
12941
12942 exception=AcquireExceptionInfo();
12943 perl_exception=newSVpv("",0);
12944
12945 if (sv_isobject(ST(0)) == 0)
12946 {
12947 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12948 PackageName);
12949 goto PerlException;
12950 }
12951
12952 reference=SvRV(ST(0));
12953 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12954 if (image == (Image *) NULL)
12955 {
12956 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12957 PackageName);
12958 goto PerlException;
12959 }
12960
12961 status=SyncAuthenticPixels(image,exception);
12962 if (status != MagickFalse)
12963 return;
12964 InheritException(exception,&image->exception);
12965
12966 PerlException:
12967 InheritPerlException(exception,perl_exception);
12968 exception=DestroyExceptionInfo(exception);
12969 SvREFCNT_dec(perl_exception); /* throw away all errors */
12970 }
12971
12972#
12973###############################################################################
12974# #
12975# #
12976# #
12977# T r a n s f o r m #
12978# #
12979# #
12980# #
12981###############################################################################
12982#
12983#
12984void
12985Transform(ref,...)
12986 Image::Magick ref=NO_INIT
12987 ALIAS:
12988 TransformImage = 1
12989 transform = 2
12990 transformimage = 3
12991 PPCODE:
12992 {
12993 AV
12994 *av;
12995
12996 char
12997 *attribute,
12998 *crop_geometry,
12999 *geometry;
13000
13001 ExceptionInfo
13002 *exception;
13003
13004 HV
13005 *hv;
13006
13007 Image
13008 *clone,
13009 *image;
13010
13011 register long
13012 i;
13013
13014 struct PackageInfo
13015 *info;
13016
13017 SV
13018 *av_reference,
13019 *perl_exception,
13020 *reference,
13021 *rv,
13022 *sv;
13023
13024 exception=AcquireExceptionInfo();
13025 perl_exception=newSVpv("",0);
13026 av=NULL;
13027 attribute=NULL;
13028 if (sv_isobject(ST(0)) == 0)
13029 {
13030 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13031 PackageName);
13032 goto PerlException;
13033 }
13034 reference=SvRV(ST(0));
13035 hv=SvSTASH(reference);
13036 av=newAV();
13037 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
13038 SvREFCNT_dec(av);
13039 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13040 if (image == (Image *) NULL)
13041 {
13042 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13043 PackageName);
13044 goto PerlException;
13045 }
13046 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
13047 /*
13048 Get attribute.
13049 */
13050 crop_geometry=(char *) NULL;
13051 geometry=(char *) NULL;
13052 for (i=2; i < items; i+=2)
13053 {
13054 attribute=(char *) SvPV(ST(i-1),na);
13055 switch (*attribute)
13056 {
13057 case 'c':
13058 case 'C':
13059 {
13060 if (LocaleCompare(attribute,"crop") == 0)
13061 {
13062 crop_geometry=SvPV(ST(i),na);
13063 break;
13064 }
13065 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13066 attribute);
13067 break;
13068 }
13069 case 'g':
13070 case 'G':
13071 {
13072 if (LocaleCompare(attribute,"geometry") == 0)
13073 {
13074 geometry=SvPV(ST(i),na);
13075 break;
13076 }
13077 if (LocaleCompare(attribute,"gravity") == 0)
13078 {
13079 Image
13080 *next;
13081
13082 long
13083 in;
13084
13085 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
13086 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13087 if (in < 0)
13088 {
13089 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13090 SvPV(ST(i),na));
13091 return;
13092 }
13093 for (next=image; next; next=next->next)
13094 next->gravity=(GravityType) in;
13095 break;
13096 }
13097 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13098 attribute);
13099 break;
13100 }
13101 default:
13102 {
13103 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13104 attribute);
13105 break;
13106 }
13107 }
13108 }
13109 for ( ; image; image=image->next)
13110 {
13111 clone=CloneImage(image,0,0,MagickTrue,exception);
13112 if ((clone == (Image *) NULL) || (exception->severity >= ErrorException))
13113 goto PerlException;
13114 TransformImage(&clone,crop_geometry,geometry);
13115 for ( ; clone; clone=clone->next)
13116 {
13117 AddImageToRegistry(clone);
13118 rv=newRV(sv);
13119 av_push(av,sv_bless(rv,hv));
13120 SvREFCNT_dec(sv);
13121 }
13122 }
13123 exception=DestroyExceptionInfo(exception);
13124 ST(0)=av_reference;
13125 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13126 XSRETURN(1);
13127
13128 PerlException:
13129 InheritPerlException(exception,perl_exception);
13130 exception=DestroyExceptionInfo(exception);
13131 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
13132 SvPOK_on(perl_exception);
13133 ST(0)=sv_2mortal(perl_exception);
13134 XSRETURN(1);
13135 }
13136
13137#
13138###############################################################################
13139# #
13140# #
13141# #
13142# W r i t e #
13143# #
13144# #
13145# #
13146###############################################################################
13147#
13148#
13149void
13150Write(ref,...)
13151 Image::Magick ref=NO_INIT
13152 ALIAS:
13153 WriteImage = 1
13154 write = 2
13155 writeimage = 3
13156 PPCODE:
13157 {
13158 char
13159 filename[MaxTextExtent];
13160
13161 ExceptionInfo
13162 *exception;
13163
13164 Image
13165 *image,
13166 *next;
13167
13168 long
13169 number_images,
13170 scene;
13171
13172 register long
13173 i;
13174
13175 struct PackageInfo
13176 *info,
13177 *package_info;
13178
13179 SV
13180 *perl_exception,
13181 *reference;
13182
13183 exception=AcquireExceptionInfo();
13184 perl_exception=newSVpv("",0);
13185 number_images=0;
13186 package_info=(struct PackageInfo *) NULL;
13187 if (sv_isobject(ST(0)) == 0)
13188 {
13189 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13190 PackageName);
13191 goto PerlException;
13192 }
13193 reference=SvRV(ST(0));
13194 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13195 if (image == (Image *) NULL)
13196 {
13197 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13198 PackageName);
13199 goto PerlException;
13200 }
13201 package_info=ClonePackageInfo(info,exception);
13202 if (items == 2)
13203 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
13204 else
13205 if (items > 2)
13206 for (i=2; i < items; i+=2)
13207 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
13208 exception);
13209 (void) CopyMagickString(filename,package_info->image_info->filename,
13210 MaxTextExtent);
13211 scene=0;
13212 for (next=image; next; next=next->next)
13213 {
13214 (void) CopyMagickString(next->filename,filename,MaxTextExtent);
13215 next->scene=scene++;
13216 }
13217 SetImageInfo(package_info->image_info,MagickTrue,&image->exception);
13218 for (next=image; next; next=next->next)
13219 {
13220 (void) WriteImage(package_info->image_info,next);
13221 if (next->exception.severity >= ErrorException)
13222 InheritException(exception,&next->exception);
13223 GetImageException(next,exception);
13224 number_images++;
13225 if (package_info->image_info->adjoin)
13226 break;
13227 }
13228
13229 PerlException:
13230 if (package_info != (struct PackageInfo *) NULL)
13231 DestroyPackageInfo(package_info);
13232 InheritPerlException(exception,perl_exception);
13233 exception=DestroyExceptionInfo(exception);
13234 sv_setiv(perl_exception,(IV) number_images);
13235 SvPOK_on(perl_exception);
13236 ST(0)=sv_2mortal(perl_exception);
13237 XSRETURN(1);
13238 }