blob: 5761f4664f746ba56e48771d0ddba7a9ee10d2e7 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% PPPP EEEEE RRRR L %
6% P P E R R L %
7% PPPP EEE RRRR L %
8% P E R R L %
9% P EEEEE R R LLLLL %
10% %
11% M M AAA GGGG IIIII CCCC K K %
12% MM MM A A G I C K K %
13% M M M AAAAA G GGG I C KKK %
14% M M A A G G I C K K %
15% M M A A GGGG IIIII CCCC K K %
16% %
17% %
18% Object-oriented Perl interface to ImageMagick %
19% %
20% Software Design %
21% Kyle Shorter %
22% John Cristy %
23% February 1997 %
24% %
25% %
26% Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization %
27% dedicated to making software imaging solutions freely available. %
28% %
29% You may not use this file except in compliance with the License. You may %
30% obtain a copy of the License at %
31% %
32% http://www.imagemagick.org/script/license.php %
33% %
34% Unless required by applicable law or agreed to in writing, software %
35% distributed under the License is distributed on an "AS IS" BASIS, %
36% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
37% See the License for the specific language governing permissions and %
38% limitations under the License. %
39% %
40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41%
42% PerlMagick is an objected-oriented Perl interface to ImageMagick. Use
43% the module to read, manipulate, or write an image or image sequence from
44% within a Perl script. This makes PerlMagick suitable for Web CGI scripts.
45%
46*/
47
48/*
49 Include declarations.
50*/
51#if !defined(WIN32)
52#define MagickExport
53#endif
54
55#if defined(__cplusplus) || defined(c_plusplus)
56extern "C" {
57#endif
58
59#define PERL_NO_GET_CONTEXT
60#include "EXTERN.h"
61#include "perl.h"
62#include "XSUB.h"
63#include <math.h>
64#include <magick/MagickCore.h>
65#undef tainted
66
67#if defined(__cplusplus) || defined(c_plusplus)
68}
69#endif
70
71/*
72 Define declarations.
73*/
74#ifndef aTHX_
75#define aTHX_
76#define pTHX_
77#define dTHX
78#endif
79#define DegreesToRadians(x) (MagickPI*(x)/180.0)
80#define EndOf(array) (&array[NumberOf(array)])
81#define MagickPI 3.14159265358979323846264338327950288419716939937510
cristyd4160cf2009-09-07 21:51:25 +000082#define MaxArguments 32
cristy3ed852e2009-09-05 21:47:34 +000083#ifndef na
84#define na PL_na
85#endif
86#define NumberOf(array) (sizeof(array)/sizeof(*array))
87#define PackageName "Image::Magick"
88#if PERL_VERSION <= 6
89#define PerlIO FILE
90#define PerlIO_importFILE(f, fl) (f)
91#define PerlIO_findFILE(f) NULL
92#endif
93#define RoundToQuantum(value) ((Quantum) ((value) < 0.0 ? 0.0 : \
94 ((value) > (MagickRealType) QuantumRange) ? (MagickRealType) \
95 QuantumRange : (value)+0.5))
96#ifndef sv_undef
97#define sv_undef PL_sv_undef
98#endif
99
100#define AddImageToRegistry(image) \
101{ \
102 if (magick_registry != (SplayTreeInfo *) NULL) \
103 { \
104 (void) AddValueToSplayTree(magick_registry,image,image); \
105 sv=newSViv((IV) image); \
106 } \
107}
108
109#define DeleteImageFromRegistry(reference,image) \
110{ \
111 if (magick_registry != (SplayTreeInfo *) NULL) \
112 { \
113 if (GetImageReferenceCount(image) == 1) \
114 (void) DeleteNodeByValueFromSplayTree(magick_registry,image); \
115 image=DestroyImage(image); \
116 sv_setiv(reference,0); \
117 } \
118}
119
120#define InheritPerlException(exception,perl_exception) \
121{ \
122 char \
123 message[MaxTextExtent]; \
124 \
125 if ((exception)->severity != UndefinedException) \
126 { \
127 (void) FormatMagickString(message,MaxTextExtent,"Exception %d: %s%s%s%s",\
128 (exception)->severity, (exception)->reason ? \
129 GetLocaleExceptionMessage((exception)->severity,(exception)->reason) : \
130 "Unknown", (exception)->description ? " (" : "", \
131 (exception)->description ? GetLocaleExceptionMessage( \
132 (exception)->severity,(exception)->description) : "", \
133 (exception)->description ? ")" : ""); \
134 if ((perl_exception) != (SV *) NULL) \
135 { \
136 if (SvCUR(perl_exception)) \
137 sv_catpv(perl_exception,"\n"); \
138 sv_catpv(perl_exception,message); \
139 } \
140 } \
141}
142
143#define ThrowPerlException(exception,severity,tag,reason) \
144 (void) ThrowMagickException(exception,GetMagickModule(),severity, \
145 tag,"`%s'",reason); \
146
147/*
148 Typedef and structure declarations.
149*/
150typedef enum
151{
152 ArrayReference = (~0),
153 RealReference = (~0)-1,
154 FileReference = (~0)-2,
155 ImageReference = (~0)-3,
156 IntegerReference = (~0)-4,
157 StringReference = (~0)-5
158} MagickReference;
159
160typedef struct _Arguments
161{
162 const char
163 *method;
164
165 long
166 type;
167} Arguments;
168
169struct ArgumentList
170{
171 long
172 long_reference;
173
174 MagickRealType
175 real_reference;
176
177 const char
178 *string_reference;
179
180 Image
181 *image_reference;
182
183 SV
184 *array_reference;
185
186 FILE
187 *file_reference;
188
189 size_t
190 length;
191};
192
193struct PackageInfo
194{
195 ImageInfo
196 *image_info;
197};
198
199typedef void
200 *Image__Magick; /* data type for the Image::Magick package */
201
202/*
203 Static declarations.
204*/
205static struct
206 Methods
207 {
208 const char
209 *name;
210
211 Arguments
212 arguments[MaxArguments];
213 } Methods[] =
214 {
215 { "Comment", { {"comment", StringReference} } },
216 { "Label", { {"label", StringReference} } },
217 { "AddNoise", { {"noise", MagickNoiseOptions},
218 {"channel", MagickChannelOptions} } },
219 { "Colorize", { {"fill", StringReference}, {"opacity", StringReference} } },
220 { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
221 {"height", IntegerReference}, {"fill", StringReference},
222 {"bordercolor", StringReference}, {"color", StringReference},
223 {"compose", MagickComposeOptions} } },
224 { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
225 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
226 { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
227 {"height", IntegerReference}, {"x", IntegerReference},
228 {"y", IntegerReference} } },
229 { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
230 {"height", IntegerReference}, {"x", IntegerReference},
231 {"y", IntegerReference}, {"fuzz", StringReference} } },
232 { "Despeckle", },
233 { "Edge", { {"radius", RealReference} } },
234 { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
235 {"sigma", RealReference} } },
236 { "Enhance", },
237 { "Flip", },
238 { "Flop", },
239 { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
240 {"height", IntegerReference}, {"inner", IntegerReference},
241 {"outer", IntegerReference}, {"fill", StringReference},
242 {"color", StringReference}, {"compose", MagickComposeOptions} } },
243 { "Implode", { {"amount", RealReference},
244 {"interpolate", MagickInterpolateOptions} } },
245 { "Magnify", },
246 { "MedianFilter", { {"radius", RealReference} } },
247 { "Minify", },
248 { "OilPaint", { {"radius", RealReference} } },
249 { "ReduceNoise", { {"radius", RealReference} } },
250 { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
251 {"y", IntegerReference} } },
252 { "Rotate", { {"degrees", RealReference}, {"fill", StringReference},
253 {"color", StringReference}, {"background", StringReference} } },
254 { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
255 {"height", IntegerReference} } },
256 { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
257 {"height", IntegerReference} } },
258 { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
259 {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
260 { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
261 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
262 { "Shear", { {"geometry", StringReference}, {"x", RealReference},
263 {"y", RealReference}, { "fill", StringReference},
264 {"color", StringReference} } },
265 { "Spread", { {"radius", RealReference} } },
266 { "Swirl", { {"degrees", RealReference},
267 {"interpolate", MagickInterpolateOptions} } },
268 { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
269 {"height", IntegerReference}, {"filter", MagickFilterOptions},
270 {"support", StringReference }, {"blur", RealReference } } },
271 { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
272 {"height", IntegerReference}, {"filter", MagickFilterOptions},
273 {"support", RealReference }, {"blur", RealReference } } },
274 { "Annotate", { {"text", StringReference}, {"font", StringReference},
275 {"pointsize", RealReference}, {"density", StringReference},
276 {"undercolor", StringReference}, {"stroke", StringReference},
277 {"fill", StringReference}, {"geometry", StringReference},
278 {"pen", StringReference}, {"x", RealReference},
279 {"y", RealReference}, {"gravity", MagickGravityOptions},
280 {"translate", StringReference}, {"scale", StringReference},
281 {"rotate", RealReference}, {"skewX", RealReference},
282 {"skewY", RealReference}, {"strokewidth", RealReference},
283 {"antialias", MagickBooleanOptions}, {"family", StringReference},
284 {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
285 {"weight", IntegerReference}, {"align", MagickAlignOptions},
286 {"encoding", StringReference}, {"affine", ArrayReference},
287 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
288 {"tile", ImageReference}, {"kerning", RealReference},
cristyb32b90a2009-09-07 21:45:48 +0000289 {"interline-spacing", RealReference},
cristy3ed852e2009-09-05 21:47:34 +0000290 {"interword-spacing", RealReference} } },
291 { "ColorFloodfill", { {"geometry", StringReference},
292 {"x", IntegerReference}, {"y", IntegerReference},
293 {"fill", StringReference}, {"bordercolor", StringReference},
294 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
295 { "Composite", { {"image", ImageReference},
296 {"compose", MagickComposeOptions}, {"geometry", StringReference},
297 {"x", IntegerReference}, {"y", IntegerReference},
298 {"gravity", MagickGravityOptions}, {"opacity", StringReference},
299 {"tile", MagickBooleanOptions}, {"rotate", RealReference},
300 {"color", StringReference}, {"mask", ImageReference},
301 {"channel", MagickChannelOptions},
302 {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
303 {"blend", StringReference} } },
304 { "Contrast", { {"sharpen", MagickBooleanOptions} } },
305 { "CycleColormap", { {"display", IntegerReference} } },
306 { "Draw", { {"primitive", MagickPrimitiveOptions},
307 {"points", StringReference}, {"method", MagickMethodOptions},
308 {"stroke", StringReference}, {"fill", StringReference},
309 {"strokewidth", RealReference}, {"font", StringReference},
310 {"bordercolor", StringReference}, {"x", RealReference},
311 {"y", RealReference}, {"translate", StringReference},
312 {"scale", StringReference}, {"rotate", RealReference},
313 {"skewX", RealReference}, {"skewY", RealReference},
314 {"tile", ImageReference}, {"pointsize", RealReference},
315 {"antialias", MagickBooleanOptions}, {"density", StringReference},
316 {"linewidth", RealReference}, {"affine", ArrayReference},
317 {"stroke-dashoffset", RealReference},
318 {"stroke-dasharray", ArrayReference},
319 {"interpolate", MagickInterpolateOptions},
320 {"origin", StringReference}, {"text", StringReference},
321 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
322 {"vector-graphics", StringReference}, {"kerning", RealReference},
cristyb32b90a2009-09-07 21:45:48 +0000323 {"interline-spacing", RealReference},
cristy3ed852e2009-09-05 21:47:34 +0000324 {"interword-spacing", RealReference} } },
325 { "Equalize", { {"channel", MagickChannelOptions} } },
326 { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
327 {"red", RealReference}, {"green", RealReference},
328 {"blue", RealReference} } },
329 { "Map", { {"image", ImageReference}, {"dither", MagickBooleanOptions} } },
330 { "MatteFloodfill", { {"geometry", StringReference},
331 {"x", IntegerReference}, {"y", IntegerReference},
332 {"opacity", StringReference}, {"bordercolor", StringReference},
333 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
334 { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
335 {"saturation", RealReference}, {"whiteness", RealReference},
336 {"brightness", RealReference}, {"luminosity", RealReference},
337 {"blackness", RealReference} } },
338 { "Negate", { {"gray", MagickBooleanOptions},
339 {"channel", MagickChannelOptions} } },
340 { "Normalize", { {"channel", MagickChannelOptions} } },
341 { "NumberColors", },
342 { "Opaque", { {"color", StringReference}, {"fill", StringReference},
343 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
344 {"invert", MagickBooleanOptions} } },
345 { "Quantize", { {"colors", IntegerReference},
346 {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
347 {"dither", MagickBooleanOptions}, {"measure", MagickBooleanOptions},
348 {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
349 {"dither-method", MagickDitherOptions} } },
350 { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
351 {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
352 { "Segment", { {"geometry", StringReference},
353 {"cluster-threshold", RealReference},
354 {"smoothing-threshold", RealReference},
355 {"colorspace", MagickColorspaceOptions},
356 {"verbose", MagickBooleanOptions} } },
357 { "Signature", },
358 { "Solarize", { {"geometry", StringReference},
359 {"threshold", StringReference} } },
360 { "Sync", },
361 { "Texture", { {"texture", ImageReference} } },
362 { "Evaluate", { {"value", RealReference},
363 {"operator", MagickEvaluateOptions},
364 {"channel", MagickChannelOptions} } },
365 { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
366 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
367 { "Threshold", { {"threshold", StringReference},
368 {"channel", MagickChannelOptions} } },
369 { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
370 {"sigma", RealReference} } },
371 { "Trim", { {"fuzz", StringReference} } },
372 { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
373 {"wavelength", RealReference},
374 {"interpolate", MagickInterpolateOptions} } },
375 { "Separate", { {"channel", MagickChannelOptions} } },
376 { "Condense", },
377 { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
378 {"y", IntegerReference} } },
379 { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
380 { "Deconstruct", },
381 { "GaussianBlur", { {"geometry", StringReference},
382 {"radius", RealReference}, {"sigma", RealReference},
383 {"channel", MagickChannelOptions} } },
384 { "Convolve", { {"coefficients", ArrayReference},
385 {"channel", MagickChannelOptions}, {"bias", StringReference} } },
386 { "Profile", { {"name", StringReference}, {"profile", StringReference},
387 { "rendering-intent", MagickIntentOptions},
388 { "black-point-compensation", MagickBooleanOptions} } },
389 { "UnsharpMask", { {"geometry", StringReference},
390 {"radius", RealReference}, {"sigma", RealReference},
391 {"amount", RealReference}, {"threshold", RealReference},
392 {"channel", MagickChannelOptions} } },
393 { "MotionBlur", { {"geometry", StringReference},
394 {"radius", RealReference}, {"sigma", RealReference},
395 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
396 { "OrderedDither", { {"threshold", StringReference},
397 {"channel", MagickChannelOptions} } },
398 { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
399 {"height", IntegerReference} } },
400 { "Level", { {"levels", StringReference}, {"black-point", RealReference},
401 {"white-point", RealReference}, {"gamma", RealReference},
402 {"channel", MagickChannelOptions}, {"level", StringReference} } },
403 { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
404 { "AffineTransform", { {"affine", ArrayReference},
405 {"translate", StringReference}, {"scale", StringReference},
406 {"rotate", RealReference}, {"skewX", RealReference},
407 {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
408 {"background", StringReference} } },
409 { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
410 { "AdaptiveThreshold", { {"geometry", StringReference},
411 {"width", IntegerReference}, {"height", IntegerReference},
412 {"offset", IntegerReference} } },
413 { "Resample", { {"density", StringReference}, {"x", RealReference},
414 {"y", RealReference}, {"filter", MagickFilterOptions},
415 {"support", RealReference }, {"blur", RealReference } } },
416 { "Describe", { {"file", FileReference} } },
417 { "BlackThreshold", { {"threshold", StringReference},
418 {"channel", MagickChannelOptions} } },
419 { "WhiteThreshold", { {"threshold", StringReference},
420 {"channel", MagickChannelOptions} } },
421 { "RadialBlur", { {"geometry", StringReference}, {"angle", RealReference},
422 {"channel", MagickChannelOptions} } },
423 { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
424 {"height", IntegerReference} } },
425 { "Strip", },
426 { "Tint", { {"fill", StringReference}, {"opacity", StringReference} } },
427 { "Channel", { {"channel", MagickChannelOptions} } },
428 { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
429 {"height", IntegerReference}, {"x", IntegerReference},
430 {"y", IntegerReference}, {"fuzz", StringReference},
431 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
432 { "Posterize", { {"levels", IntegerReference},
433 {"dither", MagickBooleanOptions} } },
434 { "Shadow", { {"geometry", StringReference}, {"opacity", RealReference},
435 {"sigma", RealReference}, {"x", IntegerReference},
436 {"y", IntegerReference} } },
437 { "Identify", { {"file", FileReference} } },
438 { "SepiaTone", { {"threshold", RealReference} } },
439 { "SigmoidalContrast", { {"geometry", StringReference},
440 {"contrast", RealReference}, {"mid-point", RealReference},
441 {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
442 { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
443 {"height", IntegerReference}, {"x", IntegerReference},
444 {"y", IntegerReference}, {"fuzz", StringReference},
445 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
446 { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
447 {"sigma", RealReference}, {"x", IntegerReference},
448 {"y", IntegerReference}, {"background", StringReference} } },
449 { "ContrastStretch", { {"levels", StringReference},
450 {"black-point", RealReference},{"white-point", RealReference},
451 {"channel", MagickChannelOptions} } },
452 { "Sans0", },
453 { "Sans1", },
454 { "AdaptiveSharpen", { {"geometry", StringReference},
455 {"radius", RealReference}, {"sigma", RealReference},
456 {"channel", MagickChannelOptions} } },
457 { "Transpose", },
458 { "Transverse", },
459 { "AutoOrient", },
460 { "AdaptiveBlur", { {"geometry", StringReference},
461 {"radius", RealReference}, {"sigma", RealReference},
462 {"channel", MagickChannelOptions} } },
463 { "Sketch", { {"geometry", StringReference},
464 {"radius", RealReference}, {"sigma", RealReference},
465 {"angle", RealReference} } },
466 { "UniqueColors", },
467 { "AdaptiveResize", { {"geometry", StringReference},
468 {"width", IntegerReference}, {"height", IntegerReference},
469 {"filter", MagickFilterOptions}, {"support", StringReference },
470 {"blur", RealReference } } },
471 { "ClipMask", { {"mask", ImageReference} } },
472 { "LinearStretch", { {"levels", StringReference},
473 {"black-point", RealReference},{"white-point", RealReference} } },
474 { "Recolor", { {"matrix", ArrayReference} } },
475 { "Mask", { {"mask", ImageReference} } },
476 { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
477 {"font", StringReference}, {"stroke", StringReference},
478 {"fill", StringReference}, {"strokewidth", RealReference},
479 {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
480 {"background", StringReference} } },
481 { "FloodfillPaint", { {"geometry", StringReference},
482 {"x", IntegerReference}, {"y", IntegerReference},
483 {"fill", StringReference}, {"bordercolor", StringReference},
484 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
485 {"invert", MagickBooleanOptions} } },
486 { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
487 {"virtual-pixel", MagickVirtualPixelOptions},
488 {"best-fit", MagickBooleanOptions} } },
489 { "Clut", { {"image", ImageReference},
490 {"channel", MagickChannelOptions} } },
491 { "LiquidRescale", { {"geometry", StringReference},
492 {"width", IntegerReference}, {"height", IntegerReference},
493 {"delta-x", RealReference}, {"rigidity", RealReference } } },
494 { "Encipher", { {"passphrase", StringReference} } },
495 { "Decipher", { {"passphrase", StringReference} } },
496 { "Deskew", { {"geometry", StringReference},
497 {"threshold", StringReference} } },
498 { "Remap", { {"image", ImageReference},
499 {"dither-method", MagickDitherOptions} } },
500 { "SparseColor", { {"points", ArrayReference},
501 {"method", MagickSparseColorOptions},
502 {"virtual-pixel", MagickVirtualPixelOptions},
503 {"channel", MagickChannelOptions} } },
504 { "Function", { {"parameters", ArrayReference},
505 {"function", MagickFunctionOptions},
506 {"virtual-pixel", MagickVirtualPixelOptions} } },
507 { "SelectiveBlur", { {"geometry", StringReference},
508 {"radius", RealReference}, {"sigma", RealReference},
509 {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
510 { "HaldClut", { {"image", ImageReference},
511 {"channel", MagickChannelOptions} } },
512 { "BlueShift", {"factor", StringReference} },
513 { "ForwardFourierTransform", {"magnitude", MagickBooleanOptions} },
514 { "InverseFourierTransform", {"magnitude", MagickBooleanOptions} },
515 { "ColorDecisionList", {
516 {"color-correction-collection", StringReference} } },
517 { "AutoGamma", { {"channel", MagickChannelOptions} } },
518 { "AutoLevel", { {"channel", MagickChannelOptions} } },
cristyee0f8d72009-09-19 00:58:29 +0000519 { "LevelColors", { {"invert", MagickBooleanOptions},
520 {"black-point", RealReference}, {"white-point", RealReference},
521 {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
cristy1eb45dd2009-09-25 16:38:06 +0000522 { "Clamp", { {"channel", MagickChannelOptions} } },
cristy3ed852e2009-09-05 21:47:34 +0000523 };
524
525static SplayTreeInfo
526 *magick_registry = (SplayTreeInfo *) NULL;
527
528/*
529 Forward declarations.
530*/
531static Image
532 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
533
534static long
535 strEQcase(const char *,const char *);
536
537/*
538%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
539% %
540% %
541% %
542% C l o n e P a c k a g e I n f o %
543% %
544% %
545% %
546%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
547%
548% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
549% a new one.
550%
551% The format of the ClonePackageInfo routine is:
552%
553% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
554% exception)
555%
556% A description of each parameter follows:
557%
558% o info: a structure of type info.
559%
560% o exception: Return any errors or warnings in this structure.
561%
562*/
563static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
564 ExceptionInfo *exception)
565{
566 struct PackageInfo
567 *clone_info;
568
569 clone_info=(struct PackageInfo *) AcquireMagickMemory(sizeof(*clone_info));
570 if (clone_info == (struct PackageInfo *) NULL)
571 {
572 ThrowPerlException(exception,ResourceLimitError,
573 "UnableToClonePackageInfo",PackageName);
574 return((struct PackageInfo *) NULL);
575 }
576 if (info == (struct PackageInfo *) NULL)
577 {
578 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
579 return(clone_info);
580 }
581 *clone_info=(*info);
582 clone_info->image_info=CloneImageInfo(info->image_info);
583 return(clone_info);
584}
585
586/*
587%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
588% %
589% %
590% %
591% c o n s t a n t %
592% %
593% %
594% %
595%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
596%
597% constant() returns a double value for the specified name.
598%
599% The format of the constant routine is:
600%
601% double constant(char *name,long sans)
602%
603% A description of each parameter follows:
604%
605% o value: Method constant returns a double value for the specified name.
606%
607% o name: The name of the constant.
608%
609% o sans: This integer value is not used.
610%
611*/
612static double constant(char *name,long sans)
613{
614 (void) sans;
615 errno=0;
616 switch (*name)
617 {
618 case 'B':
619 {
620 if (strEQ(name,"BlobError"))
621 return(BlobError);
622 if (strEQ(name,"BlobWarning"))
623 return(BlobWarning);
624 break;
625 }
626 case 'C':
627 {
628 if (strEQ(name,"CacheError"))
629 return(CacheError);
630 if (strEQ(name,"CacheWarning"))
631 return(CacheWarning);
632 if (strEQ(name,"CoderError"))
633 return(CoderError);
634 if (strEQ(name,"CoderWarning"))
635 return(CoderWarning);
636 if (strEQ(name,"ConfigureError"))
637 return(ConfigureError);
638 if (strEQ(name,"ConfigureWarning"))
639 return(ConfigureWarning);
640 if (strEQ(name,"CorruptImageError"))
641 return(CorruptImageError);
642 if (strEQ(name,"CorruptImageWarning"))
643 return(CorruptImageWarning);
644 break;
645 }
646 case 'D':
647 {
648 if (strEQ(name,"DelegateError"))
649 return(DelegateError);
650 if (strEQ(name,"DelegateWarning"))
651 return(DelegateWarning);
652 if (strEQ(name,"DrawError"))
653 return(DrawError);
654 if (strEQ(name,"DrawWarning"))
655 return(DrawWarning);
656 break;
657 }
658 case 'E':
659 {
660 if (strEQ(name,"ErrorException"))
661 return(ErrorException);
662 if (strEQ(name,"ExceptionError"))
663 return(CoderError);
664 if (strEQ(name,"ExceptionWarning"))
665 return(CoderWarning);
666 break;
667 }
668 case 'F':
669 {
670 if (strEQ(name,"FatalErrorException"))
671 return(FatalErrorException);
672 if (strEQ(name,"FileOpenError"))
673 return(FileOpenError);
674 if (strEQ(name,"FileOpenWarning"))
675 return(FileOpenWarning);
676 break;
677 }
678 case 'I':
679 {
680 if (strEQ(name,"ImageError"))
681 return(ImageError);
682 if (strEQ(name,"ImageWarning"))
683 return(ImageWarning);
684 break;
685 }
686 case 'M':
687 {
688 if (strEQ(name,"MaxRGB"))
689 return(QuantumRange);
690 if (strEQ(name,"MissingDelegateError"))
691 return(MissingDelegateError);
692 if (strEQ(name,"MissingDelegateWarning"))
693 return(MissingDelegateWarning);
694 if (strEQ(name,"ModuleError"))
695 return(ModuleError);
696 if (strEQ(name,"ModuleWarning"))
697 return(ModuleWarning);
698 break;
699 }
700 case 'O':
701 {
702 if (strEQ(name,"Opaque"))
703 return(OpaqueOpacity);
704 if (strEQ(name,"OptionError"))
705 return(OptionError);
706 if (strEQ(name,"OptionWarning"))
707 return(OptionWarning);
708 break;
709 }
710 case 'Q':
711 {
712 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
713 return(MAGICKCORE_QUANTUM_DEPTH);
714 if (strEQ(name,"QuantumDepth"))
715 return(QuantumDepth);
716 if (strEQ(name,"QuantumRange"))
717 return(QuantumRange);
718 break;
719 }
720 case 'R':
721 {
722 if (strEQ(name,"ResourceLimitError"))
723 return(ResourceLimitError);
724 if (strEQ(name,"ResourceLimitWarning"))
725 return(ResourceLimitWarning);
726 if (strEQ(name,"RegistryError"))
727 return(RegistryError);
728 if (strEQ(name,"RegistryWarning"))
729 return(RegistryWarning);
730 break;
731 }
732 case 'S':
733 {
734 if (strEQ(name,"StreamError"))
735 return(StreamError);
736 if (strEQ(name,"StreamWarning"))
737 return(StreamWarning);
738 if (strEQ(name,"Success"))
739 return(0);
740 break;
741 }
742 case 'T':
743 {
744 if (strEQ(name,"Transparent"))
745 return(TransparentOpacity);
746 if (strEQ(name,"TypeError"))
747 return(TypeError);
748 if (strEQ(name,"TypeWarning"))
749 return(TypeWarning);
750 break;
751 }
752 case 'W':
753 {
754 if (strEQ(name,"WarningException"))
755 return(WarningException);
756 break;
757 }
758 case 'X':
759 {
760 if (strEQ(name,"XServerError"))
761 return(XServerError);
762 if (strEQ(name,"XServerWarning"))
763 return(XServerWarning);
764 break;
765 }
766 }
767 errno=EINVAL;
768 return(0);
769}
770
771/*
772%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
773% %
774% %
775% %
776% D e s t r o y P a c k a g e I n f o %
777% %
778% %
779% %
780%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
781%
782% Method DestroyPackageInfo frees a previously created info structure.
783%
784% The format of the DestroyPackageInfo routine is:
785%
786% DestroyPackageInfo(struct PackageInfo *info)
787%
788% A description of each parameter follows:
789%
790% o info: a structure of type info.
791%
792*/
793static void DestroyPackageInfo(struct PackageInfo *info)
794{
795 info->image_info=DestroyImageInfo(info->image_info);
796 info=(struct PackageInfo *) RelinquishMagickMemory(info);
797}
798
799/*
800%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
801% %
802% %
803% %
804% G e t L i s t %
805% %
806% %
807% %
808%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
809%
810% Method GetList is recursively called by SetupList to traverse the
811% Image__Magick reference. If building an reference_vector (see SetupList),
812% *current is the current position in *reference_vector and *last is the final
813% entry in *reference_vector.
814%
815% The format of the GetList routine is:
816%
817% GetList(info)
818%
819% A description of each parameter follows:
820%
821% o info: a structure of type info.
822%
823*/
824static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,long *current,
825 long *last,ExceptionInfo *exception)
826{
827 Image
828 *image;
829
830 if (reference == (SV *) NULL)
831 return(NULL);
832 switch (SvTYPE(reference))
833 {
834 case SVt_PVAV:
835 {
836 AV
837 *av;
838
839 Image
840 *head,
841 *previous;
842
843 long
844 n;
845
846 register long
847 i;
848
849 /*
850 Array of images.
851 */
852 previous=(Image *) NULL;
853 head=(Image *) NULL;
854 av=(AV *) reference;
855 n=av_len(av);
856 for (i=0; i <= n; i++)
857 {
858 SV
859 **rv;
860
861 rv=av_fetch(av,i,0);
862 if (rv && *rv && sv_isobject(*rv))
863 {
864 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
865 exception);
866 if (image == (Image *) NULL)
867 continue;
868 if (image == previous)
869 {
870 image=CloneImage(image,0,0,MagickTrue,exception);
871 if (image == (Image *) NULL)
872 return(NULL);
873 }
874 image->previous=previous;
875 *(previous ? &previous->next : &head)=image;
876 for (previous=image; previous->next; previous=previous->next) ;
877 }
878 }
879 return(head);
880 }
881 case SVt_PVMG:
882 {
883 /*
884 Blessed scalar, one image.
885 */
886 image=(Image *) SvIV(reference);
887 if (image == (Image *) NULL)
888 return(NULL);
889 image->previous=(Image *) NULL;
890 image->next=(Image *) NULL;
891 if (reference_vector)
892 {
893 if (*current == *last)
894 {
895 *last+=256;
896 if (*reference_vector == (SV **) NULL)
897 *reference_vector=(SV **) AcquireQuantumMemory(*last,
898 sizeof(*reference_vector));
899 else
900 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
901 *last,sizeof(*reference_vector));
902 }
903 if (*reference_vector == (SV **) NULL)
904 {
905 ThrowPerlException(exception,ResourceLimitError,
906 "MemoryAllocationFailed",PackageName);
907 return((Image *) NULL);
908 }
909 (*reference_vector)[*current]=reference;
910 (*reference_vector)[++(*current)]=NULL;
911 }
912 return(image);
913 }
914 default:
915 break;
916 }
917 (void) fprintf(stderr,"GetList: UnrecognizedType %ld\n",
918 (long) SvTYPE(reference));
919 return((Image *) NULL);
920}
921
922/*
923%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
924% %
925% %
926% %
927% G e t P a c k a g e I n f o %
928% %
929% %
930% %
931%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
932%
933% Method GetPackageInfo looks up or creates an info structure for the given
934% Image__Magick reference. If it does create a new one, the information in
935% package_info is used to initialize it.
936%
937% The format of the GetPackageInfo routine is:
938%
939% struct PackageInfo *GetPackageInfo(void *reference,
940% struct PackageInfo *package_info,ExceptionInfo *exception)
941%
942% A description of each parameter follows:
943%
944% o info: a structure of type info.
945%
946% o exception: Return any errors or warnings in this structure.
947%
948*/
949static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
950 struct PackageInfo *package_info,ExceptionInfo *exception)
951{
952 char
953 message[MaxTextExtent];
954
955 struct PackageInfo
956 *clone_info;
957
958 SV
959 *sv;
960
961 (void) FormatMagickString(message,MaxTextExtent,"%s::package%s%lx",
962 PackageName,XS_VERSION,(long) reference);
963 sv=perl_get_sv(message,(TRUE | 0x02));
964 if (sv == (SV *) NULL)
965 {
966 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
967 message);
968 return(package_info);
969 }
970 if (SvREFCNT(sv) == 0)
971 (void) SvREFCNT_inc(sv);
972 if (SvIOKp(sv) && (clone_info=(struct PackageInfo *) SvIV(sv)))
973 return(clone_info);
974 clone_info=ClonePackageInfo(package_info,exception);
975 sv_setiv(sv,(IV) clone_info);
976 return(clone_info);
977}
978
979/*
980%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
981% %
982% %
983% %
984% S e t A t t r i b u t e %
985% %
986% %
987% %
988%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
989%
990% SetAttribute() sets the attribute to the value in sval. This can change
991% either or both of image or info.
992%
993% The format of the SetAttribute routine is:
994%
995% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
996% SV *sval,ExceptionInfo *exception)
997%
998% A description of each parameter follows:
999%
1000% o list: a list of strings.
1001%
1002% o string: a character string.
1003%
1004*/
1005static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1006 const char *attribute,SV *sval,ExceptionInfo *exception)
1007{
1008 GeometryInfo
1009 geometry_info;
1010
1011 long
1012 sp;
1013
1014 long
1015 x,
1016 y;
1017
1018 MagickPixelPacket
1019 pixel;
1020
1021 MagickStatusType
1022 flags;
1023
1024 PixelPacket
1025 *color,
1026 target_color;
1027
1028 switch (*attribute)
1029 {
1030 case 'A':
1031 case 'a':
1032 {
1033 if (LocaleCompare(attribute,"adjoin") == 0)
1034 {
1035 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1036 SvPV(sval,na)) : SvIV(sval);
1037 if (sp < 0)
1038 {
1039 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1040 SvPV(sval,na));
1041 break;
1042 }
1043 if (info)
1044 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1045 break;
1046 }
1047 if (LocaleCompare(attribute,"alpha") == 0)
1048 {
1049 sp=SvPOK(sval) ? ParseMagickOption(MagickAlphaOptions,MagickFalse,
1050 SvPV(sval,na)) : SvIV(sval);
1051 if (sp < 0)
1052 {
1053 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1054 SvPV(sval,na));
1055 break;
1056 }
1057 for ( ; image; image=image->next)
1058 (void) SetImageAlphaChannel(image,(AlphaChannelType) sp);
1059 break;
1060 }
1061 if (LocaleCompare(attribute,"antialias") == 0)
1062 {
1063 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1064 SvPV(sval,na)) : SvIV(sval);
1065 if (sp < 0)
1066 {
1067 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1068 SvPV(sval,na));
1069 break;
1070 }
1071 if (info)
1072 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1073 break;
1074 }
1075 if (LocaleCompare(attribute,"area-limit") == 0)
1076 {
1077 MagickSizeType
1078 limit;
1079
1080 limit=MagickResourceInfinity;
1081 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1082 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1083 (void) SetMagickResourceLimit(AreaResource,limit);
1084 break;
1085 }
1086 if (LocaleCompare(attribute,"attenuate") == 0)
1087 {
1088 if (info)
1089 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1090 break;
1091 }
1092 if (LocaleCompare(attribute,"authenticate") == 0)
1093 {
1094 if (info)
1095 (void) CloneString(&info->image_info->authenticate,SvPV(sval,na));
1096 break;
1097 }
1098 if (info)
1099 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1100 for ( ; image; image=image->next)
1101 SetImageProperty(image,attribute,SvPV(sval,na));
1102 break;
1103 }
1104 case 'B':
1105 case 'b':
1106 {
1107 if (LocaleCompare(attribute,"background") == 0)
1108 {
1109 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
1110 if (info)
1111 info->image_info->background_color=target_color;
1112 for ( ; image; image=image->next)
1113 image->background_color=target_color;
1114 break;
1115 }
1116 if (LocaleCompare(attribute,"bias") == 0)
1117 {
1118 for ( ; image; image=image->next)
1119 image->bias=StringToDouble(SvPV(sval,na),QuantumRange);
1120 break;
1121 }
1122 if (LocaleCompare(attribute,"blue-primary") == 0)
1123 {
1124 for ( ; image; image=image->next)
1125 {
1126 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1127 image->chromaticity.blue_primary.x=geometry_info.rho;
1128 image->chromaticity.blue_primary.y=geometry_info.sigma;
1129 if ((flags & SigmaValue) == 0)
1130 image->chromaticity.blue_primary.y=
1131 image->chromaticity.blue_primary.x;
1132 }
1133 break;
1134 }
1135 if (LocaleCompare(attribute,"bordercolor") == 0)
1136 {
1137 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
1138 if (info)
1139 info->image_info->border_color=target_color;
1140 for ( ; image; image=image->next)
1141 image->border_color=target_color;
1142 break;
1143 }
1144 if (info)
1145 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1146 for ( ; image; image=image->next)
1147 SetImageProperty(image,attribute,SvPV(sval,na));
1148 break;
1149 }
1150 case 'C':
1151 case 'c':
1152 {
1153 if (LocaleCompare(attribute,"cache-threshold") == 0)
1154 {
1155 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1156 StringToDouble(SvPV(sval,na),100.0));
1157 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1158 (2*StringToDouble(SvPV(sval,na),100.0)));
1159 break;
1160 }
1161 if (LocaleCompare(attribute,"clip-mask") == 0)
1162 {
1163 Image
1164 *clip_mask;
1165
1166 clip_mask=(Image *) NULL;
1167 if (SvPOK(sval))
1168 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1169 for ( ; image; image=image->next)
1170 SetImageClipMask(image,clip_mask);
1171 break;
1172 }
1173 if (LocaleNCompare(attribute,"colormap",8) == 0)
1174 {
1175 for ( ; image; image=image->next)
1176 {
1177 int
1178 items;
1179
1180 long
1181 i;
1182
1183 if (image->storage_class == DirectClass)
1184 continue;
1185 i=0;
1186 items=sscanf(attribute,"%*[^[][%ld",&i);
1187 if (i > (long) image->colors)
1188 i%=image->colors;
1189 if ((strchr(SvPV(sval,na),',') == 0) ||
1190 (strchr(SvPV(sval,na),')') != 0))
1191 QueryColorDatabase(SvPV(sval,na),image->colormap+i,exception);
1192 else
1193 {
1194 color=image->colormap+i;
1195 pixel.red=color->red;
1196 pixel.green=color->green;
1197 pixel.blue=color->blue;
1198 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1199 pixel.red=geometry_info.rho;
1200 pixel.green=geometry_info.sigma;
1201 pixel.blue=geometry_info.xi;
1202 color->red=RoundToQuantum(pixel.red);
1203 color->green=RoundToQuantum(pixel.green);
1204 color->blue=RoundToQuantum(pixel.blue);
1205 }
1206 }
1207 break;
1208 }
1209 if (LocaleCompare(attribute,"colorspace") == 0)
1210 {
1211 sp=SvPOK(sval) ? ParseMagickOption(MagickColorspaceOptions,
1212 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1213 if (sp < 0)
1214 {
1215 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1216 SvPV(sval,na));
1217 break;
1218 }
1219 for ( ; image; image=image->next)
1220 (void) TransformImageColorspace(image,(ColorspaceType) sp);
1221 break;
1222 }
1223 if (LocaleCompare(attribute,"comment") == 0)
1224 {
1225 for ( ; image; image=image->next)
1226 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1227 info ? info->image_info : (ImageInfo *) NULL,image,
1228 SvPV(sval,na)));
1229 break;
1230 }
1231 if (LocaleCompare(attribute,"compression") == 0)
1232 {
1233 sp=SvPOK(sval) ? ParseMagickOption(MagickCompressOptions,
1234 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1235 if (sp < 0)
1236 {
1237 ThrowPerlException(exception,OptionError,
1238 "UnrecognizedImageCompression",SvPV(sval,na));
1239 break;
1240 }
1241 if (info)
1242 info->image_info->compression=(CompressionType) sp;
1243 for ( ; image; image=image->next)
1244 image->compression=(CompressionType) sp;
1245 break;
1246 }
1247 if (info)
1248 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1249 for ( ; image; image=image->next)
1250 SetImageProperty(image,attribute,SvPV(sval,na));
1251 break;
1252 }
1253 case 'D':
1254 case 'd':
1255 {
1256 if (LocaleCompare(attribute,"debug") == 0)
1257 {
1258 SetLogEventMask(SvPV(sval,na));
1259 break;
1260 }
1261 if (LocaleCompare(attribute,"delay") == 0)
1262 {
1263 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1264 for ( ; image; image=image->next)
1265 {
1266 image->delay=(unsigned long) (geometry_info.rho+0.5);
1267 if ((flags & SigmaValue) != 0)
1268 image->ticks_per_second=(unsigned long) (geometry_info.sigma+0.5);
1269 }
1270 break;
1271 }
1272 if (LocaleCompare(attribute,"disk-limit") == 0)
1273 {
1274 MagickSizeType
1275 limit;
1276
1277 limit=MagickResourceInfinity;
1278 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1279 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1280 (void) SetMagickResourceLimit(DiskResource,limit);
1281 break;
1282 }
1283 if (LocaleCompare(attribute,"density") == 0)
1284 {
1285 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1286 {
1287 ThrowPerlException(exception,OptionError,"MissingGeometry",
1288 SvPV(sval,na));
1289 break;
1290 }
1291 if (info)
1292 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1293 for ( ; image; image=image->next)
1294 {
1295 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1296 image->x_resolution=geometry_info.rho;
1297 image->y_resolution=geometry_info.sigma;
1298 if ((flags & SigmaValue) == 0)
1299 image->y_resolution=image->x_resolution;
1300 }
1301 break;
1302 }
1303 if (LocaleCompare(attribute,"depth") == 0)
1304 {
1305 if (info)
1306 info->image_info->depth=SvIV(sval);
1307 for ( ; image; image=image->next)
1308 (void) SetImageDepth(image,SvIV(sval));
1309 break;
1310 }
1311 if (LocaleCompare(attribute,"dispose") == 0)
1312 {
1313 sp=SvPOK(sval) ? ParseMagickOption(MagickDisposeOptions,MagickFalse,
1314 SvPV(sval,na)) : SvIV(sval);
1315 if (sp < 0)
1316 {
1317 ThrowPerlException(exception,OptionError,
1318 "UnrecognizedDisposeMethod",SvPV(sval,na));
1319 break;
1320 }
1321 for ( ; image; image=image->next)
1322 image->dispose=(DisposeType) sp;
1323 break;
1324 }
1325 if (LocaleCompare(attribute,"dither") == 0)
1326 {
1327 if (info)
1328 {
1329 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,
1330 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1331 if (sp < 0)
1332 {
1333 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1334 SvPV(sval,na));
1335 break;
1336 }
1337 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1338 }
1339 break;
1340 }
1341 if (LocaleCompare(attribute,"display") == 0)
1342 {
1343 display:
1344 if (info)
1345 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1346 break;
1347 }
1348 if (info)
1349 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1350 for ( ; image; image=image->next)
1351 SetImageProperty(image,attribute,SvPV(sval,na));
1352 break;
1353 }
1354 case 'E':
1355 case 'e':
1356 {
1357 if (LocaleCompare(attribute,"endian") == 0)
1358 {
1359 sp=SvPOK(sval) ? ParseMagickOption(MagickEndianOptions,MagickFalse,
1360 SvPV(sval,na)) : SvIV(sval);
1361 if (sp < 0)
1362 {
1363 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1364 SvPV(sval,na));
1365 break;
1366 }
1367 if (info)
1368 info->image_info->endian=(EndianType) sp;
1369 for ( ; image; image=image->next)
1370 image->endian=(EndianType) sp;
1371 break;
1372 }
1373 if (LocaleCompare(attribute,"extract") == 0)
1374 {
1375 /*
1376 Set image extract geometry.
1377 */
1378 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1379 break;
1380 }
1381 if (info)
1382 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1383 for ( ; image; image=image->next)
1384 SetImageProperty(image,attribute,SvPV(sval,na));
1385 break;
1386 }
1387 case 'F':
1388 case 'f':
1389 {
1390 if (LocaleCompare(attribute,"filename") == 0)
1391 {
1392 if (info)
1393 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
1394 MaxTextExtent);
1395 for ( ; image; image=image->next)
1396 (void) CopyMagickString(image->filename,SvPV(sval,na),
1397 MaxTextExtent);
1398 break;
1399 }
1400 if (LocaleCompare(attribute,"file") == 0)
1401 {
1402 FILE
1403 *file;
1404
1405 PerlIO
1406 *io_info;
1407
1408 if (info == (struct PackageInfo *) NULL)
1409 break;
1410 io_info=IoIFP(sv_2io(sval));
1411 if (io_info == (PerlIO *) NULL)
1412 {
1413 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1414 PackageName);
1415 break;
1416 }
1417 file=PerlIO_findFILE(io_info);
1418 if (file == (FILE *) NULL)
1419 {
1420 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1421 PackageName);
1422 break;
1423 }
1424 SetImageInfoFile(info->image_info,file);
1425 break;
1426 }
1427 if (LocaleCompare(attribute,"fill") == 0)
1428 {
1429 if (info)
1430 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1431 break;
1432 }
1433 if (LocaleCompare(attribute,"font") == 0)
1434 {
1435 if (info)
1436 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1437 break;
1438 }
1439 if (LocaleCompare(attribute,"foreground") == 0)
1440 break;
1441 if (LocaleCompare(attribute,"fuzz") == 0)
1442 {
1443 if (info)
1444 info->image_info->fuzz=StringToDouble(SvPV(sval,na),QuantumRange);
1445 for ( ; image; image=image->next)
1446 image->fuzz=StringToDouble(SvPV(sval,na),QuantumRange);
1447 break;
1448 }
1449 if (info)
1450 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1451 for ( ; image; image=image->next)
1452 SetImageProperty(image,attribute,SvPV(sval,na));
1453 break;
1454 }
1455 case 'G':
1456 case 'g':
1457 {
1458 if (LocaleCompare(attribute,"gamma") == 0)
1459 {
1460 for ( ; image; image=image->next)
1461 image->gamma=SvNV(sval);
1462 break;
1463 }
1464 if (LocaleCompare(attribute,"gravity") == 0)
1465 {
1466 sp=SvPOK(sval) ? ParseMagickOption(MagickGravityOptions,MagickFalse,
1467 SvPV(sval,na)) : SvIV(sval);
1468 if (sp < 0)
1469 {
1470 ThrowPerlException(exception,OptionError,
1471 "UnrecognizedGravityType",SvPV(sval,na));
1472 break;
1473 }
1474 for ( ; image; image=image->next)
1475 image->gravity=(GravityType) sp;
1476 break;
1477 }
1478 if (LocaleCompare(attribute,"green-primary") == 0)
1479 {
1480 for ( ; image; image=image->next)
1481 {
1482 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1483 image->chromaticity.green_primary.x=geometry_info.rho;
1484 image->chromaticity.green_primary.y=geometry_info.sigma;
1485 if ((flags & SigmaValue) == 0)
1486 image->chromaticity.green_primary.y=
1487 image->chromaticity.green_primary.x;
1488 }
1489 break;
1490 }
1491 if (info)
1492 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1493 for ( ; image; image=image->next)
1494 SetImageProperty(image,attribute,SvPV(sval,na));
1495 break;
1496 }
1497 case 'I':
1498 case 'i':
1499 {
1500 if (LocaleNCompare(attribute,"index",5) == 0)
1501 {
1502 IndexPacket
1503 *indexes;
1504
1505 int
1506 items;
1507
1508 long
1509 index;
1510
1511 register PixelPacket
1512 *p;
1513
1514 CacheView
1515 *image_view;
1516
1517 for ( ; image; image=image->next)
1518 {
1519 if (image->storage_class != PseudoClass)
1520 continue;
1521 x=0;
1522 y=0;
1523 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1524 image_view=OpenCacheView(image);
1525 p=GetCacheViewPixels(image_view,x,y,1,1);
1526 if (p != (PixelPacket *) NULL)
1527 {
1528 indexes=GetCacheViewIndexes(image_view);
1529 items=sscanf(SvPV(sval,na),"%ld",&index);
1530 if ((index >= 0) && (index < (long) image->colors))
1531 *indexes=(IndexPacket) index;
1532 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1533 }
1534 image_view=CloseCacheView(image_view);
1535 }
1536 break;
1537 }
1538 if (LocaleCompare(attribute,"iterations") == 0)
1539 {
1540 iterations:
1541 for ( ; image; image=image->next)
1542 image->iterations=SvIV(sval);
1543 break;
1544 }
1545 if (LocaleCompare(attribute,"interlace") == 0)
1546 {
1547 sp=SvPOK(sval) ? ParseMagickOption(MagickInterlaceOptions,MagickFalse,
1548 SvPV(sval,na)) : SvIV(sval);
1549 if (sp < 0)
1550 {
1551 ThrowPerlException(exception,OptionError,
1552 "UnrecognizedInterlaceType",SvPV(sval,na));
1553 break;
1554 }
1555 if (info)
1556 info->image_info->interlace=(InterlaceType) sp;
1557 for ( ; image; image=image->next)
1558 image->interlace=(InterlaceType) sp;
1559 break;
1560 }
1561 if (info)
1562 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1563 for ( ; image; image=image->next)
1564 SetImageProperty(image,attribute,SvPV(sval,na));
1565 break;
1566 }
1567 case 'L':
1568 case 'l':
1569 {
1570 if (LocaleCompare(attribute,"label") == 0)
1571 {
1572 for ( ; image; image=image->next)
1573 (void) SetImageProperty(image,"label",InterpretImageProperties(
1574 info ? info->image_info : (ImageInfo *) NULL,image,
1575 SvPV(sval,na)));
1576 break;
1577 }
1578 if (LocaleCompare(attribute,"loop") == 0)
1579 goto iterations;
1580 if (info)
1581 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1582 for ( ; image; image=image->next)
1583 SetImageProperty(image,attribute,SvPV(sval,na));
1584 break;
1585 }
1586 case 'M':
1587 case 'm':
1588 {
1589 if (LocaleCompare(attribute,"magick") == 0)
1590 {
1591 if (info)
1592 (void) FormatMagickString(info->image_info->filename,MaxTextExtent,
1593 "%.1024s:",SvPV(sval,na));
1594 for ( ; image; image=image->next)
1595 (void) CopyMagickString(image->magick,SvPV(sval,na),MaxTextExtent);
1596 break;
1597 }
1598 if (LocaleCompare(attribute,"map-limit") == 0)
1599 {
1600 MagickSizeType
1601 limit;
1602
1603 limit=MagickResourceInfinity;
1604 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1605 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1606 (void) SetMagickResourceLimit(MapResource,limit);
1607 break;
1608 }
1609 if (LocaleCompare(attribute,"mask") == 0)
1610 {
1611 Image
1612 *mask;
1613
1614 mask=(Image *) NULL;
1615 if (SvPOK(sval))
1616 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1617 for ( ; image; image=image->next)
1618 SetImageMask(image,mask);
1619 break;
1620 }
1621 if (LocaleCompare(attribute,"mattecolor") == 0)
1622 {
1623 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
1624 if (info)
1625 info->image_info->matte_color=target_color;
1626 for ( ; image; image=image->next)
1627 image->matte_color=target_color;
1628 break;
1629 }
1630 if (LocaleCompare(attribute,"matte") == 0)
1631 {
1632 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1633 SvPV(sval,na)) : SvIV(sval);
1634 if (sp < 0)
1635 {
1636 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1637 SvPV(sval,na));
1638 break;
1639 }
1640 for ( ; image; image=image->next)
1641 image->matte=sp != 0 ? MagickTrue : MagickFalse;
1642 break;
1643 }
1644 if (LocaleCompare(attribute,"memory-limit") == 0)
1645 {
1646 MagickSizeType
1647 limit;
1648
1649 limit=MagickResourceInfinity;
1650 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1651 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1652 (void) SetMagickResourceLimit(MemoryResource,limit);
1653 break;
1654 }
1655 if (LocaleCompare(attribute,"monochrome") == 0)
1656 {
1657 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1658 SvPV(sval,na)) : SvIV(sval);
1659 if (sp < 0)
1660 {
1661 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1662 SvPV(sval,na));
1663 break;
1664 }
1665 if (info)
1666 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1667 for ( ; image; image=image->next)
1668 (void) SetImageType(image,BilevelType);
1669 break;
1670 }
1671 if (info)
1672 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1673 for ( ; image; image=image->next)
1674 SetImageProperty(image,attribute,SvPV(sval,na));
1675 break;
1676 }
1677 case 'O':
1678 case 'o':
1679 {
1680 if (LocaleCompare(attribute,"option") == 0)
1681 {
1682 if (info)
1683 DefineImageOption(info->image_info,SvPV(sval,na));
1684 break;
1685 }
1686 if (LocaleCompare(attribute,"orientation") == 0)
1687 {
1688 sp=SvPOK(sval) ? ParseMagickOption(MagickOrientationOptions,
1689 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1690 if (sp < 0)
1691 {
1692 ThrowPerlException(exception,OptionError,
1693 "UnrecognizedOrientationType",SvPV(sval,na));
1694 break;
1695 }
1696 if (info)
1697 info->image_info->orientation=(OrientationType) sp;
1698 for ( ; image; image=image->next)
1699 image->orientation=(OrientationType) sp;
1700 break;
1701 }
1702 if (info)
1703 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1704 for ( ; image; image=image->next)
1705 SetImageProperty(image,attribute,SvPV(sval,na));
1706 break;
1707 }
1708 case 'P':
1709 case 'p':
1710 {
1711 if (LocaleCompare(attribute,"page") == 0)
1712 {
1713 char
1714 *geometry;
1715
1716 geometry=GetPageGeometry(SvPV(sval,na));
1717 if (info)
1718 (void) CloneString(&info->image_info->page,geometry);
1719 for ( ; image; image=image->next)
1720 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1721 geometry=(char *) RelinquishMagickMemory(geometry);
1722 break;
1723 }
1724 if (LocaleCompare(attribute,"pen") == 0)
1725 {
1726 if (info)
1727 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1728 break;
1729 }
1730 if (LocaleNCompare(attribute,"pixel",5) == 0)
1731 {
1732 int
1733 items;
1734
1735 MagickPixelPacket
1736 pixel;
1737
1738 register IndexPacket
1739 *indexes;
1740
1741 register PixelPacket
1742 *p;
1743
1744 CacheView
1745 *image_view;
1746
1747 for ( ; image; image=image->next)
1748 {
1749 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1750 break;
1751 x=0;
1752 y=0;
1753 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1754 image_view=OpenCacheView(image);
1755 p=GetCacheViewPixels(image_view,x,y,1,1);
1756 indexes=GetCacheViewIndexes(image_view);
1757 if (p != (PixelPacket *) NULL)
1758 {
1759 if ((strchr(SvPV(sval,na),',') == 0) ||
1760 (strchr(SvPV(sval,na),')') != 0))
1761 QueryMagickColor(SvPV(sval,na),&pixel,exception);
1762 else
1763 {
1764 GetMagickPixelPacket(image,&pixel);
1765 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1766 pixel.red=geometry_info.rho;
1767 if ((flags & SigmaValue) != 0)
1768 pixel.green=geometry_info.sigma;
1769 if ((flags & XiValue) != 0)
1770 pixel.blue=geometry_info.xi;
1771 if ((flags & PsiValue) != 0)
1772 pixel.opacity=geometry_info.psi;
1773 if ((flags & ChiValue) != 0)
1774 pixel.index=geometry_info.chi;
1775 }
1776 p->red=RoundToQuantum(pixel.red);
1777 p->green=RoundToQuantum(pixel.green);
1778 p->blue=RoundToQuantum(pixel.blue);
1779 p->opacity=RoundToQuantum(pixel.opacity);
1780 if (((image->colorspace == CMYKColorspace) ||
1781 (image->storage_class == PseudoClass)) &&
1782 (indexes != (IndexPacket *) NULL))
1783 *indexes=RoundToQuantum(pixel.index);
1784 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1785 }
1786 image_view=CloseCacheView(image_view);
1787 }
1788 break;
1789 }
1790 if (LocaleCompare(attribute,"pointsize") == 0)
1791 {
1792 if (info)
1793 {
1794 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1795 info->image_info->pointsize=geometry_info.rho;
1796 }
1797 break;
1798 }
1799 if (LocaleCompare(attribute,"preview") == 0)
1800 {
1801 sp=SvPOK(sval) ? ParseMagickOption(MagickPreviewOptions,MagickFalse,
1802 SvPV(sval,na)) : SvIV(sval);
1803 if (sp < 0)
1804 {
1805 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1806 SvPV(sval,na));
1807 break;
1808 }
1809 if (info)
1810 info->image_info->preview_type=(PreviewType) sp;
1811 break;
1812 }
1813 if (info)
1814 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1815 for ( ; image; image=image->next)
1816 SetImageProperty(image,attribute,SvPV(sval,na));
1817 break;
1818 }
1819 case 'Q':
1820 case 'q':
1821 {
1822 if (LocaleCompare(attribute,"quality") == 0)
1823 {
1824 if (info)
1825 info->image_info->quality=SvIV(sval);
1826 for ( ; image; image=image->next)
1827 image->quality=SvIV(sval);
1828 break;
1829 }
1830 if (info)
1831 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1832 for ( ; image; image=image->next)
1833 SetImageProperty(image,attribute,SvPV(sval,na));
1834 break;
1835 }
1836 case 'R':
1837 case 'r':
1838 {
1839 if (LocaleCompare(attribute,"red-primary") == 0)
1840 {
1841 for ( ; image; image=image->next)
1842 {
1843 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1844 image->chromaticity.red_primary.x=geometry_info.rho;
1845 image->chromaticity.red_primary.y=geometry_info.sigma;
1846 if ((flags & SigmaValue) == 0)
1847 image->chromaticity.red_primary.y=
1848 image->chromaticity.red_primary.x;
1849 }
1850 break;
1851 }
1852 if (LocaleCompare(attribute,"render") == 0)
1853 {
1854 sp=SvPOK(sval) ? ParseMagickOption(MagickIntentOptions,MagickFalse,
1855 SvPV(sval,na)) : SvIV(sval);
1856 if (sp < 0)
1857 {
1858 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1859 SvPV(sval,na));
1860 break;
1861 }
1862 for ( ; image; image=image->next)
1863 image->rendering_intent=(RenderingIntent) sp;
1864 break;
1865 }
1866 if (LocaleCompare(attribute,"repage") == 0)
1867 {
1868 RectangleInfo
1869 geometry;
1870
1871 for ( ; image; image=image->next)
1872 {
1873 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1874 if ((flags & WidthValue) != 0)
1875 {
1876 if ((flags & HeightValue) == 0)
1877 geometry.height=geometry.width;
1878 image->page.width=geometry.width;
1879 image->page.height=geometry.height;
1880 }
1881 if ((flags & AspectValue) != 0)
1882 {
1883 if ((flags & XValue) != 0)
1884 image->page.x+=geometry.x;
1885 if ((flags & YValue) != 0)
1886 image->page.y+=geometry.y;
1887 }
1888 else
1889 {
1890 if ((flags & XValue) != 0)
1891 {
1892 image->page.x=geometry.x;
1893 if (((flags & WidthValue) != 0) && (geometry.x > 0))
1894 image->page.width=image->columns+geometry.x;
1895 }
1896 if ((flags & YValue) != 0)
1897 {
1898 image->page.y=geometry.y;
1899 if (((flags & HeightValue) != 0) && (geometry.y > 0))
1900 image->page.height=image->rows+geometry.y;
1901 }
1902 }
1903 }
1904 break;
1905 }
1906 if (info)
1907 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1908 for ( ; image; image=image->next)
1909 SetImageProperty(image,attribute,SvPV(sval,na));
1910 break;
1911 }
1912 case 'S':
1913 case 's':
1914 {
1915 if (LocaleCompare(attribute,"sampling-factor") == 0)
1916 {
1917 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1918 {
1919 ThrowPerlException(exception,OptionError,"MissingGeometry",
1920 SvPV(sval,na));
1921 break;
1922 }
1923 if (info)
1924 (void) CloneString(&info->image_info->sampling_factor,
1925 SvPV(sval,na));
1926 break;
1927 }
1928 if (LocaleCompare(attribute,"scene") == 0)
1929 {
1930 for ( ; image; image=image->next)
1931 image->scene=SvIV(sval);
1932 break;
1933 }
1934 if (LocaleCompare(attribute,"subimage") == 0)
1935 {
1936 if (info)
1937 info->image_info->subimage=SvIV(sval);
1938 break;
1939 }
1940 if (LocaleCompare(attribute,"subrange") == 0)
1941 {
1942 if (info)
1943 info->image_info->subrange=SvIV(sval);
1944 break;
1945 }
1946 if (LocaleCompare(attribute,"server") == 0)
1947 goto display;
1948 if (LocaleCompare(attribute,"size") == 0)
1949 {
1950 if (info)
1951 {
1952 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1953 {
1954 ThrowPerlException(exception,OptionError,"MissingGeometry",
1955 SvPV(sval,na));
1956 break;
1957 }
1958 (void) CloneString(&info->image_info->size,SvPV(sval,na));
1959 }
1960 break;
1961 }
1962 if (LocaleCompare(attribute,"stroke") == 0)
1963 {
1964 if (info)
1965 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
1966 break;
1967 }
1968 if (info)
1969 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1970 for ( ; image; image=image->next)
1971 SetImageProperty(image,attribute,SvPV(sval,na));
1972 break;
1973 }
1974 case 'T':
1975 case 't':
1976 {
1977 if (LocaleCompare(attribute,"tile") == 0)
1978 {
1979 if (info)
1980 (void) CloneString(&info->image_info->tile,SvPV(sval,na));
1981 break;
1982 }
1983 if (LocaleCompare(attribute,"texture") == 0)
1984 {
1985 if (info)
1986 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
1987 break;
1988 }
1989 if (LocaleCompare(attribute,"tile-offset") == 0)
1990 {
1991 char
1992 *geometry;
1993
1994 geometry=GetPageGeometry(SvPV(sval,na));
1995 if (info)
1996 (void) CloneString(&info->image_info->page,geometry);
1997 for ( ; image; image=image->next)
1998 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
1999 exception);
2000 geometry=(char *) RelinquishMagickMemory(geometry);
2001 break;
2002 }
2003 if (LocaleCompare(attribute,"time-limit") == 0)
2004 {
2005 MagickSizeType
2006 limit;
2007
2008 limit=MagickResourceInfinity;
2009 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2010 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
2011 (void) SetMagickResourceLimit(TimeResource,limit);
2012 break;
2013 }
2014 if (LocaleCompare(attribute,"transparent-color") == 0)
2015 {
2016 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
2017 if (info)
2018 info->image_info->transparent_color=target_color;
2019 for ( ; image; image=image->next)
2020 image->transparent_color=target_color;
2021 break;
2022 }
2023 if (LocaleCompare(attribute,"type") == 0)
2024 {
2025 sp=SvPOK(sval) ? ParseMagickOption(MagickTypeOptions,MagickFalse,
2026 SvPV(sval,na)) : SvIV(sval);
2027 if (sp < 0)
2028 {
2029 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2030 SvPV(sval,na));
2031 break;
2032 }
2033 if (info)
2034 info->image_info->type=(ImageType) sp;
2035 for ( ; image; image=image->next)
2036 SetImageType(image,(ImageType) sp);
2037 break;
2038 }
2039 if (info)
2040 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2041 for ( ; image; image=image->next)
2042 SetImageProperty(image,attribute,SvPV(sval,na));
2043 break;
2044 }
2045 case 'U':
2046 case 'u':
2047 {
2048 if (LocaleCompare(attribute,"units") == 0)
2049 {
2050 sp=SvPOK(sval) ? ParseMagickOption(MagickResolutionOptions,
2051 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2052 if (sp < 0)
2053 {
2054 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2055 SvPV(sval,na));
2056 break;
2057 }
2058 if (info)
2059 info->image_info->units=(ResolutionType) sp;
2060 for ( ; image; image=image->next)
2061 {
2062 ResolutionType
2063 units;
2064
2065 units=(ResolutionType) sp;
2066 if (image->units != units)
2067 switch (image->units)
2068 {
2069 case UndefinedResolution:
2070 case PixelsPerInchResolution:
2071 {
2072 if (units == PixelsPerCentimeterResolution)
2073 {
2074 image->x_resolution*=2.54;
2075 image->y_resolution*=2.54;
2076 }
2077 break;
2078 }
2079 case PixelsPerCentimeterResolution:
2080 {
2081 if (units == PixelsPerInchResolution)
2082 {
2083 image->x_resolution/=2.54;
2084 image->y_resolution/=2.54;
2085 }
2086 break;
2087 }
2088 }
2089 image->units=units;
2090 }
2091 break;
2092 }
2093 if (info)
2094 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2095 for ( ; image; image=image->next)
2096 SetImageProperty(image,attribute,SvPV(sval,na));
2097 break;
2098 }
2099 case 'V':
2100 case 'v':
2101 {
2102 if (LocaleCompare(attribute,"verbose") == 0)
2103 {
2104 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
2105 SvPV(sval,na)) : SvIV(sval);
2106 if (sp < 0)
2107 {
2108 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2109 SvPV(sval,na));
2110 break;
2111 }
2112 if (info)
2113 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2114 break;
2115 }
2116 if (LocaleCompare(attribute,"view") == 0)
2117 {
2118 if (info)
2119 (void) CloneString(&info->image_info->view,SvPV(sval,na));
2120 break;
2121 }
2122 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2123 {
2124 sp=SvPOK(sval) ? ParseMagickOption(MagickVirtualPixelOptions,
2125 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2126 if (sp < 0)
2127 {
2128 ThrowPerlException(exception,OptionError,
2129 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2130 break;
2131 }
2132 if (info)
2133 info->image_info->virtual_pixel_method=(VirtualPixelMethod) sp;
2134 for ( ; image; image=image->next)
2135 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp);
2136 break;
2137 }
2138 if (info)
2139 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2140 for ( ; image; image=image->next)
2141 SetImageProperty(image,attribute,SvPV(sval,na));
2142 break;
2143 }
2144 case 'W':
2145 case 'w':
2146 {
2147 if (LocaleCompare(attribute,"white-point") == 0)
2148 {
2149 for ( ; image; image=image->next)
2150 {
2151 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2152 image->chromaticity.white_point.x=geometry_info.rho;
2153 image->chromaticity.white_point.y=geometry_info.sigma;
2154 if ((flags & SigmaValue) == 0)
2155 image->chromaticity.white_point.y=
2156 image->chromaticity.white_point.x;
2157 }
2158 break;
2159 }
2160 if (info)
2161 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2162 for ( ; image; image=image->next)
2163 SetImageProperty(image,attribute,SvPV(sval,na));
2164 break;
2165 }
2166 default:
2167 {
2168 if (info)
2169 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2170 for ( ; image; image=image->next)
2171 SetImageProperty(image,attribute,SvPV(sval,na));
2172 break;
2173 }
2174 }
2175}
2176
2177/*
2178%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2179% %
2180% %
2181% %
2182% S e t u p L i s t %
2183% %
2184% %
2185% %
2186%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2187%
2188% Method SetupList returns the list of all the images linked by their
2189% image->next and image->previous link lists for use with ImageMagick. If
2190% info is non-NULL, an info structure is returned in *info. If
2191% reference_vector is non-NULL,an array of SV* are returned in
2192% *reference_vector. Reference_vector is used when the images are going to be
2193% replaced with new Image*'s.
2194%
2195% The format of the SetupList routine is:
2196%
2197% Image *SetupList(SV *reference,struct PackageInfo **info,
2198% SV ***reference_vector,ExceptionInfo *exception)
2199%
2200% A description of each parameter follows:
2201%
2202% o list: a list of strings.
2203%
2204% o string: a character string.
2205%
2206% o exception: Return any errors or warnings in this structure.
2207%
2208*/
2209static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2210 SV ***reference_vector,ExceptionInfo *exception)
2211{
2212 Image
2213 *image;
2214
2215 long
2216 current,
2217 last;
2218
2219 if (reference_vector)
2220 *reference_vector=NULL;
2221 if (info)
2222 *info=NULL;
2223 current=0;
2224 last=0;
2225 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2226 if (info && (SvTYPE(reference) == SVt_PVAV))
2227 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2228 exception);
2229 return(image);
2230}
2231
2232/*
2233%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2234% %
2235% %
2236% %
2237% s t r E Q c a s e %
2238% %
2239% %
2240% %
2241%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2242%
2243% strEQcase() compares two strings and returns 0 if they are the
2244% same or if the second string runs out first. The comparison is case
2245% insensitive.
2246%
2247% The format of the strEQcase routine is:
2248%
2249% long strEQcase(const char *p,const char *q)
2250%
2251% A description of each parameter follows:
2252%
2253% o p: a character string.
2254%
2255% o q: a character string.
2256%
2257%
2258*/
2259static long strEQcase(const char *p,const char *q)
2260{
2261 char
2262 c;
2263
2264 register long
2265 i;
2266
2267 for (i=0 ; (c=(*q)) != 0; i++)
2268 {
2269 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2270 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2271 return(0);
2272 p++;
2273 q++;
2274 }
2275 return(((*q == 0) && (*p == 0)) ? i : 0);
2276}
2277
2278/*
2279%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2280% %
2281% %
2282% %
2283% I m a g e : : M a g i c k %
2284% %
2285% %
2286% %
2287%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2288%
2289%
2290*/
2291MODULE = Image::Magick PACKAGE = Image::Magick
2292
2293PROTOTYPES: ENABLE
2294
2295BOOT:
2296 MagickCoreGenesis("PerlMagick",MagickFalse);
2297 SetWarningHandler(NULL);
2298 SetErrorHandler(NULL);
2299 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2300 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2301
2302void
2303UNLOAD()
2304 PPCODE:
2305 {
2306 if (magick_registry != (SplayTreeInfo *) NULL)
2307 magick_registry=DestroySplayTree(magick_registry);
2308 MagickCoreTerminus();
2309 }
2310
2311double
2312constant(name,argument)
2313 char *name
2314 long argument
2315
2316#
2317###############################################################################
2318# #
2319# #
2320# #
2321# A n i m a t e #
2322# #
2323# #
2324# #
2325###############################################################################
2326#
2327#
2328void
2329Animate(ref,...)
2330 Image::Magick ref=NO_INIT
2331 ALIAS:
2332 AnimateImage = 1
2333 animate = 2
2334 animateimage = 3
2335 PPCODE:
2336 {
2337 ExceptionInfo
2338 *exception;
2339
2340 Image
2341 *image;
2342
2343 register long
2344 i;
2345
2346 struct PackageInfo
2347 *info,
2348 *package_info;
2349
2350 SV
2351 *perl_exception,
2352 *reference;
2353
2354 exception=AcquireExceptionInfo();
2355 perl_exception=newSVpv("",0);
2356 package_info=(struct PackageInfo *) NULL;
2357 if (sv_isobject(ST(0)) == 0)
2358 {
2359 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2360 PackageName);
2361 goto PerlException;
2362 }
2363 reference=SvRV(ST(0));
2364 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2365 if (image == (Image *) NULL)
2366 {
2367 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2368 PackageName);
2369 goto PerlException;
2370 }
2371 package_info=ClonePackageInfo(info,exception);
2372 if (items == 2)
2373 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2374 else
2375 if (items > 2)
2376 for (i=2; i < items; i+=2)
2377 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2378 exception);
2379 (void) AnimateImages(package_info->image_info,image);
2380 (void) CatchImageException(image);
2381 InheritException(exception,&image->exception);
2382
2383 PerlException:
2384 if (package_info != (struct PackageInfo *) NULL)
2385 DestroyPackageInfo(package_info);
2386 InheritPerlException(exception,perl_exception);
2387 exception=DestroyExceptionInfo(exception);
2388 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2389 SvPOK_on(perl_exception);
2390 ST(0)=sv_2mortal(perl_exception);
2391 XSRETURN(1);
2392 }
2393
2394#
2395###############################################################################
2396# #
2397# #
2398# #
2399# A p p e n d #
2400# #
2401# #
2402# #
2403###############################################################################
2404#
2405#
2406void
2407Append(ref,...)
2408 Image::Magick ref=NO_INIT
2409 ALIAS:
2410 AppendImage = 1
2411 append = 2
2412 appendimage = 3
2413 PPCODE:
2414 {
2415 AV
2416 *av;
2417
2418 char
2419 *attribute;
2420
2421 ExceptionInfo
2422 *exception;
2423
2424 HV
2425 *hv;
2426
2427 Image
2428 *image;
2429
2430 long
2431 stack;
2432
2433 register long
2434 i;
2435
2436 struct PackageInfo
2437 *info;
2438
2439 SV
2440 *av_reference,
2441 *perl_exception,
2442 *reference,
2443 *rv,
2444 *sv;
2445
2446 exception=AcquireExceptionInfo();
2447 perl_exception=newSVpv("",0);
2448 attribute=NULL;
2449 av=NULL;
2450 if (sv_isobject(ST(0)) == 0)
2451 {
2452 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2453 PackageName);
2454 goto PerlException;
2455 }
2456 reference=SvRV(ST(0));
2457 hv=SvSTASH(reference);
2458 av=newAV();
2459 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2460 SvREFCNT_dec(av);
2461 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2462 if (image == (Image *) NULL)
2463 {
2464 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2465 PackageName);
2466 goto PerlException;
2467 }
2468 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2469 /*
2470 Get options.
2471 */
2472 stack=MagickTrue;
2473 for (i=2; i < items; i+=2)
2474 {
2475 attribute=(char *) SvPV(ST(i-1),na);
2476 switch (*attribute)
2477 {
2478 case 'S':
2479 case 's':
2480 {
2481 if (LocaleCompare(attribute,"stack") == 0)
2482 {
2483 stack=ParseMagickOption(MagickBooleanOptions,MagickFalse,
2484 SvPV(ST(i),na));
2485 if (stack < 0)
2486 {
2487 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2488 SvPV(ST(i),na));
2489 return;
2490 }
2491 break;
2492 }
2493 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2494 attribute);
2495 break;
2496 }
2497 default:
2498 {
2499 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2500 attribute);
2501 break;
2502 }
2503 }
2504 }
2505 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2506 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2507 goto PerlException;
2508 for ( ; image; image=image->next)
2509 {
2510 AddImageToRegistry(image);
2511 rv=newRV(sv);
2512 av_push(av,sv_bless(rv,hv));
2513 SvREFCNT_dec(sv);
2514 }
2515 exception=DestroyExceptionInfo(exception);
2516 ST(0)=av_reference;
2517 SvREFCNT_dec(perl_exception);
2518 XSRETURN(1);
2519
2520 PerlException:
2521 InheritPerlException(exception,perl_exception);
2522 exception=DestroyExceptionInfo(exception);
2523 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2524 SvPOK_on(perl_exception);
2525 ST(0)=sv_2mortal(perl_exception);
2526 XSRETURN(1);
2527 }
2528
2529#
2530###############################################################################
2531# #
2532# #
2533# #
2534# A v e r a g e #
2535# #
2536# #
2537# #
2538###############################################################################
2539#
2540#
2541void
2542Average(ref)
2543 Image::Magick ref=NO_INIT
2544 ALIAS:
2545 AverageImage = 1
2546 average = 2
2547 averageimage = 3
2548 PPCODE:
2549 {
2550 AV
2551 *av;
2552
2553 char
2554 *p;
2555
2556 ExceptionInfo
2557 *exception;
2558
2559 HV
2560 *hv;
2561
2562 Image
2563 *image;
2564
2565 struct PackageInfo
2566 *info;
2567
2568 SV
2569 *perl_exception,
2570 *reference,
2571 *rv,
2572 *sv;
2573
2574 exception=AcquireExceptionInfo();
2575 perl_exception=newSVpv("",0);
2576 if (sv_isobject(ST(0)) == 0)
2577 {
2578 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2579 PackageName);
2580 goto PerlException;
2581 }
2582 reference=SvRV(ST(0));
2583 hv=SvSTASH(reference);
2584 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2585 if (image == (Image *) NULL)
2586 {
2587 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2588 PackageName);
2589 goto PerlException;
2590 }
2591 image=AverageImages(image,exception);
2592 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2593 goto PerlException;
2594 /*
2595 Create blessed Perl array for the returned image.
2596 */
2597 av=newAV();
2598 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2599 SvREFCNT_dec(av);
2600 AddImageToRegistry(image);
2601 rv=newRV(sv);
2602 av_push(av,sv_bless(rv,hv));
2603 SvREFCNT_dec(sv);
2604 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2605 (void) FormatMagickString(info->image_info->filename,MaxTextExtent,
2606 "average-%.*s",(int) (MaxTextExtent-9),
2607 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2608 (void) CopyMagickString(image->filename,info->image_info->filename,
2609 MaxTextExtent);
2610 SetImageInfo(info->image_info,MagickFalse,exception);
2611 exception=DestroyExceptionInfo(exception);
2612 SvREFCNT_dec(perl_exception);
2613 XSRETURN(1);
2614
2615 PerlException:
2616 InheritPerlException(exception,perl_exception);
2617 exception=DestroyExceptionInfo(exception);
2618 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2619 SvPOK_on(perl_exception);
2620 ST(0)=sv_2mortal(perl_exception);
2621 XSRETURN(1);
2622 }
2623
2624#
2625###############################################################################
2626# #
2627# #
2628# #
2629# B l o b T o I m a g e #
2630# #
2631# #
2632# #
2633###############################################################################
2634#
2635#
2636void
2637BlobToImage(ref,...)
2638 Image::Magick ref=NO_INIT
2639 ALIAS:
2640 BlobToImage = 1
2641 blobtoimage = 2
2642 blobto = 3
2643 PPCODE:
2644 {
2645 AV
2646 *av;
2647
2648 char
2649 **keep,
2650 **list;
2651
2652 ExceptionInfo
2653 *exception;
2654
2655 HV
2656 *hv;
2657
2658 Image
2659 *image;
2660
2661 long
2662 ac,
2663 n,
2664 number_images;
2665
2666 register char
2667 **p;
2668
2669 register long
2670 i;
2671
2672 STRLEN
2673 *length;
2674
2675 struct PackageInfo
2676 *info;
2677
2678 SV
2679 *perl_exception,
2680 *reference,
2681 *rv,
2682 *sv;
2683
2684 exception=AcquireExceptionInfo();
2685 perl_exception=newSVpv("",0);
2686 number_images=0;
2687 ac=(items < 2) ? 1 : items-1;
2688 length=(STRLEN *) NULL;
2689 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2690 if (list == (char **) NULL)
2691 {
2692 ThrowPerlException(exception,ResourceLimitError,
2693 "MemoryAllocationFailed",PackageName);
2694 goto PerlException;
2695 }
2696 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2697 if (length == (STRLEN *) NULL)
2698 {
2699 ThrowPerlException(exception,ResourceLimitError,
2700 "MemoryAllocationFailed",PackageName);
2701 goto PerlException;
2702 }
2703 if (sv_isobject(ST(0)) == 0)
2704 {
2705 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2706 PackageName);
2707 goto PerlException;
2708 }
2709 reference=SvRV(ST(0));
2710 hv=SvSTASH(reference);
2711 if (SvTYPE(reference) != SVt_PVAV)
2712 {
2713 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2714 PackageName);
2715 goto PerlException;
2716 }
2717 av=(AV *) reference;
2718 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2719 exception);
2720 n=1;
2721 if (items <= 1)
2722 {
2723 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2724 goto PerlException;
2725 }
2726 for (n=0, i=0; i < ac; i++)
2727 {
2728 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2729 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2730 {
2731 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2732 continue;
2733 }
2734 n++;
2735 }
2736 list[n]=(char *) NULL;
2737 keep=list;
2738 for (i=number_images=0; i < n; i++)
2739 {
2740 image=BlobToImage(info->image_info,list[i],length[i],exception);
2741 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2742 break;
2743 for ( ; image; image=image->next)
2744 {
2745 AddImageToRegistry(image);
2746 rv=newRV(sv);
2747 av_push(av,sv_bless(rv,hv));
2748 SvREFCNT_dec(sv);
2749 number_images++;
2750 }
2751 }
2752 /*
2753 Free resources.
2754 */
2755 for (i=0; i < n; i++)
2756 if (list[i] != (char *) NULL)
2757 for (p=keep; list[i] != *p++; )
2758 if (*p == (char *) NULL)
2759 {
2760 list[i]=(char *) RelinquishMagickMemory(list[i]);
2761 break;
2762 }
2763
2764 PerlException:
2765 if (list)
2766 list=(char **) RelinquishMagickMemory(list);
2767 if (length)
2768 length=(STRLEN *) RelinquishMagickMemory(length);
2769 InheritPerlException(exception,perl_exception);
2770 exception=DestroyExceptionInfo(exception);
2771 sv_setiv(perl_exception,(IV) number_images);
2772 SvPOK_on(perl_exception);
2773 ST(0)=sv_2mortal(perl_exception);
2774 XSRETURN(1);
2775 }
2776
2777#
2778###############################################################################
2779# #
2780# #
2781# #
2782# C l o n e #
2783# #
2784# #
2785# #
2786###############################################################################
2787#
2788#
2789void
2790Clone(ref)
2791 Image::Magick ref=NO_INIT
2792 ALIAS:
2793 CopyImage = 1
2794 copy = 2
2795 copyimage = 3
2796 CloneImage = 4
2797 clone = 5
2798 cloneimage = 6
2799 Clone = 7
2800 PPCODE:
2801 {
2802 AV
2803 *av;
2804
2805 ExceptionInfo
2806 *exception;
2807
2808 HV
2809 *hv;
2810
2811 Image
2812 *clone,
2813 *image;
2814
2815 struct PackageInfo
2816 *info;
2817
2818 SV
2819 *perl_exception,
2820 *reference,
2821 *rv,
2822 *sv;
2823
2824 exception=AcquireExceptionInfo();
2825 perl_exception=newSVpv("",0);
2826 if (sv_isobject(ST(0)) == 0)
2827 {
2828 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2829 PackageName);
2830 goto PerlException;
2831 }
2832 reference=SvRV(ST(0));
2833 hv=SvSTASH(reference);
2834 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2835 if (image == (Image *) NULL)
2836 {
2837 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2838 PackageName);
2839 goto PerlException;
2840 }
2841 /*
2842 Create blessed Perl array for the returned image.
2843 */
2844 av=newAV();
2845 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2846 SvREFCNT_dec(av);
2847 for ( ; image; image=image->next)
2848 {
2849 clone=CloneImage(image,0,0,MagickTrue,exception);
2850 if ((clone == (Image *) NULL) || (exception->severity >= ErrorException))
2851 break;
2852 AddImageToRegistry(clone);
2853 rv=newRV(sv);
2854 av_push(av,sv_bless(rv,hv));
2855 SvREFCNT_dec(sv);
2856 }
2857 exception=DestroyExceptionInfo(exception);
2858 SvREFCNT_dec(perl_exception);
2859 XSRETURN(1);
2860
2861 PerlException:
2862 InheritPerlException(exception,perl_exception);
2863 exception=DestroyExceptionInfo(exception);
2864 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2865 SvPOK_on(perl_exception);
2866 ST(0)=sv_2mortal(perl_exception);
2867 XSRETURN(1);
2868 }
2869
2870#
2871###############################################################################
2872# #
2873# #
2874# #
2875# C L O N E #
2876# #
2877# #
2878# #
2879###############################################################################
2880#
2881#
2882void
2883CLONE(ref,...)
2884 SV *ref;
2885 CODE:
2886 {
2887 if (magick_registry != (SplayTreeInfo *) NULL)
2888 {
2889 register Image
2890 *p;
2891
2892 ResetSplayTreeIterator(magick_registry);
2893 p=(Image *) GetNextKeyInSplayTree(magick_registry);
2894 while (p != (Image *) NULL)
2895 {
2896 ReferenceImage(p);
2897 p=(Image *) GetNextKeyInSplayTree(magick_registry);
2898 }
2899 }
2900 }
2901
2902#
2903###############################################################################
2904# #
2905# #
2906# #
2907# C o a l e s c e #
2908# #
2909# #
2910# #
2911###############################################################################
2912#
2913#
2914void
2915Coalesce(ref)
2916 Image::Magick ref=NO_INIT
2917 ALIAS:
2918 CoalesceImage = 1
2919 coalesce = 2
2920 coalesceimage = 3
2921 PPCODE:
2922 {
2923 AV
2924 *av;
2925
2926 ExceptionInfo
2927 *exception;
2928
2929 HV
2930 *hv;
2931
2932 Image
2933 *image;
2934
2935 struct PackageInfo
2936 *info;
2937
2938 SV
2939 *av_reference,
2940 *perl_exception,
2941 *reference,
2942 *rv,
2943 *sv;
2944
2945 exception=AcquireExceptionInfo();
2946 perl_exception=newSVpv("",0);
2947 if (sv_isobject(ST(0)) == 0)
2948 {
2949 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2950 PackageName);
2951 goto PerlException;
2952 }
2953 reference=SvRV(ST(0));
2954 hv=SvSTASH(reference);
2955 av=newAV();
2956 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2957 SvREFCNT_dec(av);
2958 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2959 if (image == (Image *) NULL)
2960 {
2961 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2962 PackageName);
2963 goto PerlException;
2964 }
2965 image=CoalesceImages(image,exception);
2966 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2967 goto PerlException;
2968 for ( ; image; image=image->next)
2969 {
2970 AddImageToRegistry(image);
2971 rv=newRV(sv);
2972 av_push(av,sv_bless(rv,hv));
2973 SvREFCNT_dec(sv);
2974 }
2975 exception=DestroyExceptionInfo(exception);
2976 ST(0)=av_reference;
2977 SvREFCNT_dec(perl_exception);
2978 XSRETURN(1);
2979
2980 PerlException:
2981 InheritPerlException(exception,perl_exception);
2982 exception=DestroyExceptionInfo(exception);
2983 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2984 SvPOK_on(perl_exception);
2985 ST(0)=sv_2mortal(perl_exception);
2986 XSRETURN(1);
2987 }
2988
2989#
2990###############################################################################
2991# #
2992# #
2993# #
2994# C o m p a r e #
2995# #
2996# #
2997# #
2998###############################################################################
2999#
3000#
3001void
3002Compare(ref,...)
3003 Image::Magick ref=NO_INIT
3004 ALIAS:
3005 CompareImage = 1
3006 compare = 2
3007 compareimage = 3
3008 PPCODE:
3009 {
3010 AV
3011 *av;
3012
3013 char
3014 *attribute;
3015
3016 ChannelType
3017 channel;
3018
3019 double
3020 distortion;
3021
3022 ExceptionInfo
3023 *exception;
3024
3025 HV
3026 *hv;
3027
3028 Image
3029 *difference_image,
3030 *image,
3031 *reconstruct_image;
3032
3033 long
3034 option;
3035
3036 MetricType
3037 metric;
3038
3039 register long
3040 i;
3041
3042 struct PackageInfo
3043 *info;
3044
3045 SV
3046 *av_reference,
3047 *perl_exception,
3048 *reference,
3049 *rv,
3050 *sv;
3051
3052 exception=AcquireExceptionInfo();
3053 perl_exception=newSVpv("",0);
3054 av=NULL;
3055 attribute=NULL;
3056 if (sv_isobject(ST(0)) == 0)
3057 {
3058 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3059 PackageName);
3060 goto PerlException;
3061 }
3062 reference=SvRV(ST(0));
3063 hv=SvSTASH(reference);
3064 av=newAV();
3065 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3066 SvREFCNT_dec(av);
3067 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3068 if (image == (Image *) NULL)
3069 {
3070 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3071 PackageName);
3072 goto PerlException;
3073 }
3074 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3075 /*
3076 Get attribute.
3077 */
3078 channel=DefaultChannels;
3079 reconstruct_image=image;
3080 metric=RootMeanSquaredErrorMetric;
3081 for (i=2; i < items; i+=2)
3082 {
3083 attribute=(char *) SvPV(ST(i-1),na);
3084 switch (*attribute)
3085 {
3086 case 'C':
3087 case 'c':
3088 {
3089 if (LocaleCompare(attribute,"channel") == 0)
3090 {
3091 long
3092 option;
3093
3094 option=ParseChannelOption(SvPV(ST(i),na));
3095 if (option < 0)
3096 {
3097 ThrowPerlException(exception,OptionError,
3098 "UnrecognizedType",SvPV(ST(i),na));
3099 return;
3100 }
3101 channel=(ChannelType) option;
3102 break;
3103 }
3104 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3105 attribute);
3106 break;
3107 }
3108 case 'F':
3109 case 'f':
3110 {
3111 if (LocaleCompare(attribute,"fuzz") == 0)
3112 {
3113 image->fuzz=StringToDouble(SvPV(ST(i),na),100.0);
3114 break;
3115 }
3116 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3117 attribute);
3118 break;
3119 }
3120 case 'I':
3121 case 'i':
3122 {
3123 if (LocaleCompare(attribute,"image") == 0)
3124 {
3125 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3126 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3127 }
3128 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3129 attribute);
3130 break;
3131 }
3132 case 'M':
3133 case 'm':
3134 {
3135 if (LocaleCompare(attribute,"metric") == 0)
3136 {
3137 option=ParseMagickOption(MagickMetricOptions,MagickFalse,
3138 SvPV(ST(i),na));
3139 if (option < 0)
3140 {
3141 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3142 SvPV(ST(i),na));
3143 break;
3144 }
3145 metric=(MetricType) option;
3146 break;
3147 }
3148 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3149 attribute);
3150 break;
3151 }
3152 default:
3153 {
3154 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3155 attribute);
3156 break;
3157 }
3158 }
3159 }
3160 difference_image=CompareImageChannels(image,reconstruct_image,channel,
3161 metric,&distortion,exception);
3162 if (difference_image != (Image *) NULL)
3163 {
3164 difference_image->error.mean_error_per_pixel=distortion;
3165 AddImageToRegistry(difference_image);
3166 rv=newRV(sv);
3167 av_push(av,sv_bless(rv,hv));
3168 SvREFCNT_dec(sv);
3169 }
3170 exception=DestroyExceptionInfo(exception);
3171 ST(0)=av_reference;
3172 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3173 XSRETURN(1);
3174
3175 PerlException:
3176 InheritPerlException(exception,perl_exception);
3177 exception=DestroyExceptionInfo(exception);
3178 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3179 SvPOK_on(perl_exception);
3180 ST(0)=sv_2mortal(perl_exception);
3181 XSRETURN(1);
3182 }
3183
3184#
3185###############################################################################
3186# #
3187# #
3188# #
3189# C o m p a r e L a y e r s #
3190# #
3191# #
3192# #
3193###############################################################################
3194#
3195#
3196void
3197CompareLayers(ref)
3198 Image::Magick ref=NO_INIT
3199 ALIAS:
3200 CompareImageLayers = 1
3201 comparelayers = 2
3202 compareimagelayers = 3
3203 PPCODE:
3204 {
3205 AV
3206 *av;
3207
3208 char
3209 *attribute;
3210
3211 ExceptionInfo
3212 *exception;
3213
3214 HV
3215 *hv;
3216
3217 Image
3218 *image;
3219
3220 long
3221 option;
3222
3223 ImageLayerMethod
3224 method;
3225
3226 register long
3227 i;
3228
3229 struct PackageInfo
3230 *info;
3231
3232 SV
3233 *av_reference,
3234 *perl_exception,
3235 *reference,
3236 *rv,
3237 *sv;
3238
3239 exception=AcquireExceptionInfo();
3240 perl_exception=newSVpv("",0);
3241 if (sv_isobject(ST(0)) == 0)
3242 {
3243 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3244 PackageName);
3245 goto PerlException;
3246 }
3247 reference=SvRV(ST(0));
3248 hv=SvSTASH(reference);
3249 av=newAV();
3250 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3251 SvREFCNT_dec(av);
3252 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3253 if (image == (Image *) NULL)
3254 {
3255 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3256 PackageName);
3257 goto PerlException;
3258 }
3259 method=CompareAnyLayer;
3260 for (i=2; i < items; i+=2)
3261 {
3262 attribute=(char *) SvPV(ST(i-1),na);
3263 switch (*attribute)
3264 {
3265 case 'M':
3266 case 'm':
3267 {
3268 if (LocaleCompare(attribute,"method") == 0)
3269 {
3270 option=ParseMagickOption(MagickLayerOptions,MagickFalse,
3271 SvPV(ST(i),na));
3272 if (option < 0)
3273 {
3274 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3275 SvPV(ST(i),na));
3276 break;
3277 }
3278 method=(ImageLayerMethod) option;
3279 break;
3280 }
3281 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3282 attribute);
3283 break;
3284 }
3285 default:
3286 {
3287 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3288 attribute);
3289 break;
3290 }
3291 }
3292 }
3293 image=CompareImageLayers(image,method,exception);
3294 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
3295 goto PerlException;
3296 for ( ; image; image=image->next)
3297 {
3298 AddImageToRegistry(image);
3299 rv=newRV(sv);
3300 av_push(av,sv_bless(rv,hv));
3301 SvREFCNT_dec(sv);
3302 }
3303 exception=DestroyExceptionInfo(exception);
3304 ST(0)=av_reference;
3305 SvREFCNT_dec(perl_exception);
3306 XSRETURN(1);
3307
3308 PerlException:
3309 InheritPerlException(exception,perl_exception);
3310 exception=DestroyExceptionInfo(exception);
3311 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3312 SvPOK_on(perl_exception);
3313 ST(0)=sv_2mortal(perl_exception);
3314 XSRETURN(1);
3315 }
3316
3317#
3318###############################################################################
3319# #
3320# #
3321# #
3322# D e s t r o y #
3323# #
3324# #
3325# #
3326###############################################################################
3327#
3328#
3329void
3330DESTROY(ref)
3331 Image::Magick ref=NO_INIT
3332 PPCODE:
3333 {
3334 SV
3335 *reference;
3336
3337 if (sv_isobject(ST(0)) == 0)
3338 croak("ReferenceIsNotMyType");
3339 reference=SvRV(ST(0));
3340 switch (SvTYPE(reference))
3341 {
3342 case SVt_PVAV:
3343 {
3344 char
3345 message[MaxTextExtent];
3346
3347 struct PackageInfo
3348 *info;
3349
3350 HV
3351 *hv;
3352
3353 GV
3354 **gvp;
3355
3356 SV
3357 *sv;
3358
3359 /*
3360 Array (AV *) reference
3361 */
3362 (void) FormatMagickString(message,MaxTextExtent,"package%s%lx",
3363 XS_VERSION,(long) reference);
3364 hv=gv_stashpv(PackageName, FALSE);
3365 if (!hv)
3366 break;
3367 gvp=(GV **) hv_fetch(hv,message,strlen(message),FALSE);
3368 if (!gvp)
3369 break;
3370 sv=GvSV(*gvp);
3371 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3372 {
3373 info=(struct PackageInfo *) SvIV(sv);
3374 DestroyPackageInfo(info);
3375 }
3376 hv_delete(hv,message,strlen(message),G_DISCARD);
3377 break;
3378 }
3379 case SVt_PVMG:
3380 {
3381 Image
3382 *image;
3383
3384 /*
3385 Blessed scalar = (Image *) SvIV(reference)
3386 */
3387 image=(Image *) SvIV(reference);
3388 if (image != (Image *) NULL)
3389 DeleteImageFromRegistry(reference,image);
3390 break;
3391 }
3392 default:
3393 break;
3394 }
3395 }
3396
3397#
3398###############################################################################
3399# #
3400# #
3401# #
3402# D i s p l a y #
3403# #
3404# #
3405# #
3406###############################################################################
3407#
3408#
3409void
3410Display(ref,...)
3411 Image::Magick ref=NO_INIT
3412 ALIAS:
3413 DisplayImage = 1
3414 display = 2
3415 displayimage = 3
3416 PPCODE:
3417 {
3418 ExceptionInfo
3419 *exception;
3420
3421 Image
3422 *image;
3423
3424 register long
3425 i;
3426
3427 struct PackageInfo
3428 *info,
3429 *package_info;
3430
3431 SV
3432 *perl_exception,
3433 *reference;
3434
3435 exception=AcquireExceptionInfo();
3436 perl_exception=newSVpv("",0);
3437 package_info=(struct PackageInfo *) NULL;
3438 if (sv_isobject(ST(0)) == 0)
3439 {
3440 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3441 PackageName);
3442 goto PerlException;
3443 }
3444 reference=SvRV(ST(0));
3445 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3446 if (image == (Image *) NULL)
3447 {
3448 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3449 PackageName);
3450 goto PerlException;
3451 }
3452 package_info=ClonePackageInfo(info,exception);
3453 if (items == 2)
3454 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3455 else
3456 if (items > 2)
3457 for (i=2; i < items; i+=2)
3458 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3459 exception);
3460 (void) DisplayImages(package_info->image_info,image);
3461 (void) CatchImageException(image);
3462 InheritException(exception,&image->exception);
3463
3464 PerlException:
3465 if (package_info != (struct PackageInfo *) NULL)
3466 DestroyPackageInfo(package_info);
3467 InheritPerlException(exception,perl_exception);
3468 exception=DestroyExceptionInfo(exception);
3469 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3470 SvPOK_on(perl_exception);
3471 ST(0)=sv_2mortal(perl_exception);
3472 XSRETURN(1);
3473 }
3474
3475#
3476###############################################################################
3477# #
3478# #
3479# #
3480# F l a t t e n #
3481# #
3482# #
3483# #
3484###############################################################################
3485#
3486#
3487void
3488Flatten(ref)
3489 Image::Magick ref=NO_INIT
3490 ALIAS:
3491 FlattenImage = 1
3492 flatten = 2
3493 flattenimage = 3
3494 PPCODE:
3495 {
3496 AV
3497 *av;
3498
3499 char
3500 *attribute,
3501 *p;
3502
3503 ExceptionInfo
3504 *exception;
3505
3506 HV
3507 *hv;
3508
3509 Image
3510 *image;
3511
3512 PixelPacket
3513 background_color;
3514
3515 register long
3516 i;
3517
3518 struct PackageInfo
3519 *info;
3520
3521 SV
3522 *perl_exception,
3523 *reference,
3524 *rv,
3525 *sv;
3526
3527 exception=AcquireExceptionInfo();
3528 perl_exception=newSVpv("",0);
3529 if (sv_isobject(ST(0)) == 0)
3530 {
3531 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3532 PackageName);
3533 goto PerlException;
3534 }
3535 reference=SvRV(ST(0));
3536 hv=SvSTASH(reference);
3537 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3538 if (image == (Image *) NULL)
3539 {
3540 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3541 PackageName);
3542 goto PerlException;
3543 }
3544 background_color=image->background_color;
3545 if (items == 2)
3546 (void) QueryColorDatabase((char *) SvPV(ST(1),na),&background_color,
3547 exception);
3548 else
3549 for (i=2; i < items; i+=2)
3550 {
3551 attribute=(char *) SvPV(ST(i-1),na);
3552 switch (*attribute)
3553 {
3554 case 'B':
3555 case 'b':
3556 {
3557 if (LocaleCompare(attribute,"background") == 0)
3558 {
3559 (void) QueryColorDatabase((char *) SvPV(ST(1),na),
3560 &background_color,exception);
3561 break;
3562 }
3563 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3564 attribute);
3565 break;
3566 }
3567 default:
3568 {
3569 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3570 attribute);
3571 break;
3572 }
3573 }
3574 }
3575 image->background_color=background_color;
3576 image=MergeImageLayers(image,FlattenLayer,exception);
3577 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
3578 goto PerlException;
3579 /*
3580 Create blessed Perl array for the returned image.
3581 */
3582 av=newAV();
3583 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3584 SvREFCNT_dec(av);
3585 AddImageToRegistry(image);
3586 rv=newRV(sv);
3587 av_push(av,sv_bless(rv,hv));
3588 SvREFCNT_dec(sv);
3589 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3590 (void) FormatMagickString(info->image_info->filename,MaxTextExtent,
3591 "flatten-%.*s",(int) (MaxTextExtent-9),
3592 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3593 (void) CopyMagickString(image->filename,info->image_info->filename,
3594 MaxTextExtent);
3595 SetImageInfo(info->image_info,MagickFalse,exception);
3596 exception=DestroyExceptionInfo(exception);
3597 SvREFCNT_dec(perl_exception);
3598 XSRETURN(1);
3599
3600 PerlException:
3601 InheritPerlException(exception,perl_exception);
3602 exception=DestroyExceptionInfo(exception);
3603 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3604 SvPOK_on(perl_exception); /* return messages in string context */
3605 ST(0)=sv_2mortal(perl_exception);
3606 XSRETURN(1);
3607 }
3608
3609#
3610###############################################################################
3611# #
3612# #
3613# #
3614# F x #
3615# #
3616# #
3617# #
3618###############################################################################
3619#
3620#
3621void
3622Fx(ref,...)
3623 Image::Magick ref=NO_INIT
3624 ALIAS:
3625 FxImage = 1
3626 fx = 2
3627 fximage = 3
3628 PPCODE:
3629 {
3630 AV
3631 *av;
3632
3633 char
3634 *attribute,
3635 expression[MaxTextExtent];
3636
3637 ChannelType
3638 channel;
3639
3640 ExceptionInfo
3641 *exception;
3642
3643 HV
3644 *hv;
3645
3646 Image
3647 *image;
3648
3649 register long
3650 i;
3651
3652 struct PackageInfo
3653 *info;
3654
3655 SV
3656 *av_reference,
3657 *perl_exception,
3658 *reference,
3659 *rv,
3660 *sv;
3661
3662 exception=AcquireExceptionInfo();
3663 perl_exception=newSVpv("",0);
3664 attribute=NULL;
3665 av=NULL;
3666 if (sv_isobject(ST(0)) == 0)
3667 {
3668 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3669 PackageName);
3670 goto PerlException;
3671 }
3672 reference=SvRV(ST(0));
3673 hv=SvSTASH(reference);
3674 av=newAV();
3675 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3676 SvREFCNT_dec(av);
3677 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3678 if (image == (Image *) NULL)
3679 {
3680 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3681 PackageName);
3682 goto PerlException;
3683 }
3684 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3685 /*
3686 Get options.
3687 */
3688 channel=DefaultChannels;
3689 (void) CopyMagickString(expression,"u",MaxTextExtent);
3690 if (items == 2)
3691 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MaxTextExtent);
3692 else
3693 for (i=2; i < items; i+=2)
3694 {
3695 attribute=(char *) SvPV(ST(i-1),na);
3696 switch (*attribute)
3697 {
3698 case 'C':
3699 case 'c':
3700 {
3701 if (LocaleCompare(attribute,"channel") == 0)
3702 {
3703 long
3704 option;
3705
3706 option=ParseChannelOption(SvPV(ST(i),na));
3707 if (option < 0)
3708 {
3709 ThrowPerlException(exception,OptionError,
3710 "UnrecognizedType",SvPV(ST(i),na));
3711 return;
3712 }
3713 channel=(ChannelType) option;
3714 break;
3715 }
3716 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3717 attribute);
3718 break;
3719 }
3720 case 'E':
3721 case 'e':
3722 {
3723 if (LocaleCompare(attribute,"expression") == 0)
3724 {
3725 (void) CopyMagickString(expression,SvPV(ST(i),na),
3726 MaxTextExtent);
3727 break;
3728 }
3729 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3730 attribute);
3731 break;
3732 }
3733 default:
3734 {
3735 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3736 attribute);
3737 break;
3738 }
3739 }
3740 }
3741 image=FxImageChannel(image,channel,expression,exception);
3742 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
3743 goto PerlException;
3744 for ( ; image; image=image->next)
3745 {
3746 AddImageToRegistry(image);
3747 rv=newRV(sv);
3748 av_push(av,sv_bless(rv,hv));
3749 SvREFCNT_dec(sv);
3750 }
3751 exception=DestroyExceptionInfo(exception);
3752 ST(0)=av_reference;
3753 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3754 XSRETURN(1);
3755
3756 PerlException:
3757 InheritPerlException(exception,perl_exception);
3758 exception=DestroyExceptionInfo(exception);
3759 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3760 SvPOK_on(perl_exception);
3761 ST(0)=sv_2mortal(perl_exception);
3762 XSRETURN(1);
3763 }
3764
3765#
3766###############################################################################
3767# #
3768# #
3769# #
3770# G e t #
3771# #
3772# #
3773# #
3774###############################################################################
3775#
3776#
3777void
3778Get(ref,...)
3779 Image::Magick ref=NO_INIT
3780 ALIAS:
3781 GetAttributes = 1
3782 GetAttribute = 2
3783 get = 3
3784 getattributes = 4
3785 getattribute = 5
3786 PPCODE:
3787 {
3788 char
3789 *attribute,
3790 color[MaxTextExtent];
3791
3792 const char
3793 *value;
3794
3795 ExceptionInfo
3796 *exception;
3797
3798 Image
3799 *image;
3800
3801 long
3802 j;
3803
3804 register long
3805 i;
3806
3807 struct PackageInfo
3808 *info;
3809
3810 SV
3811 *perl_exception,
3812 *reference,
3813 *s;
3814
3815 exception=AcquireExceptionInfo();
3816 perl_exception=newSVpv("",0);
3817 if (sv_isobject(ST(0)) == 0)
3818 {
3819 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3820 PackageName);
3821 XSRETURN_EMPTY;
3822 }
3823 reference=SvRV(ST(0));
3824 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3825 if (image == (Image *) NULL && !info)
3826 XSRETURN_EMPTY;
3827 EXTEND(sp,items);
3828 for (i=1; i < items; i++)
3829 {
3830 attribute=(char *) SvPV(ST(i),na);
3831 s=NULL;
3832 switch (*attribute)
3833 {
3834 case 'A':
3835 case 'a':
3836 {
3837 if (LocaleCompare(attribute,"adjoin") == 0)
3838 {
3839 if (info)
3840 s=newSViv((long) info->image_info->adjoin);
3841 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3842 continue;
3843 }
3844 if (LocaleCompare(attribute,"antialias") == 0)
3845 {
3846 if (info)
3847 s=newSViv((long) info->image_info->antialias);
3848 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3849 continue;
3850 }
3851 if (LocaleCompare(attribute,"area") == 0)
3852 {
3853 s=newSViv(GetMagickResource(AreaResource));
3854 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3855 continue;
3856 }
3857 if (LocaleCompare(attribute,"attenuate") == 0)
3858 {
3859 const char
3860 *value;
3861
3862 value=GetImageProperty(image,attribute);
3863 if (value != (const char *) NULL)
3864 s=newSVpv(value,0);
3865 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3866 continue;
3867 }
3868 if (LocaleCompare(attribute,"authenticate") == 0)
3869 {
3870 if (info)
3871 s=newSVpv(info->image_info->authenticate,0);
3872 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3873 continue;
3874 }
3875 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3876 attribute);
3877 break;
3878 }
3879 case 'B':
3880 case 'b':
3881 {
3882 if (LocaleCompare(attribute,"background") == 0)
3883 {
3884 if (image == (Image *) NULL)
3885 break;
3886 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
3887 QuantumFormat "," QuantumFormat "," QuantumFormat,
3888 image->background_color.red,image->background_color.green,
3889 image->background_color.blue,image->background_color.opacity);
3890 s=newSVpv(color,0);
3891 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3892 continue;
3893 }
3894 if (LocaleCompare(attribute,"base-columns") == 0)
3895 {
3896 if (image != (Image *) NULL)
3897 s=newSViv((long) image->magick_columns);
3898 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3899 continue;
3900 }
3901 if (LocaleCompare(attribute,"base-filename") == 0)
3902 {
3903 if (image != (Image *) NULL)
3904 s=newSVpv(image->magick_filename,0);
3905 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3906 continue;
3907 }
3908 if (LocaleCompare(attribute,"base-height") == 0)
3909 {
3910 if (image != (Image *) NULL)
3911 s=newSViv((long) image->magick_rows);
3912 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3913 continue;
3914 }
3915 if (LocaleCompare(attribute,"base-rows") == 0)
3916 {
3917 if (image != (Image *) NULL)
3918 s=newSViv((long) image->magick_rows);
3919 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3920 continue;
3921 }
3922 if (LocaleCompare(attribute,"base-width") == 0)
3923 {
3924 if (image != (Image *) NULL)
3925 s=newSViv((long) image->magick_columns);
3926 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3927 continue;
3928 }
3929 if (LocaleCompare(attribute,"bias") == 0)
3930 {
3931 if (image != (Image *) NULL)
3932 s=newSVnv(image->bias);
3933 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3934 continue;
3935 }
3936 if (LocaleCompare(attribute,"blue-primary") == 0)
3937 {
3938 if (image == (Image *) NULL)
3939 break;
3940 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
3941 image->chromaticity.blue_primary.x,
3942 image->chromaticity.blue_primary.y);
3943 s=newSVpv(color,0);
3944 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3945 continue;
3946 }
3947 if (LocaleCompare(attribute,"bordercolor") == 0)
3948 {
3949 if (image == (Image *) NULL)
3950 break;
3951 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
3952 QuantumFormat "," QuantumFormat "," QuantumFormat,
3953 image->border_color.red,image->border_color.green,
3954 image->border_color.blue,image->border_color.opacity);
3955 s=newSVpv(color,0);
3956 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3957 continue;
3958 }
3959 if (LocaleCompare(attribute,"bounding-box") == 0)
3960 {
3961 char
3962 geometry[MaxTextExtent];
3963
3964 RectangleInfo
3965 page;
3966
3967 if (image == (Image *) NULL)
3968 break;
3969 page=GetImageBoundingBox(image,&image->exception);
3970 (void) FormatMagickString(geometry,MaxTextExtent,
3971 "%lux%lu%+ld%+ld",page.width,page.height,page.x,page.y);
3972 s=newSVpv(geometry,0);
3973 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3974 continue;
3975 }
3976 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3977 attribute);
3978 break;
3979 }
3980 case 'C':
3981 case 'c':
3982 {
3983 if (LocaleCompare(attribute,"class") == 0)
3984 {
3985 if (image == (Image *) NULL)
3986 break;
3987 s=newSViv(image->storage_class);
3988 (void) sv_setpv(s,MagickOptionToMnemonic(MagickClassOptions,
3989 image->storage_class));
3990 SvIOK_on(s);
3991 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3992 continue;
3993 }
3994 if (LocaleCompare(attribute,"clip-mask") == 0)
3995 {
3996 if (image != (Image *) NULL)
3997 {
3998 SV
3999 *sv;
4000
4001 if (image->mask == (Image *) NULL)
4002 ClipImage(image);
4003 if (image->mask != (Image *) NULL)
4004 {
4005 AddImageToRegistry(image->mask);
4006 s=sv_bless(newRV(sv),SvSTASH(reference));
4007 }
4008 }
4009 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4010 continue;
4011 }
4012 if (LocaleCompare(attribute,"clip-path") == 0)
4013 {
4014 if (image != (Image *) NULL)
4015 {
4016 SV
4017 *sv;
4018
4019 if (image->clip_mask == (Image *) NULL)
4020 ClipImage(image);
4021 if (image->clip_mask != (Image *) NULL)
4022 {
4023 AddImageToRegistry(image->clip_mask);
4024 s=sv_bless(newRV(sv),SvSTASH(reference));
4025 }
4026 }
4027 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4028 continue;
4029 }
4030 if (LocaleCompare(attribute,"compression") == 0)
4031 {
4032 j=info ? info->image_info->compression : image->compression;
4033 if (info)
4034 if (info->image_info->compression == UndefinedCompression)
4035 j=image->compression;
4036 s=newSViv(j);
4037 (void) sv_setpv(s,MagickOptionToMnemonic(MagickCompressOptions,
4038 j));
4039 SvIOK_on(s);
4040 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4041 continue;
4042 }
4043 if (LocaleCompare(attribute,"colorspace") == 0)
4044 {
4045 j=image ? image->colorspace : RGBColorspace;
4046 s=newSViv(j);
4047 (void) sv_setpv(s,MagickOptionToMnemonic(MagickColorspaceOptions,
4048 j));
4049 SvIOK_on(s);
4050 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4051 continue;
4052 }
4053 if (LocaleCompare(attribute,"colors") == 0)
4054 {
4055 if (image != (Image *) NULL)
4056 s=newSViv((long) GetNumberColors(image,(FILE *) NULL,
4057 &image->exception));
4058 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4059 continue;
4060 }
4061 if (LocaleNCompare(attribute,"colormap",8) == 0)
4062 {
4063 int
4064 items;
4065
4066 if (image == (Image *) NULL || !image->colormap)
4067 break;
4068 j=0;
4069 items=sscanf(attribute,"%*[^[][%ld",&j);
4070 if (j > (long) image->colors)
4071 j%=image->colors;
4072 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
4073 QuantumFormat "," QuantumFormat "," QuantumFormat,
4074 image->colormap[j].red,image->colormap[j].green,
4075 image->colormap[j].blue,image->colormap[j].opacity);
4076 s=newSVpv(color,0);
4077 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4078 continue;
4079 }
4080 if (LocaleCompare(attribute,"columns") == 0)
4081 {
4082 if (image != (Image *) NULL)
4083 s=newSViv((long) image->columns);
4084 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4085 continue;
4086 }
4087 if (LocaleCompare(attribute,"comment") == 0)
4088 {
4089 const char
4090 *value;
4091
4092 value=GetImageProperty(image,attribute);
4093 if (value != (const char *) NULL)
4094 s=newSVpv(value,0);
4095 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4096 continue;
4097 }
4098 if (LocaleCompare(attribute,"copyright") == 0)
4099 {
4100 s=newSVpv(GetMagickCopyright(),0);
4101 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4102 continue;
4103 }
4104 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4105 attribute);
4106 break;
4107 }
4108 case 'D':
4109 case 'd':
4110 {
4111 if (LocaleCompare(attribute,"density") == 0)
4112 {
4113 char
4114 geometry[MaxTextExtent];
4115
4116 if (image == (Image *) NULL)
4117 break;
4118 (void) FormatMagickString(geometry,MaxTextExtent,"%gx%g",
4119 image->x_resolution,image->y_resolution);
4120 s=newSVpv(geometry,0);
4121 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4122 continue;
4123 }
4124 if (LocaleCompare(attribute,"dispose") == 0)
4125 {
4126 if (image == (Image *) NULL)
4127 break;
4128
4129 s=newSViv(image->dispose);
4130 (void) sv_setpv(s,
4131 MagickOptionToMnemonic(MagickDisposeOptions,image->dispose));
4132 SvIOK_on(s);
4133 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4134 continue;
4135 }
4136 if (LocaleCompare(attribute,"delay") == 0)
4137 {
4138 if (image != (Image *) NULL)
4139 s=newSViv((long) image->delay);
4140 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4141 continue;
4142 }
4143 if (LocaleCompare(attribute,"depth") == 0)
4144 {
4145 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4146 if (image != (Image *) NULL)
4147 s=newSViv((long) GetImageDepth(image,&image->exception));
4148 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4149 continue;
4150 }
4151 if (LocaleCompare(attribute,"disk") == 0)
4152 {
4153 s=newSViv(GetMagickResource(DiskResource));
4154 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4155 continue;
4156 }
4157 if (LocaleCompare(attribute,"dither") == 0)
4158 {
4159 if (info)
4160 s=newSViv((long) info->image_info->dither);
4161 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4162 continue;
4163 }
4164 if (LocaleCompare(attribute,"display") == 0) /* same as server */
4165 {
4166 if (info && info->image_info->server_name)
4167 s=newSVpv(info->image_info->server_name,0);
4168 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4169 continue;
4170 }
4171 if (LocaleCompare(attribute,"directory") == 0)
4172 {
4173 if (image && image->directory)
4174 s=newSVpv(image->directory,0);
4175 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4176 continue;
4177 }
4178 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4179 attribute);
4180 break;
4181 }
4182 case 'E':
4183 case 'e':
4184 {
4185 if (LocaleCompare(attribute,"elapsed-time") == 0)
4186 {
4187 if (image != (Image *) NULL)
4188 s=newSVnv(GetElapsedTime(&image->timer));
4189 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4190 continue;
4191 }
4192 if (LocaleCompare(attribute,"endian") == 0)
4193 {
4194 j=info ? info->image_info->endian : image->endian;
4195 s=newSViv(j);
4196 (void) sv_setpv(s,MagickOptionToMnemonic(MagickEndianOptions,j));
4197 SvIOK_on(s);
4198 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4199 continue;
4200 }
4201 if (LocaleCompare(attribute,"error") == 0)
4202 {
4203 if (image != (Image *) NULL)
4204 s=newSVnv(image->error.mean_error_per_pixel);
4205 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4206 continue;
4207 }
4208 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4209 attribute);
4210 break;
4211 }
4212 case 'F':
4213 case 'f':
4214 {
4215 if (LocaleCompare(attribute,"filesize") == 0)
4216 {
4217 if (image != (Image *) NULL)
4218 s=newSViv((long) GetBlobSize(image));
4219 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4220 continue;
4221 }
4222 if (LocaleCompare(attribute,"filename") == 0)
4223 {
4224 if (info && info->image_info->filename &&
4225 *info->image_info->filename)
4226 s=newSVpv(info->image_info->filename,0);
4227 if (image != (Image *) NULL)
4228 s=newSVpv(image->filename,0);
4229 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4230 continue;
4231 }
4232 if (LocaleCompare(attribute,"filter") == 0)
4233 {
4234 s=newSViv(image->filter);
4235 (void) sv_setpv(s,MagickOptionToMnemonic(MagickFilterOptions,
4236 image->filter));
4237 SvIOK_on(s);
4238 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4239 continue;
4240 }
4241 if (LocaleCompare(attribute,"font") == 0)
4242 {
4243 if (info && info->image_info->font)
4244 s=newSVpv(info->image_info->font,0);
4245 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4246 continue;
4247 }
4248 if (LocaleCompare(attribute,"foreground") == 0)
4249 continue;
4250 if (LocaleCompare(attribute,"format") == 0)
4251 {
4252 const MagickInfo
4253 *magick_info;
4254
4255 magick_info=(const MagickInfo *) NULL;
4256 if (info && (*info->image_info->magick != '\0'))
4257 magick_info=GetMagickInfo(info->image_info->magick,exception);
4258 if (image != (Image *) NULL)
4259 magick_info=GetMagickInfo(image->magick,&image->exception);
4260 if ((magick_info != (const MagickInfo *) NULL) &&
4261 (*magick_info->description != '\0'))
4262 s=newSVpv((char *) magick_info->description,0);
4263 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4264 continue;
4265 }
4266 if (LocaleCompare(attribute,"fuzz") == 0)
4267 {
4268 if (info)
4269 s=newSVnv(info->image_info->fuzz);
4270 if (image != (Image *) NULL)
4271 s=newSVnv(image->fuzz);
4272 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4273 continue;
4274 }
4275 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4276 attribute);
4277 break;
4278 }
4279 case 'G':
4280 case 'g':
4281 {
4282 if (LocaleCompare(attribute,"gamma") == 0)
4283 {
4284 if (image != (Image *) NULL)
4285 s=newSVnv(image->gamma);
4286 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4287 continue;
4288 }
4289 if (LocaleCompare(attribute,"geometry") == 0)
4290 {
4291 if (image && image->geometry)
4292 s=newSVpv(image->geometry,0);
4293 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4294 continue;
4295 }
4296 if (LocaleCompare(attribute,"gravity") == 0)
4297 {
4298 s=newSViv(image->gravity);
4299 (void) sv_setpv(s,
4300 MagickOptionToMnemonic(MagickGravityOptions,image->gravity));
4301 SvIOK_on(s);
4302 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4303 continue;
4304 }
4305 if (LocaleCompare(attribute,"green-primary") == 0)
4306 {
4307 if (image == (Image *) NULL)
4308 break;
4309 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
4310 image->chromaticity.green_primary.x,
4311 image->chromaticity.green_primary.y);
4312 s=newSVpv(color,0);
4313 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4314 continue;
4315 }
4316 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4317 attribute);
4318 break;
4319 }
4320 case 'H':
4321 case 'h':
4322 {
4323 if (LocaleCompare(attribute,"height") == 0)
4324 {
4325 if (image != (Image *) NULL)
4326 s=newSViv((long) image->rows);
4327 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4328 continue;
4329 }
4330 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4331 attribute);
4332 break;
4333 }
4334 case 'I':
4335 case 'i':
4336 {
4337 if (LocaleCompare(attribute,"icc") == 0)
4338 {
4339 if (image != (Image *) NULL)
4340 {
4341 const StringInfo
4342 *profile;
4343
4344 profile=GetImageProfile(image,"icc");
4345 if (profile != (StringInfo *) NULL)
4346 s=newSVpv((const char *) GetStringInfoDatum(profile),
4347 GetStringInfoLength(profile));
4348 }
4349 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4350 continue;
4351 }
4352 if (LocaleCompare(attribute,"icm") == 0)
4353 {
4354 if (image != (Image *) NULL)
4355 {
4356 const StringInfo
4357 *profile;
4358
4359 profile=GetImageProfile(image,"icm");
4360 if (profile != (const StringInfo *) NULL)
4361 s=newSVpv((const char *) GetStringInfoDatum(profile),
4362 GetStringInfoLength(profile));
4363 }
4364 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4365 continue;
4366 }
4367 if (LocaleCompare(attribute,"id") == 0)
4368 {
4369 if (image != (Image *) NULL)
4370 s=newSViv(SetMagickRegistry(ImageRegistryType,image,0,
4371 &image->exception));
4372 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4373 continue;
4374 }
4375 if (LocaleNCompare(attribute,"index",5) == 0)
4376 {
4377 char
4378 name[MaxTextExtent];
4379
4380 int
4381 items;
4382
4383 long
4384 x,
4385 y;
4386
4387 register const IndexPacket
4388 *indexes;
4389
4390 register const PixelPacket
4391 *p;
4392
4393 CacheView
4394 *image_view;
4395
4396 if (image == (Image *) NULL)
4397 break;
4398 if (image->storage_class != PseudoClass)
4399 break;
4400 x=0;
4401 y=0;
4402 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
4403 image_view=OpenCacheView(image);
4404 p=AcquireCacheViewPixels(image_view,x,y,1,1,&image->exception);
4405 if (p != (const PixelPacket *) NULL)
4406 {
4407 indexes=AcquireCacheViewIndexes(image_view);
4408 (void) FormatMagickString(name,MaxTextExtent,QuantumFormat,
4409 *indexes);
4410 s=newSVpv(name,0);
4411 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4412 }
4413 image_view=CloseCacheView(image_view);
4414 continue;
4415 }
4416 if (LocaleCompare(attribute,"iptc") == 0)
4417 {
4418 if (image != (Image *) NULL)
4419 {
4420 const StringInfo
4421 *profile;
4422
4423 profile=GetImageProfile(image,"iptc");
4424 if (profile != (const StringInfo *) NULL)
4425 s=newSVpv((const char *) GetStringInfoDatum(profile),
4426 GetStringInfoLength(profile));
4427 }
4428 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4429 continue;
4430 }
4431 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
4432 {
4433 if (image != (Image *) NULL)
4434 s=newSViv((long) image->iterations);
4435 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4436 continue;
4437 }
4438 if (LocaleCompare(attribute,"interlace") == 0)
4439 {
4440 j=info ? info->image_info->interlace : image->interlace;
4441 s=newSViv(j);
4442 (void) sv_setpv(s,MagickOptionToMnemonic(MagickInterlaceOptions,
4443 j));
4444 SvIOK_on(s);
4445 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4446 continue;
4447 }
4448 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4449 attribute);
4450 break;
4451 }
4452 case 'L':
4453 case 'l':
4454 {
4455 if (LocaleCompare(attribute,"label") == 0)
4456 {
4457 const char
4458 *value;
4459
4460 if (image == (Image *) NULL)
4461 break;
4462 value=GetImageProperty(image,"Label");
4463 if (value != (const char *) NULL)
4464 s=newSVpv(value,0);
4465 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4466 continue;
4467 }
4468 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
4469 {
4470 if (image != (Image *) NULL)
4471 s=newSViv((long) image->iterations);
4472 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4473 continue;
4474 }
4475 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4476 attribute);
4477 break;
4478 }
4479 case 'M':
4480 case 'm':
4481 {
4482 if (LocaleCompare(attribute,"magick") == 0)
4483 {
4484 if (info && *info->image_info->magick)
4485 s=newSVpv(info->image_info->magick,0);
4486 if (image != (Image *) NULL)
4487 s=newSVpv(image->magick,0);
4488 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4489 continue;
4490 }
4491 if (LocaleCompare(attribute,"map") == 0)
4492 {
4493 s=newSViv(GetMagickResource(MapResource));
4494 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4495 continue;
4496 }
4497 if (LocaleCompare(attribute,"maximum-error") == 0)
4498 {
4499 if (image != (Image *) NULL)
4500 s=newSVnv(image->error.normalized_maximum_error);
4501 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4502 continue;
4503 }
4504 if (LocaleCompare(attribute,"memory") == 0)
4505 {
4506 s=newSViv(GetMagickResource(MemoryResource));
4507 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4508 continue;
4509 }
4510 if (LocaleCompare(attribute,"mean-error") == 0)
4511 {
4512 if (image != (Image *) NULL)
4513 s=newSVnv(image->error.normalized_mean_error);
4514 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4515 continue;
4516 }
4517 if (LocaleCompare(attribute,"mime") == 0)
4518 {
4519 if (info && *info->image_info->magick)
4520 s=newSVpv(MagickToMime(info->image_info->magick),0);
4521 if (image != (Image *) NULL)
4522 s=newSVpv(MagickToMime(image->magick),0);
4523 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4524 continue;
4525 }
4526 if (LocaleCompare(attribute,"monochrome") == 0)
4527 {
4528 if (image == (Image *) NULL)
4529 continue;
4530 j=info ? info->image_info->monochrome :
4531 IsMonochromeImage(image,&image->exception);
4532 s=newSViv(j);
4533 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4534 continue;
4535 }
4536 if (LocaleCompare(attribute,"mattecolor") == 0)
4537 {
4538 if (image == (Image *) NULL)
4539 break;
4540 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
4541 QuantumFormat "," QuantumFormat "," QuantumFormat,
4542 image->matte_color.red,image->matte_color.green,
4543 image->matte_color.blue,image->matte_color.opacity);
4544 s=newSVpv(color,0);
4545 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4546 continue;
4547 }
4548 if (LocaleCompare(attribute,"matte") == 0)
4549 {
4550 if (image != (Image *) NULL)
4551 s=newSViv((long) image->matte);
4552 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4553 continue;
4554 }
4555 if (LocaleCompare(attribute,"montage") == 0)
4556 {
4557 if (image && image->montage)
4558 s=newSVpv(image->montage,0);
4559 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4560 continue;
4561 }
4562 if (LocaleCompare(attribute,"mime") == 0)
4563 {
4564 const char
4565 *magick;
4566
4567 magick=NULL;
4568 if (info && *info->image_info->magick)
4569 magick=info->image_info->magick;
4570 if (image != (Image *) NULL)
4571 magick=image->magick;
4572 if (magick)
4573 {
4574 char
4575 *mime;
4576
4577 mime=MagickToMime(magick);
4578 s=newSVpv(mime,0);
4579 mime=(char *) RelinquishMagickMemory(mime);
4580 }
4581 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4582 continue;
4583 }
4584 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4585 attribute);
4586 break;
4587 }
4588 case 'O':
4589 case 'o':
4590 {
4591 if (LocaleCompare(attribute,"orientation") == 0)
4592 {
4593 j=info ? info->image_info->orientation : image->orientation;
4594 s=newSViv(j);
4595 (void) sv_setpv(s,MagickOptionToMnemonic(MagickOrientationOptions,
4596 j));
4597 SvIOK_on(s);
4598 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4599 continue;
4600 }
4601 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4602 attribute);
4603 break;
4604 }
4605 case 'P':
4606 case 'p':
4607 {
4608 if (LocaleCompare(attribute,"page") == 0)
4609 {
4610 if (info && info->image_info->page)
4611 s=newSVpv(info->image_info->page,0);
4612 if (image != (Image *) NULL)
4613 {
4614 char
4615 geometry[MaxTextExtent];
4616
4617 (void) FormatMagickString(geometry,MaxTextExtent,
4618 "%lux%lu%+ld%+ld",image->page.width,image->page.height,
4619 image->page.x,image->page.y);
4620 s=newSVpv(geometry,0);
4621 }
4622 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4623 continue;
4624 }
4625 if (LocaleCompare(attribute,"page.x") == 0)
4626 {
4627 if (image != (Image *) NULL)
4628 s=newSViv((long) image->page.x);
4629 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4630 continue;
4631 }
4632 if (LocaleCompare(attribute,"page.y") == 0)
4633 {
4634 if (image != (Image *) NULL)
4635 s=newSViv((long) image->page.y);
4636 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4637 continue;
4638 }
4639 if (LocaleNCompare(attribute,"pixel",5) == 0)
4640 {
4641 char
4642 tuple[MaxTextExtent];
4643
4644 int
4645 items;
4646
4647 long
4648 x,
4649 y;
4650
4651 register const PixelPacket
4652 *p;
4653
4654 register const IndexPacket
4655 *indexes;
4656
4657 if (image == (Image *) NULL)
4658 break;
4659 x=0;
4660 y=0;
4661 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
4662 p=GetVirtualPixels(image,x,y,1,1,exception);
4663 indexes=AcquireIndexes(image);
4664 if (image->colorspace != CMYKColorspace)
4665 (void) FormatMagickString(tuple,MaxTextExtent,QuantumFormat ","
4666 QuantumFormat "," QuantumFormat "," QuantumFormat,
4667 p->red,p->green,p->blue,p->opacity);
4668 else
4669 (void) FormatMagickString(tuple,MaxTextExtent,QuantumFormat ","
4670 QuantumFormat "," QuantumFormat "," QuantumFormat ","
4671 QuantumFormat,p->red,p->green,p->blue,*indexes,p->opacity);
4672 s=newSVpv(tuple,0);
4673 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4674 continue;
4675 }
4676 if (LocaleCompare(attribute,"pointsize") == 0)
4677 {
4678 if (info)
4679 s=newSViv((long) info->image_info->pointsize);
4680 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4681 continue;
4682 }
4683 if (LocaleCompare(attribute,"preview") == 0)
4684 {
4685 s=newSViv(info->image_info->preview_type);
4686 (void) sv_setpv(s,MagickOptionToMnemonic(MagickPreviewOptions,
4687 info->image_info->preview_type));
4688 SvIOK_on(s);
4689 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4690 continue;
4691 }
4692 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4693 attribute);
4694 break;
4695 }
4696 case 'Q':
4697 case 'q':
4698 {
4699 if (LocaleCompare(attribute,"quality") == 0)
4700 {
4701 if (info)
4702 s=newSViv((long) info->image_info->quality);
4703 if (image != (Image *) NULL)
4704 s=newSViv((long) image->quality);
4705 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4706 continue;
4707 }
4708 if (LocaleCompare(attribute,"quantum") == 0)
4709 {
4710 if (info)
4711 s=newSViv((long) MAGICKCORE_QUANTUM_DEPTH);
4712 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4713 continue;
4714 }
4715 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4716 attribute);
4717 break;
4718 }
4719 case 'R':
4720 case 'r':
4721 {
4722 if (LocaleCompare(attribute,"rendering-intent") == 0)
4723 {
4724 s=newSViv(image->rendering_intent);
4725 (void) sv_setpv(s,MagickOptionToMnemonic(MagickIntentOptions,
4726 image->rendering_intent));
4727 SvIOK_on(s);
4728 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4729 continue;
4730 }
4731 if (LocaleCompare(attribute,"red-primary") == 0)
4732 {
4733 if (image == (Image *) NULL)
4734 break;
4735 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
4736 image->chromaticity.red_primary.x,
4737 image->chromaticity.red_primary.y);
4738 s=newSVpv(color,0);
4739 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4740 continue;
4741 }
4742 if (LocaleCompare(attribute,"rows") == 0)
4743 {
4744 if (image != (Image *) NULL)
4745 s=newSViv((long) image->rows);
4746 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4747 continue;
4748 }
4749 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4750 attribute);
4751 break;
4752 }
4753 case 'S':
4754 case 's':
4755 {
4756 if (LocaleCompare(attribute,"sampling-factor") == 0)
4757 {
4758 if (info && info->image_info->sampling_factor)
4759 s=newSVpv(info->image_info->sampling_factor,0);
4760 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4761 continue;
4762 }
4763 if (LocaleCompare(attribute,"subimage") == 0)
4764 {
4765 if (info)
4766 s=newSViv((long) info->image_info->subimage);
4767 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4768 continue;
4769 }
4770 if (LocaleCompare(attribute,"subrange") == 0)
4771 {
4772 if (info)
4773 s=newSViv((long) info->image_info->subrange);
4774 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4775 continue;
4776 }
4777 if (LocaleCompare(attribute,"server") == 0) /* same as display */
4778 {
4779 if (info && info->image_info->server_name)
4780 s=newSVpv(info->image_info->server_name,0);
4781 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4782 continue;
4783 }
4784 if (LocaleCompare(attribute,"size") == 0)
4785 {
4786 if (info && info->image_info->size)
4787 s=newSVpv(info->image_info->size,0);
4788 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4789 continue;
4790 }
4791 if (LocaleCompare(attribute,"scene") == 0)
4792 {
4793 if (image != (Image *) NULL)
4794 s=newSViv((long) image->scene);
4795 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4796 continue;
4797 }
4798 if (LocaleCompare(attribute,"scenes") == 0)
4799 {
4800 if (image != (Image *) NULL)
4801 s=newSViv((long) info->image_info->number_scenes);
4802 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4803 continue;
4804 }
4805 if (LocaleCompare(attribute,"signature") == 0)
4806 {
4807 const char
4808 *value;
4809
4810 if (image == (Image *) NULL)
4811 break;
4812 (void) SignatureImage(image);
4813 value=GetImageProperty(image,"Signature");
4814 if (value != (const char *) NULL)
4815 s=newSVpv(value,0);
4816 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4817 continue;
4818 }
4819 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4820 attribute);
4821 break;
4822 }
4823 case 'T':
4824 case 't':
4825 {
4826 if (LocaleCompare(attribute,"taint") == 0)
4827 {
4828 if (image != (Image *) NULL)
4829 s=newSViv((long) IsTaintImage(image));
4830 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4831 continue;
4832 }
4833 if (LocaleCompare(attribute,"tile") == 0)
4834 {
4835 if (info && info->image_info->tile)
4836 s=newSVpv(info->image_info->tile,0);
4837 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4838 continue;
4839 }
4840 if (LocaleCompare(attribute,"texture") == 0)
4841 {
4842 if (info && info->image_info->texture)
4843 s=newSVpv(info->image_info->texture,0);
4844 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4845 continue;
4846 }
4847 if (LocaleCompare(attribute,"total-ink-density") == 0)
4848 {
4849 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4850 if (image != (Image *) NULL)
4851 s=newSVnv(GetImageTotalInkDensity(image));
4852 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4853 continue;
4854 }
4855 if (LocaleCompare(attribute,"type") == 0)
4856 {
4857 if (image == (Image *) NULL)
4858 break;
4859 j=(long) GetImageType(image,&image->exception);
4860 s=newSViv(j);
4861 (void) sv_setpv(s,MagickOptionToMnemonic(MagickTypeOptions,j));
4862 SvIOK_on(s);
4863 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4864 continue;
4865 }
4866 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4867 attribute);
4868 break;
4869 }
4870 case 'U':
4871 case 'u':
4872 {
4873 if (LocaleCompare(attribute,"units") == 0)
4874 {
4875 j=info ? info->image_info->units : image->units;
4876 if (info)
4877 if (info->image_info->units == UndefinedResolution)
4878 j=image->units;
4879 if (j == UndefinedResolution)
4880 s=newSVpv("undefined units",0);
4881 else
4882 if (j == PixelsPerInchResolution)
4883 s=newSVpv("pixels / inch",0);
4884 else
4885 s=newSVpv("pixels / centimeter",0);
4886 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4887 continue;
4888 }
4889 if (LocaleCompare(attribute,"user-time") == 0)
4890 {
4891 if (image != (Image *) NULL)
4892 s=newSVnv(GetUserTime(&image->timer));
4893 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4894 continue;
4895 }
4896 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4897 attribute);
4898 break;
4899 }
4900 case 'V':
4901 case 'v':
4902 {
4903 if (LocaleCompare(attribute,"verbose") == 0)
4904 {
4905 if (info)
4906 s=newSViv((long) info->image_info->verbose);
4907 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4908 continue;
4909 }
4910 if (LocaleCompare(attribute,"version") == 0)
4911 {
4912 s=newSVpv(GetMagickVersion((unsigned long *) NULL),0);
4913 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4914 continue;
4915 }
4916 if (LocaleCompare(attribute,"view") == 0)
4917 {
4918 if (info && info->image_info->view)
4919 s=newSVpv(info->image_info->view,0);
4920 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4921 continue;
4922 }
4923 if (LocaleCompare(attribute,"virtual-pixel") == 0)
4924 {
4925 if (image == (Image *) NULL)
4926 break;
4927 j=(long) GetImageVirtualPixelMethod(image);
4928 s=newSViv(j);
4929 (void) sv_setpv(s,MagickOptionToMnemonic(
4930 MagickVirtualPixelOptions,j));
4931 SvIOK_on(s);
4932 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4933 continue;
4934 }
4935 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4936 attribute);
4937 break;
4938 }
4939 case 'W':
4940 case 'w':
4941 {
4942 if (LocaleCompare(attribute,"white-point") == 0)
4943 {
4944 if (image == (Image *) NULL)
4945 break;
4946 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
4947 image->chromaticity.white_point.x,
4948 image->chromaticity.white_point.y);
4949 s=newSVpv(color,0);
4950 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4951 continue;
4952 }
4953 if (LocaleCompare(attribute,"width") == 0)
4954 {
4955 if (image != (Image *) NULL)
4956 s=newSViv((long) image->columns);
4957 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4958 continue;
4959 }
4960 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4961 attribute);
4962 break;
4963 }
4964 case 'X':
4965 case 'x':
4966 {
4967 if (LocaleCompare(attribute,"x-resolution") == 0)
4968 {
4969 if (image != (Image *) NULL)
4970 s=newSVnv(image->x_resolution);
4971 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4972 continue;
4973 }
4974 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4975 attribute);
4976 break;
4977 }
4978 case 'Y':
4979 case 'y':
4980 {
4981 if (LocaleCompare(attribute,"y-resolution") == 0)
4982 {
4983 if (image != (Image *) NULL)
4984 s=newSVnv(image->y_resolution);
4985 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4986 continue;
4987 }
4988 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4989 attribute);
4990 break;
4991 }
4992 default:
4993 break;
4994 }
4995 if (image == (Image *) NULL)
4996 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4997 attribute)
4998 else
4999 {
5000 value=GetImageProperty(image,attribute);
5001 if (value != (const char *) NULL)
5002 {
5003 s=newSVpv(value,0);
5004 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5005 }
5006 else
5007 if (*attribute != '%')
5008 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5009 attribute)
5010 else
5011 {
5012 char
5013 *meta;
5014
5015 meta=InterpretImageProperties(info ? info->image_info :
5016 (ImageInfo *) NULL,image,attribute);
5017 s=newSVpv(meta,0);
5018 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5019 meta=(char *) RelinquishMagickMemory(meta);
5020 }
5021 }
5022 }
5023 exception=DestroyExceptionInfo(exception);
5024 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5025 }
5026
5027#
5028###############################################################################
5029# #
5030# #
5031# #
5032# G e t A u t h e n t i c P i x e l s #
5033# #
5034# #
5035# #
5036###############################################################################
5037#
5038#
5039void *
5040GetAuthenticPixels(ref,...)
5041 Image::Magick ref = NO_INIT
5042 ALIAS:
5043 getauthenticpixels = 1
5044 GetImagePixels = 2
5045 getimagepixels = 3
5046 CODE:
5047 {
5048 char
5049 *attribute;
5050
5051 ExceptionInfo
5052 *exception;
5053
5054 Image
5055 *image;
5056
5057 long
5058 i;
5059
5060 RectangleInfo
5061 region;
5062
5063 struct PackageInfo
5064 *info;
5065
5066 SV
5067 *perl_exception,
5068 *reference;
5069
5070 void
5071 *blob = NULL;
5072
5073 exception=AcquireExceptionInfo();
5074 perl_exception=newSVpv("",0);
5075 if (sv_isobject(ST(0)) == 0)
5076 {
5077 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5078 PackageName);
5079 goto PerlException;
5080 }
5081 reference=SvRV(ST(0));
5082
5083 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5084 if (image == (Image *) NULL)
5085 {
5086 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5087 PackageName);
5088 goto PerlException;
5089 }
5090
5091 region.x=0;
5092 region.y=0;
5093 region.width=image->columns;
5094 region.height=1;
5095 if (items == 1)
5096 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5097 for (i=2; i < items; i+=2)
5098 {
5099 attribute=(char *) SvPV(ST(i-1),na);
5100 switch (*attribute)
5101 {
5102 case 'g':
5103 case 'G':
5104 {
5105 if (LocaleCompare(attribute,"geometry") == 0)
5106 {
5107 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5108 break;
5109 }
5110 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5111 attribute);
5112 break;
5113 }
5114 case 'H':
5115 case 'h':
5116 {
5117 if (LocaleCompare(attribute,"height") == 0)
5118 {
5119 region.height=SvIV(ST(i));
5120 continue;
5121 }
5122 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5123 attribute);
5124 break;
5125 }
5126 case 'X':
5127 case 'x':
5128 {
5129 if (LocaleCompare(attribute,"x") == 0)
5130 {
5131 region.x=SvIV(ST(i));
5132 continue;
5133 }
5134 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5135 attribute);
5136 break;
5137 }
5138 case 'Y':
5139 case 'y':
5140 {
5141 if (LocaleCompare(attribute,"y") == 0)
5142 {
5143 region.y=SvIV(ST(i));
5144 continue;
5145 }
5146 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5147 attribute);
5148 break;
5149 }
5150 case 'W':
5151 case 'w':
5152 {
5153 if (LocaleCompare(attribute,"width") == 0)
5154 {
5155 region.width=SvIV(ST(i));
5156 continue;
5157 }
5158 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5159 attribute);
5160 break;
5161 }
5162 }
5163 }
5164 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5165 region.height,exception);
5166 if (blob != (void *) NULL)
5167 goto PerlEnd;
5168
5169 PerlException:
5170 InheritPerlException(exception,perl_exception);
5171 exception=DestroyExceptionInfo(exception);
5172 SvREFCNT_dec(perl_exception); /* throw away all errors */
5173
5174 PerlEnd:
5175 RETVAL = blob;
5176 }
5177 OUTPUT:
5178 RETVAL
5179
5180#
5181###############################################################################
5182# #
5183# #
5184# #
5185# G e t V i r t u a l P i x e l s #
5186# #
5187# #
5188# #
5189###############################################################################
5190#
5191#
5192void *
5193GetVirtualPixels(ref,...)
5194 Image::Magick ref = NO_INIT
5195 ALIAS:
5196 getvirtualpixels = 1
5197 AcquireImagePixels = 2
5198 acquireimagepixels = 3
5199 CODE:
5200 {
5201 char
5202 *attribute;
5203
5204 const void
5205 *blob = NULL;
5206
5207 ExceptionInfo
5208 *exception;
5209
5210 Image
5211 *image;
5212
5213 long
5214 i;
5215
5216 RectangleInfo
5217 region;
5218
5219 struct PackageInfo
5220 *info;
5221
5222 SV
5223 *perl_exception,
5224 *reference;
5225
5226 exception=AcquireExceptionInfo();
5227 perl_exception=newSVpv("",0);
5228 if (sv_isobject(ST(0)) == 0)
5229 {
5230 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5231 PackageName);
5232 goto PerlException;
5233 }
5234 reference=SvRV(ST(0));
5235
5236 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5237 if (image == (Image *) NULL)
5238 {
5239 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5240 PackageName);
5241 goto PerlException;
5242 }
5243
5244 region.x=0;
5245 region.y=0;
5246 region.width=image->columns;
5247 region.height=1;
5248 if (items == 1)
5249 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5250 for (i=2; i < items; i+=2)
5251 {
5252 attribute=(char *) SvPV(ST(i-1),na);
5253 switch (*attribute)
5254 {
5255 case 'g':
5256 case 'G':
5257 {
5258 if (LocaleCompare(attribute,"geometry") == 0)
5259 {
5260 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5261 break;
5262 }
5263 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5264 attribute);
5265 break;
5266 }
5267 case 'H':
5268 case 'h':
5269 {
5270 if (LocaleCompare(attribute,"height") == 0)
5271 {
5272 region.height=SvIV(ST(i));
5273 continue;
5274 }
5275 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5276 attribute);
5277 break;
5278 }
5279 case 'X':
5280 case 'x':
5281 {
5282 if (LocaleCompare(attribute,"x") == 0)
5283 {
5284 region.x=SvIV(ST(i));
5285 continue;
5286 }
5287 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5288 attribute);
5289 break;
5290 }
5291 case 'Y':
5292 case 'y':
5293 {
5294 if (LocaleCompare(attribute,"y") == 0)
5295 {
5296 region.y=SvIV(ST(i));
5297 continue;
5298 }
5299 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5300 attribute);
5301 break;
5302 }
5303 case 'W':
5304 case 'w':
5305 {
5306 if (LocaleCompare(attribute,"width") == 0)
5307 {
5308 region.width=SvIV(ST(i));
5309 continue;
5310 }
5311 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5312 attribute);
5313 break;
5314 }
5315 }
5316 }
5317 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
5318 region.height,exception);
5319 if (blob != (void *) NULL)
5320 goto PerlEnd;
5321
5322 PerlException:
5323 InheritPerlException(exception,perl_exception);
5324 exception=DestroyExceptionInfo(exception);
5325 SvREFCNT_dec(perl_exception); /* throw away all errors */
5326
5327 PerlEnd:
5328 RETVAL = (void *) blob;
5329 }
5330 OUTPUT:
5331 RETVAL
5332
5333#
5334###############################################################################
5335# #
5336# #
5337# #
5338# G e t A u t h e n t i c I n d e x Q u e u e #
5339# #
5340# #
5341# #
5342###############################################################################
5343#
5344#
5345void *
5346GetAuthenticIndexQueue(ref,...)
5347 Image::Magick ref = NO_INIT
5348 ALIAS:
5349 getauthenticindexqueue = 1
5350 GetIndexes = 2
5351 getindexes = 3
5352 CODE:
5353 {
5354 ExceptionInfo
5355 *exception;
5356
5357 Image
5358 *image;
5359
5360 struct PackageInfo
5361 *info;
5362
5363 SV
5364 *perl_exception,
5365 *reference;
5366
5367 void
5368 *blob = NULL;
5369
5370 exception=AcquireExceptionInfo();
5371 perl_exception=newSVpv("",0);
5372 if (sv_isobject(ST(0)) == 0)
5373 {
5374 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5375 PackageName);
5376 goto PerlException;
5377 }
5378 reference=SvRV(ST(0));
5379
5380 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5381 if (image == (Image *) NULL)
5382 {
5383 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5384 PackageName);
5385 goto PerlException;
5386 }
5387
5388 blob=(void *) GetAuthenticIndexQueue(image);
5389 if (blob != (void *) NULL)
5390 goto PerlEnd;
5391
5392 PerlException:
5393 InheritPerlException(exception,perl_exception);
5394 exception=DestroyExceptionInfo(exception);
5395 SvREFCNT_dec(perl_exception); /* throw away all errors */
5396
5397 PerlEnd:
5398 RETVAL = blob;
5399 }
5400 OUTPUT:
5401 RETVAL
5402
5403#
5404###############################################################################
5405# #
5406# #
5407# #
5408# G e t V i r t u a l I n d e x Q u e u e #
5409# #
5410# #
5411# #
5412###############################################################################
5413#
5414#
5415void *
5416GetVirtualIndexQueue(ref,...)
5417 Image::Magick ref = NO_INIT
5418 ALIAS:
5419 getvirtualindexqueue = 1
5420 CODE:
5421 {
5422 ExceptionInfo
5423 *exception;
5424
5425 Image
5426 *image;
5427
5428 struct PackageInfo
5429 *info;
5430
5431 SV
5432 *perl_exception,
5433 *reference;
5434
5435 void
5436 *blob = NULL;
5437
5438 exception=AcquireExceptionInfo();
5439 perl_exception=newSVpv("",0);
5440 if (sv_isobject(ST(0)) == 0)
5441 {
5442 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5443 PackageName);
5444 goto PerlException;
5445 }
5446 reference=SvRV(ST(0));
5447
5448 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5449 if (image == (Image *) NULL)
5450 {
5451 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5452 PackageName);
5453 goto PerlException;
5454 }
5455
5456 blob=(void *) GetVirtualIndexQueue(image);
5457 if (blob != (void *) NULL)
5458 goto PerlEnd;
5459
5460 PerlException:
5461 InheritPerlException(exception,perl_exception);
5462 exception=DestroyExceptionInfo(exception);
5463 SvREFCNT_dec(perl_exception); /* throw away all errors */
5464
5465 PerlEnd:
5466 RETVAL = blob;
5467 }
5468 OUTPUT:
5469 RETVAL
5470
5471#
5472###############################################################################
5473# #
5474# #
5475# #
5476# H i s t o g r a m #
5477# #
5478# #
5479# #
5480###############################################################################
5481#
5482#
5483void
5484Histogram(ref,...)
5485 Image::Magick ref=NO_INIT
5486 ALIAS:
5487 HistogramImage = 1
5488 histogram = 2
5489 histogramimage = 3
5490 PPCODE:
5491 {
5492 AV
5493 *av;
5494
5495 char
5496 message[MaxTextExtent];
5497
5498 ColorPacket
5499 *histogram;
5500
5501 ExceptionInfo
5502 *exception;
5503
5504 HV
5505 *hv;
5506
5507 Image
5508 *image;
5509
5510 register long
5511 i;
5512
5513 ssize_t
5514 count;
5515
5516 struct PackageInfo
5517 *info;
5518
5519 SV
5520 *av_reference,
5521 *perl_exception,
5522 *reference;
5523
5524 unsigned long
5525 number_colors;
5526
5527 exception=AcquireExceptionInfo();
5528 perl_exception=newSVpv("",0);
5529 av=NULL;
5530 if (sv_isobject(ST(0)) == 0)
5531 {
5532 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5533 PackageName);
5534 goto PerlException;
5535 }
5536 reference=SvRV(ST(0));
5537 hv=SvSTASH(reference);
5538 av=newAV();
5539 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
5540 SvREFCNT_dec(av);
5541 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5542 if (image == (Image *) NULL)
5543 {
5544 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5545 PackageName);
5546 goto PerlException;
5547 }
5548 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
5549 count=0;
5550 for ( ; image; image=image->next)
5551 {
5552 histogram=GetImageHistogram(image,&number_colors,&image->exception);
5553 if (histogram == (ColorPacket *) NULL)
5554 continue;
5555 count+=number_colors;
5556 EXTEND(sp,6*count);
5557 for (i=0; i < (long) number_colors; i++)
5558 {
5559 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5560 histogram[i].pixel.red);
5561 PUSHs(sv_2mortal(newSVpv(message,0)));
5562 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5563 histogram[i].pixel.green);
5564 PUSHs(sv_2mortal(newSVpv(message,0)));
5565 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5566 histogram[i].pixel.blue);
5567 PUSHs(sv_2mortal(newSVpv(message,0)));
5568 if (image->colorspace == CMYKColorspace)
5569 {
5570 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5571 histogram[i].index);
5572 PUSHs(sv_2mortal(newSVpv(message,0)));
5573 }
5574 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5575 histogram[i].pixel.opacity);
5576 PUSHs(sv_2mortal(newSVpv(message,0)));
5577 (void) FormatMagickString(message,MaxTextExtent,"%lu",
5578 (unsigned long) histogram[i].count);
5579 PUSHs(sv_2mortal(newSVpv(message,0)));
5580 }
5581 histogram=(ColorPacket *) RelinquishMagickMemory(histogram);
5582 }
5583
5584 PerlException:
5585 InheritPerlException(exception,perl_exception);
5586 exception=DestroyExceptionInfo(exception);
5587 SvREFCNT_dec(perl_exception);
5588 }
5589
5590#
5591###############################################################################
5592# #
5593# #
5594# #
5595# G e t P i x e l #
5596# #
5597# #
5598# #
5599###############################################################################
5600#
5601#
5602void
5603GetPixel(ref,...)
5604 Image::Magick ref=NO_INIT
5605 ALIAS:
5606 getpixel = 1
5607 getPixel = 2
5608 PPCODE:
5609 {
5610 AV
5611 *av;
5612
5613 char
5614 *attribute;
5615
5616 ChannelType
5617 channel;
5618
5619 ExceptionInfo
5620 *exception;
5621
5622 Image
5623 *image;
5624
5625 long
5626 option;
5627
5628 MagickBooleanType
5629 normalize;
5630
5631 RectangleInfo
5632 region;
5633
5634 register const IndexPacket
5635 *indexes;
5636
5637 register const PixelPacket
5638 *p;
5639
5640 register long
5641 i;
5642
5643 struct PackageInfo
5644 *info;
5645
5646 SV
5647 *perl_exception,
5648 *reference; /* reference is the SV* of ref=SvIV(reference) */
5649
5650 exception=AcquireExceptionInfo();
5651 perl_exception=newSVpv("",0);
5652 reference=SvRV(ST(0));
5653 av=(AV *) reference;
5654 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
5655 exception);
5656 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5657 if (image == (Image *) NULL)
5658 {
5659 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5660 PackageName);
5661 goto PerlException;
5662 }
5663 channel=DefaultChannels;
5664 normalize=MagickTrue;
5665 region.x=0;
5666 region.y=0;
5667 region.width=image->columns;
5668 region.height=1;
5669 if (items == 1)
5670 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5671 for (i=2; i < items; i+=2)
5672 {
5673 attribute=(char *) SvPV(ST(i-1),na);
5674 switch (*attribute)
5675 {
5676 case 'C':
5677 case 'c':
5678 {
5679 if (LocaleCompare(attribute,"channel") == 0)
5680 {
5681 long
5682 option;
5683
5684 option=ParseChannelOption(SvPV(ST(i),na));
5685 if (option < 0)
5686 {
5687 ThrowPerlException(exception,OptionError,"UnrecognizedType",
5688 SvPV(ST(i),na));
5689 return;
5690 }
5691 channel=(ChannelType) option;
5692 break;
5693 }
5694 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5695 attribute);
5696 break;
5697 }
5698 case 'g':
5699 case 'G':
5700 {
5701 if (LocaleCompare(attribute,"geometry") == 0)
5702 {
5703 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5704 break;
5705 }
5706 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5707 attribute);
5708 break;
5709 }
5710 case 'N':
5711 case 'n':
5712 {
5713 if (LocaleCompare(attribute,"normalize") == 0)
5714 {
5715 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
5716 SvPV(ST(i),na));
5717 if (option < 0)
5718 {
5719 ThrowPerlException(exception,OptionError,"UnrecognizedType",
5720 SvPV(ST(i),na));
5721 break;
5722 }
5723 normalize=option != 0 ? MagickTrue : MagickFalse;
5724 break;
5725 }
5726 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5727 attribute);
5728 break;
5729 }
5730 case 'x':
5731 case 'X':
5732 {
5733 if (LocaleCompare(attribute,"x") == 0)
5734 {
5735 region.x=SvIV(ST(i));
5736 break;
5737 }
5738 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5739 attribute);
5740 break;
5741 }
5742 case 'y':
5743 case 'Y':
5744 {
5745 if (LocaleCompare(attribute,"y") == 0)
5746 {
5747 region.y=SvIV(ST(i));
5748 break;
5749 }
5750 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5751 attribute);
5752 break;
5753 }
5754 default:
5755 {
5756 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5757 attribute);
5758 break;
5759 }
5760 }
5761 }
5762 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
5763 if (p == (const PixelPacket *) NULL)
5764 PUSHs(&sv_undef);
5765 else
5766 {
5767 double
5768 scale;
5769
5770 indexes=AcquireIndexes(image);
5771 scale=1.0;
5772 if (normalize != MagickFalse)
5773 scale=1.0/QuantumRange;
5774 if ((channel & RedChannel) != 0)
5775 PUSHs(sv_2mortal(newSVnv(scale*p->red)));
5776 if ((channel & GreenChannel) != 0)
5777 PUSHs(sv_2mortal(newSVnv(scale*p->green)));
5778 if ((channel & BlueChannel) != 0)
5779 PUSHs(sv_2mortal(newSVnv(scale*p->blue)));
5780 if (((channel & IndexChannel) != 0) &&
5781 (image->colorspace == CMYKColorspace))
5782 PUSHs(sv_2mortal(newSVnv(scale*(*indexes))));
5783 if ((channel & OpacityChannel) != 0)
5784 PUSHs(sv_2mortal(newSVnv(scale*p->opacity)));
5785 }
5786
5787 PerlException:
5788 InheritPerlException(exception,perl_exception);
5789 exception=DestroyExceptionInfo(exception);
5790 SvREFCNT_dec(perl_exception);
5791 }
5792
5793#
5794###############################################################################
5795# #
5796# #
5797# #
5798# G e t P i x e l s #
5799# #
5800# #
5801# #
5802###############################################################################
5803#
5804#
5805void
5806GetPixels(ref,...)
5807 Image::Magick ref=NO_INIT
5808 ALIAS:
5809 getpixels = 1
5810 getPixels = 2
5811 PPCODE:
5812 {
5813 AV
5814 *av;
5815
5816 char
5817 *attribute;
5818
5819 const char
5820 *map;
5821
5822 ExceptionInfo
5823 *exception;
5824
5825 Image
5826 *image;
5827
5828 long
5829 option;
5830
5831 MagickBooleanType
5832 normalize,
5833 status;
5834
5835 RectangleInfo
5836 region;
5837
5838 register long
5839 i;
5840
5841 struct PackageInfo
5842 *info;
5843
5844 SV
5845 *perl_exception,
5846 *reference; /* reference is the SV* of ref=SvIV(reference) */
5847
5848 exception=AcquireExceptionInfo();
5849 perl_exception=newSVpv("",0);
5850 reference=SvRV(ST(0));
5851 av=(AV *) reference;
5852 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
5853 exception);
5854 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5855 if (image == (Image *) NULL)
5856 {
5857 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5858 PackageName);
5859 goto PerlException;
5860 }
5861 map="RGB";
5862 if (image->matte != MagickFalse)
5863 map="RGBA";
5864 if (image->colorspace == CMYKColorspace)
5865 {
5866 map="CMYK";
5867 if (image->matte != MagickFalse)
5868 map="CMYKA";
5869 }
5870 normalize=MagickFalse;
5871 region.x=0;
5872 region.y=0;
5873 region.width=image->columns;
5874 region.height=1;
5875 if (items == 1)
5876 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5877 for (i=2; i < items; i+=2)
5878 {
5879 attribute=(char *) SvPV(ST(i-1),na);
5880 switch (*attribute)
5881 {
5882 case 'g':
5883 case 'G':
5884 {
5885 if (LocaleCompare(attribute,"geometry") == 0)
5886 {
5887 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5888 break;
5889 }
5890 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5891 attribute);
5892 break;
5893 }
5894 case 'H':
5895 case 'h':
5896 {
5897 if (LocaleCompare(attribute,"height") == 0)
5898 {
5899 region.height=SvIV(ST(i));
5900 break;
5901 }
5902 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5903 attribute);
5904 break;
5905 }
5906 case 'M':
5907 case 'm':
5908 {
5909 if (LocaleCompare(attribute,"map") == 0)
5910 {
5911 map=SvPV(ST(i),na);
5912 break;
5913 }
5914 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5915 attribute);
5916 break;
5917 }
5918 case 'N':
5919 case 'n':
5920 {
5921 if (LocaleCompare(attribute,"normalize") == 0)
5922 {
5923 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
5924 SvPV(ST(i),na));
5925 if (option < 0)
5926 {
5927 ThrowPerlException(exception,OptionError,"UnrecognizedType",
5928 SvPV(ST(i),na));
5929 break;
5930 }
5931 normalize=option != 0 ? MagickTrue : MagickFalse;
5932 break;
5933 }
5934 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5935 attribute);
5936 break;
5937 }
5938 case 'W':
5939 case 'w':
5940 {
5941 if (LocaleCompare(attribute,"width") == 0)
5942 {
5943 region.width=SvIV(ST(i));
5944 break;
5945 }
5946 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5947 attribute);
5948 break;
5949 }
5950 case 'x':
5951 case 'X':
5952 {
5953 if (LocaleCompare(attribute,"x") == 0)
5954 {
5955 region.x=SvIV(ST(i));
5956 break;
5957 }
5958 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5959 attribute);
5960 break;
5961 }
5962 case 'y':
5963 case 'Y':
5964 {
5965 if (LocaleCompare(attribute,"y") == 0)
5966 {
5967 region.y=SvIV(ST(i));
5968 break;
5969 }
5970 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5971 attribute);
5972 break;
5973 }
5974 default:
5975 {
5976 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5977 attribute);
5978 break;
5979 }
5980 }
5981 }
5982 if (normalize != MagickFalse)
5983 {
5984 float
5985 *pixels;
5986
5987 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
5988 region.height*sizeof(*pixels));
5989 if (pixels == (float *) NULL)
5990 {
5991 ThrowPerlException(exception,ResourceLimitError,
5992 "MemoryAllocationFailed",PackageName);
5993 goto PerlException;
5994 }
5995 status=ExportImagePixels(image,region.x,region.y,region.width,
5996 region.height,map,FloatPixel,pixels,exception);
5997 if (status == MagickFalse)
5998 PUSHs(&sv_undef);
5999 else
6000 {
6001 EXTEND(sp,strlen(map)*region.width*region.height);
6002 for (i=0; i < (long) (strlen(map)*region.width*region.height); i++)
6003 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6004 }
6005 pixels=(float *) RelinquishMagickMemory(pixels);
6006 }
6007 else
6008 {
6009 Quantum
6010 *pixels;
6011
6012 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6013 region.height*sizeof(*pixels));
6014 if (pixels == (Quantum *) NULL)
6015 {
6016 ThrowPerlException(exception,ResourceLimitError,
6017 "MemoryAllocationFailed",PackageName);
6018 goto PerlException;
6019 }
6020 status=ExportImagePixels(image,region.x,region.y,region.width,
6021 region.height,map,QuantumPixel,pixels,exception);
6022 if (status == MagickFalse)
6023 PUSHs(&sv_undef);
6024 else
6025 {
6026 EXTEND(sp,strlen(map)*region.width*region.height);
6027 for (i=0; i < (long) (strlen(map)*region.width*region.height); i++)
6028 PUSHs(sv_2mortal(newSViv(pixels[i])));
6029 }
6030 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6031 }
6032
6033 PerlException:
6034 InheritPerlException(exception,perl_exception);
6035 exception=DestroyExceptionInfo(exception);
6036 SvREFCNT_dec(perl_exception);
6037 }
6038
6039#
6040###############################################################################
6041# #
6042# #
6043# #
6044# I m a g e T o B l o b #
6045# #
6046# #
6047# #
6048###############################################################################
6049#
6050#
6051void
6052ImageToBlob(ref,...)
6053 Image::Magick ref=NO_INIT
6054 ALIAS:
6055 ImageToBlob = 1
6056 imagetoblob = 2
6057 toblob = 3
6058 blob = 4
6059 PPCODE:
6060 {
6061 char
6062 filename[MaxTextExtent];
6063
6064 ExceptionInfo
6065 *exception;
6066
6067 Image
6068 *image,
6069 *next;
6070
6071 long
6072 scene;
6073
6074 register long
6075 i;
6076
6077 struct PackageInfo
6078 *info,
6079 *package_info;
6080
6081 size_t
6082 length;
6083
6084 SV
6085 *perl_exception,
6086 *reference;
6087
6088 void
6089 *blob;
6090
6091 exception=AcquireExceptionInfo();
6092 perl_exception=newSVpv("",0);
6093 package_info=(struct PackageInfo *) NULL;
6094 if (sv_isobject(ST(0)) == 0)
6095 {
6096 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6097 PackageName);
6098 goto PerlException;
6099 }
6100 reference=SvRV(ST(0));
6101 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6102 if (image == (Image *) NULL)
6103 {
6104 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6105 PackageName);
6106 goto PerlException;
6107 }
6108 package_info=ClonePackageInfo(info,exception);
6109 for (i=2; i < items; i+=2)
6110 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6111 (void) CopyMagickString(filename,package_info->image_info->filename,
6112 MaxTextExtent);
6113 scene=0;
6114 for (next=image; next; next=next->next)
6115 {
6116 (void) CopyMagickString(next->filename,filename,MaxTextExtent);
6117 next->scene=scene++;
6118 }
6119 SetImageInfo(package_info->image_info,MagickTrue,&image->exception);
6120 EXTEND(sp,(long) GetImageListLength(image));
6121 for ( ; image; image=image->next)
6122 {
6123 length=0;
6124 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6125 if (blob != (char *) NULL)
6126 {
6127 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6128 blob=(unsigned char *) RelinquishMagickMemory(blob);
6129 }
6130 if (package_info->image_info->adjoin)
6131 break;
6132 }
6133
6134 PerlException:
6135 if (package_info != (struct PackageInfo *) NULL)
6136 DestroyPackageInfo(package_info);
6137 InheritPerlException(exception,perl_exception);
6138 exception=DestroyExceptionInfo(exception);
6139 SvREFCNT_dec(perl_exception); /* throw away all errors */
6140 }
6141
6142#
6143###############################################################################
6144# #
6145# #
6146# #
6147# L a y e r s #
6148# #
6149# #
6150# #
6151###############################################################################
6152#
6153#
6154void
6155Layers(ref,...)
6156 Image::Magick ref=NO_INIT
6157 ALIAS:
6158 Layers = 1
6159 layers = 2
6160 OptimizeImageLayers = 3
6161 optimizelayers = 4
6162 optimizeimagelayers = 5
6163 PPCODE:
6164 {
6165 AV
6166 *av;
6167
6168 char
6169 *attribute;
6170
6171 CompositeOperator
6172 compose;
6173
6174 ExceptionInfo
6175 *exception;
6176
6177 HV
6178 *hv;
6179
6180 Image
6181 *image,
6182 *layers;
6183
6184 long
6185 option,
6186 sp;
6187
6188 MagickBooleanType
6189 dither;
6190
6191 ImageLayerMethod
6192 method;
6193
6194 register long
6195 i;
6196
6197 struct PackageInfo
6198 *info;
6199
6200 SV
6201 *av_reference,
6202 *perl_exception,
6203 *reference,
6204 *rv,
6205 *sv;
6206
6207 exception=AcquireExceptionInfo();
6208 perl_exception=newSVpv("",0);
6209 if (sv_isobject(ST(0)) == 0)
6210 {
6211 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6212 PackageName);
6213 goto PerlException;
6214 }
6215 reference=SvRV(ST(0));
6216 hv=SvSTASH(reference);
6217 av=newAV();
6218 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
6219 SvREFCNT_dec(av);
6220 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6221 if (image == (Image *) NULL)
6222 {
6223 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6224 PackageName);
6225 goto PerlException;
6226 }
6227 compose=image->compose;
6228 dither=MagickFalse;
6229 method=OptimizeLayer;
6230 for (i=2; i < items; i+=2)
6231 {
6232 attribute=(char *) SvPV(ST(i-1),na);
6233 switch (*attribute)
6234 {
6235 case 'C':
6236 case 'c':
6237 {
6238 if (LocaleCompare(attribute,"compose") == 0)
6239 {
6240 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
6241 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
6242 if (sp < 0)
6243 {
6244 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6245 SvPV(ST(i),na));
6246 break;
6247 }
6248 compose=(CompositeOperator) sp;
6249 break;
6250 }
6251 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6252 attribute);
6253 break;
6254 }
6255 case 'D':
6256 case 'd':
6257 {
6258 if (LocaleCompare(attribute,"dither") == 0)
6259 {
6260 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
6261 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
6262 if (sp < 0)
6263 {
6264 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6265 SvPV(ST(i),na));
6266 break;
6267 }
6268 dither=(MagickBooleanType) sp;
6269 break;
6270 }
6271 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6272 attribute);
6273 break;
6274 }
6275 case 'M':
6276 case 'm':
6277 {
6278 if (LocaleCompare(attribute,"method") == 0)
6279 {
6280 option=ParseMagickOption(MagickLayerOptions,MagickFalse,
6281 SvPV(ST(i),na));
6282 if (option < 0)
6283 {
6284 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6285 SvPV(ST(i),na));
6286 break;
6287 }
6288 method=(ImageLayerMethod) option;
6289 break;
6290 }
6291 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6292 attribute);
6293 break;
6294 }
6295 default:
6296 {
6297 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6298 attribute);
6299 break;
6300 }
6301 }
6302 }
6303 layers=(Image *) NULL;
6304 switch (method)
6305 {
6306 case CompareAnyLayer:
6307 case CompareClearLayer:
6308 case CompareOverlayLayer:
6309 default:
6310 {
6311 layers=CompareImageLayers(image,method,exception);
6312 break;
6313 }
6314 case MergeLayer:
6315 case FlattenLayer:
6316 case MosaicLayer:
6317 {
6318 layers=MergeImageLayers(image,method,exception);
6319 break;
6320 }
6321 case DisposeLayer:
6322 {
6323 layers=DisposeImages(image,exception);
6324 break;
6325 }
6326 case OptimizeImageLayer:
6327 {
6328 layers=OptimizeImageLayers(image,exception);
6329 break;
6330 }
6331 case OptimizePlusLayer:
6332 {
6333 layers=OptimizePlusImageLayers(image,exception);
6334 break;
6335 }
6336 case OptimizeTransLayer:
6337 {
6338 OptimizeImageTransparency(image,exception);
6339 InheritException(&(image->exception),exception);
6340 break;
6341 }
6342 case RemoveDupsLayer:
6343 {
6344 RemoveDuplicateLayers(&image,exception);
6345 InheritException(&(image->exception),exception);
6346 break;
6347 }
6348 case RemoveZeroLayer:
6349 {
6350 RemoveZeroDelayLayers(&image,exception);
6351 InheritException(&(image->exception),exception);
6352 break;
6353 }
6354 case OptimizeLayer:
6355 {
6356 QuantizeInfo
6357 *quantize_info;
6358
6359 /*
6360 General Purpose, GIF Animation Optimizer.
6361 */
6362 layers=CoalesceImages(image,exception);
6363 if (layers == (Image *) NULL)
6364 break;
6365 InheritException(&(layers->exception),exception);
6366 image=layers;
6367 layers=OptimizeImageLayers(image,exception);
6368 if (layers == (Image *) NULL)
6369 break;
6370 InheritException(&(layers->exception),exception);
6371 image=DestroyImageList(image);
6372 image=layers;
6373 layers=(Image *) NULL;
6374 OptimizeImageTransparency(image,exception);
6375 InheritException(&(image->exception),exception);
6376 quantize_info=AcquireQuantizeInfo(info->image_info);
6377 (void) RemapImages(quantize_info,image,(Image *) NULL);
6378 quantize_info=DestroyQuantizeInfo(quantize_info);
6379 break;
6380 }
6381 case CompositeLayer:
6382 {
6383 Image
6384 *source;
6385
6386 RectangleInfo
6387 geometry;
6388
6389 /*
6390 Split image sequence at the first 'NULL:' image.
6391 */
6392 source=image;
6393 while (source != (Image *) NULL)
6394 {
6395 source=GetNextImageInList(source);
6396 if ((source != (Image *) NULL) &&
6397 (LocaleCompare(source->magick,"NULL") == 0))
6398 break;
6399 }
6400 if (source != (Image *) NULL)
6401 {
6402 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
6403 (GetNextImageInList(source) == (Image *) NULL))
6404 source=(Image *) NULL;
6405 else
6406 {
6407 /*
6408 Separate the two lists, junk the null: image.
6409 */
6410 source=SplitImageList(source->previous);
6411 DeleteImageFromList(&source);
6412 }
6413 }
6414 if (source == (Image *) NULL)
6415 {
6416 (void) ThrowMagickException(exception,GetMagickModule(),
6417 OptionError,"MissingNullSeparator","layers Composite");
6418 break;
6419 }
6420 /*
6421 Adjust offset with gravity and virtual canvas.
6422 */
6423 SetGeometry(image,&geometry);
6424 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
6425 geometry.width=source->page.width != 0 ? source->page.width :
6426 source->columns;
6427 geometry.height=source->page.height != 0 ? source->page.height :
6428 source->rows;
6429 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
6430 image->columns,image->page.height != 0 ? image->page.height :
6431 image->rows,image->gravity,&geometry);
6432 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
6433 source=DestroyImageList(source);
6434 InheritException(&(image->exception),exception);
6435 break;
6436 }
6437 }
6438 if (layers != (Image *) NULL)
6439 {
6440 InheritException(&(layers->exception),exception);
6441 image=layers;
6442 }
6443 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
6444 goto PerlException;
6445 for ( ; image; image=image->next)
6446 {
6447 AddImageToRegistry(image);
6448 rv=newRV(sv);
6449 av_push(av,sv_bless(rv,hv));
6450 SvREFCNT_dec(sv);
6451 }
6452 exception=DestroyExceptionInfo(exception);
6453 ST(0)=av_reference;
6454 SvREFCNT_dec(perl_exception);
6455 XSRETURN(1);
6456
6457 PerlException:
6458 InheritPerlException(exception,perl_exception);
6459 exception=DestroyExceptionInfo(exception);
6460 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
6461 SvPOK_on(perl_exception);
6462 ST(0)=sv_2mortal(perl_exception);
6463 XSRETURN(1);
6464 }
6465
6466#
6467###############################################################################
6468# #
6469# #
6470# #
6471# M a g i c k T o M i m e #
6472# #
6473# #
6474# #
6475###############################################################################
6476#
6477#
6478SV *
6479MagickToMime(ref,name)
6480 Image::Magick ref=NO_INIT
6481 char *name
6482 ALIAS:
6483 magicktomime = 1
6484 CODE:
6485 {
6486 char
6487 *mime;
6488
6489 mime=MagickToMime(name);
6490 RETVAL=newSVpv(mime,0);
6491 mime=(char *) RelinquishMagickMemory(mime);
6492 }
6493 OUTPUT:
6494 RETVAL
6495
6496#
6497###############################################################################
6498# #
6499# #
6500# #
6501# M o g r i f y #
6502# #
6503# #
6504# #
6505###############################################################################
6506#
6507#
6508void
6509Mogrify(ref,...)
6510 Image::Magick ref=NO_INIT
6511 ALIAS:
6512 Comment = 1
6513 CommentImage = 2
6514 Label = 3
6515 LabelImage = 4
6516 AddNoise = 5
6517 AddNoiseImage = 6
6518 Colorize = 7
6519 ColorizeImage = 8
6520 Border = 9
6521 BorderImage = 10
6522 Blur = 11
6523 BlurImage = 12
6524 Chop = 13
6525 ChopImage = 14
6526 Crop = 15
6527 CropImage = 16
6528 Despeckle = 17
6529 DespeckleImage = 18
6530 Edge = 19
6531 EdgeImage = 20
6532 Emboss = 21
6533 EmbossImage = 22
6534 Enhance = 23
6535 EnhanceImage = 24
6536 Flip = 25
6537 FlipImage = 26
6538 Flop = 27
6539 FlopImage = 28
6540 Frame = 29
6541 FrameImage = 30
6542 Implode = 31
6543 ImplodeImage = 32
6544 Magnify = 33
6545 MagnifyImage = 34
6546 MedianFilter = 35
6547 MedianFilterImage = 36
6548 Minify = 37
6549 MinifyImage = 38
6550 OilPaint = 39
6551 OilPaintImage = 40
6552 ReduceNoise = 41
6553 ReduceNoiseImage = 42
6554 Roll = 43
6555 RollImage = 44
6556 Rotate = 45
6557 RotateImage = 46
6558 Sample = 47
6559 SampleImage = 48
6560 Scale = 49
6561 ScaleImage = 50
6562 Shade = 51
6563 ShadeImage = 52
6564 Sharpen = 53
6565 SharpenImage = 54
6566 Shear = 55
6567 ShearImage = 56
6568 Spread = 57
6569 SpreadImage = 58
6570 Swirl = 59
6571 SwirlImage = 60
6572 Resize = 61
6573 ResizeImage = 62
6574 Zoom = 63
6575 ZoomImage = 64
6576 Annotate = 65
6577 AnnotateImage = 66
6578 ColorFloodfill = 67
6579 ColorFloodfillImage= 68
6580 Composite = 69
6581 CompositeImage = 70
6582 Contrast = 71
6583 ContrastImage = 72
6584 CycleColormap = 73
6585 CycleColormapImage = 74
6586 Draw = 75
6587 DrawImage = 76
6588 Equalize = 77
6589 EqualizeImage = 78
6590 Gamma = 79
6591 GammaImage = 80
6592 Map = 81
6593 MapImage = 82
6594 MatteFloodfill = 83
6595 MatteFloodfillImage= 84
6596 Modulate = 85
6597 ModulateImage = 86
6598 Negate = 87
6599 NegateImage = 88
6600 Normalize = 89
6601 NormalizeImage = 90
6602 NumberColors = 91
6603 NumberColorsImage = 92
6604 Opaque = 93
6605 OpaqueImage = 94
6606 Quantize = 95
6607 QuantizeImage = 96
6608 Raise = 97
6609 RaiseImage = 98
6610 Segment = 99
6611 SegmentImage = 100
6612 Signature = 101
6613 SignatureImage = 102
6614 Solarize = 103
6615 SolarizeImage = 104
6616 Sync = 105
6617 SyncImage = 106
6618 Texture = 107
6619 TextureImage = 108
6620 Evaluate = 109
6621 EvaluateImage = 110
6622 Transparent = 111
6623 TransparentImage = 112
6624 Threshold = 113
6625 ThresholdImage = 114
6626 Charcoal = 115
6627 CharcoalImage = 116
6628 Trim = 117
6629 TrimImage = 118
6630 Wave = 119
6631 WaveImage = 120
6632 Separate = 121
6633 SeparateImage = 122
6634 Stereo = 125
6635 StereoImage = 126
6636 Stegano = 127
6637 SteganoImage = 128
6638 Deconstruct = 129
6639 DeconstructImage = 130
6640 GaussianBlur = 131
6641 GaussianBlurImage = 132
6642 Convolve = 133
6643 ConvolveImage = 134
6644 Profile = 135
6645 ProfileImage = 136
6646 UnsharpMask = 137
6647 UnsharpMaskImage = 138
6648 MotionBlur = 139
6649 MotionBlurImage = 140
6650 OrderedDither = 141
6651 OrderedDitherImage = 142
6652 Shave = 143
6653 ShaveImage = 144
6654 Level = 145
6655 LevelImage = 146
6656 Clip = 147
6657 ClipImage = 148
6658 AffineTransform = 149
6659 AffineTransformImage = 150
6660 Difference = 151
6661 DifferenceImage = 152
6662 AdaptiveThreshold = 153
6663 AdaptiveThresholdImage = 154
6664 Resample = 155
6665 ResampleImage = 156
6666 Describe = 157
6667 DescribeImage = 158
6668 BlackThreshold = 159
6669 BlackThresholdImage= 160
6670 WhiteThreshold = 161
6671 WhiteThresholdImage= 162
6672 RadialBlur = 163
6673 RadialBlurImage = 164
6674 Thumbnail = 165
6675 ThumbnailImage = 166
6676 Strip = 167
6677 StripImage = 168
6678 Tint = 169
6679 TintImage = 170
6680 Channel = 171
6681 ChannelImage = 172
6682 Splice = 173
6683 SpliceImage = 174
6684 Posterize = 175
6685 PosterizeImage = 176
6686 Shadow = 177
6687 ShadowImage = 178
6688 Identify = 179
6689 IdentifyImage = 180
6690 SepiaTone = 181
6691 SepiaToneImage = 182
6692 SigmoidalContrast = 183
6693 SigmoidalContrastImage = 184
6694 Extent = 185
6695 ExtentImage = 186
6696 Vignette = 187
6697 VignetteImage = 188
6698 ContrastStretch = 189
6699 ContrastStretchImage = 190
6700 Sans0 = 191
6701 Sans0Image = 192
6702 Sans1 = 193
6703 Sans1Image = 194
6704 AdaptiveSharpen = 195
6705 AdaptiveSharpenImage = 196
6706 Transpose = 197
6707 TransposeImage = 198
6708 Transverse = 199
6709 TransverseImage = 200
6710 AutoOrient = 201
6711 AutoOrientImage = 202
6712 AdaptiveBlur = 203
6713 AdaptiveBlurImage = 204
6714 Sketch = 205
6715 SketchImage = 206
6716 UniqueColors = 207
6717 UniqueColorsImage = 208
6718 AdaptiveResize = 209
6719 AdaptiveResizeImage= 210
6720 ClipMask = 211
6721 ClipMaskImage = 212
6722 LinearStretch = 213
6723 LinearStretchImage = 214
6724 RecolorImage = 215
6725 Recolor = 216
6726 Mask = 217
6727 MaskImage = 218
6728 Polaroid = 219
6729 PolaroidImage = 220
6730 FloodfillPaint = 221
6731 FloodfillPaintImage= 222
6732 Distort = 223
6733 DistortImage = 224
6734 Clut = 225
6735 ClutImage = 226
6736 LiquidRescale = 227
6737 LiquidRescaleImage = 228
6738 Encipher = 229
6739 EncipherImage = 230
6740 Decipher = 231
6741 DecipherImage = 232
6742 Deskew = 233
6743 DeskewImage = 234
6744 Remap = 235
6745 RemapImage = 236
6746 SparseColor = 237
6747 SparseColorImage = 238
6748 Function = 239
6749 FunctionImage = 240
6750 SelectiveBlur = 241
6751 SelectiveBlurImage = 242
6752 HaldClut = 243
6753 HaldClutImage = 244
6754 BlueShift = 245
6755 BlueShiftImage = 246
6756 ForwardFourierTransform = 247
6757 ForwardFourierTransformImage = 248
6758 InverseFourierTransform = 249
6759 InverseFourierTransformImage = 250
6760 ColorDecisionList = 251
6761 ColorDecisionListImage = 252
6762 AutoGamma = 253
6763 AutoGammaImage = 254
6764 AutoLevel = 255
6765 AutoLevelImage = 256
cristyee0f8d72009-09-19 00:58:29 +00006766 LevelColors = 257
6767 LevelColorsImage = 258
cristy1eb45dd2009-09-25 16:38:06 +00006768 Clamp = 259
6769 ClampImage = 260
cristy3ed852e2009-09-05 21:47:34 +00006770 MogrifyRegion = 666
6771 PPCODE:
6772 {
6773 AffineMatrix
6774 affine,
6775 current;
6776
6777 char
6778 attribute_flag[MaxArguments],
6779 message[MaxTextExtent];
6780
6781 ChannelType
6782 channel;
6783
6784 CompositeOperator
6785 compose;
6786
6787 const char
6788 *attribute,
6789 *value;
6790
6791 double
6792 angle;
6793
6794 ExceptionInfo
6795 *exception;
6796
6797 GeometryInfo
6798 geometry_info;
6799
6800 Image
6801 *image,
6802 *next,
6803 *region_image;
6804
6805 long
6806 base,
6807 j,
6808 number_images;
6809
6810 MagickBooleanType
6811 status;
6812
6813 MagickStatusType
6814 flags;
6815
6816 PixelPacket
6817 fill_color;
6818
6819 RectangleInfo
6820 geometry,
6821 region_info;
6822
6823 register long
6824 i;
6825
6826 struct PackageInfo
6827 *info;
6828
6829 struct Methods
6830 *rp;
6831
6832 SV
6833 *perl_exception,
6834 **pv,
6835 *reference,
6836 **reference_vector;
6837
6838 struct ArgumentList
6839 argument_list[MaxArguments];
6840
6841 exception=AcquireExceptionInfo();
6842 perl_exception=newSVpv("",0);
6843 reference_vector=NULL;
6844 region_image=NULL;
6845 number_images=0;
6846 base=2;
6847 if (sv_isobject(ST(0)) == 0)
6848 {
6849 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6850 PackageName);
6851 goto PerlException;
6852 }
6853 reference=SvRV(ST(0));
6854 region_info.width=0;
6855 region_info.height=0;
6856 region_info.x=0;
6857 region_info.y=0;
6858 region_image=(Image *) NULL;
6859 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
6860 if (ix && (ix != 666))
6861 {
6862 /*
6863 Called as Method(...)
6864 */
6865 ix=(ix+1)/2;
6866 rp=(&Methods[ix-1]);
6867 attribute=rp->name;
6868 }
6869 else
6870 {
6871 /*
6872 Called as Mogrify("Method",...)
6873 */
6874 attribute=(char *) SvPV(ST(1),na);
6875 if (ix)
6876 {
6877 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
6878 attribute=(char *) SvPV(ST(2),na);
6879 base++;
6880 }
6881 for (rp=Methods; ; rp++)
6882 {
6883 if (rp >= EndOf(Methods))
6884 {
6885 ThrowPerlException(exception,OptionError,
6886 "UnrecognizedPerlMagickMethod",attribute);
6887 goto PerlException;
6888 }
6889 if (strEQcase(attribute,rp->name))
6890 break;
6891 }
6892 ix=rp-Methods+1;
6893 base++;
6894 }
6895 if (image == (Image *) NULL)
6896 {
6897 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
6898 goto PerlException;
6899 }
6900 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
6901 Zero(&attribute_flag,NumberOf(attribute_flag),char);
6902 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
6903 {
6904 long
6905 longest;
6906
6907 Arguments
6908 *pp,
6909 *qq;
6910
6911 struct ArgumentList
6912 *al;
6913
6914 SV
6915 *sv;
6916
6917 longest=0;
6918 pp=(Arguments *) NULL;
6919 qq=rp->arguments;
6920 if (i == items)
6921 {
6922 pp=rp->arguments,
6923 sv=ST(i-1);
6924 }
6925 else
6926 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
6927 {
6928 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
6929 break;
6930 if (strEQcase(attribute,qq->method) > longest)
6931 {
6932 pp=qq;
6933 longest=strEQcase(attribute,qq->method);
6934 }
6935 }
6936 if (pp == (Arguments *) NULL)
6937 {
6938 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6939 attribute);
6940 goto continue_outer_loop;
6941 }
6942 al=(&argument_list[pp-rp->arguments]);
6943 switch (pp->type)
6944 {
6945 case ArrayReference:
6946 {
6947 if (SvTYPE(sv) != SVt_RV)
6948 {
6949 (void) FormatMagickString(message,MaxTextExtent,
6950 "invalid %.60s value",pp->method);
6951 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
6952 goto continue_outer_loop;
6953 }
6954 al->array_reference=SvRV(sv);
6955 break;
6956 }
6957 case RealReference:
6958 {
6959 al->real_reference=SvNV(sv);
6960 break;
6961 }
6962 case FileReference:
6963 {
6964 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
6965 break;
6966 }
6967 case ImageReference:
6968 {
6969 if (!sv_isobject(sv) ||
6970 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
6971 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
6972 {
6973 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6974 PackageName);
6975 goto PerlException;
6976 }
6977 break;
6978 }
6979 case IntegerReference:
6980 {
6981 al->long_reference=SvIV(sv);
6982 break;
6983 }
6984 case StringReference:
6985 {
6986 al->string_reference=(char *) SvPV(sv,al->length);
6987 if (sv_isobject(sv))
6988 al->image_reference=SetupList(aTHX_ SvRV(sv),
6989 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
6990 break;
6991 }
6992 default:
6993 {
6994 /*
6995 Is a string; look up name.
6996 */
6997 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
6998 {
6999 al->string_reference=(char *) SvPV(sv,al->length);
7000 al->long_reference=(-1);
7001 break;
7002 }
7003 al->long_reference=ParseMagickOption((MagickOption) pp->type,
7004 MagickFalse,SvPV(sv,na));
7005 if (pp->type == MagickChannelOptions)
7006 al->long_reference=ParseChannelOption(SvPV(sv,na));
7007 if ((al->long_reference < 0) && ((al->long_reference=SvIV(sv)) <= 0))
7008 {
7009 (void) FormatMagickString(message,MaxTextExtent,
7010 "invalid %.60s value",pp->method);
7011 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7012 goto continue_outer_loop;
7013 }
7014 break;
7015 }
7016 }
7017 attribute_flag[pp-rp->arguments]++;
7018 continue_outer_loop: ;
7019 }
7020 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7021 pv=reference_vector;
7022 SetGeometryInfo(&geometry_info);
7023 channel=DefaultChannels;
7024 for (next=image; next; next=next->next)
7025 {
7026 image=next;
7027 SetGeometry(image,&geometry);
7028 if ((region_info.width*region_info.height) != 0)
7029 {
7030 region_image=image;
7031 image=CropImage(image,&region_info,exception);
7032 }
7033 switch (ix)
7034 {
7035 default:
7036 {
7037 (void) FormatMagickString(message,MaxTextExtent,"%ld",(long) ix);
7038 ThrowPerlException(exception,OptionError,
7039 "UnrecognizedPerlMagickMethod",message);
7040 goto PerlException;
7041 }
7042 case 1: /* Comment */
7043 {
7044 if (attribute_flag[0] == 0)
7045 argument_list[0].string_reference=(char *) NULL;
7046 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7047 info ? info->image_info : (ImageInfo *) NULL,image,
7048 argument_list[0].string_reference));
7049 break;
7050 }
7051 case 2: /* Label */
7052 {
7053 if (attribute_flag[0] == 0)
7054 argument_list[0].string_reference=(char *) NULL;
7055 (void) SetImageProperty(image,"label",InterpretImageProperties(
7056 info ? info->image_info : (ImageInfo *) NULL,image,
7057 argument_list[0].string_reference));
7058 break;
7059 }
7060 case 3: /* AddNoise */
7061 {
7062 if (attribute_flag[0] == 0)
7063 argument_list[0].long_reference=UniformNoise;
7064 if (attribute_flag[1] != 0)
7065 channel=(ChannelType) argument_list[1].long_reference;
7066 image=AddNoiseImageChannel(image,channel,(NoiseType)
7067 argument_list[0].long_reference,exception);
7068 break;
7069 }
7070 case 4: /* Colorize */
7071 {
7072 PixelPacket
7073 target;
7074
7075 (void) GetOneVirtualPixel(image,0,0,&target,exception);
7076 if (attribute_flag[0] != 0)
7077 (void) QueryColorDatabase(argument_list[0].string_reference,&target,
7078 exception);
7079 if (attribute_flag[1] == 0)
7080 argument_list[1].string_reference="100%";
7081 image=ColorizeImage(image,argument_list[1].string_reference,target,
7082 exception);
7083 break;
7084 }
7085 case 5: /* Border */
7086 {
7087 geometry.width=0;
7088 geometry.height=0;
7089 if (attribute_flag[0] != 0)
7090 {
7091 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7092 &geometry,exception);
7093 if ((flags & HeightValue) == 0)
7094 geometry.height=geometry.width;
7095 }
7096 if (attribute_flag[1] != 0)
7097 geometry.width=argument_list[1].long_reference;
7098 if (attribute_flag[2] != 0)
7099 geometry.height=argument_list[2].long_reference;
7100 if (attribute_flag[3] != 0)
7101 QueryColorDatabase(argument_list[3].string_reference,
7102 &image->border_color,exception);
7103 if (attribute_flag[4] != 0)
7104 QueryColorDatabase(argument_list[4].string_reference,
7105 &image->border_color,exception);
7106 if (attribute_flag[5] != 0)
7107 QueryColorDatabase(argument_list[5].string_reference,
7108 &image->border_color,exception);
7109 if (attribute_flag[6] != 0)
7110 image->compose=(CompositeOperator) argument_list[6].long_reference;
7111 image=BorderImage(image,&geometry,exception);
7112 break;
7113 }
7114 case 6: /* Blur */
7115 {
7116 if (attribute_flag[0] != 0)
7117 {
7118 flags=ParseGeometry(argument_list[0].string_reference,
7119 &geometry_info);
7120 if ((flags & SigmaValue) == 0)
7121 geometry_info.sigma=1.0;
7122 }
7123 if (attribute_flag[1] != 0)
7124 geometry_info.rho=argument_list[1].real_reference;
7125 if (attribute_flag[2] != 0)
7126 geometry_info.sigma=argument_list[2].real_reference;
7127 if (attribute_flag[3] != 0)
7128 channel=(ChannelType) argument_list[3].long_reference;
7129 image=BlurImageChannel(image,channel,geometry_info.rho,
7130 geometry_info.sigma,exception);
7131 break;
7132 }
7133 case 7: /* Chop */
7134 {
7135 if (attribute_flag[0] != 0)
7136 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7137 &geometry,exception);
7138 if (attribute_flag[1] != 0)
7139 geometry.width=argument_list[1].long_reference;
7140 if (attribute_flag[2] != 0)
7141 geometry.height=argument_list[2].long_reference;
7142 if (attribute_flag[3] != 0)
7143 geometry.x=argument_list[3].long_reference;
7144 if (attribute_flag[4] != 0)
7145 geometry.y=argument_list[4].long_reference;
7146 image=ChopImage(image,&geometry,exception);
7147 break;
7148 }
7149 case 8: /* Crop */
7150 {
7151 if (attribute_flag[0] != 0)
7152 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7153 &geometry,exception);
7154 if (attribute_flag[1] != 0)
7155 geometry.width=argument_list[1].long_reference;
7156 if (attribute_flag[2] != 0)
7157 geometry.height=argument_list[2].long_reference;
7158 if (attribute_flag[3] != 0)
7159 geometry.x=argument_list[3].long_reference;
7160 if (attribute_flag[4] != 0)
7161 geometry.y=argument_list[4].long_reference;
7162 if (attribute_flag[5] != 0)
7163 image->fuzz=
7164 StringToDouble(argument_list[5].string_reference,QuantumRange);
7165 image=CropImage(image,&geometry,exception);
7166 break;
7167 }
7168 case 9: /* Despeckle */
7169 {
7170 image=DespeckleImage(image,exception);
7171 break;
7172 }
7173 case 10: /* Edge */
7174 {
7175 if (attribute_flag[0] != 0)
7176 geometry_info.rho=argument_list[0].real_reference;
7177 image=EdgeImage(image,geometry_info.rho,exception);
7178 break;
7179 }
7180 case 11: /* Emboss */
7181 {
7182 if (attribute_flag[0] != 0)
7183 {
7184 flags=ParseGeometry(argument_list[0].string_reference,
7185 &geometry_info);
7186 if ((flags & SigmaValue) == 0)
7187 geometry_info.sigma=1.0;
7188 }
7189 if (attribute_flag[1] != 0)
7190 geometry_info.rho=argument_list[1].real_reference;
7191 if (attribute_flag[2] != 0)
7192 geometry_info.sigma=argument_list[2].real_reference;
7193 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
7194 exception);
7195 break;
7196 }
7197 case 12: /* Enhance */
7198 {
7199 image=EnhanceImage(image,exception);
7200 break;
7201 }
7202 case 13: /* Flip */
7203 {
7204 image=FlipImage(image,exception);
7205 break;
7206 }
7207 case 14: /* Flop */
7208 {
7209 image=FlopImage(image,exception);
7210 break;
7211 }
7212 case 15: /* Frame */
7213 {
7214 FrameInfo
7215 frame_info;
7216
7217 if (attribute_flag[0] != 0)
7218 {
7219 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7220 &geometry,exception);
7221 if ((flags & HeightValue) == 0)
7222 geometry.height=geometry.width;
7223 frame_info.width=geometry.width;
7224 frame_info.height=geometry.height;
7225 frame_info.outer_bevel=geometry.x;
7226 frame_info.inner_bevel=geometry.y;
7227 }
7228 if (attribute_flag[1] != 0)
7229 frame_info.width=argument_list[1].long_reference;
7230 if (attribute_flag[2] != 0)
7231 frame_info.height=argument_list[2].long_reference;
7232 if (attribute_flag[3] != 0)
7233 frame_info.inner_bevel=argument_list[3].long_reference;
7234 if (attribute_flag[4] != 0)
7235 frame_info.outer_bevel=argument_list[4].long_reference;
7236 if (attribute_flag[5] != 0)
7237 QueryColorDatabase(argument_list[5].string_reference,&fill_color,
7238 exception);
7239 if (attribute_flag[6] != 0)
7240 QueryColorDatabase(argument_list[6].string_reference,&fill_color,
7241 exception);
7242 frame_info.x=(long) frame_info.width;
7243 frame_info.y=(long) frame_info.height;
7244 frame_info.width=image->columns+2*frame_info.x;
7245 frame_info.height=image->rows+2*frame_info.y;
7246 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
7247 image->matte_color=fill_color;
7248 if (attribute_flag[7] != 0)
7249 image->compose=(CompositeOperator) argument_list[7].long_reference;
7250 image=FrameImage(image,&frame_info,exception);
7251 break;
7252 }
7253 case 16: /* Implode */
7254 {
7255 if (attribute_flag[0] == 0)
7256 argument_list[0].real_reference=0.5;
7257 if (attribute_flag[1] != 0)
7258 image->interpolate=(InterpolatePixelMethod)
7259 argument_list[1].long_reference;
7260 image=ImplodeImage(image,argument_list[0].real_reference,
7261 exception);
7262 break;
7263 }
7264 case 17: /* Magnify */
7265 {
7266 image=MagnifyImage(image,exception);
7267 break;
7268 }
7269 case 18: /* MedianFilter */
7270 {
7271 if (attribute_flag[0] == 0)
7272 argument_list[0].real_reference=0.0;
7273 image=MedianFilterImage(image,argument_list[0].real_reference,
7274 exception);
7275 break;
7276 }
7277 case 19: /* Minify */
7278 {
7279 image=MinifyImage(image,exception);
7280 break;
7281 }
7282 case 20: /* OilPaint */
7283 {
7284 if (attribute_flag[0] == 0)
7285 argument_list[0].real_reference=0.0;
7286 image=OilPaintImage(image,argument_list[0].real_reference,
7287 exception);
7288 break;
7289 }
7290 case 21: /* ReduceNoise */
7291 {
7292 if (attribute_flag[0] == 0)
7293 argument_list[0].real_reference=0.0;
7294 image=ReduceNoiseImage(image,argument_list[0].real_reference,
7295 exception);
7296 break;
7297 }
7298 case 22: /* Roll */
7299 {
7300 if (attribute_flag[0] != 0)
7301 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7302 &geometry,exception);
7303 if (attribute_flag[1] != 0)
7304 geometry.x=argument_list[1].long_reference;
7305 if (attribute_flag[2] != 0)
7306 geometry.y=argument_list[2].long_reference;
7307 image=RollImage(image,geometry.x,geometry.y,exception);
7308 break;
7309 }
7310 case 23: /* Rotate */
7311 {
7312 if (attribute_flag[0] == 0)
7313 argument_list[0].real_reference=90.0;
7314 if (attribute_flag[1] != 0)
7315 QueryColorDatabase(argument_list[1].string_reference,
7316 &image->background_color,exception);
7317 if (attribute_flag[2] != 0)
7318 QueryColorDatabase(argument_list[2].string_reference,
7319 &image->background_color,exception);
7320 if (attribute_flag[3] != 0)
7321 QueryColorDatabase(argument_list[3].string_reference,
7322 &image->background_color,exception);
7323 image=RotateImage(image,argument_list[0].real_reference,exception);
7324 break;
7325 }
7326 case 24: /* Sample */
7327 {
7328 if (attribute_flag[0] != 0)
7329 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7330 &geometry,exception);
7331 if (attribute_flag[1] != 0)
7332 geometry.width=argument_list[1].long_reference;
7333 if (attribute_flag[2] != 0)
7334 geometry.height=argument_list[2].long_reference;
7335 image=SampleImage(image,geometry.width,geometry.height,exception);
7336 break;
7337 }
7338 case 25: /* Scale */
7339 {
7340 if (attribute_flag[0] != 0)
7341 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7342 &geometry,exception);
7343 if (attribute_flag[1] != 0)
7344 geometry.width=argument_list[1].long_reference;
7345 if (attribute_flag[2] != 0)
7346 geometry.height=argument_list[2].long_reference;
7347 image=ScaleImage(image,geometry.width,geometry.height,exception);
7348 break;
7349 }
7350 case 26: /* Shade */
7351 {
7352 if (attribute_flag[0] != 0)
7353 {
7354 flags=ParseGeometry(argument_list[0].string_reference,
7355 &geometry_info);
7356 if ((flags & SigmaValue) == 0)
7357 geometry_info.sigma=0.0;
7358 }
7359 if (attribute_flag[1] != 0)
7360 geometry_info.rho=argument_list[1].real_reference;
7361 if (attribute_flag[2] != 0)
7362 geometry_info.sigma=argument_list[2].real_reference;
7363 image=ShadeImage(image,
7364 argument_list[3].long_reference != 0 ? MagickTrue : MagickFalse,
7365 geometry_info.rho,geometry_info.sigma,exception);
7366 break;
7367 }
7368 case 27: /* Sharpen */
7369 {
7370 if (attribute_flag[0] != 0)
7371 {
7372 flags=ParseGeometry(argument_list[0].string_reference,
7373 &geometry_info);
7374 if ((flags & SigmaValue) == 0)
7375 geometry_info.sigma=1.0;
7376 }
7377 if (attribute_flag[1] != 0)
7378 geometry_info.rho=argument_list[1].real_reference;
7379 if (attribute_flag[2] != 0)
7380 geometry_info.sigma=argument_list[2].real_reference;
7381 if (attribute_flag[3] != 0)
7382 channel=(ChannelType) argument_list[3].long_reference;
7383 image=SharpenImageChannel(image,channel,geometry_info.rho,
7384 geometry_info.sigma,exception);
7385 break;
7386 }
7387 case 28: /* Shear */
7388 {
7389 if (attribute_flag[0] != 0)
7390 {
7391 flags=ParseGeometry(argument_list[0].string_reference,
7392 &geometry_info);
7393 if ((flags & SigmaValue) == 0)
7394 geometry_info.sigma=geometry_info.rho;
7395 }
7396 if (attribute_flag[1] != 0)
7397 geometry_info.rho=argument_list[1].real_reference;
7398 if (attribute_flag[2] != 0)
7399 geometry_info.sigma=argument_list[2].real_reference;
7400 if (attribute_flag[3] != 0)
7401 QueryColorDatabase(argument_list[3].string_reference,
7402 &image->background_color,exception);
7403 if (attribute_flag[4] != 0)
7404 QueryColorDatabase(argument_list[4].string_reference,
7405 &image->background_color,exception);
7406 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
7407 exception);
7408 break;
7409 }
7410 case 29: /* Spread */
7411 {
7412 if (attribute_flag[0] == 0)
7413 argument_list[0].real_reference=1.0;
7414 image=SpreadImage(image,argument_list[0].real_reference,exception);
7415 break;
7416 }
7417 case 30: /* Swirl */
7418 {
7419 if (attribute_flag[0] == 0)
7420 argument_list[0].real_reference=50.0;
7421 if (attribute_flag[1] != 0)
7422 image->interpolate=(InterpolatePixelMethod)
7423 argument_list[1].long_reference;
7424 image=SwirlImage(image,argument_list[0].real_reference,exception);
7425 break;
7426 }
7427 case 31: /* Resize */
7428 case 32: /* Zoom */
7429 {
7430 if (attribute_flag[0] != 0)
7431 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7432 &geometry,exception);
7433 if (attribute_flag[1] != 0)
7434 geometry.width=argument_list[1].long_reference;
7435 if (attribute_flag[2] != 0)
7436 geometry.height=argument_list[2].long_reference;
7437 if (attribute_flag[3] == 0)
7438 argument_list[3].long_reference=(long) UndefinedFilter;
7439 if (attribute_flag[4] != 0)
7440 SetImageArtifact(image,"filter:support",
7441 argument_list[4].string_reference);
7442 if (attribute_flag[5] == 0)
7443 argument_list[5].real_reference=1.0;
7444 image=ResizeImage(image,geometry.width,geometry.height,
7445 (FilterTypes) argument_list[3].long_reference,
7446 argument_list[5].real_reference,exception);
7447 break;
7448 }
7449 case 33: /* Annotate */
7450 {
7451 DrawInfo
7452 *draw_info;
7453
7454 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
7455 (DrawInfo *) NULL);
7456 if (attribute_flag[0] != 0)
7457 {
7458 char
7459 *text;
7460
7461 text=InterpretImageProperties(info ? info->image_info :
7462 (ImageInfo *) NULL,image,argument_list[0].string_reference);
7463 (void) CloneString(&draw_info->text,text);
7464 text=DestroyString(text);
7465 }
7466 if (attribute_flag[1] != 0)
7467 (void) CloneString(&draw_info->font,
7468 argument_list[1].string_reference);
7469 if (attribute_flag[2] != 0)
7470 draw_info->pointsize=argument_list[2].real_reference;
7471 if (attribute_flag[3] != 0)
7472 (void) CloneString(&draw_info->density,
7473 argument_list[3].string_reference);
7474 if (attribute_flag[4] != 0)
7475 (void) QueryColorDatabase(argument_list[4].string_reference,
7476 &draw_info->undercolor,exception);
7477 if (attribute_flag[5] != 0)
7478 {
7479 (void) QueryColorDatabase(argument_list[5].string_reference,
7480 &draw_info->stroke,exception);
7481 if (argument_list[5].image_reference != (Image *) NULL)
7482 draw_info->stroke_pattern=CloneImage(
7483 argument_list[5].image_reference,0,0,MagickTrue,exception);
7484 }
7485 if (attribute_flag[6] != 0)
7486 {
7487 (void) QueryColorDatabase(argument_list[6].string_reference,
7488 &draw_info->fill,exception);
7489 if (argument_list[6].image_reference != (Image *) NULL)
7490 draw_info->fill_pattern=CloneImage(
7491 argument_list[6].image_reference,0,0,MagickTrue,exception);
7492 }
7493 if (attribute_flag[7] != 0)
7494 {
7495 (void) CloneString(&draw_info->geometry,
7496 argument_list[7].string_reference);
7497 flags=ParsePageGeometry(image,argument_list[7].string_reference,
7498 &geometry,exception);
7499 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
7500 geometry_info.sigma=geometry_info.xi;
7501 }
7502 if (attribute_flag[8] != 0)
7503 (void) QueryColorDatabase(argument_list[8].string_reference,
7504 &draw_info->fill,exception);
7505 if (attribute_flag[11] != 0)
7506 draw_info->gravity=(GravityType) argument_list[11].long_reference;
7507 if (attribute_flag[25] != 0)
7508 {
7509 AV
7510 *av;
7511
7512 av=(AV *) argument_list[25].array_reference;
7513 if ((av_len(av) != 3) && (av_len(av) != 5))
7514 {
7515 ThrowPerlException(exception,OptionError,
7516 "affine matrix must have 4 or 6 elements",PackageName);
7517 goto PerlException;
7518 }
7519 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
7520 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
7521 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
7522 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
7523 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
7524 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
7525 {
7526 ThrowPerlException(exception,OptionError,
7527 "affine matrix is singular",PackageName);
7528 goto PerlException;
7529 }
7530 if (av_len(av) == 5)
7531 {
7532 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
7533 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
7534 }
7535 }
7536 for (j=12; j < 17; j++)
7537 {
7538 if (attribute_flag[j] == 0)
7539 continue;
7540 value=argument_list[j].string_reference;
7541 angle=argument_list[j].real_reference;
7542 current=draw_info->affine;
7543 GetAffineMatrix(&affine);
7544 switch (j)
7545 {
7546 case 12:
7547 {
7548 /*
7549 Translate.
7550 */
7551 flags=ParseGeometry(value,&geometry_info);
7552 affine.tx=geometry_info.xi;
7553 affine.ty=geometry_info.psi;
7554 if ((flags & PsiValue) == 0)
7555 affine.ty=affine.tx;
7556 break;
7557 }
7558 case 13:
7559 {
7560 /*
7561 Scale.
7562 */
7563 flags=ParseGeometry(value,&geometry_info);
7564 affine.sx=geometry_info.rho;
7565 affine.sy=geometry_info.sigma;
7566 if ((flags & SigmaValue) == 0)
7567 affine.sy=affine.sx;
7568 break;
7569 }
7570 case 14:
7571 {
7572 /*
7573 Rotate.
7574 */
7575 if (angle == 0.0)
7576 break;
7577 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
7578 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
7579 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
7580 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
7581 break;
7582 }
7583 case 15:
7584 {
7585 /*
7586 SkewX.
7587 */
7588 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
7589 break;
7590 }
7591 case 16:
7592 {
7593 /*
7594 SkewY.
7595 */
7596 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
7597 break;
7598 }
7599 }
7600 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
7601 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
7602 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
7603 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
7604 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
7605 current.tx;
7606 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
7607 current.ty;
7608 }
7609 if (attribute_flag[9] == 0)
7610 argument_list[9].real_reference=0.0;
7611 if (attribute_flag[10] == 0)
7612 argument_list[10].real_reference=0.0;
7613 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
7614 {
7615 char
7616 geometry[MaxTextExtent];
7617
7618 (void) FormatMagickString(geometry,MaxTextExtent,"%+f%+f",
7619 (double) argument_list[9].real_reference+draw_info->affine.tx,
7620 (double) argument_list[10].real_reference+draw_info->affine.ty);
7621 (void) CloneString(&draw_info->geometry,geometry);
7622 }
7623 if (attribute_flag[17] != 0)
7624 draw_info->stroke_width=argument_list[17].real_reference;
7625 if (attribute_flag[18] != 0)
7626 {
7627 draw_info->text_antialias=argument_list[18].long_reference != 0 ?
7628 MagickTrue : MagickFalse;
7629 draw_info->stroke_antialias=draw_info->text_antialias;
7630 }
7631 if (attribute_flag[19] != 0)
7632 (void) CloneString(&draw_info->family,
7633 argument_list[19].string_reference);
7634 if (attribute_flag[20] != 0)
7635 draw_info->style=(StyleType) argument_list[20].long_reference;
7636 if (attribute_flag[21] != 0)
7637 draw_info->stretch=(StretchType) argument_list[21].long_reference;
7638 if (attribute_flag[22] != 0)
7639 draw_info->weight=argument_list[22].long_reference;
7640 if (attribute_flag[23] != 0)
7641 draw_info->align=(AlignType) argument_list[23].long_reference;
7642 if (attribute_flag[24] != 0)
7643 (void) CloneString(&draw_info->encoding,
7644 argument_list[24].string_reference);
7645 if (attribute_flag[25] != 0)
7646 draw_info->fill_pattern=CloneImage(
7647 argument_list[25].image_reference,0,0,MagickTrue,exception);
7648 if (attribute_flag[26] != 0)
7649 draw_info->fill_pattern=CloneImage(
7650 argument_list[26].image_reference,0,0,MagickTrue,exception);
7651 if (attribute_flag[27] != 0)
7652 draw_info->stroke_pattern=CloneImage(
7653 argument_list[27].image_reference,0,0,MagickTrue,exception);
7654 if (attribute_flag[29] != 0)
7655 draw_info->kerning=argument_list[29].real_reference;
7656 if (attribute_flag[30] != 0)
cristyb32b90a2009-09-07 21:45:48 +00007657 draw_info->interline_spacing=argument_list[30].real_reference;
7658 if (attribute_flag[31] != 0)
7659 draw_info->interword_spacing=argument_list[31].real_reference;
cristy3ed852e2009-09-05 21:47:34 +00007660 (void) AnnotateImage(image,draw_info);
7661 draw_info=DestroyDrawInfo(draw_info);
7662 break;
7663 }
7664 case 34: /* ColorFloodfill */
7665 {
7666 DrawInfo
7667 *draw_info;
7668
7669 MagickBooleanType
7670 invert;
7671
7672 MagickPixelPacket
7673 target;
7674
7675 draw_info=CloneDrawInfo(info ? info->image_info :
7676 (ImageInfo *) NULL,(DrawInfo *) NULL);
7677 if (attribute_flag[0] != 0)
7678 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7679 &geometry,exception);
7680 if (attribute_flag[1] != 0)
7681 geometry.x=argument_list[1].long_reference;
7682 if (attribute_flag[2] != 0)
7683 geometry.y=argument_list[2].long_reference;
7684 if (attribute_flag[3] != 0)
7685 (void) QueryColorDatabase(argument_list[3].string_reference,
7686 &draw_info->fill,exception);
7687 (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target,
7688 exception);
7689 invert=MagickFalse;
7690 if (attribute_flag[4] != 0)
7691 {
7692 QueryMagickColor(argument_list[4].string_reference,&target,
7693 exception);
7694 invert=MagickTrue;
7695 }
7696 if (attribute_flag[5] != 0)
7697 image->fuzz=StringToDouble(argument_list[5].string_reference,
7698 QuantumRange);
7699 if (attribute_flag[6] != 0)
7700 invert=(MagickBooleanType) argument_list[6].long_reference;
7701 (void) FloodfillPaintImage(image,DefaultChannels,draw_info,&target,
7702 geometry.x,geometry.y,invert);
7703 draw_info=DestroyDrawInfo(draw_info);
7704 break;
7705 }
7706 case 35: /* Composite */
7707 {
7708 char
7709 composite_geometry[MaxTextExtent];
7710
7711 Image
7712 *composite_image,
7713 *rotate_image;
7714
7715 compose=OverCompositeOp;
7716 if (attribute_flag[0] != 0)
7717 composite_image=argument_list[0].image_reference;
7718 else
7719 {
7720 ThrowPerlException(exception,OptionError,
7721 "CompositeImageRequired",PackageName);
7722 goto PerlException;
7723 }
7724 /*
7725 Parameter Handling used for BOTH normal and tiled composition.
7726 */
7727 if (attribute_flag[1] != 0) /* compose */
7728 compose=(CompositeOperator) argument_list[1].long_reference;
7729 if (attribute_flag[6] != 0) /* opacity */
7730 {
7731 if (compose != DissolveCompositeOp)
7732 (void) SetImageOpacity(composite_image,(Quantum) (QuantumRange-
7733 StringToDouble(argument_list[6].string_reference,
7734 QuantumRange)));
7735 else
7736 {
7737 double
7738 opacity;
7739
7740 long
7741 y;
7742
7743 MagickBooleanType
7744 sync;
7745
7746 register long
7747 x;
7748
7749 register PixelPacket
7750 *q;
7751
7752 CacheView
7753 *composite_view;
7754
7755 /*
7756 Handle dissolve composite operator (patch by
7757 Kevin A. McGrail).
7758 */
7759 (void) CloneString(&image->geometry,
7760 argument_list[6].string_reference);
7761 opacity=(Quantum) (QuantumRange-StringToDouble(
7762 argument_list[6].string_reference,QuantumRange));
7763 if (composite_image->matte != MagickTrue)
7764 (void) SetImageOpacity(composite_image,OpaqueOpacity);
7765 composite_view=OpenCacheView(composite_image);
7766 for (y=0; y < (long) composite_image->rows ; y++)
7767 {
7768 q=GetCacheViewPixels(composite_view,0,y,(long)
7769 composite_image->columns,1);
7770 for (x=0; x < (long) composite_image->columns; x++)
7771 {
7772 if (q->opacity == OpaqueOpacity)
7773 q->opacity=RoundToQuantum(opacity);
7774 q++;
7775 }
7776 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
7777 if (sync == MagickFalse)
7778 break;
7779 }
7780 composite_view=CloseCacheView(composite_view);
7781 }
7782 }
7783 if (attribute_flag[9] != 0) /* "color=>" */
7784 QueryColorDatabase(argument_list[9].string_reference,
7785 &composite_image->background_color,exception);
7786 if (attribute_flag[12] != 0) /* "interpolate=>" */
7787 image->interpolate=(InterpolatePixelMethod)
7788 argument_list[12].long_reference;
7789 if (attribute_flag[13] != 0) /* "args=>" */
7790 (void) SetImageArtifact(composite_image,"compose:args",
7791 argument_list[13].string_reference);
7792 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
7793 (void) SetImageArtifact(composite_image,"compose:args",
7794 argument_list[14].string_reference);
7795 /*
7796 Tiling Composition (with orthogonal rotate).
7797 */
7798 rotate_image=(Image *) NULL;
7799 if (attribute_flag[8] != 0) /* "rotate=>" */
7800 {
7801 /*
7802 Rotate image.
7803 */
7804 rotate_image=RotateImage(composite_image,
7805 argument_list[8].real_reference,exception);
7806 if (rotate_image == (Image *) NULL)
7807 break;
7808 }
7809 if (attribute_flag[7] && argument_list[7].long_reference) /* tile */
7810 {
7811 long
7812 x,
7813 y;
7814
7815 /*
7816 Tile the composite image.
7817 */
7818 if (attribute_flag[8] != 0) /* "tile=>" */
7819 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
7820 "false");
7821 else
7822 (void) SetImageArtifact(composite_image,
7823 "compose:outside-overlay","false");
7824 for (y=0; y < (long) image->rows; y+=composite_image->rows)
7825 for (x=0; x < (long) image->columns; x+=composite_image->columns)
7826 {
7827 if (attribute_flag[8] != 0) /* rotate */
7828 (void) CompositeImage(image,compose,rotate_image,x,y);
7829 else
7830 (void) CompositeImage(image,compose,composite_image,x,y);
7831 }
7832 if (attribute_flag[8] != 0) /* rotate */
7833 rotate_image=DestroyImage(rotate_image);
7834 break;
7835 }
7836 /*
7837 Parameter Handling used used ONLY for normal composition.
7838 */
7839 if (attribute_flag[5] != 0) /* gravity */
7840 image->gravity=(GravityType) argument_list[5].long_reference;
7841 if (attribute_flag[2] != 0) /* geometry offset */
7842 {
7843 SetGeometry(image,&geometry);
7844 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
7845 &geometry);
7846 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
7847 &geometry);
7848 }
7849 if (attribute_flag[3] != 0) /* x offset */
7850 geometry.x=argument_list[3].long_reference;
7851 if (attribute_flag[4] != 0) /* y offset */
7852 geometry.y=argument_list[4].long_reference;
7853 if (attribute_flag[10] != 0) /* mask */
7854 {
7855 if ((image->compose == DisplaceCompositeOp) ||
7856 (image->compose == DistortCompositeOp))
7857 {
7858 /*
7859 Merge Y displacement into X displacement image.
7860 */
7861 composite_image=CloneImage(composite_image,0,0,MagickTrue,
7862 &image->exception);
7863 (void) CompositeImage(composite_image,CopyGreenCompositeOp,
7864 argument_list[10].image_reference,0,0);
7865 }
7866 else
7867 {
7868 /*
7869 Set a blending mask for the composition.
7870 */
7871 image->mask=CloneImage(argument_list[10].image_reference,0,0,
7872 MagickTrue,&image->exception);
7873 (void) NegateImage(image->mask,MagickFalse);
7874 }
7875 }
7876 if (attribute_flag[11] != 0) /* channel */
7877 channel=(ChannelType) argument_list[11].long_reference;
7878 /*
7879 Composite two images (normal composition).
7880 */
7881 (void) FormatMagickString(composite_geometry,MaxTextExtent,
7882 "%lux%lu%+ld%+ld",composite_image->columns,composite_image->rows,
7883 geometry.x,geometry.y);
7884 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
7885 exception);
7886 if (attribute_flag[8] == 0) /* no rotate */
7887 CompositeImageChannel(image,channel,compose,composite_image,
7888 geometry.x,geometry.y);
7889 else
7890 {
7891 /*
7892 Position adjust rotated image then composite.
7893 */
7894 geometry.x-=(long) (rotate_image->columns-
7895 composite_image->columns)/2;
7896 geometry.y-=(long) (rotate_image->rows-composite_image->rows)/2;
7897 CompositeImageChannel(image,channel,compose,rotate_image,
7898 geometry.x,geometry.y);
7899 rotate_image=DestroyImage(rotate_image);
7900 }
7901 if (attribute_flag[10] != 0) /* mask */
7902 {
7903 if ((image->compose == DisplaceCompositeOp) ||
7904 (image->compose == DistortCompositeOp))
7905 composite_image=DestroyImage(composite_image);
7906 else
7907 image->mask=DestroyImage(image->mask);
7908 }
7909 break;
7910 }
7911 case 36: /* Contrast */
7912 {
7913 if (attribute_flag[0] == 0)
7914 argument_list[0].long_reference=0;
7915 (void) ContrastImage(image,argument_list[0].long_reference != 0 ?
7916 MagickTrue : MagickFalse);
7917 break;
7918 }
7919 case 37: /* CycleColormap */
7920 {
7921 if (attribute_flag[0] == 0)
7922 argument_list[0].long_reference=6;
7923 (void) CycleColormapImage(image,argument_list[0].long_reference);
7924 break;
7925 }
7926 case 38: /* Draw */
7927 {
7928 DrawInfo
7929 *draw_info;
7930
7931 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
7932 (DrawInfo *) NULL);
7933 (void) CloneString(&draw_info->primitive,"point");
7934 if (attribute_flag[0] != 0)
7935 {
7936 if (argument_list[0].long_reference < 0)
7937 (void) CloneString(&draw_info->primitive,
7938 argument_list[0].string_reference);
7939 else
7940 (void) CloneString(&draw_info->primitive,MagickOptionToMnemonic(
7941 MagickPrimitiveOptions,argument_list[0].long_reference));
7942 }
7943 if (attribute_flag[1] != 0)
7944 {
7945 if (LocaleCompare(draw_info->primitive,"path") == 0)
7946 {
7947 (void) ConcatenateString(&draw_info->primitive," '");
7948 ConcatenateString(&draw_info->primitive,
7949 argument_list[1].string_reference);
7950 (void) ConcatenateString(&draw_info->primitive,"'");
7951 }
7952 else
7953 {
7954 (void) ConcatenateString(&draw_info->primitive," ");
7955 ConcatenateString(&draw_info->primitive,
7956 argument_list[1].string_reference);
7957 }
7958 }
7959 if (attribute_flag[2] != 0)
7960 {
7961 (void) ConcatenateString(&draw_info->primitive," ");
7962 (void) ConcatenateString(&draw_info->primitive,
7963 MagickOptionToMnemonic(MagickMethodOptions,
7964 argument_list[2].long_reference));
7965 }
7966 if (attribute_flag[3] != 0)
7967 {
7968 (void) QueryColorDatabase(argument_list[3].string_reference,
7969 &draw_info->stroke,exception);
7970 if (argument_list[3].image_reference != (Image *) NULL)
7971 draw_info->stroke_pattern=CloneImage(
7972 argument_list[3].image_reference,0,0,MagickTrue,exception);
7973 }
7974 if (attribute_flag[4] != 0)
7975 {
7976 (void) QueryColorDatabase(argument_list[4].string_reference,
7977 &draw_info->fill,exception);
7978 if (argument_list[4].image_reference != (Image *) NULL)
7979 draw_info->fill_pattern=CloneImage(
7980 argument_list[4].image_reference,0,0,MagickTrue,exception);
7981 }
7982 if (attribute_flag[5] != 0)
7983 draw_info->stroke_width=argument_list[5].real_reference;
7984 if (attribute_flag[6] != 0)
7985 (void) CloneString(&draw_info->font,
7986 argument_list[6].string_reference);
7987 if (attribute_flag[7] != 0)
7988 (void) QueryColorDatabase(argument_list[7].string_reference,
7989 &draw_info->border_color,exception);
7990 if (attribute_flag[8] != 0)
7991 draw_info->affine.tx=argument_list[8].real_reference;
7992 if (attribute_flag[9] != 0)
7993 draw_info->affine.ty=argument_list[9].real_reference;
7994 if (attribute_flag[20] != 0)
7995 {
7996 AV
7997 *av;
7998
7999 av=(AV *) argument_list[20].array_reference;
8000 if ((av_len(av) != 3) && (av_len(av) != 5))
8001 {
8002 ThrowPerlException(exception,OptionError,
8003 "affine matrix must have 4 or 6 elements",PackageName);
8004 goto PerlException;
8005 }
8006 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8007 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8008 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8009 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8010 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8011 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8012 {
8013 ThrowPerlException(exception,OptionError,
8014 "affine matrix is singular",PackageName);
8015 goto PerlException;
8016 }
8017 if (av_len(av) == 5)
8018 {
8019 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8020 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8021 }
8022 }
8023 for (j=10; j < 15; j++)
8024 {
8025 if (attribute_flag[j] == 0)
8026 continue;
8027 value=argument_list[j].string_reference;
8028 angle=argument_list[j].real_reference;
8029 current=draw_info->affine;
8030 GetAffineMatrix(&affine);
8031 switch (j)
8032 {
8033 case 10:
8034 {
8035 /*
8036 Translate.
8037 */
8038 flags=ParseGeometry(value,&geometry_info);
8039 affine.tx=geometry_info.xi;
8040 affine.ty=geometry_info.psi;
8041 if ((flags & PsiValue) == 0)
8042 affine.ty=affine.tx;
8043 break;
8044 }
8045 case 11:
8046 {
8047 /*
8048 Scale.
8049 */
8050 flags=ParseGeometry(value,&geometry_info);
8051 affine.sx=geometry_info.rho;
8052 affine.sy=geometry_info.sigma;
8053 if ((flags & SigmaValue) == 0)
8054 affine.sy=affine.sx;
8055 break;
8056 }
8057 case 12:
8058 {
8059 /*
8060 Rotate.
8061 */
8062 if (angle == 0.0)
8063 break;
8064 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8065 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8066 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8067 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8068 break;
8069 }
8070 case 13:
8071 {
8072 /*
8073 SkewX.
8074 */
8075 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8076 break;
8077 }
8078 case 14:
8079 {
8080 /*
8081 SkewY.
8082 */
8083 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8084 break;
8085 }
8086 }
8087 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8088 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8089 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8090 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8091 draw_info->affine.tx=
8092 current.sx*affine.tx+current.ry*affine.ty+current.tx;
8093 draw_info->affine.ty=
8094 current.rx*affine.tx+current.sy*affine.ty+current.ty;
8095 }
8096 if (attribute_flag[15] != 0)
8097 draw_info->fill_pattern=CloneImage(
8098 argument_list[15].image_reference,0,0,MagickTrue,exception);
8099 if (attribute_flag[16] != 0)
8100 draw_info->pointsize=argument_list[16].real_reference;
8101 if (attribute_flag[17] != 0)
8102 {
8103 draw_info->stroke_antialias=argument_list[17].long_reference != 0
8104 ? MagickTrue : MagickFalse;
8105 draw_info->text_antialias=draw_info->stroke_antialias;
8106 }
8107 if (attribute_flag[18] != 0)
8108 (void) CloneString(&draw_info->density,
8109 argument_list[18].string_reference);
8110 if (attribute_flag[19] != 0)
8111 draw_info->stroke_width=argument_list[19].real_reference;
8112 if (attribute_flag[21] != 0)
8113 draw_info->dash_offset=argument_list[21].real_reference;
8114 if (attribute_flag[22] != 0)
8115 {
8116 AV
8117 *av;
8118
8119 av=(AV *) argument_list[22].array_reference;
8120 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
8121 av_len(av)+1UL,sizeof(draw_info->dash_pattern));
8122 if (draw_info->dash_pattern != (double *) NULL)
8123 {
8124 for (i=0; i <= av_len(av); i++)
8125 draw_info->dash_pattern[i]=(double)
8126 SvNV(*(av_fetch(av,i,0)));
8127 draw_info->dash_pattern[i]=0.0;
8128 }
8129 }
8130 if (attribute_flag[23] != 0)
8131 image->interpolate=(InterpolatePixelMethod)
8132 argument_list[23].long_reference;
8133 if ((attribute_flag[24] != 0) &&
8134 (draw_info->fill_pattern != (Image *) NULL))
8135 flags=ParsePageGeometry(draw_info->fill_pattern,
8136 argument_list[24].string_reference,
8137 &draw_info->fill_pattern->tile_offset,exception);
8138 if (attribute_flag[25] != 0)
8139 {
8140 (void) ConcatenateString(&draw_info->primitive," '");
8141 (void) ConcatenateString(&draw_info->primitive,
8142 argument_list[25].string_reference);
8143 (void) ConcatenateString(&draw_info->primitive,"'");
8144 }
8145 if (attribute_flag[26] != 0)
8146 draw_info->fill_pattern=CloneImage(
8147 argument_list[26].image_reference,0,0,MagickTrue,exception);
8148 if (attribute_flag[27] != 0)
8149 draw_info->stroke_pattern=CloneImage(
8150 argument_list[27].image_reference,0,0,MagickTrue,exception);
8151 if (attribute_flag[28] != 0)
8152 (void) CloneString(&draw_info->primitive,
8153 argument_list[28].string_reference);
8154 if (attribute_flag[29] != 0)
8155 draw_info->kerning=argument_list[29].real_reference;
8156 if (attribute_flag[30] != 0)
cristyb32b90a2009-09-07 21:45:48 +00008157 draw_info->interline_spacing=argument_list[30].real_reference;
8158 if (attribute_flag[31] != 0)
8159 draw_info->interword_spacing=argument_list[31].real_reference;
cristy3ed852e2009-09-05 21:47:34 +00008160 DrawImage(image,draw_info);
8161 draw_info=DestroyDrawInfo(draw_info);
8162 break;
8163 }
8164 case 39: /* Equalize */
8165 {
8166 if (attribute_flag[0] != 0)
8167 channel=(ChannelType) argument_list[0].long_reference;
8168 EqualizeImageChannel(image,channel);
8169 break;
8170 }
8171 case 40: /* Gamma */
8172 {
8173 if (attribute_flag[1] != 0)
8174 channel=(ChannelType) argument_list[1].long_reference;
8175 if (attribute_flag[2] == 0)
8176 argument_list[2].real_reference=1.0;
8177 if (attribute_flag[3] == 0)
8178 argument_list[3].real_reference=1.0;
8179 if (attribute_flag[4] == 0)
8180 argument_list[4].real_reference=1.0;
8181 if (attribute_flag[0] == 0)
8182 {
8183 (void) FormatMagickString(message,MaxTextExtent,"%g,%g,%g",
8184 (double) argument_list[2].real_reference,
8185 (double) argument_list[3].real_reference,
8186 (double) argument_list[4].real_reference);
8187 argument_list[0].string_reference=message;
8188 }
8189 if (strchr(argument_list[0].string_reference,',') != (char *) NULL)
8190 (void) GammaImage(image,argument_list[0].string_reference);
8191 else
8192 (void) GammaImageChannel(image,channel,
8193 atof(argument_list[0].string_reference));
8194 break;
8195 }
8196 case 41: /* Map */
8197 {
8198 QuantizeInfo
8199 *quantize_info;
8200
8201 if (attribute_flag[0] == 0)
8202 {
8203 ThrowPerlException(exception,OptionError,"MapImageRequired",
8204 PackageName);
8205 goto PerlException;
8206 }
8207 quantize_info=AcquireQuantizeInfo(info->image_info);
8208 if (attribute_flag[1] != 0)
8209 quantize_info->dither=(MagickBooleanType)
8210 argument_list[1].long_reference;
8211 (void) RemapImages(quantize_info,image,
8212 argument_list[0].image_reference);
8213 quantize_info=DestroyQuantizeInfo(quantize_info);
8214 break;
8215 }
8216 case 42: /* MatteFloodfill */
8217 {
8218 DrawInfo
8219 *draw_info;
8220
8221 MagickBooleanType
8222 invert;
8223
8224 MagickPixelPacket
8225 target;
8226
8227 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8228 (DrawInfo *) NULL);
8229 if (attribute_flag[0] != 0)
8230 if (attribute_flag[0] != 0)
8231 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8232 &geometry,exception);
8233 if (attribute_flag[1] != 0)
8234 geometry.x=argument_list[1].long_reference;
8235 if (attribute_flag[2] != 0)
8236 geometry.y=argument_list[2].long_reference;
8237 if (image->matte == MagickFalse)
8238 (void) SetImageOpacity(image,OpaqueOpacity);
8239 (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target,
8240 exception);
8241 if (attribute_flag[4] != 0)
8242 QueryMagickColor(argument_list[4].string_reference,&target,
8243 exception);
8244 if (attribute_flag[3] != 0)
8245 target.opacity=StringToDouble(argument_list[3].string_reference,
8246 QuantumRange);
8247 if (attribute_flag[5] != 0)
8248 image->fuzz=StringToDouble(argument_list[5].string_reference,
8249 QuantumRange);
8250 invert=MagickFalse;
8251 if (attribute_flag[6] != 0)
8252 invert=(MagickBooleanType) argument_list[6].long_reference;
8253 (void) FloodfillPaintImage(image,OpacityChannel,draw_info,&target,
8254 geometry.x,geometry.y,invert);
8255 draw_info=DestroyDrawInfo(draw_info);
8256 break;
8257 }
8258 case 43: /* Modulate */
8259 {
8260 char
8261 modulate[MaxTextExtent];
8262
8263 ColorspaceType
8264 colorspace;
8265
8266 colorspace=image->colorspace;
8267 geometry_info.rho=100.0;
8268 geometry_info.sigma=100.0;
8269 geometry_info.xi=100.0;
8270 if (attribute_flag[0] != 0)
8271 (void)ParseGeometry(argument_list[0].string_reference,
8272 &geometry_info);
8273 if (attribute_flag[1] != 0)
8274 geometry_info.xi=argument_list[1].real_reference;
8275 if (attribute_flag[2] != 0)
8276 geometry_info.sigma=argument_list[2].real_reference;
8277 if (attribute_flag[3] != 0)
8278 {
8279 (void) SetImageColorspace(image,HWBColorspace);
8280 geometry_info.sigma=argument_list[3].real_reference;
8281 }
8282 if (attribute_flag[4] != 0)
8283 geometry_info.rho=argument_list[4].real_reference;
8284 if (attribute_flag[5] != 0)
8285 {
8286 (void) SetImageColorspace(image,HSLColorspace);
8287 geometry_info.sigma=argument_list[5].real_reference;
8288 }
8289 if (attribute_flag[6] != 0)
8290 {
8291 (void) SetImageColorspace(image,HWBColorspace);
8292 geometry_info.rho=argument_list[6].real_reference;
8293 }
8294 (void) FormatMagickString(modulate,MaxTextExtent,"%g,%g,%g",
8295 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
8296 (void) ModulateImage(image,modulate);
8297 (void) SetImageColorspace(image,colorspace);
8298 break;
8299 }
8300 case 44: /* Negate */
8301 {
8302 if (attribute_flag[0] == 0)
8303 argument_list[0].long_reference=0;
8304 if (attribute_flag[1] != 0)
8305 channel=(ChannelType) argument_list[1].long_reference;
8306 (void) NegateImageChannel(image,channel,
8307 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse);
8308 break;
8309 }
8310 case 45: /* Normalize */
8311 {
8312 if (attribute_flag[0] != 0)
8313 channel=(ChannelType) argument_list[0].long_reference;
8314 NormalizeImageChannel(image,channel);
8315 break;
8316 }
8317 case 46: /* NumberColors */
8318 break;
8319 case 47: /* Opaque */
8320 {
8321 MagickBooleanType
8322 invert;
8323
8324 MagickPixelPacket
8325 fill_color,
8326 target;
8327
8328 (void) QueryMagickColor("none",&target,exception);
8329 (void) QueryMagickColor("none",&fill_color,exception);
8330 if (attribute_flag[0] != 0)
8331 (void) QueryMagickColor(argument_list[0].string_reference,
8332 &target,exception);
8333 if (attribute_flag[1] != 0)
8334 (void) QueryMagickColor(argument_list[1].string_reference,
8335 &fill_color,exception);
8336 if (attribute_flag[2] != 0)
8337 image->fuzz=StringToDouble(argument_list[2].string_reference,
8338 QuantumRange);
8339 if (attribute_flag[3] != 0)
8340 channel=(ChannelType) argument_list[3].long_reference;
8341 invert=MagickFalse;
8342 if (attribute_flag[4] != 0)
8343 invert=(MagickBooleanType) argument_list[4].long_reference;
8344 (void) OpaquePaintImageChannel(image,channel,&target,&fill_color,
8345 invert);
8346 break;
8347 }
8348 case 48: /* Quantize */
8349 {
8350 QuantizeInfo
8351 *quantize_info;
8352
8353 quantize_info=AcquireQuantizeInfo(info->image_info);
8354 if (attribute_flag[0] != 0)
8355 quantize_info->number_colors=(unsigned long)
8356 argument_list[0].long_reference;
8357 if (attribute_flag[1] != 0)
8358 quantize_info->tree_depth=(unsigned long)
8359 argument_list[1].long_reference;
8360 if (attribute_flag[2] != 0)
8361 quantize_info->colorspace=(ColorspaceType)
8362 argument_list[2].long_reference;
8363 if (attribute_flag[3] != 0)
8364 quantize_info->dither=argument_list[3].long_reference != 0 ?
8365 MagickTrue : MagickFalse;
8366 if (attribute_flag[4] != 0)
8367 quantize_info->measure_error=
8368 argument_list[4].long_reference != 0 ? MagickTrue : MagickFalse;
8369 if (attribute_flag[5] != 0)
8370 (void) QueryColorDatabase(argument_list[5].string_reference,
8371 &image->transparent_color,exception);
8372 if (attribute_flag[5] && argument_list[5].long_reference)
8373 {
8374 (void) QuantizeImages(quantize_info,image);
8375 goto PerlException;
8376 }
8377 if (attribute_flag[6] != 0)
8378 quantize_info->dither_method=(DitherMethod)
8379 argument_list[6].long_reference;
8380 if ((image->storage_class == DirectClass) ||
8381 (image->colors > quantize_info->number_colors) ||
8382 (quantize_info->colorspace == GRAYColorspace))
8383 (void) QuantizeImage(quantize_info,image);
8384 else
8385 CompressImageColormap(image);
8386 quantize_info=DestroyQuantizeInfo(quantize_info);
8387 break;
8388 }
8389 case 49: /* Raise */
8390 {
8391 if (attribute_flag[0] != 0)
8392 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8393 &geometry,exception);
8394 if (attribute_flag[1] != 0)
8395 geometry.width=argument_list[1].long_reference;
8396 if (attribute_flag[2] != 0)
8397 geometry.height=argument_list[2].long_reference;
8398 if (attribute_flag[3] == 0)
8399 argument_list[3].long_reference=1;
8400 (void) RaiseImage(image,&geometry,argument_list[3].long_reference !=
8401 0 ? MagickTrue : MagickFalse);
8402 break;
8403 }
8404 case 50: /* Segment */
8405 {
8406 ColorspaceType
8407 colorspace;
8408
8409 double
8410 cluster_threshold,
8411 smoothing_threshold;
8412
8413 MagickBooleanType
8414 verbose;
8415
8416 cluster_threshold=1.0;
8417 smoothing_threshold=1.5;
8418 colorspace=RGBColorspace;
8419 verbose=MagickFalse;
8420 if (attribute_flag[0] != 0)
8421 {
8422 flags=ParseGeometry(argument_list[0].string_reference,
8423 &geometry_info);
8424 cluster_threshold=geometry_info.rho;
8425 if (flags & SigmaValue)
8426 smoothing_threshold=geometry_info.sigma;
8427 }
8428 if (attribute_flag[1] != 0)
8429 cluster_threshold=argument_list[1].real_reference;
8430 if (attribute_flag[2] != 0)
8431 smoothing_threshold=argument_list[2].real_reference;
8432 if (attribute_flag[3] != 0)
8433 colorspace=(ColorspaceType) argument_list[3].long_reference;
8434 if (attribute_flag[4] != 0)
8435 verbose=argument_list[4].long_reference != 0 ?
8436 MagickTrue : MagickFalse;
8437 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
8438 smoothing_threshold);
8439 break;
8440 }
8441 case 51: /* Signature */
8442 {
8443 (void) SignatureImage(image);
8444 break;
8445 }
8446 case 52: /* Solarize */
8447 {
8448 geometry_info.rho=QuantumRange/2.0;
8449 if (attribute_flag[0] != 0)
8450 flags=ParseGeometry(argument_list[0].string_reference,
8451 &geometry_info);
8452 if (attribute_flag[1] != 0)
8453 geometry_info.rho=StringToDouble(argument_list[1].string_reference,
8454 QuantumRange);
8455 (void) SolarizeImage(image,geometry_info.rho);
8456 break;
8457 }
8458 case 53: /* Sync */
8459 {
8460 (void) SyncImage(image);
8461 break;
8462 }
8463 case 54: /* Texture */
8464 {
8465 if (attribute_flag[0] == 0)
8466 break;
8467 TextureImage(image,argument_list[0].image_reference);
8468 break;
8469 }
8470 case 55: /* Evalute */
8471 {
8472 MagickEvaluateOperator
8473 op;
8474
8475 op=SetEvaluateOperator;
8476 if (attribute_flag[0] == MagickFalse)
8477 argument_list[0].real_reference=0.0;
8478 if (attribute_flag[1] != MagickFalse)
8479 op=(MagickEvaluateOperator) argument_list[1].long_reference;
8480 if (attribute_flag[2] != MagickFalse)
8481 channel=(ChannelType) argument_list[2].long_reference;
8482 (void) EvaluateImageChannel(image,channel,op,
8483 argument_list[0].real_reference,exception);
8484 break;
8485 }
8486 case 56: /* Transparent */
8487 {
8488 double
8489 opacity;
8490
8491 MagickBooleanType
8492 invert;
8493
8494 MagickPixelPacket
8495 target;
8496
8497 (void) QueryMagickColor("none",&target,exception);
8498 if (attribute_flag[0] != 0)
8499 (void) QueryMagickColor(argument_list[0].string_reference,&target,
8500 exception);
8501 opacity=TransparentOpacity;
8502 if (attribute_flag[1] != 0)
8503 opacity=StringToDouble(argument_list[1].string_reference,
8504 QuantumRange);
8505 if (attribute_flag[2] != 0)
8506 image->fuzz=StringToDouble(argument_list[2].string_reference,
8507 QuantumRange);
8508 if (attribute_flag[3] == 0)
8509 argument_list[3].long_reference=0;
8510 invert=MagickFalse;
8511 if (attribute_flag[3] != 0)
8512 invert=(MagickBooleanType) argument_list[3].long_reference;
8513 (void) TransparentPaintImage(image,&target,RoundToQuantum(opacity),
8514 invert);
8515 break;
8516 }
8517 case 57: /* Threshold */
8518 {
8519 double
8520 threshold;
8521
8522 if (attribute_flag[0] == 0)
8523 argument_list[0].string_reference="50%";
8524 if (attribute_flag[1] != 0)
8525 channel=(ChannelType) argument_list[1].long_reference;
8526 threshold=StringToDouble(argument_list[0].string_reference,
8527 QuantumRange);
8528 (void) BilevelImageChannel(image,channel,threshold);
8529 break;
8530 }
8531 case 58: /* Charcoal */
8532 {
8533 if (attribute_flag[0] != 0)
8534 {
8535 flags=ParseGeometry(argument_list[0].string_reference,
8536 &geometry_info);
8537 if ((flags & SigmaValue) == 0)
8538 geometry_info.sigma=1.0;
8539 }
8540 if (attribute_flag[1] != 0)
8541 geometry_info.rho=argument_list[1].real_reference;
8542 if (attribute_flag[2] != 0)
8543 geometry_info.sigma=argument_list[2].real_reference;
8544 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
8545 exception);
8546 break;
8547 }
8548 case 59: /* Trim */
8549 {
8550 if (attribute_flag[0] != 0)
8551 image->fuzz=StringToDouble(argument_list[0].string_reference,
8552 QuantumRange);
8553 image=TrimImage(image,exception);
8554 break;
8555 }
8556 case 60: /* Wave */
8557 {
8558 if (attribute_flag[0] != 0)
8559 {
8560 flags=ParseGeometry(argument_list[0].string_reference,
8561 &geometry_info);
8562 if ((flags & SigmaValue) == 0)
8563 geometry_info.sigma=1.0;
8564 }
8565 if (attribute_flag[1] != 0)
8566 geometry_info.rho=argument_list[1].real_reference;
8567 if (attribute_flag[2] != 0)
8568 geometry_info.sigma=argument_list[2].real_reference;
8569 if (attribute_flag[3] != 0)
8570 image->interpolate=(InterpolatePixelMethod)
8571 argument_list[3].long_reference;
8572 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
8573 exception);
8574 break;
8575 }
8576 case 61: /* Separate */
8577 {
8578 if (attribute_flag[0] != 0)
8579 channel=(ChannelType) argument_list[0].long_reference;
8580 (void) SeparateImageChannel(image,channel);
8581 break;
8582 }
8583 case 63: /* Stereo */
8584 {
8585 if (attribute_flag[0] == 0)
8586 {
8587 ThrowPerlException(exception,OptionError,"StereoImageRequired",
8588 PackageName);
8589 goto PerlException;
8590 }
8591 if (attribute_flag[1] != 0)
8592 geometry.x=argument_list[1].long_reference;
8593 if (attribute_flag[2] != 0)
8594 geometry.y=argument_list[2].long_reference;
8595 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
8596 geometry.x,geometry.y,exception);
8597 break;
8598 }
8599 case 64: /* Stegano */
8600 {
8601 if (attribute_flag[0] == 0)
8602 {
8603 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
8604 PackageName);
8605 goto PerlException;
8606 }
8607 if (attribute_flag[1] == 0)
8608 argument_list[1].long_reference=0;
8609 image->offset=argument_list[1].long_reference;
8610 image=SteganoImage(image,argument_list[0].image_reference,exception);
8611 break;
8612 }
8613 case 65: /* Deconstruct */
8614 {
8615 image=DeconstructImages(image,exception);
8616 break;
8617 }
8618 case 66: /* GaussianBlur */
8619 {
8620 if (attribute_flag[0] != 0)
8621 {
8622 flags=ParseGeometry(argument_list[0].string_reference,
8623 &geometry_info);
8624 if ((flags & SigmaValue) == 0)
8625 geometry_info.sigma=1.0;
8626 }
8627 if (attribute_flag[1] != 0)
8628 geometry_info.rho=argument_list[1].real_reference;
8629 if (attribute_flag[2] != 0)
8630 geometry_info.sigma=argument_list[2].real_reference;
8631 if (attribute_flag[3] != 0)
8632 channel=(ChannelType) argument_list[3].long_reference;
8633 image=GaussianBlurImageChannel(image,channel,geometry_info.rho,
8634 geometry_info.sigma,exception);
8635 break;
8636 }
8637 case 67: /* Convolve */
8638 {
8639 AV
8640 *av;
8641
8642 double
8643 *kernel;
8644
8645 unsigned long
8646 order;
8647
8648 if (attribute_flag[0] == 0)
8649 break;
8650 if (attribute_flag[1] != 0)
8651 channel=(ChannelType) argument_list[1].long_reference;
8652 if (attribute_flag[2] != 0)
8653 image->bias=StringToDouble(argument_list[2].string_reference,
8654 QuantumRange);
8655 av=(AV *) argument_list[0].array_reference;
8656 order=(unsigned long) sqrt(av_len(av)+1);
8657 kernel=(double *) AcquireQuantumMemory(order,order*sizeof(*kernel));
8658 if (kernel == (double *) NULL)
8659 {
8660 ThrowPerlException(exception,ResourceLimitFatalError,
8661 "MemoryAllocationFailed",PackageName);
8662 goto PerlException;
8663 }
8664 for (j=0; (j < (long) (order*order)) && (j < (av_len(av)+1)); j++)
8665 kernel[j]=(double) SvNV(*(av_fetch(av,j,0)));
8666 for ( ; j < (long) (order*order); j++)
8667 kernel[j]=0.0;
8668 image=ConvolveImageChannel(image,channel,order,kernel,exception);
8669 kernel=(double *) RelinquishMagickMemory(kernel);
8670 break;
8671 }
8672 case 68: /* Profile */
8673 {
8674 const char
8675 *name;
8676
8677 Image
8678 *profile_image;
8679
8680 ImageInfo
8681 *profile_info;
8682
8683 StringInfo
8684 *profile;
8685
8686 name="*";
8687 if (attribute_flag[0] != 0)
8688 name=argument_list[0].string_reference;
8689 if (attribute_flag[2] != 0)
8690 image->rendering_intent=(RenderingIntent)
8691 argument_list[2].long_reference;
8692 if (attribute_flag[3] != 0)
8693 image->black_point_compensation=
8694 argument_list[3].long_reference != 0 ? MagickTrue : MagickFalse;
8695 if (attribute_flag[1] != 0)
8696 {
8697 if (argument_list[1].length == 0)
8698 {
8699 /*
8700 Remove a profile from the image.
8701 */
8702 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
8703 MagickTrue);
8704 break;
8705 }
8706 /*
8707 Associate user supplied profile with the image.
8708 */
8709 profile=AcquireStringInfo(argument_list[1].length);
8710 SetStringInfoDatum(profile,(const unsigned char *)
8711 argument_list[1].string_reference);
8712 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
8713 (unsigned long) GetStringInfoLength(profile),MagickFalse);
8714 profile=DestroyStringInfo(profile);
8715 break;
8716 }
8717 /*
8718 Associate a profile with the image.
8719 */
8720 profile_info=
8721 CloneImageInfo(info ? info->image_info : (ImageInfo *) NULL);
8722 (void) CopyMagickString(profile_info->filename,name,MaxTextExtent);
8723 profile_image=ReadImages(profile_info,&image->exception);
8724 if (profile_image == (Image *) NULL)
8725 break;
8726 ResetImageProfileIterator(profile_image);
8727 name=GetNextImageProfile(profile_image);
8728 while (name != (const char *) NULL)
8729 {
8730 const StringInfo
8731 *profile;
8732
8733 profile=GetImageProfile(profile_image,name);
8734 if (profile != (const StringInfo *) NULL)
8735 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
8736 (unsigned long) GetStringInfoLength(profile),MagickFalse);
8737 name=GetNextImageProfile(profile_image);
8738 }
8739 profile_image=DestroyImage(profile_image);
8740 profile_info=DestroyImageInfo(profile_info);
8741 break;
8742 }
8743 case 69: /* UnsharpMask */
8744 {
8745 if (attribute_flag[0] != 0)
8746 {
8747 flags=ParseGeometry(argument_list[0].string_reference,
8748 &geometry_info);
8749 if ((flags & SigmaValue) == 0)
8750 geometry_info.sigma=1.0;
8751 if ((flags & XiValue) == 0)
8752 geometry_info.xi=1.0;
8753 if ((flags & PsiValue) == 0)
8754 geometry_info.psi=0.5;
8755 }
8756 if (attribute_flag[1] != 0)
8757 geometry_info.rho=argument_list[1].real_reference;
8758 if (attribute_flag[2] != 0)
8759 geometry_info.sigma=argument_list[2].real_reference;
8760 if (attribute_flag[3] != 0)
8761 geometry_info.xi=argument_list[3].real_reference;
8762 if (attribute_flag[4] != 0)
8763 geometry_info.psi=argument_list[4].real_reference;
8764 if (attribute_flag[5] != 0)
8765 channel=(ChannelType) argument_list[5].long_reference;
8766 image=UnsharpMaskImageChannel(image,channel,geometry_info.rho,
8767 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
8768 break;
8769 }
8770 case 70: /* MotionBlur */
8771 {
8772 if (attribute_flag[0] != 0)
8773 {
8774 flags=ParseGeometry(argument_list[0].string_reference,
8775 &geometry_info);
8776 if ((flags & SigmaValue) == 0)
8777 geometry_info.sigma=1.0;
8778 if ((flags & XiValue) == 0)
8779 geometry_info.xi=1.0;
8780 }
8781 if (attribute_flag[1] != 0)
8782 geometry_info.rho=argument_list[1].real_reference;
8783 if (attribute_flag[2] != 0)
8784 geometry_info.sigma=argument_list[2].real_reference;
8785 if (attribute_flag[3] != 0)
8786 geometry_info.xi=argument_list[3].real_reference;
8787 if (attribute_flag[4] != 0)
8788 channel=(ChannelType) argument_list[4].long_reference;
8789 image=MotionBlurImageChannel(image,channel,geometry_info.rho,geometry_info.sigma,
8790 geometry_info.xi,exception);
8791 break;
8792 }
8793 case 71: /* OrderedDither */
8794 {
8795 if (attribute_flag[0] == 0)
8796 argument_list[0].string_reference="o8x8";
8797 if (attribute_flag[1] != 0)
8798 channel=(ChannelType) argument_list[1].long_reference;
8799 (void) OrderedPosterizeImageChannel(image,channel,
8800 argument_list[0].string_reference,exception);
8801 break;
8802 }
8803 case 72: /* Shave */
8804 {
8805 if (attribute_flag[0] != 0)
8806 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8807 &geometry,exception);
8808 if (attribute_flag[1] != 0)
8809 geometry.width=argument_list[1].long_reference;
8810 if (attribute_flag[2] != 0)
8811 geometry.height=argument_list[2].long_reference;
8812 image=ShaveImage(image,&geometry,exception);
8813 break;
8814 }
8815 case 73: /* Level */
8816 {
8817 double
8818 black_point,
8819 gamma,
8820 white_point;
8821
8822 black_point=0.0;
8823 white_point=(MagickRealType) image->columns*image->rows;
8824 gamma=1.0;
8825 if (attribute_flag[0] != 0)
8826 {
8827 flags=ParseGeometry(argument_list[0].string_reference,
8828 &geometry_info);
8829 black_point=geometry_info.rho;
8830 if ((flags & SigmaValue) != 0)
8831 white_point=geometry_info.sigma;
8832 if ((flags & XiValue) != 0)
8833 gamma=geometry_info.xi;
8834 if ((flags & PercentValue) != 0)
8835 {
8836 black_point*=(double) (QuantumRange/100.0);
8837 white_point*=(double) (QuantumRange/100.0);
8838 }
8839 if ((flags & SigmaValue) == 0)
8840 white_point=(double) QuantumRange-black_point;
8841 }
8842 if (attribute_flag[1] != 0)
8843 black_point=argument_list[1].real_reference;
8844 if (attribute_flag[2] != 0)
8845 white_point=argument_list[2].real_reference;
8846 if (attribute_flag[3] != 0)
8847 gamma=argument_list[3].real_reference;
8848 if (attribute_flag[4] != 0)
8849 channel=(ChannelType) argument_list[4].long_reference;
8850 if (attribute_flag[5] != 0)
8851 {
8852 argument_list[0].real_reference=argument_list[5].real_reference;
8853 attribute_flag[0]=attribute_flag[5];
8854 }
8855 (void) LevelImageChannel(image,channel,black_point,white_point,gamma);
8856 break;
8857 }
8858 case 74: /* Clip */
8859 {
8860 if (attribute_flag[0] == 0)
8861 argument_list[0].string_reference="#1";
8862 if (attribute_flag[1] == 0)
8863 argument_list[1].long_reference=MagickTrue;
8864 (void) ClipImagePath(image,argument_list[0].string_reference,
8865 argument_list[1].long_reference != 0 ? MagickTrue : MagickFalse);
8866 break;
8867 }
8868 case 75: /* AffineTransform */
8869 {
8870 DrawInfo
8871 *draw_info;
8872
8873 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8874 (DrawInfo *) NULL);
8875 if (attribute_flag[0] != 0)
8876 {
8877 AV
8878 *av;
8879
8880 av=(AV *) argument_list[0].array_reference;
8881 if ((av_len(av) != 3) && (av_len(av) != 5))
8882 {
8883 ThrowPerlException(exception,OptionError,
8884 "affine matrix must have 4 or 6 elements",PackageName);
8885 goto PerlException;
8886 }
8887 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8888 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8889 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8890 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8891 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8892 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8893 {
8894 ThrowPerlException(exception,OptionError,
8895 "affine matrix is singular",PackageName);
8896 goto PerlException;
8897 }
8898 if (av_len(av) == 5)
8899 {
8900 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8901 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8902 }
8903 }
8904 for (j=1; j < 6; j++)
8905 {
8906 if (attribute_flag[j] == 0)
8907 continue;
8908 value=argument_list[j].string_reference;
8909 angle=argument_list[j].real_reference;
8910 current=draw_info->affine;
8911 GetAffineMatrix(&affine);
8912 switch (j)
8913 {
8914 case 1:
8915 {
8916 /*
8917 Translate.
8918 */
8919 flags=ParseGeometry(value,&geometry_info);
8920 affine.tx=geometry_info.xi;
8921 affine.ty=geometry_info.psi;
8922 if ((flags & PsiValue) == 0)
8923 affine.ty=affine.tx;
8924 break;
8925 }
8926 case 2:
8927 {
8928 /*
8929 Scale.
8930 */
8931 flags=ParseGeometry(value,&geometry_info);
8932 affine.sx=geometry_info.rho;
8933 affine.sy=geometry_info.sigma;
8934 if ((flags & SigmaValue) == 0)
8935 affine.sy=affine.sx;
8936 break;
8937 }
8938 case 3:
8939 {
8940 /*
8941 Rotate.
8942 */
8943 if (angle == 0.0)
8944 break;
8945 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8946 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8947 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8948 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8949 break;
8950 }
8951 case 4:
8952 {
8953 /*
8954 SkewX.
8955 */
8956 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8957 break;
8958 }
8959 case 5:
8960 {
8961 /*
8962 SkewY.
8963 */
8964 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8965 break;
8966 }
8967 }
8968 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8969 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8970 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8971 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8972 draw_info->affine.tx=
8973 current.sx*affine.tx+current.ry*affine.ty+current.tx;
8974 draw_info->affine.ty=
8975 current.rx*affine.tx+current.sy*affine.ty+current.ty;
8976 }
8977 if (attribute_flag[6] != 0)
8978 image->interpolate=(InterpolatePixelMethod)
8979 argument_list[6].long_reference;
8980 if (attribute_flag[7] != 0)
8981 QueryColorDatabase(argument_list[7].string_reference,
8982 &image->background_color,exception);
8983 image=AffineTransformImage(image,&draw_info->affine,exception);
8984 draw_info=DestroyDrawInfo(draw_info);
8985 break;
8986 }
8987 case 76: /* Difference */
8988 {
8989 if (attribute_flag[0] == 0)
8990 {
8991 ThrowPerlException(exception,OptionError,
8992 "ReferenceImageRequired",PackageName);
8993 goto PerlException;
8994 }
8995 if (attribute_flag[1] != 0)
8996 image->fuzz=StringToDouble(argument_list[1].string_reference,
8997 QuantumRange);
8998 (void) IsImagesEqual(image,argument_list[0].image_reference);
8999 break;
9000 }
9001 case 77: /* AdaptiveThreshold */
9002 {
9003 if (attribute_flag[0] != 0)
9004 {
9005 flags=ParseGeometry(argument_list[0].string_reference,
9006 &geometry_info);
9007 if ((flags & PercentValue) != 0)
9008 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9009 }
9010 if (attribute_flag[1] != 0)
9011 geometry_info.rho=argument_list[1].long_reference;
9012 if (attribute_flag[2] != 0)
9013 geometry_info.sigma=argument_list[2].long_reference;
9014 if (attribute_flag[3] != 0)
9015 geometry_info.xi=argument_list[3].long_reference;;
9016 image=AdaptiveThresholdImage(image,(unsigned long) geometry_info.rho,
9017 (unsigned long) geometry_info.sigma,(long) geometry_info.xi,
9018 exception);
9019 break;
9020 }
9021 case 78: /* Resample */
9022 {
9023 unsigned long
9024 height,
9025 width;
9026
9027 if (attribute_flag[0] != 0)
9028 {
9029 flags=ParseGeometry(argument_list[0].string_reference,
9030 &geometry_info);
9031 if ((flags & SigmaValue) == 0)
9032 geometry_info.sigma=geometry_info.rho;
9033 }
9034 if (attribute_flag[1] != 0)
9035 geometry_info.rho=argument_list[1].real_reference;
9036 if (attribute_flag[2] != 0)
9037 geometry_info.sigma=argument_list[2].real_reference;
9038 if (attribute_flag[3] == 0)
9039 argument_list[3].long_reference=(long) UndefinedFilter;
9040 if (attribute_flag[4] == 0)
9041 SetImageArtifact(image,"filter:support",
9042 argument_list[4].string_reference);
9043 if (attribute_flag[5] != 0)
9044 argument_list[5].real_reference=1.0;
9045 width=(unsigned long) (geometry_info.rho*image->columns/
9046 (image->x_resolution == 0.0 ? 72.0 : image->x_resolution)+0.5);
9047 height=(unsigned long) (geometry_info.sigma*image->rows/
9048 (image->y_resolution == 0.0 ? 72.0 : image->y_resolution)+0.5);
9049 image=ResizeImage(image,width,height,(FilterTypes)
9050 argument_list[3].long_reference,argument_list[5].real_reference,
9051 exception);
9052 if (image != (Image *) NULL)
9053 {
9054 image->x_resolution=geometry_info.rho;
9055 image->y_resolution=geometry_info.sigma;
9056 }
9057 break;
9058 }
9059 case 79: /* Describe */
9060 {
9061 if (attribute_flag[0] == 0)
9062 argument_list[0].file_reference=(FILE *) NULL;
9063 (void) IdentifyImage(image,argument_list[0].file_reference,
9064 MagickTrue);
9065 break;
9066 }
9067 case 80: /* BlackThreshold */
9068 {
9069 if (attribute_flag[0] == 0)
9070 argument_list[0].string_reference="50%";
9071 if (attribute_flag[2] != 0)
9072 channel=(ChannelType) argument_list[2].long_reference;
9073 BlackThresholdImageChannel(image,channel,
9074 argument_list[0].string_reference,exception);
9075 break;
9076 }
9077 case 81: /* WhiteThreshold */
9078 {
9079 if (attribute_flag[0] == 0)
9080 argument_list[0].string_reference="50%";
9081 if (attribute_flag[2] != 0)
9082 channel=(ChannelType) argument_list[2].long_reference;
9083 WhiteThresholdImageChannel(image,channel,
9084 argument_list[0].string_reference,exception);
9085 break;
9086 }
9087 case 82: /* RadialBlur */
9088 {
9089 if (attribute_flag[0] != 0)
9090 {
9091 flags=ParseGeometry(argument_list[0].string_reference,
9092 &geometry_info);
9093 if ((flags & SigmaValue) == 0)
9094 geometry_info.sigma=1.0;
9095 }
9096 if (attribute_flag[1] != 0)
9097 geometry_info.rho=argument_list[1].real_reference;
9098 if (attribute_flag[2] != 0)
9099 channel=(ChannelType) argument_list[2].long_reference;
9100 image=RadialBlurImageChannel(image,channel,geometry_info.rho,
9101 exception);
9102 break;
9103 }
9104 case 83: /* Thumbnail */
9105 {
9106 if (attribute_flag[0] != 0)
9107 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9108 &geometry,exception);
9109 if (attribute_flag[1] != 0)
9110 geometry.width=argument_list[1].long_reference;
9111 if (attribute_flag[2] != 0)
9112 geometry.height=argument_list[2].long_reference;
9113 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
9114 break;
9115 }
9116 case 84: /* Strip */
9117 {
9118 (void) StripImage(image);
9119 break;
9120 }
9121 case 85: /* Tint */
9122 {
9123 PixelPacket
9124 target;
9125
9126 (void) GetOneVirtualPixel(image,0,0,&target,exception);
9127 if (attribute_flag[0] != 0)
9128 (void) QueryColorDatabase(argument_list[0].string_reference,&target,
9129 exception);
9130 if (attribute_flag[1] == 0)
9131 argument_list[1].string_reference="100";
9132 image=TintImage(image,argument_list[1].string_reference,target,
9133 exception);
9134 break;
9135 }
9136 case 86: /* Channel */
9137 {
9138 if (attribute_flag[0] != 0)
9139 channel=(ChannelType) argument_list[0].long_reference;
9140 (void) SeparateImageChannel(image,channel);
9141 break;
9142 }
9143 case 87: /* Splice */
9144 {
9145 if (attribute_flag[0] != 0)
9146 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
9147 &geometry,exception);
9148 if (attribute_flag[1] != 0)
9149 geometry.width=argument_list[1].long_reference;
9150 if (attribute_flag[2] != 0)
9151 geometry.height=argument_list[2].long_reference;
9152 if (attribute_flag[3] != 0)
9153 geometry.x=argument_list[3].long_reference;
9154 if (attribute_flag[4] != 0)
9155 geometry.y=argument_list[4].long_reference;
9156 if (attribute_flag[5] != 0)
9157 image->fuzz=StringToDouble(argument_list[5].string_reference,
9158 QuantumRange);
9159 if (attribute_flag[6] != 0)
9160 (void) QueryColorDatabase(argument_list[6].string_reference,
9161 &image->background_color,exception);
9162 if (attribute_flag[7] != 0)
9163 image->gravity=(GravityType) argument_list[7].long_reference;
9164 image=SpliceImage(image,&geometry,exception);
9165 break;
9166 }
9167 case 88: /* Posterize */
9168 {
9169 if (attribute_flag[0] == 0)
9170 argument_list[0].long_reference=3;
9171 if (attribute_flag[1] == 0)
9172 argument_list[1].long_reference=0;
9173 (void) PosterizeImage(image,argument_list[0].long_reference,
9174 argument_list[1].long_reference ? MagickTrue : MagickFalse);
9175 break;
9176 }
9177 case 89: /* Shadow */
9178 {
9179 if (attribute_flag[0] != 0)
9180 {
9181 flags=ParseGeometry(argument_list[0].string_reference,
9182 &geometry_info);
9183 if ((flags & SigmaValue) == 0)
9184 geometry_info.sigma=1.0;
9185 if ((flags & XiValue) == 0)
9186 geometry_info.xi=4.0;
9187 if ((flags & PsiValue) == 0)
9188 geometry_info.psi=4.0;
9189 }
9190 if (attribute_flag[1] != 0)
9191 geometry_info.rho=argument_list[1].real_reference;
9192 if (attribute_flag[2] != 0)
9193 geometry_info.sigma=argument_list[2].real_reference;
9194 if (attribute_flag[3] != 0)
9195 geometry_info.xi=argument_list[3].long_reference;
9196 if (attribute_flag[4] != 0)
9197 geometry_info.psi=argument_list[4].long_reference;
9198 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
9199 (long) (geometry_info.xi+0.5),(long) (geometry_info.psi+0.5),
9200 exception);
9201 break;
9202 }
9203 case 90: /* Identify */
9204 {
9205 if (attribute_flag[0] == 0)
9206 argument_list[0].file_reference=(FILE *) NULL;
9207 (void) IdentifyImage(image,argument_list[0].file_reference,
9208 MagickTrue);
9209 break;
9210 }
9211 case 91: /* SepiaTone */
9212 {
9213 if (attribute_flag[0] == 0)
9214 argument_list[0].real_reference=80.0*QuantumRange/100.0;
9215 image=SepiaToneImage(image,argument_list[0].real_reference,
9216 exception);
9217 break;
9218 }
9219 case 92: /* SigmoidalContrast */
9220 {
9221 MagickBooleanType
9222 sharpen;
9223
9224 if (attribute_flag[0] != 0)
9225 {
9226 flags=ParseGeometry(argument_list[0].string_reference,
9227 &geometry_info);
9228 if ((flags & SigmaValue) == 0)
9229 geometry_info.sigma=QuantumRange/2.0;
9230 if ((flags & PercentValue) != 0)
9231 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
9232 }
9233 if (attribute_flag[1] != 0)
9234 geometry_info.rho=argument_list[1].real_reference;
9235 if (attribute_flag[2] != 0)
9236 geometry_info.sigma=argument_list[2].real_reference;
9237 if (attribute_flag[3] != 0)
9238 channel=(ChannelType) argument_list[3].long_reference;
9239 sharpen=MagickTrue;
9240 if (attribute_flag[4] != 0)
9241 sharpen=argument_list[4].long_reference != 0 ? MagickTrue :
9242 MagickFalse;
9243 (void) SigmoidalContrastImageChannel(image,channel,sharpen,
9244 geometry_info.rho,geometry_info.sigma);
9245 break;
9246 }
9247 case 93: /* Extent */
9248 {
9249 GravityType
9250 gravity;
9251
9252 gravity=image->gravity;
9253 if (attribute_flag[7] != 0)
9254 gravity=(GravityType) argument_list[7].long_reference;
9255 if (attribute_flag[0] != 0)
9256 {
9257 SetGeometry(image,&geometry);
9258 (void) ParseAbsoluteGeometry(argument_list[0].string_reference,
9259 &geometry);
9260 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
9261 &geometry);
9262 }
9263 if (attribute_flag[1] != 0)
9264 geometry.width=argument_list[1].long_reference;
9265 if (attribute_flag[2] != 0)
9266 geometry.height=argument_list[2].long_reference;
9267 if (attribute_flag[3] != 0)
9268 geometry.x=argument_list[3].long_reference;
9269 if (attribute_flag[4] != 0)
9270 geometry.y=argument_list[4].long_reference;
9271 if (attribute_flag[5] != 0)
9272 image->fuzz=StringToDouble(argument_list[5].string_reference,
9273 QuantumRange);
9274 if (attribute_flag[6] != 0)
9275 (void) QueryColorDatabase(argument_list[6].string_reference,
9276 &image->background_color,exception);
9277 GravityAdjustGeometry(image->columns,image->rows,gravity,&geometry);
9278 image=ExtentImage(image,&geometry,exception);
9279 break;
9280 }
9281 case 94: /* Vignette */
9282 {
9283 if (attribute_flag[0] != 0)
9284 {
9285 flags=ParseGeometry(argument_list[0].string_reference,
9286 &geometry_info);
9287 if ((flags & SigmaValue) == 0)
9288 geometry_info.sigma=1.0;
9289 if ((flags & XiValue) == 0)
9290 geometry_info.xi=0.1*image->columns;
9291 if ((flags & PsiValue) == 0)
9292 geometry_info.psi=0.1*image->rows;
9293 }
9294 if (attribute_flag[1] != 0)
9295 geometry_info.rho=argument_list[1].real_reference;
9296 if (attribute_flag[2] != 0)
9297 geometry_info.sigma=argument_list[2].real_reference;
9298 if (attribute_flag[3] != 0)
9299 geometry_info.xi=argument_list[3].long_reference;
9300 if (attribute_flag[4] != 0)
9301 geometry_info.psi=argument_list[4].long_reference;
9302 if (attribute_flag[5] != 0)
9303 (void) QueryColorDatabase(argument_list[5].string_reference,
9304 &image->background_color,exception);
9305 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
9306 (long) (geometry_info.xi+0.5),(long) (geometry_info.psi+0.5),
9307 exception);
9308 break;
9309 }
9310 case 95: /* ContrastStretch */
9311 {
9312 double
9313 black_point,
9314 white_point;
9315
9316 black_point=0.0;
9317 white_point=(MagickRealType) image->columns*image->rows;
9318 if (attribute_flag[0] != 0)
9319 {
9320 flags=ParseGeometry(argument_list[0].string_reference,
9321 &geometry_info);
9322 black_point=geometry_info.rho;
9323 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
9324 black_point;
9325 if ((flags & PercentValue) != 0)
9326 {
9327 black_point*=(double) image->columns*image->rows/100.0;
9328 white_point*=(double) image->columns*image->rows/100.0;
9329 }
9330 white_point=(MagickRealType) image->columns*image->rows-
9331 white_point;
9332 }
9333 if (attribute_flag[1] != 0)
9334 black_point=argument_list[1].real_reference;
9335 if (attribute_flag[2] != 0)
9336 white_point=argument_list[2].real_reference;
9337 if (attribute_flag[4] != 0)
9338 channel=(ChannelType) argument_list[4].long_reference;
9339 (void) ContrastStretchImageChannel(image,channel,black_point,
9340 white_point);
9341 break;
9342 }
9343 case 96: /* Sans0 */
9344 {
9345 break;
9346 }
9347 case 97: /* Sans1 */
9348 {
9349 break;
9350 }
9351 case 98: /* AdaptiveSharpen */
9352 {
9353 if (attribute_flag[0] != 0)
9354 {
9355 flags=ParseGeometry(argument_list[0].string_reference,
9356 &geometry_info);
9357 if ((flags & SigmaValue) == 0)
9358 geometry_info.sigma=1.0;
9359 }
9360 if (attribute_flag[1] != 0)
9361 geometry_info.rho=argument_list[1].real_reference;
9362 if (attribute_flag[2] != 0)
9363 geometry_info.sigma=argument_list[2].real_reference;
9364 if (attribute_flag[3] != 0)
9365 channel=(ChannelType) argument_list[3].long_reference;
9366 image=AdaptiveSharpenImageChannel(image,channel,geometry_info.rho,
9367 geometry_info.sigma,exception);
9368 break;
9369 }
9370 case 99: /* Transpose */
9371 {
9372 image=TransposeImage(image,exception);
9373 break;
9374 }
9375 case 100: /* Tranverse */
9376 {
9377 image=TransverseImage(image,exception);
9378 break;
9379 }
9380 case 101: /* AutoOrient */
9381 {
9382 switch (image->orientation)
9383 {
9384 case TopRightOrientation:
9385 {
9386 image=FlopImage(image,exception);
9387 break;
9388 }
9389 case BottomRightOrientation:
9390 {
9391 image=RotateImage(image,180.0,exception);
9392 break;
9393 }
9394 case BottomLeftOrientation:
9395 {
9396 image=FlipImage(image,exception);
9397 break;
9398 }
9399 case LeftTopOrientation:
9400 {
9401 image=TransposeImage(image,exception);
9402 break;
9403 }
9404 case RightTopOrientation:
9405 {
9406 image=RotateImage(image,90.0,exception);
9407 break;
9408 }
9409 case RightBottomOrientation:
9410 {
9411 image=TransverseImage(image,exception);
9412 break;
9413 }
9414 case LeftBottomOrientation:
9415 {
9416 image=RotateImage(image,270.0,exception);
9417 break;
9418 }
9419 default:
9420 break;
9421 }
9422 break;
9423 }
9424 case 102: /* AdaptiveBlur */
9425 {
9426 if (attribute_flag[0] != 0)
9427 {
9428 flags=ParseGeometry(argument_list[0].string_reference,
9429 &geometry_info);
9430 if ((flags & SigmaValue) == 0)
9431 geometry_info.sigma=1.0;
9432 }
9433 if (attribute_flag[1] != 0)
9434 geometry_info.rho=argument_list[1].real_reference;
9435 if (attribute_flag[2] != 0)
9436 geometry_info.sigma=argument_list[2].real_reference;
9437 if (attribute_flag[3] != 0)
9438 channel=(ChannelType) argument_list[3].long_reference;
9439 image=AdaptiveBlurImageChannel(image,channel,geometry_info.rho,
9440 geometry_info.sigma,exception);
9441 break;
9442 }
9443 case 103: /* Sketch */
9444 {
9445 if (attribute_flag[0] != 0)
9446 {
9447 flags=ParseGeometry(argument_list[0].string_reference,
9448 &geometry_info);
9449 if ((flags & SigmaValue) == 0)
9450 geometry_info.sigma=1.0;
9451 if ((flags & XiValue) == 0)
9452 geometry_info.xi=1.0;
9453 }
9454 if (attribute_flag[1] != 0)
9455 geometry_info.rho=argument_list[1].real_reference;
9456 if (attribute_flag[2] != 0)
9457 geometry_info.sigma=argument_list[2].real_reference;
9458 if (attribute_flag[3] != 0)
9459 geometry_info.xi=argument_list[3].real_reference;
9460 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
9461 geometry_info.xi,exception);
9462 break;
9463 }
9464 case 104: /* UniqueColors */
9465 {
9466 image=UniqueImageColors(image,exception);
9467 break;
9468 }
9469 case 105: /* AdaptiveResize */
9470 {
9471 if (attribute_flag[0] != 0)
9472 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9473 &geometry,exception);
9474 if (attribute_flag[1] != 0)
9475 geometry.width=argument_list[1].long_reference;
9476 if (attribute_flag[2] != 0)
9477 geometry.height=argument_list[2].long_reference;
9478 if (attribute_flag[3] != 0)
9479 image->filter=(FilterTypes) argument_list[4].long_reference;
9480 if (attribute_flag[4] != 0)
9481 SetImageArtifact(image,"filter:support",
9482 argument_list[4].string_reference);
9483 if (attribute_flag[5] != 0)
9484 image->blur=argument_list[5].real_reference;
9485 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
9486 exception);
9487 break;
9488 }
9489 case 106: /* ClipMask */
9490 {
9491 if (attribute_flag[0] == 0)
9492 {
9493 ThrowPerlException(exception,OptionError,"MaskImageRequired",
9494 PackageName);
9495 goto PerlException;
9496 }
9497 image->clip_mask=CloneImage(argument_list[0].image_reference,0,0,
9498 MagickTrue,exception);
9499 (void) NegateImage(image->clip_mask,MagickFalse);
9500 break;
9501 }
9502 case 107: /* LinearStretch */
9503 {
9504 double
9505 black_point,
9506 white_point;
9507
9508 black_point=0.0;
9509 white_point=(MagickRealType) image->columns*image->rows;
9510 if (attribute_flag[0] != 0)
9511 {
9512 flags=ParseGeometry(argument_list[0].string_reference,
9513 &geometry_info);
9514 if ((flags & SigmaValue) != 0)
9515 white_point=geometry_info.sigma;
9516 if ((flags & PercentValue) != 0)
9517 {
9518 black_point*=(double) image->columns*image->rows/100.0;
9519 white_point*=(double) image->columns*image->rows/100.0;
9520 }
9521 if ((flags & SigmaValue) == 0)
9522 white_point=(double) image->columns*image->rows-black_point;
9523 }
9524 if (attribute_flag[1] != 0)
9525 black_point=argument_list[1].real_reference;
9526 if (attribute_flag[2] != 0)
9527 white_point=argument_list[2].real_reference;
9528 (void) LinearStretchImage(image,black_point,white_point);
9529 break;
9530 }
9531 case 108: /* Recolor */
9532 {
9533 AV
9534 *av;
9535
9536 double
9537 *color_matrix;
9538
9539 unsigned long
9540 order;
9541
9542 if (attribute_flag[0] == 0)
9543 break;
9544 av=(AV *) argument_list[0].array_reference;
9545 order=(unsigned long) sqrt(av_len(av)+1);
9546 color_matrix=(double *) AcquireQuantumMemory(order,order*
9547 sizeof(*color_matrix));
9548 if (color_matrix == (double *) NULL)
9549 {
9550 ThrowPerlException(exception,ResourceLimitFatalError,
9551 "MemoryAllocationFailed",PackageName);
9552 goto PerlException;
9553 }
9554 for (j=0; (j < (long) (order*order)) && (j < (av_len(av)+1)); j++)
9555 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
9556 for ( ; j < (long) (order*order); j++)
9557 color_matrix[j]=0.0;
9558 image=RecolorImage(image,order,color_matrix,exception);
9559 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
9560 break;
9561 }
9562 case 109: /* Mask */
9563 {
9564 if (attribute_flag[0] == 0)
9565 {
9566 ThrowPerlException(exception,OptionError,"MaskImageRequired",
9567 PackageName);
9568 goto PerlException;
9569 }
9570 image->mask=CloneImage(argument_list[0].image_reference,0,0,
9571 MagickTrue,exception);
9572 (void) NegateImage(image->mask,MagickFalse);
9573 break;
9574 }
9575 case 110: /* Polaroid */
9576 {
9577 DrawInfo
9578 *draw_info;
9579
9580 double
9581 angle;
9582
9583 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9584 (DrawInfo *) NULL);
9585 if (attribute_flag[0] != 0)
9586 (void) SetImageProperty(image,"caption",InterpretImageProperties(
9587 info ? info->image_info : (ImageInfo *) NULL,image,
9588 argument_list[0].string_reference));
9589 angle=0.0;
9590 if (attribute_flag[1] != 0)
9591 angle=argument_list[1].real_reference;
9592 if (attribute_flag[2] != 0)
9593 (void) CloneString(&draw_info->font,
9594 argument_list[2].string_reference);
9595 if (attribute_flag[3] != 0)
9596 (void) QueryColorDatabase(argument_list[3].string_reference,
9597 &draw_info->stroke,exception);
9598 if (attribute_flag[4] != 0)
9599 (void) QueryColorDatabase(argument_list[4].string_reference,
9600 &draw_info->fill,exception);
9601 if (attribute_flag[5] != 0)
9602 draw_info->stroke_width=argument_list[5].real_reference;
9603 if (attribute_flag[6] != 0)
9604 draw_info->pointsize=argument_list[6].real_reference;
9605 if (attribute_flag[7] != 0)
9606 draw_info->gravity=(GravityType) argument_list[7].long_reference;
9607 if (attribute_flag[8] != 0)
9608 (void) QueryColorDatabase(argument_list[8].string_reference,
9609 &image->background_color,exception);
9610 image=PolaroidImage(image,draw_info,angle,exception);
9611 draw_info=DestroyDrawInfo(draw_info);
9612 break;
9613 }
9614 case 111: /* FloodfillPaint */
9615 {
9616 DrawInfo
9617 *draw_info;
9618
9619 MagickBooleanType
9620 invert;
9621
9622 MagickPixelPacket
9623 target;
9624
9625 draw_info=CloneDrawInfo(info ? info->image_info :
9626 (ImageInfo *) NULL,(DrawInfo *) NULL);
9627 if (attribute_flag[0] != 0)
9628 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9629 &geometry,exception);
9630 if (attribute_flag[1] != 0)
9631 geometry.x=argument_list[1].long_reference;
9632 if (attribute_flag[2] != 0)
9633 geometry.y=argument_list[2].long_reference;
9634 if (attribute_flag[3] != 0)
9635 (void) QueryColorDatabase(argument_list[3].string_reference,
9636 &draw_info->fill,exception);
9637 (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target,
9638 exception);
9639 if (attribute_flag[4] != 0)
9640 QueryMagickColor(argument_list[4].string_reference,&target,
9641 exception);
9642 if (attribute_flag[5] != 0)
9643 image->fuzz=StringToDouble(argument_list[5].string_reference,
9644 QuantumRange);
9645 if (attribute_flag[6] != 0)
9646 channel=(ChannelType) argument_list[6].long_reference;
9647 invert=MagickFalse;
9648 if (attribute_flag[7] != 0)
9649 invert=(MagickBooleanType) argument_list[7].long_reference;
9650 (void) FloodfillPaintImage(image,channel,draw_info,&target,geometry.x,
9651 geometry.y,invert);
9652 draw_info=DestroyDrawInfo(draw_info);
9653 break;
9654 }
9655 case 112: /* Distort */
9656 {
9657 AV
9658 *av;
9659
9660 double
9661 *coordinates;
9662
9663 DistortImageMethod
9664 method;
9665
9666 unsigned long
9667 number_coordinates;
9668
9669 VirtualPixelMethod
9670 virtual_pixel;
9671
9672 if (attribute_flag[0] == 0)
9673 break;
9674 method=UndefinedDistortion;
9675 if (attribute_flag[1] != 0)
9676 method=(DistortImageMethod) argument_list[1].long_reference;
9677 av=(AV *) argument_list[0].array_reference;
9678 number_coordinates=(unsigned long) av_len(av)+1;
9679 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
9680 sizeof(*coordinates));
9681 if (coordinates == (double *) NULL)
9682 {
9683 ThrowPerlException(exception,ResourceLimitFatalError,
9684 "MemoryAllocationFailed",PackageName);
9685 goto PerlException;
9686 }
9687 for (j=0; j < (long) number_coordinates; j++)
9688 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
9689 virtual_pixel=UndefinedVirtualPixelMethod;
9690 if (attribute_flag[2] != 0)
9691 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
9692 argument_list[2].long_reference);
9693 image=DistortImage(image,method,number_coordinates,coordinates,
9694 argument_list[3].long_reference != 0 ? MagickTrue : MagickFalse,
9695 exception);
9696 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
9697 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel);
9698 coordinates=(double *) RelinquishMagickMemory(coordinates);
9699 break;
9700 }
9701 case 113: /* Clut */
9702 {
9703 if (attribute_flag[0] == 0)
9704 {
9705 ThrowPerlException(exception,OptionError,"ClutImageRequired",
9706 PackageName);
9707 goto PerlException;
9708 }
9709 if (attribute_flag[1] != 0)
9710 channel=(ChannelType) argument_list[1].long_reference;
9711 (void) ClutImageChannel(image,channel,
9712 argument_list[0].image_reference);
9713 break;
9714 }
9715 case 114: /* LiquidRescale */
9716 {
9717 if (attribute_flag[0] != 0)
9718 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9719 &geometry,exception);
9720 if (attribute_flag[1] != 0)
9721 geometry.width=argument_list[1].long_reference;
9722 if (attribute_flag[2] != 0)
9723 geometry.height=argument_list[2].long_reference;
9724 if (attribute_flag[3] == 0)
9725 argument_list[3].real_reference=1.0;
9726 if (attribute_flag[4] == 0)
9727 argument_list[4].real_reference=0.0;
9728 image=LiquidRescaleImage(image,geometry.width,geometry.height,
9729 argument_list[3].real_reference,argument_list[4].real_reference,
9730 exception);
9731 break;
9732 }
9733 case 115: /* EncipherImage */
9734 {
9735 (void) EncipherImage(image,argument_list[0].string_reference,
9736 exception);
9737 break;
9738 }
9739 case 116: /* DecipherImage */
9740 {
9741 (void) DecipherImage(image,argument_list[0].string_reference,
9742 exception);
9743 break;
9744 }
9745 case 117: /* Deskew */
9746 {
9747 geometry_info.rho=QuantumRange/2.0;
9748 if (attribute_flag[0] != 0)
9749 flags=ParseGeometry(argument_list[0].string_reference,
9750 &geometry_info);
9751 if (attribute_flag[1] != 0)
9752 geometry_info.rho=StringToDouble(argument_list[1].string_reference,
9753 QuantumRange);
9754 image=DeskewImage(image,geometry_info.rho,exception);
9755 break;
9756 }
9757 case 118: /* Remap */
9758 {
9759 QuantizeInfo
9760 *quantize_info;
9761
9762 if (attribute_flag[0] == 0)
9763 {
9764 ThrowPerlException(exception,OptionError,"RemapImageRequired",
9765 PackageName);
9766 goto PerlException;
9767 }
9768 quantize_info=AcquireQuantizeInfo(info->image_info);
9769 if (attribute_flag[1] == 0)
9770 quantize_info->dither_method=(DitherMethod)
9771 argument_list[1].long_reference;
9772 (void) RemapImages(quantize_info,image,
9773 argument_list[0].image_reference);
9774 quantize_info=DestroyQuantizeInfo(quantize_info);
9775 break;
9776 }
9777 case 119: /* SparseColor */
9778 {
9779 AV
9780 *av;
9781
9782 double
9783 *coordinates;
9784
9785 SparseColorMethod
9786 method;
9787
9788 unsigned long
9789 number_coordinates;
9790
9791 VirtualPixelMethod
9792 virtual_pixel;
9793
9794 if (attribute_flag[0] == 0)
9795 break;
9796 method=UndefinedColorInterpolate;
9797 if (attribute_flag[1] != 0)
9798 method=(SparseColorMethod) argument_list[1].long_reference;
9799 av=(AV *) argument_list[0].array_reference;
9800 number_coordinates=(unsigned long) av_len(av)+1;
9801 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
9802 sizeof(*coordinates));
9803 if (coordinates == (double *) NULL)
9804 {
9805 ThrowPerlException(exception,ResourceLimitFatalError,
9806 "MemoryAllocationFailed",PackageName);
9807 goto PerlException;
9808 }
9809 for (j=0; j < (long) number_coordinates; j++)
9810 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
9811 virtual_pixel=UndefinedVirtualPixelMethod;
9812 if (attribute_flag[2] != 0)
9813 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
9814 argument_list[2].long_reference);
9815 if (attribute_flag[3] != 0)
9816 channel=(ChannelType) argument_list[3].long_reference;
9817 image=SparseColorImage(image,channel,method,number_coordinates,
9818 coordinates,exception);
9819 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
9820 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel);
9821 coordinates=(double *) RelinquishMagickMemory(coordinates);
9822 break;
9823 }
9824 case 120: /* Function */
9825 {
9826 AV
9827 *av;
9828
9829 double
9830 *parameters;
9831
9832 MagickFunction
9833 function;
9834
9835 unsigned long
9836 number_parameters;
9837
9838 VirtualPixelMethod
9839 virtual_pixel;
9840
9841 if (attribute_flag[0] == 0)
9842 break;
9843 function=UndefinedFunction;
9844 if (attribute_flag[1] != 0)
9845 function=(MagickFunction) argument_list[1].long_reference;
9846 av=(AV *) argument_list[0].array_reference;
9847 number_parameters=(unsigned long) av_len(av)+1;
9848 parameters=(double *) AcquireQuantumMemory(number_parameters,
9849 sizeof(*parameters));
9850 if (parameters == (double *) NULL)
9851 {
9852 ThrowPerlException(exception,ResourceLimitFatalError,
9853 "MemoryAllocationFailed",PackageName);
9854 goto PerlException;
9855 }
9856 for (j=0; j < (long) number_parameters; j++)
9857 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
9858 virtual_pixel=UndefinedVirtualPixelMethod;
9859 if (attribute_flag[2] != 0)
9860 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
9861 argument_list[2].long_reference);
9862 (void) FunctionImage(image,function,number_parameters,parameters,
9863 exception);
9864 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
9865 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel);
9866 parameters=(double *) RelinquishMagickMemory(parameters);
9867 break;
9868 }
9869 case 121: /* SelectiveBlur */
9870 {
9871 if (attribute_flag[0] != 0)
9872 {
9873 flags=ParseGeometry(argument_list[0].string_reference,
9874 &geometry_info);
9875 if ((flags & SigmaValue) == 0)
9876 geometry_info.sigma=1.0;
9877 if ((flags & PercentValue) != 0)
9878 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9879 }
9880 if (attribute_flag[1] != 0)
9881 geometry_info.rho=argument_list[1].real_reference;
9882 if (attribute_flag[2] != 0)
9883 geometry_info.sigma=argument_list[2].real_reference;
9884 if (attribute_flag[3] != 0)
9885 geometry_info.xi=argument_list[3].long_reference;;
9886 if (attribute_flag[4] != 0)
9887 channel=(ChannelType) argument_list[4].long_reference;
9888 image=SelectiveBlurImageChannel(image,channel,geometry_info.rho,
9889 geometry_info.sigma,geometry_info.xi,exception);
9890 break;
9891 }
9892 case 122: /* HaldClut */
9893 {
9894 if (attribute_flag[0] == 0)
9895 {
9896 ThrowPerlException(exception,OptionError,"ClutImageRequired",
9897 PackageName);
9898 goto PerlException;
9899 }
9900 if (attribute_flag[1] != 0)
9901 channel=(ChannelType) argument_list[1].long_reference;
9902 (void) HaldClutImageChannel(image,channel,
9903 argument_list[0].image_reference);
9904 break;
9905 }
9906 case 123: /* BlueShift */
9907 {
9908 if (attribute_flag[0] != 0)
9909 (void) ParseGeometry(argument_list[0].string_reference,
9910 &geometry_info);
9911 image=BlueShiftImage(image,geometry_info.rho,exception);
9912 break;
9913 }
9914 case 124: /* ForwardFourierTransformImage */
9915 {
9916 image=ForwardFourierTransformImage(image,
9917 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse,
9918 exception);
9919 break;
9920 }
9921 case 125: /* InverseFourierTransformImage */
9922 {
9923 image=InverseFourierTransformImage(image,
9924 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse,
9925 exception);
9926 break;
9927 }
9928 case 126: /* ColorDecisionList */
9929 {
9930 if (attribute_flag[0] == 0)
9931 argument_list[0].string_reference=(char *) NULL;
9932 (void) ColorDecisionListImage(image,
9933 argument_list[0].string_reference);
9934 break;
9935 }
9936 case 127: /* AutoGamma */
9937 {
9938 if (attribute_flag[0] != 0)
9939 channel=(ChannelType) argument_list[0].long_reference;
9940 (void) AutoGammaImageChannel(image,channel);
9941 break;
9942 }
9943 case 128: /* AutoLevel */
9944 {
9945 if (attribute_flag[0] != 0)
9946 channel=(ChannelType) argument_list[0].long_reference;
9947 (void) AutoLevelImageChannel(image,channel);
9948 break;
9949 }
cristyee0f8d72009-09-19 00:58:29 +00009950 case 129: /* LevelColors */
9951 {
9952 MagickPixelPacket
9953 black_point,
9954 white_point;
9955
9956 (void) QueryMagickColor("#000000",&black_point,exception);
9957 (void) QueryMagickColor("#ffffff",&black_point,exception);
9958 if (attribute_flag[1] != 0)
9959 (void) QueryMagickColor(argument_list[1].string_reference,
9960 &black_point,exception);
9961 if (attribute_flag[2] != 0)
9962 (void) QueryMagickColor(argument_list[2].string_reference,
9963 &white_point,exception);
9964 if (attribute_flag[3] != 0)
9965 channel=(ChannelType) argument_list[3].long_reference;
cristy1eb45dd2009-09-25 16:38:06 +00009966 (void) LevelColorsImageChannel(image,channel,&black_point,
9967 &white_point,argument_list[0].long_reference != 0 ? MagickTrue :
9968 MagickFalse);
9969 break;
9970 }
9971 case 130: /* Clamp */
9972 {
9973 if (attribute_flag[0] != 0)
9974 channel=(ChannelType) argument_list[0].long_reference;
9975 (void) ClampImageChannel(image,channel);
cristyee0f8d72009-09-19 00:58:29 +00009976 break;
9977 }
cristy3ed852e2009-09-05 21:47:34 +00009978 }
9979 if (next != (Image *) NULL)
9980 (void) CatchImageException(next);
9981 if (region_image != (Image *) NULL)
9982 {
9983 /*
9984 Composite region.
9985 */
9986 status=CompositeImage(region_image,CopyCompositeOp,image,
9987 region_info.x,region_info.y);
9988 (void) CatchImageException(region_image);
9989 image=DestroyImage(image);
9990 image=region_image;
9991 }
9992 if (image != (Image *) NULL)
9993 {
9994 number_images++;
9995 if (next && (next != image))
9996 {
9997 image->next=next->next;
9998 DeleteImageFromRegistry(*pv,next);
9999 }
10000 sv_setiv(*pv,(IV) image);
10001 next=image;
10002 }
10003 if (*pv)
10004 pv++;
10005 }
10006
10007 PerlException:
10008 if (reference_vector)
10009 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
10010 InheritPerlException(exception,perl_exception);
10011 exception=DestroyExceptionInfo(exception);
10012 sv_setiv(perl_exception,(IV) number_images);
10013 SvPOK_on(perl_exception);
10014 ST(0)=sv_2mortal(perl_exception);
10015 XSRETURN(1);
10016 }
10017
10018#
10019###############################################################################
10020# #
10021# #
10022# #
10023# M o n t a g e #
10024# #
10025# #
10026# #
10027###############################################################################
10028#
10029#
10030void
10031Montage(ref,...)
10032 Image::Magick ref=NO_INIT
10033 ALIAS:
10034 MontageImage = 1
10035 montage = 2
10036 montageimage = 3
10037 PPCODE:
10038 {
10039 AV
10040 *av;
10041
10042 char
10043 *attribute;
10044
10045 ExceptionInfo
10046 *exception;
10047
10048 HV
10049 *hv;
10050
10051 Image
10052 *image,
10053 *next;
10054
10055 long
10056 sp;
10057
10058 MagickPixelPacket
10059 transparent_color;
10060
10061 MontageInfo
10062 *montage_info;
10063
10064 register long
10065 i;
10066
10067 struct PackageInfo
10068 *info;
10069
10070 SV
10071 *av_reference,
10072 *perl_exception,
10073 *reference,
10074 *rv,
10075 *sv;
10076
10077 exception=AcquireExceptionInfo();
10078 perl_exception=newSVpv("",0);
10079 attribute=NULL;
10080 if (sv_isobject(ST(0)) == 0)
10081 {
10082 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10083 PackageName);
10084 goto PerlException;
10085 }
10086 reference=SvRV(ST(0));
10087 hv=SvSTASH(reference);
10088 av=newAV();
10089 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10090 SvREFCNT_dec(av);
10091 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10092 if (image == (Image *) NULL)
10093 {
10094 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10095 PackageName);
10096 goto PerlException;
10097 }
10098 /*
10099 Get options.
10100 */
10101 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10102 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
10103 (void) QueryMagickColor("none",&transparent_color,exception);
10104 for (i=2; i < items; i+=2)
10105 {
10106 attribute=(char *) SvPV(ST(i-1),na);
10107 switch (*attribute)
10108 {
10109 case 'B':
10110 case 'b':
10111 {
10112 if (LocaleCompare(attribute,"background") == 0)
10113 {
10114 (void) QueryColorDatabase(SvPV(ST(i),na),
10115 &montage_info->background_color,exception);
10116 for (next=image; next; next=next->next)
10117 next->background_color=montage_info->background_color;
10118 break;
10119 }
10120 if (LocaleCompare(attribute,"border") == 0)
10121 {
10122 montage_info->border_width=SvIV(ST(i));
10123 break;
10124 }
10125 if (LocaleCompare(attribute,"bordercolor") == 0)
10126 {
10127 (void) QueryColorDatabase(SvPV(ST(i),na),
10128 &montage_info->border_color,exception);
10129 for (next=image; next; next=next->next)
10130 next->border_color=montage_info->border_color;
10131 break;
10132 }
10133 if (LocaleCompare(attribute,"borderwidth") == 0)
10134 {
10135 montage_info->border_width=SvIV(ST(i));
10136 break;
10137 }
10138 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10139 attribute);
10140 break;
10141 }
10142 case 'C':
10143 case 'c':
10144 {
10145 if (LocaleCompare(attribute,"compose") == 0)
10146 {
10147 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
10148 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
10149 if (sp < 0)
10150 {
10151 ThrowPerlException(exception,OptionError,"UnrecognizedType",
10152 SvPV(ST(i),na));
10153 break;
10154 }
10155 for (next=image; next; next=next->next)
10156 next->compose=(CompositeOperator) sp;
10157 break;
10158 }
10159 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10160 attribute);
10161 break;
10162 }
10163 case 'F':
10164 case 'f':
10165 {
10166 if (LocaleCompare(attribute,"fill") == 0)
10167 {
10168 (void) QueryColorDatabase(SvPV(ST(i),na),&montage_info->fill,
10169 exception);
10170 break;
10171 }
10172 if (LocaleCompare(attribute,"font") == 0)
10173 {
10174 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
10175 break;
10176 }
10177 if (LocaleCompare(attribute,"frame") == 0)
10178 {
10179 char
10180 *p;
10181
10182 p=SvPV(ST(i),na);
10183 if (IsGeometry(p) == MagickFalse)
10184 {
10185 ThrowPerlException(exception,OptionError,"MissingGeometry",
10186 p);
10187 break;
10188 }
10189 (void) CloneString(&montage_info->frame,p);
10190 if (*p == '\0')
10191 montage_info->frame=(char *) NULL;
10192 break;
10193 }
10194 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10195 attribute);
10196 break;
10197 }
10198 case 'G':
10199 case 'g':
10200 {
10201 if (LocaleCompare(attribute,"geometry") == 0)
10202 {
10203 char
10204 *p;
10205
10206 p=SvPV(ST(i),na);
10207 if (IsGeometry(p) == MagickFalse)
10208 {
10209 ThrowPerlException(exception,OptionError,"MissingGeometry",
10210 p);
10211 break;
10212 }
10213 (void) CloneString(&montage_info->geometry,p);
10214 if (*p == '\0')
10215 montage_info->geometry=(char *) NULL;
10216 break;
10217 }
10218 if (LocaleCompare(attribute,"gravity") == 0)
10219 {
10220 long
10221 in;
10222
10223 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
10224 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
10225 if (in < 0)
10226 {
10227 ThrowPerlException(exception,OptionError,"UnrecognizedType",
10228 SvPV(ST(i),na));
10229 return;
10230 }
10231 montage_info->gravity=(GravityType) in;
10232 for (next=image; next; next=next->next)
10233 next->gravity=(GravityType) in;
10234 break;
10235 }
10236 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10237 attribute);
10238 break;
10239 }
10240 case 'L':
10241 case 'l':
10242 {
10243 if (LocaleCompare(attribute,"label") == 0)
10244 {
10245 for (next=image; next; next=next->next)
10246 (void) SetImageProperty(next,"label",InterpretImageProperties(
10247 info ? info->image_info : (ImageInfo *) NULL,next,
10248 SvPV(ST(i),na)));
10249 break;
10250 }
10251 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10252 attribute);
10253 break;
10254 }
10255 case 'M':
10256 case 'm':
10257 {
10258 if (LocaleCompare(attribute,"mattecolor") == 0)
10259 {
10260 (void) QueryColorDatabase(SvPV(ST(i),na),
10261 &montage_info->matte_color,exception);
10262 for (next=image; next; next=next->next)
10263 next->matte_color=montage_info->matte_color;
10264 break;
10265 }
10266 if (LocaleCompare(attribute,"mode") == 0)
10267 {
10268 long
10269 in;
10270
10271 in=!SvPOK(ST(i)) ? SvIV(ST(i)) :
10272 ParseMagickOption(MagickModeOptions,MagickFalse,SvPV(ST(i),na));
10273 switch (in)
10274 {
10275 default:
10276 {
10277 ThrowPerlException(exception,OptionError,
10278 "UnrecognizedModeType",SvPV(ST(i),na));
10279 break;
10280 }
10281 case FrameMode:
10282 {
10283 (void) CloneString(&montage_info->frame,"15x15+3+3");
10284 montage_info->shadow=MagickTrue;
10285 break;
10286 }
10287 case UnframeMode:
10288 {
10289 montage_info->frame=(char *) NULL;
10290 montage_info->shadow=MagickFalse;
10291 montage_info->border_width=0;
10292 break;
10293 }
10294 case ConcatenateMode:
10295 {
10296 montage_info->frame=(char *) NULL;
10297 montage_info->shadow=MagickFalse;
10298 (void) CloneString(&montage_info->geometry,"+0+0");
10299 montage_info->border_width=0;
10300 }
10301 }
10302 break;
10303 }
10304 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10305 attribute);
10306 break;
10307 }
10308 case 'P':
10309 case 'p':
10310 {
10311 if (LocaleCompare(attribute,"pointsize") == 0)
10312 {
10313 montage_info->pointsize=SvIV(ST(i));
10314 break;
10315 }
10316 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10317 attribute);
10318 break;
10319 }
10320 case 'S':
10321 case 's':
10322 {
10323 if (LocaleCompare(attribute,"shadow") == 0)
10324 {
10325 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
10326 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
10327 if (sp < 0)
10328 {
10329 ThrowPerlException(exception,OptionError,"UnrecognizedType",
10330 SvPV(ST(i),na));
10331 break;
10332 }
10333 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
10334 break;
10335 }
10336 if (LocaleCompare(attribute,"stroke") == 0)
10337 {
10338 (void) QueryColorDatabase(SvPV(ST(i),na),&montage_info->stroke,
10339 exception);
10340 break;
10341 }
10342 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10343 attribute);
10344 break;
10345 }
10346 case 'T':
10347 case 't':
10348 {
10349 if (LocaleCompare(attribute,"texture") == 0)
10350 {
10351 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
10352 break;
10353 }
10354 if (LocaleCompare(attribute,"tile") == 0)
10355 {
10356 char *p=SvPV(ST(i),na);
10357 if (IsGeometry(p) == MagickFalse)
10358 {
10359 ThrowPerlException(exception,OptionError,"MissingGeometry",
10360 p);
10361 break;
10362 }
10363 (void) CloneString(&montage_info->tile,p);
10364 if (*p == '\0')
10365 montage_info->tile=(char *) NULL;
10366 break;
10367 }
10368 if (LocaleCompare(attribute,"title") == 0)
10369 {
10370 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
10371 break;
10372 }
10373 if (LocaleCompare(attribute,"transparent") == 0)
10374 {
10375 MagickPixelPacket
10376 transparent_color;
10377
10378 QueryMagickColor(SvPV(ST(i),na),&transparent_color,exception);
10379 for (next=image; next; next=next->next)
10380 (void) TransparentPaintImage(next,&transparent_color,
10381 TransparentOpacity,MagickFalse);
10382 break;
10383 }
10384 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10385 attribute);
10386 break;
10387 }
10388 default:
10389 {
10390 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10391 attribute);
10392 break;
10393 }
10394 }
10395 }
10396 image=MontageImageList(info->image_info,montage_info,image,exception);
10397 montage_info=DestroyMontageInfo(montage_info);
10398 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
10399 goto PerlException;
10400 if (transparent_color.opacity != TransparentOpacity)
10401 for (next=image; next; next=next->next)
10402 (void) TransparentPaintImage(next,&transparent_color,
10403 TransparentOpacity,MagickFalse);
10404 for ( ; image; image=image->next)
10405 {
10406 AddImageToRegistry(image);
10407 rv=newRV(sv);
10408 av_push(av,sv_bless(rv,hv));
10409 SvREFCNT_dec(sv);
10410 }
10411 exception=DestroyExceptionInfo(exception);
10412 ST(0)=av_reference;
10413 SvREFCNT_dec(perl_exception);
10414 XSRETURN(1);
10415
10416 PerlException:
10417 InheritPerlException(exception,perl_exception);
10418 exception=DestroyExceptionInfo(exception);
10419 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10420 SvPOK_on(perl_exception);
10421 ST(0)=sv_2mortal(perl_exception);
10422 XSRETURN(1);
10423 }
10424
10425#
10426###############################################################################
10427# #
10428# #
10429# #
10430# M o r p h #
10431# #
10432# #
10433# #
10434###############################################################################
10435#
10436#
10437void
10438Morph(ref,...)
10439 Image::Magick ref=NO_INIT
10440 ALIAS:
10441 MorphImage = 1
10442 morph = 2
10443 morphimage = 3
10444 PPCODE:
10445 {
10446 AV
10447 *av;
10448
10449 char
10450 *attribute;
10451
10452 ExceptionInfo
10453 *exception;
10454
10455 HV
10456 *hv;
10457
10458 Image
10459 *image;
10460
10461 long
10462 number_frames;
10463
10464 register long
10465 i;
10466
10467 struct PackageInfo
10468 *info;
10469
10470 SV
10471 *av_reference,
10472 *perl_exception,
10473 *reference,
10474 *rv,
10475 *sv;
10476
10477 exception=AcquireExceptionInfo();
10478 perl_exception=newSVpv("",0);
10479 av=NULL;
10480 attribute=NULL;
10481 if (sv_isobject(ST(0)) == 0)
10482 {
10483 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10484 PackageName);
10485 goto PerlException;
10486 }
10487 reference=SvRV(ST(0));
10488 hv=SvSTASH(reference);
10489 av=newAV();
10490 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10491 SvREFCNT_dec(av);
10492 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10493 if (image == (Image *) NULL)
10494 {
10495 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10496 PackageName);
10497 goto PerlException;
10498 }
10499 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10500 /*
10501 Get attribute.
10502 */
10503 number_frames=30;
10504 for (i=2; i < items; i+=2)
10505 {
10506 attribute=(char *) SvPV(ST(i-1),na);
10507 switch (*attribute)
10508 {
10509 case 'F':
10510 case 'f':
10511 {
10512 if (LocaleCompare(attribute,"frames") == 0)
10513 {
10514 number_frames=SvIV(ST(i));
10515 break;
10516 }
10517 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10518 attribute);
10519 break;
10520 }
10521 default:
10522 {
10523 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10524 attribute);
10525 break;
10526 }
10527 }
10528 }
10529 image=MorphImages(image,number_frames,exception);
10530 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
10531 goto PerlException;
10532 for ( ; image; image=image->next)
10533 {
10534 AddImageToRegistry(image);
10535 rv=newRV(sv);
10536 av_push(av,sv_bless(rv,hv));
10537 SvREFCNT_dec(sv);
10538 }
10539 exception=DestroyExceptionInfo(exception);
10540 ST(0)=av_reference;
10541 SvREFCNT_dec(perl_exception); /* can't return warning messages */
10542 XSRETURN(1);
10543
10544 PerlException:
10545 InheritPerlException(exception,perl_exception);
10546 exception=DestroyExceptionInfo(exception);
10547 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10548 SvPOK_on(perl_exception);
10549 ST(0)=sv_2mortal(perl_exception);
10550 XSRETURN(1);
10551 }
10552
10553#
10554###############################################################################
10555# #
10556# #
10557# #
10558# M o s a i c #
10559# #
10560# #
10561# #
10562###############################################################################
10563#
10564#
10565void
10566Mosaic(ref)
10567 Image::Magick ref=NO_INIT
10568 ALIAS:
10569 MosaicImage = 1
10570 mosaic = 2
10571 mosaicimage = 3
10572 PPCODE:
10573 {
10574 AV
10575 *av;
10576
10577 ExceptionInfo
10578 *exception;
10579
10580 HV
10581 *hv;
10582
10583 Image
10584 *image;
10585
10586 struct PackageInfo
10587 *info;
10588
10589 SV
10590 *perl_exception,
10591 *reference,
10592 *rv,
10593 *sv;
10594
10595 exception=AcquireExceptionInfo();
10596 perl_exception=newSVpv("",0);
10597 if (sv_isobject(ST(0)) == 0)
10598 {
10599 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10600 PackageName);
10601 goto PerlException;
10602 }
10603 reference=SvRV(ST(0));
10604 hv=SvSTASH(reference);
10605 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10606 if (image == (Image *) NULL)
10607 {
10608 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10609 PackageName);
10610 goto PerlException;
10611 }
10612 image=MergeImageLayers(image,MosaicLayer,exception);
10613 /*
10614 Create blessed Perl array for the returned image.
10615 */
10616 av=newAV();
10617 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10618 SvREFCNT_dec(av);
10619 AddImageToRegistry(image);
10620 rv=newRV(sv);
10621 av_push(av,sv_bless(rv,hv));
10622 SvREFCNT_dec(sv);
10623 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10624 (void) CopyMagickString(image->filename,info->image_info->filename,
10625 MaxTextExtent);
10626 SetImageInfo(info->image_info,MagickFalse,&image->exception);
10627 exception=DestroyExceptionInfo(exception);
10628 SvREFCNT_dec(perl_exception);
10629 XSRETURN(1);
10630
10631 PerlException:
10632 InheritPerlException(exception,perl_exception);
10633 exception=DestroyExceptionInfo(exception);
10634 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10635 SvPOK_on(perl_exception); /* return messages in string context */
10636 ST(0)=sv_2mortal(perl_exception);
10637 XSRETURN(1);
10638 }
10639
10640#
10641###############################################################################
10642# #
10643# #
10644# #
10645# P i n g #
10646# #
10647# #
10648# #
10649###############################################################################
10650#
10651#
10652void
10653Ping(ref,...)
10654 Image::Magick ref=NO_INIT
10655 ALIAS:
10656 PingImage = 1
10657 ping = 2
10658 pingimage = 3
10659 PPCODE:
10660 {
10661 AV
10662 *av;
10663
10664 char
10665 **keep,
10666 **list;
10667
10668 ExceptionInfo
10669 *exception;
10670
10671 HV
10672 *hv;
10673
10674 Image
10675 *image,
10676 *next;
10677
10678 int
10679 n;
10680
10681 long
10682 ac;
10683
10684 MagickBooleanType
10685 status;
10686
10687 register char
10688 **p;
10689
10690 register long
10691 i;
10692
10693 STRLEN
10694 *length;
10695
10696 struct PackageInfo
10697 *info,
10698 *package_info;
10699
10700 SV
10701 *perl_exception,
10702 *reference;
10703
10704 unsigned long
10705 count;
10706
10707 exception=AcquireExceptionInfo();
10708 perl_exception=newSVpv("",0);
10709 package_info=(struct PackageInfo *) NULL;
10710 ac=(items < 2) ? 1 : items-1;
10711 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
10712 keep=list;
10713 length=(STRLEN *) NULL;
10714 if (list == (char **) NULL)
10715 {
10716 ThrowPerlException(exception,ResourceLimitError,
10717 "MemoryAllocationFailed",PackageName);
10718 goto PerlException;
10719 }
10720 keep=list;
10721 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
10722 if (length == (STRLEN *) NULL)
10723 {
10724 ThrowPerlException(exception,ResourceLimitError,
10725 "MemoryAllocationFailed",PackageName);
10726 goto PerlException;
10727 }
10728 if (sv_isobject(ST(0)) == 0)
10729 {
10730 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10731 PackageName);
10732 goto PerlException;
10733 }
10734 reference=SvRV(ST(0));
10735 hv=SvSTASH(reference);
10736 if (SvTYPE(reference) != SVt_PVAV)
10737 {
10738 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10739 PackageName);
10740 goto PerlException;
10741 }
10742 av=(AV *) reference;
10743 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
10744 exception);
10745 package_info=ClonePackageInfo(info,exception);
10746 n=1;
10747 if (items <= 1)
10748 *list=(char *) (*package_info->image_info->filename ?
10749 package_info->image_info->filename : "XC:black");
10750 else
10751 for (n=0, i=0; i < ac; i++)
10752 {
10753 list[n]=(char *) SvPV(ST(i+1),length[n]);
10754 if ((items >= 3) && strEQcase(list[n],"blob"))
10755 {
10756 void
10757 *blob;
10758
10759 i++;
10760 blob=(void *) (SvPV(ST(i+1),length[n]));
10761 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
10762 }
10763 if ((items >= 3) && strEQcase(list[n],"filename"))
10764 continue;
10765 if ((items >= 3) && strEQcase(list[n],"file"))
10766 {
10767 FILE
10768 *file;
10769
10770 PerlIO
10771 *io_info;
10772
10773 i++;
10774 io_info=IoIFP(sv_2io(ST(i+1)));
10775 if (io_info == (PerlIO *) NULL)
10776 {
10777 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
10778 PackageName);
10779 continue;
10780 }
10781 file=PerlIO_findFILE(io_info);
10782 if (file == (FILE *) NULL)
10783 {
10784 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
10785 PackageName);
10786 continue;
10787 }
10788 SetImageInfoFile(package_info->image_info,file);
10789 }
10790 if ((items >= 3) && strEQcase(list[n],"magick"))
10791 continue;
10792 n++;
10793 }
10794 list[n]=(char *) NULL;
10795 keep=list;
10796 status=ExpandFilenames(&n,&list);
10797 if (status == MagickFalse)
10798 {
10799 ThrowPerlException(exception,ResourceLimitError,
10800 "MemoryAllocationFailed",PackageName);
10801 goto PerlException;
10802 }
10803 count=0;
10804 for (i=0; i < n; i++)
10805 {
10806 (void) CopyMagickString(package_info->image_info->filename,list[i],
10807 MaxTextExtent);
10808 image=PingImage(package_info->image_info,exception);
10809 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
10810 break;
10811 if ((package_info->image_info->file != (FILE *) NULL) ||
10812 (package_info->image_info->blob != (void *) NULL))
10813 DisassociateImageStream(image);
10814 count+=GetImageListLength(image);
10815 EXTEND(sp,4*count);
10816 for (next=image; next; next=next->next)
10817 {
10818 PUSHs(sv_2mortal(newSViv(next->columns)));
10819 PUSHs(sv_2mortal(newSViv(next->rows)));
10820 PUSHs(sv_2mortal(newSViv((unsigned long) GetBlobSize(next))));
10821 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
10822 }
10823 image=DestroyImageList(image);
10824 }
10825 /*
10826 Free resources.
10827 */
10828 for (i=0; i < n; i++)
10829 if (list[i] != (char *) NULL)
10830 for (p=keep; list[i] != *p++; )
10831 if (*p == NULL)
10832 {
10833 list[i]=(char *) RelinquishMagickMemory(list[i]);
10834 break;
10835 }
10836
10837 PerlException:
10838 if (package_info != (struct PackageInfo *) NULL)
10839 DestroyPackageInfo(package_info);
10840 if (list && (list != keep))
10841 list=(char **) RelinquishMagickMemory(list);
10842 if (keep)
10843 keep=(char **) RelinquishMagickMemory(keep);
10844 if (length)
10845 length=(STRLEN *) RelinquishMagickMemory(length);
10846 InheritPerlException(exception,perl_exception);
10847 exception=DestroyExceptionInfo(exception);
10848 SvREFCNT_dec(perl_exception); /* throw away all errors */
10849 }
10850
10851#
10852###############################################################################
10853# #
10854# #
10855# #
10856# P r e v i e w #
10857# #
10858# #
10859# #
10860###############################################################################
10861#
10862#
10863void
10864Preview(ref,...)
10865 Image::Magick ref=NO_INIT
10866 ALIAS:
10867 PreviewImage = 1
10868 preview = 2
10869 previewimage = 3
10870 PPCODE:
10871 {
10872 AV
10873 *av;
10874
10875 ExceptionInfo
10876 *exception;
10877
10878 HV
10879 *hv;
10880
10881 Image
10882 *image,
10883 *preview_image;
10884
10885 PreviewType
10886 preview_type;
10887
10888 struct PackageInfo
10889 *info;
10890
10891 SV
10892 *av_reference,
10893 *perl_exception,
10894 *reference,
10895 *rv,
10896 *sv;
10897
10898 exception=AcquireExceptionInfo();
10899 perl_exception=newSVpv("",0);
10900 av=NULL;
10901 if (sv_isobject(ST(0)) == 0)
10902 {
10903 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10904 PackageName);
10905 goto PerlException;
10906 }
10907 reference=SvRV(ST(0));
10908 hv=SvSTASH(reference);
10909 av=newAV();
10910 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10911 SvREFCNT_dec(av);
10912 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10913 if (image == (Image *) NULL)
10914 {
10915 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10916 PackageName);
10917 goto PerlException;
10918 }
10919 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10920 preview_type=GammaPreview;
10921 if (items > 1)
10922 preview_type=(PreviewType)
10923 ParseMagickOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
10924 for ( ; image; image=image->next)
10925 {
10926 preview_image=PreviewImage(image,preview_type,exception);
10927 if (preview_image == (Image *) NULL)
10928 goto PerlException;
10929 AddImageToRegistry(preview_image);
10930 rv=newRV(sv);
10931 av_push(av,sv_bless(rv,hv));
10932 SvREFCNT_dec(sv);
10933 }
10934 exception=DestroyExceptionInfo(exception);
10935 ST(0)=av_reference;
10936 SvREFCNT_dec(perl_exception); /* can't return warning messages */
10937 XSRETURN(1);
10938
10939 PerlException:
10940 InheritPerlException(exception,perl_exception);
10941 exception=DestroyExceptionInfo(exception);
10942 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10943 SvPOK_on(perl_exception);
10944 ST(0)=sv_2mortal(perl_exception);
10945 XSRETURN(1);
10946 }
10947
10948#
10949###############################################################################
10950# #
10951# #
10952# #
10953# Q u e r y C o l o r #
10954# #
10955# #
10956# #
10957###############################################################################
10958#
10959#
10960void
10961QueryColor(ref,...)
10962 Image::Magick ref=NO_INIT
10963 ALIAS:
10964 querycolor = 1
10965 PPCODE:
10966 {
10967 char
10968 *name;
10969
10970 ExceptionInfo
10971 *exception;
10972
10973 MagickPixelPacket
10974 color;
10975
10976 register long
10977 i;
10978
10979 SV
10980 *perl_exception;
10981
10982 exception=AcquireExceptionInfo();
10983 perl_exception=newSVpv("",0);
10984 if (items == 1)
10985 {
10986 const ColorInfo
10987 **colorlist;
10988
10989 unsigned long
10990 colors;
10991
10992 colorlist=GetColorInfoList("*",&colors,exception);
10993 EXTEND(sp,colors);
10994 for (i=0; i < (long) colors; i++)
10995 {
10996 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
10997 }
10998 colorlist=(const ColorInfo **)
10999 RelinquishMagickMemory((ColorInfo **) colorlist);
11000 goto PerlException;
11001 }
11002 EXTEND(sp,5*items);
11003 for (i=1; i < items; i++)
11004 {
11005 name=(char *) SvPV(ST(i),na);
11006 if (QueryMagickColor(name,&color,exception) == MagickFalse)
11007 {
11008 PUSHs(&sv_undef);
11009 continue;
11010 }
11011 PUSHs(sv_2mortal(newSViv((unsigned long) (color.red+0.5))));
11012 PUSHs(sv_2mortal(newSViv((unsigned long) (color.green+0.5))));
11013 PUSHs(sv_2mortal(newSViv((unsigned long) (color.blue+0.5))));
11014 if (color.matte != MagickFalse)
11015 PUSHs(sv_2mortal(newSViv((unsigned long) (color.opacity+0.5))));
11016 if (color.colorspace == CMYKColorspace)
11017 PUSHs(sv_2mortal(newSViv((unsigned long) (color.index+0.5))));
11018 }
11019
11020 PerlException:
11021 InheritPerlException(exception,perl_exception);
11022 exception=DestroyExceptionInfo(exception);
11023 SvREFCNT_dec(perl_exception);
11024 }
11025
11026#
11027###############################################################################
11028# #
11029# #
11030# #
11031# Q u e r y C o l o r N a m e #
11032# #
11033# #
11034# #
11035###############################################################################
11036#
11037#
11038void
11039QueryColorname(ref,...)
11040 Image::Magick ref=NO_INIT
11041 ALIAS:
11042 querycolorname = 1
11043 PPCODE:
11044 {
11045 AV
11046 *av;
11047
11048 char
11049 message[MaxTextExtent];
11050
11051 ExceptionInfo
11052 *exception;
11053
11054 Image
11055 *image;
11056
11057 PixelPacket
11058 target_color;
11059
11060 register long
11061 i;
11062
11063 struct PackageInfo
11064 *info;
11065
11066 SV
11067 *perl_exception,
11068 *reference; /* reference is the SV* of ref=SvIV(reference) */
11069
11070 exception=AcquireExceptionInfo();
11071 perl_exception=newSVpv("",0);
11072 reference=SvRV(ST(0));
11073 av=(AV *) reference;
11074 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11075 exception);
11076 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11077 if (image == (Image *) NULL)
11078 {
11079 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11080 PackageName);
11081 goto PerlException;
11082 }
11083 EXTEND(sp,items);
11084 for (i=1; i < items; i++)
11085 {
11086 (void) QueryColorDatabase(SvPV(ST(i),na),&target_color,exception);
11087 (void) QueryColorname(image,&target_color,SVGCompliance,message,
11088 exception);
11089 PUSHs(sv_2mortal(newSVpv(message,0)));
11090 }
11091
11092 PerlException:
11093 InheritPerlException(exception,perl_exception);
11094 exception=DestroyExceptionInfo(exception);
11095 SvREFCNT_dec(perl_exception);
11096 }
11097
11098#
11099###############################################################################
11100# #
11101# #
11102# #
11103# Q u e r y F o n t #
11104# #
11105# #
11106# #
11107###############################################################################
11108#
11109#
11110void
11111QueryFont(ref,...)
11112 Image::Magick ref=NO_INIT
11113 ALIAS:
11114 queryfont = 1
11115 PPCODE:
11116 {
11117 char
11118 *name,
11119 message[MaxTextExtent];
11120
11121 ExceptionInfo
11122 *exception;
11123
11124 register long
11125 i;
11126
11127 SV
11128 *perl_exception;
11129
11130 volatile const TypeInfo
11131 *type_info;
11132
11133 exception=AcquireExceptionInfo();
11134 perl_exception=newSVpv("",0);
11135 if (items == 1)
11136 {
11137 const TypeInfo
11138 **typelist;
11139
11140 unsigned long
11141 types;
11142
11143 typelist=GetTypeInfoList("*",&types,exception);
11144 EXTEND(sp,types);
11145 for (i=0; i < (long) types; i++)
11146 {
11147 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
11148 }
11149 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
11150 typelist);
11151 goto PerlException;
11152 }
11153 EXTEND(sp,10*items);
11154 for (i=1; i < items; i++)
11155 {
11156 name=(char *) SvPV(ST(i),na);
11157 type_info=GetTypeInfo(name,exception);
11158 if (type_info == (TypeInfo *) NULL)
11159 {
11160 PUSHs(&sv_undef);
11161 continue;
11162 }
11163 if (type_info->name == (char *) NULL)
11164 PUSHs(&sv_undef);
11165 else
11166 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
11167 if (type_info->description == (char *) NULL)
11168 PUSHs(&sv_undef);
11169 else
11170 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
11171 if (type_info->family == (char *) NULL)
11172 PUSHs(&sv_undef);
11173 else
11174 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
11175 if (type_info->style == UndefinedStyle)
11176 PUSHs(&sv_undef);
11177 else
11178 PUSHs(sv_2mortal(newSVpv(MagickOptionToMnemonic(MagickStyleOptions,
11179 type_info->style),0)));
11180 if (type_info->stretch == UndefinedStretch)
11181 PUSHs(&sv_undef);
11182 else
11183 PUSHs(sv_2mortal(newSVpv(MagickOptionToMnemonic(MagickStretchOptions,
11184 type_info->stretch),0)));
11185 (void) FormatMagickString(message,MaxTextExtent,"%lu",type_info->weight);
11186 PUSHs(sv_2mortal(newSVpv(message,0)));
11187 if (type_info->encoding == (char *) NULL)
11188 PUSHs(&sv_undef);
11189 else
11190 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
11191 if (type_info->foundry == (char *) NULL)
11192 PUSHs(&sv_undef);
11193 else
11194 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
11195 if (type_info->format == (char *) NULL)
11196 PUSHs(&sv_undef);
11197 else
11198 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
11199 if (type_info->metrics == (char *) NULL)
11200 PUSHs(&sv_undef);
11201 else
11202 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
11203 if (type_info->glyphs == (char *) NULL)
11204 PUSHs(&sv_undef);
11205 else
11206 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
11207 }
11208
11209 PerlException:
11210 InheritPerlException(exception,perl_exception);
11211 exception=DestroyExceptionInfo(exception);
11212 SvREFCNT_dec(perl_exception);
11213 }
11214
11215#
11216###############################################################################
11217# #
11218# #
11219# #
11220# Q u e r y F o n t M e t r i c s #
11221# #
11222# #
11223# #
11224###############################################################################
11225#
11226#
11227void
11228QueryFontMetrics(ref,...)
11229 Image::Magick ref=NO_INIT
11230 ALIAS:
11231 queryfontmetrics = 1
11232 PPCODE:
11233 {
11234 AffineMatrix
11235 affine,
11236 current;
11237
11238 AV
11239 *av;
11240
11241 char
11242 *attribute;
11243
11244 double
11245 x,
11246 y;
11247
11248 DrawInfo
11249 *draw_info;
11250
11251 ExceptionInfo
11252 *exception;
11253
11254 GeometryInfo
11255 geometry_info;
11256
11257 Image
11258 *image;
11259
11260 long
11261 type;
11262
11263 MagickBooleanType
11264 status;
11265
11266 MagickStatusType
11267 flags;
11268
11269 register long
11270 i;
11271
11272 struct PackageInfo
11273 *info,
11274 *package_info;
11275
11276 SV
11277 *perl_exception,
11278 *reference; /* reference is the SV* of ref=SvIV(reference) */
11279
11280 TypeMetric
11281 metrics;
11282
11283 exception=AcquireExceptionInfo();
11284 package_info=(struct PackageInfo *) NULL;
11285 perl_exception=newSVpv("",0);
11286 reference=SvRV(ST(0));
11287 av=(AV *) reference;
11288 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11289 exception);
11290 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11291 if (image == (Image *) NULL)
11292 {
11293 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11294 PackageName);
11295 goto PerlException;
11296 }
11297 package_info=ClonePackageInfo(info,exception);
11298 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
11299 CloneString(&draw_info->text,"");
11300 current=draw_info->affine;
11301 GetAffineMatrix(&affine);
11302 x=0.0;
11303 y=0.0;
11304 EXTEND(sp,7*items);
11305 for (i=2; i < items; i+=2)
11306 {
11307 attribute=(char *) SvPV(ST(i-1),na);
11308 switch (*attribute)
11309 {
11310 case 'A':
11311 case 'a':
11312 {
11313 if (LocaleCompare(attribute,"antialias") == 0)
11314 {
11315 type=ParseMagickOption(MagickBooleanOptions,MagickFalse,
11316 SvPV(ST(i),na));
11317 if (type < 0)
11318 {
11319 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11320 SvPV(ST(i),na));
11321 break;
11322 }
11323 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
11324 break;
11325 }
11326 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11327 attribute);
11328 break;
11329 }
11330 case 'd':
11331 case 'D':
11332 {
11333 if (LocaleCompare(attribute,"density") == 0)
11334 {
11335 CloneString(&draw_info->density,SvPV(ST(i),na));
11336 break;
11337 }
11338 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11339 attribute);
11340 break;
11341 }
11342 case 'e':
11343 case 'E':
11344 {
11345 if (LocaleCompare(attribute,"encoding") == 0)
11346 {
11347 CloneString(&draw_info->encoding,SvPV(ST(i),na));
11348 break;
11349 }
11350 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11351 attribute);
11352 break;
11353 }
11354 case 'f':
11355 case 'F':
11356 {
11357 if (LocaleCompare(attribute,"family") == 0)
11358 {
11359 CloneString(&draw_info->family,SvPV(ST(i),na));
11360 break;
11361 }
11362 if (LocaleCompare(attribute,"fill") == 0)
11363 {
11364 if (info)
11365 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->fill,
11366 &image->exception);
11367 break;
11368 }
11369 if (LocaleCompare(attribute,"font") == 0)
11370 {
11371 CloneString(&draw_info->font,SvPV(ST(i),na));
11372 break;
11373 }
11374 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11375 attribute);
11376 break;
11377 }
11378 case 'g':
11379 case 'G':
11380 {
11381 if (LocaleCompare(attribute,"geometry") == 0)
11382 {
11383 CloneString(&draw_info->geometry,SvPV(ST(i),na));
11384 break;
11385 }
11386 if (LocaleCompare(attribute,"gravity") == 0)
11387 {
11388 draw_info->gravity=(GravityType) ParseMagickOption(
11389 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11390 break;
11391 }
11392 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11393 attribute);
11394 break;
11395 }
11396 case 'i':
11397 case 'I':
11398 {
cristyb32b90a2009-09-07 21:45:48 +000011399 if (LocaleCompare(attribute,"interline-spacing") == 0)
11400 {
11401 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11402 draw_info->interline_spacing=geometry_info.rho;
11403 break;
11404 }
cristy3ed852e2009-09-05 21:47:34 +000011405 if (LocaleCompare(attribute,"interword-spacing") == 0)
11406 {
11407 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11408 draw_info->interword_spacing=geometry_info.rho;
11409 break;
11410 }
11411 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11412 attribute);
11413 break;
11414 }
11415 case 'k':
11416 case 'K':
11417 {
11418 if (LocaleCompare(attribute,"kerning") == 0)
11419 {
11420 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11421 draw_info->kerning=geometry_info.rho;
11422 break;
11423 }
11424 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11425 attribute);
11426 break;
11427 }
11428 case 'p':
11429 case 'P':
11430 {
11431 if (LocaleCompare(attribute,"pointsize") == 0)
11432 {
11433 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11434 draw_info->pointsize=geometry_info.rho;
11435 break;
11436 }
11437 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11438 attribute);
11439 break;
11440 }
11441 case 'r':
11442 case 'R':
11443 {
11444 if (LocaleCompare(attribute,"rotate") == 0)
11445 {
11446 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11447 affine.rx=geometry_info.rho;
11448 affine.ry=geometry_info.sigma;
11449 if ((flags & SigmaValue) == 0)
11450 affine.ry=affine.rx;
11451 break;
11452 }
11453 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11454 attribute);
11455 break;
11456 }
11457 case 's':
11458 case 'S':
11459 {
11460 if (LocaleCompare(attribute,"scale") == 0)
11461 {
11462 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11463 affine.sx=geometry_info.rho;
11464 affine.sy=geometry_info.sigma;
11465 if ((flags & SigmaValue) == 0)
11466 affine.sy=affine.sx;
11467 break;
11468 }
11469 if (LocaleCompare(attribute,"skew") == 0)
11470 {
11471 double
11472 x_angle,
11473 y_angle;
11474
11475 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11476 x_angle=geometry_info.rho;
11477 y_angle=geometry_info.sigma;
11478 if ((flags & SigmaValue) == 0)
11479 y_angle=x_angle;
11480 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
11481 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
11482 break;
11483 }
11484 if (LocaleCompare(attribute,"stroke") == 0)
11485 {
11486 if (info)
11487 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->stroke,
11488 &image->exception);
11489 break;
11490 }
11491 if (LocaleCompare(attribute,"style") == 0)
11492 {
11493 type=ParseMagickOption(MagickStyleOptions,MagickFalse,
11494 SvPV(ST(i),na));
11495 if (type < 0)
11496 {
11497 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11498 SvPV(ST(i),na));
11499 break;
11500 }
11501 draw_info->style=(StyleType) type;
11502 break;
11503 }
11504 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11505 attribute);
11506 break;
11507 }
11508 case 't':
11509 case 'T':
11510 {
11511 if (LocaleCompare(attribute,"text") == 0)
11512 {
11513 CloneString(&draw_info->text,SvPV(ST(i),na));
11514 break;
11515 }
11516 if (LocaleCompare(attribute,"translate") == 0)
11517 {
11518 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11519 affine.tx=geometry_info.rho;
11520 affine.ty=geometry_info.sigma;
11521 if ((flags & SigmaValue) == 0)
11522 affine.ty=affine.tx;
11523 break;
11524 }
11525 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11526 attribute);
11527 break;
11528 }
11529 case 'w':
11530 case 'W':
11531 {
11532 if (LocaleCompare(attribute,"weight") == 0)
11533 {
11534 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11535 draw_info->weight=(unsigned long) geometry_info.rho;
11536 break;
11537 }
11538 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11539 attribute);
11540 break;
11541 }
11542 case 'x':
11543 case 'X':
11544 {
11545 if (LocaleCompare(attribute,"x") == 0)
11546 {
11547 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11548 x=geometry_info.rho;
11549 break;
11550 }
11551 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11552 attribute);
11553 break;
11554 }
11555 case 'y':
11556 case 'Y':
11557 {
11558 if (LocaleCompare(attribute,"y") == 0)
11559 {
11560 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11561 y=geometry_info.rho;
11562 break;
11563 }
11564 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11565 attribute);
11566 break;
11567 }
11568 default:
11569 {
11570 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11571 attribute);
11572 break;
11573 }
11574 }
11575 }
11576 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
11577 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
11578 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
11579 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
11580 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
11581 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
11582 if (draw_info->geometry == (char *) NULL)
11583 {
11584 draw_info->geometry=AcquireString((char *) NULL);
11585 (void) FormatMagickString(draw_info->geometry,MaxTextExtent,"%g,%g",
11586 x,y);
11587 }
11588 status=GetTypeMetrics(image,draw_info,&metrics);
11589 (void) CatchImageException(image);
11590 if (status == MagickFalse)
11591 PUSHs(&sv_undef);
11592 else
11593 {
11594 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
11595 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
11596 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
11597 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
11598 PUSHs(sv_2mortal(newSVnv(metrics.width)));
11599 PUSHs(sv_2mortal(newSVnv(metrics.height)));
11600 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
11601 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
11602 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
11603 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
11604 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
11605 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
11606 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
11607 }
11608 draw_info=DestroyDrawInfo(draw_info);
11609
11610 PerlException:
11611 if (package_info != (struct PackageInfo *) NULL)
11612 DestroyPackageInfo(package_info);
11613 InheritPerlException(exception,perl_exception);
11614 exception=DestroyExceptionInfo(exception);
11615 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11616 }
11617
11618#
11619###############################################################################
11620# #
11621# #
11622# #
11623# 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 #
11624# #
11625# #
11626# #
11627###############################################################################
11628#
11629#
11630void
11631QueryMultilineFontMetrics(ref,...)
11632 Image::Magick ref=NO_INIT
11633 ALIAS:
11634 querymultilinefontmetrics = 1
11635 PPCODE:
11636 {
11637 AffineMatrix
11638 affine,
11639 current;
11640
11641 AV
11642 *av;
11643
11644 char
11645 *attribute;
11646
11647 double
11648 x,
11649 y;
11650
11651 DrawInfo
11652 *draw_info;
11653
11654 ExceptionInfo
11655 *exception;
11656
11657 GeometryInfo
11658 geometry_info;
11659
11660 Image
11661 *image;
11662
11663 long
11664 type;
11665
11666 MagickBooleanType
11667 status;
11668
11669 MagickStatusType
11670 flags;
11671
11672 register long
11673 i;
11674
11675 struct PackageInfo
11676 *info,
11677 *package_info;
11678
11679 SV
11680 *perl_exception,
11681 *reference; /* reference is the SV* of ref=SvIV(reference) */
11682
11683 TypeMetric
11684 metrics;
11685
11686 exception=AcquireExceptionInfo();
11687 package_info=(struct PackageInfo *) NULL;
11688 perl_exception=newSVpv("",0);
11689 reference=SvRV(ST(0));
11690 av=(AV *) reference;
11691 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11692 exception);
11693 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11694 if (image == (Image *) NULL)
11695 {
11696 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11697 PackageName);
11698 goto PerlException;
11699 }
11700 package_info=ClonePackageInfo(info,exception);
11701 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
11702 CloneString(&draw_info->text,"");
11703 current=draw_info->affine;
11704 GetAffineMatrix(&affine);
11705 x=0.0;
11706 y=0.0;
11707 EXTEND(sp,7*items);
11708 for (i=2; i < items; i+=2)
11709 {
11710 attribute=(char *) SvPV(ST(i-1),na);
11711 switch (*attribute)
11712 {
11713 case 'A':
11714 case 'a':
11715 {
11716 if (LocaleCompare(attribute,"antialias") == 0)
11717 {
11718 type=ParseMagickOption(MagickBooleanOptions,MagickFalse,
11719 SvPV(ST(i),na));
11720 if (type < 0)
11721 {
11722 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11723 SvPV(ST(i),na));
11724 break;
11725 }
11726 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
11727 break;
11728 }
11729 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11730 attribute);
11731 break;
11732 }
11733 case 'd':
11734 case 'D':
11735 {
11736 if (LocaleCompare(attribute,"density") == 0)
11737 {
11738 CloneString(&draw_info->density,SvPV(ST(i),na));
11739 break;
11740 }
11741 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11742 attribute);
11743 break;
11744 }
11745 case 'e':
11746 case 'E':
11747 {
11748 if (LocaleCompare(attribute,"encoding") == 0)
11749 {
11750 CloneString(&draw_info->encoding,SvPV(ST(i),na));
11751 break;
11752 }
11753 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11754 attribute);
11755 break;
11756 }
11757 case 'f':
11758 case 'F':
11759 {
11760 if (LocaleCompare(attribute,"family") == 0)
11761 {
11762 CloneString(&draw_info->family,SvPV(ST(i),na));
11763 break;
11764 }
11765 if (LocaleCompare(attribute,"fill") == 0)
11766 {
11767 if (info)
11768 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->fill,
11769 &image->exception);
11770 break;
11771 }
11772 if (LocaleCompare(attribute,"font") == 0)
11773 {
11774 CloneString(&draw_info->font,SvPV(ST(i),na));
11775 break;
11776 }
11777 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11778 attribute);
11779 break;
11780 }
11781 case 'g':
11782 case 'G':
11783 {
11784 if (LocaleCompare(attribute,"geometry") == 0)
11785 {
11786 CloneString(&draw_info->geometry,SvPV(ST(i),na));
11787 break;
11788 }
11789 if (LocaleCompare(attribute,"gravity") == 0)
11790 {
11791 draw_info->gravity=(GravityType) ParseMagickOption(
11792 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11793 break;
11794 }
11795 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11796 attribute);
11797 break;
11798 }
11799 case 'p':
11800 case 'P':
11801 {
11802 if (LocaleCompare(attribute,"pointsize") == 0)
11803 {
11804 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11805 draw_info->pointsize=geometry_info.rho;
11806 break;
11807 }
11808 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11809 attribute);
11810 break;
11811 }
11812 case 'r':
11813 case 'R':
11814 {
11815 if (LocaleCompare(attribute,"rotate") == 0)
11816 {
11817 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11818 affine.rx=geometry_info.rho;
11819 affine.ry=geometry_info.sigma;
11820 if ((flags & SigmaValue) == 0)
11821 affine.ry=affine.rx;
11822 break;
11823 }
11824 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11825 attribute);
11826 break;
11827 }
11828 case 's':
11829 case 'S':
11830 {
11831 if (LocaleCompare(attribute,"scale") == 0)
11832 {
11833 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11834 affine.sx=geometry_info.rho;
11835 affine.sy=geometry_info.sigma;
11836 if ((flags & SigmaValue) == 0)
11837 affine.sy=affine.sx;
11838 break;
11839 }
11840 if (LocaleCompare(attribute,"skew") == 0)
11841 {
11842 double
11843 x_angle,
11844 y_angle;
11845
11846 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11847 x_angle=geometry_info.rho;
11848 y_angle=geometry_info.sigma;
11849 if ((flags & SigmaValue) == 0)
11850 y_angle=x_angle;
11851 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
11852 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
11853 break;
11854 }
11855 if (LocaleCompare(attribute,"stroke") == 0)
11856 {
11857 if (info)
11858 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->stroke,
11859 &image->exception);
11860 break;
11861 }
11862 if (LocaleCompare(attribute,"style") == 0)
11863 {
11864 type=ParseMagickOption(MagickStyleOptions,MagickFalse,
11865 SvPV(ST(i),na));
11866 if (type < 0)
11867 {
11868 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11869 SvPV(ST(i),na));
11870 break;
11871 }
11872 draw_info->style=(StyleType) type;
11873 break;
11874 }
11875 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11876 attribute);
11877 break;
11878 }
11879 case 't':
11880 case 'T':
11881 {
11882 if (LocaleCompare(attribute,"text") == 0)
11883 {
11884 CloneString(&draw_info->text,SvPV(ST(i),na));
11885 break;
11886 }
11887 if (LocaleCompare(attribute,"translate") == 0)
11888 {
11889 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11890 affine.tx=geometry_info.rho;
11891 affine.ty=geometry_info.sigma;
11892 if ((flags & SigmaValue) == 0)
11893 affine.ty=affine.tx;
11894 break;
11895 }
11896 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11897 attribute);
11898 break;
11899 }
11900 case 'w':
11901 case 'W':
11902 {
11903 if (LocaleCompare(attribute,"weight") == 0)
11904 {
11905 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11906 draw_info->weight=(unsigned long) geometry_info.rho;
11907 break;
11908 }
11909 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11910 attribute);
11911 break;
11912 }
11913 case 'x':
11914 case 'X':
11915 {
11916 if (LocaleCompare(attribute,"x") == 0)
11917 {
11918 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11919 x=geometry_info.rho;
11920 break;
11921 }
11922 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11923 attribute);
11924 break;
11925 }
11926 case 'y':
11927 case 'Y':
11928 {
11929 if (LocaleCompare(attribute,"y") == 0)
11930 {
11931 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11932 y=geometry_info.rho;
11933 break;
11934 }
11935 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11936 attribute);
11937 break;
11938 }
11939 default:
11940 {
11941 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11942 attribute);
11943 break;
11944 }
11945 }
11946 }
11947 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
11948 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
11949 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
11950 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
11951 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
11952 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
11953 if (draw_info->geometry == (char *) NULL)
11954 {
11955 draw_info->geometry=AcquireString((char *) NULL);
11956 (void) FormatMagickString(draw_info->geometry,MaxTextExtent,"%g,%g",
11957 x,y);
11958 }
11959 status=GetMultilineTypeMetrics(image,draw_info,&metrics);
11960 (void) CatchImageException(image);
11961 if (status == MagickFalse)
11962 PUSHs(&sv_undef);
11963 else
11964 {
11965 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
11966 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
11967 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
11968 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
11969 PUSHs(sv_2mortal(newSVnv(metrics.width)));
11970 PUSHs(sv_2mortal(newSVnv(metrics.height)));
11971 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
11972 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
11973 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
11974 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
11975 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
11976 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
11977 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
11978 }
11979 draw_info=DestroyDrawInfo(draw_info);
11980
11981 PerlException:
11982 if (package_info != (struct PackageInfo *) NULL)
11983 DestroyPackageInfo(package_info);
11984 InheritPerlException(exception,perl_exception);
11985 exception=DestroyExceptionInfo(exception);
11986 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11987 }
11988
11989#
11990###############################################################################
11991# #
11992# #
11993# #
11994# Q u e r y F o r m a t #
11995# #
11996# #
11997# #
11998###############################################################################
11999#
12000#
12001void
12002QueryFormat(ref,...)
12003 Image::Magick ref=NO_INIT
12004 ALIAS:
12005 queryformat = 1
12006 PPCODE:
12007 {
12008 char
12009 *name;
12010
12011 ExceptionInfo
12012 *exception;
12013
12014 register long
12015 i;
12016
12017 SV
12018 *perl_exception;
12019
12020 volatile const MagickInfo
12021 *magick_info;
12022
12023 exception=AcquireExceptionInfo();
12024 perl_exception=newSVpv("",0);
12025 if (items == 1)
12026 {
12027 char
12028 format[MaxTextExtent];
12029
12030 const MagickInfo
12031 **format_list;
12032
12033 unsigned long
12034 types;
12035
12036 format_list=GetMagickInfoList("*",&types,exception);
12037 EXTEND(sp,types);
12038 for (i=0; i < (long) types; i++)
12039 {
12040 (void) CopyMagickString(format,format_list[i]->name,MaxTextExtent);
12041 LocaleLower(format);
12042 PUSHs(sv_2mortal(newSVpv(format,0)));
12043 }
12044 format_list=(const MagickInfo **)
12045 RelinquishMagickMemory((MagickInfo *) format_list);
12046 goto PerlException;
12047 }
12048 EXTEND(sp,8*items);
12049 for (i=1; i < items; i++)
12050 {
12051 name=(char *) SvPV(ST(i),na);
12052 magick_info=GetMagickInfo(name,exception);
12053 if (magick_info == (const MagickInfo *) NULL)
12054 {
12055 PUSHs(&sv_undef);
12056 continue;
12057 }
12058 PUSHs(sv_2mortal(newSViv(magick_info->adjoin)));
12059 PUSHs(sv_2mortal(newSViv(magick_info->blob_support)));
12060 PUSHs(sv_2mortal(newSViv(magick_info->raw)));
12061 PUSHs(sv_2mortal(newSViv((long) magick_info->decoder)));
12062 PUSHs(sv_2mortal(newSViv((long) magick_info->encoder)));
12063 if (magick_info->description == (char *) NULL)
12064 PUSHs(&sv_undef);
12065 else
12066 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
12067 if (magick_info->module == (char *) NULL)
12068 PUSHs(&sv_undef);
12069 else
12070 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
12071 }
12072
12073 PerlException:
12074 InheritPerlException(exception,perl_exception);
12075 exception=DestroyExceptionInfo(exception);
12076 SvREFCNT_dec(perl_exception);
12077 }
12078
12079#
12080###############################################################################
12081# #
12082# #
12083# #
12084# Q u e r y O p t i o n #
12085# #
12086# #
12087# #
12088###############################################################################
12089#
12090#
12091void
12092QueryOption(ref,...)
12093 Image::Magick ref=NO_INIT
12094 ALIAS:
12095 queryoption = 1
12096 PPCODE:
12097 {
12098 char
12099 **options;
12100
12101 ExceptionInfo
12102 *exception;
12103
12104 long
12105 j,
12106 option;
12107
12108 register long
12109 i;
12110
12111 SV
12112 *perl_exception;
12113
12114 exception=AcquireExceptionInfo();
12115 perl_exception=newSVpv("",0);
12116 EXTEND(sp,8*items);
12117 for (i=1; i < items; i++)
12118 {
12119 option=ParseMagickOption(MagickListOptions,MagickFalse,(char *)
12120 SvPV(ST(i),na));
12121 options=GetMagickOptions((MagickOption) option);
12122 if (options == (char **) NULL)
12123 PUSHs(&sv_undef);
12124 else
12125 {
12126 for (j=0; options[j] != (char *) NULL; j++)
12127 PUSHs(sv_2mortal(newSVpv(options[j],0)));
12128 options=DestroyStringList(options);
12129 }
12130 }
12131
12132 PerlException:
12133 InheritPerlException(exception,perl_exception);
12134 exception=DestroyExceptionInfo(exception);
12135 SvREFCNT_dec(perl_exception);
12136 }
12137
12138#
12139###############################################################################
12140# #
12141# #
12142# #
12143# R e a d #
12144# #
12145# #
12146# #
12147###############################################################################
12148#
12149#
12150void
12151Read(ref,...)
12152 Image::Magick ref=NO_INIT
12153 ALIAS:
12154 ReadImage = 1
12155 read = 2
12156 readimage = 3
12157 PPCODE:
12158 {
12159 AV
12160 *av;
12161
12162 char
12163 **keep,
12164 **list;
12165
12166 ExceptionInfo
12167 *exception;
12168
12169 HV
12170 *hv;
12171
12172 Image
12173 *image;
12174
12175 int
12176 n;
12177
12178 long
12179 ac,
12180 number_images;
12181
12182 MagickBooleanType
12183 status;
12184
12185 register char
12186 **p;
12187
12188 register long
12189 i;
12190
12191 STRLEN
12192 *length;
12193
12194 struct PackageInfo
12195 *info,
12196 *package_info;
12197
12198 SV
12199 *perl_exception, /* Perl variable for storing messages */
12200 *reference,
12201 *rv,
12202 *sv;
12203
12204 exception=AcquireExceptionInfo();
12205 perl_exception=newSVpv("",0);
12206 package_info=(struct PackageInfo *) NULL;
12207 number_images=0;
12208 ac=(items < 2) ? 1 : items-1;
12209 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12210 keep=list;
12211 length=(STRLEN *) NULL;
12212 if (list == (char **) NULL)
12213 {
12214 ThrowPerlException(exception,ResourceLimitError,
12215 "MemoryAllocationFailed",PackageName);
12216 goto PerlException;
12217 }
12218 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12219 if (length == (STRLEN *) NULL)
12220 {
12221 ThrowPerlException(exception,ResourceLimitError,
12222 "MemoryAllocationFailed",PackageName);
12223 goto PerlException;
12224 }
12225 if (sv_isobject(ST(0)) == 0)
12226 {
12227 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12228 PackageName);
12229 goto PerlException;
12230 }
12231 reference=SvRV(ST(0));
12232 hv=SvSTASH(reference);
12233 if (SvTYPE(reference) != SVt_PVAV)
12234 {
12235 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12236 PackageName);
12237 goto PerlException;
12238 }
12239 av=(AV *) reference;
12240 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12241 exception);
12242 package_info=ClonePackageInfo(info,exception);
12243 n=1;
12244 if (items <= 1)
12245 *list=(char *) (*package_info->image_info->filename ?
12246 package_info->image_info->filename : "XC:black");
12247 else
12248 for (n=0, i=0; i < ac; i++)
12249 {
12250 list[n]=(char *) SvPV(ST(i+1),length[n]);
12251 if ((items >= 3) && strEQcase(list[n],"blob"))
12252 {
12253 void
12254 *blob;
12255
12256 i++;
12257 blob=(void *) (SvPV(ST(i+1),length[n]));
12258 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12259 }
12260 if ((items >= 3) && strEQcase(list[n],"filename"))
12261 continue;
12262 if ((items >= 3) && strEQcase(list[n],"file"))
12263 {
12264 FILE
12265 *file;
12266
12267 PerlIO
12268 *io_info;
12269
12270 i++;
12271 io_info=IoIFP(sv_2io(ST(i+1)));
12272 if (io_info == (PerlIO *) NULL)
12273 {
12274 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12275 PackageName);
12276 continue;
12277 }
12278 file=PerlIO_findFILE(io_info);
12279 if (file == (FILE *) NULL)
12280 {
12281 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12282 PackageName);
12283 continue;
12284 }
12285 SetImageInfoFile(package_info->image_info,file);
12286 }
12287 if ((items >= 3) && strEQcase(list[n],"magick"))
12288 continue;
12289 n++;
12290 }
12291 list[n]=(char *) NULL;
12292 keep=list;
12293 status=ExpandFilenames(&n,&list);
12294 if (status == MagickFalse)
12295 {
12296 ThrowPerlException(exception,ResourceLimitError,
12297 "MemoryAllocationFailed",PackageName);
12298 goto PerlException;
12299 }
12300 number_images=0;
12301 for (i=0; i < n; i++)
12302 {
12303 if ((package_info->image_info->file != (FILE *) NULL) ||
12304 (package_info->image_info->blob != (void *) NULL))
12305 {
12306 image=ReadImages(package_info->image_info,exception);
12307 if (image != (Image *) NULL)
12308 DisassociateImageStream(image);
12309 }
12310 else
12311 {
12312 (void) CopyMagickString(package_info->image_info->filename,list[i],
12313 MaxTextExtent);
12314 image=ReadImages(package_info->image_info,exception);
12315 }
12316 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
12317 break;
12318 for ( ; image; image=image->next)
12319 {
12320 AddImageToRegistry(image);
12321 rv=newRV(sv);
12322 av_push(av,sv_bless(rv,hv));
12323 SvREFCNT_dec(sv);
12324 number_images++;
12325 }
12326 }
12327 /*
12328 Free resources.
12329 */
12330 for (i=0; i < n; i++)
12331 if (list[i] != (char *) NULL)
12332 for (p=keep; list[i] != *p++; )
12333 if (*p == (char *) NULL)
12334 {
12335 list[i]=(char *) RelinquishMagickMemory(list[i]);
12336 break;
12337 }
12338
12339 PerlException:
12340 if (package_info != (struct PackageInfo *) NULL)
12341 DestroyPackageInfo(package_info);
12342 if (list && (list != keep))
12343 list=(char **) RelinquishMagickMemory(list);
12344 if (keep)
12345 keep=(char **) RelinquishMagickMemory(keep);
12346 if (length)
12347 length=(STRLEN *) RelinquishMagickMemory(length);
12348 InheritPerlException(exception,perl_exception);
12349 exception=DestroyExceptionInfo(exception);
12350 sv_setiv(perl_exception,(IV) number_images);
12351 SvPOK_on(perl_exception);
12352 ST(0)=sv_2mortal(perl_exception);
12353 XSRETURN(1);
12354 }
12355
12356#
12357###############################################################################
12358# #
12359# #
12360# #
12361# R e m o t e #
12362# #
12363# #
12364# #
12365###############################################################################
12366#
12367#
12368void
12369Remote(ref,...)
12370 Image::Magick ref=NO_INIT
12371 ALIAS:
12372 RemoteCommand = 1
12373 remote = 2
12374 remoteCommand = 3
12375 PPCODE:
12376 {
12377 AV
12378 *av;
12379
12380 ExceptionInfo
12381 *exception;
12382
12383 register long
12384 i;
12385
12386 SV
12387 *perl_exception,
12388 *reference;
12389
12390 struct PackageInfo
12391 *info;
12392
12393 exception=AcquireExceptionInfo();
12394 perl_exception=newSVpv("",0);
12395 reference=SvRV(ST(0));
12396 av=(AV *) reference;
12397 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12398 exception);
12399 for (i=1; i < items; i++)
12400 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
12401 SvPV(ST(i),na),exception);
12402 InheritPerlException(exception,perl_exception);
12403 exception=DestroyExceptionInfo(exception);
12404 SvREFCNT_dec(perl_exception); /* throw away all errors */
12405 }
12406
12407#
12408###############################################################################
12409# #
12410# #
12411# #
12412# S e t #
12413# #
12414# #
12415# #
12416###############################################################################
12417#
12418#
12419void
12420Set(ref,...)
12421 Image::Magick ref=NO_INIT
12422 ALIAS:
12423 SetAttributes = 1
12424 SetAttribute = 2
12425 set = 3
12426 setattributes = 4
12427 setattribute = 5
12428 PPCODE:
12429 {
12430 ExceptionInfo
12431 *exception;
12432
12433 Image
12434 *image;
12435
12436 register long
12437 i;
12438
12439 struct PackageInfo
12440 *info;
12441
12442 SV
12443 *perl_exception,
12444 *reference; /* reference is the SV* of ref=SvIV(reference) */
12445
12446 exception=AcquireExceptionInfo();
12447 perl_exception=newSVpv("",0);
12448 if (sv_isobject(ST(0)) == 0)
12449 {
12450 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12451 PackageName);
12452 goto PerlException;
12453 }
12454 reference=SvRV(ST(0));
12455 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12456 if (items == 2)
12457 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
12458 else
12459 for (i=2; i < items; i+=2)
12460 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
12461
12462 PerlException:
12463 InheritPerlException(exception,perl_exception);
12464 exception=DestroyExceptionInfo(exception);
12465 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
12466 SvPOK_on(perl_exception);
12467 ST(0)=sv_2mortal(perl_exception);
12468 XSRETURN(1);
12469 }
12470
12471#
12472###############################################################################
12473# #
12474# #
12475# #
12476# S e t P i x e l #
12477# #
12478# #
12479# #
12480###############################################################################
12481#
12482#
12483void
12484SetPixel(ref,...)
12485 Image::Magick ref=NO_INIT
12486 ALIAS:
12487 setpixel = 1
12488 setPixel = 2
12489 PPCODE:
12490 {
12491 AV
12492 *av;
12493
12494 char
12495 *attribute;
12496
12497 ChannelType
12498 channel;
12499
12500 ExceptionInfo
12501 *exception;
12502
12503 Image
12504 *image;
12505
12506 long
12507 option;
12508
12509 MagickBooleanType
12510 normalize;
12511
12512 RectangleInfo
12513 region;
12514
12515 register IndexPacket
12516 *indexes;
12517
12518 register long
12519 i;
12520
12521 register PixelPacket
12522 *q;
12523
12524 struct PackageInfo
12525 *info;
12526
12527 SV
12528 *perl_exception,
12529 *reference; /* reference is the SV* of ref=SvIV(reference) */
12530
12531 exception=AcquireExceptionInfo();
12532 perl_exception=newSVpv("",0);
12533 reference=SvRV(ST(0));
12534 av=(AV *) reference;
12535 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12536 exception);
12537 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12538 if (image == (Image *) NULL)
12539 {
12540 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12541 PackageName);
12542 goto PerlException;
12543 }
12544 av=(AV *) NULL;
12545 channel=DefaultChannels;
12546 normalize=MagickTrue;
12547 region.x=0;
12548 region.y=0;
12549 region.width=image->columns;
12550 region.height=1;
12551 if (items == 1)
12552 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
12553 for (i=2; i < items; i+=2)
12554 {
12555 attribute=(char *) SvPV(ST(i-1),na);
12556 switch (*attribute)
12557 {
12558 case 'C':
12559 case 'c':
12560 {
12561 if (LocaleCompare(attribute,"channel") == 0)
12562 {
12563 long
12564 option;
12565
12566 option=ParseChannelOption(SvPV(ST(i),na));
12567 if (option < 0)
12568 {
12569 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12570 SvPV(ST(i),na));
12571 return;
12572 }
12573 channel=(ChannelType) option;
12574 break;
12575 }
12576 if (LocaleCompare(attribute,"color") == 0)
12577 {
12578 if (SvTYPE(ST(i)) != SVt_RV)
12579 {
12580 char
12581 message[MaxTextExtent];
12582
12583 (void) FormatMagickString(message,MaxTextExtent,
12584 "invalid %.60s value",attribute);
12585 ThrowPerlException(exception,OptionError,message,
12586 SvPV(ST(i),na));
12587 }
12588 av=(AV *) SvRV(ST(i));
12589 break;
12590 }
12591 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12592 attribute);
12593 break;
12594 }
12595 case 'g':
12596 case 'G':
12597 {
12598 if (LocaleCompare(attribute,"geometry") == 0)
12599 {
12600 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
12601 break;
12602 }
12603 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12604 attribute);
12605 break;
12606 }
12607 case 'N':
12608 case 'n':
12609 {
12610 if (LocaleCompare(attribute,"normalize") == 0)
12611 {
12612 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
12613 SvPV(ST(i),na));
12614 if (option < 0)
12615 {
12616 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12617 SvPV(ST(i),na));
12618 break;
12619 }
12620 normalize=option != 0 ? MagickTrue : MagickFalse;
12621 break;
12622 }
12623 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12624 attribute);
12625 break;
12626 }
12627 case 'x':
12628 case 'X':
12629 {
12630 if (LocaleCompare(attribute,"x") == 0)
12631 {
12632 region.x=SvIV(ST(i));
12633 break;
12634 }
12635 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12636 attribute);
12637 break;
12638 }
12639 case 'y':
12640 case 'Y':
12641 {
12642 if (LocaleCompare(attribute,"y") == 0)
12643 {
12644 region.y=SvIV(ST(i));
12645 break;
12646 }
12647 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12648 attribute);
12649 break;
12650 }
12651 default:
12652 {
12653 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12654 attribute);
12655 break;
12656 }
12657 }
12658 }
12659 (void) SetImageStorageClass(image,DirectClass);
12660 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
12661 if ((q == (PixelPacket *) NULL) || (av == (AV *) NULL))
12662 PUSHs(&sv_undef);
12663 else
12664 {
12665 double
12666 scale;
12667
12668 register long
12669 i;
12670
12671 i=0;
12672 indexes=GetAuthenticIndexQueue(image);
12673 scale=1.0;
12674 if (normalize != MagickFalse)
12675 scale=QuantumRange;
12676 if (((channel & RedChannel) != 0) && (i <= av_len(av)))
12677 {
12678 q->red=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12679 i++;
12680 }
12681 if (((channel & GreenChannel) != 0) && (i <= av_len(av)))
12682 {
12683 q->green=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12684 i++;
12685 }
12686 if (((channel & BlueChannel) != 0) && (i <= av_len(av)))
12687 {
12688 q->blue=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12689 i++;
12690 }
12691 if ((((channel & IndexChannel) != 0) &&
12692 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
12693 {
12694 *indexes=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12695 i++;
12696 }
12697 if (((channel & OpacityChannel) != 0) && (i <= av_len(av)))
12698 {
12699 q->opacity=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12700 i++;
12701 }
12702 (void) SyncAuthenticPixels(image,exception);
12703 }
12704
12705 PerlException:
12706 InheritPerlException(exception,perl_exception);
12707 exception=DestroyExceptionInfo(exception);
12708 SvREFCNT_dec(perl_exception);
12709 }
12710
12711#
12712###############################################################################
12713# #
12714# #
12715# #
12716# S t a t i s t i c s #
12717# #
12718# #
12719# #
12720###############################################################################
12721#
12722#
12723void
12724Statistics(ref,...)
12725 Image::Magick ref=NO_INIT
12726 ALIAS:
12727 StatisticsImage = 1
12728 statistics = 2
12729 statisticsimage = 3
12730 PPCODE:
12731 {
12732 AV
12733 *av;
12734
12735 char
12736 message[MaxTextExtent];
12737
12738 ChannelStatistics
12739 *channel_statistics;
12740
12741 double
12742 scale;
12743
12744 ExceptionInfo
12745 *exception;
12746
12747 HV
12748 *hv;
12749
12750 Image
12751 *image;
12752
12753 ssize_t
12754 count;
12755
12756 struct PackageInfo
12757 *info;
12758
12759 SV
12760 *av_reference,
12761 *perl_exception,
12762 *reference;
12763
12764 exception=AcquireExceptionInfo();
12765 perl_exception=newSVpv("",0);
12766 av=NULL;
12767 if (sv_isobject(ST(0)) == 0)
12768 {
12769 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12770 PackageName);
12771 goto PerlException;
12772 }
12773 reference=SvRV(ST(0));
12774 hv=SvSTASH(reference);
12775 av=newAV();
12776 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12777 SvREFCNT_dec(av);
12778 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12779 if (image == (Image *) NULL)
12780 {
12781 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12782 PackageName);
12783 goto PerlException;
12784 }
12785 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12786 count=0;
12787 for ( ; image; image=image->next)
12788 {
12789 channel_statistics=GetImageChannelStatistics(image,&image->exception);
12790 if (channel_statistics == (ChannelStatistics *) NULL)
12791 continue;
12792 count++;
12793 EXTEND(sp,25*count);
12794 scale=(double) QuantumRange;
12795 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12796 channel_statistics[RedChannel].depth);
12797 PUSHs(sv_2mortal(newSVpv(message,0)));
12798 (void) FormatMagickString(message,MaxTextExtent,"%g",
12799 channel_statistics[RedChannel].minima/scale);
12800 PUSHs(sv_2mortal(newSVpv(message,0)));
12801 (void) FormatMagickString(message,MaxTextExtent,"%g",
12802 channel_statistics[RedChannel].maxima/scale);
12803 PUSHs(sv_2mortal(newSVpv(message,0)));
12804 (void) FormatMagickString(message,MaxTextExtent,"%g",
12805 channel_statistics[RedChannel].mean/scale);
12806 PUSHs(sv_2mortal(newSVpv(message,0)));
12807 (void) FormatMagickString(message,MaxTextExtent,"%g",
12808 channel_statistics[RedChannel].standard_deviation/scale);
12809 PUSHs(sv_2mortal(newSVpv(message,0)));
12810 (void) FormatMagickString(message,MaxTextExtent,"%g",
12811 channel_statistics[RedChannel].kurtosis);
12812 PUSHs(sv_2mortal(newSVpv(message,0)));
12813 (void) FormatMagickString(message,MaxTextExtent,"%g",
12814 channel_statistics[RedChannel].skewness);
12815 PUSHs(sv_2mortal(newSVpv(message,0)));
12816 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12817 channel_statistics[GreenChannel].depth);
12818 PUSHs(sv_2mortal(newSVpv(message,0)));
12819 (void) FormatMagickString(message,MaxTextExtent,"%g",
12820 channel_statistics[GreenChannel].minima/scale);
12821 PUSHs(sv_2mortal(newSVpv(message,0)));
12822 (void) FormatMagickString(message,MaxTextExtent,"%g",
12823 channel_statistics[GreenChannel].maxima/scale);
12824 PUSHs(sv_2mortal(newSVpv(message,0)));
12825 (void) FormatMagickString(message,MaxTextExtent,"%g",
12826 channel_statistics[GreenChannel].mean/scale);
12827 PUSHs(sv_2mortal(newSVpv(message,0)));
12828 (void) FormatMagickString(message,MaxTextExtent,"%g",
12829 channel_statistics[GreenChannel].standard_deviation/scale);
12830 PUSHs(sv_2mortal(newSVpv(message,0)));
12831 (void) FormatMagickString(message,MaxTextExtent,"%g",
12832 channel_statistics[GreenChannel].kurtosis);
12833 PUSHs(sv_2mortal(newSVpv(message,0)));
12834 (void) FormatMagickString(message,MaxTextExtent,"%g",
12835 channel_statistics[GreenChannel].skewness);
12836 PUSHs(sv_2mortal(newSVpv(message,0)));
12837 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12838 channel_statistics[BlueChannel].depth);
12839 PUSHs(sv_2mortal(newSVpv(message,0)));
12840 (void) FormatMagickString(message,MaxTextExtent,"%g",
12841 channel_statistics[BlueChannel].minima/scale);
12842 PUSHs(sv_2mortal(newSVpv(message,0)));
12843 (void) FormatMagickString(message,MaxTextExtent,"%g",
12844 channel_statistics[BlueChannel].maxima/scale);
12845 PUSHs(sv_2mortal(newSVpv(message,0)));
12846 (void) FormatMagickString(message,MaxTextExtent,"%g",
12847 channel_statistics[BlueChannel].mean/scale);
12848 PUSHs(sv_2mortal(newSVpv(message,0)));
12849 (void) FormatMagickString(message,MaxTextExtent,"%g",
12850 channel_statistics[BlueChannel].standard_deviation/scale);
12851 PUSHs(sv_2mortal(newSVpv(message,0)));
12852 (void) FormatMagickString(message,MaxTextExtent,"%g",
12853 channel_statistics[BlueChannel].kurtosis);
12854 PUSHs(sv_2mortal(newSVpv(message,0)));
12855 (void) FormatMagickString(message,MaxTextExtent,"%g",
12856 channel_statistics[BlueChannel].skewness);
12857 PUSHs(sv_2mortal(newSVpv(message,0)));
12858 if (image->colorspace == CMYKColorspace)
12859 {
12860 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12861 channel_statistics[BlackChannel].depth);
12862 PUSHs(sv_2mortal(newSVpv(message,0)));
12863 (void) FormatMagickString(message,MaxTextExtent,"%g",
12864 channel_statistics[BlackChannel].minima/scale);
12865 PUSHs(sv_2mortal(newSVpv(message,0)));
12866 (void) FormatMagickString(message,MaxTextExtent,"%g",
12867 channel_statistics[BlackChannel].maxima/scale);
12868 PUSHs(sv_2mortal(newSVpv(message,0)));
12869 (void) FormatMagickString(message,MaxTextExtent,"%g",
12870 channel_statistics[BlackChannel].mean/scale);
12871 PUSHs(sv_2mortal(newSVpv(message,0)));
12872 (void) FormatMagickString(message,MaxTextExtent,"%g",
12873 channel_statistics[BlackChannel].standard_deviation/scale);
12874 PUSHs(sv_2mortal(newSVpv(message,0)));
12875 (void) FormatMagickString(message,MaxTextExtent,"%g",
12876 channel_statistics[BlackChannel].kurtosis);
12877 PUSHs(sv_2mortal(newSVpv(message,0)));
12878 (void) FormatMagickString(message,MaxTextExtent,"%g",
12879 channel_statistics[BlackChannel].skewness);
12880 PUSHs(sv_2mortal(newSVpv(message,0)));
12881 }
12882 if (image->matte != MagickFalse)
12883 {
12884 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12885 channel_statistics[OpacityChannel].depth);
12886 PUSHs(sv_2mortal(newSVpv(message,0)));
12887 (void) FormatMagickString(message,MaxTextExtent,"%g",
12888 channel_statistics[OpacityChannel].minima/scale);
12889 PUSHs(sv_2mortal(newSVpv(message,0)));
12890 (void) FormatMagickString(message,MaxTextExtent,"%g",
12891 channel_statistics[OpacityChannel].maxima/scale);
12892 PUSHs(sv_2mortal(newSVpv(message,0)));
12893 (void) FormatMagickString(message,MaxTextExtent,"%g",
12894 channel_statistics[OpacityChannel].mean/scale);
12895 PUSHs(sv_2mortal(newSVpv(message,0)));
12896 (void) FormatMagickString(message,MaxTextExtent,"%g",
12897 channel_statistics[OpacityChannel].standard_deviation/scale);
12898 PUSHs(sv_2mortal(newSVpv(message,0)));
12899 (void) FormatMagickString(message,MaxTextExtent,"%g",
12900 channel_statistics[OpacityChannel].kurtosis);
12901 PUSHs(sv_2mortal(newSVpv(message,0)));
12902 (void) FormatMagickString(message,MaxTextExtent,"%g",
12903 channel_statistics[OpacityChannel].skewness);
12904 PUSHs(sv_2mortal(newSVpv(message,0)));
12905 }
12906 channel_statistics=(ChannelStatistics *)
12907 RelinquishMagickMemory(channel_statistics);
12908 }
12909
12910 PerlException:
12911 InheritPerlException(exception,perl_exception);
12912 exception=DestroyExceptionInfo(exception);
12913 SvREFCNT_dec(perl_exception);
12914 }
12915
12916#
12917###############################################################################
12918# #
12919# #
12920# #
12921# S y n c A u t h e n t i c P i x e l s #
12922# #
12923# #
12924# #
12925###############################################################################
12926#
12927#
12928void
12929SyncAuthenticPixels(ref,...)
12930 Image::Magick ref = NO_INIT
12931 ALIAS:
12932 Syncauthenticpixels = 1
12933 SyncImagePixels = 2
12934 syncimagepixels = 3
12935 CODE:
12936 {
12937 ExceptionInfo
12938 *exception;
12939
12940 Image
12941 *image;
12942
12943 MagickBooleanType
12944 status;
12945
12946 struct PackageInfo
12947 *info;
12948
12949 SV
12950 *perl_exception,
12951 *reference;
12952
12953 exception=AcquireExceptionInfo();
12954 perl_exception=newSVpv("",0);
12955
12956 if (sv_isobject(ST(0)) == 0)
12957 {
12958 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12959 PackageName);
12960 goto PerlException;
12961 }
12962
12963 reference=SvRV(ST(0));
12964 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12965 if (image == (Image *) NULL)
12966 {
12967 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12968 PackageName);
12969 goto PerlException;
12970 }
12971
12972 status=SyncAuthenticPixels(image,exception);
12973 if (status != MagickFalse)
12974 return;
12975 InheritException(exception,&image->exception);
12976
12977 PerlException:
12978 InheritPerlException(exception,perl_exception);
12979 exception=DestroyExceptionInfo(exception);
12980 SvREFCNT_dec(perl_exception); /* throw away all errors */
12981 }
12982
12983#
12984###############################################################################
12985# #
12986# #
12987# #
12988# T r a n s f o r m #
12989# #
12990# #
12991# #
12992###############################################################################
12993#
12994#
12995void
12996Transform(ref,...)
12997 Image::Magick ref=NO_INIT
12998 ALIAS:
12999 TransformImage = 1
13000 transform = 2
13001 transformimage = 3
13002 PPCODE:
13003 {
13004 AV
13005 *av;
13006
13007 char
13008 *attribute,
13009 *crop_geometry,
13010 *geometry;
13011
13012 ExceptionInfo
13013 *exception;
13014
13015 HV
13016 *hv;
13017
13018 Image
13019 *clone,
13020 *image;
13021
13022 register long
13023 i;
13024
13025 struct PackageInfo
13026 *info;
13027
13028 SV
13029 *av_reference,
13030 *perl_exception,
13031 *reference,
13032 *rv,
13033 *sv;
13034
13035 exception=AcquireExceptionInfo();
13036 perl_exception=newSVpv("",0);
13037 av=NULL;
13038 attribute=NULL;
13039 if (sv_isobject(ST(0)) == 0)
13040 {
13041 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13042 PackageName);
13043 goto PerlException;
13044 }
13045 reference=SvRV(ST(0));
13046 hv=SvSTASH(reference);
13047 av=newAV();
13048 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
13049 SvREFCNT_dec(av);
13050 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13051 if (image == (Image *) NULL)
13052 {
13053 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13054 PackageName);
13055 goto PerlException;
13056 }
13057 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
13058 /*
13059 Get attribute.
13060 */
13061 crop_geometry=(char *) NULL;
13062 geometry=(char *) NULL;
13063 for (i=2; i < items; i+=2)
13064 {
13065 attribute=(char *) SvPV(ST(i-1),na);
13066 switch (*attribute)
13067 {
13068 case 'c':
13069 case 'C':
13070 {
13071 if (LocaleCompare(attribute,"crop") == 0)
13072 {
13073 crop_geometry=SvPV(ST(i),na);
13074 break;
13075 }
13076 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13077 attribute);
13078 break;
13079 }
13080 case 'g':
13081 case 'G':
13082 {
13083 if (LocaleCompare(attribute,"geometry") == 0)
13084 {
13085 geometry=SvPV(ST(i),na);
13086 break;
13087 }
13088 if (LocaleCompare(attribute,"gravity") == 0)
13089 {
13090 Image
13091 *next;
13092
13093 long
13094 in;
13095
13096 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
13097 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13098 if (in < 0)
13099 {
13100 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13101 SvPV(ST(i),na));
13102 return;
13103 }
13104 for (next=image; next; next=next->next)
13105 next->gravity=(GravityType) in;
13106 break;
13107 }
13108 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13109 attribute);
13110 break;
13111 }
13112 default:
13113 {
13114 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13115 attribute);
13116 break;
13117 }
13118 }
13119 }
13120 for ( ; image; image=image->next)
13121 {
13122 clone=CloneImage(image,0,0,MagickTrue,exception);
13123 if ((clone == (Image *) NULL) || (exception->severity >= ErrorException))
13124 goto PerlException;
13125 TransformImage(&clone,crop_geometry,geometry);
13126 for ( ; clone; clone=clone->next)
13127 {
13128 AddImageToRegistry(clone);
13129 rv=newRV(sv);
13130 av_push(av,sv_bless(rv,hv));
13131 SvREFCNT_dec(sv);
13132 }
13133 }
13134 exception=DestroyExceptionInfo(exception);
13135 ST(0)=av_reference;
13136 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13137 XSRETURN(1);
13138
13139 PerlException:
13140 InheritPerlException(exception,perl_exception);
13141 exception=DestroyExceptionInfo(exception);
13142 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
13143 SvPOK_on(perl_exception);
13144 ST(0)=sv_2mortal(perl_exception);
13145 XSRETURN(1);
13146 }
13147
13148#
13149###############################################################################
13150# #
13151# #
13152# #
13153# W r i t e #
13154# #
13155# #
13156# #
13157###############################################################################
13158#
13159#
13160void
13161Write(ref,...)
13162 Image::Magick ref=NO_INIT
13163 ALIAS:
13164 WriteImage = 1
13165 write = 2
13166 writeimage = 3
13167 PPCODE:
13168 {
13169 char
13170 filename[MaxTextExtent];
13171
13172 ExceptionInfo
13173 *exception;
13174
13175 Image
13176 *image,
13177 *next;
13178
13179 long
13180 number_images,
13181 scene;
13182
13183 register long
13184 i;
13185
13186 struct PackageInfo
13187 *info,
13188 *package_info;
13189
13190 SV
13191 *perl_exception,
13192 *reference;
13193
13194 exception=AcquireExceptionInfo();
13195 perl_exception=newSVpv("",0);
13196 number_images=0;
13197 package_info=(struct PackageInfo *) NULL;
13198 if (sv_isobject(ST(0)) == 0)
13199 {
13200 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13201 PackageName);
13202 goto PerlException;
13203 }
13204 reference=SvRV(ST(0));
13205 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13206 if (image == (Image *) NULL)
13207 {
13208 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13209 PackageName);
13210 goto PerlException;
13211 }
13212 package_info=ClonePackageInfo(info,exception);
13213 if (items == 2)
13214 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
13215 else
13216 if (items > 2)
13217 for (i=2; i < items; i+=2)
13218 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
13219 exception);
13220 (void) CopyMagickString(filename,package_info->image_info->filename,
13221 MaxTextExtent);
13222 scene=0;
13223 for (next=image; next; next=next->next)
13224 {
13225 (void) CopyMagickString(next->filename,filename,MaxTextExtent);
13226 next->scene=scene++;
13227 }
13228 SetImageInfo(package_info->image_info,MagickTrue,&image->exception);
13229 for (next=image; next; next=next->next)
13230 {
13231 (void) WriteImage(package_info->image_info,next);
13232 if (next->exception.severity >= ErrorException)
13233 InheritException(exception,&next->exception);
13234 GetImageException(next,exception);
13235 number_images++;
13236 if (package_info->image_info->adjoin)
13237 break;
13238 }
13239
13240 PerlException:
13241 if (package_info != (struct PackageInfo *) NULL)
13242 DestroyPackageInfo(package_info);
13243 InheritPerlException(exception,perl_exception);
13244 exception=DestroyExceptionInfo(exception);
13245 sv_setiv(perl_exception,(IV) number_images);
13246 SvPOK_on(perl_exception);
13247 ST(0)=sv_2mortal(perl_exception);
13248 XSRETURN(1);
13249 }