blob: a567bbd0cd348bcf53d908f9c1692258af6f3371 [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
82#define MaxArguments 31
83#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} } },
519 };
520
521static SplayTreeInfo
522 *magick_registry = (SplayTreeInfo *) NULL;
523
524/*
525 Forward declarations.
526*/
527static Image
528 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
529
530static long
531 strEQcase(const char *,const char *);
532
533/*
534%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
535% %
536% %
537% %
538% C l o n e P a c k a g e I n f o %
539% %
540% %
541% %
542%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
543%
544% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
545% a new one.
546%
547% The format of the ClonePackageInfo routine is:
548%
549% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
550% exception)
551%
552% A description of each parameter follows:
553%
554% o info: a structure of type info.
555%
556% o exception: Return any errors or warnings in this structure.
557%
558*/
559static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
560 ExceptionInfo *exception)
561{
562 struct PackageInfo
563 *clone_info;
564
565 clone_info=(struct PackageInfo *) AcquireMagickMemory(sizeof(*clone_info));
566 if (clone_info == (struct PackageInfo *) NULL)
567 {
568 ThrowPerlException(exception,ResourceLimitError,
569 "UnableToClonePackageInfo",PackageName);
570 return((struct PackageInfo *) NULL);
571 }
572 if (info == (struct PackageInfo *) NULL)
573 {
574 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
575 return(clone_info);
576 }
577 *clone_info=(*info);
578 clone_info->image_info=CloneImageInfo(info->image_info);
579 return(clone_info);
580}
581
582/*
583%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
584% %
585% %
586% %
587% c o n s t a n t %
588% %
589% %
590% %
591%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
592%
593% constant() returns a double value for the specified name.
594%
595% The format of the constant routine is:
596%
597% double constant(char *name,long sans)
598%
599% A description of each parameter follows:
600%
601% o value: Method constant returns a double value for the specified name.
602%
603% o name: The name of the constant.
604%
605% o sans: This integer value is not used.
606%
607*/
608static double constant(char *name,long sans)
609{
610 (void) sans;
611 errno=0;
612 switch (*name)
613 {
614 case 'B':
615 {
616 if (strEQ(name,"BlobError"))
617 return(BlobError);
618 if (strEQ(name,"BlobWarning"))
619 return(BlobWarning);
620 break;
621 }
622 case 'C':
623 {
624 if (strEQ(name,"CacheError"))
625 return(CacheError);
626 if (strEQ(name,"CacheWarning"))
627 return(CacheWarning);
628 if (strEQ(name,"CoderError"))
629 return(CoderError);
630 if (strEQ(name,"CoderWarning"))
631 return(CoderWarning);
632 if (strEQ(name,"ConfigureError"))
633 return(ConfigureError);
634 if (strEQ(name,"ConfigureWarning"))
635 return(ConfigureWarning);
636 if (strEQ(name,"CorruptImageError"))
637 return(CorruptImageError);
638 if (strEQ(name,"CorruptImageWarning"))
639 return(CorruptImageWarning);
640 break;
641 }
642 case 'D':
643 {
644 if (strEQ(name,"DelegateError"))
645 return(DelegateError);
646 if (strEQ(name,"DelegateWarning"))
647 return(DelegateWarning);
648 if (strEQ(name,"DrawError"))
649 return(DrawError);
650 if (strEQ(name,"DrawWarning"))
651 return(DrawWarning);
652 break;
653 }
654 case 'E':
655 {
656 if (strEQ(name,"ErrorException"))
657 return(ErrorException);
658 if (strEQ(name,"ExceptionError"))
659 return(CoderError);
660 if (strEQ(name,"ExceptionWarning"))
661 return(CoderWarning);
662 break;
663 }
664 case 'F':
665 {
666 if (strEQ(name,"FatalErrorException"))
667 return(FatalErrorException);
668 if (strEQ(name,"FileOpenError"))
669 return(FileOpenError);
670 if (strEQ(name,"FileOpenWarning"))
671 return(FileOpenWarning);
672 break;
673 }
674 case 'I':
675 {
676 if (strEQ(name,"ImageError"))
677 return(ImageError);
678 if (strEQ(name,"ImageWarning"))
679 return(ImageWarning);
680 break;
681 }
682 case 'M':
683 {
684 if (strEQ(name,"MaxRGB"))
685 return(QuantumRange);
686 if (strEQ(name,"MissingDelegateError"))
687 return(MissingDelegateError);
688 if (strEQ(name,"MissingDelegateWarning"))
689 return(MissingDelegateWarning);
690 if (strEQ(name,"ModuleError"))
691 return(ModuleError);
692 if (strEQ(name,"ModuleWarning"))
693 return(ModuleWarning);
694 break;
695 }
696 case 'O':
697 {
698 if (strEQ(name,"Opaque"))
699 return(OpaqueOpacity);
700 if (strEQ(name,"OptionError"))
701 return(OptionError);
702 if (strEQ(name,"OptionWarning"))
703 return(OptionWarning);
704 break;
705 }
706 case 'Q':
707 {
708 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
709 return(MAGICKCORE_QUANTUM_DEPTH);
710 if (strEQ(name,"QuantumDepth"))
711 return(QuantumDepth);
712 if (strEQ(name,"QuantumRange"))
713 return(QuantumRange);
714 break;
715 }
716 case 'R':
717 {
718 if (strEQ(name,"ResourceLimitError"))
719 return(ResourceLimitError);
720 if (strEQ(name,"ResourceLimitWarning"))
721 return(ResourceLimitWarning);
722 if (strEQ(name,"RegistryError"))
723 return(RegistryError);
724 if (strEQ(name,"RegistryWarning"))
725 return(RegistryWarning);
726 break;
727 }
728 case 'S':
729 {
730 if (strEQ(name,"StreamError"))
731 return(StreamError);
732 if (strEQ(name,"StreamWarning"))
733 return(StreamWarning);
734 if (strEQ(name,"Success"))
735 return(0);
736 break;
737 }
738 case 'T':
739 {
740 if (strEQ(name,"Transparent"))
741 return(TransparentOpacity);
742 if (strEQ(name,"TypeError"))
743 return(TypeError);
744 if (strEQ(name,"TypeWarning"))
745 return(TypeWarning);
746 break;
747 }
748 case 'W':
749 {
750 if (strEQ(name,"WarningException"))
751 return(WarningException);
752 break;
753 }
754 case 'X':
755 {
756 if (strEQ(name,"XServerError"))
757 return(XServerError);
758 if (strEQ(name,"XServerWarning"))
759 return(XServerWarning);
760 break;
761 }
762 }
763 errno=EINVAL;
764 return(0);
765}
766
767/*
768%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
769% %
770% %
771% %
772% D e s t r o y P a c k a g e I n f o %
773% %
774% %
775% %
776%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
777%
778% Method DestroyPackageInfo frees a previously created info structure.
779%
780% The format of the DestroyPackageInfo routine is:
781%
782% DestroyPackageInfo(struct PackageInfo *info)
783%
784% A description of each parameter follows:
785%
786% o info: a structure of type info.
787%
788*/
789static void DestroyPackageInfo(struct PackageInfo *info)
790{
791 info->image_info=DestroyImageInfo(info->image_info);
792 info=(struct PackageInfo *) RelinquishMagickMemory(info);
793}
794
795/*
796%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
797% %
798% %
799% %
800% G e t L i s t %
801% %
802% %
803% %
804%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
805%
806% Method GetList is recursively called by SetupList to traverse the
807% Image__Magick reference. If building an reference_vector (see SetupList),
808% *current is the current position in *reference_vector and *last is the final
809% entry in *reference_vector.
810%
811% The format of the GetList routine is:
812%
813% GetList(info)
814%
815% A description of each parameter follows:
816%
817% o info: a structure of type info.
818%
819*/
820static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,long *current,
821 long *last,ExceptionInfo *exception)
822{
823 Image
824 *image;
825
826 if (reference == (SV *) NULL)
827 return(NULL);
828 switch (SvTYPE(reference))
829 {
830 case SVt_PVAV:
831 {
832 AV
833 *av;
834
835 Image
836 *head,
837 *previous;
838
839 long
840 n;
841
842 register long
843 i;
844
845 /*
846 Array of images.
847 */
848 previous=(Image *) NULL;
849 head=(Image *) NULL;
850 av=(AV *) reference;
851 n=av_len(av);
852 for (i=0; i <= n; i++)
853 {
854 SV
855 **rv;
856
857 rv=av_fetch(av,i,0);
858 if (rv && *rv && sv_isobject(*rv))
859 {
860 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
861 exception);
862 if (image == (Image *) NULL)
863 continue;
864 if (image == previous)
865 {
866 image=CloneImage(image,0,0,MagickTrue,exception);
867 if (image == (Image *) NULL)
868 return(NULL);
869 }
870 image->previous=previous;
871 *(previous ? &previous->next : &head)=image;
872 for (previous=image; previous->next; previous=previous->next) ;
873 }
874 }
875 return(head);
876 }
877 case SVt_PVMG:
878 {
879 /*
880 Blessed scalar, one image.
881 */
882 image=(Image *) SvIV(reference);
883 if (image == (Image *) NULL)
884 return(NULL);
885 image->previous=(Image *) NULL;
886 image->next=(Image *) NULL;
887 if (reference_vector)
888 {
889 if (*current == *last)
890 {
891 *last+=256;
892 if (*reference_vector == (SV **) NULL)
893 *reference_vector=(SV **) AcquireQuantumMemory(*last,
894 sizeof(*reference_vector));
895 else
896 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
897 *last,sizeof(*reference_vector));
898 }
899 if (*reference_vector == (SV **) NULL)
900 {
901 ThrowPerlException(exception,ResourceLimitError,
902 "MemoryAllocationFailed",PackageName);
903 return((Image *) NULL);
904 }
905 (*reference_vector)[*current]=reference;
906 (*reference_vector)[++(*current)]=NULL;
907 }
908 return(image);
909 }
910 default:
911 break;
912 }
913 (void) fprintf(stderr,"GetList: UnrecognizedType %ld\n",
914 (long) SvTYPE(reference));
915 return((Image *) NULL);
916}
917
918/*
919%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
920% %
921% %
922% %
923% G e t P a c k a g e I n f o %
924% %
925% %
926% %
927%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
928%
929% Method GetPackageInfo looks up or creates an info structure for the given
930% Image__Magick reference. If it does create a new one, the information in
931% package_info is used to initialize it.
932%
933% The format of the GetPackageInfo routine is:
934%
935% struct PackageInfo *GetPackageInfo(void *reference,
936% struct PackageInfo *package_info,ExceptionInfo *exception)
937%
938% A description of each parameter follows:
939%
940% o info: a structure of type info.
941%
942% o exception: Return any errors or warnings in this structure.
943%
944*/
945static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
946 struct PackageInfo *package_info,ExceptionInfo *exception)
947{
948 char
949 message[MaxTextExtent];
950
951 struct PackageInfo
952 *clone_info;
953
954 SV
955 *sv;
956
957 (void) FormatMagickString(message,MaxTextExtent,"%s::package%s%lx",
958 PackageName,XS_VERSION,(long) reference);
959 sv=perl_get_sv(message,(TRUE | 0x02));
960 if (sv == (SV *) NULL)
961 {
962 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
963 message);
964 return(package_info);
965 }
966 if (SvREFCNT(sv) == 0)
967 (void) SvREFCNT_inc(sv);
968 if (SvIOKp(sv) && (clone_info=(struct PackageInfo *) SvIV(sv)))
969 return(clone_info);
970 clone_info=ClonePackageInfo(package_info,exception);
971 sv_setiv(sv,(IV) clone_info);
972 return(clone_info);
973}
974
975/*
976%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
977% %
978% %
979% %
980% S e t A t t r i b u t e %
981% %
982% %
983% %
984%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
985%
986% SetAttribute() sets the attribute to the value in sval. This can change
987% either or both of image or info.
988%
989% The format of the SetAttribute routine is:
990%
991% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
992% SV *sval,ExceptionInfo *exception)
993%
994% A description of each parameter follows:
995%
996% o list: a list of strings.
997%
998% o string: a character string.
999%
1000*/
1001static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1002 const char *attribute,SV *sval,ExceptionInfo *exception)
1003{
1004 GeometryInfo
1005 geometry_info;
1006
1007 long
1008 sp;
1009
1010 long
1011 x,
1012 y;
1013
1014 MagickPixelPacket
1015 pixel;
1016
1017 MagickStatusType
1018 flags;
1019
1020 PixelPacket
1021 *color,
1022 target_color;
1023
1024 switch (*attribute)
1025 {
1026 case 'A':
1027 case 'a':
1028 {
1029 if (LocaleCompare(attribute,"adjoin") == 0)
1030 {
1031 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1032 SvPV(sval,na)) : SvIV(sval);
1033 if (sp < 0)
1034 {
1035 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1036 SvPV(sval,na));
1037 break;
1038 }
1039 if (info)
1040 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1041 break;
1042 }
1043 if (LocaleCompare(attribute,"alpha") == 0)
1044 {
1045 sp=SvPOK(sval) ? ParseMagickOption(MagickAlphaOptions,MagickFalse,
1046 SvPV(sval,na)) : SvIV(sval);
1047 if (sp < 0)
1048 {
1049 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1050 SvPV(sval,na));
1051 break;
1052 }
1053 for ( ; image; image=image->next)
1054 (void) SetImageAlphaChannel(image,(AlphaChannelType) sp);
1055 break;
1056 }
1057 if (LocaleCompare(attribute,"antialias") == 0)
1058 {
1059 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1060 SvPV(sval,na)) : SvIV(sval);
1061 if (sp < 0)
1062 {
1063 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1064 SvPV(sval,na));
1065 break;
1066 }
1067 if (info)
1068 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1069 break;
1070 }
1071 if (LocaleCompare(attribute,"area-limit") == 0)
1072 {
1073 MagickSizeType
1074 limit;
1075
1076 limit=MagickResourceInfinity;
1077 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1078 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1079 (void) SetMagickResourceLimit(AreaResource,limit);
1080 break;
1081 }
1082 if (LocaleCompare(attribute,"attenuate") == 0)
1083 {
1084 if (info)
1085 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1086 break;
1087 }
1088 if (LocaleCompare(attribute,"authenticate") == 0)
1089 {
1090 if (info)
1091 (void) CloneString(&info->image_info->authenticate,SvPV(sval,na));
1092 break;
1093 }
1094 if (info)
1095 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1096 for ( ; image; image=image->next)
1097 SetImageProperty(image,attribute,SvPV(sval,na));
1098 break;
1099 }
1100 case 'B':
1101 case 'b':
1102 {
1103 if (LocaleCompare(attribute,"background") == 0)
1104 {
1105 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
1106 if (info)
1107 info->image_info->background_color=target_color;
1108 for ( ; image; image=image->next)
1109 image->background_color=target_color;
1110 break;
1111 }
1112 if (LocaleCompare(attribute,"bias") == 0)
1113 {
1114 for ( ; image; image=image->next)
1115 image->bias=StringToDouble(SvPV(sval,na),QuantumRange);
1116 break;
1117 }
1118 if (LocaleCompare(attribute,"blue-primary") == 0)
1119 {
1120 for ( ; image; image=image->next)
1121 {
1122 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1123 image->chromaticity.blue_primary.x=geometry_info.rho;
1124 image->chromaticity.blue_primary.y=geometry_info.sigma;
1125 if ((flags & SigmaValue) == 0)
1126 image->chromaticity.blue_primary.y=
1127 image->chromaticity.blue_primary.x;
1128 }
1129 break;
1130 }
1131 if (LocaleCompare(attribute,"bordercolor") == 0)
1132 {
1133 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
1134 if (info)
1135 info->image_info->border_color=target_color;
1136 for ( ; image; image=image->next)
1137 image->border_color=target_color;
1138 break;
1139 }
1140 if (info)
1141 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1142 for ( ; image; image=image->next)
1143 SetImageProperty(image,attribute,SvPV(sval,na));
1144 break;
1145 }
1146 case 'C':
1147 case 'c':
1148 {
1149 if (LocaleCompare(attribute,"cache-threshold") == 0)
1150 {
1151 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1152 StringToDouble(SvPV(sval,na),100.0));
1153 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1154 (2*StringToDouble(SvPV(sval,na),100.0)));
1155 break;
1156 }
1157 if (LocaleCompare(attribute,"clip-mask") == 0)
1158 {
1159 Image
1160 *clip_mask;
1161
1162 clip_mask=(Image *) NULL;
1163 if (SvPOK(sval))
1164 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1165 for ( ; image; image=image->next)
1166 SetImageClipMask(image,clip_mask);
1167 break;
1168 }
1169 if (LocaleNCompare(attribute,"colormap",8) == 0)
1170 {
1171 for ( ; image; image=image->next)
1172 {
1173 int
1174 items;
1175
1176 long
1177 i;
1178
1179 if (image->storage_class == DirectClass)
1180 continue;
1181 i=0;
1182 items=sscanf(attribute,"%*[^[][%ld",&i);
1183 if (i > (long) image->colors)
1184 i%=image->colors;
1185 if ((strchr(SvPV(sval,na),',') == 0) ||
1186 (strchr(SvPV(sval,na),')') != 0))
1187 QueryColorDatabase(SvPV(sval,na),image->colormap+i,exception);
1188 else
1189 {
1190 color=image->colormap+i;
1191 pixel.red=color->red;
1192 pixel.green=color->green;
1193 pixel.blue=color->blue;
1194 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1195 pixel.red=geometry_info.rho;
1196 pixel.green=geometry_info.sigma;
1197 pixel.blue=geometry_info.xi;
1198 color->red=RoundToQuantum(pixel.red);
1199 color->green=RoundToQuantum(pixel.green);
1200 color->blue=RoundToQuantum(pixel.blue);
1201 }
1202 }
1203 break;
1204 }
1205 if (LocaleCompare(attribute,"colorspace") == 0)
1206 {
1207 sp=SvPOK(sval) ? ParseMagickOption(MagickColorspaceOptions,
1208 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1209 if (sp < 0)
1210 {
1211 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1212 SvPV(sval,na));
1213 break;
1214 }
1215 for ( ; image; image=image->next)
1216 (void) TransformImageColorspace(image,(ColorspaceType) sp);
1217 break;
1218 }
1219 if (LocaleCompare(attribute,"comment") == 0)
1220 {
1221 for ( ; image; image=image->next)
1222 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1223 info ? info->image_info : (ImageInfo *) NULL,image,
1224 SvPV(sval,na)));
1225 break;
1226 }
1227 if (LocaleCompare(attribute,"compression") == 0)
1228 {
1229 sp=SvPOK(sval) ? ParseMagickOption(MagickCompressOptions,
1230 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1231 if (sp < 0)
1232 {
1233 ThrowPerlException(exception,OptionError,
1234 "UnrecognizedImageCompression",SvPV(sval,na));
1235 break;
1236 }
1237 if (info)
1238 info->image_info->compression=(CompressionType) sp;
1239 for ( ; image; image=image->next)
1240 image->compression=(CompressionType) sp;
1241 break;
1242 }
1243 if (info)
1244 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1245 for ( ; image; image=image->next)
1246 SetImageProperty(image,attribute,SvPV(sval,na));
1247 break;
1248 }
1249 case 'D':
1250 case 'd':
1251 {
1252 if (LocaleCompare(attribute,"debug") == 0)
1253 {
1254 SetLogEventMask(SvPV(sval,na));
1255 break;
1256 }
1257 if (LocaleCompare(attribute,"delay") == 0)
1258 {
1259 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1260 for ( ; image; image=image->next)
1261 {
1262 image->delay=(unsigned long) (geometry_info.rho+0.5);
1263 if ((flags & SigmaValue) != 0)
1264 image->ticks_per_second=(unsigned long) (geometry_info.sigma+0.5);
1265 }
1266 break;
1267 }
1268 if (LocaleCompare(attribute,"disk-limit") == 0)
1269 {
1270 MagickSizeType
1271 limit;
1272
1273 limit=MagickResourceInfinity;
1274 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1275 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1276 (void) SetMagickResourceLimit(DiskResource,limit);
1277 break;
1278 }
1279 if (LocaleCompare(attribute,"density") == 0)
1280 {
1281 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1282 {
1283 ThrowPerlException(exception,OptionError,"MissingGeometry",
1284 SvPV(sval,na));
1285 break;
1286 }
1287 if (info)
1288 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1289 for ( ; image; image=image->next)
1290 {
1291 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1292 image->x_resolution=geometry_info.rho;
1293 image->y_resolution=geometry_info.sigma;
1294 if ((flags & SigmaValue) == 0)
1295 image->y_resolution=image->x_resolution;
1296 }
1297 break;
1298 }
1299 if (LocaleCompare(attribute,"depth") == 0)
1300 {
1301 if (info)
1302 info->image_info->depth=SvIV(sval);
1303 for ( ; image; image=image->next)
1304 (void) SetImageDepth(image,SvIV(sval));
1305 break;
1306 }
1307 if (LocaleCompare(attribute,"dispose") == 0)
1308 {
1309 sp=SvPOK(sval) ? ParseMagickOption(MagickDisposeOptions,MagickFalse,
1310 SvPV(sval,na)) : SvIV(sval);
1311 if (sp < 0)
1312 {
1313 ThrowPerlException(exception,OptionError,
1314 "UnrecognizedDisposeMethod",SvPV(sval,na));
1315 break;
1316 }
1317 for ( ; image; image=image->next)
1318 image->dispose=(DisposeType) sp;
1319 break;
1320 }
1321 if (LocaleCompare(attribute,"dither") == 0)
1322 {
1323 if (info)
1324 {
1325 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,
1326 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1327 if (sp < 0)
1328 {
1329 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1330 SvPV(sval,na));
1331 break;
1332 }
1333 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1334 }
1335 break;
1336 }
1337 if (LocaleCompare(attribute,"display") == 0)
1338 {
1339 display:
1340 if (info)
1341 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1342 break;
1343 }
1344 if (info)
1345 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1346 for ( ; image; image=image->next)
1347 SetImageProperty(image,attribute,SvPV(sval,na));
1348 break;
1349 }
1350 case 'E':
1351 case 'e':
1352 {
1353 if (LocaleCompare(attribute,"endian") == 0)
1354 {
1355 sp=SvPOK(sval) ? ParseMagickOption(MagickEndianOptions,MagickFalse,
1356 SvPV(sval,na)) : SvIV(sval);
1357 if (sp < 0)
1358 {
1359 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1360 SvPV(sval,na));
1361 break;
1362 }
1363 if (info)
1364 info->image_info->endian=(EndianType) sp;
1365 for ( ; image; image=image->next)
1366 image->endian=(EndianType) sp;
1367 break;
1368 }
1369 if (LocaleCompare(attribute,"extract") == 0)
1370 {
1371 /*
1372 Set image extract geometry.
1373 */
1374 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1375 break;
1376 }
1377 if (info)
1378 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1379 for ( ; image; image=image->next)
1380 SetImageProperty(image,attribute,SvPV(sval,na));
1381 break;
1382 }
1383 case 'F':
1384 case 'f':
1385 {
1386 if (LocaleCompare(attribute,"filename") == 0)
1387 {
1388 if (info)
1389 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
1390 MaxTextExtent);
1391 for ( ; image; image=image->next)
1392 (void) CopyMagickString(image->filename,SvPV(sval,na),
1393 MaxTextExtent);
1394 break;
1395 }
1396 if (LocaleCompare(attribute,"file") == 0)
1397 {
1398 FILE
1399 *file;
1400
1401 PerlIO
1402 *io_info;
1403
1404 if (info == (struct PackageInfo *) NULL)
1405 break;
1406 io_info=IoIFP(sv_2io(sval));
1407 if (io_info == (PerlIO *) NULL)
1408 {
1409 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1410 PackageName);
1411 break;
1412 }
1413 file=PerlIO_findFILE(io_info);
1414 if (file == (FILE *) NULL)
1415 {
1416 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1417 PackageName);
1418 break;
1419 }
1420 SetImageInfoFile(info->image_info,file);
1421 break;
1422 }
1423 if (LocaleCompare(attribute,"fill") == 0)
1424 {
1425 if (info)
1426 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1427 break;
1428 }
1429 if (LocaleCompare(attribute,"font") == 0)
1430 {
1431 if (info)
1432 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1433 break;
1434 }
1435 if (LocaleCompare(attribute,"foreground") == 0)
1436 break;
1437 if (LocaleCompare(attribute,"fuzz") == 0)
1438 {
1439 if (info)
1440 info->image_info->fuzz=StringToDouble(SvPV(sval,na),QuantumRange);
1441 for ( ; image; image=image->next)
1442 image->fuzz=StringToDouble(SvPV(sval,na),QuantumRange);
1443 break;
1444 }
1445 if (info)
1446 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1447 for ( ; image; image=image->next)
1448 SetImageProperty(image,attribute,SvPV(sval,na));
1449 break;
1450 }
1451 case 'G':
1452 case 'g':
1453 {
1454 if (LocaleCompare(attribute,"gamma") == 0)
1455 {
1456 for ( ; image; image=image->next)
1457 image->gamma=SvNV(sval);
1458 break;
1459 }
1460 if (LocaleCompare(attribute,"gravity") == 0)
1461 {
1462 sp=SvPOK(sval) ? ParseMagickOption(MagickGravityOptions,MagickFalse,
1463 SvPV(sval,na)) : SvIV(sval);
1464 if (sp < 0)
1465 {
1466 ThrowPerlException(exception,OptionError,
1467 "UnrecognizedGravityType",SvPV(sval,na));
1468 break;
1469 }
1470 for ( ; image; image=image->next)
1471 image->gravity=(GravityType) sp;
1472 break;
1473 }
1474 if (LocaleCompare(attribute,"green-primary") == 0)
1475 {
1476 for ( ; image; image=image->next)
1477 {
1478 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1479 image->chromaticity.green_primary.x=geometry_info.rho;
1480 image->chromaticity.green_primary.y=geometry_info.sigma;
1481 if ((flags & SigmaValue) == 0)
1482 image->chromaticity.green_primary.y=
1483 image->chromaticity.green_primary.x;
1484 }
1485 break;
1486 }
1487 if (info)
1488 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1489 for ( ; image; image=image->next)
1490 SetImageProperty(image,attribute,SvPV(sval,na));
1491 break;
1492 }
1493 case 'I':
1494 case 'i':
1495 {
1496 if (LocaleNCompare(attribute,"index",5) == 0)
1497 {
1498 IndexPacket
1499 *indexes;
1500
1501 int
1502 items;
1503
1504 long
1505 index;
1506
1507 register PixelPacket
1508 *p;
1509
1510 CacheView
1511 *image_view;
1512
1513 for ( ; image; image=image->next)
1514 {
1515 if (image->storage_class != PseudoClass)
1516 continue;
1517 x=0;
1518 y=0;
1519 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1520 image_view=OpenCacheView(image);
1521 p=GetCacheViewPixels(image_view,x,y,1,1);
1522 if (p != (PixelPacket *) NULL)
1523 {
1524 indexes=GetCacheViewIndexes(image_view);
1525 items=sscanf(SvPV(sval,na),"%ld",&index);
1526 if ((index >= 0) && (index < (long) image->colors))
1527 *indexes=(IndexPacket) index;
1528 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1529 }
1530 image_view=CloseCacheView(image_view);
1531 }
1532 break;
1533 }
1534 if (LocaleCompare(attribute,"iterations") == 0)
1535 {
1536 iterations:
1537 for ( ; image; image=image->next)
1538 image->iterations=SvIV(sval);
1539 break;
1540 }
1541 if (LocaleCompare(attribute,"interlace") == 0)
1542 {
1543 sp=SvPOK(sval) ? ParseMagickOption(MagickInterlaceOptions,MagickFalse,
1544 SvPV(sval,na)) : SvIV(sval);
1545 if (sp < 0)
1546 {
1547 ThrowPerlException(exception,OptionError,
1548 "UnrecognizedInterlaceType",SvPV(sval,na));
1549 break;
1550 }
1551 if (info)
1552 info->image_info->interlace=(InterlaceType) sp;
1553 for ( ; image; image=image->next)
1554 image->interlace=(InterlaceType) sp;
1555 break;
1556 }
1557 if (info)
1558 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1559 for ( ; image; image=image->next)
1560 SetImageProperty(image,attribute,SvPV(sval,na));
1561 break;
1562 }
1563 case 'L':
1564 case 'l':
1565 {
1566 if (LocaleCompare(attribute,"label") == 0)
1567 {
1568 for ( ; image; image=image->next)
1569 (void) SetImageProperty(image,"label",InterpretImageProperties(
1570 info ? info->image_info : (ImageInfo *) NULL,image,
1571 SvPV(sval,na)));
1572 break;
1573 }
1574 if (LocaleCompare(attribute,"loop") == 0)
1575 goto iterations;
1576 if (info)
1577 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1578 for ( ; image; image=image->next)
1579 SetImageProperty(image,attribute,SvPV(sval,na));
1580 break;
1581 }
1582 case 'M':
1583 case 'm':
1584 {
1585 if (LocaleCompare(attribute,"magick") == 0)
1586 {
1587 if (info)
1588 (void) FormatMagickString(info->image_info->filename,MaxTextExtent,
1589 "%.1024s:",SvPV(sval,na));
1590 for ( ; image; image=image->next)
1591 (void) CopyMagickString(image->magick,SvPV(sval,na),MaxTextExtent);
1592 break;
1593 }
1594 if (LocaleCompare(attribute,"map-limit") == 0)
1595 {
1596 MagickSizeType
1597 limit;
1598
1599 limit=MagickResourceInfinity;
1600 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1601 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1602 (void) SetMagickResourceLimit(MapResource,limit);
1603 break;
1604 }
1605 if (LocaleCompare(attribute,"mask") == 0)
1606 {
1607 Image
1608 *mask;
1609
1610 mask=(Image *) NULL;
1611 if (SvPOK(sval))
1612 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1613 for ( ; image; image=image->next)
1614 SetImageMask(image,mask);
1615 break;
1616 }
1617 if (LocaleCompare(attribute,"mattecolor") == 0)
1618 {
1619 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
1620 if (info)
1621 info->image_info->matte_color=target_color;
1622 for ( ; image; image=image->next)
1623 image->matte_color=target_color;
1624 break;
1625 }
1626 if (LocaleCompare(attribute,"matte") == 0)
1627 {
1628 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1629 SvPV(sval,na)) : SvIV(sval);
1630 if (sp < 0)
1631 {
1632 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1633 SvPV(sval,na));
1634 break;
1635 }
1636 for ( ; image; image=image->next)
1637 image->matte=sp != 0 ? MagickTrue : MagickFalse;
1638 break;
1639 }
1640 if (LocaleCompare(attribute,"memory-limit") == 0)
1641 {
1642 MagickSizeType
1643 limit;
1644
1645 limit=MagickResourceInfinity;
1646 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1647 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1648 (void) SetMagickResourceLimit(MemoryResource,limit);
1649 break;
1650 }
1651 if (LocaleCompare(attribute,"monochrome") == 0)
1652 {
1653 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1654 SvPV(sval,na)) : SvIV(sval);
1655 if (sp < 0)
1656 {
1657 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1658 SvPV(sval,na));
1659 break;
1660 }
1661 if (info)
1662 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1663 for ( ; image; image=image->next)
1664 (void) SetImageType(image,BilevelType);
1665 break;
1666 }
1667 if (info)
1668 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1669 for ( ; image; image=image->next)
1670 SetImageProperty(image,attribute,SvPV(sval,na));
1671 break;
1672 }
1673 case 'O':
1674 case 'o':
1675 {
1676 if (LocaleCompare(attribute,"option") == 0)
1677 {
1678 if (info)
1679 DefineImageOption(info->image_info,SvPV(sval,na));
1680 break;
1681 }
1682 if (LocaleCompare(attribute,"orientation") == 0)
1683 {
1684 sp=SvPOK(sval) ? ParseMagickOption(MagickOrientationOptions,
1685 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1686 if (sp < 0)
1687 {
1688 ThrowPerlException(exception,OptionError,
1689 "UnrecognizedOrientationType",SvPV(sval,na));
1690 break;
1691 }
1692 if (info)
1693 info->image_info->orientation=(OrientationType) sp;
1694 for ( ; image; image=image->next)
1695 image->orientation=(OrientationType) sp;
1696 break;
1697 }
1698 if (info)
1699 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1700 for ( ; image; image=image->next)
1701 SetImageProperty(image,attribute,SvPV(sval,na));
1702 break;
1703 }
1704 case 'P':
1705 case 'p':
1706 {
1707 if (LocaleCompare(attribute,"page") == 0)
1708 {
1709 char
1710 *geometry;
1711
1712 geometry=GetPageGeometry(SvPV(sval,na));
1713 if (info)
1714 (void) CloneString(&info->image_info->page,geometry);
1715 for ( ; image; image=image->next)
1716 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1717 geometry=(char *) RelinquishMagickMemory(geometry);
1718 break;
1719 }
1720 if (LocaleCompare(attribute,"pen") == 0)
1721 {
1722 if (info)
1723 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1724 break;
1725 }
1726 if (LocaleNCompare(attribute,"pixel",5) == 0)
1727 {
1728 int
1729 items;
1730
1731 MagickPixelPacket
1732 pixel;
1733
1734 register IndexPacket
1735 *indexes;
1736
1737 register PixelPacket
1738 *p;
1739
1740 CacheView
1741 *image_view;
1742
1743 for ( ; image; image=image->next)
1744 {
1745 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1746 break;
1747 x=0;
1748 y=0;
1749 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1750 image_view=OpenCacheView(image);
1751 p=GetCacheViewPixels(image_view,x,y,1,1);
1752 indexes=GetCacheViewIndexes(image_view);
1753 if (p != (PixelPacket *) NULL)
1754 {
1755 if ((strchr(SvPV(sval,na),',') == 0) ||
1756 (strchr(SvPV(sval,na),')') != 0))
1757 QueryMagickColor(SvPV(sval,na),&pixel,exception);
1758 else
1759 {
1760 GetMagickPixelPacket(image,&pixel);
1761 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1762 pixel.red=geometry_info.rho;
1763 if ((flags & SigmaValue) != 0)
1764 pixel.green=geometry_info.sigma;
1765 if ((flags & XiValue) != 0)
1766 pixel.blue=geometry_info.xi;
1767 if ((flags & PsiValue) != 0)
1768 pixel.opacity=geometry_info.psi;
1769 if ((flags & ChiValue) != 0)
1770 pixel.index=geometry_info.chi;
1771 }
1772 p->red=RoundToQuantum(pixel.red);
1773 p->green=RoundToQuantum(pixel.green);
1774 p->blue=RoundToQuantum(pixel.blue);
1775 p->opacity=RoundToQuantum(pixel.opacity);
1776 if (((image->colorspace == CMYKColorspace) ||
1777 (image->storage_class == PseudoClass)) &&
1778 (indexes != (IndexPacket *) NULL))
1779 *indexes=RoundToQuantum(pixel.index);
1780 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1781 }
1782 image_view=CloseCacheView(image_view);
1783 }
1784 break;
1785 }
1786 if (LocaleCompare(attribute,"pointsize") == 0)
1787 {
1788 if (info)
1789 {
1790 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1791 info->image_info->pointsize=geometry_info.rho;
1792 }
1793 break;
1794 }
1795 if (LocaleCompare(attribute,"preview") == 0)
1796 {
1797 sp=SvPOK(sval) ? ParseMagickOption(MagickPreviewOptions,MagickFalse,
1798 SvPV(sval,na)) : SvIV(sval);
1799 if (sp < 0)
1800 {
1801 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1802 SvPV(sval,na));
1803 break;
1804 }
1805 if (info)
1806 info->image_info->preview_type=(PreviewType) sp;
1807 break;
1808 }
1809 if (info)
1810 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1811 for ( ; image; image=image->next)
1812 SetImageProperty(image,attribute,SvPV(sval,na));
1813 break;
1814 }
1815 case 'Q':
1816 case 'q':
1817 {
1818 if (LocaleCompare(attribute,"quality") == 0)
1819 {
1820 if (info)
1821 info->image_info->quality=SvIV(sval);
1822 for ( ; image; image=image->next)
1823 image->quality=SvIV(sval);
1824 break;
1825 }
1826 if (info)
1827 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1828 for ( ; image; image=image->next)
1829 SetImageProperty(image,attribute,SvPV(sval,na));
1830 break;
1831 }
1832 case 'R':
1833 case 'r':
1834 {
1835 if (LocaleCompare(attribute,"red-primary") == 0)
1836 {
1837 for ( ; image; image=image->next)
1838 {
1839 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1840 image->chromaticity.red_primary.x=geometry_info.rho;
1841 image->chromaticity.red_primary.y=geometry_info.sigma;
1842 if ((flags & SigmaValue) == 0)
1843 image->chromaticity.red_primary.y=
1844 image->chromaticity.red_primary.x;
1845 }
1846 break;
1847 }
1848 if (LocaleCompare(attribute,"render") == 0)
1849 {
1850 sp=SvPOK(sval) ? ParseMagickOption(MagickIntentOptions,MagickFalse,
1851 SvPV(sval,na)) : SvIV(sval);
1852 if (sp < 0)
1853 {
1854 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1855 SvPV(sval,na));
1856 break;
1857 }
1858 for ( ; image; image=image->next)
1859 image->rendering_intent=(RenderingIntent) sp;
1860 break;
1861 }
1862 if (LocaleCompare(attribute,"repage") == 0)
1863 {
1864 RectangleInfo
1865 geometry;
1866
1867 for ( ; image; image=image->next)
1868 {
1869 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1870 if ((flags & WidthValue) != 0)
1871 {
1872 if ((flags & HeightValue) == 0)
1873 geometry.height=geometry.width;
1874 image->page.width=geometry.width;
1875 image->page.height=geometry.height;
1876 }
1877 if ((flags & AspectValue) != 0)
1878 {
1879 if ((flags & XValue) != 0)
1880 image->page.x+=geometry.x;
1881 if ((flags & YValue) != 0)
1882 image->page.y+=geometry.y;
1883 }
1884 else
1885 {
1886 if ((flags & XValue) != 0)
1887 {
1888 image->page.x=geometry.x;
1889 if (((flags & WidthValue) != 0) && (geometry.x > 0))
1890 image->page.width=image->columns+geometry.x;
1891 }
1892 if ((flags & YValue) != 0)
1893 {
1894 image->page.y=geometry.y;
1895 if (((flags & HeightValue) != 0) && (geometry.y > 0))
1896 image->page.height=image->rows+geometry.y;
1897 }
1898 }
1899 }
1900 break;
1901 }
1902 if (info)
1903 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1904 for ( ; image; image=image->next)
1905 SetImageProperty(image,attribute,SvPV(sval,na));
1906 break;
1907 }
1908 case 'S':
1909 case 's':
1910 {
1911 if (LocaleCompare(attribute,"sampling-factor") == 0)
1912 {
1913 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1914 {
1915 ThrowPerlException(exception,OptionError,"MissingGeometry",
1916 SvPV(sval,na));
1917 break;
1918 }
1919 if (info)
1920 (void) CloneString(&info->image_info->sampling_factor,
1921 SvPV(sval,na));
1922 break;
1923 }
1924 if (LocaleCompare(attribute,"scene") == 0)
1925 {
1926 for ( ; image; image=image->next)
1927 image->scene=SvIV(sval);
1928 break;
1929 }
1930 if (LocaleCompare(attribute,"subimage") == 0)
1931 {
1932 if (info)
1933 info->image_info->subimage=SvIV(sval);
1934 break;
1935 }
1936 if (LocaleCompare(attribute,"subrange") == 0)
1937 {
1938 if (info)
1939 info->image_info->subrange=SvIV(sval);
1940 break;
1941 }
1942 if (LocaleCompare(attribute,"server") == 0)
1943 goto display;
1944 if (LocaleCompare(attribute,"size") == 0)
1945 {
1946 if (info)
1947 {
1948 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1949 {
1950 ThrowPerlException(exception,OptionError,"MissingGeometry",
1951 SvPV(sval,na));
1952 break;
1953 }
1954 (void) CloneString(&info->image_info->size,SvPV(sval,na));
1955 }
1956 break;
1957 }
1958 if (LocaleCompare(attribute,"stroke") == 0)
1959 {
1960 if (info)
1961 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
1962 break;
1963 }
1964 if (info)
1965 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1966 for ( ; image; image=image->next)
1967 SetImageProperty(image,attribute,SvPV(sval,na));
1968 break;
1969 }
1970 case 'T':
1971 case 't':
1972 {
1973 if (LocaleCompare(attribute,"tile") == 0)
1974 {
1975 if (info)
1976 (void) CloneString(&info->image_info->tile,SvPV(sval,na));
1977 break;
1978 }
1979 if (LocaleCompare(attribute,"texture") == 0)
1980 {
1981 if (info)
1982 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
1983 break;
1984 }
1985 if (LocaleCompare(attribute,"tile-offset") == 0)
1986 {
1987 char
1988 *geometry;
1989
1990 geometry=GetPageGeometry(SvPV(sval,na));
1991 if (info)
1992 (void) CloneString(&info->image_info->page,geometry);
1993 for ( ; image; image=image->next)
1994 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
1995 exception);
1996 geometry=(char *) RelinquishMagickMemory(geometry);
1997 break;
1998 }
1999 if (LocaleCompare(attribute,"time-limit") == 0)
2000 {
2001 MagickSizeType
2002 limit;
2003
2004 limit=MagickResourceInfinity;
2005 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2006 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
2007 (void) SetMagickResourceLimit(TimeResource,limit);
2008 break;
2009 }
2010 if (LocaleCompare(attribute,"transparent-color") == 0)
2011 {
2012 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
2013 if (info)
2014 info->image_info->transparent_color=target_color;
2015 for ( ; image; image=image->next)
2016 image->transparent_color=target_color;
2017 break;
2018 }
2019 if (LocaleCompare(attribute,"type") == 0)
2020 {
2021 sp=SvPOK(sval) ? ParseMagickOption(MagickTypeOptions,MagickFalse,
2022 SvPV(sval,na)) : SvIV(sval);
2023 if (sp < 0)
2024 {
2025 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2026 SvPV(sval,na));
2027 break;
2028 }
2029 if (info)
2030 info->image_info->type=(ImageType) sp;
2031 for ( ; image; image=image->next)
2032 SetImageType(image,(ImageType) sp);
2033 break;
2034 }
2035 if (info)
2036 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2037 for ( ; image; image=image->next)
2038 SetImageProperty(image,attribute,SvPV(sval,na));
2039 break;
2040 }
2041 case 'U':
2042 case 'u':
2043 {
2044 if (LocaleCompare(attribute,"units") == 0)
2045 {
2046 sp=SvPOK(sval) ? ParseMagickOption(MagickResolutionOptions,
2047 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2048 if (sp < 0)
2049 {
2050 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2051 SvPV(sval,na));
2052 break;
2053 }
2054 if (info)
2055 info->image_info->units=(ResolutionType) sp;
2056 for ( ; image; image=image->next)
2057 {
2058 ResolutionType
2059 units;
2060
2061 units=(ResolutionType) sp;
2062 if (image->units != units)
2063 switch (image->units)
2064 {
2065 case UndefinedResolution:
2066 case PixelsPerInchResolution:
2067 {
2068 if (units == PixelsPerCentimeterResolution)
2069 {
2070 image->x_resolution*=2.54;
2071 image->y_resolution*=2.54;
2072 }
2073 break;
2074 }
2075 case PixelsPerCentimeterResolution:
2076 {
2077 if (units == PixelsPerInchResolution)
2078 {
2079 image->x_resolution/=2.54;
2080 image->y_resolution/=2.54;
2081 }
2082 break;
2083 }
2084 }
2085 image->units=units;
2086 }
2087 break;
2088 }
2089 if (info)
2090 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2091 for ( ; image; image=image->next)
2092 SetImageProperty(image,attribute,SvPV(sval,na));
2093 break;
2094 }
2095 case 'V':
2096 case 'v':
2097 {
2098 if (LocaleCompare(attribute,"verbose") == 0)
2099 {
2100 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
2101 SvPV(sval,na)) : SvIV(sval);
2102 if (sp < 0)
2103 {
2104 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2105 SvPV(sval,na));
2106 break;
2107 }
2108 if (info)
2109 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2110 break;
2111 }
2112 if (LocaleCompare(attribute,"view") == 0)
2113 {
2114 if (info)
2115 (void) CloneString(&info->image_info->view,SvPV(sval,na));
2116 break;
2117 }
2118 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2119 {
2120 sp=SvPOK(sval) ? ParseMagickOption(MagickVirtualPixelOptions,
2121 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2122 if (sp < 0)
2123 {
2124 ThrowPerlException(exception,OptionError,
2125 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2126 break;
2127 }
2128 if (info)
2129 info->image_info->virtual_pixel_method=(VirtualPixelMethod) sp;
2130 for ( ; image; image=image->next)
2131 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp);
2132 break;
2133 }
2134 if (info)
2135 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2136 for ( ; image; image=image->next)
2137 SetImageProperty(image,attribute,SvPV(sval,na));
2138 break;
2139 }
2140 case 'W':
2141 case 'w':
2142 {
2143 if (LocaleCompare(attribute,"white-point") == 0)
2144 {
2145 for ( ; image; image=image->next)
2146 {
2147 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2148 image->chromaticity.white_point.x=geometry_info.rho;
2149 image->chromaticity.white_point.y=geometry_info.sigma;
2150 if ((flags & SigmaValue) == 0)
2151 image->chromaticity.white_point.y=
2152 image->chromaticity.white_point.x;
2153 }
2154 break;
2155 }
2156 if (info)
2157 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2158 for ( ; image; image=image->next)
2159 SetImageProperty(image,attribute,SvPV(sval,na));
2160 break;
2161 }
2162 default:
2163 {
2164 if (info)
2165 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2166 for ( ; image; image=image->next)
2167 SetImageProperty(image,attribute,SvPV(sval,na));
2168 break;
2169 }
2170 }
2171}
2172
2173/*
2174%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2175% %
2176% %
2177% %
2178% S e t u p L i s t %
2179% %
2180% %
2181% %
2182%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2183%
2184% Method SetupList returns the list of all the images linked by their
2185% image->next and image->previous link lists for use with ImageMagick. If
2186% info is non-NULL, an info structure is returned in *info. If
2187% reference_vector is non-NULL,an array of SV* are returned in
2188% *reference_vector. Reference_vector is used when the images are going to be
2189% replaced with new Image*'s.
2190%
2191% The format of the SetupList routine is:
2192%
2193% Image *SetupList(SV *reference,struct PackageInfo **info,
2194% SV ***reference_vector,ExceptionInfo *exception)
2195%
2196% A description of each parameter follows:
2197%
2198% o list: a list of strings.
2199%
2200% o string: a character string.
2201%
2202% o exception: Return any errors or warnings in this structure.
2203%
2204*/
2205static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2206 SV ***reference_vector,ExceptionInfo *exception)
2207{
2208 Image
2209 *image;
2210
2211 long
2212 current,
2213 last;
2214
2215 if (reference_vector)
2216 *reference_vector=NULL;
2217 if (info)
2218 *info=NULL;
2219 current=0;
2220 last=0;
2221 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2222 if (info && (SvTYPE(reference) == SVt_PVAV))
2223 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2224 exception);
2225 return(image);
2226}
2227
2228/*
2229%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2230% %
2231% %
2232% %
2233% s t r E Q c a s e %
2234% %
2235% %
2236% %
2237%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2238%
2239% strEQcase() compares two strings and returns 0 if they are the
2240% same or if the second string runs out first. The comparison is case
2241% insensitive.
2242%
2243% The format of the strEQcase routine is:
2244%
2245% long strEQcase(const char *p,const char *q)
2246%
2247% A description of each parameter follows:
2248%
2249% o p: a character string.
2250%
2251% o q: a character string.
2252%
2253%
2254*/
2255static long strEQcase(const char *p,const char *q)
2256{
2257 char
2258 c;
2259
2260 register long
2261 i;
2262
2263 for (i=0 ; (c=(*q)) != 0; i++)
2264 {
2265 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2266 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2267 return(0);
2268 p++;
2269 q++;
2270 }
2271 return(((*q == 0) && (*p == 0)) ? i : 0);
2272}
2273
2274/*
2275%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2276% %
2277% %
2278% %
2279% I m a g e : : M a g i c k %
2280% %
2281% %
2282% %
2283%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2284%
2285%
2286*/
2287MODULE = Image::Magick PACKAGE = Image::Magick
2288
2289PROTOTYPES: ENABLE
2290
2291BOOT:
2292 MagickCoreGenesis("PerlMagick",MagickFalse);
2293 SetWarningHandler(NULL);
2294 SetErrorHandler(NULL);
2295 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2296 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2297
2298void
2299UNLOAD()
2300 PPCODE:
2301 {
2302 if (magick_registry != (SplayTreeInfo *) NULL)
2303 magick_registry=DestroySplayTree(magick_registry);
2304 MagickCoreTerminus();
2305 }
2306
2307double
2308constant(name,argument)
2309 char *name
2310 long argument
2311
2312#
2313###############################################################################
2314# #
2315# #
2316# #
2317# A n i m a t e #
2318# #
2319# #
2320# #
2321###############################################################################
2322#
2323#
2324void
2325Animate(ref,...)
2326 Image::Magick ref=NO_INIT
2327 ALIAS:
2328 AnimateImage = 1
2329 animate = 2
2330 animateimage = 3
2331 PPCODE:
2332 {
2333 ExceptionInfo
2334 *exception;
2335
2336 Image
2337 *image;
2338
2339 register long
2340 i;
2341
2342 struct PackageInfo
2343 *info,
2344 *package_info;
2345
2346 SV
2347 *perl_exception,
2348 *reference;
2349
2350 exception=AcquireExceptionInfo();
2351 perl_exception=newSVpv("",0);
2352 package_info=(struct PackageInfo *) NULL;
2353 if (sv_isobject(ST(0)) == 0)
2354 {
2355 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2356 PackageName);
2357 goto PerlException;
2358 }
2359 reference=SvRV(ST(0));
2360 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2361 if (image == (Image *) NULL)
2362 {
2363 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2364 PackageName);
2365 goto PerlException;
2366 }
2367 package_info=ClonePackageInfo(info,exception);
2368 if (items == 2)
2369 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2370 else
2371 if (items > 2)
2372 for (i=2; i < items; i+=2)
2373 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2374 exception);
2375 (void) AnimateImages(package_info->image_info,image);
2376 (void) CatchImageException(image);
2377 InheritException(exception,&image->exception);
2378
2379 PerlException:
2380 if (package_info != (struct PackageInfo *) NULL)
2381 DestroyPackageInfo(package_info);
2382 InheritPerlException(exception,perl_exception);
2383 exception=DestroyExceptionInfo(exception);
2384 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2385 SvPOK_on(perl_exception);
2386 ST(0)=sv_2mortal(perl_exception);
2387 XSRETURN(1);
2388 }
2389
2390#
2391###############################################################################
2392# #
2393# #
2394# #
2395# A p p e n d #
2396# #
2397# #
2398# #
2399###############################################################################
2400#
2401#
2402void
2403Append(ref,...)
2404 Image::Magick ref=NO_INIT
2405 ALIAS:
2406 AppendImage = 1
2407 append = 2
2408 appendimage = 3
2409 PPCODE:
2410 {
2411 AV
2412 *av;
2413
2414 char
2415 *attribute;
2416
2417 ExceptionInfo
2418 *exception;
2419
2420 HV
2421 *hv;
2422
2423 Image
2424 *image;
2425
2426 long
2427 stack;
2428
2429 register long
2430 i;
2431
2432 struct PackageInfo
2433 *info;
2434
2435 SV
2436 *av_reference,
2437 *perl_exception,
2438 *reference,
2439 *rv,
2440 *sv;
2441
2442 exception=AcquireExceptionInfo();
2443 perl_exception=newSVpv("",0);
2444 attribute=NULL;
2445 av=NULL;
2446 if (sv_isobject(ST(0)) == 0)
2447 {
2448 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2449 PackageName);
2450 goto PerlException;
2451 }
2452 reference=SvRV(ST(0));
2453 hv=SvSTASH(reference);
2454 av=newAV();
2455 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2456 SvREFCNT_dec(av);
2457 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2458 if (image == (Image *) NULL)
2459 {
2460 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2461 PackageName);
2462 goto PerlException;
2463 }
2464 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2465 /*
2466 Get options.
2467 */
2468 stack=MagickTrue;
2469 for (i=2; i < items; i+=2)
2470 {
2471 attribute=(char *) SvPV(ST(i-1),na);
2472 switch (*attribute)
2473 {
2474 case 'S':
2475 case 's':
2476 {
2477 if (LocaleCompare(attribute,"stack") == 0)
2478 {
2479 stack=ParseMagickOption(MagickBooleanOptions,MagickFalse,
2480 SvPV(ST(i),na));
2481 if (stack < 0)
2482 {
2483 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2484 SvPV(ST(i),na));
2485 return;
2486 }
2487 break;
2488 }
2489 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2490 attribute);
2491 break;
2492 }
2493 default:
2494 {
2495 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2496 attribute);
2497 break;
2498 }
2499 }
2500 }
2501 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2502 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2503 goto PerlException;
2504 for ( ; image; image=image->next)
2505 {
2506 AddImageToRegistry(image);
2507 rv=newRV(sv);
2508 av_push(av,sv_bless(rv,hv));
2509 SvREFCNT_dec(sv);
2510 }
2511 exception=DestroyExceptionInfo(exception);
2512 ST(0)=av_reference;
2513 SvREFCNT_dec(perl_exception);
2514 XSRETURN(1);
2515
2516 PerlException:
2517 InheritPerlException(exception,perl_exception);
2518 exception=DestroyExceptionInfo(exception);
2519 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2520 SvPOK_on(perl_exception);
2521 ST(0)=sv_2mortal(perl_exception);
2522 XSRETURN(1);
2523 }
2524
2525#
2526###############################################################################
2527# #
2528# #
2529# #
2530# A v e r a g e #
2531# #
2532# #
2533# #
2534###############################################################################
2535#
2536#
2537void
2538Average(ref)
2539 Image::Magick ref=NO_INIT
2540 ALIAS:
2541 AverageImage = 1
2542 average = 2
2543 averageimage = 3
2544 PPCODE:
2545 {
2546 AV
2547 *av;
2548
2549 char
2550 *p;
2551
2552 ExceptionInfo
2553 *exception;
2554
2555 HV
2556 *hv;
2557
2558 Image
2559 *image;
2560
2561 struct PackageInfo
2562 *info;
2563
2564 SV
2565 *perl_exception,
2566 *reference,
2567 *rv,
2568 *sv;
2569
2570 exception=AcquireExceptionInfo();
2571 perl_exception=newSVpv("",0);
2572 if (sv_isobject(ST(0)) == 0)
2573 {
2574 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2575 PackageName);
2576 goto PerlException;
2577 }
2578 reference=SvRV(ST(0));
2579 hv=SvSTASH(reference);
2580 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2581 if (image == (Image *) NULL)
2582 {
2583 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2584 PackageName);
2585 goto PerlException;
2586 }
2587 image=AverageImages(image,exception);
2588 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2589 goto PerlException;
2590 /*
2591 Create blessed Perl array for the returned image.
2592 */
2593 av=newAV();
2594 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2595 SvREFCNT_dec(av);
2596 AddImageToRegistry(image);
2597 rv=newRV(sv);
2598 av_push(av,sv_bless(rv,hv));
2599 SvREFCNT_dec(sv);
2600 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2601 (void) FormatMagickString(info->image_info->filename,MaxTextExtent,
2602 "average-%.*s",(int) (MaxTextExtent-9),
2603 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2604 (void) CopyMagickString(image->filename,info->image_info->filename,
2605 MaxTextExtent);
2606 SetImageInfo(info->image_info,MagickFalse,exception);
2607 exception=DestroyExceptionInfo(exception);
2608 SvREFCNT_dec(perl_exception);
2609 XSRETURN(1);
2610
2611 PerlException:
2612 InheritPerlException(exception,perl_exception);
2613 exception=DestroyExceptionInfo(exception);
2614 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2615 SvPOK_on(perl_exception);
2616 ST(0)=sv_2mortal(perl_exception);
2617 XSRETURN(1);
2618 }
2619
2620#
2621###############################################################################
2622# #
2623# #
2624# #
2625# B l o b T o I m a g e #
2626# #
2627# #
2628# #
2629###############################################################################
2630#
2631#
2632void
2633BlobToImage(ref,...)
2634 Image::Magick ref=NO_INIT
2635 ALIAS:
2636 BlobToImage = 1
2637 blobtoimage = 2
2638 blobto = 3
2639 PPCODE:
2640 {
2641 AV
2642 *av;
2643
2644 char
2645 **keep,
2646 **list;
2647
2648 ExceptionInfo
2649 *exception;
2650
2651 HV
2652 *hv;
2653
2654 Image
2655 *image;
2656
2657 long
2658 ac,
2659 n,
2660 number_images;
2661
2662 register char
2663 **p;
2664
2665 register long
2666 i;
2667
2668 STRLEN
2669 *length;
2670
2671 struct PackageInfo
2672 *info;
2673
2674 SV
2675 *perl_exception,
2676 *reference,
2677 *rv,
2678 *sv;
2679
2680 exception=AcquireExceptionInfo();
2681 perl_exception=newSVpv("",0);
2682 number_images=0;
2683 ac=(items < 2) ? 1 : items-1;
2684 length=(STRLEN *) NULL;
2685 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2686 if (list == (char **) NULL)
2687 {
2688 ThrowPerlException(exception,ResourceLimitError,
2689 "MemoryAllocationFailed",PackageName);
2690 goto PerlException;
2691 }
2692 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2693 if (length == (STRLEN *) NULL)
2694 {
2695 ThrowPerlException(exception,ResourceLimitError,
2696 "MemoryAllocationFailed",PackageName);
2697 goto PerlException;
2698 }
2699 if (sv_isobject(ST(0)) == 0)
2700 {
2701 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2702 PackageName);
2703 goto PerlException;
2704 }
2705 reference=SvRV(ST(0));
2706 hv=SvSTASH(reference);
2707 if (SvTYPE(reference) != SVt_PVAV)
2708 {
2709 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2710 PackageName);
2711 goto PerlException;
2712 }
2713 av=(AV *) reference;
2714 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2715 exception);
2716 n=1;
2717 if (items <= 1)
2718 {
2719 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2720 goto PerlException;
2721 }
2722 for (n=0, i=0; i < ac; i++)
2723 {
2724 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2725 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2726 {
2727 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2728 continue;
2729 }
2730 n++;
2731 }
2732 list[n]=(char *) NULL;
2733 keep=list;
2734 for (i=number_images=0; i < n; i++)
2735 {
2736 image=BlobToImage(info->image_info,list[i],length[i],exception);
2737 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2738 break;
2739 for ( ; image; image=image->next)
2740 {
2741 AddImageToRegistry(image);
2742 rv=newRV(sv);
2743 av_push(av,sv_bless(rv,hv));
2744 SvREFCNT_dec(sv);
2745 number_images++;
2746 }
2747 }
2748 /*
2749 Free resources.
2750 */
2751 for (i=0; i < n; i++)
2752 if (list[i] != (char *) NULL)
2753 for (p=keep; list[i] != *p++; )
2754 if (*p == (char *) NULL)
2755 {
2756 list[i]=(char *) RelinquishMagickMemory(list[i]);
2757 break;
2758 }
2759
2760 PerlException:
2761 if (list)
2762 list=(char **) RelinquishMagickMemory(list);
2763 if (length)
2764 length=(STRLEN *) RelinquishMagickMemory(length);
2765 InheritPerlException(exception,perl_exception);
2766 exception=DestroyExceptionInfo(exception);
2767 sv_setiv(perl_exception,(IV) number_images);
2768 SvPOK_on(perl_exception);
2769 ST(0)=sv_2mortal(perl_exception);
2770 XSRETURN(1);
2771 }
2772
2773#
2774###############################################################################
2775# #
2776# #
2777# #
2778# C l o n e #
2779# #
2780# #
2781# #
2782###############################################################################
2783#
2784#
2785void
2786Clone(ref)
2787 Image::Magick ref=NO_INIT
2788 ALIAS:
2789 CopyImage = 1
2790 copy = 2
2791 copyimage = 3
2792 CloneImage = 4
2793 clone = 5
2794 cloneimage = 6
2795 Clone = 7
2796 PPCODE:
2797 {
2798 AV
2799 *av;
2800
2801 ExceptionInfo
2802 *exception;
2803
2804 HV
2805 *hv;
2806
2807 Image
2808 *clone,
2809 *image;
2810
2811 struct PackageInfo
2812 *info;
2813
2814 SV
2815 *perl_exception,
2816 *reference,
2817 *rv,
2818 *sv;
2819
2820 exception=AcquireExceptionInfo();
2821 perl_exception=newSVpv("",0);
2822 if (sv_isobject(ST(0)) == 0)
2823 {
2824 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2825 PackageName);
2826 goto PerlException;
2827 }
2828 reference=SvRV(ST(0));
2829 hv=SvSTASH(reference);
2830 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2831 if (image == (Image *) NULL)
2832 {
2833 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2834 PackageName);
2835 goto PerlException;
2836 }
2837 /*
2838 Create blessed Perl array for the returned image.
2839 */
2840 av=newAV();
2841 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2842 SvREFCNT_dec(av);
2843 for ( ; image; image=image->next)
2844 {
2845 clone=CloneImage(image,0,0,MagickTrue,exception);
2846 if ((clone == (Image *) NULL) || (exception->severity >= ErrorException))
2847 break;
2848 AddImageToRegistry(clone);
2849 rv=newRV(sv);
2850 av_push(av,sv_bless(rv,hv));
2851 SvREFCNT_dec(sv);
2852 }
2853 exception=DestroyExceptionInfo(exception);
2854 SvREFCNT_dec(perl_exception);
2855 XSRETURN(1);
2856
2857 PerlException:
2858 InheritPerlException(exception,perl_exception);
2859 exception=DestroyExceptionInfo(exception);
2860 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2861 SvPOK_on(perl_exception);
2862 ST(0)=sv_2mortal(perl_exception);
2863 XSRETURN(1);
2864 }
2865
2866#
2867###############################################################################
2868# #
2869# #
2870# #
2871# C L O N E #
2872# #
2873# #
2874# #
2875###############################################################################
2876#
2877#
2878void
2879CLONE(ref,...)
2880 SV *ref;
2881 CODE:
2882 {
2883 if (magick_registry != (SplayTreeInfo *) NULL)
2884 {
2885 register Image
2886 *p;
2887
2888 ResetSplayTreeIterator(magick_registry);
2889 p=(Image *) GetNextKeyInSplayTree(magick_registry);
2890 while (p != (Image *) NULL)
2891 {
2892 ReferenceImage(p);
2893 p=(Image *) GetNextKeyInSplayTree(magick_registry);
2894 }
2895 }
2896 }
2897
2898#
2899###############################################################################
2900# #
2901# #
2902# #
2903# C o a l e s c e #
2904# #
2905# #
2906# #
2907###############################################################################
2908#
2909#
2910void
2911Coalesce(ref)
2912 Image::Magick ref=NO_INIT
2913 ALIAS:
2914 CoalesceImage = 1
2915 coalesce = 2
2916 coalesceimage = 3
2917 PPCODE:
2918 {
2919 AV
2920 *av;
2921
2922 ExceptionInfo
2923 *exception;
2924
2925 HV
2926 *hv;
2927
2928 Image
2929 *image;
2930
2931 struct PackageInfo
2932 *info;
2933
2934 SV
2935 *av_reference,
2936 *perl_exception,
2937 *reference,
2938 *rv,
2939 *sv;
2940
2941 exception=AcquireExceptionInfo();
2942 perl_exception=newSVpv("",0);
2943 if (sv_isobject(ST(0)) == 0)
2944 {
2945 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2946 PackageName);
2947 goto PerlException;
2948 }
2949 reference=SvRV(ST(0));
2950 hv=SvSTASH(reference);
2951 av=newAV();
2952 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2953 SvREFCNT_dec(av);
2954 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2955 if (image == (Image *) NULL)
2956 {
2957 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2958 PackageName);
2959 goto PerlException;
2960 }
2961 image=CoalesceImages(image,exception);
2962 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2963 goto PerlException;
2964 for ( ; image; image=image->next)
2965 {
2966 AddImageToRegistry(image);
2967 rv=newRV(sv);
2968 av_push(av,sv_bless(rv,hv));
2969 SvREFCNT_dec(sv);
2970 }
2971 exception=DestroyExceptionInfo(exception);
2972 ST(0)=av_reference;
2973 SvREFCNT_dec(perl_exception);
2974 XSRETURN(1);
2975
2976 PerlException:
2977 InheritPerlException(exception,perl_exception);
2978 exception=DestroyExceptionInfo(exception);
2979 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2980 SvPOK_on(perl_exception);
2981 ST(0)=sv_2mortal(perl_exception);
2982 XSRETURN(1);
2983 }
2984
2985#
2986###############################################################################
2987# #
2988# #
2989# #
2990# C o m p a r e #
2991# #
2992# #
2993# #
2994###############################################################################
2995#
2996#
2997void
2998Compare(ref,...)
2999 Image::Magick ref=NO_INIT
3000 ALIAS:
3001 CompareImage = 1
3002 compare = 2
3003 compareimage = 3
3004 PPCODE:
3005 {
3006 AV
3007 *av;
3008
3009 char
3010 *attribute;
3011
3012 ChannelType
3013 channel;
3014
3015 double
3016 distortion;
3017
3018 ExceptionInfo
3019 *exception;
3020
3021 HV
3022 *hv;
3023
3024 Image
3025 *difference_image,
3026 *image,
3027 *reconstruct_image;
3028
3029 long
3030 option;
3031
3032 MetricType
3033 metric;
3034
3035 register long
3036 i;
3037
3038 struct PackageInfo
3039 *info;
3040
3041 SV
3042 *av_reference,
3043 *perl_exception,
3044 *reference,
3045 *rv,
3046 *sv;
3047
3048 exception=AcquireExceptionInfo();
3049 perl_exception=newSVpv("",0);
3050 av=NULL;
3051 attribute=NULL;
3052 if (sv_isobject(ST(0)) == 0)
3053 {
3054 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3055 PackageName);
3056 goto PerlException;
3057 }
3058 reference=SvRV(ST(0));
3059 hv=SvSTASH(reference);
3060 av=newAV();
3061 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3062 SvREFCNT_dec(av);
3063 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3064 if (image == (Image *) NULL)
3065 {
3066 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3067 PackageName);
3068 goto PerlException;
3069 }
3070 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3071 /*
3072 Get attribute.
3073 */
3074 channel=DefaultChannels;
3075 reconstruct_image=image;
3076 metric=RootMeanSquaredErrorMetric;
3077 for (i=2; i < items; i+=2)
3078 {
3079 attribute=(char *) SvPV(ST(i-1),na);
3080 switch (*attribute)
3081 {
3082 case 'C':
3083 case 'c':
3084 {
3085 if (LocaleCompare(attribute,"channel") == 0)
3086 {
3087 long
3088 option;
3089
3090 option=ParseChannelOption(SvPV(ST(i),na));
3091 if (option < 0)
3092 {
3093 ThrowPerlException(exception,OptionError,
3094 "UnrecognizedType",SvPV(ST(i),na));
3095 return;
3096 }
3097 channel=(ChannelType) option;
3098 break;
3099 }
3100 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3101 attribute);
3102 break;
3103 }
3104 case 'F':
3105 case 'f':
3106 {
3107 if (LocaleCompare(attribute,"fuzz") == 0)
3108 {
3109 image->fuzz=StringToDouble(SvPV(ST(i),na),100.0);
3110 break;
3111 }
3112 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3113 attribute);
3114 break;
3115 }
3116 case 'I':
3117 case 'i':
3118 {
3119 if (LocaleCompare(attribute,"image") == 0)
3120 {
3121 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3122 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3123 }
3124 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3125 attribute);
3126 break;
3127 }
3128 case 'M':
3129 case 'm':
3130 {
3131 if (LocaleCompare(attribute,"metric") == 0)
3132 {
3133 option=ParseMagickOption(MagickMetricOptions,MagickFalse,
3134 SvPV(ST(i),na));
3135 if (option < 0)
3136 {
3137 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3138 SvPV(ST(i),na));
3139 break;
3140 }
3141 metric=(MetricType) option;
3142 break;
3143 }
3144 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3145 attribute);
3146 break;
3147 }
3148 default:
3149 {
3150 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3151 attribute);
3152 break;
3153 }
3154 }
3155 }
3156 difference_image=CompareImageChannels(image,reconstruct_image,channel,
3157 metric,&distortion,exception);
3158 if (difference_image != (Image *) NULL)
3159 {
3160 difference_image->error.mean_error_per_pixel=distortion;
3161 AddImageToRegistry(difference_image);
3162 rv=newRV(sv);
3163 av_push(av,sv_bless(rv,hv));
3164 SvREFCNT_dec(sv);
3165 }
3166 exception=DestroyExceptionInfo(exception);
3167 ST(0)=av_reference;
3168 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3169 XSRETURN(1);
3170
3171 PerlException:
3172 InheritPerlException(exception,perl_exception);
3173 exception=DestroyExceptionInfo(exception);
3174 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3175 SvPOK_on(perl_exception);
3176 ST(0)=sv_2mortal(perl_exception);
3177 XSRETURN(1);
3178 }
3179
3180#
3181###############################################################################
3182# #
3183# #
3184# #
3185# C o m p a r e L a y e r s #
3186# #
3187# #
3188# #
3189###############################################################################
3190#
3191#
3192void
3193CompareLayers(ref)
3194 Image::Magick ref=NO_INIT
3195 ALIAS:
3196 CompareImageLayers = 1
3197 comparelayers = 2
3198 compareimagelayers = 3
3199 PPCODE:
3200 {
3201 AV
3202 *av;
3203
3204 char
3205 *attribute;
3206
3207 ExceptionInfo
3208 *exception;
3209
3210 HV
3211 *hv;
3212
3213 Image
3214 *image;
3215
3216 long
3217 option;
3218
3219 ImageLayerMethod
3220 method;
3221
3222 register long
3223 i;
3224
3225 struct PackageInfo
3226 *info;
3227
3228 SV
3229 *av_reference,
3230 *perl_exception,
3231 *reference,
3232 *rv,
3233 *sv;
3234
3235 exception=AcquireExceptionInfo();
3236 perl_exception=newSVpv("",0);
3237 if (sv_isobject(ST(0)) == 0)
3238 {
3239 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3240 PackageName);
3241 goto PerlException;
3242 }
3243 reference=SvRV(ST(0));
3244 hv=SvSTASH(reference);
3245 av=newAV();
3246 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3247 SvREFCNT_dec(av);
3248 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3249 if (image == (Image *) NULL)
3250 {
3251 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3252 PackageName);
3253 goto PerlException;
3254 }
3255 method=CompareAnyLayer;
3256 for (i=2; i < items; i+=2)
3257 {
3258 attribute=(char *) SvPV(ST(i-1),na);
3259 switch (*attribute)
3260 {
3261 case 'M':
3262 case 'm':
3263 {
3264 if (LocaleCompare(attribute,"method") == 0)
3265 {
3266 option=ParseMagickOption(MagickLayerOptions,MagickFalse,
3267 SvPV(ST(i),na));
3268 if (option < 0)
3269 {
3270 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3271 SvPV(ST(i),na));
3272 break;
3273 }
3274 method=(ImageLayerMethod) option;
3275 break;
3276 }
3277 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3278 attribute);
3279 break;
3280 }
3281 default:
3282 {
3283 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3284 attribute);
3285 break;
3286 }
3287 }
3288 }
3289 image=CompareImageLayers(image,method,exception);
3290 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
3291 goto PerlException;
3292 for ( ; image; image=image->next)
3293 {
3294 AddImageToRegistry(image);
3295 rv=newRV(sv);
3296 av_push(av,sv_bless(rv,hv));
3297 SvREFCNT_dec(sv);
3298 }
3299 exception=DestroyExceptionInfo(exception);
3300 ST(0)=av_reference;
3301 SvREFCNT_dec(perl_exception);
3302 XSRETURN(1);
3303
3304 PerlException:
3305 InheritPerlException(exception,perl_exception);
3306 exception=DestroyExceptionInfo(exception);
3307 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3308 SvPOK_on(perl_exception);
3309 ST(0)=sv_2mortal(perl_exception);
3310 XSRETURN(1);
3311 }
3312
3313#
3314###############################################################################
3315# #
3316# #
3317# #
3318# D e s t r o y #
3319# #
3320# #
3321# #
3322###############################################################################
3323#
3324#
3325void
3326DESTROY(ref)
3327 Image::Magick ref=NO_INIT
3328 PPCODE:
3329 {
3330 SV
3331 *reference;
3332
3333 if (sv_isobject(ST(0)) == 0)
3334 croak("ReferenceIsNotMyType");
3335 reference=SvRV(ST(0));
3336 switch (SvTYPE(reference))
3337 {
3338 case SVt_PVAV:
3339 {
3340 char
3341 message[MaxTextExtent];
3342
3343 struct PackageInfo
3344 *info;
3345
3346 HV
3347 *hv;
3348
3349 GV
3350 **gvp;
3351
3352 SV
3353 *sv;
3354
3355 /*
3356 Array (AV *) reference
3357 */
3358 (void) FormatMagickString(message,MaxTextExtent,"package%s%lx",
3359 XS_VERSION,(long) reference);
3360 hv=gv_stashpv(PackageName, FALSE);
3361 if (!hv)
3362 break;
3363 gvp=(GV **) hv_fetch(hv,message,strlen(message),FALSE);
3364 if (!gvp)
3365 break;
3366 sv=GvSV(*gvp);
3367 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3368 {
3369 info=(struct PackageInfo *) SvIV(sv);
3370 DestroyPackageInfo(info);
3371 }
3372 hv_delete(hv,message,strlen(message),G_DISCARD);
3373 break;
3374 }
3375 case SVt_PVMG:
3376 {
3377 Image
3378 *image;
3379
3380 /*
3381 Blessed scalar = (Image *) SvIV(reference)
3382 */
3383 image=(Image *) SvIV(reference);
3384 if (image != (Image *) NULL)
3385 DeleteImageFromRegistry(reference,image);
3386 break;
3387 }
3388 default:
3389 break;
3390 }
3391 }
3392
3393#
3394###############################################################################
3395# #
3396# #
3397# #
3398# D i s p l a y #
3399# #
3400# #
3401# #
3402###############################################################################
3403#
3404#
3405void
3406Display(ref,...)
3407 Image::Magick ref=NO_INIT
3408 ALIAS:
3409 DisplayImage = 1
3410 display = 2
3411 displayimage = 3
3412 PPCODE:
3413 {
3414 ExceptionInfo
3415 *exception;
3416
3417 Image
3418 *image;
3419
3420 register long
3421 i;
3422
3423 struct PackageInfo
3424 *info,
3425 *package_info;
3426
3427 SV
3428 *perl_exception,
3429 *reference;
3430
3431 exception=AcquireExceptionInfo();
3432 perl_exception=newSVpv("",0);
3433 package_info=(struct PackageInfo *) NULL;
3434 if (sv_isobject(ST(0)) == 0)
3435 {
3436 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3437 PackageName);
3438 goto PerlException;
3439 }
3440 reference=SvRV(ST(0));
3441 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3442 if (image == (Image *) NULL)
3443 {
3444 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3445 PackageName);
3446 goto PerlException;
3447 }
3448 package_info=ClonePackageInfo(info,exception);
3449 if (items == 2)
3450 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3451 else
3452 if (items > 2)
3453 for (i=2; i < items; i+=2)
3454 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3455 exception);
3456 (void) DisplayImages(package_info->image_info,image);
3457 (void) CatchImageException(image);
3458 InheritException(exception,&image->exception);
3459
3460 PerlException:
3461 if (package_info != (struct PackageInfo *) NULL)
3462 DestroyPackageInfo(package_info);
3463 InheritPerlException(exception,perl_exception);
3464 exception=DestroyExceptionInfo(exception);
3465 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3466 SvPOK_on(perl_exception);
3467 ST(0)=sv_2mortal(perl_exception);
3468 XSRETURN(1);
3469 }
3470
3471#
3472###############################################################################
3473# #
3474# #
3475# #
3476# F l a t t e n #
3477# #
3478# #
3479# #
3480###############################################################################
3481#
3482#
3483void
3484Flatten(ref)
3485 Image::Magick ref=NO_INIT
3486 ALIAS:
3487 FlattenImage = 1
3488 flatten = 2
3489 flattenimage = 3
3490 PPCODE:
3491 {
3492 AV
3493 *av;
3494
3495 char
3496 *attribute,
3497 *p;
3498
3499 ExceptionInfo
3500 *exception;
3501
3502 HV
3503 *hv;
3504
3505 Image
3506 *image;
3507
3508 PixelPacket
3509 background_color;
3510
3511 register long
3512 i;
3513
3514 struct PackageInfo
3515 *info;
3516
3517 SV
3518 *perl_exception,
3519 *reference,
3520 *rv,
3521 *sv;
3522
3523 exception=AcquireExceptionInfo();
3524 perl_exception=newSVpv("",0);
3525 if (sv_isobject(ST(0)) == 0)
3526 {
3527 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3528 PackageName);
3529 goto PerlException;
3530 }
3531 reference=SvRV(ST(0));
3532 hv=SvSTASH(reference);
3533 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3534 if (image == (Image *) NULL)
3535 {
3536 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3537 PackageName);
3538 goto PerlException;
3539 }
3540 background_color=image->background_color;
3541 if (items == 2)
3542 (void) QueryColorDatabase((char *) SvPV(ST(1),na),&background_color,
3543 exception);
3544 else
3545 for (i=2; i < items; i+=2)
3546 {
3547 attribute=(char *) SvPV(ST(i-1),na);
3548 switch (*attribute)
3549 {
3550 case 'B':
3551 case 'b':
3552 {
3553 if (LocaleCompare(attribute,"background") == 0)
3554 {
3555 (void) QueryColorDatabase((char *) SvPV(ST(1),na),
3556 &background_color,exception);
3557 break;
3558 }
3559 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3560 attribute);
3561 break;
3562 }
3563 default:
3564 {
3565 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3566 attribute);
3567 break;
3568 }
3569 }
3570 }
3571 image->background_color=background_color;
3572 image=MergeImageLayers(image,FlattenLayer,exception);
3573 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
3574 goto PerlException;
3575 /*
3576 Create blessed Perl array for the returned image.
3577 */
3578 av=newAV();
3579 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3580 SvREFCNT_dec(av);
3581 AddImageToRegistry(image);
3582 rv=newRV(sv);
3583 av_push(av,sv_bless(rv,hv));
3584 SvREFCNT_dec(sv);
3585 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3586 (void) FormatMagickString(info->image_info->filename,MaxTextExtent,
3587 "flatten-%.*s",(int) (MaxTextExtent-9),
3588 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3589 (void) CopyMagickString(image->filename,info->image_info->filename,
3590 MaxTextExtent);
3591 SetImageInfo(info->image_info,MagickFalse,exception);
3592 exception=DestroyExceptionInfo(exception);
3593 SvREFCNT_dec(perl_exception);
3594 XSRETURN(1);
3595
3596 PerlException:
3597 InheritPerlException(exception,perl_exception);
3598 exception=DestroyExceptionInfo(exception);
3599 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3600 SvPOK_on(perl_exception); /* return messages in string context */
3601 ST(0)=sv_2mortal(perl_exception);
3602 XSRETURN(1);
3603 }
3604
3605#
3606###############################################################################
3607# #
3608# #
3609# #
3610# F x #
3611# #
3612# #
3613# #
3614###############################################################################
3615#
3616#
3617void
3618Fx(ref,...)
3619 Image::Magick ref=NO_INIT
3620 ALIAS:
3621 FxImage = 1
3622 fx = 2
3623 fximage = 3
3624 PPCODE:
3625 {
3626 AV
3627 *av;
3628
3629 char
3630 *attribute,
3631 expression[MaxTextExtent];
3632
3633 ChannelType
3634 channel;
3635
3636 ExceptionInfo
3637 *exception;
3638
3639 HV
3640 *hv;
3641
3642 Image
3643 *image;
3644
3645 register long
3646 i;
3647
3648 struct PackageInfo
3649 *info;
3650
3651 SV
3652 *av_reference,
3653 *perl_exception,
3654 *reference,
3655 *rv,
3656 *sv;
3657
3658 exception=AcquireExceptionInfo();
3659 perl_exception=newSVpv("",0);
3660 attribute=NULL;
3661 av=NULL;
3662 if (sv_isobject(ST(0)) == 0)
3663 {
3664 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3665 PackageName);
3666 goto PerlException;
3667 }
3668 reference=SvRV(ST(0));
3669 hv=SvSTASH(reference);
3670 av=newAV();
3671 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3672 SvREFCNT_dec(av);
3673 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3674 if (image == (Image *) NULL)
3675 {
3676 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3677 PackageName);
3678 goto PerlException;
3679 }
3680 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3681 /*
3682 Get options.
3683 */
3684 channel=DefaultChannels;
3685 (void) CopyMagickString(expression,"u",MaxTextExtent);
3686 if (items == 2)
3687 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MaxTextExtent);
3688 else
3689 for (i=2; i < items; i+=2)
3690 {
3691 attribute=(char *) SvPV(ST(i-1),na);
3692 switch (*attribute)
3693 {
3694 case 'C':
3695 case 'c':
3696 {
3697 if (LocaleCompare(attribute,"channel") == 0)
3698 {
3699 long
3700 option;
3701
3702 option=ParseChannelOption(SvPV(ST(i),na));
3703 if (option < 0)
3704 {
3705 ThrowPerlException(exception,OptionError,
3706 "UnrecognizedType",SvPV(ST(i),na));
3707 return;
3708 }
3709 channel=(ChannelType) option;
3710 break;
3711 }
3712 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3713 attribute);
3714 break;
3715 }
3716 case 'E':
3717 case 'e':
3718 {
3719 if (LocaleCompare(attribute,"expression") == 0)
3720 {
3721 (void) CopyMagickString(expression,SvPV(ST(i),na),
3722 MaxTextExtent);
3723 break;
3724 }
3725 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3726 attribute);
3727 break;
3728 }
3729 default:
3730 {
3731 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3732 attribute);
3733 break;
3734 }
3735 }
3736 }
3737 image=FxImageChannel(image,channel,expression,exception);
3738 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
3739 goto PerlException;
3740 for ( ; image; image=image->next)
3741 {
3742 AddImageToRegistry(image);
3743 rv=newRV(sv);
3744 av_push(av,sv_bless(rv,hv));
3745 SvREFCNT_dec(sv);
3746 }
3747 exception=DestroyExceptionInfo(exception);
3748 ST(0)=av_reference;
3749 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3750 XSRETURN(1);
3751
3752 PerlException:
3753 InheritPerlException(exception,perl_exception);
3754 exception=DestroyExceptionInfo(exception);
3755 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3756 SvPOK_on(perl_exception);
3757 ST(0)=sv_2mortal(perl_exception);
3758 XSRETURN(1);
3759 }
3760
3761#
3762###############################################################################
3763# #
3764# #
3765# #
3766# G e t #
3767# #
3768# #
3769# #
3770###############################################################################
3771#
3772#
3773void
3774Get(ref,...)
3775 Image::Magick ref=NO_INIT
3776 ALIAS:
3777 GetAttributes = 1
3778 GetAttribute = 2
3779 get = 3
3780 getattributes = 4
3781 getattribute = 5
3782 PPCODE:
3783 {
3784 char
3785 *attribute,
3786 color[MaxTextExtent];
3787
3788 const char
3789 *value;
3790
3791 ExceptionInfo
3792 *exception;
3793
3794 Image
3795 *image;
3796
3797 long
3798 j;
3799
3800 register long
3801 i;
3802
3803 struct PackageInfo
3804 *info;
3805
3806 SV
3807 *perl_exception,
3808 *reference,
3809 *s;
3810
3811 exception=AcquireExceptionInfo();
3812 perl_exception=newSVpv("",0);
3813 if (sv_isobject(ST(0)) == 0)
3814 {
3815 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3816 PackageName);
3817 XSRETURN_EMPTY;
3818 }
3819 reference=SvRV(ST(0));
3820 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3821 if (image == (Image *) NULL && !info)
3822 XSRETURN_EMPTY;
3823 EXTEND(sp,items);
3824 for (i=1; i < items; i++)
3825 {
3826 attribute=(char *) SvPV(ST(i),na);
3827 s=NULL;
3828 switch (*attribute)
3829 {
3830 case 'A':
3831 case 'a':
3832 {
3833 if (LocaleCompare(attribute,"adjoin") == 0)
3834 {
3835 if (info)
3836 s=newSViv((long) info->image_info->adjoin);
3837 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3838 continue;
3839 }
3840 if (LocaleCompare(attribute,"antialias") == 0)
3841 {
3842 if (info)
3843 s=newSViv((long) info->image_info->antialias);
3844 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3845 continue;
3846 }
3847 if (LocaleCompare(attribute,"area") == 0)
3848 {
3849 s=newSViv(GetMagickResource(AreaResource));
3850 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3851 continue;
3852 }
3853 if (LocaleCompare(attribute,"attenuate") == 0)
3854 {
3855 const char
3856 *value;
3857
3858 value=GetImageProperty(image,attribute);
3859 if (value != (const char *) NULL)
3860 s=newSVpv(value,0);
3861 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3862 continue;
3863 }
3864 if (LocaleCompare(attribute,"authenticate") == 0)
3865 {
3866 if (info)
3867 s=newSVpv(info->image_info->authenticate,0);
3868 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3869 continue;
3870 }
3871 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3872 attribute);
3873 break;
3874 }
3875 case 'B':
3876 case 'b':
3877 {
3878 if (LocaleCompare(attribute,"background") == 0)
3879 {
3880 if (image == (Image *) NULL)
3881 break;
3882 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
3883 QuantumFormat "," QuantumFormat "," QuantumFormat,
3884 image->background_color.red,image->background_color.green,
3885 image->background_color.blue,image->background_color.opacity);
3886 s=newSVpv(color,0);
3887 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3888 continue;
3889 }
3890 if (LocaleCompare(attribute,"base-columns") == 0)
3891 {
3892 if (image != (Image *) NULL)
3893 s=newSViv((long) image->magick_columns);
3894 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3895 continue;
3896 }
3897 if (LocaleCompare(attribute,"base-filename") == 0)
3898 {
3899 if (image != (Image *) NULL)
3900 s=newSVpv(image->magick_filename,0);
3901 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3902 continue;
3903 }
3904 if (LocaleCompare(attribute,"base-height") == 0)
3905 {
3906 if (image != (Image *) NULL)
3907 s=newSViv((long) image->magick_rows);
3908 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3909 continue;
3910 }
3911 if (LocaleCompare(attribute,"base-rows") == 0)
3912 {
3913 if (image != (Image *) NULL)
3914 s=newSViv((long) image->magick_rows);
3915 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3916 continue;
3917 }
3918 if (LocaleCompare(attribute,"base-width") == 0)
3919 {
3920 if (image != (Image *) NULL)
3921 s=newSViv((long) image->magick_columns);
3922 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3923 continue;
3924 }
3925 if (LocaleCompare(attribute,"bias") == 0)
3926 {
3927 if (image != (Image *) NULL)
3928 s=newSVnv(image->bias);
3929 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3930 continue;
3931 }
3932 if (LocaleCompare(attribute,"blue-primary") == 0)
3933 {
3934 if (image == (Image *) NULL)
3935 break;
3936 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
3937 image->chromaticity.blue_primary.x,
3938 image->chromaticity.blue_primary.y);
3939 s=newSVpv(color,0);
3940 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3941 continue;
3942 }
3943 if (LocaleCompare(attribute,"bordercolor") == 0)
3944 {
3945 if (image == (Image *) NULL)
3946 break;
3947 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
3948 QuantumFormat "," QuantumFormat "," QuantumFormat,
3949 image->border_color.red,image->border_color.green,
3950 image->border_color.blue,image->border_color.opacity);
3951 s=newSVpv(color,0);
3952 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3953 continue;
3954 }
3955 if (LocaleCompare(attribute,"bounding-box") == 0)
3956 {
3957 char
3958 geometry[MaxTextExtent];
3959
3960 RectangleInfo
3961 page;
3962
3963 if (image == (Image *) NULL)
3964 break;
3965 page=GetImageBoundingBox(image,&image->exception);
3966 (void) FormatMagickString(geometry,MaxTextExtent,
3967 "%lux%lu%+ld%+ld",page.width,page.height,page.x,page.y);
3968 s=newSVpv(geometry,0);
3969 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3970 continue;
3971 }
3972 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3973 attribute);
3974 break;
3975 }
3976 case 'C':
3977 case 'c':
3978 {
3979 if (LocaleCompare(attribute,"class") == 0)
3980 {
3981 if (image == (Image *) NULL)
3982 break;
3983 s=newSViv(image->storage_class);
3984 (void) sv_setpv(s,MagickOptionToMnemonic(MagickClassOptions,
3985 image->storage_class));
3986 SvIOK_on(s);
3987 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3988 continue;
3989 }
3990 if (LocaleCompare(attribute,"clip-mask") == 0)
3991 {
3992 if (image != (Image *) NULL)
3993 {
3994 SV
3995 *sv;
3996
3997 if (image->mask == (Image *) NULL)
3998 ClipImage(image);
3999 if (image->mask != (Image *) NULL)
4000 {
4001 AddImageToRegistry(image->mask);
4002 s=sv_bless(newRV(sv),SvSTASH(reference));
4003 }
4004 }
4005 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4006 continue;
4007 }
4008 if (LocaleCompare(attribute,"clip-path") == 0)
4009 {
4010 if (image != (Image *) NULL)
4011 {
4012 SV
4013 *sv;
4014
4015 if (image->clip_mask == (Image *) NULL)
4016 ClipImage(image);
4017 if (image->clip_mask != (Image *) NULL)
4018 {
4019 AddImageToRegistry(image->clip_mask);
4020 s=sv_bless(newRV(sv),SvSTASH(reference));
4021 }
4022 }
4023 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4024 continue;
4025 }
4026 if (LocaleCompare(attribute,"compression") == 0)
4027 {
4028 j=info ? info->image_info->compression : image->compression;
4029 if (info)
4030 if (info->image_info->compression == UndefinedCompression)
4031 j=image->compression;
4032 s=newSViv(j);
4033 (void) sv_setpv(s,MagickOptionToMnemonic(MagickCompressOptions,
4034 j));
4035 SvIOK_on(s);
4036 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4037 continue;
4038 }
4039 if (LocaleCompare(attribute,"colorspace") == 0)
4040 {
4041 j=image ? image->colorspace : RGBColorspace;
4042 s=newSViv(j);
4043 (void) sv_setpv(s,MagickOptionToMnemonic(MagickColorspaceOptions,
4044 j));
4045 SvIOK_on(s);
4046 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4047 continue;
4048 }
4049 if (LocaleCompare(attribute,"colors") == 0)
4050 {
4051 if (image != (Image *) NULL)
4052 s=newSViv((long) GetNumberColors(image,(FILE *) NULL,
4053 &image->exception));
4054 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4055 continue;
4056 }
4057 if (LocaleNCompare(attribute,"colormap",8) == 0)
4058 {
4059 int
4060 items;
4061
4062 if (image == (Image *) NULL || !image->colormap)
4063 break;
4064 j=0;
4065 items=sscanf(attribute,"%*[^[][%ld",&j);
4066 if (j > (long) image->colors)
4067 j%=image->colors;
4068 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
4069 QuantumFormat "," QuantumFormat "," QuantumFormat,
4070 image->colormap[j].red,image->colormap[j].green,
4071 image->colormap[j].blue,image->colormap[j].opacity);
4072 s=newSVpv(color,0);
4073 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4074 continue;
4075 }
4076 if (LocaleCompare(attribute,"columns") == 0)
4077 {
4078 if (image != (Image *) NULL)
4079 s=newSViv((long) image->columns);
4080 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4081 continue;
4082 }
4083 if (LocaleCompare(attribute,"comment") == 0)
4084 {
4085 const char
4086 *value;
4087
4088 value=GetImageProperty(image,attribute);
4089 if (value != (const char *) NULL)
4090 s=newSVpv(value,0);
4091 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4092 continue;
4093 }
4094 if (LocaleCompare(attribute,"copyright") == 0)
4095 {
4096 s=newSVpv(GetMagickCopyright(),0);
4097 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4098 continue;
4099 }
4100 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4101 attribute);
4102 break;
4103 }
4104 case 'D':
4105 case 'd':
4106 {
4107 if (LocaleCompare(attribute,"density") == 0)
4108 {
4109 char
4110 geometry[MaxTextExtent];
4111
4112 if (image == (Image *) NULL)
4113 break;
4114 (void) FormatMagickString(geometry,MaxTextExtent,"%gx%g",
4115 image->x_resolution,image->y_resolution);
4116 s=newSVpv(geometry,0);
4117 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4118 continue;
4119 }
4120 if (LocaleCompare(attribute,"dispose") == 0)
4121 {
4122 if (image == (Image *) NULL)
4123 break;
4124
4125 s=newSViv(image->dispose);
4126 (void) sv_setpv(s,
4127 MagickOptionToMnemonic(MagickDisposeOptions,image->dispose));
4128 SvIOK_on(s);
4129 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4130 continue;
4131 }
4132 if (LocaleCompare(attribute,"delay") == 0)
4133 {
4134 if (image != (Image *) NULL)
4135 s=newSViv((long) image->delay);
4136 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4137 continue;
4138 }
4139 if (LocaleCompare(attribute,"depth") == 0)
4140 {
4141 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4142 if (image != (Image *) NULL)
4143 s=newSViv((long) GetImageDepth(image,&image->exception));
4144 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4145 continue;
4146 }
4147 if (LocaleCompare(attribute,"disk") == 0)
4148 {
4149 s=newSViv(GetMagickResource(DiskResource));
4150 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4151 continue;
4152 }
4153 if (LocaleCompare(attribute,"dither") == 0)
4154 {
4155 if (info)
4156 s=newSViv((long) info->image_info->dither);
4157 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4158 continue;
4159 }
4160 if (LocaleCompare(attribute,"display") == 0) /* same as server */
4161 {
4162 if (info && info->image_info->server_name)
4163 s=newSVpv(info->image_info->server_name,0);
4164 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4165 continue;
4166 }
4167 if (LocaleCompare(attribute,"directory") == 0)
4168 {
4169 if (image && image->directory)
4170 s=newSVpv(image->directory,0);
4171 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4172 continue;
4173 }
4174 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4175 attribute);
4176 break;
4177 }
4178 case 'E':
4179 case 'e':
4180 {
4181 if (LocaleCompare(attribute,"elapsed-time") == 0)
4182 {
4183 if (image != (Image *) NULL)
4184 s=newSVnv(GetElapsedTime(&image->timer));
4185 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4186 continue;
4187 }
4188 if (LocaleCompare(attribute,"endian") == 0)
4189 {
4190 j=info ? info->image_info->endian : image->endian;
4191 s=newSViv(j);
4192 (void) sv_setpv(s,MagickOptionToMnemonic(MagickEndianOptions,j));
4193 SvIOK_on(s);
4194 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4195 continue;
4196 }
4197 if (LocaleCompare(attribute,"error") == 0)
4198 {
4199 if (image != (Image *) NULL)
4200 s=newSVnv(image->error.mean_error_per_pixel);
4201 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4202 continue;
4203 }
4204 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4205 attribute);
4206 break;
4207 }
4208 case 'F':
4209 case 'f':
4210 {
4211 if (LocaleCompare(attribute,"filesize") == 0)
4212 {
4213 if (image != (Image *) NULL)
4214 s=newSViv((long) GetBlobSize(image));
4215 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4216 continue;
4217 }
4218 if (LocaleCompare(attribute,"filename") == 0)
4219 {
4220 if (info && info->image_info->filename &&
4221 *info->image_info->filename)
4222 s=newSVpv(info->image_info->filename,0);
4223 if (image != (Image *) NULL)
4224 s=newSVpv(image->filename,0);
4225 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4226 continue;
4227 }
4228 if (LocaleCompare(attribute,"filter") == 0)
4229 {
4230 s=newSViv(image->filter);
4231 (void) sv_setpv(s,MagickOptionToMnemonic(MagickFilterOptions,
4232 image->filter));
4233 SvIOK_on(s);
4234 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4235 continue;
4236 }
4237 if (LocaleCompare(attribute,"font") == 0)
4238 {
4239 if (info && info->image_info->font)
4240 s=newSVpv(info->image_info->font,0);
4241 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4242 continue;
4243 }
4244 if (LocaleCompare(attribute,"foreground") == 0)
4245 continue;
4246 if (LocaleCompare(attribute,"format") == 0)
4247 {
4248 const MagickInfo
4249 *magick_info;
4250
4251 magick_info=(const MagickInfo *) NULL;
4252 if (info && (*info->image_info->magick != '\0'))
4253 magick_info=GetMagickInfo(info->image_info->magick,exception);
4254 if (image != (Image *) NULL)
4255 magick_info=GetMagickInfo(image->magick,&image->exception);
4256 if ((magick_info != (const MagickInfo *) NULL) &&
4257 (*magick_info->description != '\0'))
4258 s=newSVpv((char *) magick_info->description,0);
4259 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4260 continue;
4261 }
4262 if (LocaleCompare(attribute,"fuzz") == 0)
4263 {
4264 if (info)
4265 s=newSVnv(info->image_info->fuzz);
4266 if (image != (Image *) NULL)
4267 s=newSVnv(image->fuzz);
4268 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4269 continue;
4270 }
4271 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4272 attribute);
4273 break;
4274 }
4275 case 'G':
4276 case 'g':
4277 {
4278 if (LocaleCompare(attribute,"gamma") == 0)
4279 {
4280 if (image != (Image *) NULL)
4281 s=newSVnv(image->gamma);
4282 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4283 continue;
4284 }
4285 if (LocaleCompare(attribute,"geometry") == 0)
4286 {
4287 if (image && image->geometry)
4288 s=newSVpv(image->geometry,0);
4289 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4290 continue;
4291 }
4292 if (LocaleCompare(attribute,"gravity") == 0)
4293 {
4294 s=newSViv(image->gravity);
4295 (void) sv_setpv(s,
4296 MagickOptionToMnemonic(MagickGravityOptions,image->gravity));
4297 SvIOK_on(s);
4298 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4299 continue;
4300 }
4301 if (LocaleCompare(attribute,"green-primary") == 0)
4302 {
4303 if (image == (Image *) NULL)
4304 break;
4305 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
4306 image->chromaticity.green_primary.x,
4307 image->chromaticity.green_primary.y);
4308 s=newSVpv(color,0);
4309 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4310 continue;
4311 }
4312 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4313 attribute);
4314 break;
4315 }
4316 case 'H':
4317 case 'h':
4318 {
4319 if (LocaleCompare(attribute,"height") == 0)
4320 {
4321 if (image != (Image *) NULL)
4322 s=newSViv((long) image->rows);
4323 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4324 continue;
4325 }
4326 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4327 attribute);
4328 break;
4329 }
4330 case 'I':
4331 case 'i':
4332 {
4333 if (LocaleCompare(attribute,"icc") == 0)
4334 {
4335 if (image != (Image *) NULL)
4336 {
4337 const StringInfo
4338 *profile;
4339
4340 profile=GetImageProfile(image,"icc");
4341 if (profile != (StringInfo *) NULL)
4342 s=newSVpv((const char *) GetStringInfoDatum(profile),
4343 GetStringInfoLength(profile));
4344 }
4345 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4346 continue;
4347 }
4348 if (LocaleCompare(attribute,"icm") == 0)
4349 {
4350 if (image != (Image *) NULL)
4351 {
4352 const StringInfo
4353 *profile;
4354
4355 profile=GetImageProfile(image,"icm");
4356 if (profile != (const StringInfo *) NULL)
4357 s=newSVpv((const char *) GetStringInfoDatum(profile),
4358 GetStringInfoLength(profile));
4359 }
4360 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4361 continue;
4362 }
4363 if (LocaleCompare(attribute,"id") == 0)
4364 {
4365 if (image != (Image *) NULL)
4366 s=newSViv(SetMagickRegistry(ImageRegistryType,image,0,
4367 &image->exception));
4368 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4369 continue;
4370 }
4371 if (LocaleNCompare(attribute,"index",5) == 0)
4372 {
4373 char
4374 name[MaxTextExtent];
4375
4376 int
4377 items;
4378
4379 long
4380 x,
4381 y;
4382
4383 register const IndexPacket
4384 *indexes;
4385
4386 register const PixelPacket
4387 *p;
4388
4389 CacheView
4390 *image_view;
4391
4392 if (image == (Image *) NULL)
4393 break;
4394 if (image->storage_class != PseudoClass)
4395 break;
4396 x=0;
4397 y=0;
4398 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
4399 image_view=OpenCacheView(image);
4400 p=AcquireCacheViewPixels(image_view,x,y,1,1,&image->exception);
4401 if (p != (const PixelPacket *) NULL)
4402 {
4403 indexes=AcquireCacheViewIndexes(image_view);
4404 (void) FormatMagickString(name,MaxTextExtent,QuantumFormat,
4405 *indexes);
4406 s=newSVpv(name,0);
4407 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4408 }
4409 image_view=CloseCacheView(image_view);
4410 continue;
4411 }
4412 if (LocaleCompare(attribute,"iptc") == 0)
4413 {
4414 if (image != (Image *) NULL)
4415 {
4416 const StringInfo
4417 *profile;
4418
4419 profile=GetImageProfile(image,"iptc");
4420 if (profile != (const StringInfo *) NULL)
4421 s=newSVpv((const char *) GetStringInfoDatum(profile),
4422 GetStringInfoLength(profile));
4423 }
4424 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4425 continue;
4426 }
4427 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
4428 {
4429 if (image != (Image *) NULL)
4430 s=newSViv((long) image->iterations);
4431 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4432 continue;
4433 }
4434 if (LocaleCompare(attribute,"interlace") == 0)
4435 {
4436 j=info ? info->image_info->interlace : image->interlace;
4437 s=newSViv(j);
4438 (void) sv_setpv(s,MagickOptionToMnemonic(MagickInterlaceOptions,
4439 j));
4440 SvIOK_on(s);
4441 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4442 continue;
4443 }
4444 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4445 attribute);
4446 break;
4447 }
4448 case 'L':
4449 case 'l':
4450 {
4451 if (LocaleCompare(attribute,"label") == 0)
4452 {
4453 const char
4454 *value;
4455
4456 if (image == (Image *) NULL)
4457 break;
4458 value=GetImageProperty(image,"Label");
4459 if (value != (const char *) NULL)
4460 s=newSVpv(value,0);
4461 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4462 continue;
4463 }
4464 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
4465 {
4466 if (image != (Image *) NULL)
4467 s=newSViv((long) image->iterations);
4468 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4469 continue;
4470 }
4471 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4472 attribute);
4473 break;
4474 }
4475 case 'M':
4476 case 'm':
4477 {
4478 if (LocaleCompare(attribute,"magick") == 0)
4479 {
4480 if (info && *info->image_info->magick)
4481 s=newSVpv(info->image_info->magick,0);
4482 if (image != (Image *) NULL)
4483 s=newSVpv(image->magick,0);
4484 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4485 continue;
4486 }
4487 if (LocaleCompare(attribute,"map") == 0)
4488 {
4489 s=newSViv(GetMagickResource(MapResource));
4490 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4491 continue;
4492 }
4493 if (LocaleCompare(attribute,"maximum-error") == 0)
4494 {
4495 if (image != (Image *) NULL)
4496 s=newSVnv(image->error.normalized_maximum_error);
4497 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4498 continue;
4499 }
4500 if (LocaleCompare(attribute,"memory") == 0)
4501 {
4502 s=newSViv(GetMagickResource(MemoryResource));
4503 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4504 continue;
4505 }
4506 if (LocaleCompare(attribute,"mean-error") == 0)
4507 {
4508 if (image != (Image *) NULL)
4509 s=newSVnv(image->error.normalized_mean_error);
4510 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4511 continue;
4512 }
4513 if (LocaleCompare(attribute,"mime") == 0)
4514 {
4515 if (info && *info->image_info->magick)
4516 s=newSVpv(MagickToMime(info->image_info->magick),0);
4517 if (image != (Image *) NULL)
4518 s=newSVpv(MagickToMime(image->magick),0);
4519 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4520 continue;
4521 }
4522 if (LocaleCompare(attribute,"monochrome") == 0)
4523 {
4524 if (image == (Image *) NULL)
4525 continue;
4526 j=info ? info->image_info->monochrome :
4527 IsMonochromeImage(image,&image->exception);
4528 s=newSViv(j);
4529 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4530 continue;
4531 }
4532 if (LocaleCompare(attribute,"mattecolor") == 0)
4533 {
4534 if (image == (Image *) NULL)
4535 break;
4536 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
4537 QuantumFormat "," QuantumFormat "," QuantumFormat,
4538 image->matte_color.red,image->matte_color.green,
4539 image->matte_color.blue,image->matte_color.opacity);
4540 s=newSVpv(color,0);
4541 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4542 continue;
4543 }
4544 if (LocaleCompare(attribute,"matte") == 0)
4545 {
4546 if (image != (Image *) NULL)
4547 s=newSViv((long) image->matte);
4548 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4549 continue;
4550 }
4551 if (LocaleCompare(attribute,"montage") == 0)
4552 {
4553 if (image && image->montage)
4554 s=newSVpv(image->montage,0);
4555 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4556 continue;
4557 }
4558 if (LocaleCompare(attribute,"mime") == 0)
4559 {
4560 const char
4561 *magick;
4562
4563 magick=NULL;
4564 if (info && *info->image_info->magick)
4565 magick=info->image_info->magick;
4566 if (image != (Image *) NULL)
4567 magick=image->magick;
4568 if (magick)
4569 {
4570 char
4571 *mime;
4572
4573 mime=MagickToMime(magick);
4574 s=newSVpv(mime,0);
4575 mime=(char *) RelinquishMagickMemory(mime);
4576 }
4577 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4578 continue;
4579 }
4580 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4581 attribute);
4582 break;
4583 }
4584 case 'O':
4585 case 'o':
4586 {
4587 if (LocaleCompare(attribute,"orientation") == 0)
4588 {
4589 j=info ? info->image_info->orientation : image->orientation;
4590 s=newSViv(j);
4591 (void) sv_setpv(s,MagickOptionToMnemonic(MagickOrientationOptions,
4592 j));
4593 SvIOK_on(s);
4594 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4595 continue;
4596 }
4597 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4598 attribute);
4599 break;
4600 }
4601 case 'P':
4602 case 'p':
4603 {
4604 if (LocaleCompare(attribute,"page") == 0)
4605 {
4606 if (info && info->image_info->page)
4607 s=newSVpv(info->image_info->page,0);
4608 if (image != (Image *) NULL)
4609 {
4610 char
4611 geometry[MaxTextExtent];
4612
4613 (void) FormatMagickString(geometry,MaxTextExtent,
4614 "%lux%lu%+ld%+ld",image->page.width,image->page.height,
4615 image->page.x,image->page.y);
4616 s=newSVpv(geometry,0);
4617 }
4618 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4619 continue;
4620 }
4621 if (LocaleCompare(attribute,"page.x") == 0)
4622 {
4623 if (image != (Image *) NULL)
4624 s=newSViv((long) image->page.x);
4625 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4626 continue;
4627 }
4628 if (LocaleCompare(attribute,"page.y") == 0)
4629 {
4630 if (image != (Image *) NULL)
4631 s=newSViv((long) image->page.y);
4632 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4633 continue;
4634 }
4635 if (LocaleNCompare(attribute,"pixel",5) == 0)
4636 {
4637 char
4638 tuple[MaxTextExtent];
4639
4640 int
4641 items;
4642
4643 long
4644 x,
4645 y;
4646
4647 register const PixelPacket
4648 *p;
4649
4650 register const IndexPacket
4651 *indexes;
4652
4653 if (image == (Image *) NULL)
4654 break;
4655 x=0;
4656 y=0;
4657 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
4658 p=GetVirtualPixels(image,x,y,1,1,exception);
4659 indexes=AcquireIndexes(image);
4660 if (image->colorspace != CMYKColorspace)
4661 (void) FormatMagickString(tuple,MaxTextExtent,QuantumFormat ","
4662 QuantumFormat "," QuantumFormat "," QuantumFormat,
4663 p->red,p->green,p->blue,p->opacity);
4664 else
4665 (void) FormatMagickString(tuple,MaxTextExtent,QuantumFormat ","
4666 QuantumFormat "," QuantumFormat "," QuantumFormat ","
4667 QuantumFormat,p->red,p->green,p->blue,*indexes,p->opacity);
4668 s=newSVpv(tuple,0);
4669 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4670 continue;
4671 }
4672 if (LocaleCompare(attribute,"pointsize") == 0)
4673 {
4674 if (info)
4675 s=newSViv((long) info->image_info->pointsize);
4676 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4677 continue;
4678 }
4679 if (LocaleCompare(attribute,"preview") == 0)
4680 {
4681 s=newSViv(info->image_info->preview_type);
4682 (void) sv_setpv(s,MagickOptionToMnemonic(MagickPreviewOptions,
4683 info->image_info->preview_type));
4684 SvIOK_on(s);
4685 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4686 continue;
4687 }
4688 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4689 attribute);
4690 break;
4691 }
4692 case 'Q':
4693 case 'q':
4694 {
4695 if (LocaleCompare(attribute,"quality") == 0)
4696 {
4697 if (info)
4698 s=newSViv((long) info->image_info->quality);
4699 if (image != (Image *) NULL)
4700 s=newSViv((long) image->quality);
4701 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4702 continue;
4703 }
4704 if (LocaleCompare(attribute,"quantum") == 0)
4705 {
4706 if (info)
4707 s=newSViv((long) MAGICKCORE_QUANTUM_DEPTH);
4708 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4709 continue;
4710 }
4711 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4712 attribute);
4713 break;
4714 }
4715 case 'R':
4716 case 'r':
4717 {
4718 if (LocaleCompare(attribute,"rendering-intent") == 0)
4719 {
4720 s=newSViv(image->rendering_intent);
4721 (void) sv_setpv(s,MagickOptionToMnemonic(MagickIntentOptions,
4722 image->rendering_intent));
4723 SvIOK_on(s);
4724 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4725 continue;
4726 }
4727 if (LocaleCompare(attribute,"red-primary") == 0)
4728 {
4729 if (image == (Image *) NULL)
4730 break;
4731 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
4732 image->chromaticity.red_primary.x,
4733 image->chromaticity.red_primary.y);
4734 s=newSVpv(color,0);
4735 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4736 continue;
4737 }
4738 if (LocaleCompare(attribute,"rows") == 0)
4739 {
4740 if (image != (Image *) NULL)
4741 s=newSViv((long) image->rows);
4742 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4743 continue;
4744 }
4745 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4746 attribute);
4747 break;
4748 }
4749 case 'S':
4750 case 's':
4751 {
4752 if (LocaleCompare(attribute,"sampling-factor") == 0)
4753 {
4754 if (info && info->image_info->sampling_factor)
4755 s=newSVpv(info->image_info->sampling_factor,0);
4756 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4757 continue;
4758 }
4759 if (LocaleCompare(attribute,"subimage") == 0)
4760 {
4761 if (info)
4762 s=newSViv((long) info->image_info->subimage);
4763 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4764 continue;
4765 }
4766 if (LocaleCompare(attribute,"subrange") == 0)
4767 {
4768 if (info)
4769 s=newSViv((long) info->image_info->subrange);
4770 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4771 continue;
4772 }
4773 if (LocaleCompare(attribute,"server") == 0) /* same as display */
4774 {
4775 if (info && info->image_info->server_name)
4776 s=newSVpv(info->image_info->server_name,0);
4777 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4778 continue;
4779 }
4780 if (LocaleCompare(attribute,"size") == 0)
4781 {
4782 if (info && info->image_info->size)
4783 s=newSVpv(info->image_info->size,0);
4784 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4785 continue;
4786 }
4787 if (LocaleCompare(attribute,"scene") == 0)
4788 {
4789 if (image != (Image *) NULL)
4790 s=newSViv((long) image->scene);
4791 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4792 continue;
4793 }
4794 if (LocaleCompare(attribute,"scenes") == 0)
4795 {
4796 if (image != (Image *) NULL)
4797 s=newSViv((long) info->image_info->number_scenes);
4798 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4799 continue;
4800 }
4801 if (LocaleCompare(attribute,"signature") == 0)
4802 {
4803 const char
4804 *value;
4805
4806 if (image == (Image *) NULL)
4807 break;
4808 (void) SignatureImage(image);
4809 value=GetImageProperty(image,"Signature");
4810 if (value != (const char *) NULL)
4811 s=newSVpv(value,0);
4812 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4813 continue;
4814 }
4815 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4816 attribute);
4817 break;
4818 }
4819 case 'T':
4820 case 't':
4821 {
4822 if (LocaleCompare(attribute,"taint") == 0)
4823 {
4824 if (image != (Image *) NULL)
4825 s=newSViv((long) IsTaintImage(image));
4826 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4827 continue;
4828 }
4829 if (LocaleCompare(attribute,"tile") == 0)
4830 {
4831 if (info && info->image_info->tile)
4832 s=newSVpv(info->image_info->tile,0);
4833 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4834 continue;
4835 }
4836 if (LocaleCompare(attribute,"texture") == 0)
4837 {
4838 if (info && info->image_info->texture)
4839 s=newSVpv(info->image_info->texture,0);
4840 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4841 continue;
4842 }
4843 if (LocaleCompare(attribute,"total-ink-density") == 0)
4844 {
4845 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4846 if (image != (Image *) NULL)
4847 s=newSVnv(GetImageTotalInkDensity(image));
4848 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4849 continue;
4850 }
4851 if (LocaleCompare(attribute,"type") == 0)
4852 {
4853 if (image == (Image *) NULL)
4854 break;
4855 j=(long) GetImageType(image,&image->exception);
4856 s=newSViv(j);
4857 (void) sv_setpv(s,MagickOptionToMnemonic(MagickTypeOptions,j));
4858 SvIOK_on(s);
4859 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4860 continue;
4861 }
4862 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4863 attribute);
4864 break;
4865 }
4866 case 'U':
4867 case 'u':
4868 {
4869 if (LocaleCompare(attribute,"units") == 0)
4870 {
4871 j=info ? info->image_info->units : image->units;
4872 if (info)
4873 if (info->image_info->units == UndefinedResolution)
4874 j=image->units;
4875 if (j == UndefinedResolution)
4876 s=newSVpv("undefined units",0);
4877 else
4878 if (j == PixelsPerInchResolution)
4879 s=newSVpv("pixels / inch",0);
4880 else
4881 s=newSVpv("pixels / centimeter",0);
4882 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4883 continue;
4884 }
4885 if (LocaleCompare(attribute,"user-time") == 0)
4886 {
4887 if (image != (Image *) NULL)
4888 s=newSVnv(GetUserTime(&image->timer));
4889 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4890 continue;
4891 }
4892 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4893 attribute);
4894 break;
4895 }
4896 case 'V':
4897 case 'v':
4898 {
4899 if (LocaleCompare(attribute,"verbose") == 0)
4900 {
4901 if (info)
4902 s=newSViv((long) info->image_info->verbose);
4903 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4904 continue;
4905 }
4906 if (LocaleCompare(attribute,"version") == 0)
4907 {
4908 s=newSVpv(GetMagickVersion((unsigned long *) NULL),0);
4909 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4910 continue;
4911 }
4912 if (LocaleCompare(attribute,"view") == 0)
4913 {
4914 if (info && info->image_info->view)
4915 s=newSVpv(info->image_info->view,0);
4916 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4917 continue;
4918 }
4919 if (LocaleCompare(attribute,"virtual-pixel") == 0)
4920 {
4921 if (image == (Image *) NULL)
4922 break;
4923 j=(long) GetImageVirtualPixelMethod(image);
4924 s=newSViv(j);
4925 (void) sv_setpv(s,MagickOptionToMnemonic(
4926 MagickVirtualPixelOptions,j));
4927 SvIOK_on(s);
4928 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4929 continue;
4930 }
4931 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4932 attribute);
4933 break;
4934 }
4935 case 'W':
4936 case 'w':
4937 {
4938 if (LocaleCompare(attribute,"white-point") == 0)
4939 {
4940 if (image == (Image *) NULL)
4941 break;
4942 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
4943 image->chromaticity.white_point.x,
4944 image->chromaticity.white_point.y);
4945 s=newSVpv(color,0);
4946 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4947 continue;
4948 }
4949 if (LocaleCompare(attribute,"width") == 0)
4950 {
4951 if (image != (Image *) NULL)
4952 s=newSViv((long) image->columns);
4953 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4954 continue;
4955 }
4956 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4957 attribute);
4958 break;
4959 }
4960 case 'X':
4961 case 'x':
4962 {
4963 if (LocaleCompare(attribute,"x-resolution") == 0)
4964 {
4965 if (image != (Image *) NULL)
4966 s=newSVnv(image->x_resolution);
4967 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4968 continue;
4969 }
4970 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4971 attribute);
4972 break;
4973 }
4974 case 'Y':
4975 case 'y':
4976 {
4977 if (LocaleCompare(attribute,"y-resolution") == 0)
4978 {
4979 if (image != (Image *) NULL)
4980 s=newSVnv(image->y_resolution);
4981 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4982 continue;
4983 }
4984 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4985 attribute);
4986 break;
4987 }
4988 default:
4989 break;
4990 }
4991 if (image == (Image *) NULL)
4992 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4993 attribute)
4994 else
4995 {
4996 value=GetImageProperty(image,attribute);
4997 if (value != (const char *) NULL)
4998 {
4999 s=newSVpv(value,0);
5000 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5001 }
5002 else
5003 if (*attribute != '%')
5004 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5005 attribute)
5006 else
5007 {
5008 char
5009 *meta;
5010
5011 meta=InterpretImageProperties(info ? info->image_info :
5012 (ImageInfo *) NULL,image,attribute);
5013 s=newSVpv(meta,0);
5014 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5015 meta=(char *) RelinquishMagickMemory(meta);
5016 }
5017 }
5018 }
5019 exception=DestroyExceptionInfo(exception);
5020 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5021 }
5022
5023#
5024###############################################################################
5025# #
5026# #
5027# #
5028# G e t A u t h e n t i c P i x e l s #
5029# #
5030# #
5031# #
5032###############################################################################
5033#
5034#
5035void *
5036GetAuthenticPixels(ref,...)
5037 Image::Magick ref = NO_INIT
5038 ALIAS:
5039 getauthenticpixels = 1
5040 GetImagePixels = 2
5041 getimagepixels = 3
5042 CODE:
5043 {
5044 char
5045 *attribute;
5046
5047 ExceptionInfo
5048 *exception;
5049
5050 Image
5051 *image;
5052
5053 long
5054 i;
5055
5056 RectangleInfo
5057 region;
5058
5059 struct PackageInfo
5060 *info;
5061
5062 SV
5063 *perl_exception,
5064 *reference;
5065
5066 void
5067 *blob = NULL;
5068
5069 exception=AcquireExceptionInfo();
5070 perl_exception=newSVpv("",0);
5071 if (sv_isobject(ST(0)) == 0)
5072 {
5073 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5074 PackageName);
5075 goto PerlException;
5076 }
5077 reference=SvRV(ST(0));
5078
5079 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5080 if (image == (Image *) NULL)
5081 {
5082 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5083 PackageName);
5084 goto PerlException;
5085 }
5086
5087 region.x=0;
5088 region.y=0;
5089 region.width=image->columns;
5090 region.height=1;
5091 if (items == 1)
5092 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5093 for (i=2; i < items; i+=2)
5094 {
5095 attribute=(char *) SvPV(ST(i-1),na);
5096 switch (*attribute)
5097 {
5098 case 'g':
5099 case 'G':
5100 {
5101 if (LocaleCompare(attribute,"geometry") == 0)
5102 {
5103 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5104 break;
5105 }
5106 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5107 attribute);
5108 break;
5109 }
5110 case 'H':
5111 case 'h':
5112 {
5113 if (LocaleCompare(attribute,"height") == 0)
5114 {
5115 region.height=SvIV(ST(i));
5116 continue;
5117 }
5118 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5119 attribute);
5120 break;
5121 }
5122 case 'X':
5123 case 'x':
5124 {
5125 if (LocaleCompare(attribute,"x") == 0)
5126 {
5127 region.x=SvIV(ST(i));
5128 continue;
5129 }
5130 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5131 attribute);
5132 break;
5133 }
5134 case 'Y':
5135 case 'y':
5136 {
5137 if (LocaleCompare(attribute,"y") == 0)
5138 {
5139 region.y=SvIV(ST(i));
5140 continue;
5141 }
5142 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5143 attribute);
5144 break;
5145 }
5146 case 'W':
5147 case 'w':
5148 {
5149 if (LocaleCompare(attribute,"width") == 0)
5150 {
5151 region.width=SvIV(ST(i));
5152 continue;
5153 }
5154 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5155 attribute);
5156 break;
5157 }
5158 }
5159 }
5160 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5161 region.height,exception);
5162 if (blob != (void *) NULL)
5163 goto PerlEnd;
5164
5165 PerlException:
5166 InheritPerlException(exception,perl_exception);
5167 exception=DestroyExceptionInfo(exception);
5168 SvREFCNT_dec(perl_exception); /* throw away all errors */
5169
5170 PerlEnd:
5171 RETVAL = blob;
5172 }
5173 OUTPUT:
5174 RETVAL
5175
5176#
5177###############################################################################
5178# #
5179# #
5180# #
5181# G e t V i r t u a l P i x e l s #
5182# #
5183# #
5184# #
5185###############################################################################
5186#
5187#
5188void *
5189GetVirtualPixels(ref,...)
5190 Image::Magick ref = NO_INIT
5191 ALIAS:
5192 getvirtualpixels = 1
5193 AcquireImagePixels = 2
5194 acquireimagepixels = 3
5195 CODE:
5196 {
5197 char
5198 *attribute;
5199
5200 const void
5201 *blob = NULL;
5202
5203 ExceptionInfo
5204 *exception;
5205
5206 Image
5207 *image;
5208
5209 long
5210 i;
5211
5212 RectangleInfo
5213 region;
5214
5215 struct PackageInfo
5216 *info;
5217
5218 SV
5219 *perl_exception,
5220 *reference;
5221
5222 exception=AcquireExceptionInfo();
5223 perl_exception=newSVpv("",0);
5224 if (sv_isobject(ST(0)) == 0)
5225 {
5226 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5227 PackageName);
5228 goto PerlException;
5229 }
5230 reference=SvRV(ST(0));
5231
5232 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5233 if (image == (Image *) NULL)
5234 {
5235 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5236 PackageName);
5237 goto PerlException;
5238 }
5239
5240 region.x=0;
5241 region.y=0;
5242 region.width=image->columns;
5243 region.height=1;
5244 if (items == 1)
5245 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5246 for (i=2; i < items; i+=2)
5247 {
5248 attribute=(char *) SvPV(ST(i-1),na);
5249 switch (*attribute)
5250 {
5251 case 'g':
5252 case 'G':
5253 {
5254 if (LocaleCompare(attribute,"geometry") == 0)
5255 {
5256 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5257 break;
5258 }
5259 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5260 attribute);
5261 break;
5262 }
5263 case 'H':
5264 case 'h':
5265 {
5266 if (LocaleCompare(attribute,"height") == 0)
5267 {
5268 region.height=SvIV(ST(i));
5269 continue;
5270 }
5271 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5272 attribute);
5273 break;
5274 }
5275 case 'X':
5276 case 'x':
5277 {
5278 if (LocaleCompare(attribute,"x") == 0)
5279 {
5280 region.x=SvIV(ST(i));
5281 continue;
5282 }
5283 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5284 attribute);
5285 break;
5286 }
5287 case 'Y':
5288 case 'y':
5289 {
5290 if (LocaleCompare(attribute,"y") == 0)
5291 {
5292 region.y=SvIV(ST(i));
5293 continue;
5294 }
5295 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5296 attribute);
5297 break;
5298 }
5299 case 'W':
5300 case 'w':
5301 {
5302 if (LocaleCompare(attribute,"width") == 0)
5303 {
5304 region.width=SvIV(ST(i));
5305 continue;
5306 }
5307 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5308 attribute);
5309 break;
5310 }
5311 }
5312 }
5313 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
5314 region.height,exception);
5315 if (blob != (void *) NULL)
5316 goto PerlEnd;
5317
5318 PerlException:
5319 InheritPerlException(exception,perl_exception);
5320 exception=DestroyExceptionInfo(exception);
5321 SvREFCNT_dec(perl_exception); /* throw away all errors */
5322
5323 PerlEnd:
5324 RETVAL = (void *) blob;
5325 }
5326 OUTPUT:
5327 RETVAL
5328
5329#
5330###############################################################################
5331# #
5332# #
5333# #
5334# G e t A u t h e n t i c I n d e x Q u e u e #
5335# #
5336# #
5337# #
5338###############################################################################
5339#
5340#
5341void *
5342GetAuthenticIndexQueue(ref,...)
5343 Image::Magick ref = NO_INIT
5344 ALIAS:
5345 getauthenticindexqueue = 1
5346 GetIndexes = 2
5347 getindexes = 3
5348 CODE:
5349 {
5350 ExceptionInfo
5351 *exception;
5352
5353 Image
5354 *image;
5355
5356 struct PackageInfo
5357 *info;
5358
5359 SV
5360 *perl_exception,
5361 *reference;
5362
5363 void
5364 *blob = NULL;
5365
5366 exception=AcquireExceptionInfo();
5367 perl_exception=newSVpv("",0);
5368 if (sv_isobject(ST(0)) == 0)
5369 {
5370 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5371 PackageName);
5372 goto PerlException;
5373 }
5374 reference=SvRV(ST(0));
5375
5376 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5377 if (image == (Image *) NULL)
5378 {
5379 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5380 PackageName);
5381 goto PerlException;
5382 }
5383
5384 blob=(void *) GetAuthenticIndexQueue(image);
5385 if (blob != (void *) NULL)
5386 goto PerlEnd;
5387
5388 PerlException:
5389 InheritPerlException(exception,perl_exception);
5390 exception=DestroyExceptionInfo(exception);
5391 SvREFCNT_dec(perl_exception); /* throw away all errors */
5392
5393 PerlEnd:
5394 RETVAL = blob;
5395 }
5396 OUTPUT:
5397 RETVAL
5398
5399#
5400###############################################################################
5401# #
5402# #
5403# #
5404# G e t V i r t u a l I n d e x Q u e u e #
5405# #
5406# #
5407# #
5408###############################################################################
5409#
5410#
5411void *
5412GetVirtualIndexQueue(ref,...)
5413 Image::Magick ref = NO_INIT
5414 ALIAS:
5415 getvirtualindexqueue = 1
5416 CODE:
5417 {
5418 ExceptionInfo
5419 *exception;
5420
5421 Image
5422 *image;
5423
5424 struct PackageInfo
5425 *info;
5426
5427 SV
5428 *perl_exception,
5429 *reference;
5430
5431 void
5432 *blob = NULL;
5433
5434 exception=AcquireExceptionInfo();
5435 perl_exception=newSVpv("",0);
5436 if (sv_isobject(ST(0)) == 0)
5437 {
5438 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5439 PackageName);
5440 goto PerlException;
5441 }
5442 reference=SvRV(ST(0));
5443
5444 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5445 if (image == (Image *) NULL)
5446 {
5447 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5448 PackageName);
5449 goto PerlException;
5450 }
5451
5452 blob=(void *) GetVirtualIndexQueue(image);
5453 if (blob != (void *) NULL)
5454 goto PerlEnd;
5455
5456 PerlException:
5457 InheritPerlException(exception,perl_exception);
5458 exception=DestroyExceptionInfo(exception);
5459 SvREFCNT_dec(perl_exception); /* throw away all errors */
5460
5461 PerlEnd:
5462 RETVAL = blob;
5463 }
5464 OUTPUT:
5465 RETVAL
5466
5467#
5468###############################################################################
5469# #
5470# #
5471# #
5472# H i s t o g r a m #
5473# #
5474# #
5475# #
5476###############################################################################
5477#
5478#
5479void
5480Histogram(ref,...)
5481 Image::Magick ref=NO_INIT
5482 ALIAS:
5483 HistogramImage = 1
5484 histogram = 2
5485 histogramimage = 3
5486 PPCODE:
5487 {
5488 AV
5489 *av;
5490
5491 char
5492 message[MaxTextExtent];
5493
5494 ColorPacket
5495 *histogram;
5496
5497 ExceptionInfo
5498 *exception;
5499
5500 HV
5501 *hv;
5502
5503 Image
5504 *image;
5505
5506 register long
5507 i;
5508
5509 ssize_t
5510 count;
5511
5512 struct PackageInfo
5513 *info;
5514
5515 SV
5516 *av_reference,
5517 *perl_exception,
5518 *reference;
5519
5520 unsigned long
5521 number_colors;
5522
5523 exception=AcquireExceptionInfo();
5524 perl_exception=newSVpv("",0);
5525 av=NULL;
5526 if (sv_isobject(ST(0)) == 0)
5527 {
5528 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5529 PackageName);
5530 goto PerlException;
5531 }
5532 reference=SvRV(ST(0));
5533 hv=SvSTASH(reference);
5534 av=newAV();
5535 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
5536 SvREFCNT_dec(av);
5537 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5538 if (image == (Image *) NULL)
5539 {
5540 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5541 PackageName);
5542 goto PerlException;
5543 }
5544 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
5545 count=0;
5546 for ( ; image; image=image->next)
5547 {
5548 histogram=GetImageHistogram(image,&number_colors,&image->exception);
5549 if (histogram == (ColorPacket *) NULL)
5550 continue;
5551 count+=number_colors;
5552 EXTEND(sp,6*count);
5553 for (i=0; i < (long) number_colors; i++)
5554 {
5555 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5556 histogram[i].pixel.red);
5557 PUSHs(sv_2mortal(newSVpv(message,0)));
5558 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5559 histogram[i].pixel.green);
5560 PUSHs(sv_2mortal(newSVpv(message,0)));
5561 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5562 histogram[i].pixel.blue);
5563 PUSHs(sv_2mortal(newSVpv(message,0)));
5564 if (image->colorspace == CMYKColorspace)
5565 {
5566 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5567 histogram[i].index);
5568 PUSHs(sv_2mortal(newSVpv(message,0)));
5569 }
5570 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5571 histogram[i].pixel.opacity);
5572 PUSHs(sv_2mortal(newSVpv(message,0)));
5573 (void) FormatMagickString(message,MaxTextExtent,"%lu",
5574 (unsigned long) histogram[i].count);
5575 PUSHs(sv_2mortal(newSVpv(message,0)));
5576 }
5577 histogram=(ColorPacket *) RelinquishMagickMemory(histogram);
5578 }
5579
5580 PerlException:
5581 InheritPerlException(exception,perl_exception);
5582 exception=DestroyExceptionInfo(exception);
5583 SvREFCNT_dec(perl_exception);
5584 }
5585
5586#
5587###############################################################################
5588# #
5589# #
5590# #
5591# G e t P i x e l #
5592# #
5593# #
5594# #
5595###############################################################################
5596#
5597#
5598void
5599GetPixel(ref,...)
5600 Image::Magick ref=NO_INIT
5601 ALIAS:
5602 getpixel = 1
5603 getPixel = 2
5604 PPCODE:
5605 {
5606 AV
5607 *av;
5608
5609 char
5610 *attribute;
5611
5612 ChannelType
5613 channel;
5614
5615 ExceptionInfo
5616 *exception;
5617
5618 Image
5619 *image;
5620
5621 long
5622 option;
5623
5624 MagickBooleanType
5625 normalize;
5626
5627 RectangleInfo
5628 region;
5629
5630 register const IndexPacket
5631 *indexes;
5632
5633 register const PixelPacket
5634 *p;
5635
5636 register long
5637 i;
5638
5639 struct PackageInfo
5640 *info;
5641
5642 SV
5643 *perl_exception,
5644 *reference; /* reference is the SV* of ref=SvIV(reference) */
5645
5646 exception=AcquireExceptionInfo();
5647 perl_exception=newSVpv("",0);
5648 reference=SvRV(ST(0));
5649 av=(AV *) reference;
5650 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
5651 exception);
5652 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5653 if (image == (Image *) NULL)
5654 {
5655 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5656 PackageName);
5657 goto PerlException;
5658 }
5659 channel=DefaultChannels;
5660 normalize=MagickTrue;
5661 region.x=0;
5662 region.y=0;
5663 region.width=image->columns;
5664 region.height=1;
5665 if (items == 1)
5666 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5667 for (i=2; i < items; i+=2)
5668 {
5669 attribute=(char *) SvPV(ST(i-1),na);
5670 switch (*attribute)
5671 {
5672 case 'C':
5673 case 'c':
5674 {
5675 if (LocaleCompare(attribute,"channel") == 0)
5676 {
5677 long
5678 option;
5679
5680 option=ParseChannelOption(SvPV(ST(i),na));
5681 if (option < 0)
5682 {
5683 ThrowPerlException(exception,OptionError,"UnrecognizedType",
5684 SvPV(ST(i),na));
5685 return;
5686 }
5687 channel=(ChannelType) option;
5688 break;
5689 }
5690 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5691 attribute);
5692 break;
5693 }
5694 case 'g':
5695 case 'G':
5696 {
5697 if (LocaleCompare(attribute,"geometry") == 0)
5698 {
5699 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5700 break;
5701 }
5702 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5703 attribute);
5704 break;
5705 }
5706 case 'N':
5707 case 'n':
5708 {
5709 if (LocaleCompare(attribute,"normalize") == 0)
5710 {
5711 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
5712 SvPV(ST(i),na));
5713 if (option < 0)
5714 {
5715 ThrowPerlException(exception,OptionError,"UnrecognizedType",
5716 SvPV(ST(i),na));
5717 break;
5718 }
5719 normalize=option != 0 ? MagickTrue : MagickFalse;
5720 break;
5721 }
5722 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5723 attribute);
5724 break;
5725 }
5726 case 'x':
5727 case 'X':
5728 {
5729 if (LocaleCompare(attribute,"x") == 0)
5730 {
5731 region.x=SvIV(ST(i));
5732 break;
5733 }
5734 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5735 attribute);
5736 break;
5737 }
5738 case 'y':
5739 case 'Y':
5740 {
5741 if (LocaleCompare(attribute,"y") == 0)
5742 {
5743 region.y=SvIV(ST(i));
5744 break;
5745 }
5746 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5747 attribute);
5748 break;
5749 }
5750 default:
5751 {
5752 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5753 attribute);
5754 break;
5755 }
5756 }
5757 }
5758 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
5759 if (p == (const PixelPacket *) NULL)
5760 PUSHs(&sv_undef);
5761 else
5762 {
5763 double
5764 scale;
5765
5766 indexes=AcquireIndexes(image);
5767 scale=1.0;
5768 if (normalize != MagickFalse)
5769 scale=1.0/QuantumRange;
5770 if ((channel & RedChannel) != 0)
5771 PUSHs(sv_2mortal(newSVnv(scale*p->red)));
5772 if ((channel & GreenChannel) != 0)
5773 PUSHs(sv_2mortal(newSVnv(scale*p->green)));
5774 if ((channel & BlueChannel) != 0)
5775 PUSHs(sv_2mortal(newSVnv(scale*p->blue)));
5776 if (((channel & IndexChannel) != 0) &&
5777 (image->colorspace == CMYKColorspace))
5778 PUSHs(sv_2mortal(newSVnv(scale*(*indexes))));
5779 if ((channel & OpacityChannel) != 0)
5780 PUSHs(sv_2mortal(newSVnv(scale*p->opacity)));
5781 }
5782
5783 PerlException:
5784 InheritPerlException(exception,perl_exception);
5785 exception=DestroyExceptionInfo(exception);
5786 SvREFCNT_dec(perl_exception);
5787 }
5788
5789#
5790###############################################################################
5791# #
5792# #
5793# #
5794# G e t P i x e l s #
5795# #
5796# #
5797# #
5798###############################################################################
5799#
5800#
5801void
5802GetPixels(ref,...)
5803 Image::Magick ref=NO_INIT
5804 ALIAS:
5805 getpixels = 1
5806 getPixels = 2
5807 PPCODE:
5808 {
5809 AV
5810 *av;
5811
5812 char
5813 *attribute;
5814
5815 const char
5816 *map;
5817
5818 ExceptionInfo
5819 *exception;
5820
5821 Image
5822 *image;
5823
5824 long
5825 option;
5826
5827 MagickBooleanType
5828 normalize,
5829 status;
5830
5831 RectangleInfo
5832 region;
5833
5834 register long
5835 i;
5836
5837 struct PackageInfo
5838 *info;
5839
5840 SV
5841 *perl_exception,
5842 *reference; /* reference is the SV* of ref=SvIV(reference) */
5843
5844 exception=AcquireExceptionInfo();
5845 perl_exception=newSVpv("",0);
5846 reference=SvRV(ST(0));
5847 av=(AV *) reference;
5848 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
5849 exception);
5850 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5851 if (image == (Image *) NULL)
5852 {
5853 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5854 PackageName);
5855 goto PerlException;
5856 }
5857 map="RGB";
5858 if (image->matte != MagickFalse)
5859 map="RGBA";
5860 if (image->colorspace == CMYKColorspace)
5861 {
5862 map="CMYK";
5863 if (image->matte != MagickFalse)
5864 map="CMYKA";
5865 }
5866 normalize=MagickFalse;
5867 region.x=0;
5868 region.y=0;
5869 region.width=image->columns;
5870 region.height=1;
5871 if (items == 1)
5872 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5873 for (i=2; i < items; i+=2)
5874 {
5875 attribute=(char *) SvPV(ST(i-1),na);
5876 switch (*attribute)
5877 {
5878 case 'g':
5879 case 'G':
5880 {
5881 if (LocaleCompare(attribute,"geometry") == 0)
5882 {
5883 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5884 break;
5885 }
5886 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5887 attribute);
5888 break;
5889 }
5890 case 'H':
5891 case 'h':
5892 {
5893 if (LocaleCompare(attribute,"height") == 0)
5894 {
5895 region.height=SvIV(ST(i));
5896 break;
5897 }
5898 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5899 attribute);
5900 break;
5901 }
5902 case 'M':
5903 case 'm':
5904 {
5905 if (LocaleCompare(attribute,"map") == 0)
5906 {
5907 map=SvPV(ST(i),na);
5908 break;
5909 }
5910 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5911 attribute);
5912 break;
5913 }
5914 case 'N':
5915 case 'n':
5916 {
5917 if (LocaleCompare(attribute,"normalize") == 0)
5918 {
5919 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
5920 SvPV(ST(i),na));
5921 if (option < 0)
5922 {
5923 ThrowPerlException(exception,OptionError,"UnrecognizedType",
5924 SvPV(ST(i),na));
5925 break;
5926 }
5927 normalize=option != 0 ? MagickTrue : MagickFalse;
5928 break;
5929 }
5930 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5931 attribute);
5932 break;
5933 }
5934 case 'W':
5935 case 'w':
5936 {
5937 if (LocaleCompare(attribute,"width") == 0)
5938 {
5939 region.width=SvIV(ST(i));
5940 break;
5941 }
5942 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5943 attribute);
5944 break;
5945 }
5946 case 'x':
5947 case 'X':
5948 {
5949 if (LocaleCompare(attribute,"x") == 0)
5950 {
5951 region.x=SvIV(ST(i));
5952 break;
5953 }
5954 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5955 attribute);
5956 break;
5957 }
5958 case 'y':
5959 case 'Y':
5960 {
5961 if (LocaleCompare(attribute,"y") == 0)
5962 {
5963 region.y=SvIV(ST(i));
5964 break;
5965 }
5966 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5967 attribute);
5968 break;
5969 }
5970 default:
5971 {
5972 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5973 attribute);
5974 break;
5975 }
5976 }
5977 }
5978 if (normalize != MagickFalse)
5979 {
5980 float
5981 *pixels;
5982
5983 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
5984 region.height*sizeof(*pixels));
5985 if (pixels == (float *) NULL)
5986 {
5987 ThrowPerlException(exception,ResourceLimitError,
5988 "MemoryAllocationFailed",PackageName);
5989 goto PerlException;
5990 }
5991 status=ExportImagePixels(image,region.x,region.y,region.width,
5992 region.height,map,FloatPixel,pixels,exception);
5993 if (status == MagickFalse)
5994 PUSHs(&sv_undef);
5995 else
5996 {
5997 EXTEND(sp,strlen(map)*region.width*region.height);
5998 for (i=0; i < (long) (strlen(map)*region.width*region.height); i++)
5999 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6000 }
6001 pixels=(float *) RelinquishMagickMemory(pixels);
6002 }
6003 else
6004 {
6005 Quantum
6006 *pixels;
6007
6008 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6009 region.height*sizeof(*pixels));
6010 if (pixels == (Quantum *) NULL)
6011 {
6012 ThrowPerlException(exception,ResourceLimitError,
6013 "MemoryAllocationFailed",PackageName);
6014 goto PerlException;
6015 }
6016 status=ExportImagePixels(image,region.x,region.y,region.width,
6017 region.height,map,QuantumPixel,pixels,exception);
6018 if (status == MagickFalse)
6019 PUSHs(&sv_undef);
6020 else
6021 {
6022 EXTEND(sp,strlen(map)*region.width*region.height);
6023 for (i=0; i < (long) (strlen(map)*region.width*region.height); i++)
6024 PUSHs(sv_2mortal(newSViv(pixels[i])));
6025 }
6026 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6027 }
6028
6029 PerlException:
6030 InheritPerlException(exception,perl_exception);
6031 exception=DestroyExceptionInfo(exception);
6032 SvREFCNT_dec(perl_exception);
6033 }
6034
6035#
6036###############################################################################
6037# #
6038# #
6039# #
6040# I m a g e T o B l o b #
6041# #
6042# #
6043# #
6044###############################################################################
6045#
6046#
6047void
6048ImageToBlob(ref,...)
6049 Image::Magick ref=NO_INIT
6050 ALIAS:
6051 ImageToBlob = 1
6052 imagetoblob = 2
6053 toblob = 3
6054 blob = 4
6055 PPCODE:
6056 {
6057 char
6058 filename[MaxTextExtent];
6059
6060 ExceptionInfo
6061 *exception;
6062
6063 Image
6064 *image,
6065 *next;
6066
6067 long
6068 scene;
6069
6070 register long
6071 i;
6072
6073 struct PackageInfo
6074 *info,
6075 *package_info;
6076
6077 size_t
6078 length;
6079
6080 SV
6081 *perl_exception,
6082 *reference;
6083
6084 void
6085 *blob;
6086
6087 exception=AcquireExceptionInfo();
6088 perl_exception=newSVpv("",0);
6089 package_info=(struct PackageInfo *) NULL;
6090 if (sv_isobject(ST(0)) == 0)
6091 {
6092 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6093 PackageName);
6094 goto PerlException;
6095 }
6096 reference=SvRV(ST(0));
6097 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6098 if (image == (Image *) NULL)
6099 {
6100 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6101 PackageName);
6102 goto PerlException;
6103 }
6104 package_info=ClonePackageInfo(info,exception);
6105 for (i=2; i < items; i+=2)
6106 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6107 (void) CopyMagickString(filename,package_info->image_info->filename,
6108 MaxTextExtent);
6109 scene=0;
6110 for (next=image; next; next=next->next)
6111 {
6112 (void) CopyMagickString(next->filename,filename,MaxTextExtent);
6113 next->scene=scene++;
6114 }
6115 SetImageInfo(package_info->image_info,MagickTrue,&image->exception);
6116 EXTEND(sp,(long) GetImageListLength(image));
6117 for ( ; image; image=image->next)
6118 {
6119 length=0;
6120 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6121 if (blob != (char *) NULL)
6122 {
6123 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6124 blob=(unsigned char *) RelinquishMagickMemory(blob);
6125 }
6126 if (package_info->image_info->adjoin)
6127 break;
6128 }
6129
6130 PerlException:
6131 if (package_info != (struct PackageInfo *) NULL)
6132 DestroyPackageInfo(package_info);
6133 InheritPerlException(exception,perl_exception);
6134 exception=DestroyExceptionInfo(exception);
6135 SvREFCNT_dec(perl_exception); /* throw away all errors */
6136 }
6137
6138#
6139###############################################################################
6140# #
6141# #
6142# #
6143# L a y e r s #
6144# #
6145# #
6146# #
6147###############################################################################
6148#
6149#
6150void
6151Layers(ref,...)
6152 Image::Magick ref=NO_INIT
6153 ALIAS:
6154 Layers = 1
6155 layers = 2
6156 OptimizeImageLayers = 3
6157 optimizelayers = 4
6158 optimizeimagelayers = 5
6159 PPCODE:
6160 {
6161 AV
6162 *av;
6163
6164 char
6165 *attribute;
6166
6167 CompositeOperator
6168 compose;
6169
6170 ExceptionInfo
6171 *exception;
6172
6173 HV
6174 *hv;
6175
6176 Image
6177 *image,
6178 *layers;
6179
6180 long
6181 option,
6182 sp;
6183
6184 MagickBooleanType
6185 dither;
6186
6187 ImageLayerMethod
6188 method;
6189
6190 register long
6191 i;
6192
6193 struct PackageInfo
6194 *info;
6195
6196 SV
6197 *av_reference,
6198 *perl_exception,
6199 *reference,
6200 *rv,
6201 *sv;
6202
6203 exception=AcquireExceptionInfo();
6204 perl_exception=newSVpv("",0);
6205 if (sv_isobject(ST(0)) == 0)
6206 {
6207 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6208 PackageName);
6209 goto PerlException;
6210 }
6211 reference=SvRV(ST(0));
6212 hv=SvSTASH(reference);
6213 av=newAV();
6214 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
6215 SvREFCNT_dec(av);
6216 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6217 if (image == (Image *) NULL)
6218 {
6219 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6220 PackageName);
6221 goto PerlException;
6222 }
6223 compose=image->compose;
6224 dither=MagickFalse;
6225 method=OptimizeLayer;
6226 for (i=2; i < items; i+=2)
6227 {
6228 attribute=(char *) SvPV(ST(i-1),na);
6229 switch (*attribute)
6230 {
6231 case 'C':
6232 case 'c':
6233 {
6234 if (LocaleCompare(attribute,"compose") == 0)
6235 {
6236 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
6237 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
6238 if (sp < 0)
6239 {
6240 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6241 SvPV(ST(i),na));
6242 break;
6243 }
6244 compose=(CompositeOperator) sp;
6245 break;
6246 }
6247 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6248 attribute);
6249 break;
6250 }
6251 case 'D':
6252 case 'd':
6253 {
6254 if (LocaleCompare(attribute,"dither") == 0)
6255 {
6256 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
6257 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
6258 if (sp < 0)
6259 {
6260 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6261 SvPV(ST(i),na));
6262 break;
6263 }
6264 dither=(MagickBooleanType) sp;
6265 break;
6266 }
6267 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6268 attribute);
6269 break;
6270 }
6271 case 'M':
6272 case 'm':
6273 {
6274 if (LocaleCompare(attribute,"method") == 0)
6275 {
6276 option=ParseMagickOption(MagickLayerOptions,MagickFalse,
6277 SvPV(ST(i),na));
6278 if (option < 0)
6279 {
6280 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6281 SvPV(ST(i),na));
6282 break;
6283 }
6284 method=(ImageLayerMethod) option;
6285 break;
6286 }
6287 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6288 attribute);
6289 break;
6290 }
6291 default:
6292 {
6293 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6294 attribute);
6295 break;
6296 }
6297 }
6298 }
6299 layers=(Image *) NULL;
6300 switch (method)
6301 {
6302 case CompareAnyLayer:
6303 case CompareClearLayer:
6304 case CompareOverlayLayer:
6305 default:
6306 {
6307 layers=CompareImageLayers(image,method,exception);
6308 break;
6309 }
6310 case MergeLayer:
6311 case FlattenLayer:
6312 case MosaicLayer:
6313 {
6314 layers=MergeImageLayers(image,method,exception);
6315 break;
6316 }
6317 case DisposeLayer:
6318 {
6319 layers=DisposeImages(image,exception);
6320 break;
6321 }
6322 case OptimizeImageLayer:
6323 {
6324 layers=OptimizeImageLayers(image,exception);
6325 break;
6326 }
6327 case OptimizePlusLayer:
6328 {
6329 layers=OptimizePlusImageLayers(image,exception);
6330 break;
6331 }
6332 case OptimizeTransLayer:
6333 {
6334 OptimizeImageTransparency(image,exception);
6335 InheritException(&(image->exception),exception);
6336 break;
6337 }
6338 case RemoveDupsLayer:
6339 {
6340 RemoveDuplicateLayers(&image,exception);
6341 InheritException(&(image->exception),exception);
6342 break;
6343 }
6344 case RemoveZeroLayer:
6345 {
6346 RemoveZeroDelayLayers(&image,exception);
6347 InheritException(&(image->exception),exception);
6348 break;
6349 }
6350 case OptimizeLayer:
6351 {
6352 QuantizeInfo
6353 *quantize_info;
6354
6355 /*
6356 General Purpose, GIF Animation Optimizer.
6357 */
6358 layers=CoalesceImages(image,exception);
6359 if (layers == (Image *) NULL)
6360 break;
6361 InheritException(&(layers->exception),exception);
6362 image=layers;
6363 layers=OptimizeImageLayers(image,exception);
6364 if (layers == (Image *) NULL)
6365 break;
6366 InheritException(&(layers->exception),exception);
6367 image=DestroyImageList(image);
6368 image=layers;
6369 layers=(Image *) NULL;
6370 OptimizeImageTransparency(image,exception);
6371 InheritException(&(image->exception),exception);
6372 quantize_info=AcquireQuantizeInfo(info->image_info);
6373 (void) RemapImages(quantize_info,image,(Image *) NULL);
6374 quantize_info=DestroyQuantizeInfo(quantize_info);
6375 break;
6376 }
6377 case CompositeLayer:
6378 {
6379 Image
6380 *source;
6381
6382 RectangleInfo
6383 geometry;
6384
6385 /*
6386 Split image sequence at the first 'NULL:' image.
6387 */
6388 source=image;
6389 while (source != (Image *) NULL)
6390 {
6391 source=GetNextImageInList(source);
6392 if ((source != (Image *) NULL) &&
6393 (LocaleCompare(source->magick,"NULL") == 0))
6394 break;
6395 }
6396 if (source != (Image *) NULL)
6397 {
6398 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
6399 (GetNextImageInList(source) == (Image *) NULL))
6400 source=(Image *) NULL;
6401 else
6402 {
6403 /*
6404 Separate the two lists, junk the null: image.
6405 */
6406 source=SplitImageList(source->previous);
6407 DeleteImageFromList(&source);
6408 }
6409 }
6410 if (source == (Image *) NULL)
6411 {
6412 (void) ThrowMagickException(exception,GetMagickModule(),
6413 OptionError,"MissingNullSeparator","layers Composite");
6414 break;
6415 }
6416 /*
6417 Adjust offset with gravity and virtual canvas.
6418 */
6419 SetGeometry(image,&geometry);
6420 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
6421 geometry.width=source->page.width != 0 ? source->page.width :
6422 source->columns;
6423 geometry.height=source->page.height != 0 ? source->page.height :
6424 source->rows;
6425 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
6426 image->columns,image->page.height != 0 ? image->page.height :
6427 image->rows,image->gravity,&geometry);
6428 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
6429 source=DestroyImageList(source);
6430 InheritException(&(image->exception),exception);
6431 break;
6432 }
6433 }
6434 if (layers != (Image *) NULL)
6435 {
6436 InheritException(&(layers->exception),exception);
6437 image=layers;
6438 }
6439 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
6440 goto PerlException;
6441 for ( ; image; image=image->next)
6442 {
6443 AddImageToRegistry(image);
6444 rv=newRV(sv);
6445 av_push(av,sv_bless(rv,hv));
6446 SvREFCNT_dec(sv);
6447 }
6448 exception=DestroyExceptionInfo(exception);
6449 ST(0)=av_reference;
6450 SvREFCNT_dec(perl_exception);
6451 XSRETURN(1);
6452
6453 PerlException:
6454 InheritPerlException(exception,perl_exception);
6455 exception=DestroyExceptionInfo(exception);
6456 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
6457 SvPOK_on(perl_exception);
6458 ST(0)=sv_2mortal(perl_exception);
6459 XSRETURN(1);
6460 }
6461
6462#
6463###############################################################################
6464# #
6465# #
6466# #
6467# M a g i c k T o M i m e #
6468# #
6469# #
6470# #
6471###############################################################################
6472#
6473#
6474SV *
6475MagickToMime(ref,name)
6476 Image::Magick ref=NO_INIT
6477 char *name
6478 ALIAS:
6479 magicktomime = 1
6480 CODE:
6481 {
6482 char
6483 *mime;
6484
6485 mime=MagickToMime(name);
6486 RETVAL=newSVpv(mime,0);
6487 mime=(char *) RelinquishMagickMemory(mime);
6488 }
6489 OUTPUT:
6490 RETVAL
6491
6492#
6493###############################################################################
6494# #
6495# #
6496# #
6497# M o g r i f y #
6498# #
6499# #
6500# #
6501###############################################################################
6502#
6503#
6504void
6505Mogrify(ref,...)
6506 Image::Magick ref=NO_INIT
6507 ALIAS:
6508 Comment = 1
6509 CommentImage = 2
6510 Label = 3
6511 LabelImage = 4
6512 AddNoise = 5
6513 AddNoiseImage = 6
6514 Colorize = 7
6515 ColorizeImage = 8
6516 Border = 9
6517 BorderImage = 10
6518 Blur = 11
6519 BlurImage = 12
6520 Chop = 13
6521 ChopImage = 14
6522 Crop = 15
6523 CropImage = 16
6524 Despeckle = 17
6525 DespeckleImage = 18
6526 Edge = 19
6527 EdgeImage = 20
6528 Emboss = 21
6529 EmbossImage = 22
6530 Enhance = 23
6531 EnhanceImage = 24
6532 Flip = 25
6533 FlipImage = 26
6534 Flop = 27
6535 FlopImage = 28
6536 Frame = 29
6537 FrameImage = 30
6538 Implode = 31
6539 ImplodeImage = 32
6540 Magnify = 33
6541 MagnifyImage = 34
6542 MedianFilter = 35
6543 MedianFilterImage = 36
6544 Minify = 37
6545 MinifyImage = 38
6546 OilPaint = 39
6547 OilPaintImage = 40
6548 ReduceNoise = 41
6549 ReduceNoiseImage = 42
6550 Roll = 43
6551 RollImage = 44
6552 Rotate = 45
6553 RotateImage = 46
6554 Sample = 47
6555 SampleImage = 48
6556 Scale = 49
6557 ScaleImage = 50
6558 Shade = 51
6559 ShadeImage = 52
6560 Sharpen = 53
6561 SharpenImage = 54
6562 Shear = 55
6563 ShearImage = 56
6564 Spread = 57
6565 SpreadImage = 58
6566 Swirl = 59
6567 SwirlImage = 60
6568 Resize = 61
6569 ResizeImage = 62
6570 Zoom = 63
6571 ZoomImage = 64
6572 Annotate = 65
6573 AnnotateImage = 66
6574 ColorFloodfill = 67
6575 ColorFloodfillImage= 68
6576 Composite = 69
6577 CompositeImage = 70
6578 Contrast = 71
6579 ContrastImage = 72
6580 CycleColormap = 73
6581 CycleColormapImage = 74
6582 Draw = 75
6583 DrawImage = 76
6584 Equalize = 77
6585 EqualizeImage = 78
6586 Gamma = 79
6587 GammaImage = 80
6588 Map = 81
6589 MapImage = 82
6590 MatteFloodfill = 83
6591 MatteFloodfillImage= 84
6592 Modulate = 85
6593 ModulateImage = 86
6594 Negate = 87
6595 NegateImage = 88
6596 Normalize = 89
6597 NormalizeImage = 90
6598 NumberColors = 91
6599 NumberColorsImage = 92
6600 Opaque = 93
6601 OpaqueImage = 94
6602 Quantize = 95
6603 QuantizeImage = 96
6604 Raise = 97
6605 RaiseImage = 98
6606 Segment = 99
6607 SegmentImage = 100
6608 Signature = 101
6609 SignatureImage = 102
6610 Solarize = 103
6611 SolarizeImage = 104
6612 Sync = 105
6613 SyncImage = 106
6614 Texture = 107
6615 TextureImage = 108
6616 Evaluate = 109
6617 EvaluateImage = 110
6618 Transparent = 111
6619 TransparentImage = 112
6620 Threshold = 113
6621 ThresholdImage = 114
6622 Charcoal = 115
6623 CharcoalImage = 116
6624 Trim = 117
6625 TrimImage = 118
6626 Wave = 119
6627 WaveImage = 120
6628 Separate = 121
6629 SeparateImage = 122
6630 Stereo = 125
6631 StereoImage = 126
6632 Stegano = 127
6633 SteganoImage = 128
6634 Deconstruct = 129
6635 DeconstructImage = 130
6636 GaussianBlur = 131
6637 GaussianBlurImage = 132
6638 Convolve = 133
6639 ConvolveImage = 134
6640 Profile = 135
6641 ProfileImage = 136
6642 UnsharpMask = 137
6643 UnsharpMaskImage = 138
6644 MotionBlur = 139
6645 MotionBlurImage = 140
6646 OrderedDither = 141
6647 OrderedDitherImage = 142
6648 Shave = 143
6649 ShaveImage = 144
6650 Level = 145
6651 LevelImage = 146
6652 Clip = 147
6653 ClipImage = 148
6654 AffineTransform = 149
6655 AffineTransformImage = 150
6656 Difference = 151
6657 DifferenceImage = 152
6658 AdaptiveThreshold = 153
6659 AdaptiveThresholdImage = 154
6660 Resample = 155
6661 ResampleImage = 156
6662 Describe = 157
6663 DescribeImage = 158
6664 BlackThreshold = 159
6665 BlackThresholdImage= 160
6666 WhiteThreshold = 161
6667 WhiteThresholdImage= 162
6668 RadialBlur = 163
6669 RadialBlurImage = 164
6670 Thumbnail = 165
6671 ThumbnailImage = 166
6672 Strip = 167
6673 StripImage = 168
6674 Tint = 169
6675 TintImage = 170
6676 Channel = 171
6677 ChannelImage = 172
6678 Splice = 173
6679 SpliceImage = 174
6680 Posterize = 175
6681 PosterizeImage = 176
6682 Shadow = 177
6683 ShadowImage = 178
6684 Identify = 179
6685 IdentifyImage = 180
6686 SepiaTone = 181
6687 SepiaToneImage = 182
6688 SigmoidalContrast = 183
6689 SigmoidalContrastImage = 184
6690 Extent = 185
6691 ExtentImage = 186
6692 Vignette = 187
6693 VignetteImage = 188
6694 ContrastStretch = 189
6695 ContrastStretchImage = 190
6696 Sans0 = 191
6697 Sans0Image = 192
6698 Sans1 = 193
6699 Sans1Image = 194
6700 AdaptiveSharpen = 195
6701 AdaptiveSharpenImage = 196
6702 Transpose = 197
6703 TransposeImage = 198
6704 Transverse = 199
6705 TransverseImage = 200
6706 AutoOrient = 201
6707 AutoOrientImage = 202
6708 AdaptiveBlur = 203
6709 AdaptiveBlurImage = 204
6710 Sketch = 205
6711 SketchImage = 206
6712 UniqueColors = 207
6713 UniqueColorsImage = 208
6714 AdaptiveResize = 209
6715 AdaptiveResizeImage= 210
6716 ClipMask = 211
6717 ClipMaskImage = 212
6718 LinearStretch = 213
6719 LinearStretchImage = 214
6720 RecolorImage = 215
6721 Recolor = 216
6722 Mask = 217
6723 MaskImage = 218
6724 Polaroid = 219
6725 PolaroidImage = 220
6726 FloodfillPaint = 221
6727 FloodfillPaintImage= 222
6728 Distort = 223
6729 DistortImage = 224
6730 Clut = 225
6731 ClutImage = 226
6732 LiquidRescale = 227
6733 LiquidRescaleImage = 228
6734 Encipher = 229
6735 EncipherImage = 230
6736 Decipher = 231
6737 DecipherImage = 232
6738 Deskew = 233
6739 DeskewImage = 234
6740 Remap = 235
6741 RemapImage = 236
6742 SparseColor = 237
6743 SparseColorImage = 238
6744 Function = 239
6745 FunctionImage = 240
6746 SelectiveBlur = 241
6747 SelectiveBlurImage = 242
6748 HaldClut = 243
6749 HaldClutImage = 244
6750 BlueShift = 245
6751 BlueShiftImage = 246
6752 ForwardFourierTransform = 247
6753 ForwardFourierTransformImage = 248
6754 InverseFourierTransform = 249
6755 InverseFourierTransformImage = 250
6756 ColorDecisionList = 251
6757 ColorDecisionListImage = 252
6758 AutoGamma = 253
6759 AutoGammaImage = 254
6760 AutoLevel = 255
6761 AutoLevelImage = 256
6762 MogrifyRegion = 666
6763 PPCODE:
6764 {
6765 AffineMatrix
6766 affine,
6767 current;
6768
6769 char
6770 attribute_flag[MaxArguments],
6771 message[MaxTextExtent];
6772
6773 ChannelType
6774 channel;
6775
6776 CompositeOperator
6777 compose;
6778
6779 const char
6780 *attribute,
6781 *value;
6782
6783 double
6784 angle;
6785
6786 ExceptionInfo
6787 *exception;
6788
6789 GeometryInfo
6790 geometry_info;
6791
6792 Image
6793 *image,
6794 *next,
6795 *region_image;
6796
6797 long
6798 base,
6799 j,
6800 number_images;
6801
6802 MagickBooleanType
6803 status;
6804
6805 MagickStatusType
6806 flags;
6807
6808 PixelPacket
6809 fill_color;
6810
6811 RectangleInfo
6812 geometry,
6813 region_info;
6814
6815 register long
6816 i;
6817
6818 struct PackageInfo
6819 *info;
6820
6821 struct Methods
6822 *rp;
6823
6824 SV
6825 *perl_exception,
6826 **pv,
6827 *reference,
6828 **reference_vector;
6829
6830 struct ArgumentList
6831 argument_list[MaxArguments];
6832
6833 exception=AcquireExceptionInfo();
6834 perl_exception=newSVpv("",0);
6835 reference_vector=NULL;
6836 region_image=NULL;
6837 number_images=0;
6838 base=2;
6839 if (sv_isobject(ST(0)) == 0)
6840 {
6841 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6842 PackageName);
6843 goto PerlException;
6844 }
6845 reference=SvRV(ST(0));
6846 region_info.width=0;
6847 region_info.height=0;
6848 region_info.x=0;
6849 region_info.y=0;
6850 region_image=(Image *) NULL;
6851 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
6852 if (ix && (ix != 666))
6853 {
6854 /*
6855 Called as Method(...)
6856 */
6857 ix=(ix+1)/2;
6858 rp=(&Methods[ix-1]);
6859 attribute=rp->name;
6860 }
6861 else
6862 {
6863 /*
6864 Called as Mogrify("Method",...)
6865 */
6866 attribute=(char *) SvPV(ST(1),na);
6867 if (ix)
6868 {
6869 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
6870 attribute=(char *) SvPV(ST(2),na);
6871 base++;
6872 }
6873 for (rp=Methods; ; rp++)
6874 {
6875 if (rp >= EndOf(Methods))
6876 {
6877 ThrowPerlException(exception,OptionError,
6878 "UnrecognizedPerlMagickMethod",attribute);
6879 goto PerlException;
6880 }
6881 if (strEQcase(attribute,rp->name))
6882 break;
6883 }
6884 ix=rp-Methods+1;
6885 base++;
6886 }
6887 if (image == (Image *) NULL)
6888 {
6889 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
6890 goto PerlException;
6891 }
6892 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
6893 Zero(&attribute_flag,NumberOf(attribute_flag),char);
6894 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
6895 {
6896 long
6897 longest;
6898
6899 Arguments
6900 *pp,
6901 *qq;
6902
6903 struct ArgumentList
6904 *al;
6905
6906 SV
6907 *sv;
6908
6909 longest=0;
6910 pp=(Arguments *) NULL;
6911 qq=rp->arguments;
6912 if (i == items)
6913 {
6914 pp=rp->arguments,
6915 sv=ST(i-1);
6916 }
6917 else
6918 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
6919 {
6920 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
6921 break;
6922 if (strEQcase(attribute,qq->method) > longest)
6923 {
6924 pp=qq;
6925 longest=strEQcase(attribute,qq->method);
6926 }
6927 }
6928 if (pp == (Arguments *) NULL)
6929 {
6930 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6931 attribute);
6932 goto continue_outer_loop;
6933 }
6934 al=(&argument_list[pp-rp->arguments]);
6935 switch (pp->type)
6936 {
6937 case ArrayReference:
6938 {
6939 if (SvTYPE(sv) != SVt_RV)
6940 {
6941 (void) FormatMagickString(message,MaxTextExtent,
6942 "invalid %.60s value",pp->method);
6943 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
6944 goto continue_outer_loop;
6945 }
6946 al->array_reference=SvRV(sv);
6947 break;
6948 }
6949 case RealReference:
6950 {
6951 al->real_reference=SvNV(sv);
6952 break;
6953 }
6954 case FileReference:
6955 {
6956 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
6957 break;
6958 }
6959 case ImageReference:
6960 {
6961 if (!sv_isobject(sv) ||
6962 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
6963 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
6964 {
6965 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6966 PackageName);
6967 goto PerlException;
6968 }
6969 break;
6970 }
6971 case IntegerReference:
6972 {
6973 al->long_reference=SvIV(sv);
6974 break;
6975 }
6976 case StringReference:
6977 {
6978 al->string_reference=(char *) SvPV(sv,al->length);
6979 if (sv_isobject(sv))
6980 al->image_reference=SetupList(aTHX_ SvRV(sv),
6981 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
6982 break;
6983 }
6984 default:
6985 {
6986 /*
6987 Is a string; look up name.
6988 */
6989 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
6990 {
6991 al->string_reference=(char *) SvPV(sv,al->length);
6992 al->long_reference=(-1);
6993 break;
6994 }
6995 al->long_reference=ParseMagickOption((MagickOption) pp->type,
6996 MagickFalse,SvPV(sv,na));
6997 if (pp->type == MagickChannelOptions)
6998 al->long_reference=ParseChannelOption(SvPV(sv,na));
6999 if ((al->long_reference < 0) && ((al->long_reference=SvIV(sv)) <= 0))
7000 {
7001 (void) FormatMagickString(message,MaxTextExtent,
7002 "invalid %.60s value",pp->method);
7003 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7004 goto continue_outer_loop;
7005 }
7006 break;
7007 }
7008 }
7009 attribute_flag[pp-rp->arguments]++;
7010 continue_outer_loop: ;
7011 }
7012 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7013 pv=reference_vector;
7014 SetGeometryInfo(&geometry_info);
7015 channel=DefaultChannels;
7016 for (next=image; next; next=next->next)
7017 {
7018 image=next;
7019 SetGeometry(image,&geometry);
7020 if ((region_info.width*region_info.height) != 0)
7021 {
7022 region_image=image;
7023 image=CropImage(image,&region_info,exception);
7024 }
7025 switch (ix)
7026 {
7027 default:
7028 {
7029 (void) FormatMagickString(message,MaxTextExtent,"%ld",(long) ix);
7030 ThrowPerlException(exception,OptionError,
7031 "UnrecognizedPerlMagickMethod",message);
7032 goto PerlException;
7033 }
7034 case 1: /* Comment */
7035 {
7036 if (attribute_flag[0] == 0)
7037 argument_list[0].string_reference=(char *) NULL;
7038 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7039 info ? info->image_info : (ImageInfo *) NULL,image,
7040 argument_list[0].string_reference));
7041 break;
7042 }
7043 case 2: /* Label */
7044 {
7045 if (attribute_flag[0] == 0)
7046 argument_list[0].string_reference=(char *) NULL;
7047 (void) SetImageProperty(image,"label",InterpretImageProperties(
7048 info ? info->image_info : (ImageInfo *) NULL,image,
7049 argument_list[0].string_reference));
7050 break;
7051 }
7052 case 3: /* AddNoise */
7053 {
7054 if (attribute_flag[0] == 0)
7055 argument_list[0].long_reference=UniformNoise;
7056 if (attribute_flag[1] != 0)
7057 channel=(ChannelType) argument_list[1].long_reference;
7058 image=AddNoiseImageChannel(image,channel,(NoiseType)
7059 argument_list[0].long_reference,exception);
7060 break;
7061 }
7062 case 4: /* Colorize */
7063 {
7064 PixelPacket
7065 target;
7066
7067 (void) GetOneVirtualPixel(image,0,0,&target,exception);
7068 if (attribute_flag[0] != 0)
7069 (void) QueryColorDatabase(argument_list[0].string_reference,&target,
7070 exception);
7071 if (attribute_flag[1] == 0)
7072 argument_list[1].string_reference="100%";
7073 image=ColorizeImage(image,argument_list[1].string_reference,target,
7074 exception);
7075 break;
7076 }
7077 case 5: /* Border */
7078 {
7079 geometry.width=0;
7080 geometry.height=0;
7081 if (attribute_flag[0] != 0)
7082 {
7083 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7084 &geometry,exception);
7085 if ((flags & HeightValue) == 0)
7086 geometry.height=geometry.width;
7087 }
7088 if (attribute_flag[1] != 0)
7089 geometry.width=argument_list[1].long_reference;
7090 if (attribute_flag[2] != 0)
7091 geometry.height=argument_list[2].long_reference;
7092 if (attribute_flag[3] != 0)
7093 QueryColorDatabase(argument_list[3].string_reference,
7094 &image->border_color,exception);
7095 if (attribute_flag[4] != 0)
7096 QueryColorDatabase(argument_list[4].string_reference,
7097 &image->border_color,exception);
7098 if (attribute_flag[5] != 0)
7099 QueryColorDatabase(argument_list[5].string_reference,
7100 &image->border_color,exception);
7101 if (attribute_flag[6] != 0)
7102 image->compose=(CompositeOperator) argument_list[6].long_reference;
7103 image=BorderImage(image,&geometry,exception);
7104 break;
7105 }
7106 case 6: /* Blur */
7107 {
7108 if (attribute_flag[0] != 0)
7109 {
7110 flags=ParseGeometry(argument_list[0].string_reference,
7111 &geometry_info);
7112 if ((flags & SigmaValue) == 0)
7113 geometry_info.sigma=1.0;
7114 }
7115 if (attribute_flag[1] != 0)
7116 geometry_info.rho=argument_list[1].real_reference;
7117 if (attribute_flag[2] != 0)
7118 geometry_info.sigma=argument_list[2].real_reference;
7119 if (attribute_flag[3] != 0)
7120 channel=(ChannelType) argument_list[3].long_reference;
7121 image=BlurImageChannel(image,channel,geometry_info.rho,
7122 geometry_info.sigma,exception);
7123 break;
7124 }
7125 case 7: /* Chop */
7126 {
7127 if (attribute_flag[0] != 0)
7128 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7129 &geometry,exception);
7130 if (attribute_flag[1] != 0)
7131 geometry.width=argument_list[1].long_reference;
7132 if (attribute_flag[2] != 0)
7133 geometry.height=argument_list[2].long_reference;
7134 if (attribute_flag[3] != 0)
7135 geometry.x=argument_list[3].long_reference;
7136 if (attribute_flag[4] != 0)
7137 geometry.y=argument_list[4].long_reference;
7138 image=ChopImage(image,&geometry,exception);
7139 break;
7140 }
7141 case 8: /* Crop */
7142 {
7143 if (attribute_flag[0] != 0)
7144 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7145 &geometry,exception);
7146 if (attribute_flag[1] != 0)
7147 geometry.width=argument_list[1].long_reference;
7148 if (attribute_flag[2] != 0)
7149 geometry.height=argument_list[2].long_reference;
7150 if (attribute_flag[3] != 0)
7151 geometry.x=argument_list[3].long_reference;
7152 if (attribute_flag[4] != 0)
7153 geometry.y=argument_list[4].long_reference;
7154 if (attribute_flag[5] != 0)
7155 image->fuzz=
7156 StringToDouble(argument_list[5].string_reference,QuantumRange);
7157 image=CropImage(image,&geometry,exception);
7158 break;
7159 }
7160 case 9: /* Despeckle */
7161 {
7162 image=DespeckleImage(image,exception);
7163 break;
7164 }
7165 case 10: /* Edge */
7166 {
7167 if (attribute_flag[0] != 0)
7168 geometry_info.rho=argument_list[0].real_reference;
7169 image=EdgeImage(image,geometry_info.rho,exception);
7170 break;
7171 }
7172 case 11: /* Emboss */
7173 {
7174 if (attribute_flag[0] != 0)
7175 {
7176 flags=ParseGeometry(argument_list[0].string_reference,
7177 &geometry_info);
7178 if ((flags & SigmaValue) == 0)
7179 geometry_info.sigma=1.0;
7180 }
7181 if (attribute_flag[1] != 0)
7182 geometry_info.rho=argument_list[1].real_reference;
7183 if (attribute_flag[2] != 0)
7184 geometry_info.sigma=argument_list[2].real_reference;
7185 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
7186 exception);
7187 break;
7188 }
7189 case 12: /* Enhance */
7190 {
7191 image=EnhanceImage(image,exception);
7192 break;
7193 }
7194 case 13: /* Flip */
7195 {
7196 image=FlipImage(image,exception);
7197 break;
7198 }
7199 case 14: /* Flop */
7200 {
7201 image=FlopImage(image,exception);
7202 break;
7203 }
7204 case 15: /* Frame */
7205 {
7206 FrameInfo
7207 frame_info;
7208
7209 if (attribute_flag[0] != 0)
7210 {
7211 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7212 &geometry,exception);
7213 if ((flags & HeightValue) == 0)
7214 geometry.height=geometry.width;
7215 frame_info.width=geometry.width;
7216 frame_info.height=geometry.height;
7217 frame_info.outer_bevel=geometry.x;
7218 frame_info.inner_bevel=geometry.y;
7219 }
7220 if (attribute_flag[1] != 0)
7221 frame_info.width=argument_list[1].long_reference;
7222 if (attribute_flag[2] != 0)
7223 frame_info.height=argument_list[2].long_reference;
7224 if (attribute_flag[3] != 0)
7225 frame_info.inner_bevel=argument_list[3].long_reference;
7226 if (attribute_flag[4] != 0)
7227 frame_info.outer_bevel=argument_list[4].long_reference;
7228 if (attribute_flag[5] != 0)
7229 QueryColorDatabase(argument_list[5].string_reference,&fill_color,
7230 exception);
7231 if (attribute_flag[6] != 0)
7232 QueryColorDatabase(argument_list[6].string_reference,&fill_color,
7233 exception);
7234 frame_info.x=(long) frame_info.width;
7235 frame_info.y=(long) frame_info.height;
7236 frame_info.width=image->columns+2*frame_info.x;
7237 frame_info.height=image->rows+2*frame_info.y;
7238 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
7239 image->matte_color=fill_color;
7240 if (attribute_flag[7] != 0)
7241 image->compose=(CompositeOperator) argument_list[7].long_reference;
7242 image=FrameImage(image,&frame_info,exception);
7243 break;
7244 }
7245 case 16: /* Implode */
7246 {
7247 if (attribute_flag[0] == 0)
7248 argument_list[0].real_reference=0.5;
7249 if (attribute_flag[1] != 0)
7250 image->interpolate=(InterpolatePixelMethod)
7251 argument_list[1].long_reference;
7252 image=ImplodeImage(image,argument_list[0].real_reference,
7253 exception);
7254 break;
7255 }
7256 case 17: /* Magnify */
7257 {
7258 image=MagnifyImage(image,exception);
7259 break;
7260 }
7261 case 18: /* MedianFilter */
7262 {
7263 if (attribute_flag[0] == 0)
7264 argument_list[0].real_reference=0.0;
7265 image=MedianFilterImage(image,argument_list[0].real_reference,
7266 exception);
7267 break;
7268 }
7269 case 19: /* Minify */
7270 {
7271 image=MinifyImage(image,exception);
7272 break;
7273 }
7274 case 20: /* OilPaint */
7275 {
7276 if (attribute_flag[0] == 0)
7277 argument_list[0].real_reference=0.0;
7278 image=OilPaintImage(image,argument_list[0].real_reference,
7279 exception);
7280 break;
7281 }
7282 case 21: /* ReduceNoise */
7283 {
7284 if (attribute_flag[0] == 0)
7285 argument_list[0].real_reference=0.0;
7286 image=ReduceNoiseImage(image,argument_list[0].real_reference,
7287 exception);
7288 break;
7289 }
7290 case 22: /* Roll */
7291 {
7292 if (attribute_flag[0] != 0)
7293 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7294 &geometry,exception);
7295 if (attribute_flag[1] != 0)
7296 geometry.x=argument_list[1].long_reference;
7297 if (attribute_flag[2] != 0)
7298 geometry.y=argument_list[2].long_reference;
7299 image=RollImage(image,geometry.x,geometry.y,exception);
7300 break;
7301 }
7302 case 23: /* Rotate */
7303 {
7304 if (attribute_flag[0] == 0)
7305 argument_list[0].real_reference=90.0;
7306 if (attribute_flag[1] != 0)
7307 QueryColorDatabase(argument_list[1].string_reference,
7308 &image->background_color,exception);
7309 if (attribute_flag[2] != 0)
7310 QueryColorDatabase(argument_list[2].string_reference,
7311 &image->background_color,exception);
7312 if (attribute_flag[3] != 0)
7313 QueryColorDatabase(argument_list[3].string_reference,
7314 &image->background_color,exception);
7315 image=RotateImage(image,argument_list[0].real_reference,exception);
7316 break;
7317 }
7318 case 24: /* Sample */
7319 {
7320 if (attribute_flag[0] != 0)
7321 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7322 &geometry,exception);
7323 if (attribute_flag[1] != 0)
7324 geometry.width=argument_list[1].long_reference;
7325 if (attribute_flag[2] != 0)
7326 geometry.height=argument_list[2].long_reference;
7327 image=SampleImage(image,geometry.width,geometry.height,exception);
7328 break;
7329 }
7330 case 25: /* Scale */
7331 {
7332 if (attribute_flag[0] != 0)
7333 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7334 &geometry,exception);
7335 if (attribute_flag[1] != 0)
7336 geometry.width=argument_list[1].long_reference;
7337 if (attribute_flag[2] != 0)
7338 geometry.height=argument_list[2].long_reference;
7339 image=ScaleImage(image,geometry.width,geometry.height,exception);
7340 break;
7341 }
7342 case 26: /* Shade */
7343 {
7344 if (attribute_flag[0] != 0)
7345 {
7346 flags=ParseGeometry(argument_list[0].string_reference,
7347 &geometry_info);
7348 if ((flags & SigmaValue) == 0)
7349 geometry_info.sigma=0.0;
7350 }
7351 if (attribute_flag[1] != 0)
7352 geometry_info.rho=argument_list[1].real_reference;
7353 if (attribute_flag[2] != 0)
7354 geometry_info.sigma=argument_list[2].real_reference;
7355 image=ShadeImage(image,
7356 argument_list[3].long_reference != 0 ? MagickTrue : MagickFalse,
7357 geometry_info.rho,geometry_info.sigma,exception);
7358 break;
7359 }
7360 case 27: /* Sharpen */
7361 {
7362 if (attribute_flag[0] != 0)
7363 {
7364 flags=ParseGeometry(argument_list[0].string_reference,
7365 &geometry_info);
7366 if ((flags & SigmaValue) == 0)
7367 geometry_info.sigma=1.0;
7368 }
7369 if (attribute_flag[1] != 0)
7370 geometry_info.rho=argument_list[1].real_reference;
7371 if (attribute_flag[2] != 0)
7372 geometry_info.sigma=argument_list[2].real_reference;
7373 if (attribute_flag[3] != 0)
7374 channel=(ChannelType) argument_list[3].long_reference;
7375 image=SharpenImageChannel(image,channel,geometry_info.rho,
7376 geometry_info.sigma,exception);
7377 break;
7378 }
7379 case 28: /* Shear */
7380 {
7381 if (attribute_flag[0] != 0)
7382 {
7383 flags=ParseGeometry(argument_list[0].string_reference,
7384 &geometry_info);
7385 if ((flags & SigmaValue) == 0)
7386 geometry_info.sigma=geometry_info.rho;
7387 }
7388 if (attribute_flag[1] != 0)
7389 geometry_info.rho=argument_list[1].real_reference;
7390 if (attribute_flag[2] != 0)
7391 geometry_info.sigma=argument_list[2].real_reference;
7392 if (attribute_flag[3] != 0)
7393 QueryColorDatabase(argument_list[3].string_reference,
7394 &image->background_color,exception);
7395 if (attribute_flag[4] != 0)
7396 QueryColorDatabase(argument_list[4].string_reference,
7397 &image->background_color,exception);
7398 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
7399 exception);
7400 break;
7401 }
7402 case 29: /* Spread */
7403 {
7404 if (attribute_flag[0] == 0)
7405 argument_list[0].real_reference=1.0;
7406 image=SpreadImage(image,argument_list[0].real_reference,exception);
7407 break;
7408 }
7409 case 30: /* Swirl */
7410 {
7411 if (attribute_flag[0] == 0)
7412 argument_list[0].real_reference=50.0;
7413 if (attribute_flag[1] != 0)
7414 image->interpolate=(InterpolatePixelMethod)
7415 argument_list[1].long_reference;
7416 image=SwirlImage(image,argument_list[0].real_reference,exception);
7417 break;
7418 }
7419 case 31: /* Resize */
7420 case 32: /* Zoom */
7421 {
7422 if (attribute_flag[0] != 0)
7423 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7424 &geometry,exception);
7425 if (attribute_flag[1] != 0)
7426 geometry.width=argument_list[1].long_reference;
7427 if (attribute_flag[2] != 0)
7428 geometry.height=argument_list[2].long_reference;
7429 if (attribute_flag[3] == 0)
7430 argument_list[3].long_reference=(long) UndefinedFilter;
7431 if (attribute_flag[4] != 0)
7432 SetImageArtifact(image,"filter:support",
7433 argument_list[4].string_reference);
7434 if (attribute_flag[5] == 0)
7435 argument_list[5].real_reference=1.0;
7436 image=ResizeImage(image,geometry.width,geometry.height,
7437 (FilterTypes) argument_list[3].long_reference,
7438 argument_list[5].real_reference,exception);
7439 break;
7440 }
7441 case 33: /* Annotate */
7442 {
7443 DrawInfo
7444 *draw_info;
7445
7446 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
7447 (DrawInfo *) NULL);
7448 if (attribute_flag[0] != 0)
7449 {
7450 char
7451 *text;
7452
7453 text=InterpretImageProperties(info ? info->image_info :
7454 (ImageInfo *) NULL,image,argument_list[0].string_reference);
7455 (void) CloneString(&draw_info->text,text);
7456 text=DestroyString(text);
7457 }
7458 if (attribute_flag[1] != 0)
7459 (void) CloneString(&draw_info->font,
7460 argument_list[1].string_reference);
7461 if (attribute_flag[2] != 0)
7462 draw_info->pointsize=argument_list[2].real_reference;
7463 if (attribute_flag[3] != 0)
7464 (void) CloneString(&draw_info->density,
7465 argument_list[3].string_reference);
7466 if (attribute_flag[4] != 0)
7467 (void) QueryColorDatabase(argument_list[4].string_reference,
7468 &draw_info->undercolor,exception);
7469 if (attribute_flag[5] != 0)
7470 {
7471 (void) QueryColorDatabase(argument_list[5].string_reference,
7472 &draw_info->stroke,exception);
7473 if (argument_list[5].image_reference != (Image *) NULL)
7474 draw_info->stroke_pattern=CloneImage(
7475 argument_list[5].image_reference,0,0,MagickTrue,exception);
7476 }
7477 if (attribute_flag[6] != 0)
7478 {
7479 (void) QueryColorDatabase(argument_list[6].string_reference,
7480 &draw_info->fill,exception);
7481 if (argument_list[6].image_reference != (Image *) NULL)
7482 draw_info->fill_pattern=CloneImage(
7483 argument_list[6].image_reference,0,0,MagickTrue,exception);
7484 }
7485 if (attribute_flag[7] != 0)
7486 {
7487 (void) CloneString(&draw_info->geometry,
7488 argument_list[7].string_reference);
7489 flags=ParsePageGeometry(image,argument_list[7].string_reference,
7490 &geometry,exception);
7491 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
7492 geometry_info.sigma=geometry_info.xi;
7493 }
7494 if (attribute_flag[8] != 0)
7495 (void) QueryColorDatabase(argument_list[8].string_reference,
7496 &draw_info->fill,exception);
7497 if (attribute_flag[11] != 0)
7498 draw_info->gravity=(GravityType) argument_list[11].long_reference;
7499 if (attribute_flag[25] != 0)
7500 {
7501 AV
7502 *av;
7503
7504 av=(AV *) argument_list[25].array_reference;
7505 if ((av_len(av) != 3) && (av_len(av) != 5))
7506 {
7507 ThrowPerlException(exception,OptionError,
7508 "affine matrix must have 4 or 6 elements",PackageName);
7509 goto PerlException;
7510 }
7511 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
7512 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
7513 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
7514 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
7515 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
7516 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
7517 {
7518 ThrowPerlException(exception,OptionError,
7519 "affine matrix is singular",PackageName);
7520 goto PerlException;
7521 }
7522 if (av_len(av) == 5)
7523 {
7524 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
7525 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
7526 }
7527 }
7528 for (j=12; j < 17; j++)
7529 {
7530 if (attribute_flag[j] == 0)
7531 continue;
7532 value=argument_list[j].string_reference;
7533 angle=argument_list[j].real_reference;
7534 current=draw_info->affine;
7535 GetAffineMatrix(&affine);
7536 switch (j)
7537 {
7538 case 12:
7539 {
7540 /*
7541 Translate.
7542 */
7543 flags=ParseGeometry(value,&geometry_info);
7544 affine.tx=geometry_info.xi;
7545 affine.ty=geometry_info.psi;
7546 if ((flags & PsiValue) == 0)
7547 affine.ty=affine.tx;
7548 break;
7549 }
7550 case 13:
7551 {
7552 /*
7553 Scale.
7554 */
7555 flags=ParseGeometry(value,&geometry_info);
7556 affine.sx=geometry_info.rho;
7557 affine.sy=geometry_info.sigma;
7558 if ((flags & SigmaValue) == 0)
7559 affine.sy=affine.sx;
7560 break;
7561 }
7562 case 14:
7563 {
7564 /*
7565 Rotate.
7566 */
7567 if (angle == 0.0)
7568 break;
7569 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
7570 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
7571 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
7572 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
7573 break;
7574 }
7575 case 15:
7576 {
7577 /*
7578 SkewX.
7579 */
7580 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
7581 break;
7582 }
7583 case 16:
7584 {
7585 /*
7586 SkewY.
7587 */
7588 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
7589 break;
7590 }
7591 }
7592 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
7593 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
7594 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
7595 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
7596 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
7597 current.tx;
7598 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
7599 current.ty;
7600 }
7601 if (attribute_flag[9] == 0)
7602 argument_list[9].real_reference=0.0;
7603 if (attribute_flag[10] == 0)
7604 argument_list[10].real_reference=0.0;
7605 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
7606 {
7607 char
7608 geometry[MaxTextExtent];
7609
7610 (void) FormatMagickString(geometry,MaxTextExtent,"%+f%+f",
7611 (double) argument_list[9].real_reference+draw_info->affine.tx,
7612 (double) argument_list[10].real_reference+draw_info->affine.ty);
7613 (void) CloneString(&draw_info->geometry,geometry);
7614 }
7615 if (attribute_flag[17] != 0)
7616 draw_info->stroke_width=argument_list[17].real_reference;
7617 if (attribute_flag[18] != 0)
7618 {
7619 draw_info->text_antialias=argument_list[18].long_reference != 0 ?
7620 MagickTrue : MagickFalse;
7621 draw_info->stroke_antialias=draw_info->text_antialias;
7622 }
7623 if (attribute_flag[19] != 0)
7624 (void) CloneString(&draw_info->family,
7625 argument_list[19].string_reference);
7626 if (attribute_flag[20] != 0)
7627 draw_info->style=(StyleType) argument_list[20].long_reference;
7628 if (attribute_flag[21] != 0)
7629 draw_info->stretch=(StretchType) argument_list[21].long_reference;
7630 if (attribute_flag[22] != 0)
7631 draw_info->weight=argument_list[22].long_reference;
7632 if (attribute_flag[23] != 0)
7633 draw_info->align=(AlignType) argument_list[23].long_reference;
7634 if (attribute_flag[24] != 0)
7635 (void) CloneString(&draw_info->encoding,
7636 argument_list[24].string_reference);
7637 if (attribute_flag[25] != 0)
7638 draw_info->fill_pattern=CloneImage(
7639 argument_list[25].image_reference,0,0,MagickTrue,exception);
7640 if (attribute_flag[26] != 0)
7641 draw_info->fill_pattern=CloneImage(
7642 argument_list[26].image_reference,0,0,MagickTrue,exception);
7643 if (attribute_flag[27] != 0)
7644 draw_info->stroke_pattern=CloneImage(
7645 argument_list[27].image_reference,0,0,MagickTrue,exception);
7646 if (attribute_flag[29] != 0)
7647 draw_info->kerning=argument_list[29].real_reference;
7648 if (attribute_flag[30] != 0)
cristyb32b90a2009-09-07 21:45:48 +00007649 draw_info->interline_spacing=argument_list[30].real_reference;
7650 if (attribute_flag[31] != 0)
7651 draw_info->interword_spacing=argument_list[31].real_reference;
cristy3ed852e2009-09-05 21:47:34 +00007652 (void) AnnotateImage(image,draw_info);
7653 draw_info=DestroyDrawInfo(draw_info);
7654 break;
7655 }
7656 case 34: /* ColorFloodfill */
7657 {
7658 DrawInfo
7659 *draw_info;
7660
7661 MagickBooleanType
7662 invert;
7663
7664 MagickPixelPacket
7665 target;
7666
7667 draw_info=CloneDrawInfo(info ? info->image_info :
7668 (ImageInfo *) NULL,(DrawInfo *) NULL);
7669 if (attribute_flag[0] != 0)
7670 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7671 &geometry,exception);
7672 if (attribute_flag[1] != 0)
7673 geometry.x=argument_list[1].long_reference;
7674 if (attribute_flag[2] != 0)
7675 geometry.y=argument_list[2].long_reference;
7676 if (attribute_flag[3] != 0)
7677 (void) QueryColorDatabase(argument_list[3].string_reference,
7678 &draw_info->fill,exception);
7679 (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target,
7680 exception);
7681 invert=MagickFalse;
7682 if (attribute_flag[4] != 0)
7683 {
7684 QueryMagickColor(argument_list[4].string_reference,&target,
7685 exception);
7686 invert=MagickTrue;
7687 }
7688 if (attribute_flag[5] != 0)
7689 image->fuzz=StringToDouble(argument_list[5].string_reference,
7690 QuantumRange);
7691 if (attribute_flag[6] != 0)
7692 invert=(MagickBooleanType) argument_list[6].long_reference;
7693 (void) FloodfillPaintImage(image,DefaultChannels,draw_info,&target,
7694 geometry.x,geometry.y,invert);
7695 draw_info=DestroyDrawInfo(draw_info);
7696 break;
7697 }
7698 case 35: /* Composite */
7699 {
7700 char
7701 composite_geometry[MaxTextExtent];
7702
7703 Image
7704 *composite_image,
7705 *rotate_image;
7706
7707 compose=OverCompositeOp;
7708 if (attribute_flag[0] != 0)
7709 composite_image=argument_list[0].image_reference;
7710 else
7711 {
7712 ThrowPerlException(exception,OptionError,
7713 "CompositeImageRequired",PackageName);
7714 goto PerlException;
7715 }
7716 /*
7717 Parameter Handling used for BOTH normal and tiled composition.
7718 */
7719 if (attribute_flag[1] != 0) /* compose */
7720 compose=(CompositeOperator) argument_list[1].long_reference;
7721 if (attribute_flag[6] != 0) /* opacity */
7722 {
7723 if (compose != DissolveCompositeOp)
7724 (void) SetImageOpacity(composite_image,(Quantum) (QuantumRange-
7725 StringToDouble(argument_list[6].string_reference,
7726 QuantumRange)));
7727 else
7728 {
7729 double
7730 opacity;
7731
7732 long
7733 y;
7734
7735 MagickBooleanType
7736 sync;
7737
7738 register long
7739 x;
7740
7741 register PixelPacket
7742 *q;
7743
7744 CacheView
7745 *composite_view;
7746
7747 /*
7748 Handle dissolve composite operator (patch by
7749 Kevin A. McGrail).
7750 */
7751 (void) CloneString(&image->geometry,
7752 argument_list[6].string_reference);
7753 opacity=(Quantum) (QuantumRange-StringToDouble(
7754 argument_list[6].string_reference,QuantumRange));
7755 if (composite_image->matte != MagickTrue)
7756 (void) SetImageOpacity(composite_image,OpaqueOpacity);
7757 composite_view=OpenCacheView(composite_image);
7758 for (y=0; y < (long) composite_image->rows ; y++)
7759 {
7760 q=GetCacheViewPixels(composite_view,0,y,(long)
7761 composite_image->columns,1);
7762 for (x=0; x < (long) composite_image->columns; x++)
7763 {
7764 if (q->opacity == OpaqueOpacity)
7765 q->opacity=RoundToQuantum(opacity);
7766 q++;
7767 }
7768 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
7769 if (sync == MagickFalse)
7770 break;
7771 }
7772 composite_view=CloseCacheView(composite_view);
7773 }
7774 }
7775 if (attribute_flag[9] != 0) /* "color=>" */
7776 QueryColorDatabase(argument_list[9].string_reference,
7777 &composite_image->background_color,exception);
7778 if (attribute_flag[12] != 0) /* "interpolate=>" */
7779 image->interpolate=(InterpolatePixelMethod)
7780 argument_list[12].long_reference;
7781 if (attribute_flag[13] != 0) /* "args=>" */
7782 (void) SetImageArtifact(composite_image,"compose:args",
7783 argument_list[13].string_reference);
7784 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
7785 (void) SetImageArtifact(composite_image,"compose:args",
7786 argument_list[14].string_reference);
7787 /*
7788 Tiling Composition (with orthogonal rotate).
7789 */
7790 rotate_image=(Image *) NULL;
7791 if (attribute_flag[8] != 0) /* "rotate=>" */
7792 {
7793 /*
7794 Rotate image.
7795 */
7796 rotate_image=RotateImage(composite_image,
7797 argument_list[8].real_reference,exception);
7798 if (rotate_image == (Image *) NULL)
7799 break;
7800 }
7801 if (attribute_flag[7] && argument_list[7].long_reference) /* tile */
7802 {
7803 long
7804 x,
7805 y;
7806
7807 /*
7808 Tile the composite image.
7809 */
7810 if (attribute_flag[8] != 0) /* "tile=>" */
7811 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
7812 "false");
7813 else
7814 (void) SetImageArtifact(composite_image,
7815 "compose:outside-overlay","false");
7816 for (y=0; y < (long) image->rows; y+=composite_image->rows)
7817 for (x=0; x < (long) image->columns; x+=composite_image->columns)
7818 {
7819 if (attribute_flag[8] != 0) /* rotate */
7820 (void) CompositeImage(image,compose,rotate_image,x,y);
7821 else
7822 (void) CompositeImage(image,compose,composite_image,x,y);
7823 }
7824 if (attribute_flag[8] != 0) /* rotate */
7825 rotate_image=DestroyImage(rotate_image);
7826 break;
7827 }
7828 /*
7829 Parameter Handling used used ONLY for normal composition.
7830 */
7831 if (attribute_flag[5] != 0) /* gravity */
7832 image->gravity=(GravityType) argument_list[5].long_reference;
7833 if (attribute_flag[2] != 0) /* geometry offset */
7834 {
7835 SetGeometry(image,&geometry);
7836 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
7837 &geometry);
7838 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
7839 &geometry);
7840 }
7841 if (attribute_flag[3] != 0) /* x offset */
7842 geometry.x=argument_list[3].long_reference;
7843 if (attribute_flag[4] != 0) /* y offset */
7844 geometry.y=argument_list[4].long_reference;
7845 if (attribute_flag[10] != 0) /* mask */
7846 {
7847 if ((image->compose == DisplaceCompositeOp) ||
7848 (image->compose == DistortCompositeOp))
7849 {
7850 /*
7851 Merge Y displacement into X displacement image.
7852 */
7853 composite_image=CloneImage(composite_image,0,0,MagickTrue,
7854 &image->exception);
7855 (void) CompositeImage(composite_image,CopyGreenCompositeOp,
7856 argument_list[10].image_reference,0,0);
7857 }
7858 else
7859 {
7860 /*
7861 Set a blending mask for the composition.
7862 */
7863 image->mask=CloneImage(argument_list[10].image_reference,0,0,
7864 MagickTrue,&image->exception);
7865 (void) NegateImage(image->mask,MagickFalse);
7866 }
7867 }
7868 if (attribute_flag[11] != 0) /* channel */
7869 channel=(ChannelType) argument_list[11].long_reference;
7870 /*
7871 Composite two images (normal composition).
7872 */
7873 (void) FormatMagickString(composite_geometry,MaxTextExtent,
7874 "%lux%lu%+ld%+ld",composite_image->columns,composite_image->rows,
7875 geometry.x,geometry.y);
7876 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
7877 exception);
7878 if (attribute_flag[8] == 0) /* no rotate */
7879 CompositeImageChannel(image,channel,compose,composite_image,
7880 geometry.x,geometry.y);
7881 else
7882 {
7883 /*
7884 Position adjust rotated image then composite.
7885 */
7886 geometry.x-=(long) (rotate_image->columns-
7887 composite_image->columns)/2;
7888 geometry.y-=(long) (rotate_image->rows-composite_image->rows)/2;
7889 CompositeImageChannel(image,channel,compose,rotate_image,
7890 geometry.x,geometry.y);
7891 rotate_image=DestroyImage(rotate_image);
7892 }
7893 if (attribute_flag[10] != 0) /* mask */
7894 {
7895 if ((image->compose == DisplaceCompositeOp) ||
7896 (image->compose == DistortCompositeOp))
7897 composite_image=DestroyImage(composite_image);
7898 else
7899 image->mask=DestroyImage(image->mask);
7900 }
7901 break;
7902 }
7903 case 36: /* Contrast */
7904 {
7905 if (attribute_flag[0] == 0)
7906 argument_list[0].long_reference=0;
7907 (void) ContrastImage(image,argument_list[0].long_reference != 0 ?
7908 MagickTrue : MagickFalse);
7909 break;
7910 }
7911 case 37: /* CycleColormap */
7912 {
7913 if (attribute_flag[0] == 0)
7914 argument_list[0].long_reference=6;
7915 (void) CycleColormapImage(image,argument_list[0].long_reference);
7916 break;
7917 }
7918 case 38: /* Draw */
7919 {
7920 DrawInfo
7921 *draw_info;
7922
7923 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
7924 (DrawInfo *) NULL);
7925 (void) CloneString(&draw_info->primitive,"point");
7926 if (attribute_flag[0] != 0)
7927 {
7928 if (argument_list[0].long_reference < 0)
7929 (void) CloneString(&draw_info->primitive,
7930 argument_list[0].string_reference);
7931 else
7932 (void) CloneString(&draw_info->primitive,MagickOptionToMnemonic(
7933 MagickPrimitiveOptions,argument_list[0].long_reference));
7934 }
7935 if (attribute_flag[1] != 0)
7936 {
7937 if (LocaleCompare(draw_info->primitive,"path") == 0)
7938 {
7939 (void) ConcatenateString(&draw_info->primitive," '");
7940 ConcatenateString(&draw_info->primitive,
7941 argument_list[1].string_reference);
7942 (void) ConcatenateString(&draw_info->primitive,"'");
7943 }
7944 else
7945 {
7946 (void) ConcatenateString(&draw_info->primitive," ");
7947 ConcatenateString(&draw_info->primitive,
7948 argument_list[1].string_reference);
7949 }
7950 }
7951 if (attribute_flag[2] != 0)
7952 {
7953 (void) ConcatenateString(&draw_info->primitive," ");
7954 (void) ConcatenateString(&draw_info->primitive,
7955 MagickOptionToMnemonic(MagickMethodOptions,
7956 argument_list[2].long_reference));
7957 }
7958 if (attribute_flag[3] != 0)
7959 {
7960 (void) QueryColorDatabase(argument_list[3].string_reference,
7961 &draw_info->stroke,exception);
7962 if (argument_list[3].image_reference != (Image *) NULL)
7963 draw_info->stroke_pattern=CloneImage(
7964 argument_list[3].image_reference,0,0,MagickTrue,exception);
7965 }
7966 if (attribute_flag[4] != 0)
7967 {
7968 (void) QueryColorDatabase(argument_list[4].string_reference,
7969 &draw_info->fill,exception);
7970 if (argument_list[4].image_reference != (Image *) NULL)
7971 draw_info->fill_pattern=CloneImage(
7972 argument_list[4].image_reference,0,0,MagickTrue,exception);
7973 }
7974 if (attribute_flag[5] != 0)
7975 draw_info->stroke_width=argument_list[5].real_reference;
7976 if (attribute_flag[6] != 0)
7977 (void) CloneString(&draw_info->font,
7978 argument_list[6].string_reference);
7979 if (attribute_flag[7] != 0)
7980 (void) QueryColorDatabase(argument_list[7].string_reference,
7981 &draw_info->border_color,exception);
7982 if (attribute_flag[8] != 0)
7983 draw_info->affine.tx=argument_list[8].real_reference;
7984 if (attribute_flag[9] != 0)
7985 draw_info->affine.ty=argument_list[9].real_reference;
7986 if (attribute_flag[20] != 0)
7987 {
7988 AV
7989 *av;
7990
7991 av=(AV *) argument_list[20].array_reference;
7992 if ((av_len(av) != 3) && (av_len(av) != 5))
7993 {
7994 ThrowPerlException(exception,OptionError,
7995 "affine matrix must have 4 or 6 elements",PackageName);
7996 goto PerlException;
7997 }
7998 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
7999 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8000 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8001 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8002 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8003 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8004 {
8005 ThrowPerlException(exception,OptionError,
8006 "affine matrix is singular",PackageName);
8007 goto PerlException;
8008 }
8009 if (av_len(av) == 5)
8010 {
8011 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8012 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8013 }
8014 }
8015 for (j=10; j < 15; j++)
8016 {
8017 if (attribute_flag[j] == 0)
8018 continue;
8019 value=argument_list[j].string_reference;
8020 angle=argument_list[j].real_reference;
8021 current=draw_info->affine;
8022 GetAffineMatrix(&affine);
8023 switch (j)
8024 {
8025 case 10:
8026 {
8027 /*
8028 Translate.
8029 */
8030 flags=ParseGeometry(value,&geometry_info);
8031 affine.tx=geometry_info.xi;
8032 affine.ty=geometry_info.psi;
8033 if ((flags & PsiValue) == 0)
8034 affine.ty=affine.tx;
8035 break;
8036 }
8037 case 11:
8038 {
8039 /*
8040 Scale.
8041 */
8042 flags=ParseGeometry(value,&geometry_info);
8043 affine.sx=geometry_info.rho;
8044 affine.sy=geometry_info.sigma;
8045 if ((flags & SigmaValue) == 0)
8046 affine.sy=affine.sx;
8047 break;
8048 }
8049 case 12:
8050 {
8051 /*
8052 Rotate.
8053 */
8054 if (angle == 0.0)
8055 break;
8056 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8057 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8058 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8059 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8060 break;
8061 }
8062 case 13:
8063 {
8064 /*
8065 SkewX.
8066 */
8067 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8068 break;
8069 }
8070 case 14:
8071 {
8072 /*
8073 SkewY.
8074 */
8075 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8076 break;
8077 }
8078 }
8079 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8080 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8081 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8082 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8083 draw_info->affine.tx=
8084 current.sx*affine.tx+current.ry*affine.ty+current.tx;
8085 draw_info->affine.ty=
8086 current.rx*affine.tx+current.sy*affine.ty+current.ty;
8087 }
8088 if (attribute_flag[15] != 0)
8089 draw_info->fill_pattern=CloneImage(
8090 argument_list[15].image_reference,0,0,MagickTrue,exception);
8091 if (attribute_flag[16] != 0)
8092 draw_info->pointsize=argument_list[16].real_reference;
8093 if (attribute_flag[17] != 0)
8094 {
8095 draw_info->stroke_antialias=argument_list[17].long_reference != 0
8096 ? MagickTrue : MagickFalse;
8097 draw_info->text_antialias=draw_info->stroke_antialias;
8098 }
8099 if (attribute_flag[18] != 0)
8100 (void) CloneString(&draw_info->density,
8101 argument_list[18].string_reference);
8102 if (attribute_flag[19] != 0)
8103 draw_info->stroke_width=argument_list[19].real_reference;
8104 if (attribute_flag[21] != 0)
8105 draw_info->dash_offset=argument_list[21].real_reference;
8106 if (attribute_flag[22] != 0)
8107 {
8108 AV
8109 *av;
8110
8111 av=(AV *) argument_list[22].array_reference;
8112 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
8113 av_len(av)+1UL,sizeof(draw_info->dash_pattern));
8114 if (draw_info->dash_pattern != (double *) NULL)
8115 {
8116 for (i=0; i <= av_len(av); i++)
8117 draw_info->dash_pattern[i]=(double)
8118 SvNV(*(av_fetch(av,i,0)));
8119 draw_info->dash_pattern[i]=0.0;
8120 }
8121 }
8122 if (attribute_flag[23] != 0)
8123 image->interpolate=(InterpolatePixelMethod)
8124 argument_list[23].long_reference;
8125 if ((attribute_flag[24] != 0) &&
8126 (draw_info->fill_pattern != (Image *) NULL))
8127 flags=ParsePageGeometry(draw_info->fill_pattern,
8128 argument_list[24].string_reference,
8129 &draw_info->fill_pattern->tile_offset,exception);
8130 if (attribute_flag[25] != 0)
8131 {
8132 (void) ConcatenateString(&draw_info->primitive," '");
8133 (void) ConcatenateString(&draw_info->primitive,
8134 argument_list[25].string_reference);
8135 (void) ConcatenateString(&draw_info->primitive,"'");
8136 }
8137 if (attribute_flag[26] != 0)
8138 draw_info->fill_pattern=CloneImage(
8139 argument_list[26].image_reference,0,0,MagickTrue,exception);
8140 if (attribute_flag[27] != 0)
8141 draw_info->stroke_pattern=CloneImage(
8142 argument_list[27].image_reference,0,0,MagickTrue,exception);
8143 if (attribute_flag[28] != 0)
8144 (void) CloneString(&draw_info->primitive,
8145 argument_list[28].string_reference);
8146 if (attribute_flag[29] != 0)
8147 draw_info->kerning=argument_list[29].real_reference;
8148 if (attribute_flag[30] != 0)
cristyb32b90a2009-09-07 21:45:48 +00008149 draw_info->interline_spacing=argument_list[30].real_reference;
8150 if (attribute_flag[31] != 0)
8151 draw_info->interword_spacing=argument_list[31].real_reference;
cristy3ed852e2009-09-05 21:47:34 +00008152 DrawImage(image,draw_info);
8153 draw_info=DestroyDrawInfo(draw_info);
8154 break;
8155 }
8156 case 39: /* Equalize */
8157 {
8158 if (attribute_flag[0] != 0)
8159 channel=(ChannelType) argument_list[0].long_reference;
8160 EqualizeImageChannel(image,channel);
8161 break;
8162 }
8163 case 40: /* Gamma */
8164 {
8165 if (attribute_flag[1] != 0)
8166 channel=(ChannelType) argument_list[1].long_reference;
8167 if (attribute_flag[2] == 0)
8168 argument_list[2].real_reference=1.0;
8169 if (attribute_flag[3] == 0)
8170 argument_list[3].real_reference=1.0;
8171 if (attribute_flag[4] == 0)
8172 argument_list[4].real_reference=1.0;
8173 if (attribute_flag[0] == 0)
8174 {
8175 (void) FormatMagickString(message,MaxTextExtent,"%g,%g,%g",
8176 (double) argument_list[2].real_reference,
8177 (double) argument_list[3].real_reference,
8178 (double) argument_list[4].real_reference);
8179 argument_list[0].string_reference=message;
8180 }
8181 if (strchr(argument_list[0].string_reference,',') != (char *) NULL)
8182 (void) GammaImage(image,argument_list[0].string_reference);
8183 else
8184 (void) GammaImageChannel(image,channel,
8185 atof(argument_list[0].string_reference));
8186 break;
8187 }
8188 case 41: /* Map */
8189 {
8190 QuantizeInfo
8191 *quantize_info;
8192
8193 if (attribute_flag[0] == 0)
8194 {
8195 ThrowPerlException(exception,OptionError,"MapImageRequired",
8196 PackageName);
8197 goto PerlException;
8198 }
8199 quantize_info=AcquireQuantizeInfo(info->image_info);
8200 if (attribute_flag[1] != 0)
8201 quantize_info->dither=(MagickBooleanType)
8202 argument_list[1].long_reference;
8203 (void) RemapImages(quantize_info,image,
8204 argument_list[0].image_reference);
8205 quantize_info=DestroyQuantizeInfo(quantize_info);
8206 break;
8207 }
8208 case 42: /* MatteFloodfill */
8209 {
8210 DrawInfo
8211 *draw_info;
8212
8213 MagickBooleanType
8214 invert;
8215
8216 MagickPixelPacket
8217 target;
8218
8219 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8220 (DrawInfo *) NULL);
8221 if (attribute_flag[0] != 0)
8222 if (attribute_flag[0] != 0)
8223 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8224 &geometry,exception);
8225 if (attribute_flag[1] != 0)
8226 geometry.x=argument_list[1].long_reference;
8227 if (attribute_flag[2] != 0)
8228 geometry.y=argument_list[2].long_reference;
8229 if (image->matte == MagickFalse)
8230 (void) SetImageOpacity(image,OpaqueOpacity);
8231 (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target,
8232 exception);
8233 if (attribute_flag[4] != 0)
8234 QueryMagickColor(argument_list[4].string_reference,&target,
8235 exception);
8236 if (attribute_flag[3] != 0)
8237 target.opacity=StringToDouble(argument_list[3].string_reference,
8238 QuantumRange);
8239 if (attribute_flag[5] != 0)
8240 image->fuzz=StringToDouble(argument_list[5].string_reference,
8241 QuantumRange);
8242 invert=MagickFalse;
8243 if (attribute_flag[6] != 0)
8244 invert=(MagickBooleanType) argument_list[6].long_reference;
8245 (void) FloodfillPaintImage(image,OpacityChannel,draw_info,&target,
8246 geometry.x,geometry.y,invert);
8247 draw_info=DestroyDrawInfo(draw_info);
8248 break;
8249 }
8250 case 43: /* Modulate */
8251 {
8252 char
8253 modulate[MaxTextExtent];
8254
8255 ColorspaceType
8256 colorspace;
8257
8258 colorspace=image->colorspace;
8259 geometry_info.rho=100.0;
8260 geometry_info.sigma=100.0;
8261 geometry_info.xi=100.0;
8262 if (attribute_flag[0] != 0)
8263 (void)ParseGeometry(argument_list[0].string_reference,
8264 &geometry_info);
8265 if (attribute_flag[1] != 0)
8266 geometry_info.xi=argument_list[1].real_reference;
8267 if (attribute_flag[2] != 0)
8268 geometry_info.sigma=argument_list[2].real_reference;
8269 if (attribute_flag[3] != 0)
8270 {
8271 (void) SetImageColorspace(image,HWBColorspace);
8272 geometry_info.sigma=argument_list[3].real_reference;
8273 }
8274 if (attribute_flag[4] != 0)
8275 geometry_info.rho=argument_list[4].real_reference;
8276 if (attribute_flag[5] != 0)
8277 {
8278 (void) SetImageColorspace(image,HSLColorspace);
8279 geometry_info.sigma=argument_list[5].real_reference;
8280 }
8281 if (attribute_flag[6] != 0)
8282 {
8283 (void) SetImageColorspace(image,HWBColorspace);
8284 geometry_info.rho=argument_list[6].real_reference;
8285 }
8286 (void) FormatMagickString(modulate,MaxTextExtent,"%g,%g,%g",
8287 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
8288 (void) ModulateImage(image,modulate);
8289 (void) SetImageColorspace(image,colorspace);
8290 break;
8291 }
8292 case 44: /* Negate */
8293 {
8294 if (attribute_flag[0] == 0)
8295 argument_list[0].long_reference=0;
8296 if (attribute_flag[1] != 0)
8297 channel=(ChannelType) argument_list[1].long_reference;
8298 (void) NegateImageChannel(image,channel,
8299 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse);
8300 break;
8301 }
8302 case 45: /* Normalize */
8303 {
8304 if (attribute_flag[0] != 0)
8305 channel=(ChannelType) argument_list[0].long_reference;
8306 NormalizeImageChannel(image,channel);
8307 break;
8308 }
8309 case 46: /* NumberColors */
8310 break;
8311 case 47: /* Opaque */
8312 {
8313 MagickBooleanType
8314 invert;
8315
8316 MagickPixelPacket
8317 fill_color,
8318 target;
8319
8320 (void) QueryMagickColor("none",&target,exception);
8321 (void) QueryMagickColor("none",&fill_color,exception);
8322 if (attribute_flag[0] != 0)
8323 (void) QueryMagickColor(argument_list[0].string_reference,
8324 &target,exception);
8325 if (attribute_flag[1] != 0)
8326 (void) QueryMagickColor(argument_list[1].string_reference,
8327 &fill_color,exception);
8328 if (attribute_flag[2] != 0)
8329 image->fuzz=StringToDouble(argument_list[2].string_reference,
8330 QuantumRange);
8331 if (attribute_flag[3] != 0)
8332 channel=(ChannelType) argument_list[3].long_reference;
8333 invert=MagickFalse;
8334 if (attribute_flag[4] != 0)
8335 invert=(MagickBooleanType) argument_list[4].long_reference;
8336 (void) OpaquePaintImageChannel(image,channel,&target,&fill_color,
8337 invert);
8338 break;
8339 }
8340 case 48: /* Quantize */
8341 {
8342 QuantizeInfo
8343 *quantize_info;
8344
8345 quantize_info=AcquireQuantizeInfo(info->image_info);
8346 if (attribute_flag[0] != 0)
8347 quantize_info->number_colors=(unsigned long)
8348 argument_list[0].long_reference;
8349 if (attribute_flag[1] != 0)
8350 quantize_info->tree_depth=(unsigned long)
8351 argument_list[1].long_reference;
8352 if (attribute_flag[2] != 0)
8353 quantize_info->colorspace=(ColorspaceType)
8354 argument_list[2].long_reference;
8355 if (attribute_flag[3] != 0)
8356 quantize_info->dither=argument_list[3].long_reference != 0 ?
8357 MagickTrue : MagickFalse;
8358 if (attribute_flag[4] != 0)
8359 quantize_info->measure_error=
8360 argument_list[4].long_reference != 0 ? MagickTrue : MagickFalse;
8361 if (attribute_flag[5] != 0)
8362 (void) QueryColorDatabase(argument_list[5].string_reference,
8363 &image->transparent_color,exception);
8364 if (attribute_flag[5] && argument_list[5].long_reference)
8365 {
8366 (void) QuantizeImages(quantize_info,image);
8367 goto PerlException;
8368 }
8369 if (attribute_flag[6] != 0)
8370 quantize_info->dither_method=(DitherMethod)
8371 argument_list[6].long_reference;
8372 if ((image->storage_class == DirectClass) ||
8373 (image->colors > quantize_info->number_colors) ||
8374 (quantize_info->colorspace == GRAYColorspace))
8375 (void) QuantizeImage(quantize_info,image);
8376 else
8377 CompressImageColormap(image);
8378 quantize_info=DestroyQuantizeInfo(quantize_info);
8379 break;
8380 }
8381 case 49: /* Raise */
8382 {
8383 if (attribute_flag[0] != 0)
8384 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8385 &geometry,exception);
8386 if (attribute_flag[1] != 0)
8387 geometry.width=argument_list[1].long_reference;
8388 if (attribute_flag[2] != 0)
8389 geometry.height=argument_list[2].long_reference;
8390 if (attribute_flag[3] == 0)
8391 argument_list[3].long_reference=1;
8392 (void) RaiseImage(image,&geometry,argument_list[3].long_reference !=
8393 0 ? MagickTrue : MagickFalse);
8394 break;
8395 }
8396 case 50: /* Segment */
8397 {
8398 ColorspaceType
8399 colorspace;
8400
8401 double
8402 cluster_threshold,
8403 smoothing_threshold;
8404
8405 MagickBooleanType
8406 verbose;
8407
8408 cluster_threshold=1.0;
8409 smoothing_threshold=1.5;
8410 colorspace=RGBColorspace;
8411 verbose=MagickFalse;
8412 if (attribute_flag[0] != 0)
8413 {
8414 flags=ParseGeometry(argument_list[0].string_reference,
8415 &geometry_info);
8416 cluster_threshold=geometry_info.rho;
8417 if (flags & SigmaValue)
8418 smoothing_threshold=geometry_info.sigma;
8419 }
8420 if (attribute_flag[1] != 0)
8421 cluster_threshold=argument_list[1].real_reference;
8422 if (attribute_flag[2] != 0)
8423 smoothing_threshold=argument_list[2].real_reference;
8424 if (attribute_flag[3] != 0)
8425 colorspace=(ColorspaceType) argument_list[3].long_reference;
8426 if (attribute_flag[4] != 0)
8427 verbose=argument_list[4].long_reference != 0 ?
8428 MagickTrue : MagickFalse;
8429 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
8430 smoothing_threshold);
8431 break;
8432 }
8433 case 51: /* Signature */
8434 {
8435 (void) SignatureImage(image);
8436 break;
8437 }
8438 case 52: /* Solarize */
8439 {
8440 geometry_info.rho=QuantumRange/2.0;
8441 if (attribute_flag[0] != 0)
8442 flags=ParseGeometry(argument_list[0].string_reference,
8443 &geometry_info);
8444 if (attribute_flag[1] != 0)
8445 geometry_info.rho=StringToDouble(argument_list[1].string_reference,
8446 QuantumRange);
8447 (void) SolarizeImage(image,geometry_info.rho);
8448 break;
8449 }
8450 case 53: /* Sync */
8451 {
8452 (void) SyncImage(image);
8453 break;
8454 }
8455 case 54: /* Texture */
8456 {
8457 if (attribute_flag[0] == 0)
8458 break;
8459 TextureImage(image,argument_list[0].image_reference);
8460 break;
8461 }
8462 case 55: /* Evalute */
8463 {
8464 MagickEvaluateOperator
8465 op;
8466
8467 op=SetEvaluateOperator;
8468 if (attribute_flag[0] == MagickFalse)
8469 argument_list[0].real_reference=0.0;
8470 if (attribute_flag[1] != MagickFalse)
8471 op=(MagickEvaluateOperator) argument_list[1].long_reference;
8472 if (attribute_flag[2] != MagickFalse)
8473 channel=(ChannelType) argument_list[2].long_reference;
8474 (void) EvaluateImageChannel(image,channel,op,
8475 argument_list[0].real_reference,exception);
8476 break;
8477 }
8478 case 56: /* Transparent */
8479 {
8480 double
8481 opacity;
8482
8483 MagickBooleanType
8484 invert;
8485
8486 MagickPixelPacket
8487 target;
8488
8489 (void) QueryMagickColor("none",&target,exception);
8490 if (attribute_flag[0] != 0)
8491 (void) QueryMagickColor(argument_list[0].string_reference,&target,
8492 exception);
8493 opacity=TransparentOpacity;
8494 if (attribute_flag[1] != 0)
8495 opacity=StringToDouble(argument_list[1].string_reference,
8496 QuantumRange);
8497 if (attribute_flag[2] != 0)
8498 image->fuzz=StringToDouble(argument_list[2].string_reference,
8499 QuantumRange);
8500 if (attribute_flag[3] == 0)
8501 argument_list[3].long_reference=0;
8502 invert=MagickFalse;
8503 if (attribute_flag[3] != 0)
8504 invert=(MagickBooleanType) argument_list[3].long_reference;
8505 (void) TransparentPaintImage(image,&target,RoundToQuantum(opacity),
8506 invert);
8507 break;
8508 }
8509 case 57: /* Threshold */
8510 {
8511 double
8512 threshold;
8513
8514 if (attribute_flag[0] == 0)
8515 argument_list[0].string_reference="50%";
8516 if (attribute_flag[1] != 0)
8517 channel=(ChannelType) argument_list[1].long_reference;
8518 threshold=StringToDouble(argument_list[0].string_reference,
8519 QuantumRange);
8520 (void) BilevelImageChannel(image,channel,threshold);
8521 break;
8522 }
8523 case 58: /* Charcoal */
8524 {
8525 if (attribute_flag[0] != 0)
8526 {
8527 flags=ParseGeometry(argument_list[0].string_reference,
8528 &geometry_info);
8529 if ((flags & SigmaValue) == 0)
8530 geometry_info.sigma=1.0;
8531 }
8532 if (attribute_flag[1] != 0)
8533 geometry_info.rho=argument_list[1].real_reference;
8534 if (attribute_flag[2] != 0)
8535 geometry_info.sigma=argument_list[2].real_reference;
8536 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
8537 exception);
8538 break;
8539 }
8540 case 59: /* Trim */
8541 {
8542 if (attribute_flag[0] != 0)
8543 image->fuzz=StringToDouble(argument_list[0].string_reference,
8544 QuantumRange);
8545 image=TrimImage(image,exception);
8546 break;
8547 }
8548 case 60: /* Wave */
8549 {
8550 if (attribute_flag[0] != 0)
8551 {
8552 flags=ParseGeometry(argument_list[0].string_reference,
8553 &geometry_info);
8554 if ((flags & SigmaValue) == 0)
8555 geometry_info.sigma=1.0;
8556 }
8557 if (attribute_flag[1] != 0)
8558 geometry_info.rho=argument_list[1].real_reference;
8559 if (attribute_flag[2] != 0)
8560 geometry_info.sigma=argument_list[2].real_reference;
8561 if (attribute_flag[3] != 0)
8562 image->interpolate=(InterpolatePixelMethod)
8563 argument_list[3].long_reference;
8564 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
8565 exception);
8566 break;
8567 }
8568 case 61: /* Separate */
8569 {
8570 if (attribute_flag[0] != 0)
8571 channel=(ChannelType) argument_list[0].long_reference;
8572 (void) SeparateImageChannel(image,channel);
8573 break;
8574 }
8575 case 63: /* Stereo */
8576 {
8577 if (attribute_flag[0] == 0)
8578 {
8579 ThrowPerlException(exception,OptionError,"StereoImageRequired",
8580 PackageName);
8581 goto PerlException;
8582 }
8583 if (attribute_flag[1] != 0)
8584 geometry.x=argument_list[1].long_reference;
8585 if (attribute_flag[2] != 0)
8586 geometry.y=argument_list[2].long_reference;
8587 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
8588 geometry.x,geometry.y,exception);
8589 break;
8590 }
8591 case 64: /* Stegano */
8592 {
8593 if (attribute_flag[0] == 0)
8594 {
8595 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
8596 PackageName);
8597 goto PerlException;
8598 }
8599 if (attribute_flag[1] == 0)
8600 argument_list[1].long_reference=0;
8601 image->offset=argument_list[1].long_reference;
8602 image=SteganoImage(image,argument_list[0].image_reference,exception);
8603 break;
8604 }
8605 case 65: /* Deconstruct */
8606 {
8607 image=DeconstructImages(image,exception);
8608 break;
8609 }
8610 case 66: /* GaussianBlur */
8611 {
8612 if (attribute_flag[0] != 0)
8613 {
8614 flags=ParseGeometry(argument_list[0].string_reference,
8615 &geometry_info);
8616 if ((flags & SigmaValue) == 0)
8617 geometry_info.sigma=1.0;
8618 }
8619 if (attribute_flag[1] != 0)
8620 geometry_info.rho=argument_list[1].real_reference;
8621 if (attribute_flag[2] != 0)
8622 geometry_info.sigma=argument_list[2].real_reference;
8623 if (attribute_flag[3] != 0)
8624 channel=(ChannelType) argument_list[3].long_reference;
8625 image=GaussianBlurImageChannel(image,channel,geometry_info.rho,
8626 geometry_info.sigma,exception);
8627 break;
8628 }
8629 case 67: /* Convolve */
8630 {
8631 AV
8632 *av;
8633
8634 double
8635 *kernel;
8636
8637 unsigned long
8638 order;
8639
8640 if (attribute_flag[0] == 0)
8641 break;
8642 if (attribute_flag[1] != 0)
8643 channel=(ChannelType) argument_list[1].long_reference;
8644 if (attribute_flag[2] != 0)
8645 image->bias=StringToDouble(argument_list[2].string_reference,
8646 QuantumRange);
8647 av=(AV *) argument_list[0].array_reference;
8648 order=(unsigned long) sqrt(av_len(av)+1);
8649 kernel=(double *) AcquireQuantumMemory(order,order*sizeof(*kernel));
8650 if (kernel == (double *) NULL)
8651 {
8652 ThrowPerlException(exception,ResourceLimitFatalError,
8653 "MemoryAllocationFailed",PackageName);
8654 goto PerlException;
8655 }
8656 for (j=0; (j < (long) (order*order)) && (j < (av_len(av)+1)); j++)
8657 kernel[j]=(double) SvNV(*(av_fetch(av,j,0)));
8658 for ( ; j < (long) (order*order); j++)
8659 kernel[j]=0.0;
8660 image=ConvolveImageChannel(image,channel,order,kernel,exception);
8661 kernel=(double *) RelinquishMagickMemory(kernel);
8662 break;
8663 }
8664 case 68: /* Profile */
8665 {
8666 const char
8667 *name;
8668
8669 Image
8670 *profile_image;
8671
8672 ImageInfo
8673 *profile_info;
8674
8675 StringInfo
8676 *profile;
8677
8678 name="*";
8679 if (attribute_flag[0] != 0)
8680 name=argument_list[0].string_reference;
8681 if (attribute_flag[2] != 0)
8682 image->rendering_intent=(RenderingIntent)
8683 argument_list[2].long_reference;
8684 if (attribute_flag[3] != 0)
8685 image->black_point_compensation=
8686 argument_list[3].long_reference != 0 ? MagickTrue : MagickFalse;
8687 if (attribute_flag[1] != 0)
8688 {
8689 if (argument_list[1].length == 0)
8690 {
8691 /*
8692 Remove a profile from the image.
8693 */
8694 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
8695 MagickTrue);
8696 break;
8697 }
8698 /*
8699 Associate user supplied profile with the image.
8700 */
8701 profile=AcquireStringInfo(argument_list[1].length);
8702 SetStringInfoDatum(profile,(const unsigned char *)
8703 argument_list[1].string_reference);
8704 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
8705 (unsigned long) GetStringInfoLength(profile),MagickFalse);
8706 profile=DestroyStringInfo(profile);
8707 break;
8708 }
8709 /*
8710 Associate a profile with the image.
8711 */
8712 profile_info=
8713 CloneImageInfo(info ? info->image_info : (ImageInfo *) NULL);
8714 (void) CopyMagickString(profile_info->filename,name,MaxTextExtent);
8715 profile_image=ReadImages(profile_info,&image->exception);
8716 if (profile_image == (Image *) NULL)
8717 break;
8718 ResetImageProfileIterator(profile_image);
8719 name=GetNextImageProfile(profile_image);
8720 while (name != (const char *) NULL)
8721 {
8722 const StringInfo
8723 *profile;
8724
8725 profile=GetImageProfile(profile_image,name);
8726 if (profile != (const StringInfo *) NULL)
8727 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
8728 (unsigned long) GetStringInfoLength(profile),MagickFalse);
8729 name=GetNextImageProfile(profile_image);
8730 }
8731 profile_image=DestroyImage(profile_image);
8732 profile_info=DestroyImageInfo(profile_info);
8733 break;
8734 }
8735 case 69: /* UnsharpMask */
8736 {
8737 if (attribute_flag[0] != 0)
8738 {
8739 flags=ParseGeometry(argument_list[0].string_reference,
8740 &geometry_info);
8741 if ((flags & SigmaValue) == 0)
8742 geometry_info.sigma=1.0;
8743 if ((flags & XiValue) == 0)
8744 geometry_info.xi=1.0;
8745 if ((flags & PsiValue) == 0)
8746 geometry_info.psi=0.5;
8747 }
8748 if (attribute_flag[1] != 0)
8749 geometry_info.rho=argument_list[1].real_reference;
8750 if (attribute_flag[2] != 0)
8751 geometry_info.sigma=argument_list[2].real_reference;
8752 if (attribute_flag[3] != 0)
8753 geometry_info.xi=argument_list[3].real_reference;
8754 if (attribute_flag[4] != 0)
8755 geometry_info.psi=argument_list[4].real_reference;
8756 if (attribute_flag[5] != 0)
8757 channel=(ChannelType) argument_list[5].long_reference;
8758 image=UnsharpMaskImageChannel(image,channel,geometry_info.rho,
8759 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
8760 break;
8761 }
8762 case 70: /* MotionBlur */
8763 {
8764 if (attribute_flag[0] != 0)
8765 {
8766 flags=ParseGeometry(argument_list[0].string_reference,
8767 &geometry_info);
8768 if ((flags & SigmaValue) == 0)
8769 geometry_info.sigma=1.0;
8770 if ((flags & XiValue) == 0)
8771 geometry_info.xi=1.0;
8772 }
8773 if (attribute_flag[1] != 0)
8774 geometry_info.rho=argument_list[1].real_reference;
8775 if (attribute_flag[2] != 0)
8776 geometry_info.sigma=argument_list[2].real_reference;
8777 if (attribute_flag[3] != 0)
8778 geometry_info.xi=argument_list[3].real_reference;
8779 if (attribute_flag[4] != 0)
8780 channel=(ChannelType) argument_list[4].long_reference;
8781 image=MotionBlurImageChannel(image,channel,geometry_info.rho,geometry_info.sigma,
8782 geometry_info.xi,exception);
8783 break;
8784 }
8785 case 71: /* OrderedDither */
8786 {
8787 if (attribute_flag[0] == 0)
8788 argument_list[0].string_reference="o8x8";
8789 if (attribute_flag[1] != 0)
8790 channel=(ChannelType) argument_list[1].long_reference;
8791 (void) OrderedPosterizeImageChannel(image,channel,
8792 argument_list[0].string_reference,exception);
8793 break;
8794 }
8795 case 72: /* Shave */
8796 {
8797 if (attribute_flag[0] != 0)
8798 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8799 &geometry,exception);
8800 if (attribute_flag[1] != 0)
8801 geometry.width=argument_list[1].long_reference;
8802 if (attribute_flag[2] != 0)
8803 geometry.height=argument_list[2].long_reference;
8804 image=ShaveImage(image,&geometry,exception);
8805 break;
8806 }
8807 case 73: /* Level */
8808 {
8809 double
8810 black_point,
8811 gamma,
8812 white_point;
8813
8814 black_point=0.0;
8815 white_point=(MagickRealType) image->columns*image->rows;
8816 gamma=1.0;
8817 if (attribute_flag[0] != 0)
8818 {
8819 flags=ParseGeometry(argument_list[0].string_reference,
8820 &geometry_info);
8821 black_point=geometry_info.rho;
8822 if ((flags & SigmaValue) != 0)
8823 white_point=geometry_info.sigma;
8824 if ((flags & XiValue) != 0)
8825 gamma=geometry_info.xi;
8826 if ((flags & PercentValue) != 0)
8827 {
8828 black_point*=(double) (QuantumRange/100.0);
8829 white_point*=(double) (QuantumRange/100.0);
8830 }
8831 if ((flags & SigmaValue) == 0)
8832 white_point=(double) QuantumRange-black_point;
8833 }
8834 if (attribute_flag[1] != 0)
8835 black_point=argument_list[1].real_reference;
8836 if (attribute_flag[2] != 0)
8837 white_point=argument_list[2].real_reference;
8838 if (attribute_flag[3] != 0)
8839 gamma=argument_list[3].real_reference;
8840 if (attribute_flag[4] != 0)
8841 channel=(ChannelType) argument_list[4].long_reference;
8842 if (attribute_flag[5] != 0)
8843 {
8844 argument_list[0].real_reference=argument_list[5].real_reference;
8845 attribute_flag[0]=attribute_flag[5];
8846 }
8847 (void) LevelImageChannel(image,channel,black_point,white_point,gamma);
8848 break;
8849 }
8850 case 74: /* Clip */
8851 {
8852 if (attribute_flag[0] == 0)
8853 argument_list[0].string_reference="#1";
8854 if (attribute_flag[1] == 0)
8855 argument_list[1].long_reference=MagickTrue;
8856 (void) ClipImagePath(image,argument_list[0].string_reference,
8857 argument_list[1].long_reference != 0 ? MagickTrue : MagickFalse);
8858 break;
8859 }
8860 case 75: /* AffineTransform */
8861 {
8862 DrawInfo
8863 *draw_info;
8864
8865 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8866 (DrawInfo *) NULL);
8867 if (attribute_flag[0] != 0)
8868 {
8869 AV
8870 *av;
8871
8872 av=(AV *) argument_list[0].array_reference;
8873 if ((av_len(av) != 3) && (av_len(av) != 5))
8874 {
8875 ThrowPerlException(exception,OptionError,
8876 "affine matrix must have 4 or 6 elements",PackageName);
8877 goto PerlException;
8878 }
8879 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8880 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8881 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8882 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8883 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8884 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8885 {
8886 ThrowPerlException(exception,OptionError,
8887 "affine matrix is singular",PackageName);
8888 goto PerlException;
8889 }
8890 if (av_len(av) == 5)
8891 {
8892 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8893 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8894 }
8895 }
8896 for (j=1; j < 6; j++)
8897 {
8898 if (attribute_flag[j] == 0)
8899 continue;
8900 value=argument_list[j].string_reference;
8901 angle=argument_list[j].real_reference;
8902 current=draw_info->affine;
8903 GetAffineMatrix(&affine);
8904 switch (j)
8905 {
8906 case 1:
8907 {
8908 /*
8909 Translate.
8910 */
8911 flags=ParseGeometry(value,&geometry_info);
8912 affine.tx=geometry_info.xi;
8913 affine.ty=geometry_info.psi;
8914 if ((flags & PsiValue) == 0)
8915 affine.ty=affine.tx;
8916 break;
8917 }
8918 case 2:
8919 {
8920 /*
8921 Scale.
8922 */
8923 flags=ParseGeometry(value,&geometry_info);
8924 affine.sx=geometry_info.rho;
8925 affine.sy=geometry_info.sigma;
8926 if ((flags & SigmaValue) == 0)
8927 affine.sy=affine.sx;
8928 break;
8929 }
8930 case 3:
8931 {
8932 /*
8933 Rotate.
8934 */
8935 if (angle == 0.0)
8936 break;
8937 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8938 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8939 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8940 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8941 break;
8942 }
8943 case 4:
8944 {
8945 /*
8946 SkewX.
8947 */
8948 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8949 break;
8950 }
8951 case 5:
8952 {
8953 /*
8954 SkewY.
8955 */
8956 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8957 break;
8958 }
8959 }
8960 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8961 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8962 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8963 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8964 draw_info->affine.tx=
8965 current.sx*affine.tx+current.ry*affine.ty+current.tx;
8966 draw_info->affine.ty=
8967 current.rx*affine.tx+current.sy*affine.ty+current.ty;
8968 }
8969 if (attribute_flag[6] != 0)
8970 image->interpolate=(InterpolatePixelMethod)
8971 argument_list[6].long_reference;
8972 if (attribute_flag[7] != 0)
8973 QueryColorDatabase(argument_list[7].string_reference,
8974 &image->background_color,exception);
8975 image=AffineTransformImage(image,&draw_info->affine,exception);
8976 draw_info=DestroyDrawInfo(draw_info);
8977 break;
8978 }
8979 case 76: /* Difference */
8980 {
8981 if (attribute_flag[0] == 0)
8982 {
8983 ThrowPerlException(exception,OptionError,
8984 "ReferenceImageRequired",PackageName);
8985 goto PerlException;
8986 }
8987 if (attribute_flag[1] != 0)
8988 image->fuzz=StringToDouble(argument_list[1].string_reference,
8989 QuantumRange);
8990 (void) IsImagesEqual(image,argument_list[0].image_reference);
8991 break;
8992 }
8993 case 77: /* AdaptiveThreshold */
8994 {
8995 if (attribute_flag[0] != 0)
8996 {
8997 flags=ParseGeometry(argument_list[0].string_reference,
8998 &geometry_info);
8999 if ((flags & PercentValue) != 0)
9000 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9001 }
9002 if (attribute_flag[1] != 0)
9003 geometry_info.rho=argument_list[1].long_reference;
9004 if (attribute_flag[2] != 0)
9005 geometry_info.sigma=argument_list[2].long_reference;
9006 if (attribute_flag[3] != 0)
9007 geometry_info.xi=argument_list[3].long_reference;;
9008 image=AdaptiveThresholdImage(image,(unsigned long) geometry_info.rho,
9009 (unsigned long) geometry_info.sigma,(long) geometry_info.xi,
9010 exception);
9011 break;
9012 }
9013 case 78: /* Resample */
9014 {
9015 unsigned long
9016 height,
9017 width;
9018
9019 if (attribute_flag[0] != 0)
9020 {
9021 flags=ParseGeometry(argument_list[0].string_reference,
9022 &geometry_info);
9023 if ((flags & SigmaValue) == 0)
9024 geometry_info.sigma=geometry_info.rho;
9025 }
9026 if (attribute_flag[1] != 0)
9027 geometry_info.rho=argument_list[1].real_reference;
9028 if (attribute_flag[2] != 0)
9029 geometry_info.sigma=argument_list[2].real_reference;
9030 if (attribute_flag[3] == 0)
9031 argument_list[3].long_reference=(long) UndefinedFilter;
9032 if (attribute_flag[4] == 0)
9033 SetImageArtifact(image,"filter:support",
9034 argument_list[4].string_reference);
9035 if (attribute_flag[5] != 0)
9036 argument_list[5].real_reference=1.0;
9037 width=(unsigned long) (geometry_info.rho*image->columns/
9038 (image->x_resolution == 0.0 ? 72.0 : image->x_resolution)+0.5);
9039 height=(unsigned long) (geometry_info.sigma*image->rows/
9040 (image->y_resolution == 0.0 ? 72.0 : image->y_resolution)+0.5);
9041 image=ResizeImage(image,width,height,(FilterTypes)
9042 argument_list[3].long_reference,argument_list[5].real_reference,
9043 exception);
9044 if (image != (Image *) NULL)
9045 {
9046 image->x_resolution=geometry_info.rho;
9047 image->y_resolution=geometry_info.sigma;
9048 }
9049 break;
9050 }
9051 case 79: /* Describe */
9052 {
9053 if (attribute_flag[0] == 0)
9054 argument_list[0].file_reference=(FILE *) NULL;
9055 (void) IdentifyImage(image,argument_list[0].file_reference,
9056 MagickTrue);
9057 break;
9058 }
9059 case 80: /* BlackThreshold */
9060 {
9061 if (attribute_flag[0] == 0)
9062 argument_list[0].string_reference="50%";
9063 if (attribute_flag[2] != 0)
9064 channel=(ChannelType) argument_list[2].long_reference;
9065 BlackThresholdImageChannel(image,channel,
9066 argument_list[0].string_reference,exception);
9067 break;
9068 }
9069 case 81: /* WhiteThreshold */
9070 {
9071 if (attribute_flag[0] == 0)
9072 argument_list[0].string_reference="50%";
9073 if (attribute_flag[2] != 0)
9074 channel=(ChannelType) argument_list[2].long_reference;
9075 WhiteThresholdImageChannel(image,channel,
9076 argument_list[0].string_reference,exception);
9077 break;
9078 }
9079 case 82: /* RadialBlur */
9080 {
9081 if (attribute_flag[0] != 0)
9082 {
9083 flags=ParseGeometry(argument_list[0].string_reference,
9084 &geometry_info);
9085 if ((flags & SigmaValue) == 0)
9086 geometry_info.sigma=1.0;
9087 }
9088 if (attribute_flag[1] != 0)
9089 geometry_info.rho=argument_list[1].real_reference;
9090 if (attribute_flag[2] != 0)
9091 channel=(ChannelType) argument_list[2].long_reference;
9092 image=RadialBlurImageChannel(image,channel,geometry_info.rho,
9093 exception);
9094 break;
9095 }
9096 case 83: /* Thumbnail */
9097 {
9098 if (attribute_flag[0] != 0)
9099 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9100 &geometry,exception);
9101 if (attribute_flag[1] != 0)
9102 geometry.width=argument_list[1].long_reference;
9103 if (attribute_flag[2] != 0)
9104 geometry.height=argument_list[2].long_reference;
9105 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
9106 break;
9107 }
9108 case 84: /* Strip */
9109 {
9110 (void) StripImage(image);
9111 break;
9112 }
9113 case 85: /* Tint */
9114 {
9115 PixelPacket
9116 target;
9117
9118 (void) GetOneVirtualPixel(image,0,0,&target,exception);
9119 if (attribute_flag[0] != 0)
9120 (void) QueryColorDatabase(argument_list[0].string_reference,&target,
9121 exception);
9122 if (attribute_flag[1] == 0)
9123 argument_list[1].string_reference="100";
9124 image=TintImage(image,argument_list[1].string_reference,target,
9125 exception);
9126 break;
9127 }
9128 case 86: /* Channel */
9129 {
9130 if (attribute_flag[0] != 0)
9131 channel=(ChannelType) argument_list[0].long_reference;
9132 (void) SeparateImageChannel(image,channel);
9133 break;
9134 }
9135 case 87: /* Splice */
9136 {
9137 if (attribute_flag[0] != 0)
9138 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
9139 &geometry,exception);
9140 if (attribute_flag[1] != 0)
9141 geometry.width=argument_list[1].long_reference;
9142 if (attribute_flag[2] != 0)
9143 geometry.height=argument_list[2].long_reference;
9144 if (attribute_flag[3] != 0)
9145 geometry.x=argument_list[3].long_reference;
9146 if (attribute_flag[4] != 0)
9147 geometry.y=argument_list[4].long_reference;
9148 if (attribute_flag[5] != 0)
9149 image->fuzz=StringToDouble(argument_list[5].string_reference,
9150 QuantumRange);
9151 if (attribute_flag[6] != 0)
9152 (void) QueryColorDatabase(argument_list[6].string_reference,
9153 &image->background_color,exception);
9154 if (attribute_flag[7] != 0)
9155 image->gravity=(GravityType) argument_list[7].long_reference;
9156 image=SpliceImage(image,&geometry,exception);
9157 break;
9158 }
9159 case 88: /* Posterize */
9160 {
9161 if (attribute_flag[0] == 0)
9162 argument_list[0].long_reference=3;
9163 if (attribute_flag[1] == 0)
9164 argument_list[1].long_reference=0;
9165 (void) PosterizeImage(image,argument_list[0].long_reference,
9166 argument_list[1].long_reference ? MagickTrue : MagickFalse);
9167 break;
9168 }
9169 case 89: /* Shadow */
9170 {
9171 if (attribute_flag[0] != 0)
9172 {
9173 flags=ParseGeometry(argument_list[0].string_reference,
9174 &geometry_info);
9175 if ((flags & SigmaValue) == 0)
9176 geometry_info.sigma=1.0;
9177 if ((flags & XiValue) == 0)
9178 geometry_info.xi=4.0;
9179 if ((flags & PsiValue) == 0)
9180 geometry_info.psi=4.0;
9181 }
9182 if (attribute_flag[1] != 0)
9183 geometry_info.rho=argument_list[1].real_reference;
9184 if (attribute_flag[2] != 0)
9185 geometry_info.sigma=argument_list[2].real_reference;
9186 if (attribute_flag[3] != 0)
9187 geometry_info.xi=argument_list[3].long_reference;
9188 if (attribute_flag[4] != 0)
9189 geometry_info.psi=argument_list[4].long_reference;
9190 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
9191 (long) (geometry_info.xi+0.5),(long) (geometry_info.psi+0.5),
9192 exception);
9193 break;
9194 }
9195 case 90: /* Identify */
9196 {
9197 if (attribute_flag[0] == 0)
9198 argument_list[0].file_reference=(FILE *) NULL;
9199 (void) IdentifyImage(image,argument_list[0].file_reference,
9200 MagickTrue);
9201 break;
9202 }
9203 case 91: /* SepiaTone */
9204 {
9205 if (attribute_flag[0] == 0)
9206 argument_list[0].real_reference=80.0*QuantumRange/100.0;
9207 image=SepiaToneImage(image,argument_list[0].real_reference,
9208 exception);
9209 break;
9210 }
9211 case 92: /* SigmoidalContrast */
9212 {
9213 MagickBooleanType
9214 sharpen;
9215
9216 if (attribute_flag[0] != 0)
9217 {
9218 flags=ParseGeometry(argument_list[0].string_reference,
9219 &geometry_info);
9220 if ((flags & SigmaValue) == 0)
9221 geometry_info.sigma=QuantumRange/2.0;
9222 if ((flags & PercentValue) != 0)
9223 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
9224 }
9225 if (attribute_flag[1] != 0)
9226 geometry_info.rho=argument_list[1].real_reference;
9227 if (attribute_flag[2] != 0)
9228 geometry_info.sigma=argument_list[2].real_reference;
9229 if (attribute_flag[3] != 0)
9230 channel=(ChannelType) argument_list[3].long_reference;
9231 sharpen=MagickTrue;
9232 if (attribute_flag[4] != 0)
9233 sharpen=argument_list[4].long_reference != 0 ? MagickTrue :
9234 MagickFalse;
9235 (void) SigmoidalContrastImageChannel(image,channel,sharpen,
9236 geometry_info.rho,geometry_info.sigma);
9237 break;
9238 }
9239 case 93: /* Extent */
9240 {
9241 GravityType
9242 gravity;
9243
9244 gravity=image->gravity;
9245 if (attribute_flag[7] != 0)
9246 gravity=(GravityType) argument_list[7].long_reference;
9247 if (attribute_flag[0] != 0)
9248 {
9249 SetGeometry(image,&geometry);
9250 (void) ParseAbsoluteGeometry(argument_list[0].string_reference,
9251 &geometry);
9252 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
9253 &geometry);
9254 }
9255 if (attribute_flag[1] != 0)
9256 geometry.width=argument_list[1].long_reference;
9257 if (attribute_flag[2] != 0)
9258 geometry.height=argument_list[2].long_reference;
9259 if (attribute_flag[3] != 0)
9260 geometry.x=argument_list[3].long_reference;
9261 if (attribute_flag[4] != 0)
9262 geometry.y=argument_list[4].long_reference;
9263 if (attribute_flag[5] != 0)
9264 image->fuzz=StringToDouble(argument_list[5].string_reference,
9265 QuantumRange);
9266 if (attribute_flag[6] != 0)
9267 (void) QueryColorDatabase(argument_list[6].string_reference,
9268 &image->background_color,exception);
9269 GravityAdjustGeometry(image->columns,image->rows,gravity,&geometry);
9270 image=ExtentImage(image,&geometry,exception);
9271 break;
9272 }
9273 case 94: /* Vignette */
9274 {
9275 if (attribute_flag[0] != 0)
9276 {
9277 flags=ParseGeometry(argument_list[0].string_reference,
9278 &geometry_info);
9279 if ((flags & SigmaValue) == 0)
9280 geometry_info.sigma=1.0;
9281 if ((flags & XiValue) == 0)
9282 geometry_info.xi=0.1*image->columns;
9283 if ((flags & PsiValue) == 0)
9284 geometry_info.psi=0.1*image->rows;
9285 }
9286 if (attribute_flag[1] != 0)
9287 geometry_info.rho=argument_list[1].real_reference;
9288 if (attribute_flag[2] != 0)
9289 geometry_info.sigma=argument_list[2].real_reference;
9290 if (attribute_flag[3] != 0)
9291 geometry_info.xi=argument_list[3].long_reference;
9292 if (attribute_flag[4] != 0)
9293 geometry_info.psi=argument_list[4].long_reference;
9294 if (attribute_flag[5] != 0)
9295 (void) QueryColorDatabase(argument_list[5].string_reference,
9296 &image->background_color,exception);
9297 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
9298 (long) (geometry_info.xi+0.5),(long) (geometry_info.psi+0.5),
9299 exception);
9300 break;
9301 }
9302 case 95: /* ContrastStretch */
9303 {
9304 double
9305 black_point,
9306 white_point;
9307
9308 black_point=0.0;
9309 white_point=(MagickRealType) image->columns*image->rows;
9310 if (attribute_flag[0] != 0)
9311 {
9312 flags=ParseGeometry(argument_list[0].string_reference,
9313 &geometry_info);
9314 black_point=geometry_info.rho;
9315 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
9316 black_point;
9317 if ((flags & PercentValue) != 0)
9318 {
9319 black_point*=(double) image->columns*image->rows/100.0;
9320 white_point*=(double) image->columns*image->rows/100.0;
9321 }
9322 white_point=(MagickRealType) image->columns*image->rows-
9323 white_point;
9324 }
9325 if (attribute_flag[1] != 0)
9326 black_point=argument_list[1].real_reference;
9327 if (attribute_flag[2] != 0)
9328 white_point=argument_list[2].real_reference;
9329 if (attribute_flag[4] != 0)
9330 channel=(ChannelType) argument_list[4].long_reference;
9331 (void) ContrastStretchImageChannel(image,channel,black_point,
9332 white_point);
9333 break;
9334 }
9335 case 96: /* Sans0 */
9336 {
9337 break;
9338 }
9339 case 97: /* Sans1 */
9340 {
9341 break;
9342 }
9343 case 98: /* AdaptiveSharpen */
9344 {
9345 if (attribute_flag[0] != 0)
9346 {
9347 flags=ParseGeometry(argument_list[0].string_reference,
9348 &geometry_info);
9349 if ((flags & SigmaValue) == 0)
9350 geometry_info.sigma=1.0;
9351 }
9352 if (attribute_flag[1] != 0)
9353 geometry_info.rho=argument_list[1].real_reference;
9354 if (attribute_flag[2] != 0)
9355 geometry_info.sigma=argument_list[2].real_reference;
9356 if (attribute_flag[3] != 0)
9357 channel=(ChannelType) argument_list[3].long_reference;
9358 image=AdaptiveSharpenImageChannel(image,channel,geometry_info.rho,
9359 geometry_info.sigma,exception);
9360 break;
9361 }
9362 case 99: /* Transpose */
9363 {
9364 image=TransposeImage(image,exception);
9365 break;
9366 }
9367 case 100: /* Tranverse */
9368 {
9369 image=TransverseImage(image,exception);
9370 break;
9371 }
9372 case 101: /* AutoOrient */
9373 {
9374 switch (image->orientation)
9375 {
9376 case TopRightOrientation:
9377 {
9378 image=FlopImage(image,exception);
9379 break;
9380 }
9381 case BottomRightOrientation:
9382 {
9383 image=RotateImage(image,180.0,exception);
9384 break;
9385 }
9386 case BottomLeftOrientation:
9387 {
9388 image=FlipImage(image,exception);
9389 break;
9390 }
9391 case LeftTopOrientation:
9392 {
9393 image=TransposeImage(image,exception);
9394 break;
9395 }
9396 case RightTopOrientation:
9397 {
9398 image=RotateImage(image,90.0,exception);
9399 break;
9400 }
9401 case RightBottomOrientation:
9402 {
9403 image=TransverseImage(image,exception);
9404 break;
9405 }
9406 case LeftBottomOrientation:
9407 {
9408 image=RotateImage(image,270.0,exception);
9409 break;
9410 }
9411 default:
9412 break;
9413 }
9414 break;
9415 }
9416 case 102: /* AdaptiveBlur */
9417 {
9418 if (attribute_flag[0] != 0)
9419 {
9420 flags=ParseGeometry(argument_list[0].string_reference,
9421 &geometry_info);
9422 if ((flags & SigmaValue) == 0)
9423 geometry_info.sigma=1.0;
9424 }
9425 if (attribute_flag[1] != 0)
9426 geometry_info.rho=argument_list[1].real_reference;
9427 if (attribute_flag[2] != 0)
9428 geometry_info.sigma=argument_list[2].real_reference;
9429 if (attribute_flag[3] != 0)
9430 channel=(ChannelType) argument_list[3].long_reference;
9431 image=AdaptiveBlurImageChannel(image,channel,geometry_info.rho,
9432 geometry_info.sigma,exception);
9433 break;
9434 }
9435 case 103: /* Sketch */
9436 {
9437 if (attribute_flag[0] != 0)
9438 {
9439 flags=ParseGeometry(argument_list[0].string_reference,
9440 &geometry_info);
9441 if ((flags & SigmaValue) == 0)
9442 geometry_info.sigma=1.0;
9443 if ((flags & XiValue) == 0)
9444 geometry_info.xi=1.0;
9445 }
9446 if (attribute_flag[1] != 0)
9447 geometry_info.rho=argument_list[1].real_reference;
9448 if (attribute_flag[2] != 0)
9449 geometry_info.sigma=argument_list[2].real_reference;
9450 if (attribute_flag[3] != 0)
9451 geometry_info.xi=argument_list[3].real_reference;
9452 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
9453 geometry_info.xi,exception);
9454 break;
9455 }
9456 case 104: /* UniqueColors */
9457 {
9458 image=UniqueImageColors(image,exception);
9459 break;
9460 }
9461 case 105: /* AdaptiveResize */
9462 {
9463 if (attribute_flag[0] != 0)
9464 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9465 &geometry,exception);
9466 if (attribute_flag[1] != 0)
9467 geometry.width=argument_list[1].long_reference;
9468 if (attribute_flag[2] != 0)
9469 geometry.height=argument_list[2].long_reference;
9470 if (attribute_flag[3] != 0)
9471 image->filter=(FilterTypes) argument_list[4].long_reference;
9472 if (attribute_flag[4] != 0)
9473 SetImageArtifact(image,"filter:support",
9474 argument_list[4].string_reference);
9475 if (attribute_flag[5] != 0)
9476 image->blur=argument_list[5].real_reference;
9477 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
9478 exception);
9479 break;
9480 }
9481 case 106: /* ClipMask */
9482 {
9483 if (attribute_flag[0] == 0)
9484 {
9485 ThrowPerlException(exception,OptionError,"MaskImageRequired",
9486 PackageName);
9487 goto PerlException;
9488 }
9489 image->clip_mask=CloneImage(argument_list[0].image_reference,0,0,
9490 MagickTrue,exception);
9491 (void) NegateImage(image->clip_mask,MagickFalse);
9492 break;
9493 }
9494 case 107: /* LinearStretch */
9495 {
9496 double
9497 black_point,
9498 white_point;
9499
9500 black_point=0.0;
9501 white_point=(MagickRealType) image->columns*image->rows;
9502 if (attribute_flag[0] != 0)
9503 {
9504 flags=ParseGeometry(argument_list[0].string_reference,
9505 &geometry_info);
9506 if ((flags & SigmaValue) != 0)
9507 white_point=geometry_info.sigma;
9508 if ((flags & PercentValue) != 0)
9509 {
9510 black_point*=(double) image->columns*image->rows/100.0;
9511 white_point*=(double) image->columns*image->rows/100.0;
9512 }
9513 if ((flags & SigmaValue) == 0)
9514 white_point=(double) image->columns*image->rows-black_point;
9515 }
9516 if (attribute_flag[1] != 0)
9517 black_point=argument_list[1].real_reference;
9518 if (attribute_flag[2] != 0)
9519 white_point=argument_list[2].real_reference;
9520 (void) LinearStretchImage(image,black_point,white_point);
9521 break;
9522 }
9523 case 108: /* Recolor */
9524 {
9525 AV
9526 *av;
9527
9528 double
9529 *color_matrix;
9530
9531 unsigned long
9532 order;
9533
9534 if (attribute_flag[0] == 0)
9535 break;
9536 av=(AV *) argument_list[0].array_reference;
9537 order=(unsigned long) sqrt(av_len(av)+1);
9538 color_matrix=(double *) AcquireQuantumMemory(order,order*
9539 sizeof(*color_matrix));
9540 if (color_matrix == (double *) NULL)
9541 {
9542 ThrowPerlException(exception,ResourceLimitFatalError,
9543 "MemoryAllocationFailed",PackageName);
9544 goto PerlException;
9545 }
9546 for (j=0; (j < (long) (order*order)) && (j < (av_len(av)+1)); j++)
9547 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
9548 for ( ; j < (long) (order*order); j++)
9549 color_matrix[j]=0.0;
9550 image=RecolorImage(image,order,color_matrix,exception);
9551 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
9552 break;
9553 }
9554 case 109: /* Mask */
9555 {
9556 if (attribute_flag[0] == 0)
9557 {
9558 ThrowPerlException(exception,OptionError,"MaskImageRequired",
9559 PackageName);
9560 goto PerlException;
9561 }
9562 image->mask=CloneImage(argument_list[0].image_reference,0,0,
9563 MagickTrue,exception);
9564 (void) NegateImage(image->mask,MagickFalse);
9565 break;
9566 }
9567 case 110: /* Polaroid */
9568 {
9569 DrawInfo
9570 *draw_info;
9571
9572 double
9573 angle;
9574
9575 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9576 (DrawInfo *) NULL);
9577 if (attribute_flag[0] != 0)
9578 (void) SetImageProperty(image,"caption",InterpretImageProperties(
9579 info ? info->image_info : (ImageInfo *) NULL,image,
9580 argument_list[0].string_reference));
9581 angle=0.0;
9582 if (attribute_flag[1] != 0)
9583 angle=argument_list[1].real_reference;
9584 if (attribute_flag[2] != 0)
9585 (void) CloneString(&draw_info->font,
9586 argument_list[2].string_reference);
9587 if (attribute_flag[3] != 0)
9588 (void) QueryColorDatabase(argument_list[3].string_reference,
9589 &draw_info->stroke,exception);
9590 if (attribute_flag[4] != 0)
9591 (void) QueryColorDatabase(argument_list[4].string_reference,
9592 &draw_info->fill,exception);
9593 if (attribute_flag[5] != 0)
9594 draw_info->stroke_width=argument_list[5].real_reference;
9595 if (attribute_flag[6] != 0)
9596 draw_info->pointsize=argument_list[6].real_reference;
9597 if (attribute_flag[7] != 0)
9598 draw_info->gravity=(GravityType) argument_list[7].long_reference;
9599 if (attribute_flag[8] != 0)
9600 (void) QueryColorDatabase(argument_list[8].string_reference,
9601 &image->background_color,exception);
9602 image=PolaroidImage(image,draw_info,angle,exception);
9603 draw_info=DestroyDrawInfo(draw_info);
9604 break;
9605 }
9606 case 111: /* FloodfillPaint */
9607 {
9608 DrawInfo
9609 *draw_info;
9610
9611 MagickBooleanType
9612 invert;
9613
9614 MagickPixelPacket
9615 target;
9616
9617 draw_info=CloneDrawInfo(info ? info->image_info :
9618 (ImageInfo *) NULL,(DrawInfo *) NULL);
9619 if (attribute_flag[0] != 0)
9620 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9621 &geometry,exception);
9622 if (attribute_flag[1] != 0)
9623 geometry.x=argument_list[1].long_reference;
9624 if (attribute_flag[2] != 0)
9625 geometry.y=argument_list[2].long_reference;
9626 if (attribute_flag[3] != 0)
9627 (void) QueryColorDatabase(argument_list[3].string_reference,
9628 &draw_info->fill,exception);
9629 (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target,
9630 exception);
9631 if (attribute_flag[4] != 0)
9632 QueryMagickColor(argument_list[4].string_reference,&target,
9633 exception);
9634 if (attribute_flag[5] != 0)
9635 image->fuzz=StringToDouble(argument_list[5].string_reference,
9636 QuantumRange);
9637 if (attribute_flag[6] != 0)
9638 channel=(ChannelType) argument_list[6].long_reference;
9639 invert=MagickFalse;
9640 if (attribute_flag[7] != 0)
9641 invert=(MagickBooleanType) argument_list[7].long_reference;
9642 (void) FloodfillPaintImage(image,channel,draw_info,&target,geometry.x,
9643 geometry.y,invert);
9644 draw_info=DestroyDrawInfo(draw_info);
9645 break;
9646 }
9647 case 112: /* Distort */
9648 {
9649 AV
9650 *av;
9651
9652 double
9653 *coordinates;
9654
9655 DistortImageMethod
9656 method;
9657
9658 unsigned long
9659 number_coordinates;
9660
9661 VirtualPixelMethod
9662 virtual_pixel;
9663
9664 if (attribute_flag[0] == 0)
9665 break;
9666 method=UndefinedDistortion;
9667 if (attribute_flag[1] != 0)
9668 method=(DistortImageMethod) argument_list[1].long_reference;
9669 av=(AV *) argument_list[0].array_reference;
9670 number_coordinates=(unsigned long) av_len(av)+1;
9671 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
9672 sizeof(*coordinates));
9673 if (coordinates == (double *) NULL)
9674 {
9675 ThrowPerlException(exception,ResourceLimitFatalError,
9676 "MemoryAllocationFailed",PackageName);
9677 goto PerlException;
9678 }
9679 for (j=0; j < (long) number_coordinates; j++)
9680 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
9681 virtual_pixel=UndefinedVirtualPixelMethod;
9682 if (attribute_flag[2] != 0)
9683 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
9684 argument_list[2].long_reference);
9685 image=DistortImage(image,method,number_coordinates,coordinates,
9686 argument_list[3].long_reference != 0 ? MagickTrue : MagickFalse,
9687 exception);
9688 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
9689 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel);
9690 coordinates=(double *) RelinquishMagickMemory(coordinates);
9691 break;
9692 }
9693 case 113: /* Clut */
9694 {
9695 if (attribute_flag[0] == 0)
9696 {
9697 ThrowPerlException(exception,OptionError,"ClutImageRequired",
9698 PackageName);
9699 goto PerlException;
9700 }
9701 if (attribute_flag[1] != 0)
9702 channel=(ChannelType) argument_list[1].long_reference;
9703 (void) ClutImageChannel(image,channel,
9704 argument_list[0].image_reference);
9705 break;
9706 }
9707 case 114: /* LiquidRescale */
9708 {
9709 if (attribute_flag[0] != 0)
9710 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9711 &geometry,exception);
9712 if (attribute_flag[1] != 0)
9713 geometry.width=argument_list[1].long_reference;
9714 if (attribute_flag[2] != 0)
9715 geometry.height=argument_list[2].long_reference;
9716 if (attribute_flag[3] == 0)
9717 argument_list[3].real_reference=1.0;
9718 if (attribute_flag[4] == 0)
9719 argument_list[4].real_reference=0.0;
9720 image=LiquidRescaleImage(image,geometry.width,geometry.height,
9721 argument_list[3].real_reference,argument_list[4].real_reference,
9722 exception);
9723 break;
9724 }
9725 case 115: /* EncipherImage */
9726 {
9727 (void) EncipherImage(image,argument_list[0].string_reference,
9728 exception);
9729 break;
9730 }
9731 case 116: /* DecipherImage */
9732 {
9733 (void) DecipherImage(image,argument_list[0].string_reference,
9734 exception);
9735 break;
9736 }
9737 case 117: /* Deskew */
9738 {
9739 geometry_info.rho=QuantumRange/2.0;
9740 if (attribute_flag[0] != 0)
9741 flags=ParseGeometry(argument_list[0].string_reference,
9742 &geometry_info);
9743 if (attribute_flag[1] != 0)
9744 geometry_info.rho=StringToDouble(argument_list[1].string_reference,
9745 QuantumRange);
9746 image=DeskewImage(image,geometry_info.rho,exception);
9747 break;
9748 }
9749 case 118: /* Remap */
9750 {
9751 QuantizeInfo
9752 *quantize_info;
9753
9754 if (attribute_flag[0] == 0)
9755 {
9756 ThrowPerlException(exception,OptionError,"RemapImageRequired",
9757 PackageName);
9758 goto PerlException;
9759 }
9760 quantize_info=AcquireQuantizeInfo(info->image_info);
9761 if (attribute_flag[1] == 0)
9762 quantize_info->dither_method=(DitherMethod)
9763 argument_list[1].long_reference;
9764 (void) RemapImages(quantize_info,image,
9765 argument_list[0].image_reference);
9766 quantize_info=DestroyQuantizeInfo(quantize_info);
9767 break;
9768 }
9769 case 119: /* SparseColor */
9770 {
9771 AV
9772 *av;
9773
9774 double
9775 *coordinates;
9776
9777 SparseColorMethod
9778 method;
9779
9780 unsigned long
9781 number_coordinates;
9782
9783 VirtualPixelMethod
9784 virtual_pixel;
9785
9786 if (attribute_flag[0] == 0)
9787 break;
9788 method=UndefinedColorInterpolate;
9789 if (attribute_flag[1] != 0)
9790 method=(SparseColorMethod) argument_list[1].long_reference;
9791 av=(AV *) argument_list[0].array_reference;
9792 number_coordinates=(unsigned long) av_len(av)+1;
9793 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
9794 sizeof(*coordinates));
9795 if (coordinates == (double *) NULL)
9796 {
9797 ThrowPerlException(exception,ResourceLimitFatalError,
9798 "MemoryAllocationFailed",PackageName);
9799 goto PerlException;
9800 }
9801 for (j=0; j < (long) number_coordinates; j++)
9802 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
9803 virtual_pixel=UndefinedVirtualPixelMethod;
9804 if (attribute_flag[2] != 0)
9805 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
9806 argument_list[2].long_reference);
9807 if (attribute_flag[3] != 0)
9808 channel=(ChannelType) argument_list[3].long_reference;
9809 image=SparseColorImage(image,channel,method,number_coordinates,
9810 coordinates,exception);
9811 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
9812 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel);
9813 coordinates=(double *) RelinquishMagickMemory(coordinates);
9814 break;
9815 }
9816 case 120: /* Function */
9817 {
9818 AV
9819 *av;
9820
9821 double
9822 *parameters;
9823
9824 MagickFunction
9825 function;
9826
9827 unsigned long
9828 number_parameters;
9829
9830 VirtualPixelMethod
9831 virtual_pixel;
9832
9833 if (attribute_flag[0] == 0)
9834 break;
9835 function=UndefinedFunction;
9836 if (attribute_flag[1] != 0)
9837 function=(MagickFunction) argument_list[1].long_reference;
9838 av=(AV *) argument_list[0].array_reference;
9839 number_parameters=(unsigned long) av_len(av)+1;
9840 parameters=(double *) AcquireQuantumMemory(number_parameters,
9841 sizeof(*parameters));
9842 if (parameters == (double *) NULL)
9843 {
9844 ThrowPerlException(exception,ResourceLimitFatalError,
9845 "MemoryAllocationFailed",PackageName);
9846 goto PerlException;
9847 }
9848 for (j=0; j < (long) number_parameters; j++)
9849 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
9850 virtual_pixel=UndefinedVirtualPixelMethod;
9851 if (attribute_flag[2] != 0)
9852 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
9853 argument_list[2].long_reference);
9854 (void) FunctionImage(image,function,number_parameters,parameters,
9855 exception);
9856 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
9857 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel);
9858 parameters=(double *) RelinquishMagickMemory(parameters);
9859 break;
9860 }
9861 case 121: /* SelectiveBlur */
9862 {
9863 if (attribute_flag[0] != 0)
9864 {
9865 flags=ParseGeometry(argument_list[0].string_reference,
9866 &geometry_info);
9867 if ((flags & SigmaValue) == 0)
9868 geometry_info.sigma=1.0;
9869 if ((flags & PercentValue) != 0)
9870 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9871 }
9872 if (attribute_flag[1] != 0)
9873 geometry_info.rho=argument_list[1].real_reference;
9874 if (attribute_flag[2] != 0)
9875 geometry_info.sigma=argument_list[2].real_reference;
9876 if (attribute_flag[3] != 0)
9877 geometry_info.xi=argument_list[3].long_reference;;
9878 if (attribute_flag[4] != 0)
9879 channel=(ChannelType) argument_list[4].long_reference;
9880 image=SelectiveBlurImageChannel(image,channel,geometry_info.rho,
9881 geometry_info.sigma,geometry_info.xi,exception);
9882 break;
9883 }
9884 case 122: /* HaldClut */
9885 {
9886 if (attribute_flag[0] == 0)
9887 {
9888 ThrowPerlException(exception,OptionError,"ClutImageRequired",
9889 PackageName);
9890 goto PerlException;
9891 }
9892 if (attribute_flag[1] != 0)
9893 channel=(ChannelType) argument_list[1].long_reference;
9894 (void) HaldClutImageChannel(image,channel,
9895 argument_list[0].image_reference);
9896 break;
9897 }
9898 case 123: /* BlueShift */
9899 {
9900 if (attribute_flag[0] != 0)
9901 (void) ParseGeometry(argument_list[0].string_reference,
9902 &geometry_info);
9903 image=BlueShiftImage(image,geometry_info.rho,exception);
9904 break;
9905 }
9906 case 124: /* ForwardFourierTransformImage */
9907 {
9908 image=ForwardFourierTransformImage(image,
9909 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse,
9910 exception);
9911 break;
9912 }
9913 case 125: /* InverseFourierTransformImage */
9914 {
9915 image=InverseFourierTransformImage(image,
9916 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse,
9917 exception);
9918 break;
9919 }
9920 case 126: /* ColorDecisionList */
9921 {
9922 if (attribute_flag[0] == 0)
9923 argument_list[0].string_reference=(char *) NULL;
9924 (void) ColorDecisionListImage(image,
9925 argument_list[0].string_reference);
9926 break;
9927 }
9928 case 127: /* AutoGamma */
9929 {
9930 if (attribute_flag[0] != 0)
9931 channel=(ChannelType) argument_list[0].long_reference;
9932 (void) AutoGammaImageChannel(image,channel);
9933 break;
9934 }
9935 case 128: /* AutoLevel */
9936 {
9937 if (attribute_flag[0] != 0)
9938 channel=(ChannelType) argument_list[0].long_reference;
9939 (void) AutoLevelImageChannel(image,channel);
9940 break;
9941 }
9942 }
9943 if (next != (Image *) NULL)
9944 (void) CatchImageException(next);
9945 if (region_image != (Image *) NULL)
9946 {
9947 /*
9948 Composite region.
9949 */
9950 status=CompositeImage(region_image,CopyCompositeOp,image,
9951 region_info.x,region_info.y);
9952 (void) CatchImageException(region_image);
9953 image=DestroyImage(image);
9954 image=region_image;
9955 }
9956 if (image != (Image *) NULL)
9957 {
9958 number_images++;
9959 if (next && (next != image))
9960 {
9961 image->next=next->next;
9962 DeleteImageFromRegistry(*pv,next);
9963 }
9964 sv_setiv(*pv,(IV) image);
9965 next=image;
9966 }
9967 if (*pv)
9968 pv++;
9969 }
9970
9971 PerlException:
9972 if (reference_vector)
9973 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
9974 InheritPerlException(exception,perl_exception);
9975 exception=DestroyExceptionInfo(exception);
9976 sv_setiv(perl_exception,(IV) number_images);
9977 SvPOK_on(perl_exception);
9978 ST(0)=sv_2mortal(perl_exception);
9979 XSRETURN(1);
9980 }
9981
9982#
9983###############################################################################
9984# #
9985# #
9986# #
9987# M o n t a g e #
9988# #
9989# #
9990# #
9991###############################################################################
9992#
9993#
9994void
9995Montage(ref,...)
9996 Image::Magick ref=NO_INIT
9997 ALIAS:
9998 MontageImage = 1
9999 montage = 2
10000 montageimage = 3
10001 PPCODE:
10002 {
10003 AV
10004 *av;
10005
10006 char
10007 *attribute;
10008
10009 ExceptionInfo
10010 *exception;
10011
10012 HV
10013 *hv;
10014
10015 Image
10016 *image,
10017 *next;
10018
10019 long
10020 sp;
10021
10022 MagickPixelPacket
10023 transparent_color;
10024
10025 MontageInfo
10026 *montage_info;
10027
10028 register long
10029 i;
10030
10031 struct PackageInfo
10032 *info;
10033
10034 SV
10035 *av_reference,
10036 *perl_exception,
10037 *reference,
10038 *rv,
10039 *sv;
10040
10041 exception=AcquireExceptionInfo();
10042 perl_exception=newSVpv("",0);
10043 attribute=NULL;
10044 if (sv_isobject(ST(0)) == 0)
10045 {
10046 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10047 PackageName);
10048 goto PerlException;
10049 }
10050 reference=SvRV(ST(0));
10051 hv=SvSTASH(reference);
10052 av=newAV();
10053 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10054 SvREFCNT_dec(av);
10055 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10056 if (image == (Image *) NULL)
10057 {
10058 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10059 PackageName);
10060 goto PerlException;
10061 }
10062 /*
10063 Get options.
10064 */
10065 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10066 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
10067 (void) QueryMagickColor("none",&transparent_color,exception);
10068 for (i=2; i < items; i+=2)
10069 {
10070 attribute=(char *) SvPV(ST(i-1),na);
10071 switch (*attribute)
10072 {
10073 case 'B':
10074 case 'b':
10075 {
10076 if (LocaleCompare(attribute,"background") == 0)
10077 {
10078 (void) QueryColorDatabase(SvPV(ST(i),na),
10079 &montage_info->background_color,exception);
10080 for (next=image; next; next=next->next)
10081 next->background_color=montage_info->background_color;
10082 break;
10083 }
10084 if (LocaleCompare(attribute,"border") == 0)
10085 {
10086 montage_info->border_width=SvIV(ST(i));
10087 break;
10088 }
10089 if (LocaleCompare(attribute,"bordercolor") == 0)
10090 {
10091 (void) QueryColorDatabase(SvPV(ST(i),na),
10092 &montage_info->border_color,exception);
10093 for (next=image; next; next=next->next)
10094 next->border_color=montage_info->border_color;
10095 break;
10096 }
10097 if (LocaleCompare(attribute,"borderwidth") == 0)
10098 {
10099 montage_info->border_width=SvIV(ST(i));
10100 break;
10101 }
10102 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10103 attribute);
10104 break;
10105 }
10106 case 'C':
10107 case 'c':
10108 {
10109 if (LocaleCompare(attribute,"compose") == 0)
10110 {
10111 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
10112 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
10113 if (sp < 0)
10114 {
10115 ThrowPerlException(exception,OptionError,"UnrecognizedType",
10116 SvPV(ST(i),na));
10117 break;
10118 }
10119 for (next=image; next; next=next->next)
10120 next->compose=(CompositeOperator) sp;
10121 break;
10122 }
10123 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10124 attribute);
10125 break;
10126 }
10127 case 'F':
10128 case 'f':
10129 {
10130 if (LocaleCompare(attribute,"fill") == 0)
10131 {
10132 (void) QueryColorDatabase(SvPV(ST(i),na),&montage_info->fill,
10133 exception);
10134 break;
10135 }
10136 if (LocaleCompare(attribute,"font") == 0)
10137 {
10138 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
10139 break;
10140 }
10141 if (LocaleCompare(attribute,"frame") == 0)
10142 {
10143 char
10144 *p;
10145
10146 p=SvPV(ST(i),na);
10147 if (IsGeometry(p) == MagickFalse)
10148 {
10149 ThrowPerlException(exception,OptionError,"MissingGeometry",
10150 p);
10151 break;
10152 }
10153 (void) CloneString(&montage_info->frame,p);
10154 if (*p == '\0')
10155 montage_info->frame=(char *) NULL;
10156 break;
10157 }
10158 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10159 attribute);
10160 break;
10161 }
10162 case 'G':
10163 case 'g':
10164 {
10165 if (LocaleCompare(attribute,"geometry") == 0)
10166 {
10167 char
10168 *p;
10169
10170 p=SvPV(ST(i),na);
10171 if (IsGeometry(p) == MagickFalse)
10172 {
10173 ThrowPerlException(exception,OptionError,"MissingGeometry",
10174 p);
10175 break;
10176 }
10177 (void) CloneString(&montage_info->geometry,p);
10178 if (*p == '\0')
10179 montage_info->geometry=(char *) NULL;
10180 break;
10181 }
10182 if (LocaleCompare(attribute,"gravity") == 0)
10183 {
10184 long
10185 in;
10186
10187 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
10188 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
10189 if (in < 0)
10190 {
10191 ThrowPerlException(exception,OptionError,"UnrecognizedType",
10192 SvPV(ST(i),na));
10193 return;
10194 }
10195 montage_info->gravity=(GravityType) in;
10196 for (next=image; next; next=next->next)
10197 next->gravity=(GravityType) in;
10198 break;
10199 }
10200 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10201 attribute);
10202 break;
10203 }
10204 case 'L':
10205 case 'l':
10206 {
10207 if (LocaleCompare(attribute,"label") == 0)
10208 {
10209 for (next=image; next; next=next->next)
10210 (void) SetImageProperty(next,"label",InterpretImageProperties(
10211 info ? info->image_info : (ImageInfo *) NULL,next,
10212 SvPV(ST(i),na)));
10213 break;
10214 }
10215 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10216 attribute);
10217 break;
10218 }
10219 case 'M':
10220 case 'm':
10221 {
10222 if (LocaleCompare(attribute,"mattecolor") == 0)
10223 {
10224 (void) QueryColorDatabase(SvPV(ST(i),na),
10225 &montage_info->matte_color,exception);
10226 for (next=image; next; next=next->next)
10227 next->matte_color=montage_info->matte_color;
10228 break;
10229 }
10230 if (LocaleCompare(attribute,"mode") == 0)
10231 {
10232 long
10233 in;
10234
10235 in=!SvPOK(ST(i)) ? SvIV(ST(i)) :
10236 ParseMagickOption(MagickModeOptions,MagickFalse,SvPV(ST(i),na));
10237 switch (in)
10238 {
10239 default:
10240 {
10241 ThrowPerlException(exception,OptionError,
10242 "UnrecognizedModeType",SvPV(ST(i),na));
10243 break;
10244 }
10245 case FrameMode:
10246 {
10247 (void) CloneString(&montage_info->frame,"15x15+3+3");
10248 montage_info->shadow=MagickTrue;
10249 break;
10250 }
10251 case UnframeMode:
10252 {
10253 montage_info->frame=(char *) NULL;
10254 montage_info->shadow=MagickFalse;
10255 montage_info->border_width=0;
10256 break;
10257 }
10258 case ConcatenateMode:
10259 {
10260 montage_info->frame=(char *) NULL;
10261 montage_info->shadow=MagickFalse;
10262 (void) CloneString(&montage_info->geometry,"+0+0");
10263 montage_info->border_width=0;
10264 }
10265 }
10266 break;
10267 }
10268 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10269 attribute);
10270 break;
10271 }
10272 case 'P':
10273 case 'p':
10274 {
10275 if (LocaleCompare(attribute,"pointsize") == 0)
10276 {
10277 montage_info->pointsize=SvIV(ST(i));
10278 break;
10279 }
10280 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10281 attribute);
10282 break;
10283 }
10284 case 'S':
10285 case 's':
10286 {
10287 if (LocaleCompare(attribute,"shadow") == 0)
10288 {
10289 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
10290 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
10291 if (sp < 0)
10292 {
10293 ThrowPerlException(exception,OptionError,"UnrecognizedType",
10294 SvPV(ST(i),na));
10295 break;
10296 }
10297 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
10298 break;
10299 }
10300 if (LocaleCompare(attribute,"stroke") == 0)
10301 {
10302 (void) QueryColorDatabase(SvPV(ST(i),na),&montage_info->stroke,
10303 exception);
10304 break;
10305 }
10306 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10307 attribute);
10308 break;
10309 }
10310 case 'T':
10311 case 't':
10312 {
10313 if (LocaleCompare(attribute,"texture") == 0)
10314 {
10315 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
10316 break;
10317 }
10318 if (LocaleCompare(attribute,"tile") == 0)
10319 {
10320 char *p=SvPV(ST(i),na);
10321 if (IsGeometry(p) == MagickFalse)
10322 {
10323 ThrowPerlException(exception,OptionError,"MissingGeometry",
10324 p);
10325 break;
10326 }
10327 (void) CloneString(&montage_info->tile,p);
10328 if (*p == '\0')
10329 montage_info->tile=(char *) NULL;
10330 break;
10331 }
10332 if (LocaleCompare(attribute,"title") == 0)
10333 {
10334 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
10335 break;
10336 }
10337 if (LocaleCompare(attribute,"transparent") == 0)
10338 {
10339 MagickPixelPacket
10340 transparent_color;
10341
10342 QueryMagickColor(SvPV(ST(i),na),&transparent_color,exception);
10343 for (next=image; next; next=next->next)
10344 (void) TransparentPaintImage(next,&transparent_color,
10345 TransparentOpacity,MagickFalse);
10346 break;
10347 }
10348 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10349 attribute);
10350 break;
10351 }
10352 default:
10353 {
10354 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10355 attribute);
10356 break;
10357 }
10358 }
10359 }
10360 image=MontageImageList(info->image_info,montage_info,image,exception);
10361 montage_info=DestroyMontageInfo(montage_info);
10362 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
10363 goto PerlException;
10364 if (transparent_color.opacity != TransparentOpacity)
10365 for (next=image; next; next=next->next)
10366 (void) TransparentPaintImage(next,&transparent_color,
10367 TransparentOpacity,MagickFalse);
10368 for ( ; image; image=image->next)
10369 {
10370 AddImageToRegistry(image);
10371 rv=newRV(sv);
10372 av_push(av,sv_bless(rv,hv));
10373 SvREFCNT_dec(sv);
10374 }
10375 exception=DestroyExceptionInfo(exception);
10376 ST(0)=av_reference;
10377 SvREFCNT_dec(perl_exception);
10378 XSRETURN(1);
10379
10380 PerlException:
10381 InheritPerlException(exception,perl_exception);
10382 exception=DestroyExceptionInfo(exception);
10383 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10384 SvPOK_on(perl_exception);
10385 ST(0)=sv_2mortal(perl_exception);
10386 XSRETURN(1);
10387 }
10388
10389#
10390###############################################################################
10391# #
10392# #
10393# #
10394# M o r p h #
10395# #
10396# #
10397# #
10398###############################################################################
10399#
10400#
10401void
10402Morph(ref,...)
10403 Image::Magick ref=NO_INIT
10404 ALIAS:
10405 MorphImage = 1
10406 morph = 2
10407 morphimage = 3
10408 PPCODE:
10409 {
10410 AV
10411 *av;
10412
10413 char
10414 *attribute;
10415
10416 ExceptionInfo
10417 *exception;
10418
10419 HV
10420 *hv;
10421
10422 Image
10423 *image;
10424
10425 long
10426 number_frames;
10427
10428 register long
10429 i;
10430
10431 struct PackageInfo
10432 *info;
10433
10434 SV
10435 *av_reference,
10436 *perl_exception,
10437 *reference,
10438 *rv,
10439 *sv;
10440
10441 exception=AcquireExceptionInfo();
10442 perl_exception=newSVpv("",0);
10443 av=NULL;
10444 attribute=NULL;
10445 if (sv_isobject(ST(0)) == 0)
10446 {
10447 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10448 PackageName);
10449 goto PerlException;
10450 }
10451 reference=SvRV(ST(0));
10452 hv=SvSTASH(reference);
10453 av=newAV();
10454 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10455 SvREFCNT_dec(av);
10456 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10457 if (image == (Image *) NULL)
10458 {
10459 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10460 PackageName);
10461 goto PerlException;
10462 }
10463 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10464 /*
10465 Get attribute.
10466 */
10467 number_frames=30;
10468 for (i=2; i < items; i+=2)
10469 {
10470 attribute=(char *) SvPV(ST(i-1),na);
10471 switch (*attribute)
10472 {
10473 case 'F':
10474 case 'f':
10475 {
10476 if (LocaleCompare(attribute,"frames") == 0)
10477 {
10478 number_frames=SvIV(ST(i));
10479 break;
10480 }
10481 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10482 attribute);
10483 break;
10484 }
10485 default:
10486 {
10487 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10488 attribute);
10489 break;
10490 }
10491 }
10492 }
10493 image=MorphImages(image,number_frames,exception);
10494 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
10495 goto PerlException;
10496 for ( ; image; image=image->next)
10497 {
10498 AddImageToRegistry(image);
10499 rv=newRV(sv);
10500 av_push(av,sv_bless(rv,hv));
10501 SvREFCNT_dec(sv);
10502 }
10503 exception=DestroyExceptionInfo(exception);
10504 ST(0)=av_reference;
10505 SvREFCNT_dec(perl_exception); /* can't return warning messages */
10506 XSRETURN(1);
10507
10508 PerlException:
10509 InheritPerlException(exception,perl_exception);
10510 exception=DestroyExceptionInfo(exception);
10511 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10512 SvPOK_on(perl_exception);
10513 ST(0)=sv_2mortal(perl_exception);
10514 XSRETURN(1);
10515 }
10516
10517#
10518###############################################################################
10519# #
10520# #
10521# #
10522# M o s a i c #
10523# #
10524# #
10525# #
10526###############################################################################
10527#
10528#
10529void
10530Mosaic(ref)
10531 Image::Magick ref=NO_INIT
10532 ALIAS:
10533 MosaicImage = 1
10534 mosaic = 2
10535 mosaicimage = 3
10536 PPCODE:
10537 {
10538 AV
10539 *av;
10540
10541 ExceptionInfo
10542 *exception;
10543
10544 HV
10545 *hv;
10546
10547 Image
10548 *image;
10549
10550 struct PackageInfo
10551 *info;
10552
10553 SV
10554 *perl_exception,
10555 *reference,
10556 *rv,
10557 *sv;
10558
10559 exception=AcquireExceptionInfo();
10560 perl_exception=newSVpv("",0);
10561 if (sv_isobject(ST(0)) == 0)
10562 {
10563 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10564 PackageName);
10565 goto PerlException;
10566 }
10567 reference=SvRV(ST(0));
10568 hv=SvSTASH(reference);
10569 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10570 if (image == (Image *) NULL)
10571 {
10572 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10573 PackageName);
10574 goto PerlException;
10575 }
10576 image=MergeImageLayers(image,MosaicLayer,exception);
10577 /*
10578 Create blessed Perl array for the returned image.
10579 */
10580 av=newAV();
10581 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10582 SvREFCNT_dec(av);
10583 AddImageToRegistry(image);
10584 rv=newRV(sv);
10585 av_push(av,sv_bless(rv,hv));
10586 SvREFCNT_dec(sv);
10587 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10588 (void) CopyMagickString(image->filename,info->image_info->filename,
10589 MaxTextExtent);
10590 SetImageInfo(info->image_info,MagickFalse,&image->exception);
10591 exception=DestroyExceptionInfo(exception);
10592 SvREFCNT_dec(perl_exception);
10593 XSRETURN(1);
10594
10595 PerlException:
10596 InheritPerlException(exception,perl_exception);
10597 exception=DestroyExceptionInfo(exception);
10598 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10599 SvPOK_on(perl_exception); /* return messages in string context */
10600 ST(0)=sv_2mortal(perl_exception);
10601 XSRETURN(1);
10602 }
10603
10604#
10605###############################################################################
10606# #
10607# #
10608# #
10609# P i n g #
10610# #
10611# #
10612# #
10613###############################################################################
10614#
10615#
10616void
10617Ping(ref,...)
10618 Image::Magick ref=NO_INIT
10619 ALIAS:
10620 PingImage = 1
10621 ping = 2
10622 pingimage = 3
10623 PPCODE:
10624 {
10625 AV
10626 *av;
10627
10628 char
10629 **keep,
10630 **list;
10631
10632 ExceptionInfo
10633 *exception;
10634
10635 HV
10636 *hv;
10637
10638 Image
10639 *image,
10640 *next;
10641
10642 int
10643 n;
10644
10645 long
10646 ac;
10647
10648 MagickBooleanType
10649 status;
10650
10651 register char
10652 **p;
10653
10654 register long
10655 i;
10656
10657 STRLEN
10658 *length;
10659
10660 struct PackageInfo
10661 *info,
10662 *package_info;
10663
10664 SV
10665 *perl_exception,
10666 *reference;
10667
10668 unsigned long
10669 count;
10670
10671 exception=AcquireExceptionInfo();
10672 perl_exception=newSVpv("",0);
10673 package_info=(struct PackageInfo *) NULL;
10674 ac=(items < 2) ? 1 : items-1;
10675 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
10676 keep=list;
10677 length=(STRLEN *) NULL;
10678 if (list == (char **) NULL)
10679 {
10680 ThrowPerlException(exception,ResourceLimitError,
10681 "MemoryAllocationFailed",PackageName);
10682 goto PerlException;
10683 }
10684 keep=list;
10685 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
10686 if (length == (STRLEN *) NULL)
10687 {
10688 ThrowPerlException(exception,ResourceLimitError,
10689 "MemoryAllocationFailed",PackageName);
10690 goto PerlException;
10691 }
10692 if (sv_isobject(ST(0)) == 0)
10693 {
10694 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10695 PackageName);
10696 goto PerlException;
10697 }
10698 reference=SvRV(ST(0));
10699 hv=SvSTASH(reference);
10700 if (SvTYPE(reference) != SVt_PVAV)
10701 {
10702 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10703 PackageName);
10704 goto PerlException;
10705 }
10706 av=(AV *) reference;
10707 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
10708 exception);
10709 package_info=ClonePackageInfo(info,exception);
10710 n=1;
10711 if (items <= 1)
10712 *list=(char *) (*package_info->image_info->filename ?
10713 package_info->image_info->filename : "XC:black");
10714 else
10715 for (n=0, i=0; i < ac; i++)
10716 {
10717 list[n]=(char *) SvPV(ST(i+1),length[n]);
10718 if ((items >= 3) && strEQcase(list[n],"blob"))
10719 {
10720 void
10721 *blob;
10722
10723 i++;
10724 blob=(void *) (SvPV(ST(i+1),length[n]));
10725 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
10726 }
10727 if ((items >= 3) && strEQcase(list[n],"filename"))
10728 continue;
10729 if ((items >= 3) && strEQcase(list[n],"file"))
10730 {
10731 FILE
10732 *file;
10733
10734 PerlIO
10735 *io_info;
10736
10737 i++;
10738 io_info=IoIFP(sv_2io(ST(i+1)));
10739 if (io_info == (PerlIO *) NULL)
10740 {
10741 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
10742 PackageName);
10743 continue;
10744 }
10745 file=PerlIO_findFILE(io_info);
10746 if (file == (FILE *) NULL)
10747 {
10748 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
10749 PackageName);
10750 continue;
10751 }
10752 SetImageInfoFile(package_info->image_info,file);
10753 }
10754 if ((items >= 3) && strEQcase(list[n],"magick"))
10755 continue;
10756 n++;
10757 }
10758 list[n]=(char *) NULL;
10759 keep=list;
10760 status=ExpandFilenames(&n,&list);
10761 if (status == MagickFalse)
10762 {
10763 ThrowPerlException(exception,ResourceLimitError,
10764 "MemoryAllocationFailed",PackageName);
10765 goto PerlException;
10766 }
10767 count=0;
10768 for (i=0; i < n; i++)
10769 {
10770 (void) CopyMagickString(package_info->image_info->filename,list[i],
10771 MaxTextExtent);
10772 image=PingImage(package_info->image_info,exception);
10773 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
10774 break;
10775 if ((package_info->image_info->file != (FILE *) NULL) ||
10776 (package_info->image_info->blob != (void *) NULL))
10777 DisassociateImageStream(image);
10778 count+=GetImageListLength(image);
10779 EXTEND(sp,4*count);
10780 for (next=image; next; next=next->next)
10781 {
10782 PUSHs(sv_2mortal(newSViv(next->columns)));
10783 PUSHs(sv_2mortal(newSViv(next->rows)));
10784 PUSHs(sv_2mortal(newSViv((unsigned long) GetBlobSize(next))));
10785 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
10786 }
10787 image=DestroyImageList(image);
10788 }
10789 /*
10790 Free resources.
10791 */
10792 for (i=0; i < n; i++)
10793 if (list[i] != (char *) NULL)
10794 for (p=keep; list[i] != *p++; )
10795 if (*p == NULL)
10796 {
10797 list[i]=(char *) RelinquishMagickMemory(list[i]);
10798 break;
10799 }
10800
10801 PerlException:
10802 if (package_info != (struct PackageInfo *) NULL)
10803 DestroyPackageInfo(package_info);
10804 if (list && (list != keep))
10805 list=(char **) RelinquishMagickMemory(list);
10806 if (keep)
10807 keep=(char **) RelinquishMagickMemory(keep);
10808 if (length)
10809 length=(STRLEN *) RelinquishMagickMemory(length);
10810 InheritPerlException(exception,perl_exception);
10811 exception=DestroyExceptionInfo(exception);
10812 SvREFCNT_dec(perl_exception); /* throw away all errors */
10813 }
10814
10815#
10816###############################################################################
10817# #
10818# #
10819# #
10820# P r e v i e w #
10821# #
10822# #
10823# #
10824###############################################################################
10825#
10826#
10827void
10828Preview(ref,...)
10829 Image::Magick ref=NO_INIT
10830 ALIAS:
10831 PreviewImage = 1
10832 preview = 2
10833 previewimage = 3
10834 PPCODE:
10835 {
10836 AV
10837 *av;
10838
10839 ExceptionInfo
10840 *exception;
10841
10842 HV
10843 *hv;
10844
10845 Image
10846 *image,
10847 *preview_image;
10848
10849 PreviewType
10850 preview_type;
10851
10852 struct PackageInfo
10853 *info;
10854
10855 SV
10856 *av_reference,
10857 *perl_exception,
10858 *reference,
10859 *rv,
10860 *sv;
10861
10862 exception=AcquireExceptionInfo();
10863 perl_exception=newSVpv("",0);
10864 av=NULL;
10865 if (sv_isobject(ST(0)) == 0)
10866 {
10867 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10868 PackageName);
10869 goto PerlException;
10870 }
10871 reference=SvRV(ST(0));
10872 hv=SvSTASH(reference);
10873 av=newAV();
10874 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10875 SvREFCNT_dec(av);
10876 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10877 if (image == (Image *) NULL)
10878 {
10879 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10880 PackageName);
10881 goto PerlException;
10882 }
10883 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10884 preview_type=GammaPreview;
10885 if (items > 1)
10886 preview_type=(PreviewType)
10887 ParseMagickOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
10888 for ( ; image; image=image->next)
10889 {
10890 preview_image=PreviewImage(image,preview_type,exception);
10891 if (preview_image == (Image *) NULL)
10892 goto PerlException;
10893 AddImageToRegistry(preview_image);
10894 rv=newRV(sv);
10895 av_push(av,sv_bless(rv,hv));
10896 SvREFCNT_dec(sv);
10897 }
10898 exception=DestroyExceptionInfo(exception);
10899 ST(0)=av_reference;
10900 SvREFCNT_dec(perl_exception); /* can't return warning messages */
10901 XSRETURN(1);
10902
10903 PerlException:
10904 InheritPerlException(exception,perl_exception);
10905 exception=DestroyExceptionInfo(exception);
10906 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10907 SvPOK_on(perl_exception);
10908 ST(0)=sv_2mortal(perl_exception);
10909 XSRETURN(1);
10910 }
10911
10912#
10913###############################################################################
10914# #
10915# #
10916# #
10917# Q u e r y C o l o r #
10918# #
10919# #
10920# #
10921###############################################################################
10922#
10923#
10924void
10925QueryColor(ref,...)
10926 Image::Magick ref=NO_INIT
10927 ALIAS:
10928 querycolor = 1
10929 PPCODE:
10930 {
10931 char
10932 *name;
10933
10934 ExceptionInfo
10935 *exception;
10936
10937 MagickPixelPacket
10938 color;
10939
10940 register long
10941 i;
10942
10943 SV
10944 *perl_exception;
10945
10946 exception=AcquireExceptionInfo();
10947 perl_exception=newSVpv("",0);
10948 if (items == 1)
10949 {
10950 const ColorInfo
10951 **colorlist;
10952
10953 unsigned long
10954 colors;
10955
10956 colorlist=GetColorInfoList("*",&colors,exception);
10957 EXTEND(sp,colors);
10958 for (i=0; i < (long) colors; i++)
10959 {
10960 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
10961 }
10962 colorlist=(const ColorInfo **)
10963 RelinquishMagickMemory((ColorInfo **) colorlist);
10964 goto PerlException;
10965 }
10966 EXTEND(sp,5*items);
10967 for (i=1; i < items; i++)
10968 {
10969 name=(char *) SvPV(ST(i),na);
10970 if (QueryMagickColor(name,&color,exception) == MagickFalse)
10971 {
10972 PUSHs(&sv_undef);
10973 continue;
10974 }
10975 PUSHs(sv_2mortal(newSViv((unsigned long) (color.red+0.5))));
10976 PUSHs(sv_2mortal(newSViv((unsigned long) (color.green+0.5))));
10977 PUSHs(sv_2mortal(newSViv((unsigned long) (color.blue+0.5))));
10978 if (color.matte != MagickFalse)
10979 PUSHs(sv_2mortal(newSViv((unsigned long) (color.opacity+0.5))));
10980 if (color.colorspace == CMYKColorspace)
10981 PUSHs(sv_2mortal(newSViv((unsigned long) (color.index+0.5))));
10982 }
10983
10984 PerlException:
10985 InheritPerlException(exception,perl_exception);
10986 exception=DestroyExceptionInfo(exception);
10987 SvREFCNT_dec(perl_exception);
10988 }
10989
10990#
10991###############################################################################
10992# #
10993# #
10994# #
10995# Q u e r y C o l o r N a m e #
10996# #
10997# #
10998# #
10999###############################################################################
11000#
11001#
11002void
11003QueryColorname(ref,...)
11004 Image::Magick ref=NO_INIT
11005 ALIAS:
11006 querycolorname = 1
11007 PPCODE:
11008 {
11009 AV
11010 *av;
11011
11012 char
11013 message[MaxTextExtent];
11014
11015 ExceptionInfo
11016 *exception;
11017
11018 Image
11019 *image;
11020
11021 PixelPacket
11022 target_color;
11023
11024 register long
11025 i;
11026
11027 struct PackageInfo
11028 *info;
11029
11030 SV
11031 *perl_exception,
11032 *reference; /* reference is the SV* of ref=SvIV(reference) */
11033
11034 exception=AcquireExceptionInfo();
11035 perl_exception=newSVpv("",0);
11036 reference=SvRV(ST(0));
11037 av=(AV *) reference;
11038 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11039 exception);
11040 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11041 if (image == (Image *) NULL)
11042 {
11043 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11044 PackageName);
11045 goto PerlException;
11046 }
11047 EXTEND(sp,items);
11048 for (i=1; i < items; i++)
11049 {
11050 (void) QueryColorDatabase(SvPV(ST(i),na),&target_color,exception);
11051 (void) QueryColorname(image,&target_color,SVGCompliance,message,
11052 exception);
11053 PUSHs(sv_2mortal(newSVpv(message,0)));
11054 }
11055
11056 PerlException:
11057 InheritPerlException(exception,perl_exception);
11058 exception=DestroyExceptionInfo(exception);
11059 SvREFCNT_dec(perl_exception);
11060 }
11061
11062#
11063###############################################################################
11064# #
11065# #
11066# #
11067# Q u e r y F o n t #
11068# #
11069# #
11070# #
11071###############################################################################
11072#
11073#
11074void
11075QueryFont(ref,...)
11076 Image::Magick ref=NO_INIT
11077 ALIAS:
11078 queryfont = 1
11079 PPCODE:
11080 {
11081 char
11082 *name,
11083 message[MaxTextExtent];
11084
11085 ExceptionInfo
11086 *exception;
11087
11088 register long
11089 i;
11090
11091 SV
11092 *perl_exception;
11093
11094 volatile const TypeInfo
11095 *type_info;
11096
11097 exception=AcquireExceptionInfo();
11098 perl_exception=newSVpv("",0);
11099 if (items == 1)
11100 {
11101 const TypeInfo
11102 **typelist;
11103
11104 unsigned long
11105 types;
11106
11107 typelist=GetTypeInfoList("*",&types,exception);
11108 EXTEND(sp,types);
11109 for (i=0; i < (long) types; i++)
11110 {
11111 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
11112 }
11113 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
11114 typelist);
11115 goto PerlException;
11116 }
11117 EXTEND(sp,10*items);
11118 for (i=1; i < items; i++)
11119 {
11120 name=(char *) SvPV(ST(i),na);
11121 type_info=GetTypeInfo(name,exception);
11122 if (type_info == (TypeInfo *) NULL)
11123 {
11124 PUSHs(&sv_undef);
11125 continue;
11126 }
11127 if (type_info->name == (char *) NULL)
11128 PUSHs(&sv_undef);
11129 else
11130 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
11131 if (type_info->description == (char *) NULL)
11132 PUSHs(&sv_undef);
11133 else
11134 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
11135 if (type_info->family == (char *) NULL)
11136 PUSHs(&sv_undef);
11137 else
11138 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
11139 if (type_info->style == UndefinedStyle)
11140 PUSHs(&sv_undef);
11141 else
11142 PUSHs(sv_2mortal(newSVpv(MagickOptionToMnemonic(MagickStyleOptions,
11143 type_info->style),0)));
11144 if (type_info->stretch == UndefinedStretch)
11145 PUSHs(&sv_undef);
11146 else
11147 PUSHs(sv_2mortal(newSVpv(MagickOptionToMnemonic(MagickStretchOptions,
11148 type_info->stretch),0)));
11149 (void) FormatMagickString(message,MaxTextExtent,"%lu",type_info->weight);
11150 PUSHs(sv_2mortal(newSVpv(message,0)));
11151 if (type_info->encoding == (char *) NULL)
11152 PUSHs(&sv_undef);
11153 else
11154 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
11155 if (type_info->foundry == (char *) NULL)
11156 PUSHs(&sv_undef);
11157 else
11158 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
11159 if (type_info->format == (char *) NULL)
11160 PUSHs(&sv_undef);
11161 else
11162 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
11163 if (type_info->metrics == (char *) NULL)
11164 PUSHs(&sv_undef);
11165 else
11166 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
11167 if (type_info->glyphs == (char *) NULL)
11168 PUSHs(&sv_undef);
11169 else
11170 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
11171 }
11172
11173 PerlException:
11174 InheritPerlException(exception,perl_exception);
11175 exception=DestroyExceptionInfo(exception);
11176 SvREFCNT_dec(perl_exception);
11177 }
11178
11179#
11180###############################################################################
11181# #
11182# #
11183# #
11184# Q u e r y F o n t M e t r i c s #
11185# #
11186# #
11187# #
11188###############################################################################
11189#
11190#
11191void
11192QueryFontMetrics(ref,...)
11193 Image::Magick ref=NO_INIT
11194 ALIAS:
11195 queryfontmetrics = 1
11196 PPCODE:
11197 {
11198 AffineMatrix
11199 affine,
11200 current;
11201
11202 AV
11203 *av;
11204
11205 char
11206 *attribute;
11207
11208 double
11209 x,
11210 y;
11211
11212 DrawInfo
11213 *draw_info;
11214
11215 ExceptionInfo
11216 *exception;
11217
11218 GeometryInfo
11219 geometry_info;
11220
11221 Image
11222 *image;
11223
11224 long
11225 type;
11226
11227 MagickBooleanType
11228 status;
11229
11230 MagickStatusType
11231 flags;
11232
11233 register long
11234 i;
11235
11236 struct PackageInfo
11237 *info,
11238 *package_info;
11239
11240 SV
11241 *perl_exception,
11242 *reference; /* reference is the SV* of ref=SvIV(reference) */
11243
11244 TypeMetric
11245 metrics;
11246
11247 exception=AcquireExceptionInfo();
11248 package_info=(struct PackageInfo *) NULL;
11249 perl_exception=newSVpv("",0);
11250 reference=SvRV(ST(0));
11251 av=(AV *) reference;
11252 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11253 exception);
11254 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11255 if (image == (Image *) NULL)
11256 {
11257 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11258 PackageName);
11259 goto PerlException;
11260 }
11261 package_info=ClonePackageInfo(info,exception);
11262 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
11263 CloneString(&draw_info->text,"");
11264 current=draw_info->affine;
11265 GetAffineMatrix(&affine);
11266 x=0.0;
11267 y=0.0;
11268 EXTEND(sp,7*items);
11269 for (i=2; i < items; i+=2)
11270 {
11271 attribute=(char *) SvPV(ST(i-1),na);
11272 switch (*attribute)
11273 {
11274 case 'A':
11275 case 'a':
11276 {
11277 if (LocaleCompare(attribute,"antialias") == 0)
11278 {
11279 type=ParseMagickOption(MagickBooleanOptions,MagickFalse,
11280 SvPV(ST(i),na));
11281 if (type < 0)
11282 {
11283 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11284 SvPV(ST(i),na));
11285 break;
11286 }
11287 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
11288 break;
11289 }
11290 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11291 attribute);
11292 break;
11293 }
11294 case 'd':
11295 case 'D':
11296 {
11297 if (LocaleCompare(attribute,"density") == 0)
11298 {
11299 CloneString(&draw_info->density,SvPV(ST(i),na));
11300 break;
11301 }
11302 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11303 attribute);
11304 break;
11305 }
11306 case 'e':
11307 case 'E':
11308 {
11309 if (LocaleCompare(attribute,"encoding") == 0)
11310 {
11311 CloneString(&draw_info->encoding,SvPV(ST(i),na));
11312 break;
11313 }
11314 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11315 attribute);
11316 break;
11317 }
11318 case 'f':
11319 case 'F':
11320 {
11321 if (LocaleCompare(attribute,"family") == 0)
11322 {
11323 CloneString(&draw_info->family,SvPV(ST(i),na));
11324 break;
11325 }
11326 if (LocaleCompare(attribute,"fill") == 0)
11327 {
11328 if (info)
11329 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->fill,
11330 &image->exception);
11331 break;
11332 }
11333 if (LocaleCompare(attribute,"font") == 0)
11334 {
11335 CloneString(&draw_info->font,SvPV(ST(i),na));
11336 break;
11337 }
11338 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11339 attribute);
11340 break;
11341 }
11342 case 'g':
11343 case 'G':
11344 {
11345 if (LocaleCompare(attribute,"geometry") == 0)
11346 {
11347 CloneString(&draw_info->geometry,SvPV(ST(i),na));
11348 break;
11349 }
11350 if (LocaleCompare(attribute,"gravity") == 0)
11351 {
11352 draw_info->gravity=(GravityType) ParseMagickOption(
11353 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11354 break;
11355 }
11356 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11357 attribute);
11358 break;
11359 }
11360 case 'i':
11361 case 'I':
11362 {
cristyb32b90a2009-09-07 21:45:48 +000011363 if (LocaleCompare(attribute,"interline-spacing") == 0)
11364 {
11365 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11366 draw_info->interline_spacing=geometry_info.rho;
11367 break;
11368 }
cristy3ed852e2009-09-05 21:47:34 +000011369 if (LocaleCompare(attribute,"interword-spacing") == 0)
11370 {
11371 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11372 draw_info->interword_spacing=geometry_info.rho;
11373 break;
11374 }
11375 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11376 attribute);
11377 break;
11378 }
11379 case 'k':
11380 case 'K':
11381 {
11382 if (LocaleCompare(attribute,"kerning") == 0)
11383 {
11384 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11385 draw_info->kerning=geometry_info.rho;
11386 break;
11387 }
11388 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11389 attribute);
11390 break;
11391 }
11392 case 'p':
11393 case 'P':
11394 {
11395 if (LocaleCompare(attribute,"pointsize") == 0)
11396 {
11397 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11398 draw_info->pointsize=geometry_info.rho;
11399 break;
11400 }
11401 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11402 attribute);
11403 break;
11404 }
11405 case 'r':
11406 case 'R':
11407 {
11408 if (LocaleCompare(attribute,"rotate") == 0)
11409 {
11410 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11411 affine.rx=geometry_info.rho;
11412 affine.ry=geometry_info.sigma;
11413 if ((flags & SigmaValue) == 0)
11414 affine.ry=affine.rx;
11415 break;
11416 }
11417 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11418 attribute);
11419 break;
11420 }
11421 case 's':
11422 case 'S':
11423 {
11424 if (LocaleCompare(attribute,"scale") == 0)
11425 {
11426 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11427 affine.sx=geometry_info.rho;
11428 affine.sy=geometry_info.sigma;
11429 if ((flags & SigmaValue) == 0)
11430 affine.sy=affine.sx;
11431 break;
11432 }
11433 if (LocaleCompare(attribute,"skew") == 0)
11434 {
11435 double
11436 x_angle,
11437 y_angle;
11438
11439 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11440 x_angle=geometry_info.rho;
11441 y_angle=geometry_info.sigma;
11442 if ((flags & SigmaValue) == 0)
11443 y_angle=x_angle;
11444 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
11445 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
11446 break;
11447 }
11448 if (LocaleCompare(attribute,"stroke") == 0)
11449 {
11450 if (info)
11451 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->stroke,
11452 &image->exception);
11453 break;
11454 }
11455 if (LocaleCompare(attribute,"style") == 0)
11456 {
11457 type=ParseMagickOption(MagickStyleOptions,MagickFalse,
11458 SvPV(ST(i),na));
11459 if (type < 0)
11460 {
11461 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11462 SvPV(ST(i),na));
11463 break;
11464 }
11465 draw_info->style=(StyleType) type;
11466 break;
11467 }
11468 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11469 attribute);
11470 break;
11471 }
11472 case 't':
11473 case 'T':
11474 {
11475 if (LocaleCompare(attribute,"text") == 0)
11476 {
11477 CloneString(&draw_info->text,SvPV(ST(i),na));
11478 break;
11479 }
11480 if (LocaleCompare(attribute,"translate") == 0)
11481 {
11482 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11483 affine.tx=geometry_info.rho;
11484 affine.ty=geometry_info.sigma;
11485 if ((flags & SigmaValue) == 0)
11486 affine.ty=affine.tx;
11487 break;
11488 }
11489 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11490 attribute);
11491 break;
11492 }
11493 case 'w':
11494 case 'W':
11495 {
11496 if (LocaleCompare(attribute,"weight") == 0)
11497 {
11498 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11499 draw_info->weight=(unsigned long) geometry_info.rho;
11500 break;
11501 }
11502 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11503 attribute);
11504 break;
11505 }
11506 case 'x':
11507 case 'X':
11508 {
11509 if (LocaleCompare(attribute,"x") == 0)
11510 {
11511 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11512 x=geometry_info.rho;
11513 break;
11514 }
11515 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11516 attribute);
11517 break;
11518 }
11519 case 'y':
11520 case 'Y':
11521 {
11522 if (LocaleCompare(attribute,"y") == 0)
11523 {
11524 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11525 y=geometry_info.rho;
11526 break;
11527 }
11528 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11529 attribute);
11530 break;
11531 }
11532 default:
11533 {
11534 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11535 attribute);
11536 break;
11537 }
11538 }
11539 }
11540 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
11541 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
11542 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
11543 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
11544 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
11545 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
11546 if (draw_info->geometry == (char *) NULL)
11547 {
11548 draw_info->geometry=AcquireString((char *) NULL);
11549 (void) FormatMagickString(draw_info->geometry,MaxTextExtent,"%g,%g",
11550 x,y);
11551 }
11552 status=GetTypeMetrics(image,draw_info,&metrics);
11553 (void) CatchImageException(image);
11554 if (status == MagickFalse)
11555 PUSHs(&sv_undef);
11556 else
11557 {
11558 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
11559 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
11560 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
11561 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
11562 PUSHs(sv_2mortal(newSVnv(metrics.width)));
11563 PUSHs(sv_2mortal(newSVnv(metrics.height)));
11564 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
11565 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
11566 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
11567 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
11568 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
11569 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
11570 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
11571 }
11572 draw_info=DestroyDrawInfo(draw_info);
11573
11574 PerlException:
11575 if (package_info != (struct PackageInfo *) NULL)
11576 DestroyPackageInfo(package_info);
11577 InheritPerlException(exception,perl_exception);
11578 exception=DestroyExceptionInfo(exception);
11579 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11580 }
11581
11582#
11583###############################################################################
11584# #
11585# #
11586# #
11587# 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 #
11588# #
11589# #
11590# #
11591###############################################################################
11592#
11593#
11594void
11595QueryMultilineFontMetrics(ref,...)
11596 Image::Magick ref=NO_INIT
11597 ALIAS:
11598 querymultilinefontmetrics = 1
11599 PPCODE:
11600 {
11601 AffineMatrix
11602 affine,
11603 current;
11604
11605 AV
11606 *av;
11607
11608 char
11609 *attribute;
11610
11611 double
11612 x,
11613 y;
11614
11615 DrawInfo
11616 *draw_info;
11617
11618 ExceptionInfo
11619 *exception;
11620
11621 GeometryInfo
11622 geometry_info;
11623
11624 Image
11625 *image;
11626
11627 long
11628 type;
11629
11630 MagickBooleanType
11631 status;
11632
11633 MagickStatusType
11634 flags;
11635
11636 register long
11637 i;
11638
11639 struct PackageInfo
11640 *info,
11641 *package_info;
11642
11643 SV
11644 *perl_exception,
11645 *reference; /* reference is the SV* of ref=SvIV(reference) */
11646
11647 TypeMetric
11648 metrics;
11649
11650 exception=AcquireExceptionInfo();
11651 package_info=(struct PackageInfo *) NULL;
11652 perl_exception=newSVpv("",0);
11653 reference=SvRV(ST(0));
11654 av=(AV *) reference;
11655 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11656 exception);
11657 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11658 if (image == (Image *) NULL)
11659 {
11660 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11661 PackageName);
11662 goto PerlException;
11663 }
11664 package_info=ClonePackageInfo(info,exception);
11665 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
11666 CloneString(&draw_info->text,"");
11667 current=draw_info->affine;
11668 GetAffineMatrix(&affine);
11669 x=0.0;
11670 y=0.0;
11671 EXTEND(sp,7*items);
11672 for (i=2; i < items; i+=2)
11673 {
11674 attribute=(char *) SvPV(ST(i-1),na);
11675 switch (*attribute)
11676 {
11677 case 'A':
11678 case 'a':
11679 {
11680 if (LocaleCompare(attribute,"antialias") == 0)
11681 {
11682 type=ParseMagickOption(MagickBooleanOptions,MagickFalse,
11683 SvPV(ST(i),na));
11684 if (type < 0)
11685 {
11686 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11687 SvPV(ST(i),na));
11688 break;
11689 }
11690 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
11691 break;
11692 }
11693 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11694 attribute);
11695 break;
11696 }
11697 case 'd':
11698 case 'D':
11699 {
11700 if (LocaleCompare(attribute,"density") == 0)
11701 {
11702 CloneString(&draw_info->density,SvPV(ST(i),na));
11703 break;
11704 }
11705 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11706 attribute);
11707 break;
11708 }
11709 case 'e':
11710 case 'E':
11711 {
11712 if (LocaleCompare(attribute,"encoding") == 0)
11713 {
11714 CloneString(&draw_info->encoding,SvPV(ST(i),na));
11715 break;
11716 }
11717 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11718 attribute);
11719 break;
11720 }
11721 case 'f':
11722 case 'F':
11723 {
11724 if (LocaleCompare(attribute,"family") == 0)
11725 {
11726 CloneString(&draw_info->family,SvPV(ST(i),na));
11727 break;
11728 }
11729 if (LocaleCompare(attribute,"fill") == 0)
11730 {
11731 if (info)
11732 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->fill,
11733 &image->exception);
11734 break;
11735 }
11736 if (LocaleCompare(attribute,"font") == 0)
11737 {
11738 CloneString(&draw_info->font,SvPV(ST(i),na));
11739 break;
11740 }
11741 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11742 attribute);
11743 break;
11744 }
11745 case 'g':
11746 case 'G':
11747 {
11748 if (LocaleCompare(attribute,"geometry") == 0)
11749 {
11750 CloneString(&draw_info->geometry,SvPV(ST(i),na));
11751 break;
11752 }
11753 if (LocaleCompare(attribute,"gravity") == 0)
11754 {
11755 draw_info->gravity=(GravityType) ParseMagickOption(
11756 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11757 break;
11758 }
11759 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11760 attribute);
11761 break;
11762 }
11763 case 'p':
11764 case 'P':
11765 {
11766 if (LocaleCompare(attribute,"pointsize") == 0)
11767 {
11768 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11769 draw_info->pointsize=geometry_info.rho;
11770 break;
11771 }
11772 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11773 attribute);
11774 break;
11775 }
11776 case 'r':
11777 case 'R':
11778 {
11779 if (LocaleCompare(attribute,"rotate") == 0)
11780 {
11781 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11782 affine.rx=geometry_info.rho;
11783 affine.ry=geometry_info.sigma;
11784 if ((flags & SigmaValue) == 0)
11785 affine.ry=affine.rx;
11786 break;
11787 }
11788 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11789 attribute);
11790 break;
11791 }
11792 case 's':
11793 case 'S':
11794 {
11795 if (LocaleCompare(attribute,"scale") == 0)
11796 {
11797 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11798 affine.sx=geometry_info.rho;
11799 affine.sy=geometry_info.sigma;
11800 if ((flags & SigmaValue) == 0)
11801 affine.sy=affine.sx;
11802 break;
11803 }
11804 if (LocaleCompare(attribute,"skew") == 0)
11805 {
11806 double
11807 x_angle,
11808 y_angle;
11809
11810 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11811 x_angle=geometry_info.rho;
11812 y_angle=geometry_info.sigma;
11813 if ((flags & SigmaValue) == 0)
11814 y_angle=x_angle;
11815 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
11816 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
11817 break;
11818 }
11819 if (LocaleCompare(attribute,"stroke") == 0)
11820 {
11821 if (info)
11822 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->stroke,
11823 &image->exception);
11824 break;
11825 }
11826 if (LocaleCompare(attribute,"style") == 0)
11827 {
11828 type=ParseMagickOption(MagickStyleOptions,MagickFalse,
11829 SvPV(ST(i),na));
11830 if (type < 0)
11831 {
11832 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11833 SvPV(ST(i),na));
11834 break;
11835 }
11836 draw_info->style=(StyleType) type;
11837 break;
11838 }
11839 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11840 attribute);
11841 break;
11842 }
11843 case 't':
11844 case 'T':
11845 {
11846 if (LocaleCompare(attribute,"text") == 0)
11847 {
11848 CloneString(&draw_info->text,SvPV(ST(i),na));
11849 break;
11850 }
11851 if (LocaleCompare(attribute,"translate") == 0)
11852 {
11853 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11854 affine.tx=geometry_info.rho;
11855 affine.ty=geometry_info.sigma;
11856 if ((flags & SigmaValue) == 0)
11857 affine.ty=affine.tx;
11858 break;
11859 }
11860 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11861 attribute);
11862 break;
11863 }
11864 case 'w':
11865 case 'W':
11866 {
11867 if (LocaleCompare(attribute,"weight") == 0)
11868 {
11869 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11870 draw_info->weight=(unsigned long) geometry_info.rho;
11871 break;
11872 }
11873 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11874 attribute);
11875 break;
11876 }
11877 case 'x':
11878 case 'X':
11879 {
11880 if (LocaleCompare(attribute,"x") == 0)
11881 {
11882 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11883 x=geometry_info.rho;
11884 break;
11885 }
11886 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11887 attribute);
11888 break;
11889 }
11890 case 'y':
11891 case 'Y':
11892 {
11893 if (LocaleCompare(attribute,"y") == 0)
11894 {
11895 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11896 y=geometry_info.rho;
11897 break;
11898 }
11899 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11900 attribute);
11901 break;
11902 }
11903 default:
11904 {
11905 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11906 attribute);
11907 break;
11908 }
11909 }
11910 }
11911 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
11912 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
11913 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
11914 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
11915 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
11916 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
11917 if (draw_info->geometry == (char *) NULL)
11918 {
11919 draw_info->geometry=AcquireString((char *) NULL);
11920 (void) FormatMagickString(draw_info->geometry,MaxTextExtent,"%g,%g",
11921 x,y);
11922 }
11923 status=GetMultilineTypeMetrics(image,draw_info,&metrics);
11924 (void) CatchImageException(image);
11925 if (status == MagickFalse)
11926 PUSHs(&sv_undef);
11927 else
11928 {
11929 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
11930 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
11931 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
11932 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
11933 PUSHs(sv_2mortal(newSVnv(metrics.width)));
11934 PUSHs(sv_2mortal(newSVnv(metrics.height)));
11935 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
11936 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
11937 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
11938 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
11939 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
11940 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
11941 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
11942 }
11943 draw_info=DestroyDrawInfo(draw_info);
11944
11945 PerlException:
11946 if (package_info != (struct PackageInfo *) NULL)
11947 DestroyPackageInfo(package_info);
11948 InheritPerlException(exception,perl_exception);
11949 exception=DestroyExceptionInfo(exception);
11950 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11951 }
11952
11953#
11954###############################################################################
11955# #
11956# #
11957# #
11958# Q u e r y F o r m a t #
11959# #
11960# #
11961# #
11962###############################################################################
11963#
11964#
11965void
11966QueryFormat(ref,...)
11967 Image::Magick ref=NO_INIT
11968 ALIAS:
11969 queryformat = 1
11970 PPCODE:
11971 {
11972 char
11973 *name;
11974
11975 ExceptionInfo
11976 *exception;
11977
11978 register long
11979 i;
11980
11981 SV
11982 *perl_exception;
11983
11984 volatile const MagickInfo
11985 *magick_info;
11986
11987 exception=AcquireExceptionInfo();
11988 perl_exception=newSVpv("",0);
11989 if (items == 1)
11990 {
11991 char
11992 format[MaxTextExtent];
11993
11994 const MagickInfo
11995 **format_list;
11996
11997 unsigned long
11998 types;
11999
12000 format_list=GetMagickInfoList("*",&types,exception);
12001 EXTEND(sp,types);
12002 for (i=0; i < (long) types; i++)
12003 {
12004 (void) CopyMagickString(format,format_list[i]->name,MaxTextExtent);
12005 LocaleLower(format);
12006 PUSHs(sv_2mortal(newSVpv(format,0)));
12007 }
12008 format_list=(const MagickInfo **)
12009 RelinquishMagickMemory((MagickInfo *) format_list);
12010 goto PerlException;
12011 }
12012 EXTEND(sp,8*items);
12013 for (i=1; i < items; i++)
12014 {
12015 name=(char *) SvPV(ST(i),na);
12016 magick_info=GetMagickInfo(name,exception);
12017 if (magick_info == (const MagickInfo *) NULL)
12018 {
12019 PUSHs(&sv_undef);
12020 continue;
12021 }
12022 PUSHs(sv_2mortal(newSViv(magick_info->adjoin)));
12023 PUSHs(sv_2mortal(newSViv(magick_info->blob_support)));
12024 PUSHs(sv_2mortal(newSViv(magick_info->raw)));
12025 PUSHs(sv_2mortal(newSViv((long) magick_info->decoder)));
12026 PUSHs(sv_2mortal(newSViv((long) magick_info->encoder)));
12027 if (magick_info->description == (char *) NULL)
12028 PUSHs(&sv_undef);
12029 else
12030 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
12031 if (magick_info->module == (char *) NULL)
12032 PUSHs(&sv_undef);
12033 else
12034 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
12035 }
12036
12037 PerlException:
12038 InheritPerlException(exception,perl_exception);
12039 exception=DestroyExceptionInfo(exception);
12040 SvREFCNT_dec(perl_exception);
12041 }
12042
12043#
12044###############################################################################
12045# #
12046# #
12047# #
12048# Q u e r y O p t i o n #
12049# #
12050# #
12051# #
12052###############################################################################
12053#
12054#
12055void
12056QueryOption(ref,...)
12057 Image::Magick ref=NO_INIT
12058 ALIAS:
12059 queryoption = 1
12060 PPCODE:
12061 {
12062 char
12063 **options;
12064
12065 ExceptionInfo
12066 *exception;
12067
12068 long
12069 j,
12070 option;
12071
12072 register long
12073 i;
12074
12075 SV
12076 *perl_exception;
12077
12078 exception=AcquireExceptionInfo();
12079 perl_exception=newSVpv("",0);
12080 EXTEND(sp,8*items);
12081 for (i=1; i < items; i++)
12082 {
12083 option=ParseMagickOption(MagickListOptions,MagickFalse,(char *)
12084 SvPV(ST(i),na));
12085 options=GetMagickOptions((MagickOption) option);
12086 if (options == (char **) NULL)
12087 PUSHs(&sv_undef);
12088 else
12089 {
12090 for (j=0; options[j] != (char *) NULL; j++)
12091 PUSHs(sv_2mortal(newSVpv(options[j],0)));
12092 options=DestroyStringList(options);
12093 }
12094 }
12095
12096 PerlException:
12097 InheritPerlException(exception,perl_exception);
12098 exception=DestroyExceptionInfo(exception);
12099 SvREFCNT_dec(perl_exception);
12100 }
12101
12102#
12103###############################################################################
12104# #
12105# #
12106# #
12107# R e a d #
12108# #
12109# #
12110# #
12111###############################################################################
12112#
12113#
12114void
12115Read(ref,...)
12116 Image::Magick ref=NO_INIT
12117 ALIAS:
12118 ReadImage = 1
12119 read = 2
12120 readimage = 3
12121 PPCODE:
12122 {
12123 AV
12124 *av;
12125
12126 char
12127 **keep,
12128 **list;
12129
12130 ExceptionInfo
12131 *exception;
12132
12133 HV
12134 *hv;
12135
12136 Image
12137 *image;
12138
12139 int
12140 n;
12141
12142 long
12143 ac,
12144 number_images;
12145
12146 MagickBooleanType
12147 status;
12148
12149 register char
12150 **p;
12151
12152 register long
12153 i;
12154
12155 STRLEN
12156 *length;
12157
12158 struct PackageInfo
12159 *info,
12160 *package_info;
12161
12162 SV
12163 *perl_exception, /* Perl variable for storing messages */
12164 *reference,
12165 *rv,
12166 *sv;
12167
12168 exception=AcquireExceptionInfo();
12169 perl_exception=newSVpv("",0);
12170 package_info=(struct PackageInfo *) NULL;
12171 number_images=0;
12172 ac=(items < 2) ? 1 : items-1;
12173 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12174 keep=list;
12175 length=(STRLEN *) NULL;
12176 if (list == (char **) NULL)
12177 {
12178 ThrowPerlException(exception,ResourceLimitError,
12179 "MemoryAllocationFailed",PackageName);
12180 goto PerlException;
12181 }
12182 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12183 if (length == (STRLEN *) NULL)
12184 {
12185 ThrowPerlException(exception,ResourceLimitError,
12186 "MemoryAllocationFailed",PackageName);
12187 goto PerlException;
12188 }
12189 if (sv_isobject(ST(0)) == 0)
12190 {
12191 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12192 PackageName);
12193 goto PerlException;
12194 }
12195 reference=SvRV(ST(0));
12196 hv=SvSTASH(reference);
12197 if (SvTYPE(reference) != SVt_PVAV)
12198 {
12199 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12200 PackageName);
12201 goto PerlException;
12202 }
12203 av=(AV *) reference;
12204 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12205 exception);
12206 package_info=ClonePackageInfo(info,exception);
12207 n=1;
12208 if (items <= 1)
12209 *list=(char *) (*package_info->image_info->filename ?
12210 package_info->image_info->filename : "XC:black");
12211 else
12212 for (n=0, i=0; i < ac; i++)
12213 {
12214 list[n]=(char *) SvPV(ST(i+1),length[n]);
12215 if ((items >= 3) && strEQcase(list[n],"blob"))
12216 {
12217 void
12218 *blob;
12219
12220 i++;
12221 blob=(void *) (SvPV(ST(i+1),length[n]));
12222 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12223 }
12224 if ((items >= 3) && strEQcase(list[n],"filename"))
12225 continue;
12226 if ((items >= 3) && strEQcase(list[n],"file"))
12227 {
12228 FILE
12229 *file;
12230
12231 PerlIO
12232 *io_info;
12233
12234 i++;
12235 io_info=IoIFP(sv_2io(ST(i+1)));
12236 if (io_info == (PerlIO *) NULL)
12237 {
12238 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12239 PackageName);
12240 continue;
12241 }
12242 file=PerlIO_findFILE(io_info);
12243 if (file == (FILE *) NULL)
12244 {
12245 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12246 PackageName);
12247 continue;
12248 }
12249 SetImageInfoFile(package_info->image_info,file);
12250 }
12251 if ((items >= 3) && strEQcase(list[n],"magick"))
12252 continue;
12253 n++;
12254 }
12255 list[n]=(char *) NULL;
12256 keep=list;
12257 status=ExpandFilenames(&n,&list);
12258 if (status == MagickFalse)
12259 {
12260 ThrowPerlException(exception,ResourceLimitError,
12261 "MemoryAllocationFailed",PackageName);
12262 goto PerlException;
12263 }
12264 number_images=0;
12265 for (i=0; i < n; i++)
12266 {
12267 if ((package_info->image_info->file != (FILE *) NULL) ||
12268 (package_info->image_info->blob != (void *) NULL))
12269 {
12270 image=ReadImages(package_info->image_info,exception);
12271 if (image != (Image *) NULL)
12272 DisassociateImageStream(image);
12273 }
12274 else
12275 {
12276 (void) CopyMagickString(package_info->image_info->filename,list[i],
12277 MaxTextExtent);
12278 image=ReadImages(package_info->image_info,exception);
12279 }
12280 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
12281 break;
12282 for ( ; image; image=image->next)
12283 {
12284 AddImageToRegistry(image);
12285 rv=newRV(sv);
12286 av_push(av,sv_bless(rv,hv));
12287 SvREFCNT_dec(sv);
12288 number_images++;
12289 }
12290 }
12291 /*
12292 Free resources.
12293 */
12294 for (i=0; i < n; i++)
12295 if (list[i] != (char *) NULL)
12296 for (p=keep; list[i] != *p++; )
12297 if (*p == (char *) NULL)
12298 {
12299 list[i]=(char *) RelinquishMagickMemory(list[i]);
12300 break;
12301 }
12302
12303 PerlException:
12304 if (package_info != (struct PackageInfo *) NULL)
12305 DestroyPackageInfo(package_info);
12306 if (list && (list != keep))
12307 list=(char **) RelinquishMagickMemory(list);
12308 if (keep)
12309 keep=(char **) RelinquishMagickMemory(keep);
12310 if (length)
12311 length=(STRLEN *) RelinquishMagickMemory(length);
12312 InheritPerlException(exception,perl_exception);
12313 exception=DestroyExceptionInfo(exception);
12314 sv_setiv(perl_exception,(IV) number_images);
12315 SvPOK_on(perl_exception);
12316 ST(0)=sv_2mortal(perl_exception);
12317 XSRETURN(1);
12318 }
12319
12320#
12321###############################################################################
12322# #
12323# #
12324# #
12325# R e m o t e #
12326# #
12327# #
12328# #
12329###############################################################################
12330#
12331#
12332void
12333Remote(ref,...)
12334 Image::Magick ref=NO_INIT
12335 ALIAS:
12336 RemoteCommand = 1
12337 remote = 2
12338 remoteCommand = 3
12339 PPCODE:
12340 {
12341 AV
12342 *av;
12343
12344 ExceptionInfo
12345 *exception;
12346
12347 register long
12348 i;
12349
12350 SV
12351 *perl_exception,
12352 *reference;
12353
12354 struct PackageInfo
12355 *info;
12356
12357 exception=AcquireExceptionInfo();
12358 perl_exception=newSVpv("",0);
12359 reference=SvRV(ST(0));
12360 av=(AV *) reference;
12361 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12362 exception);
12363 for (i=1; i < items; i++)
12364 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
12365 SvPV(ST(i),na),exception);
12366 InheritPerlException(exception,perl_exception);
12367 exception=DestroyExceptionInfo(exception);
12368 SvREFCNT_dec(perl_exception); /* throw away all errors */
12369 }
12370
12371#
12372###############################################################################
12373# #
12374# #
12375# #
12376# S e t #
12377# #
12378# #
12379# #
12380###############################################################################
12381#
12382#
12383void
12384Set(ref,...)
12385 Image::Magick ref=NO_INIT
12386 ALIAS:
12387 SetAttributes = 1
12388 SetAttribute = 2
12389 set = 3
12390 setattributes = 4
12391 setattribute = 5
12392 PPCODE:
12393 {
12394 ExceptionInfo
12395 *exception;
12396
12397 Image
12398 *image;
12399
12400 register long
12401 i;
12402
12403 struct PackageInfo
12404 *info;
12405
12406 SV
12407 *perl_exception,
12408 *reference; /* reference is the SV* of ref=SvIV(reference) */
12409
12410 exception=AcquireExceptionInfo();
12411 perl_exception=newSVpv("",0);
12412 if (sv_isobject(ST(0)) == 0)
12413 {
12414 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12415 PackageName);
12416 goto PerlException;
12417 }
12418 reference=SvRV(ST(0));
12419 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12420 if (items == 2)
12421 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
12422 else
12423 for (i=2; i < items; i+=2)
12424 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
12425
12426 PerlException:
12427 InheritPerlException(exception,perl_exception);
12428 exception=DestroyExceptionInfo(exception);
12429 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
12430 SvPOK_on(perl_exception);
12431 ST(0)=sv_2mortal(perl_exception);
12432 XSRETURN(1);
12433 }
12434
12435#
12436###############################################################################
12437# #
12438# #
12439# #
12440# S e t P i x e l #
12441# #
12442# #
12443# #
12444###############################################################################
12445#
12446#
12447void
12448SetPixel(ref,...)
12449 Image::Magick ref=NO_INIT
12450 ALIAS:
12451 setpixel = 1
12452 setPixel = 2
12453 PPCODE:
12454 {
12455 AV
12456 *av;
12457
12458 char
12459 *attribute;
12460
12461 ChannelType
12462 channel;
12463
12464 ExceptionInfo
12465 *exception;
12466
12467 Image
12468 *image;
12469
12470 long
12471 option;
12472
12473 MagickBooleanType
12474 normalize;
12475
12476 RectangleInfo
12477 region;
12478
12479 register IndexPacket
12480 *indexes;
12481
12482 register long
12483 i;
12484
12485 register PixelPacket
12486 *q;
12487
12488 struct PackageInfo
12489 *info;
12490
12491 SV
12492 *perl_exception,
12493 *reference; /* reference is the SV* of ref=SvIV(reference) */
12494
12495 exception=AcquireExceptionInfo();
12496 perl_exception=newSVpv("",0);
12497 reference=SvRV(ST(0));
12498 av=(AV *) reference;
12499 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12500 exception);
12501 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12502 if (image == (Image *) NULL)
12503 {
12504 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12505 PackageName);
12506 goto PerlException;
12507 }
12508 av=(AV *) NULL;
12509 channel=DefaultChannels;
12510 normalize=MagickTrue;
12511 region.x=0;
12512 region.y=0;
12513 region.width=image->columns;
12514 region.height=1;
12515 if (items == 1)
12516 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
12517 for (i=2; i < items; i+=2)
12518 {
12519 attribute=(char *) SvPV(ST(i-1),na);
12520 switch (*attribute)
12521 {
12522 case 'C':
12523 case 'c':
12524 {
12525 if (LocaleCompare(attribute,"channel") == 0)
12526 {
12527 long
12528 option;
12529
12530 option=ParseChannelOption(SvPV(ST(i),na));
12531 if (option < 0)
12532 {
12533 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12534 SvPV(ST(i),na));
12535 return;
12536 }
12537 channel=(ChannelType) option;
12538 break;
12539 }
12540 if (LocaleCompare(attribute,"color") == 0)
12541 {
12542 if (SvTYPE(ST(i)) != SVt_RV)
12543 {
12544 char
12545 message[MaxTextExtent];
12546
12547 (void) FormatMagickString(message,MaxTextExtent,
12548 "invalid %.60s value",attribute);
12549 ThrowPerlException(exception,OptionError,message,
12550 SvPV(ST(i),na));
12551 }
12552 av=(AV *) SvRV(ST(i));
12553 break;
12554 }
12555 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12556 attribute);
12557 break;
12558 }
12559 case 'g':
12560 case 'G':
12561 {
12562 if (LocaleCompare(attribute,"geometry") == 0)
12563 {
12564 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
12565 break;
12566 }
12567 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12568 attribute);
12569 break;
12570 }
12571 case 'N':
12572 case 'n':
12573 {
12574 if (LocaleCompare(attribute,"normalize") == 0)
12575 {
12576 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
12577 SvPV(ST(i),na));
12578 if (option < 0)
12579 {
12580 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12581 SvPV(ST(i),na));
12582 break;
12583 }
12584 normalize=option != 0 ? MagickTrue : MagickFalse;
12585 break;
12586 }
12587 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12588 attribute);
12589 break;
12590 }
12591 case 'x':
12592 case 'X':
12593 {
12594 if (LocaleCompare(attribute,"x") == 0)
12595 {
12596 region.x=SvIV(ST(i));
12597 break;
12598 }
12599 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12600 attribute);
12601 break;
12602 }
12603 case 'y':
12604 case 'Y':
12605 {
12606 if (LocaleCompare(attribute,"y") == 0)
12607 {
12608 region.y=SvIV(ST(i));
12609 break;
12610 }
12611 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12612 attribute);
12613 break;
12614 }
12615 default:
12616 {
12617 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12618 attribute);
12619 break;
12620 }
12621 }
12622 }
12623 (void) SetImageStorageClass(image,DirectClass);
12624 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
12625 if ((q == (PixelPacket *) NULL) || (av == (AV *) NULL))
12626 PUSHs(&sv_undef);
12627 else
12628 {
12629 double
12630 scale;
12631
12632 register long
12633 i;
12634
12635 i=0;
12636 indexes=GetAuthenticIndexQueue(image);
12637 scale=1.0;
12638 if (normalize != MagickFalse)
12639 scale=QuantumRange;
12640 if (((channel & RedChannel) != 0) && (i <= av_len(av)))
12641 {
12642 q->red=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12643 i++;
12644 }
12645 if (((channel & GreenChannel) != 0) && (i <= av_len(av)))
12646 {
12647 q->green=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12648 i++;
12649 }
12650 if (((channel & BlueChannel) != 0) && (i <= av_len(av)))
12651 {
12652 q->blue=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12653 i++;
12654 }
12655 if ((((channel & IndexChannel) != 0) &&
12656 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
12657 {
12658 *indexes=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12659 i++;
12660 }
12661 if (((channel & OpacityChannel) != 0) && (i <= av_len(av)))
12662 {
12663 q->opacity=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12664 i++;
12665 }
12666 (void) SyncAuthenticPixels(image,exception);
12667 }
12668
12669 PerlException:
12670 InheritPerlException(exception,perl_exception);
12671 exception=DestroyExceptionInfo(exception);
12672 SvREFCNT_dec(perl_exception);
12673 }
12674
12675#
12676###############################################################################
12677# #
12678# #
12679# #
12680# S t a t i s t i c s #
12681# #
12682# #
12683# #
12684###############################################################################
12685#
12686#
12687void
12688Statistics(ref,...)
12689 Image::Magick ref=NO_INIT
12690 ALIAS:
12691 StatisticsImage = 1
12692 statistics = 2
12693 statisticsimage = 3
12694 PPCODE:
12695 {
12696 AV
12697 *av;
12698
12699 char
12700 message[MaxTextExtent];
12701
12702 ChannelStatistics
12703 *channel_statistics;
12704
12705 double
12706 scale;
12707
12708 ExceptionInfo
12709 *exception;
12710
12711 HV
12712 *hv;
12713
12714 Image
12715 *image;
12716
12717 ssize_t
12718 count;
12719
12720 struct PackageInfo
12721 *info;
12722
12723 SV
12724 *av_reference,
12725 *perl_exception,
12726 *reference;
12727
12728 exception=AcquireExceptionInfo();
12729 perl_exception=newSVpv("",0);
12730 av=NULL;
12731 if (sv_isobject(ST(0)) == 0)
12732 {
12733 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12734 PackageName);
12735 goto PerlException;
12736 }
12737 reference=SvRV(ST(0));
12738 hv=SvSTASH(reference);
12739 av=newAV();
12740 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12741 SvREFCNT_dec(av);
12742 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12743 if (image == (Image *) NULL)
12744 {
12745 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12746 PackageName);
12747 goto PerlException;
12748 }
12749 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12750 count=0;
12751 for ( ; image; image=image->next)
12752 {
12753 channel_statistics=GetImageChannelStatistics(image,&image->exception);
12754 if (channel_statistics == (ChannelStatistics *) NULL)
12755 continue;
12756 count++;
12757 EXTEND(sp,25*count);
12758 scale=(double) QuantumRange;
12759 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12760 channel_statistics[RedChannel].depth);
12761 PUSHs(sv_2mortal(newSVpv(message,0)));
12762 (void) FormatMagickString(message,MaxTextExtent,"%g",
12763 channel_statistics[RedChannel].minima/scale);
12764 PUSHs(sv_2mortal(newSVpv(message,0)));
12765 (void) FormatMagickString(message,MaxTextExtent,"%g",
12766 channel_statistics[RedChannel].maxima/scale);
12767 PUSHs(sv_2mortal(newSVpv(message,0)));
12768 (void) FormatMagickString(message,MaxTextExtent,"%g",
12769 channel_statistics[RedChannel].mean/scale);
12770 PUSHs(sv_2mortal(newSVpv(message,0)));
12771 (void) FormatMagickString(message,MaxTextExtent,"%g",
12772 channel_statistics[RedChannel].standard_deviation/scale);
12773 PUSHs(sv_2mortal(newSVpv(message,0)));
12774 (void) FormatMagickString(message,MaxTextExtent,"%g",
12775 channel_statistics[RedChannel].kurtosis);
12776 PUSHs(sv_2mortal(newSVpv(message,0)));
12777 (void) FormatMagickString(message,MaxTextExtent,"%g",
12778 channel_statistics[RedChannel].skewness);
12779 PUSHs(sv_2mortal(newSVpv(message,0)));
12780 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12781 channel_statistics[GreenChannel].depth);
12782 PUSHs(sv_2mortal(newSVpv(message,0)));
12783 (void) FormatMagickString(message,MaxTextExtent,"%g",
12784 channel_statistics[GreenChannel].minima/scale);
12785 PUSHs(sv_2mortal(newSVpv(message,0)));
12786 (void) FormatMagickString(message,MaxTextExtent,"%g",
12787 channel_statistics[GreenChannel].maxima/scale);
12788 PUSHs(sv_2mortal(newSVpv(message,0)));
12789 (void) FormatMagickString(message,MaxTextExtent,"%g",
12790 channel_statistics[GreenChannel].mean/scale);
12791 PUSHs(sv_2mortal(newSVpv(message,0)));
12792 (void) FormatMagickString(message,MaxTextExtent,"%g",
12793 channel_statistics[GreenChannel].standard_deviation/scale);
12794 PUSHs(sv_2mortal(newSVpv(message,0)));
12795 (void) FormatMagickString(message,MaxTextExtent,"%g",
12796 channel_statistics[GreenChannel].kurtosis);
12797 PUSHs(sv_2mortal(newSVpv(message,0)));
12798 (void) FormatMagickString(message,MaxTextExtent,"%g",
12799 channel_statistics[GreenChannel].skewness);
12800 PUSHs(sv_2mortal(newSVpv(message,0)));
12801 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12802 channel_statistics[BlueChannel].depth);
12803 PUSHs(sv_2mortal(newSVpv(message,0)));
12804 (void) FormatMagickString(message,MaxTextExtent,"%g",
12805 channel_statistics[BlueChannel].minima/scale);
12806 PUSHs(sv_2mortal(newSVpv(message,0)));
12807 (void) FormatMagickString(message,MaxTextExtent,"%g",
12808 channel_statistics[BlueChannel].maxima/scale);
12809 PUSHs(sv_2mortal(newSVpv(message,0)));
12810 (void) FormatMagickString(message,MaxTextExtent,"%g",
12811 channel_statistics[BlueChannel].mean/scale);
12812 PUSHs(sv_2mortal(newSVpv(message,0)));
12813 (void) FormatMagickString(message,MaxTextExtent,"%g",
12814 channel_statistics[BlueChannel].standard_deviation/scale);
12815 PUSHs(sv_2mortal(newSVpv(message,0)));
12816 (void) FormatMagickString(message,MaxTextExtent,"%g",
12817 channel_statistics[BlueChannel].kurtosis);
12818 PUSHs(sv_2mortal(newSVpv(message,0)));
12819 (void) FormatMagickString(message,MaxTextExtent,"%g",
12820 channel_statistics[BlueChannel].skewness);
12821 PUSHs(sv_2mortal(newSVpv(message,0)));
12822 if (image->colorspace == CMYKColorspace)
12823 {
12824 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12825 channel_statistics[BlackChannel].depth);
12826 PUSHs(sv_2mortal(newSVpv(message,0)));
12827 (void) FormatMagickString(message,MaxTextExtent,"%g",
12828 channel_statistics[BlackChannel].minima/scale);
12829 PUSHs(sv_2mortal(newSVpv(message,0)));
12830 (void) FormatMagickString(message,MaxTextExtent,"%g",
12831 channel_statistics[BlackChannel].maxima/scale);
12832 PUSHs(sv_2mortal(newSVpv(message,0)));
12833 (void) FormatMagickString(message,MaxTextExtent,"%g",
12834 channel_statistics[BlackChannel].mean/scale);
12835 PUSHs(sv_2mortal(newSVpv(message,0)));
12836 (void) FormatMagickString(message,MaxTextExtent,"%g",
12837 channel_statistics[BlackChannel].standard_deviation/scale);
12838 PUSHs(sv_2mortal(newSVpv(message,0)));
12839 (void) FormatMagickString(message,MaxTextExtent,"%g",
12840 channel_statistics[BlackChannel].kurtosis);
12841 PUSHs(sv_2mortal(newSVpv(message,0)));
12842 (void) FormatMagickString(message,MaxTextExtent,"%g",
12843 channel_statistics[BlackChannel].skewness);
12844 PUSHs(sv_2mortal(newSVpv(message,0)));
12845 }
12846 if (image->matte != MagickFalse)
12847 {
12848 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12849 channel_statistics[OpacityChannel].depth);
12850 PUSHs(sv_2mortal(newSVpv(message,0)));
12851 (void) FormatMagickString(message,MaxTextExtent,"%g",
12852 channel_statistics[OpacityChannel].minima/scale);
12853 PUSHs(sv_2mortal(newSVpv(message,0)));
12854 (void) FormatMagickString(message,MaxTextExtent,"%g",
12855 channel_statistics[OpacityChannel].maxima/scale);
12856 PUSHs(sv_2mortal(newSVpv(message,0)));
12857 (void) FormatMagickString(message,MaxTextExtent,"%g",
12858 channel_statistics[OpacityChannel].mean/scale);
12859 PUSHs(sv_2mortal(newSVpv(message,0)));
12860 (void) FormatMagickString(message,MaxTextExtent,"%g",
12861 channel_statistics[OpacityChannel].standard_deviation/scale);
12862 PUSHs(sv_2mortal(newSVpv(message,0)));
12863 (void) FormatMagickString(message,MaxTextExtent,"%g",
12864 channel_statistics[OpacityChannel].kurtosis);
12865 PUSHs(sv_2mortal(newSVpv(message,0)));
12866 (void) FormatMagickString(message,MaxTextExtent,"%g",
12867 channel_statistics[OpacityChannel].skewness);
12868 PUSHs(sv_2mortal(newSVpv(message,0)));
12869 }
12870 channel_statistics=(ChannelStatistics *)
12871 RelinquishMagickMemory(channel_statistics);
12872 }
12873
12874 PerlException:
12875 InheritPerlException(exception,perl_exception);
12876 exception=DestroyExceptionInfo(exception);
12877 SvREFCNT_dec(perl_exception);
12878 }
12879
12880#
12881###############################################################################
12882# #
12883# #
12884# #
12885# S y n c A u t h e n t i c P i x e l s #
12886# #
12887# #
12888# #
12889###############################################################################
12890#
12891#
12892void
12893SyncAuthenticPixels(ref,...)
12894 Image::Magick ref = NO_INIT
12895 ALIAS:
12896 Syncauthenticpixels = 1
12897 SyncImagePixels = 2
12898 syncimagepixels = 3
12899 CODE:
12900 {
12901 ExceptionInfo
12902 *exception;
12903
12904 Image
12905 *image;
12906
12907 MagickBooleanType
12908 status;
12909
12910 struct PackageInfo
12911 *info;
12912
12913 SV
12914 *perl_exception,
12915 *reference;
12916
12917 exception=AcquireExceptionInfo();
12918 perl_exception=newSVpv("",0);
12919
12920 if (sv_isobject(ST(0)) == 0)
12921 {
12922 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12923 PackageName);
12924 goto PerlException;
12925 }
12926
12927 reference=SvRV(ST(0));
12928 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12929 if (image == (Image *) NULL)
12930 {
12931 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12932 PackageName);
12933 goto PerlException;
12934 }
12935
12936 status=SyncAuthenticPixels(image,exception);
12937 if (status != MagickFalse)
12938 return;
12939 InheritException(exception,&image->exception);
12940
12941 PerlException:
12942 InheritPerlException(exception,perl_exception);
12943 exception=DestroyExceptionInfo(exception);
12944 SvREFCNT_dec(perl_exception); /* throw away all errors */
12945 }
12946
12947#
12948###############################################################################
12949# #
12950# #
12951# #
12952# T r a n s f o r m #
12953# #
12954# #
12955# #
12956###############################################################################
12957#
12958#
12959void
12960Transform(ref,...)
12961 Image::Magick ref=NO_INIT
12962 ALIAS:
12963 TransformImage = 1
12964 transform = 2
12965 transformimage = 3
12966 PPCODE:
12967 {
12968 AV
12969 *av;
12970
12971 char
12972 *attribute,
12973 *crop_geometry,
12974 *geometry;
12975
12976 ExceptionInfo
12977 *exception;
12978
12979 HV
12980 *hv;
12981
12982 Image
12983 *clone,
12984 *image;
12985
12986 register long
12987 i;
12988
12989 struct PackageInfo
12990 *info;
12991
12992 SV
12993 *av_reference,
12994 *perl_exception,
12995 *reference,
12996 *rv,
12997 *sv;
12998
12999 exception=AcquireExceptionInfo();
13000 perl_exception=newSVpv("",0);
13001 av=NULL;
13002 attribute=NULL;
13003 if (sv_isobject(ST(0)) == 0)
13004 {
13005 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13006 PackageName);
13007 goto PerlException;
13008 }
13009 reference=SvRV(ST(0));
13010 hv=SvSTASH(reference);
13011 av=newAV();
13012 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
13013 SvREFCNT_dec(av);
13014 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13015 if (image == (Image *) NULL)
13016 {
13017 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13018 PackageName);
13019 goto PerlException;
13020 }
13021 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
13022 /*
13023 Get attribute.
13024 */
13025 crop_geometry=(char *) NULL;
13026 geometry=(char *) NULL;
13027 for (i=2; i < items; i+=2)
13028 {
13029 attribute=(char *) SvPV(ST(i-1),na);
13030 switch (*attribute)
13031 {
13032 case 'c':
13033 case 'C':
13034 {
13035 if (LocaleCompare(attribute,"crop") == 0)
13036 {
13037 crop_geometry=SvPV(ST(i),na);
13038 break;
13039 }
13040 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13041 attribute);
13042 break;
13043 }
13044 case 'g':
13045 case 'G':
13046 {
13047 if (LocaleCompare(attribute,"geometry") == 0)
13048 {
13049 geometry=SvPV(ST(i),na);
13050 break;
13051 }
13052 if (LocaleCompare(attribute,"gravity") == 0)
13053 {
13054 Image
13055 *next;
13056
13057 long
13058 in;
13059
13060 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
13061 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13062 if (in < 0)
13063 {
13064 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13065 SvPV(ST(i),na));
13066 return;
13067 }
13068 for (next=image; next; next=next->next)
13069 next->gravity=(GravityType) in;
13070 break;
13071 }
13072 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13073 attribute);
13074 break;
13075 }
13076 default:
13077 {
13078 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13079 attribute);
13080 break;
13081 }
13082 }
13083 }
13084 for ( ; image; image=image->next)
13085 {
13086 clone=CloneImage(image,0,0,MagickTrue,exception);
13087 if ((clone == (Image *) NULL) || (exception->severity >= ErrorException))
13088 goto PerlException;
13089 TransformImage(&clone,crop_geometry,geometry);
13090 for ( ; clone; clone=clone->next)
13091 {
13092 AddImageToRegistry(clone);
13093 rv=newRV(sv);
13094 av_push(av,sv_bless(rv,hv));
13095 SvREFCNT_dec(sv);
13096 }
13097 }
13098 exception=DestroyExceptionInfo(exception);
13099 ST(0)=av_reference;
13100 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13101 XSRETURN(1);
13102
13103 PerlException:
13104 InheritPerlException(exception,perl_exception);
13105 exception=DestroyExceptionInfo(exception);
13106 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
13107 SvPOK_on(perl_exception);
13108 ST(0)=sv_2mortal(perl_exception);
13109 XSRETURN(1);
13110 }
13111
13112#
13113###############################################################################
13114# #
13115# #
13116# #
13117# W r i t e #
13118# #
13119# #
13120# #
13121###############################################################################
13122#
13123#
13124void
13125Write(ref,...)
13126 Image::Magick ref=NO_INIT
13127 ALIAS:
13128 WriteImage = 1
13129 write = 2
13130 writeimage = 3
13131 PPCODE:
13132 {
13133 char
13134 filename[MaxTextExtent];
13135
13136 ExceptionInfo
13137 *exception;
13138
13139 Image
13140 *image,
13141 *next;
13142
13143 long
13144 number_images,
13145 scene;
13146
13147 register long
13148 i;
13149
13150 struct PackageInfo
13151 *info,
13152 *package_info;
13153
13154 SV
13155 *perl_exception,
13156 *reference;
13157
13158 exception=AcquireExceptionInfo();
13159 perl_exception=newSVpv("",0);
13160 number_images=0;
13161 package_info=(struct PackageInfo *) NULL;
13162 if (sv_isobject(ST(0)) == 0)
13163 {
13164 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13165 PackageName);
13166 goto PerlException;
13167 }
13168 reference=SvRV(ST(0));
13169 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13170 if (image == (Image *) NULL)
13171 {
13172 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13173 PackageName);
13174 goto PerlException;
13175 }
13176 package_info=ClonePackageInfo(info,exception);
13177 if (items == 2)
13178 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
13179 else
13180 if (items > 2)
13181 for (i=2; i < items; i+=2)
13182 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
13183 exception);
13184 (void) CopyMagickString(filename,package_info->image_info->filename,
13185 MaxTextExtent);
13186 scene=0;
13187 for (next=image; next; next=next->next)
13188 {
13189 (void) CopyMagickString(next->filename,filename,MaxTextExtent);
13190 next->scene=scene++;
13191 }
13192 SetImageInfo(package_info->image_info,MagickTrue,&image->exception);
13193 for (next=image; next; next=next->next)
13194 {
13195 (void) WriteImage(package_info->image_info,next);
13196 if (next->exception.severity >= ErrorException)
13197 InheritException(exception,&next->exception);
13198 GetImageException(next,exception);
13199 number_images++;
13200 if (package_info->image_info->adjoin)
13201 break;
13202 }
13203
13204 PerlException:
13205 if (package_info != (struct PackageInfo *) NULL)
13206 DestroyPackageInfo(package_info);
13207 InheritPerlException(exception,perl_exception);
13208 exception=DestroyExceptionInfo(exception);
13209 sv_setiv(perl_exception,(IV) number_images);
13210 SvPOK_on(perl_exception);
13211 ST(0)=sv_2mortal(perl_exception);
13212 XSRETURN(1);
13213 }